diff --git a/sites/all/modules/advanced_help/LICENSE.txt b/sites/all/modules/advanced_help/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..2c095c8d3f42488e8168f9710a4ffbfc4125a159 --- /dev/null +++ b/sites/all/modules/advanced_help/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/sites/all/modules/advanced_help/advanced-help-popup.tpl.php b/sites/all/modules/advanced_help/advanced-help-popup.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..8e651960c3ffdd0a2de26bce5051ce2857c6b538 --- /dev/null +++ b/sites/all/modules/advanced_help/advanced-help-popup.tpl.php @@ -0,0 +1,42 @@ +<?php +// $Id: advanced-help-popup.tpl.php,v 1.2.4.1 2010/03/01 21:12:39 fgm Exp $ +/** + * @file + * Default theme implementation to display a help popup. + */ +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language ?>" lang="<?php print $language->language ?>" dir="<?php print $language->dir ?>"> + +<head> + <title><?php print $head_title; ?></title> + <?php print $head; ?> + <?php print $styles; ?> + <?php print $scripts; ?> + <script type="text/javascript"><?php /* Needed to avoid Flash of Unstyled Content in IE */ ?> </script> +</head> +<body> + <div id="page"> + <div id="header"> + <?php if (!empty($search_box)): ?> + <div id="search-box"><?php print $search_box; ?></div> + <?php endif; ?> + </div> <!-- /header --> + <div id="breadcrumb"><?php print $breadcrumb; ?></div> + + <div id="content"> + <?php if (!empty($title)): ?><h1 class="title" id="page-title"><?php print $title; ?></h1><?php endif; ?> + <?php if (!empty($tabs)): ?><div class="tabs"><?php print $tabs; ?></div><?php endif; ?> + <?php if (!empty($messages)): print $messages; endif; ?> + <?php if (!empty($help)): print $help; endif; ?> + <div id="content-content" class="clear-block"> + <?php print $content; ?> + </div> <!-- /content-content --> + </div> <!-- /content --> + + <?php print $closure; ?> + + </div> <!-- /page --> +</body> +</html> diff --git a/sites/all/modules/advanced_help/advanced_help.info b/sites/all/modules/advanced_help/advanced_help.info new file mode 100644 index 0000000000000000000000000000000000000000..d767d52754a21e4c7747b1b8b6cf1125b909f8e8 --- /dev/null +++ b/sites/all/modules/advanced_help/advanced_help.info @@ -0,0 +1,13 @@ +; $Id: advanced_help.info,v 1.2.4.2 2010/03/01 21:12:39 fgm Exp $ +name = Advanced help +description = Allow advanced help and documentation. +core = 7.x +files[] = advanced_help.module +files[] = advanced_help.install + +; Information added by drupal.org packaging script on January 1, 1970 - 00:00 +version = "7.x-1.0-beta1" +core = "7.x" +project = "advanced_help" +datestamp = "1295293901" + diff --git a/sites/all/modules/advanced_help/advanced_help.install b/sites/all/modules/advanced_help/advanced_help.install new file mode 100644 index 0000000000000000000000000000000000000000..2ed48393148ba9965e76c1b7daf8f41b1358d3c2 --- /dev/null +++ b/sites/all/modules/advanced_help/advanced_help.install @@ -0,0 +1,66 @@ +<?php +// $Id: advanced_help.install,v 1.4.2.2 2010/03/01 21:12:39 fgm Exp $ +/** + * @file + * Contains install and update functions for advanced_help. + */ + +/** + * Implements hook_install(). + */ +function advanced_help_install() { + // drupal_set_message('Installing advanced_help.'); +} + +/** + * Implements hook_uninstall(). + */ +function advanced_help_uninstall() { + variable_del('advanced_help_last_cron'); +} + +/** + * Implements hook_schema(). + */ +function advanced_help_schema() { + $schema['advanced_help_index'] = array( + 'description' => 'Stores search index correlations for advanced help topics.', + 'fields' => array( + 'sid' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The primary key to give to the search engine for this topic.', + 'no export' => TRUE, + ), + 'module' => array( + 'type' => 'varchar', + 'length' => '255', + 'default' => '', + 'not null' => TRUE, + 'description' => 'The module that owns this topic.', + ), + 'topic' => array( + 'type' => 'varchar', + 'length' => '255', + 'default' => '', + 'not null' => TRUE, + 'description' => 'The topic id.', + ), + 'language' => array( + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The language this search index relates to.', + ), + ), + 'primary key' => array('sid'), + 'indexes' => array('language' => array('language')), + 'foreign keys' => array( + 'module' => array('system' => 'name'), + ), + ); + + return $schema; +} diff --git a/sites/all/modules/advanced_help/advanced_help.module b/sites/all/modules/advanced_help/advanced_help.module new file mode 100644 index 0000000000000000000000000000000000000000..00427e5bea32a6253c355f77f3adf98cd3e1eb4c --- /dev/null +++ b/sites/all/modules/advanced_help/advanced_help.module @@ -0,0 +1,1054 @@ +<?php +// $Id: advanced_help.module,v 1.41.2.6 2011/01/17 19:49:13 dmitrig01 Exp $ +/** + * @file + * + * Pluggable system to provide advanced help facilities for Drupal and modules. + * + * Modules utilizing this help system should create a 'help' directory in their + * module. Inside that directory place MODULENAME.help.ini which will be formatted + * like this: + * + * @code + * [buses] + * title = "How buses are tied into the system" + * file = buses + * + * [TOPIC_ID] + * title = "Title of topic" + * file = filename of topic, without the .html extension + * weight = the importance of the topic on the index page + * parent = the optional topic parent to use in the breadcrumb. Can be either topic or module%topic + * @endcode + * + * All topics are addressed by the module that provides the topic, and the topic + * id. Links may be embedded as in the following example: + * + * @code + * $output .= theme('advanced_help_topic', $module, $topic); + * @endcode + * + * Link to other topics using <a href="topic:module/topic">. (Using + * this format ensures the popup status remains consistent for all + * links.) + */ + +/** + * Implements hook_menu(). + */ +function advanced_help_menu() { + // View help topic index. + + // This is structured a little oddly so POTX can properly handle the translation. + if (module_exists('help')) { + $items['admin/advanced_help'] = array( + 'title' => 'Advanced help', + 'page callback' => 'advanced_help_index_page', + 'access arguments' => array('view advanced help index'), + 'weight' => 9, + ); + } + else { + $items['admin/advanced_help'] = array( + 'title' => 'Help', + 'page callback' => 'advanced_help_index_page', + 'access arguments' => array('view advanced help index'), + 'weight' => 9, + ); + } + $items['advanced_help/search/%menu_tail'] = array( + 'title' => 'Search help', + 'page callback' => 'advanced_help_search_view', + 'page arguments' => array('advanced_help'), + 'access arguments' => array('view advanced help index'), + ); + + // View help topic. + $items['help/%/%'] = array( + 'page callback' => 'advanced_help_topic_page', + 'page arguments' => array(1, 2), + 'access arguments' => array('view advanced help topic'), + 'type' => MENU_CALLBACK, + ); + + return $items; +} + +/** + * Implements hook_menu_alter(). + */ +function advanced_help_menu_alter(&$callbacks) { + // We need to fix the menu item provided by search module to restrict access. + $callbacks['search/advanced_help/%menu_tail']['access callback'] = 'user_access'; + $callbacks['search/advanced_help/%menu_tail']['access arguments'] = array('view advanced help index'); +} + +/** + * Implements hook_theme(). + */ +function advanced_help_theme() { + $hooks['advanced_help_topic'] = array( + 'variables' => array( + 'module' => NULL, + 'topic' => NULL, + 'type' => 'icon', + ), + ); + + $hooks['advanced_help_popup'] = array( + 'render element' => 'content', + 'template' => 'advanced-help-popup', + ); + + return $hooks; +} + +function advanced_help_uasort($id_a, $id_b) { + $topics = advanced_help_get_topics(); + list($module_a, $topic_a) = $id_a; + $a = $topics[$module_a][$topic_a]; + list($module_b, $topic_b) = $id_b; + $b = $topics[$module_b][$topic_b]; + + $a_weight = isset($a['weight']) ? $a['weight'] : 0; + $b_weight = isset($b['weight']) ? $b['weight'] : 0; + if ($a_weight != $b_weight) { + return ($a_weight < $b_weight) ? -1 : 1; + } + + if ($a['title'] != $b['title']) { + return ($a['title'] < $b['title']) ? -1 : 1; + } + return 0; +} + +/** + * Page callback for advanced help search. + */ +function advanced_help_search_view() { + if (!module_exists('search')) { + return drupal_not_found(); + } + + $breadcrumb[] = advanced_help_l(t('Help'), 'admin/advanced_help'); + + if (!isset($_POST['form_id'])) { + $keys = search_get_keys(); + // Only perform search if there is non-whitespace search term: + $results = ''; + if (trim($keys)) { + // Collect the search results: + $results = array( + '#type' => 'markup', + '#markup' => search_data($keys, 'advanced_help'), + ); + } + + // Construct the search form. + $output['advanced_help_search_form'] = drupal_get_form('advanced_help_search_form', $keys); + $output['results'] = $results; + + } + else { + $output = drupal_get_form('advanced_help_search_form', empty($keys) ? '' : $keys); + } + + $popup = !empty($_GET['popup']) && user_access('view advanced help popup'); + if ($popup) { + $GLOBALS['devel_shutdown'] = FALSE; // Prevent devel module from spewing. + module_invoke('admin_menu', 'suppress'); // Suppress admin_menu. + drupal_set_breadcrumb(array_reverse($breadcrumb)); + print theme('advanced_help_popup', array('content' => $output)); + return; + } + + $breadcrumb = array_merge(drupal_get_breadcrumb(), array_reverse($breadcrumb)); + drupal_set_breadcrumb($breadcrumb); + return $output; +} + +/** + * Page callback to view the advanced help topic index. + * + * @param string $module + * @return array + */ +function advanced_help_index_page($module = '') { + $topics = advanced_help_get_topics(); + $settings = advanced_help_get_settings(); + + $output = array(); + // Print a search widget. + $output['advanced_help_search'] = module_exists('search') + ? drupal_get_form('advanced_help_search_form') + : t('Enable the search module to search help.'); + + $breadcrumb = array(); + if ($module) { + if (empty($topics[$module])) { + return drupal_not_found(); + } + + advanced_help_get_topic_hierarchy($topics); + $items = advanced_help_get_tree($topics, $topics[$module]['']['children']); + + $breadcrumb[] = advanced_help_l(t('Help'), 'admin/advanced_help'); + + drupal_set_title(t('@module help index', array('@module' => advanced_help_get_module_name($module)))); + $output['items-module'] = array( + '#theme' => 'item_list', + '#items' => $items, + ); + } + else { + // Print a module index. + $modules = array(); + $result = db_query('SELECT * FROM {system}'); + foreach ($result as $info) { + $module_info = unserialize($info->info); + $modules[$info->name] = $module_info['name']; + } + + asort($modules); + + $items = array(); + foreach ($modules as $module => $module_name) { + if (!empty($topics[$module]) && empty($settings[$module]['hide'])) { + if (isset($settings[$module]['index name'])) { + $name = $settings[$module]['index name']; + } + elseif (isset($settings[$module]['name'])) { + $name = $settings[$module]['name']; + } + else { + $name = t($module_name); + } + $items[] = advanced_help_l($name, "admin/advanced_help/$module"); + } + } + + drupal_set_title(t('Module help index')); + $output['items-nomodule'] = array( + '#theme' => 'item_list', + '#items' => $items, + ); + } + + $popup = !empty($_GET['popup']) && user_access('view advanced help popup'); + if ($popup) { + $GLOBALS['devel_shutdown'] = FALSE; // Prevent devel module from spewing. + module_invoke('admin_menu', 'suppress'); // Suppress admin_menu. + drupal_set_breadcrumb(array_reverse($breadcrumb)); + print theme('advanced_help_popup', array('content' => $output)); + return; + } + + $breadcrumb = array_merge(drupal_get_breadcrumb(), array_reverse($breadcrumb)); + drupal_set_breadcrumb($breadcrumb); + return $output; +} + +/** + * Build a tree of advanced help topics. + * + * @param array $topics + * @param array $topic_ids + * @param int $max_depth + * @param int $depth + * @return array + */ +function advanced_help_get_tree($topics, $topic_ids, $max_depth = -1, $depth = 0) { + uasort($topic_ids, 'advanced_help_uasort'); + $items = array(); + foreach ($topic_ids as $info) { + list($module, $topic) = $info; + $item = advanced_help_l($topics[$module][$topic]['title'], "help/$module/$topic"); + if (!empty($topics[$module][$topic]['children']) && ($max_depth == -1 || $depth < $max_depth)) { + $item .= theme('item_list', array('items' => + advanced_help_get_tree($topics, $topics[$module][$topic]['children'], $max_depth, $depth + 1))); + } + + $items[] = $item; + } + + return $items; +} + +/** + * Build a hierarchy for a single module's topics. + */ +function advanced_help_get_topic_hierarchy(&$topics) { + foreach ($topics as $module => $module_topics) { + foreach ($module_topics as $topic => $info) { + $parent_module = $module; + // We have a blank topic that we don't want parented to itself. + if (!$topic) { + continue; + } + + if (empty($info['parent'])) { + $parent = ''; + } + elseif (strpos($info['parent'], '%')) { + list($parent_module, $parent) = explode('%', $info['parent']); + if (empty($topics[$parent_module][$parent])) { + // If it doesn't exist, top level. + $parent = ''; + } + } + else { + $parent = $info['parent']; + if (empty($module_topics[$parent])) { + // If it doesn't exist, top level. + $parent = ''; + } + } + + if (!isset($topics[$parent_module][$parent]['children'])) { + $topics[$parent_module][$parent]['children'] = array(); + } + $topics[$parent_module][$parent]['children'][] = array($module, $topic); + $topics[$module][$topic]['_parent'] = array($parent_module, $parent); + } + } +} + +/** + * Implements hook_form_system_modules_alter(). + * + * Add advanced help links to the modules page. + */ +function advanced_help_form_system_modules_alter(&$form, &$form_state) { + $advanced_help_modules = drupal_map_assoc(array_keys(advanced_help_get_topics())); + foreach (element_children($form['modules']) as $group) { + foreach (element_children($form['modules'][$group]) as $module) { + if (isset($advanced_help_modules[$module])) { + $form['modules'][$group][$module]['links']['help'] = array( + '#type' => 'link', + '#title' => t('Help'), + '#href' => "admin/advanced_help/$module", + '#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => t('Help'))), + ); + } + } + } +} + +/** + * Form builder callback to build the search form. + * + * Load search/search.pages so that its template preprocess functions are + * visible and can be invoked. + */ +function advanced_help_search_form($form, &$form_state, $keys = '') { + module_load_include('inc', 'search', 'search.pages'); + $form = search_form($form, $form_state, advanced_help_url('admin/advanced_help'), $keys, 'advanced_help', t('Search help')); + + $form['basic']['inline']['submit']['#validate'] = array('search_form_validate'); + $form['basic']['inline']['submit']['#submit'] = array('advanced_help_search_form_submit'); + + return $form; +} + +/** + * Process a search form submission. + */ +function advanced_help_search_form_submit($form, &$form_state) { + $keys = $form_state['values']['processed_keys']; + if ($keys == '') { + form_set_error('keys', t('Please enter some keywords.')); + return; + } + + $popup = !empty($_GET['popup']) && user_access('view advanced help popup'); + + if ($popup) { + $form_state['redirect'] = array('advanced_help/search/' . $keys, array('query' => array('popup' => 'true'))); + } + else { + $form_state['redirect'] = 'advanced_help/search/' . $keys; + } +} + +/** + * Small helper function to get a module's proper name. + * + * @param $module string + * @return string + */ +function advanced_help_get_module_name($module) { + $settings = advanced_help_get_settings(); + if (isset($settings[$module]['name'])) { + $name = $settings[$module]['name']; + } + else { + $info = db_query("SELECT s.info FROM {system} s WHERE s.name = :name", + array(':name' => $module)) + ->fetchField(); + $info = unserialize($info); + $name = t($info['name']); + } + return $name; +} + +/** + * Page callback to view a help topic. + */ +function advanced_help_topic_page($module, $topic) { + $info = advanced_help_get_topic($module, $topic); + if (!$info) { + return drupal_not_found(); + } + + $popup = !empty($_GET['popup']) && user_access('view advanced help popup'); + + drupal_set_title($info['title']); + + // Set up breadcrumb. + $breadcrumb = array(); + + $parent = $info; + $pmodule = $module; + + // Loop checker. + $checked = array(); + while (!empty($parent['parent'])) { + if (strpos($parent['parent'], '%')) { + list($pmodule, $ptopic) = explode('%', $parent['parent']); + } + else { + $ptopic = $parent['parent']; + } + + if (!empty($checked[$pmodule][$ptopic])) { + break; + } + $checked[$pmodule][$ptopic] = TRUE; + + $parent = advanced_help_get_topic($pmodule, $ptopic); + if (!$parent) { + break; + } + + $breadcrumb[] = advanced_help_l($parent['title'], "help/$pmodule/$ptopic"); + } + + $breadcrumb[] = advanced_help_l(advanced_help_get_module_name($pmodule), "admin/advanced_help/$pmodule"); + $breadcrumb[] = advanced_help_l(t('Help'), "admin/advanced_help"); + + $output = advanced_help_view_topic($module, $topic, $popup); + if (empty($output)) { + $output = t('Missing help topic.'); + } + + if ($popup) { + $GLOBALS['devel_shutdown'] = FALSE; // Prevent devel module from spewing. + module_invoke('admin_menu', 'suppress'); // Suppress admin_menu. + drupal_set_breadcrumb(array_reverse($breadcrumb)); + print theme('advanced_help_popup', array('content' => $output)); + return; + } + + drupal_add_css(drupal_get_path('module', 'advanced_help') . '/help.css'); + $breadcrumb[] = l(t('Home'), ''); + drupal_set_breadcrumb(array_reverse($breadcrumb)); + return $output; +} + +/** + * Implements hook_permission(). + */ +function advanced_help_permission() { + return array( + 'view advanced help topic' => array('title' => t('View help topics')), + 'view advanced help popup' => array('title' => t('View help popups')), + 'view advanced help index' => array('title' => t('View help index')), + ); +} + +/** + * Display a help icon with a link to view the topic in a popup. + * + * @param $variables + * An associative array containing: + * - module: The module that owns this help topic. + * - topic: The identifier for the topic + * - type + * - 'icon' to display the question mark icon + * - 'title' to display the topic's title + * - any other text to display the text. Be sure to t() it! + */ +function theme_advanced_help_topic($variables) { + $module = $variables['module']; + $topic = $variables['topic']; + $type = $variables['type']; + + $info = advanced_help_get_topic($module, $topic); + if (!$info) { + return; + } + + switch ($type) { + case 'icon': + $text = '<span>' . t('Help') . '</span>'; + $class = 'advanced-help-link'; + break; + + case 'title': + $text = $info['title']; + $class = 'advanced-help-title'; + break; + + default: + $class = 'advanced-help-title'; + $text = $type; + break; + } + + if (user_access('view advanced help popup')) { + drupal_add_css(drupal_get_path('module', 'advanced_help') . '/help-icon.css'); + return l($text, "help/$module/$topic", array( + 'attributes' => array( + 'class' => $class, + 'onclick' => "var w=window.open(this.href, 'advanced_help_window', 'width=" . $info['popup width'] . ",height=" . $info['popup height'] . ",scrollbars,resizable'); w.focus(); return false;", + 'title' => $info['title'] + ), + 'query' => array('popup' => TRUE), + 'html' => TRUE) + ); + } + else { + return l($text, "help/$module/$topic", array( + 'attributes' => array( + 'class' => $class, + 'title' => $info['title'] + ), + 'html' => TRUE) + ); + } +} + +/** + * Load and render a help topic. + */ +function advanced_help_get_topic_filename($module, $topic) { + $info = advanced_help_get_topic_file_info($module, $topic); + if ($info) { + return "./$info[path]/$info[file]"; + } +} +/** + * Load and render a help topic. + */ +function advanced_help_get_topic_file_info($module, $topic) { + global $language; + + $info = advanced_help_get_topic($module, $topic); + if (empty($info)) { + return; + } + + // Search paths: + $paths = array( + path_to_theme() . '/help', // Allow theme override. + drupal_get_path('module', $module) . "/translations/help/$language->language", // Translations. + $info['path'], // In same directory as .inc file. + ); + + foreach ($paths as $path) { + if (file_exists("./$path/$info[file]")) { + return array('path' => $path, 'file' => $info['file']); + } + } +} + +/** + * Load and render a help topic. + * + * @param string $module + * @param string $topic + * @param boolean $popup + * @return array + */ +function advanced_help_view_topic($module, $topic, $popup = FALSE) { + $file_info = advanced_help_get_topic_file_info($module, $topic); + if ($file_info) { + $info = advanced_help_get_topic($module, $topic); + $file = "./$file_info[path]/$file_info[file]"; + + $output = file_get_contents($file); + if (isset($info['readme file']) && $info['readme file']) { + // Readme files are treated as plain text: filter accordingly. + $output = check_plain($output); + } + + // Make some exchanges. The strtr is because url() translates $ into %24 + // but we need to change it back for the regex replacement. + + // Change 'topic:' to the URL for another help topic. + if ($popup) { + $output = preg_replace('/href="topic:([^"]+)"/', 'href="' . strtr(url('help/$1', array('query' => array('popup' => 'true'))), array('%24' => '$')) . '"', $output); + $output = preg_replace('/src="topic:([^"]+)"/', 'src="' . strtr(url('help/$1', array('query' => array('popup' => 'true'))), array('%24' => '$')) . '"', $output); + $output = preg_replace('/&topic:([^"]+)&/', strtr(url('help/$1', array('query' => array('popup' => 'true'))), array('%24' => '$')) , $output); + } + else { + $output = preg_replace('/href="topic:([^"]+)"/', 'href="' . strtr(url('help/$1'), array('%24' => '$')) . '"', $output); + $output = preg_replace('/src="topic:([^"]+)"/', 'src="' . strtr(url('help/$1'), array('%24' => '$')) . '"', $output); + $output = preg_replace('/&topic:([^"]+)&/', strtr(url('help/$1'), array('%24' => '$')), $output); + } + + global $base_path; + + // Change 'path:' to the URL to the base help directory. + $output = preg_replace('/href="path:([^"]+)"/', 'href="' . $base_path . $info['path'] . '/$1"', $output); + $output = preg_replace('/src="path:([^"]+)"/', 'src="' . $base_path . $info['path'] . '/$1"', $output); + $output = str_replace('&path&', $base_path . $info['path'] . '/', $output); + + // Change 'trans_path:' to the URL to the actual help directory. + $output = preg_replace('/href="trans_path:([^"]+)"/', 'href="' . $base_path . $file_info['path'] . '/$1"', $output); + $output = preg_replace('/src="trans_path:([^"]+)"/', 'src="' . $base_path . $file_info['path'] . '/$1"', $output); + $output = str_replace('&trans_path&', $base_path . $file_info['path'] . '/', $output); + + // Change 'base_url:' to the URL to the site. + $output = preg_replace('/href="base_url:([^"]+)"/', 'href="' . strtr(url('$1'), array('%24' => '$')) . '"', $output); + $output = preg_replace('/src="base_url:([^"]+)"/', 'src="' . strtr(url('$1'), array('%24' => '$')) . '"', $output); + $output = preg_replace('/&base_url&([^"]+)"/', strtr(url('$1'), array('%24' => '$')) . '"', $output); + + // Run the line break filter if requested + if (!empty($info['line break'])) { + // Remove the header since it adds an extra <br /> to the filter. + $output = preg_replace('/^<!--[^\n]*-->\n/', '', $output); + + $output = _filter_autop($output); + } + + if (!empty($info['navigation'])) { + $topics = advanced_help_get_topics(); + advanced_help_get_topic_hierarchy($topics); + if (!empty($topics[$module][$topic]['children'])) { + $items = advanced_help_get_tree($topics, $topics[$module][$topic]['children']); + $output .= theme('item_list', array('items' => $items)); + } + + list($parent_module, $parent_topic) = $topics[$module][$topic]['_parent']; + if ($parent_topic) { + $parent = $topics[$module][$topic]['_parent']; + $up = "help/$parent[0]/$parent[1]"; + } + else { + $up = "admin/advanced_help/$module"; + } + + $siblings = $topics[$parent_module][$parent_topic]['children']; + uasort($siblings, 'advanced_help_uasort'); + $prev = $next = NULL; + $found = FALSE; + foreach ($siblings as $sibling) { + list($sibling_module, $sibling_topic) = $sibling; + if ($found) { + $next = $sibling; + break; + } + if ($sibling_module == $module && $sibling_topic == $topic) { + $found = TRUE; + continue; + } + $prev = $sibling; + } + + if ($prev || $up || $next) { + $navigation = '<div class="help-navigation clear-block">'; + + if ($prev) { + $navigation .= advanced_help_l('<< ' . $topics[$prev[0]][$prev[1]]['title'], "help/$prev[0]/$prev[1]", array('attributes' => array('class' => 'help-left'))); + } + if ($up) { + $navigation .= advanced_help_l(t('Up'), $up, array('attributes' => array('class' => $prev ? 'help-up' : 'help-up-noleft'))); + } + if ($next) { + $navigation .= advanced_help_l($topics[$next[0]][$next[1]]['title'] . ' >>', "help/$next[0]/$next[1]", array('attributes' => array('class' => 'help-right'))); + } + + $navigation .= '</div>'; + + $output .= $navigation; + } + } + + if (!empty($info['css'])) { + drupal_add_css($info['path'] . '/' . $info['css']); + } + + $output = '<div class="advanced-help-topic">' . $output . '</div>'; + drupal_alter('advanced_help_topic', $output, $popup); + return $output; + } +} + +/** + * Get the information for a single help topic. + */ +function advanced_help_get_topic($module, $topic) { + $topics = advanced_help_get_topics(); + if (!empty($topics[$module][$topic])) { + return $topics[$module][$topic]; + } +} + +/** + * Search the system for all available help topics. + */ +function advanced_help_get_topics() { + $cache = _advanced_help_parse_ini(); + return $cache['topics']; +} + +function advanced_help_get_settings() { + $cache = _advanced_help_parse_ini(); + return $cache['settings']; +} + +function _advanced_help_parse_ini() { + static $cache = NULL; + + if (!isset($cache)) { + $cache = array('topics' => array(), 'settings' => array()); + + $help_path = drupal_get_path('module', 'advanced_help') . '/modules'; + foreach (module_list() as $module) { + $module_path = drupal_get_path('module', $module); + $info = array(); + if (file_exists("$module_path/help/$module.help.ini")) { + $path = "$module_path/help"; + $info = parse_ini_file("./$module_path/help/$module.help.ini", TRUE); + } + elseif (file_exists("$help_path/$module/$module.help.ini")) { + $path = "$help_path/$module"; + $info = parse_ini_file("./$help_path/$module/$module.help.ini", TRUE); + } + elseif (!file_exists("$module_path/help")) { + // Look for one or more README files. + $files = file_scan_directory("./$module_path", + '/^(README|readme).*\.(txt|TXT)$/', array('.', '..', 'CVS'), + 0, FALSE); + $path = "./$module_path"; + foreach ($files as $name => $fileinfo) { + $info[$fileinfo->filename] = array( + 'line break' => TRUE, + 'readme file' => TRUE, + 'file' => $fileinfo->filename, + 'title' => $fileinfo->name, + ); + } + } + + if (!empty($info)) { + // Get translated titles: + global $language; + $translation = array(); + if (file_exists("$module_path/translations/help/$language->language/$module.help.ini")) { + $translation = parse_ini_file("$module_path/translations/help/$language->language/$module.help.ini", TRUE); + } + + $cache['settings'][$module] = array(); + if (!empty($info['advanced help settings'])) { + $cache['settings'][$module] = $info['advanced help settings']; + unset($info['advanced help settings']); + + // Check translated strings for translatable global settings. + if (isset($translation['advanced help settings']['name'])) { + $cache['settings']['name'] = $translation['advanced help settings']['name']; + } + if (isset($translation['advanced help settings']['index name'])) { + $cache['settings']['index name'] = $translation['advanced help settings']['index name']; + } + + } + + foreach ($info as $name => $topic) { + // Each topic should have a name, a title, a file and of course the path. + $file = !empty($topic['file']) ? $topic['file'] : $name; + $cache['topics'][$module][$name] = array( + 'name' => $name, + 'title' => !empty($translation[$name]['title']) ? $translation[$name]['title'] : $topic['title'], + 'weight' => isset($topic['weight']) ? $topic['weight'] : 0, + 'parent' => isset($topic['parent']) ? $topic['parent'] : 0, + 'popup width' => isset($topic['popup width']) ? $topic['popup width'] : 500, + 'popup height' => isset($topic['popup height']) ? $topic['popup height'] : 500, + 'file' => isset($topic['readme file']) ? $file : $file . '.html', // require extension + 'path' => $path, // not in .ini file + 'line break' => isset($topic['line break']) ? $topic['line break'] : (isset($cache['settings'][$module]['line break']) ? $cache['settings'][$module]['line break'] : FALSE), + 'navigation' => isset($topic['navigation']) ? $topic['navigation'] : (isset($cache['settings'][$module]['navigation']) ? $cache['settings'][$module]['navigation'] : TRUE), + 'css' => isset($topic['css']) ? $topic['css'] : (isset($cache['settings'][$module]['css']) ? $cache['settings'][$module]['css'] : NULL), + 'readme file' => isset($topic['readme file']) ? $topic['readme file'] : FALSE, + ); + } + } + } + drupal_alter('advanced_help_topic_info', $cache); + } + return $cache; +} + +/** + * Implements hook_search_info(). + * + * @return array + */ +function advanced_help_search_info() { + return array( + 'title' => t('Help'), + 'path' => 'advanced_help', + ); +} + +/** + * Implements hook_search_execute(). + */ +function advanced_help_search_execute($keys = NULL) { + $topics = advanced_help_get_topics(); + + $query = db_select('search_index', 'i', array('target' => 'slave')) + ->extend('SearchQuery') + ->extend('PagerDefault'); + $query->join('advanced_help_index', 'ahi', 'i.sid = ahi.sid'); + $query->searchExpression($keys, 'help'); + + // Only continue if the first pass query matches. + if (!$query->executeFirstPass()) { + return array(); + } + + $results = array(); + + $find = $query->execute(); + foreach ($find as $item) { + $sids[] = $item->sid; + } + + $query = db_select('advanced_help_index', 'ahi'); + $result = $query + ->fields('ahi') + ->condition('sid', $sids, 'IN') + ->execute(); + + foreach ($result as $sid) { + // Guard against removed help topics that are still indexed. + if (empty($topics[$sid->module][$sid->topic])) { + continue; + } + $info = $topics[$sid->module][$sid->topic]; + $text = advanced_help_view_topic($sid->module, $sid->topic); + $results[] = array( + 'link' => advanced_help_url("help/$sid->module/$sid->topic"), + 'title' => $info['title'], + 'snippet' => search_excerpt($keys, $text), + ); + } + return $results; +} + +/** + * Implements hook_search_reset(). + */ +function advanced_help_search_reset() { + variable_del('advanced_help_last_cron'); +} + +/** + * Implements hook_search_status(). + */ +function advanced_help_search_status() { + $topics = advanced_help_get_topics(); + $total = 0; + foreach ($topics as $module => $module_topics) { + foreach ($module_topics as $topic => $info) { + $file = advanced_help_get_topic_filename($module, $topic); + if ($file) { + $total++; + } + } + } + + $last_cron = variable_get('advanced_help_last_cron', array('time' => 0)); + $indexed = 0; + if ($last_cron['time'] != 0) { + $indexed = db_query("SELECT COUNT(*) FROM {search_dataset} sd WHERE sd.type = 'help' AND sd.sid IS NOT NULL AND sd.reindex = 0")->fetchField(); + } + return array('remaining' => $total - $indexed, 'total' => $total); +} + +/** + * Get or create an sid (search id) that correllates to each topic for + * the search system. + */ +function advanced_help_get_sids(&$topics) { + global $language; + $result = db_query("SELECT * FROM {advanced_help_index} WHERE language = :language", + array(':language' => $language->language)); + foreach ($result as $sid) { + if (empty($topics[$sid->module][$sid->topic])) { + db_query("DELETE FROM {advanced_help_index} WHERE sid = :sid", + array(':sid' => $sid->sid)); + } + else { + $topics[$sid->module][$sid->topic]['sid'] = $sid->sid; + } + } +} + +/** + * Implements hook_update_index(). + */ +function advanced_help_update_index() { + global $language; + + // If we got interrupted by limit, this will contain the last module + // and topic we looked at. + $last = variable_get('advanced_help_last_cron', array('time' => 0)); + $limit = intval(variable_get('search_cron_limit', 100)); + $topics = advanced_help_get_topics(); + advanced_help_get_sids($topics); + + $count = 0; + + foreach ($topics as $module => $module_topics) { + // Fast forward if necessary. + if (!empty($last['module']) && $last['module'] != $module) { + continue; + } + + foreach ($module_topics as $topic => $info) { + // Fast forward if necessary. + if (!empty($last['topic']) && $last['topic'] != $topic) { + continue; + } + + // If we've been looking to catch up, and we have, reset so we + // stop fast forwarding. + if (!empty($last['module'])) { + unset($last['topic']); + unset($last['module']); + } + + $file = advanced_help_get_topic_filename($module, $topic); + if ($file && (empty($info['sid']) || filemtime($file) > $last['time'])) { + if (empty($info['sid'])) { + $info['sid'] = db_insert('advanced_help_index') + ->fields(array( + 'module' => $module, + 'topic' => $topic, + 'language' => $language->language, + )) + ->execute(); + } + + search_index($info['sid'], 'help', '<h1>' . $info['title'] . '</h1>' . file_get_contents($file)); + $count++; + if ($count >= $limit) { + $last['topic'] = $topic; + $last['module'] = $module; + // Don't change time if we stop. + variable_set('advanced_help_last_cron', $last); + return; + } + } + } + } + + variable_set('advanced_help_last_cron', array('time' => time())); +} + +/** + * Fill in a bunch of page variables for our specialized popup page. + */ +function template_preprocess_advanced_help_popup(&$variables) { + // Add favicon. + if (theme_get_setting('toggle_favicon')) { + drupal_add_html_head('<link rel="shortcut icon" href="' . check_url(theme_get_setting('favicon')) . '" type="image/x-icon" />'); + } + + global $theme; + // Construct page title. + if (drupal_get_title()) { + $head_title = array(strip_tags(drupal_get_title()), variable_get('site_name', 'Drupal')); + } + else { + $head_title = array(variable_get('site_name', 'Drupal')); + if (variable_get('site_slogan', '')) { + $head_title[] = variable_get('site_slogan', ''); + } + } + + drupal_add_css(drupal_get_path('module', 'advanced_help') . '/help-popup.css'); + drupal_add_css(drupal_get_path('module', 'advanced_help') . '/help.css'); + + $variables['head_title'] = implode(' | ', $head_title); + $variables['base_path'] = base_path(); + $variables['front_page'] = url(); + $variables['breadcrumb'] = theme('breadcrumb', array('breadcrumb' => drupal_get_breadcrumb())); + $variables['feed_icons'] = drupal_get_feeds(); + $variables['head'] = drupal_get_html_head(); + $variables['language'] = $GLOBALS['language']; + $variables['language']->dir = $GLOBALS['language']->direction ? 'rtl' : 'ltr'; + $variables['logo'] = theme_get_setting('logo'); + $variables['messages'] = theme('status_messages'); + $variables['site_name'] = (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : ''); + $variables['css'] = drupal_add_css(); + $css = drupal_add_css(); + + // Remove theme css. + foreach ($css as $media => $types) { + if (isset($css[$media]['theme'])) { + $css[$media]['theme'] = array(); + } + } + + $variables['styles'] = drupal_get_css($css); + $variables['scripts'] = drupal_get_js(); + $variables['title'] = drupal_get_title(); + + // this function can be called either with a render array or an already rendered string + if (is_array($variables['content'])) { + $variables['content'] = drupal_render($variables['content']); + } + // Closure should be filled last. + $variables['closure'] = theme('closure'); +} + +/** + * Format a link but preserve popup identity. + */ +function advanced_help_l($text, $dest, $options = array()) { + $popup = !empty($_GET['popup']) && user_access('view advanced help popup'); + if ($popup) { + if (empty($options['query'])) { + $options['query'] = array(); + } + + if (is_array($options['query'])) { + $options['query'] += array('popup' => TRUE); + } + else { + $options['query'] += '&popup=TRUE'; + } + } + + return l($text, $dest, $options); +} + +/** + * Format a URL but preserve popup identity. + */ +function advanced_help_url($dest, $options = array()) { + $popup = !empty($_GET['popup']) && user_access('view advanced help popup'); + if ($popup) { + if (empty($options['query'])) { + $options['query'] = array(); + } + + $options['query'] += array('popup' => TRUE); + } + + return url($dest, $options); +} diff --git a/sites/all/modules/advanced_help/help-icon.css b/sites/all/modules/advanced_help/help-icon.css new file mode 100644 index 0000000000000000000000000000000000000000..490dc15d56301bf7da6e7c15ed3e20fa1a4e85dc --- /dev/null +++ b/sites/all/modules/advanced_help/help-icon.css @@ -0,0 +1,20 @@ +/* $Id: help-icon.css,v 1.5 2008/10/17 19:38:00 merlinofchaos Exp $ */ + +.advanced-help-link { + width: 12px; + height: 12px; + background: transparent url('help.png') no-repeat top left; + background-position: 0px 0px; + display: block; + float: left; /* this is cheesy, I know */ + margin-top: 2px; + padding: 0px; +} + +.advanced-help-link span { + display: none; +} + +.advanced-help-link:hover { + background-position: 0px -12px; +} \ No newline at end of file diff --git a/sites/all/modules/advanced_help/help-popup.css b/sites/all/modules/advanced_help/help-popup.css new file mode 100644 index 0000000000000000000000000000000000000000..2127aea83dec5bfc60d8289967299a7d24b14227 --- /dev/null +++ b/sites/all/modules/advanced_help/help-popup.css @@ -0,0 +1,115 @@ +/* $Id: help-popup.css,v 1.4 2008/04/28 20:40:59 merlinofchaos Exp $ */ + +body { + margin: 0; + padding: 0; + background: #edf5fa; + font: 12px/170% Verdana, sans-serif; + color: #494949; +} + +input { + font: 12px/100% Verdana, sans-serif; + color: #494949; +} + +textarea, select { + font: 12px/160% Verdana, sans-serif; + color: #494949; +} + +h1, h2, h3, h4, h5, h6 { + margin: 0; + padding: 0; + font-weight: normal; + font-family: Helvetica, Arial, sans-serif; +} + +h1 { + font-size: 170%; +} + +h2 { + font-size: 160%; + line-height: 130%; +} + +h3 { + font-size: 140%; +} + +h4 { + font-size: 130%; +} + +h5 { + font-size: 120%; +} + +h6 { + font-size: 110%; +} + +ul, quote, code, fieldset { + margin: .5em 0; +} + +p { + margin: 0.6em 0 1.2em; + padding: 0; +} + +a:link, a:visited { + color: #027AC6; + text-decoration: none; +} + +a:hover { + color: #0062A0; + text-decoration: underline; +} + +a:active, a.active { + color: #5895be; +} + +hr { + margin: 0; + padding: 0; + border: none; + height: 1px; + background: #5294c1; +} + +ol li, ul li { + margin: 0.4em 0 0.4em .5em; /* LTR */ +} + + +#content { + margin: .5em 1em 1em 1em; +} + +#content #page-title { + padding-bottom: .5em; +} + +div#breadcrumb { + padding-left: 1em; + background-color: white; + border-bottom: 1px solid #ccc; + height: 2em; +} + +div#breadcrumb .breadcrumb { + padding: 0; + margin: 0; +} + +code, pre { + border: 1px solid #444; + background: #f1f1f1; + margin: 1em; + padding: .2em; + display: block; +} diff --git a/sites/all/modules/advanced_help/help.css b/sites/all/modules/advanced_help/help.css new file mode 100644 index 0000000000000000000000000000000000000000..eb096668e1077c9a081fb5b72975d146697b1f33 --- /dev/null +++ b/sites/all/modules/advanced_help/help.css @@ -0,0 +1,69 @@ +/* $Id: help.css,v 1.7 2008/10/17 19:13:03 merlinofchaos Exp $ */ + +.advanced-help-topic code, .advanced-help-topic pre { + border: 1px solid #444; + background: #f1f1f1; + margin: 1em; + padding: .2em; + display: block; +} + +.advanced-help-topic h3, +.advanced-help-topic h4, +.advanced-help-topic h5, +.advanced-help-topic h6, +.advanced-help-topic dt { + font-weight: bold; +} + +.advanced-help-topic li h3, +.advanced-help-topic li h4, +.advanced-help-topic li h5, +.advanced-help-topic li h6 { + font-weight: normal; +} + +.help-left { + text-align: left; + width: 42%; + display: block; + float: left; /* LTR */ +} + +.help-up { + margin: 0 5%; + width: 4%; + display: block; + float: left; /* LTR */ +} + +.help-up-noleft { + margin: 0 5%; + width: 42%; + text-align: right; + display: block; + float: left; /* LTR */ +} + +.help-right { + text-align: right; + width: 42%; + display: block; + float: right; +} + +.help-box { + margin: .5em; +} + +.help-navigation { + border-top: 1px dotted #ccc; +} + +.help-previous { + float: left; +} + +.help-next { + float: right; +} diff --git a/sites/all/modules/advanced_help/help.png b/sites/all/modules/advanced_help/help.png new file mode 100644 index 0000000000000000000000000000000000000000..7645023a6cd23b71a728376bd7352989020b90d0 Binary files /dev/null and b/sites/all/modules/advanced_help/help.png differ diff --git a/sites/all/modules/advanced_help/help/advanced_help.help.ini b/sites/all/modules/advanced_help/help/advanced_help.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..dad69a598af427da24af6a18983434b9fd7db4d7 --- /dev/null +++ b/sites/all/modules/advanced_help/help/advanced_help.help.ini @@ -0,0 +1,16 @@ +; $Id: advanced_help.help.ini,v 1.4 2008/09/16 00:26:08 merlinofchaos Exp $ + +[using-advanced-help] +title = Using advanced help +weight = -10 + +[translation] +title = Translating advanced help + +[ini-file] +title = Help .ini file format +line break = TRUE + +[why-advanced-help] +title = Why advanced help? +line break = TRUE diff --git a/sites/all/modules/advanced_help/help/ini-file.html b/sites/all/modules/advanced_help/help/ini-file.html new file mode 100644 index 0000000000000000000000000000000000000000..b23481f87842c5044f28ea6afe280e54c620fdfe --- /dev/null +++ b/sites/all/modules/advanced_help/help/ini-file.html @@ -0,0 +1,54 @@ +<!-- $Id: ini-file.html,v 1.8 2008/10/27 22:27:03 merlinofchaos Exp $ --> +The advanced help configuration file is in simple .ini file format, divided into sections for each help file, plus an optional section for global settings that might be inherited for each help file. + +The first line of an advanced help ini file should be ;$Id $ which will be a comment providing the CVS identifier for the file. The ; indicates a comment character. Anything after the ; will be ignored. + +Global settings may be put into a section named <strong>[advanced help settings]</strong> -- this means that this name is reserved and it cannot be a help file in any module. The following settings may be set in this section: +<dl> +<dt><strong>line break</strong></dt> +<dd>If set to any value, the line break filter will be applied to all help files defined by this module, unless that help file specifically is set otherwise. By default, the line break filter is not applied; however, help files can be much easier to write with the line break filter on.</dd> +<dt><strong>navigation</strong></dt> +<dd>If set to true, the navigation will be displayed at the end of the help topic: previous topic, next topic, and child topics.</dd> +<dt><strong>css</strong></dt> +<dd>Specify a css file that will be used for all help files (unless overridden), including the .css extension. This .css file must reside in the help directory along with the .html files, and will not be affected by translation.</dd> +<dt><strong>name</strong></dt> +<dd>May be set to override the module name as displayed in both the module index as well as the navigation and breadcrumb trail. In general this does not need to be set, but a few modules may want to use a more friendly name than appears in the .info file.</dd> +<dt><strong>index name</strong></dt> +<dd>This may be set to change the name of the module in the module index. It overrides the 'name' setting above, as well as the module name in its .info file.</dd> +<dt><strong>hide</strong></dt> +<dd>This may be used to hide a module in the module index. This is particularly useful for modules who insert their help files into the hierarchy of another module, as might be done by modules that extend Views or CCK. By setting "hide = TRUE" the module will not appear as its own entry.</dd> +</dl> + +Each section after that will correspond to a single help file, and each one may have the following settings: +<dl> +<dt><strong>title</strong></dt> +<dd>The title of the topic, presented to the user and used in links. If you have special characters in your title, be sure to enclose it in quotes.</dd> +<dt><strong>file</strong></dt> +<dd>The filename, without the .html extension, used for the topic. This is optional; if not specified, the topic name wil be the file name.</dd> +<dt><strong>weight</strong></dt> +<dd>The weight, used for sorting topics on the administration page. Defaults to 0 of unspecified. Items with the same weight are sorted alphabetically.</dd> +<dt><strong>parent</strong></dt> +<dd>The topic ID to use in a hierarchy; children will be listed beneath parents in the topic list, and will have the parent in their breadcrumb trail. You may parent this topic to another module's topic by using module%topic as the identifier. For example, 'views%display' will make this a child of the 'display' topic in the 'views' module.</dd> +<dt><strong>line break</strong></dt> +<dd>If set to true, linebreaks will be converted into br and p tags automatically. If unspecified, will default to off. Set to 0 to disable the filter if this has been turned on in the global settings.</dd> +<dt><strong>css</strong></dt> +<dd>Specify a css file that will be used for this file. This .css file must reside in the help directory along with the .html files. This will override any .css file added by the global system.</dd> +<dt><strong>popup width</strong></dt> +<dd>The width in pixels of the popup window. Defaults to 500 if unspecified.</dd> +<dt><strong>popup height</strong></dt> +<dd>The height in pixels of the popup window. Defaults to 500 if unspecified.</dd> +</dl> + +For example, here is a version of the <strong>advanced_help.help.ini</strong> file: +<pre> +[using-advanced-help] +title = "Using advanced help" +weight = -10 + +[translation] +title = Translating advanced help + +[ini-file] +title = Help .ini file format +line break = TRUE +</pre> \ No newline at end of file diff --git a/sites/all/modules/advanced_help/help/translation.html b/sites/all/modules/advanced_help/help/translation.html new file mode 100644 index 0000000000000000000000000000000000000000..1ff84438f7963691a9d952e1720ec95348a3a5ec --- /dev/null +++ b/sites/all/modules/advanced_help/help/translation.html @@ -0,0 +1,10 @@ +<!-- $Id: translation.html,v 1.5 2008/10/27 22:43:28 merlinofchaos Exp $ --> +<p>To translate advanced help, first create a <b>translations/help/$language</b> directory +in the module directory. Then, copy the .ini file and all .html files from +the help directory.</p> + +<p>The .ini file only needs to keep the titles, and if there is a 'name' or 'index name' setting in the 'advanced help settings' portion, that should be retained. Any retained settings should be translated. The rest of the data in the .ini file may be discarded or ignored.</p> + +<p>Each file should then be translated in place.</p> + +<p>When translating a .html file, you will find that the <b>path</b> keyword will lead to the original directory. If you must translate items that are linked, such as images, use <b>trans_path</b> instead, which will lead to the translated directory. This will allow you to pick and choose which linked items, if any, will be translated.</p> \ No newline at end of file diff --git a/sites/all/modules/advanced_help/help/using-advanced-help.html b/sites/all/modules/advanced_help/help/using-advanced-help.html new file mode 100644 index 0000000000000000000000000000000000000000..1b7fefbd23b0024ea172b2f014041ac90613c11e --- /dev/null +++ b/sites/all/modules/advanced_help/help/using-advanced-help.html @@ -0,0 +1,46 @@ +<!-- $Id: using-advanced-help.html,v 1.6 2008/10/17 18:55:38 merlinofchaos Exp $ --> +<p>The <em>Advanced help</em> system is a pluggable system that provides advanced help facilities for Drupal and its modules. Although the advanced help does not provide general help by itself, it provides a powerful and easy framework that modules may use to provide their own help. +</p> + +<p> +Modules utilizing <em>Advanced help</em> should create a 'help' subdirectory inside their +module's directory. Place the file MODULENAME.help.ini in this subdirectory, formatted +similar to the following example: +</p> +<pre> +[buses] +title = "How buses are tied into the system" +file = buses + +[TOPIC_ID] +title = "Title of topic". +file = filename of topic, without the .html extension. +weight = How important the topic is on the index page. +parent = The optional topic parent to use in the breadcrumb, + either topic or module%topic. +</pre> + +<p> +All topics are addressed by the module providing the topic, and by the topic +id. To embed links, use the following format: +</p> +<code> +$output .= theme('advanced_help_topic', $module, $topic); +</code> + +<p>Inside your help file, link to other topics using the format <strong><a href="&topic:module/topic&"></strong>. This +format will ensure the popup status remains consistent when switching between links.</p> + +<p>Use <strong><a href="&path&example.jpg"></strong> to reference items +within the help directory, such as images you wish to embed within the help text.</p> + +<p>Use <strong><a href="&base_url&admin/settings/site-configuration"></strong> to reference any normal path in the site.</p> + +<p>If the search module is enabled, the contents of help system will be indexed on cron. If you enable new modules and wish to immediately index its help text, visit the "Administration -> Reports -> Status report" and click the "Run cron manually" link.</p> + +<p>Example: <a href="&path&nowhere.jpg">Don't click this!</a></p> + +<p>See: <a href="&topic:advanced_help/ini-file&">ini file format</a></p> + +<p><strong>NOTE: </strong> In previous versions Advanced Help did not require the &'s wrapped around the topic:, path:, and base_url: links. This +is currently still supported, but may be removed in a future version. By adding the &'s these tokens are now not limited to href="" and src="" paramaters.</p> diff --git a/sites/all/modules/advanced_help/help/why-advanced-help.html b/sites/all/modules/advanced_help/help/why-advanced-help.html new file mode 100644 index 0000000000000000000000000000000000000000..2f12dab05eafe12e386c860408c5a7db90d4f4b0 --- /dev/null +++ b/sites/all/modules/advanced_help/help/why-advanced-help.html @@ -0,0 +1,44 @@ +The advanced help system was designed to replace the original Drupal help system, which has several flaws that make it hard to create new help, hard to maintain existing help, and particularly hard to access help. + +The primary goal, then, is to increase the accessibility of help, meaning the ability of both the user and the help text author to access the needed tools to use, create, maintain and translate the help. + +This system is completely separate from Drupal's hook_help(). In Drupal 6, it actually co-exists with it; in the future, it is hoped that it will completely replace it allowing hook_help() to be deprecated and removed. + +Messages added to the top of a page are not really "help". Often these messages are an introduction to a form or a short blurb telling a user what to do with a particular page. The problem is, these messages are always there, they are easily ignored, and they come before the actual page. In general, when users are learning, they want to see the page first, then ask questions. The reverse order is much less conducive to actually teaching a user how to use something. By allowing help to be available on request, the system conforms more naturally to how most people work. + +<h3><strong>Advanced help is organized by topic</strong></h3> +With the hook_help() method, help text is organized by URL path. This is fine if you have help text describing how to use a particular page or what a particular page does, but ultimately is limiting because manuals and documentation are usually grouped by topic, and those topics are determined by the material itself. + +Advanced help allows the documentation author to organize topics as he or she sees fit; the only restriction, really, is that each individual chunk of text needs to stand on its own as a discrete topic. + +What's more, modules can insert their topics into another module's hierarchy. This would allow the Drupal core to create a task based help navigation system which allows modules insert topics into that navigation fluidly. This allows modules to continue to keep their systems separate, yet integrate into the main system. + +<h3><strong>Advanced help topics are processed HTML in their own files</strong></h3> +This separation makes it easy to find and modify. Currently, everything is lumped together in hook_help() in PHP strings that are run through t(), and there is a fair amount of PHP code necessary in this system that actually gets in the way of writing good, explanatory text. + +In fact, requiring a documentation author to understand PHP at all is a detriment. The idea that documentation writers need to have PHP development as a skill seriously reduces the number of available contributors. HTML, on the other hand, is a much more common skill, is relatively easy to learn, and the amount of HTML needed to write documentation is only a little bit more than the HTML used in forum posts. + +Another benefit to not using PHP is that the files themselves are safe. They are unlikely to include malicious PHP code that could take over the server or do worse things. This means that these files can be used relatively easily on the drupal.org hardware so that a module's help files can be made immediately available without needing to download the module. It also means that descriptions of the module can be made on drupal.org that are version aware, can be corrected easily in CVS with patches, but can also be made available with the module so that drupal.org is not required. + +This also means that we could, if we wanted, package the drupal.org handbooks, or a subset of them, directly into a drupal distribution, or a drupal add-on, so that Drupal administrators can have Drupal help without needing to visit drupal.org. This can be valuable in locked down corporate environments and on planes. But more importantly, the handbooks can be made version aware much more easily than the current method on drupal.org. + +The downside to this method is that these books can't easily be made dynamic. Though the use of alter hooks could allow a module to make modifications to the help as needed, doing this could make the help files less useful when you take them out of context. + +<h3><strong>Advanced help files are translated as a file</strong></h3> +It is actually not easy to translate documents as strings, particularly when the language being used is very much unlike English. In fact, when translating a document, the organization of the sentences may change drastically. It is also a burden on the CPU to do this, as you are indexing on very long strings. + +Translators have a much better time translating a document as a unit, because of the presence of the entire context. + +<h3><strong>Advanced help has its own navigation system</strong></h3> +By making use of a navigation system specified in a .ini file (which is not PHP code and therefore safe to use on *.drupal.org sites), the help can be structured like a book, which is typical of online manuals. This is familiar to users, can be organized (and re-organized) and allows a module to include significantly richer text without burdening the PHP code with having its help loaded unnecessarily. + +This book can be navigated hierarchically as well, making it easy to keep related topics together. +<h3><strong>Advanced help is indexed by the search engine</strong></h3> +An important goal of this system was to add searchability to the help. By being able to enter keywords into the search box and find relevant topics, we come up with a system that resembles the kind of help that comes with many operating systems. This is very valuable when searching through manuals trying to find out how to do a particular thing. + +This search is specific to the help, meaning that the help will not be mixed in with the global node search. This can be considered both an advantage and a disadvantage. For the most part, this help system is meant to provide help to site administrators, and content searches should not find it. The disadvantage, of course, is when you want to use it for end user help, you will not be able to. + +<h3><strong>Inline help can be brought in via popups</strong></h3> +In addition to the manual-like hierarchical navigation, advanced help can also provide context-sensitive additional help through a popup. While popups are controversial, the argument for using them is that when getting help while on a form, <i>a popup will not throw away a user's data.</i> Browsers are not very friendly to input forms if they are not submitted, and navigating away from the form can be dangerous. There are various other solutions to this problem, but each one has a drawback. The drawbacks to popups are well known, but mostly it is the irritation of having new windows. When getting help, though, a popup is usually invited. Help should not interfere with what the operation the user is trying to complete. It differs greatly from the uninvited popup, which are usually ads or popups meant to prevent users from navigating away from a site. + +These popups can be added to a page with text links or icon links. diff --git a/sites/all/modules/advanced_help/help_example/help/180px-Andi_Gutmans_1.jpg b/sites/all/modules/advanced_help/help_example/help/180px-Andi_Gutmans_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b182676fb36ab854729ab629c93be7539866a63a Binary files /dev/null and b/sites/all/modules/advanced_help/help_example/help/180px-Andi_Gutmans_1.jpg differ diff --git a/sites/all/modules/advanced_help/help_example/help/180px-Lerdorf.jpg b/sites/all/modules/advanced_help/help_example/help/180px-Lerdorf.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5a437f468b598b6fd9cef745864a963aa89c7eb8 Binary files /dev/null and b/sites/all/modules/advanced_help/help_example/help/180px-Lerdorf.jpg differ diff --git a/sites/all/modules/advanced_help/help_example/help/180px-PHP_Hello_World_screenshot.png b/sites/all/modules/advanced_help/help_example/help/180px-PHP_Hello_World_screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..38f33b81e1d9a6080452ac79b9fc2a2bea34f004 Binary files /dev/null and b/sites/all/modules/advanced_help/help_example/help/180px-PHP_Hello_World_screenshot.png differ diff --git a/sites/all/modules/advanced_help/help_example/help/about-php.html b/sites/all/modules/advanced_help/help_example/help/about-php.html new file mode 100644 index 0000000000000000000000000000000000000000..f19f30c14ae1b098efd8396a182cc0a662e1de9c --- /dev/null +++ b/sites/all/modules/advanced_help/help_example/help/about-php.html @@ -0,0 +1,5 @@ +<p><b>PHP</b> (<i>PHP: Hypertext Preprocessor</i>) is a computer <a target="_blank" href="http://en.wikipedia.org/wiki/Scripting_language" title="Scripting language">scripting language</a>, originally designed for producing <a target="_blank" href="http://en.wikipedia.org/wiki/Dynamic_web_page" title="Dynamic web page">dynamic web pages</a>. It is mainly used in <a target="_blank" href="http://en.wikipedia.org/wiki/Server-side_scripting" title="Server-side scripting">server-side scripting</a>, but can be used from a <a target="_blank" href="http://en.wikipedia.org/wiki/Command_line_interface" title="Command line interface">command line interface</a> or in <a target="_blank" href="http://en.wikipedia.org/wiki/Standalone" title="Standalone">standalone</a> <a target="_blank" href="http://en.wikipedia.org/wiki/Graphical_user_interface" title="Graphical user interface">graphical applications</a>.<sup id="cite_ref-1" class="reference"><a href="#cite_note-1" title="">[2]</a></sup></p> + +<p>While PHP was originally created by <a target="_blank" href="http://en.wikipedia.org/wiki/Rasmus_Lerdorf" title="Rasmus Lerdorf">Rasmus Lerdorf</a> in 1994, the main implementation of PHP is now produced by The PHP Group and serves as the <a target="_blank" href="http://en.wikipedia.org/wiki/De_facto_standard" title="De facto standard"><i>de facto</i> standard</a> for PHP as there is no <a target="_blank" href="http://en.wikipedia.org/wiki/Formal_specification" title="Formal specification">formal specification</a>.<sup id="cite_ref-history_2-0" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup> Released under the <a target="_blank" href="http://en.wikipedia.org/wiki/PHP_License" title="PHP License">PHP License</a>, the <a target="_blank" href="http://en.wikipedia.org/wiki/Free_Software_Foundation" title="Free Software Foundation">Free Software Foundation</a> considers it to be <a target="_blank" href="http://en.wikipedia.org/wiki/Free_software" title="Free software">free software</a>.<sup id="cite_ref-3" class="reference"><a href="#cite_note-3" title="">[4]</a></sup></p> + +<p>PHP is a widely-used general-purpose scripting language that is especially suited for <a target="_blank" href="http://en.wikipedia.org/wiki/Web_development" title="Web development">web development</a> and can be embedded into <a target="_blank" href="http://en.wikipedia.org/wiki/HTML" title="HTML">HTML</a>. It generally runs on a <a target="_blank" href="http://en.wikipedia.org/wiki/Web_server" title="Web server">web server</a>, taking PHP code as its input and creating <a target="_blank" href="http://en.wikipedia.org/wiki/Web_page" title="Web page">web pages</a> as output. It can be deployed on most web servers and on almost every <a target="_blank" href="http://en.wikipedia.org/wiki/Operating_system" title="Operating system">operating system</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Platform_%28computing%29" class="mw-redirect" title="Platform (computing)">platform</a> free of charge.<sup id="cite_ref-foundations_4-0" class="reference"><a href="#cite_note-foundations-4" title="">[5]</a></sup> PHP is installed on more than 20 million websites and 1 million <a target="_blank" href="http://en.wikipedia.org/wiki/Server_%28computing%29" title="Server (computing)">servers</a>, although the number of websites with PHP <a target="_blank" href="http://en.wikipedia.org/wiki/Installation_%28computer_programs%29" title="Installation (computer programs)">installed</a> has declined since August 2005.<sup id="cite_ref-usage_5-0" class="reference"><a href="#cite_note-usage-5" title="">[6]</a></sup> It is also the most popular <a target="_blank" href="http://en.wikipedia.org/wiki/Apache_HTTP_Server" title="Apache HTTP Server">Apache</a> module among computers using Apache as a web server.<sup id="cite_ref-usage_5-1" class="reference"><a href="#cite_note-usage-5" title="">[6]</a></sup> The most recent major release of PHP was version 5.2.5 on <a target="_blank" href="http://en.wikipedia.org/wiki/November_8" title="November 8">November 8</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/2007" title="2007">2007</a>.<sup id="cite_ref-php5changelog_6-0" class="reference"><a href="#cite_note-php5changelog-6" title="">[7]</a></sup></p> diff --git a/sites/all/modules/advanced_help/help_example/help/help_example.help.ini b/sites/all/modules/advanced_help/help_example/help/help_example.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..83f9ec761dbdc35d3a7ba4ff6e3b31c2c7dd3a35 --- /dev/null +++ b/sites/all/modules/advanced_help/help_example/help/help_example.help.ini @@ -0,0 +1,24 @@ +[about-php] +title = About PHP +file = about-php +weight = -10 + +[history] +title = History of PHP +file = history +parent = about-php + +[usage] +title = Usage of PHP +file = usage +weight = 1 + +[security] +title = Security of PHP +file = security +weight = 2 + +[syntax] +title = PHP syntax +file = syntax +parent = usage \ No newline at end of file diff --git a/sites/all/modules/advanced_help/help_example/help/history.html b/sites/all/modules/advanced_help/help_example/help/history.html new file mode 100644 index 0000000000000000000000000000000000000000..9993403ceb2e7409022a73f1f383fc2dc5f2c2b2 --- /dev/null +++ b/sites/all/modules/advanced_help/help_example/help/history.html @@ -0,0 +1,23 @@ +<div class="help-box help-left"> +<div class="thumbinner" style="width:182px;"><a href="http://en.wikipedia.org/wiki/Image:Lerdorf.jpg" class="image" title="Rasmus Lerdorf, who wrote the original Common Gateway Interface binaries"><img alt="Rasmus Lerdorf, who wrote the original Common Gateway Interface binaries" src="path:180px-Lerdorf.jpg" width="180" height="270" border="0" class="thumbimage" /></a> +<div class="thumbcaption"> +<div class="magnify"><a href="/wiki/Image:Lerdorf.jpg" class="internal" title="Enlarge"><img src="/skins-1.5/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div> +<a href="/wiki/Rasmus_Lerdorf" title="Rasmus Lerdorf">Rasmus Lerdorf</a>, who wrote the original <a href="/wiki/Common_Gateway_Interface" title="Common Gateway Interface">Common Gateway Interface</a> binaries</div> +</div> +</div> + + +<p>PHP, standing for Personal Home Page, began as a set of <a target="_blank" href="http://en.wikipedia.org/wiki/Common_Gateway_Interface" title="Common Gateway Interface">Common Gateway Interface</a> <a target="_blank" href="http://en.wikipedia.org/wiki/Binary_file" title="Binary file">binaries</a> written in the <a target="_blank" href="http://en.wikipedia.org/wiki/C_programming_language" class="mw-redirect" title="C programming language">C programming language</a> in 1994 by the <a target="_blank" href="http://en.wikipedia.org/wiki/Danish_people" title="Danish people">Danish</a>/<a target="_blank" href="http://en.wikipedia.org/wiki/Greenland" title="Greenland">Greenlandic</a> programmer <a target="_blank" href="http://en.wikipedia.org/wiki/Rasmus_Lerdorf" title="Rasmus Lerdorf">Rasmus Lerdorf</a>. Lerdorf initially created these Personal Home Page Tools to replace a small set of <a target="_blank" href="http://en.wikipedia.org/wiki/Perl" title="Perl">Perl</a> scripts he had been using to maintain his <a target="_blank" href="http://en.wikipedia.org/wiki/Personal_homepage" class="mw-redirect" title="Personal homepage">personal homepage</a>. The tools were originally created to perform tasks such as displaying his <a target="_blank" href="http://en.wikipedia.org/wiki/R%C3%A9sum%C3%A9" title="Résumé">résumé</a> and recording how much <a target="_blank" href="http://en.wikipedia.org/wiki/Web_traffic" title="Web traffic">traffic</a> his page was receiving.<sup id="cite_ref-history_2-1" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup> He combined these binaries with his Form Interpreter to create PHP/FI, which had more functionality. It included a larger <a target="_blank" href="http://en.wikipedia.org/wiki/C_%28programming_language%29" title="C (programming language)">C implementation</a> which could communicate with <a target="_blank" href="http://en.wikipedia.org/wiki/Database" title="Database">databases</a> and helped build simple, dynamic <a target="_blank" href="http://en.wikipedia.org/wiki/Web_application" title="Web application">web applications</a>. He released PHP publicly on <a target="_blank" href="http://en.wikipedia.org/wiki/June_8" title="June 8">June 8</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/1995" title="1995">1995</a> to speed up the finding of <a target="_blank" href="http://en.wikipedia.org/wiki/Software_bug" title="Software bug">bugs</a> and improving the code.<sup id="cite_ref-7" class="reference"><a href="#cite_note-7" title="">[8]</a></sup> This release was named PHP version 2, and already had basic functionality that PHP has today. This includes Perl-like variables, form handling, and the ability to embed HTML. The syntax was similar to Perl but was more limited, simpler, and less consistent.<sup id="cite_ref-history_2-2" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup></p> + +<div class="help-box help-right"> +<div class="thumbinner" style="width:182px;"><a target="_blank" href="http://en.wikipedia.org/wiki/Image:Andi_Gutmans_1.jpg" class="image" title="Andi Gutmans, who, along with Zeev Suraski, rewrote the parser that formed PHP 3"><img alt="Andi Gutmans, who, along with Zeev Suraski, rewrote the parser that formed PHP 3" src="path:180px-Andi_Gutmans_1.jpg" width="180" height="244" border="0" class="thumbimage" /></a> +<div class="thumbcaption"> +<div class="magnify"><a target="_blank" href="http://en.wikipedia.org/wiki/Image:Andi_Gutmans_1.jpg" class="internal" title="Enlarge"><img src="/skins-1.5/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div> +<a target="_blank" href="http://en.wikipedia.org/wiki/Andi_Gutmans" title="Andi Gutmans">Andi Gutmans</a>, who, along with <a target="_blank" href="http://en.wikipedia.org/wiki/Zeev_Suraski" title="Zeev Suraski">Zeev Suraski</a>, rewrote the <a target="_blank" href="http://en.wikipedia.org/wiki/Parser" class="mw-redirect" title="Parser">parser</a> that formed PHP 3</div> +</div> +</div> +<p><a target="_blank" href="http://en.wikipedia.org/wiki/Zeev_Suraski" title="Zeev Suraski">Zeev Suraski</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Andi_Gutmans" title="Andi Gutmans">Andi Gutmans</a>, two <a target="_blank" href="http://en.wikipedia.org/wiki/Israelis" title="Israelis">Israeli</a> developers at the <a target="_blank" href="http://en.wikipedia.org/wiki/Technion_IIT" class="mw-redirect" title="Technion IIT">Technion IIT</a>, rewrote the <a target="_blank" href="http://en.wikipedia.org/wiki/Parser" class="mw-redirect" title="Parser">parser</a> in 1997 and formed the base of PHP 3, changing the language's name to the <a target="_blank" href="http://en.wikipedia.org/wiki/Recursive_initialism" class="mw-redirect" title="Recursive initialism">recursive initialism</a> <i>PHP: Hypertext Preprocessor</i>.<sup id="cite_ref-history_2-3" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup> The development team officially released PHP/FI 2 in November 1997 after months of <a target="_blank" href="http://en.wikipedia.org/wiki/Development_stage#beta" class="mw-redirect" title="Development stage">beta</a> testing. Afterwards, public testing of PHP 3 began, and the official launch came in June 1998. Suraski and Gutmans then started a new <a target="_blank" href="http://en.wikipedia.org/wiki/Rewrite_%28programming%29" title="Rewrite (programming)">rewrite</a> of PHP's core, producing the <a target="_blank" href="http://en.wikipedia.org/wiki/Zend_Engine" title="Zend Engine">Zend Engine</a> in 1999.<sup id="cite_ref-8" class="reference"><a href="#cite_note-8" title="">[9]</a></sup> They also founded <a target="_blank" href="http://en.wikipedia.org/wiki/Zend_Technologies" title="Zend Technologies">Zend Technologies</a> in <a target="_blank" href="http://en.wikipedia.org/wiki/Ramat_Gan" title="Ramat Gan">Ramat Gan</a>, Israel, which manages the development of PHP.<sup id="cite_ref-history_2-4" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup></p> + +<p>On <a target="_blank" href="http://en.wikipedia.org/wiki/May_22" title="May 22">May 22</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/2000" title="2000">2000</a>, PHP 4, powered by the Zend Engine 1.0, was released.<sup id="cite_ref-history_2-5" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup> On <a target="_blank" href="http://en.wikipedia.org/wiki/July_13" title="July 13">July 13</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/2004" title="2004">2004</a>, PHP 5 was released and is powered by the new Zend Engine II.<sup id="cite_ref-history_2-6" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup> PHP 5 included new features such as improved support for <a target="_blank" href="http://en.wikipedia.org/wiki/Object-oriented_programming" title="Object-oriented programming">object-oriented programming</a>, the PHP Data Objects extension (which defines a lightweight and consistent interface for accessing databases), and numerous performance enhancements.<sup id="cite_ref-9" class="reference"><a href="#cite_note-9" title="">[10]</a></sup> The most recent update released by The PHP Group is for the older PHP version 4 code branch. As of January 2008, this branch is up to version 4.4.8. PHP 4 will be supported by security updates until <a target="_blank" href="http://en.wikipedia.org/wiki/August_8" title="August 8">August 8</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/2008" title="2008">2008</a>.<sup id="cite_ref-2007_news_10-0" class="reference"><a href="#cite_note-2007_news-10" title="">[11]</a></sup></p> + +<p>PHP 5 is the only stable version still being developed. <a target="_blank" href="http://en.wikipedia.org/wiki/Late_static_binding" class="mw-redirect" title="Late static binding">Late static binding</a> has been missing from PHP and will be added in version 5.3.<sup id="cite_ref-11" class="reference"><a href="#cite_note-11" title="">[12]</a></sup> <sup id="cite_ref-12" class="reference"><a href="#cite_note-12" title="">[13]</a></sup> Development on PHP 4 ceased at the end of 2007, except for the critical security updates for PHP 4 already mentioned.<sup id="cite_ref-13" class="reference"><a href="#cite_note-13" title="">[14]</a></sup><sup id="cite_ref-2007_news_10-1" class="reference"><a href="#cite_note-2007_news-10" title="">[11]</a></sup> PHP 6 is now under development and major changes include the removal of <code>register_globals</code><sup id="cite_ref-14" class="reference"><a href="#cite_note-14" title="">[15]</a></sup>, <a target="_blank" href="http://en.wikipedia.org/wiki/Magic_quotes" title="Magic quotes">magic quotes</a>, and <a target="_blank" href="http://en.wikipedia.org/wiki/Safe_mode#Application_software_safe_mode" title="Safe mode">safe mode</a>.<sup id="cite_ref-2007_news_10-2" class="reference"><a href="#cite_note-2007_news-10" title="">[11]</a></sup><sup id="cite_ref-15" class="reference"><a href="#cite_note-15" title="">[16]</a></sup> PHP does not have complete native support for <a target="_blank" href="http://en.wikipedia.org/Unicode" title="Unicode">Unicode</a> or multibyte strings;<sup id="cite_ref-16" class="reference"><a href="#cite_note-16" title="">[17]</a></sup> unicode support will be added in PHP 6.<sup id="cite_ref-17" class="reference"><a href="#cite_note-17" title="">[18]</a></sup> Many high profile open source projects ceased to support PHP 4 in new code as of <a target="_blank" href="http://en.wikipedia.org/wiki/February_5" title="February 5">February 5</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/2008" title="2008">2008</a>, due to the GoPHP5 initiative, provided by a consortium of PHP developers promoting the transition from PHP 4 to PHP 5.<sup id="cite_ref-gophp5_18-0" class="reference"><a href="#cite_note-gophp5-18" title="">[19]</a></sup><sup id="cite_ref-19" class="reference"><a href="#cite_note-19" title="">[20]</a></sup></p> diff --git a/sites/all/modules/advanced_help/help_example/help/security.html b/sites/all/modules/advanced_help/help_example/help/security.html new file mode 100644 index 0000000000000000000000000000000000000000..31d43dcebdc775c4e376073488f2831ba1a29f42 --- /dev/null +++ b/sites/all/modules/advanced_help/help_example/help/security.html @@ -0,0 +1 @@ +<p>PHP is a popular target of <a target="_blank" href="http://en.wikipedia.org/wiki/Hacker" title="Hacker">hackers</a> who exploit vulnerable applications written in PHP. Software vulnerabilities related to PHP are identified among the <a target="_blank" href="http://en.wikipedia.org/wiki/Common_Vulnerabilities_and_Exposures" title="Common Vulnerabilities and Exposures">CVE (Common Vulnerabilities and Exposures)</a> records, available from the <a target="_blank" href="http://en.wikipedia.org/wiki/National_Vulnerability_Database" title="National Vulnerability Database">National Vulnerability Database</a>. The proportion of vulnerabilities related to PHP, out of the total of all common vulnerabilities, amounted to: 12% in 2003, 20% in 2004, 28% in 2005, 43% in 2006, 36% in 2007, and 33.8% for the first quarter of 2008. More than a quarter of all software vulnerabilities listed in this database are related to PHP, and more than a third of vulnerabilities listed recently. Most of these vulnerabilities can be exploited remotely, that is without being logged on the computer hosting the vulnerable application.<sup id="cite_ref-27" class="reference"><a href="#cite_note-27" title="">[28]</a></sup> Such exploitation is made possible due to poor programming habits, such as failing to check data before entering it into a database, and features of the language such as <code>register_globals</code>, which is now deprecated.<sup id="cite_ref-register_globals_21-1" class="reference"><a href="#cite_note-register_globals-21" title="">[22]</a></sup> These result in <a target="_blank" href="http://en.wikipedia.org/wiki/Code_injection" title="Code injection">code injection</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/Cross-site_scripting" title="Cross-site scripting">cross-site scripting</a> and other <a target="_blank" href="http://en.wikipedia.org/wiki/Application_security" title="Application security">application security</a> issues. It's important to note that none of these attacks are exclusive to PHP and all are avoidable by following proper coding techniques and principles.</p> diff --git a/sites/all/modules/advanced_help/help_example/help/syntax.html b/sites/all/modules/advanced_help/help_example/help/syntax.html new file mode 100644 index 0000000000000000000000000000000000000000..48d8109d1377bcdf7b7df8e5b82c7ea0f6464c7c --- /dev/null +++ b/sites/all/modules/advanced_help/help_example/help/syntax.html @@ -0,0 +1,38 @@ +<h2> <span class="mw-headline">Syntax</span></h2> +<div class="help-right"> +<div class="thumbinner" style="width:182px;"><a target="_blank" href="http://en.wikipedia.org/wiki/Image:PHP_Hello_World_screenshot.png" class="image" title="Syntax-highlighted PHP code"><img alt="Syntax-highlighted PHP code" src="path:180px-PHP_Hello_World_screenshot.png" width="180" height="87" border="0" class="thumbimage" /></a> +<div class="thumbcaption"> + +<div class="magnify"><a target="_blank" href="http://en.wikipedia.org/wiki/Image:PHP_Hello_World_screenshot.png" class="internal" title="Enlarge"><img src="/skins-1.5/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div> +<a target="_blank" href="http://en.wikipedia.org/wiki/Syntax-highlighted" class="mw-redirect" title="Syntax-highlighted">Syntax-highlighted</a> PHP code</div> +</div> +</div> +<p>PHP only parses code within its <a target="_blank" href="http://en.wikipedia.org/wiki/Delimiter" title="Delimiter">delimiters</a>. Anything outside its delimiters is sent directly to the output and is not parsed by PHP. The most common delimiters are <span s><?php</span> and <span>?></span>, which are open and close delimiters respectively. <span><script language="php"></span> and <span></script></span> delimiters are also available. Short tags (<span><?</span> or <span><?=</span> and <span>?></span>) are also commonly used, but like ASP-style tags (<span><%</span> or <span><%=</span> and <span>%></span>), they are less portable as they can be disabled in the PHP configuration. For this reason, the use of short tags and ASP-style tags is discouraged.<sup id="cite_ref-basic_syntax_28-0" class="reference"><a href="#cite_note-basic_syntax-28" title="">[29]</a></sup> The purpose of these delimiters is to separate PHP code from non-PHP code, including HTML. Everything outside the delimiters is ignored by the parser and is passed through as output.<sup id="cite_ref-29" class="reference"><a href="#cite_note-29" title="">[30]</a></sup></p> + +<p>Variables are prefixed with a <a target="_blank" href="http://en.wikipedia.org/wiki/Dollar_sign" title="Dollar sign">dollar symbol</a> and a <a target="_blank" href="http://en.wikipedia.org/wiki/Primitive_type" title="Primitive type">type</a> does not need to be specified in advance. Unlike function and class names, variable names are case sensitive. Both double-quoted (<span>""</span>) and <a target="_blank" href="http://en.wikipedia.org/wiki/Heredoc" class="mw-redirect" title="Heredoc">heredoc</a> strings allow the ability to embed the variable's value into the string.<sup id="cite_ref-30" class="reference"><a href="#cite_note-30" title="">[31]</a></sup> PHP treats <a target="_blank" href="http://en.wikipedia.org/wiki/Newline" title="Newline">newlines</a> as <a target="_blank" href="http://en.wikipedia.org/wiki/Whitespace_%28computer_science%29" title="Whitespace (computer science)">whitespace</a> in the manner of a <a target="_blank" href="http://en.wikipedia.org/wiki/Free-form_language" title="Free-form language">free-form language</a> (except when inside string quotes), and statements are terminated by a semicolon.<sup id="cite_ref-31" class="reference"><a href="#cite_note-31" title="">[32]</a></sup> PHP has three types of <a target="_blank" href="http://en.wikipedia.org/wiki/Comparison_of_programming_languages_%28syntax%29#Comments" title="Comparison of programming languages (syntax)">comment syntax</a>: <span>/* */</span> serves as block comments, and <span>//</span> as well as <span>#</span> are used for inline comments.<sup id="cite_ref-32" class="reference"><a href="#cite_note-32" title="">[33]</a></sup> To output text to the browser, either the <tt>print</tt> function or the <tt>echo</tt> function is used. Both functions are nearly identical; the major difference is that <tt>print</tt> is slower than <tt>echo</tt> because the former will return a status indicating if it was successful or not, whereas the latter does not return a status and only returns the text for output.<sup id="cite_ref-33" class="reference"><a href="#cite_note-33" title="">[34]</a></sup></p> + +<p><a name="Data_types" id="Data_types"></a></p> +<h3><span class="mw-headline">Data types</span></h3> +<p>PHP stores whole numbers in a platform-dependent range. This range is typically that of 32-bit <a target="_blank" href="http://en.wikipedia.org/wiki/Signed_number_representations" title="Signed number representations">signed</a> <a target="_blank" href="http://en.wikipedia.org/wiki/Integer_%28computer_science%29" title="Integer (computer science)">integers</a>. Unsigned integers are converted to signed values in certain situations; this behavior is different from other programming languages.<sup id="cite_ref-34" class="reference"><a href="#cite_note-34" title="">[35]</a></sup> Integer variables can be assigned using decimal (positive and negative), <a target="_blank" href="http://en.wikipedia.org/wiki/Octal" title="Octal">octal</a>, and <a target="_blank" href="http://en.wikipedia.org/wiki/Hexadecimal" title="Hexadecimal">hexadecimal</a> notations. <a target="_blank" href="http://en.wikipedia.org/wiki/Real_numbers" class="mw-redirect" title="Real numbers">Real numbers</a> are also stored in a platform-specific range. They can be specified using <a target="_blank" href="http://en.wikipedia.org/wiki/Floating_point" title="Floating point">floating point</a> notation, or two forms of <a target="_blank" href="http://en.wikipedia.org/wiki/Scientific_notation" title="Scientific notation">scientific notation</a>.<sup id="cite_ref-types_35-0" class="reference"><a href="#cite_note-types-35" title="">[36]</a></sup> PHP has a native <a target="_blank" href="http://en.wikipedia.org/wiki/Boolean_datatype" title="Boolean datatype">Boolean</a> type that is similar to the native Boolean types in <a target="_blank" href="http://en.wikipedia.org/wiki/Java_%28programming_language%29" title="Java (programming language)">Java</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/C%2B%2B" title="C++">C++</a>. Using the Boolean type conversion rules, non-zero values are interpreted as true and zero as false, as in Perl and C++.<sup id="cite_ref-types_35-1" class="reference"><a href="#cite_note-types-35" title="">[36]</a></sup> The null data type represents a variable that has no value. The only value in the null data type is <i>NULL</i>.<sup id="cite_ref-types_35-2" class="reference"><a href="#cite_note-types-35" title="">[36]</a></sup> Variables of the "resource" type represent references to resources from external sources. These are typically created by functions from a particular extension, and can only be processed by functions from the same extension; examples include file, image, and database resources.<sup id="cite_ref-types_35-3" class="reference"><a href="#cite_note-types-35" title="">[36]</a></sup> Arrays can contain elements of any type that PHP can handle, including resources, objects, and even other arrays. Order is preserved in lists of values and in <a target="_blank" href="http://en.wikipedia.org/wiki/Hash_table" title="Hash table">hashes</a> with both keys and values, and the two can be intermingled.<sup id="cite_ref-types_35-4" class="reference"><a href="#cite_note-types-35" title="">[36]</a></sup> PHP also supports <a target="_blank" href="http://en.wikipedia.org/wiki/String_%28computing%29" class="mw-redirect" title="String (computing)">strings</a>, which can be used with single quotes, double quotes, or <a target="_blank" href="http://en.wikipedia.org/wiki/Heredoc" class="mw-redirect" title="Heredoc">heredoc syntax</a>.<sup id="cite_ref-36" class="reference"><a href="#cite_note-36" title="">[37]</a></sup></p> + +<p><a name="Functions" id="Functions"></a></p> +<h3><span class="mw-headline">Functions</span></h3> +<p>PHP has hundreds of base functions and thousands more from extensions. Functions are not <a target="_blank" href="http://en.wikipedia.org/wiki/First-class_function" title="First-class function">first-class functions</a> and can only be referenced by their name. <sup id="cite_ref-functions_37-0" class="reference"><a href="#cite_note-functions-37" title="">[38]</a></sup> User-defined functions can be created at any time without being prototyped.<sup id="cite_ref-functions_37-1" class="reference"><a href="#cite_note-functions-37" title="">[38]</a></sup> Functions can be defined inside code blocks, permitting a <a target="_blank" href="http://en.wikipedia.org/wiki/Dynamic_dispatch" title="Dynamic dispatch">run-time decision</a> as to whether or not a function should be defined. Function calls must use parentheses, with the exception of zero argument class <a target="_blank" href="http://en.wikipedia.org/wiki/Constructor_%28computer_science%29" title="Constructor (computer science)">constructor</a> functions called with the PHP <span>new</span> operator, where parentheses are optional. PHP supports quasi-<a target="_blank" href="http://en.wikipedia.org/wiki/Anonymous_function" title="Anonymous function">anonymous functions</a> through the <span>create_function()</span> function, although they are not true anonymous functions because anonymous functions are nameless, but functions can only be referenced by name, or indirectly through a variable <span>$function_name();</span>, in PHP.<sup id="cite_ref-functions_37-2" class="reference"><a href="#cite_note-functions-37" title="">[38]</a></sup></p> + +<p><a name="Objects" id="Objects"></a></p> +<h3><span class="mw-headline">Objects</span></h3> +<p>Basic <a target="_blank" href="http://en.wikipedia.org/wiki/Object-oriented_programming" title="Object-oriented programming">object-oriented programming</a> functionality was added in PHP 3.<sup id="cite_ref-history_2-10" class="reference"><a href="#cite_note-history-2" title="">[3]</a></sup> Object handling was completely rewritten for PHP 5, expanding the feature set and enhancing performance.<sup id="cite_ref-php_5_objects_38-0" class="reference"><a href="#cite_note-php_5_objects-38" title="">[39]</a></sup> In previous versions of PHP, objects were handled like <a target="_blank" href="http://en.wikipedia.org/wiki/Primitive_type" title="Primitive type">primitive types</a>.<sup id="cite_ref-php_5_objects_38-1" class="reference"><a href="#cite_note-php_5_objects-38" title="">[39]</a></sup> The drawback of this method was that the whole object was copied when a variable was assigned or passed as a parameter to a method. In the new approach, objects are referenced by <a target="_blank" href="http://en.wikipedia.org/wiki/Smart_pointer#Handles" title="Smart pointer">handle</a>, and not by value. PHP 5 introduced private and protected <a target="_blank" href="http://en.wikipedia.org/wiki/Member_variable" class="mw-redirect" title="Member variable">member variables</a> and methods, along with <a target="_blank" href="http://en.wikipedia.org/wiki/Abstract_type" title="Abstract type">abstract classes</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Final_type" class="mw-redirect" title="Final type">final classes</a> as well as <a target="_blank" href="http://en.wikipedia.org/wiki/Abstract_method" class="mw-redirect" title="Abstract method">abstract methods</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Final_method" class="mw-redirect" title="Final method">final methods</a>. It also introduced a standard way of declaring <a target="_blank" href="http://en.wikipedia.org/wiki/Constructor_%28computer_science%29" title="Constructor (computer science)">constructors</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Destructor_%28computer_science%29" title="Destructor (computer science)">destructors</a>, similar to that of other object-oriented languages such as <a target="_blank" href="http://en.wikipedia.org/wiki/C%2B%2B" title="C++">C++</a>, and a standard <a target="_blank" href="http://en.wikipedia.org/wiki/Exception_handling" title="Exception handling">exception handling</a> model. Furthermore, PHP 5 added <a target="_blank" href="http://en.wikipedia.org/wiki/Interfaces" class="mw-redirect" title="Interfaces">interfaces</a> and allowed for multiple interfaces to be implemented. There are special interfaces that allow objects to interact with the runtime system. <a target="_blank" href="http://en.wikipedia.org/wiki/Object" title="Object">Objects</a> implementing <a target="_blank" href="http://en.wikipedia.org/wiki/ArrayAccess" class="mw-redirect" title="ArrayAccess">ArrayAccess</a> can be used with array syntax and <a target="_blank" href="http://en.wikipedia.org/wiki/Object" title="Object">objects</a> implementing <a target="_blank" href="http://en.wikipedia.org/wiki/Iterator" title="Iterator">Iterator</a> or <a target="_blank" href="http://en.wikipedia.org/wiki/IteratorAggregate" class="mw-redirect" title="IteratorAggregate">IteratorAggregate</a> can be used with the <span>foreach</span> language construct. There is no <a target="_blank" href="http://en.wikipedia.org/wiki/Virtual_table" class="mw-redirect" title="Virtual table">virtual table</a> feature in the engine, so <a target="_blank" href="http://en.wikipedia.org/wiki/Static_variable" title="Static variable">static variables</a> are bound with a name instead of a reference at compile time.<sup id="cite_ref-zend_engine_2_39-0" class="reference"><a href="#cite_note-zend_engine_2-39" title="">[40]</a></sup></p> + +<p>If the developer creates a copy of an object using the reserved word <i>clone</i>, the Zend engine will check if a <tt>__clone()</tt> method has been defined or not. If not, it will call a default <tt>__clone()</tt> which will copy the object's properties. If a <tt>__clone()</tt> method is defined, then it will be responsible for setting the necessary properties in the created object. For convenience, the engine will supply a function that imports the properties of the source object, so that the programmer can start with a by-value <a href="http://en.wiktionary.org/wiki/replica" class="extiw" title="wikt:replica">replica</a> of the source object and only override properties that need to be changed.<sup id="cite_ref-40" class="reference"><a href="#cite_note-40" title="">[41]</a></sup></p> + +<p><a name="Resources" id="Resources"></a></p> +<h2> <span class="mw-headline">Resources</span></h2> +<p>PHP includes <a target="_blank" href="http://en.wikipedia.org/wiki/List_of_PHP_libraries" title="List of PHP libraries">free and open source libraries</a> with the core build. PHP is a fundamentally <a target="_blank" href="http://en.wikipedia.org/wiki/Internet" title="Internet">Internet</a>-aware system with modules built in for accessing <a target="_blank" href="http://en.wikipedia.org/wiki/File_transfer_protocol" class="mw-redirect" title="File transfer protocol">FTP</a> servers, many database servers, embedded SQL libraries such as embedded <a target="_blank" href="http://en.wikipedia.org/wiki/MySQL" title="MySQL">MySQL</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/SQLite" title="SQLite">SQLite</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol" title="Lightweight Directory Access Protocol">LDAP</a> servers, and others. Many functions familiar to C programmers such as those in the <tt><a target="_blank" href="http://en.wikipedia.org/wiki/Stdio.h" title="Stdio.h">stdio</a></tt> family are available in the standard PHP build.<sup id="cite_ref-41" class="reference"><a href="#cite_note-41" title="">[42]</a></sup> PHP has traditionally used features such as "<a target="_blank" href="http://en.wikipedia.org/wiki/Magic_quotes" title="Magic quotes">magic_quotes_gpc</a>" and "magic_quotes_runtime" which attempt to escape apostrophes (') and quotes (") in strings in the assumption that they will be used in databases, to prevent <a target="_blank" href="http://en.wikipedia.org/wiki/SQL_injection" title="SQL injection">SQL injection</a> attacks. This leads to confusion over which data is escaped and which is not, and to problems when data is not in fact used as input to a database and when the escaping used is not completely correct.<sup id="cite_ref-42" class="reference"><a href="#cite_note-42" title="">[43]</a></sup> To make code portable between servers which do and do not use magic quotes, developers can preface their code with a script to reverse the effect of magic quotes when it is applied.<sup id="cite_ref-43" class="reference"><a href="#cite_note-43" title="">[44]</a></sup></p> + +<p>PHP allows developers to write <a target="_blank" href="http://en.wikipedia.org/wiki/Extension_%28computing%29" class="mw-redirect" title="Extension (computing)">extensions</a> in <a target="_blank" href="http://en.wikipedia.org/wiki/C_%28programming_language%29" title="C (programming language)">C</a> to add functionality to the PHP language. These can then be compiled into PHP or loaded dynamically at runtime. Extensions have been written to add support for the <a target="_blank" href="http://en.wikipedia.org/wiki/Windows_API" title="Windows API">Windows API</a>, process management on <a target="_blank" href="http://en.wikipedia.org/wiki/Unix-like" title="Unix-like">Unix-like</a> <a target="_blank" href="http://en.wikipedia.org/wiki/Operating_system" title="Operating system">operating systems</a>, multibyte strings (<a target="_blank" href="http://en.wikipedia.org/wiki/Unispan" title="Unispan">Unispan</a>), <a target="_blank" href="http://en.wikipedia.org/wiki/CURL" title="CURL">cURL</a>, and several popular <a target="_blank" href="http://en.wikipedia.org/wiki/Compression_formats" class="mw-redirect" title="Compression formats">compression formats</a>. Some more unusual features include integration with <a target="_blank" href="http://en.wikipedia.org/wiki/Internet_relay_chat" class="mw-redirect" title="Internet relay chat">Internet relay chat</a>, dynamic generation of images and <a target="_blank" href="http://en.wikipedia.org/wiki/Adobe_Flash" title="Adobe Flash">Adobe Flash</a> content, and even <a target="_blank" href="http://en.wikipedia.org/wiki/Speech_synthesis" title="Speech synthesis">speech synthesis</a>. The <a target="_blank" href="http://en.wikipedia.org/wiki/PHP_Extension_Community_Library" class="mw-redirect" title="PHP Extension Community Library">PHP Extension Community Library</a> (PECL) project is a repository for extensions to the PHP language.<sup id="cite_ref-44" class="reference"><a href="#cite_note-44" title="">[45]</a></sup></p> + +<p>As with many scripting languages, PHP scripts are normally kept as human-readable source code, even on production web servers.<sup id="cite_ref-45" class="reference"><a href="#cite_note-45" title="">[46]</a></sup> While this allows flexibility, releasing scripts in source form is undesirable for commercial software developers, and can raise issues with security of web servers; as an example, if a hacker acquires control of a server, database passwords may be quickly discovered, and undesirable changes to scripts may be made that remain undiscovered indefinitely. Various encoding tools are available for PHP to offer code protection.<sup class="noprint Template-Fact"><span title="This claim needs references to reliable sources since March 2008" style="white-space: nowrap;">[<i><a target="_blank" href="http://en.wikipedia.org/wiki/Wikipedia:Citation_needed" title="Wikipedia:Citation needed">citation needed</a></i>]</span></sup></p> +<p>span optimizers improve the quality of the compiled code by reducing its size and making changes that can reduce the execution time and improve performance. The nature of the PHP <a target="_blank" href="http://en.wikipedia.org/wiki/Compiler" title="Compiler">compiler</a> is such that there are often opportunities for <a target="_blank" href="http://en.wikipedia.org/wiki/Optimization_%28computer_science%29" title="Optimization (computer science)">span optimization</a><sup id="cite_ref-46" class="reference"><a href="#cite_note-46" title="">[47]</a></sup>, and an example of a code optimizer is the <a target="_blank" href="http://en.wikipedia.org/wiki/PHP_accelerator#Zend_Optimizer" title="PHP accelerator">Zend Optimizer</a> PHP extension.<sup id="cite_ref-47" class="reference"><a href="#cite_note-47" title="">[48]</a></sup></p> + +<p><a target="_blank" href="http://en.wikipedia.org/wiki/PHP_accelerator" title="PHP accelerator">PHP accelerators</a> can offer significant performance gains by <a target="_blank" href="http://en.wikipedia.org/wiki/Caching" class="mw-redirect" title="Caching">caching</a> the compiled form of a PHP script in <a target="_blank" href="http://en.wikipedia.org/wiki/Shared_memory" title="Shared memory">shared memory</a> to avoid the overhead of <a target="_blank" href="http://en.wikipedia.org/wiki/Parsing" title="Parsing">parsing</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Compiling" class="mw-redirect" title="Compiling">compiling</a> the code every time the script runs. They may also perform <a target="_blank" href="http://en.wikipedia.org/wiki/span_optimization" class="mw-redirect" title="span optimization">span optimization</a> to provide increased execution performance.<sup class="noprint Template-Fact"><span title="This claim needs references to reliable sources since March 2008" style="white-space: nowrap;">[<i><a target="_blank" href="http://en.wikipedia.org/wiki/Wikipedia:Citation_needed" title="Wikipedia:Citation needed">citation needed</a></i>]</span></sup></p> + diff --git a/sites/all/modules/advanced_help/help_example/help/usage.html b/sites/all/modules/advanced_help/help_example/help/usage.html new file mode 100644 index 0000000000000000000000000000000000000000..8f1e9ad43f69c42aeb205136e694529f759a606c --- /dev/null +++ b/sites/all/modules/advanced_help/help_example/help/usage.html @@ -0,0 +1,9 @@ +<p>PHP is a general-purpose scripting language that is especially suited for <a target="_blank" href="http://en.wikipedia.org/wiki/Web_development" title="Web development">web development</a>. It is the fourth most popular computer programming language, ranking behind <a target="_blank" href="http://en.wikipedia.org/wiki/Java_%28programming_language%29" title="Java (programming language)">Java</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/C_%28programming_language%29" title="C (programming language)">C</a>, and <a target="_blank" href="http://en.wikipedia.org/wiki/Visual_Basic" title="Visual Basic">Visual Basic</a>.<sup id="cite_ref-22" class="reference"><a href="#cite_note-22" title="">[23]</a></sup> PHP generally runs on a <a target="_blank" href="http://en.wikipedia.org/wiki/Web_server" title="Web server">web server</a>, taking PHP code as its input and creating <a target="_blank" href="http://en.wikipedia.org/wiki/Web_page" title="Web page">web pages</a> as output. It can also be used for <a target="_blank" href="http://en.wikipedia.org/wiki/Command-line" class="mw-redirect" title="Command-line">command-line</a> scripting and <a target="_blank" href="http://en.wikipedia.org/wiki/Client-side" title="Client-side">client-side</a> <a target="_blank" href="http://en.wikipedia.org/wiki/Graphical_user_interface" title="Graphical user interface">GUI</a> applications. PHP can be deployed on most <a target="_blank" href="http://en.wikipedia.org/wiki/Web_server" title="Web server">web servers</a>, many <a target="_blank" href="http://en.wikipedia.org/wiki/Operating_system" title="Operating system">operating systems</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Platform_%28computing%29" class="mw-redirect" title="Platform (computing)">platforms</a>, and can be used with many <a target="_blank" href="http://en.wikipedia.org/wiki/Relational_database_management_system" title="Relational database management system">relational database management systems</a>. It is available free of charge, and the PHP Group provides the complete source code for users to build, customize and extend for their own use.<sup id="cite_ref-foundations_4-1" class="reference"><a href="#cite_note-foundations-4" title="">[5]</a></sup></p> + +<p>PHP primarily acts as a <a target="_blank" href="http://en.wikipedia.org/wiki/Filter_%28software%29" title="Filter (software)">filter</a><sup id="cite_ref-23" class="reference"><a href="#cite_note-23" title="">[24]</a></sup>, taking input from a file or stream containing text and/or PHP instructions and outputs another stream of data; most commonly the output will be HTML. From PHP 4, the PHP <a target="_blank" href="http://en.wikipedia.org/wiki/Parser" class="mw-redirect" title="Parser">parser</a> <a target="_blank" href="http://en.wikipedia.org/wiki/Compiler" title="Compiler">compiles</a> input to produce <a target="_blank" href="http://en.wikipedia.org/wiki/Bytecode" title="Bytecode">bytecode</a> for processing by the <a target="_blank" href="http://en.wikipedia.org/wiki/Zend_Engine" title="Zend Engine">Zend Engine</a>, giving improved performance over its <a target="_blank" href="http://en.wikipedia.org/wiki/Interpreter_%28computing%29" title="Interpreter (computing)">interpreter</a> predecessor.<sup id="cite_ref-24" class="reference"><a href="#cite_note-24" title="">[25]</a></sup></p> + +<p>Originally designed to create dynamic web pages, PHP's principal focus is <a target="_blank" href="http://en.wikipedia.org/wiki/Server-side_scripting" title="Server-side scripting">server-side scripting</a><sup id="cite_ref-25" class="reference"><a href="#cite_note-25" title="">[26]</a></sup>, and it is similar to other server-side scripting languages that provide dynamic content from a web server to a <a target="_blank" href="http://en.wikipedia.org/wiki/Client_%28computing%29" title="Client (computing)">client</a>, such as <a target="_blank" href="http://en.wikipedia.org/wiki/Microsoft" title="Microsoft">Microsoft</a>'s <a target="_blank" href="http://en.wikipedia.org/wiki/ASP.NET" title="ASP.NET">ASP.NET</a> system, <a target="_blank" href="http://en.wikipedia.org/wiki/Sun_Microsystems" title="Sun Microsystems">Sun Microsystems</a>' <a target="_blank" href="http://en.wikipedia.org/wiki/JavaServer_Pages" title="JavaServer Pages">JavaServer Pages</a><sup id="cite_ref-26" class="reference"><a href="#cite_note-26" title="">[27]</a></sup>, and <a target="_blank" href="http://en.wikipedia.org/wiki/Mod_perl" title="Mod perl">mod_perl</a>. PHP has also attracted the development of many <a target="_blank" href="http://en.wikipedia.org/wiki/Software_framework" title="Software framework">frameworks</a> that provide building blocks and a design structure to promote <a target="_blank" href="http://en.wikipedia.org/wiki/Rapid_application_development" title="Rapid application development">rapid application development</a> (RAD). Some of these include <a target="_blank" href="http://en.wikipedia.org/wiki/CakePHP" title="CakePHP">CakePHP</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/PRADO" title="PRADO">PRADO</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/Symfony" title="Symfony">Symfony</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/Zend_Framework" title="Zend Framework">Zend Framework</a>, offering features similar to other <a target="_blank" href="http://en.wikipedia.org/wiki/List_of_web_application_frameworks" title="List of web application frameworks">web application frameworks</a>.</p> + +<p>The <a target="_blank" href="http://en.wikipedia.org/wiki/LAMP_%28software_bundle%29" title="LAMP (software bundle)">LAMP</a> architecture has become popular in the web industry as a way of deploying web applications. PHP is commonly used as the <i>P</i> in this bundle alongside <a target="_blank" href="http://en.wikipedia.org/wiki/Linux" title="Linux">Linux</a>, <a target="_blank" href="http://en.wikipedia.org/wiki/Apache_HTTP_Server" title="Apache HTTP Server">Apache</a> and <a target="_blank" href="http://en.wikipedia.org/wiki/MySQL" title="MySQL">MySQL</a>, although the <i>P</i> can also refer to <a target="_blank" href="http://en.wikipedia.org/wiki/Python_%28programming_language%29" title="Python (programming language)">Python</a> or <a target="_blank" href="http://en.wikipedia.org/wiki/Perl" title="Perl">Perl</a>.</p> + +<p>As of April 2007, over 20 million Internet domains were hosted on servers with PHP installed, and PHP was recorded as the most popular Apache module.<sup id="cite_ref-usage_5-2" class="reference"><a href="#cite_note-usage-5" title="">[6]</a></sup></p> diff --git a/sites/all/modules/advanced_help/help_example/help_example.info b/sites/all/modules/advanced_help/help_example/help_example.info new file mode 100644 index 0000000000000000000000000000000000000000..5768a6b3980c2cbd7b3f9960ff18f29cfee709fd --- /dev/null +++ b/sites/all/modules/advanced_help/help_example/help_example.info @@ -0,0 +1,13 @@ +; $Id: help_example.info,v 1.3.4.1 2010/03/01 21:12:39 fgm Exp $ +name = Advanced help example +description = A example help module to demonstrate the advanced help module. +core = 7.x +dependencies[] = advanced_help +files[] = help_example.module + +; Information added by drupal.org packaging script on January 1, 1970 - 00:00 +version = "7.x-1.0-beta1" +core = "7.x" +project = "advanced_help" +datestamp = "1295293901" + diff --git a/sites/all/modules/advanced_help/help_example/help_example.module b/sites/all/modules/advanced_help/help_example/help_example.module new file mode 100644 index 0000000000000000000000000000000000000000..4f48534ea8f137ad58e5310384f8a8b290be88e2 --- /dev/null +++ b/sites/all/modules/advanced_help/help_example/help_example.module @@ -0,0 +1,30 @@ +<?php +// $Id: help_example.module,v 1.2.4.1 2010/03/01 21:12:39 fgm Exp $ +/** + * @file + * + * Provide example help for the advanced help module. + */ + +/** + * Implementation of hook_menu(). + */ +function help_example_menu() { + // View help topic index. + $items['admin/help_example'] = array( + 'title' => 'Example help', + 'page callback' => 'help_example_index_page', + 'access arguments' => array('view advanced help index'), + 'weight' => 9, + ); + return $items; +} + +function help_example_index_page() { + $output = theme('advanced_help_topic', array( + 'module' => 'help_example', + 'topic' => 'about-php', + )); + $output .= ' ' . t('Click the help icon to view some example help about the PHP programming language (from wikipedia.org). Be sure to run cron to update the index if you want to try out the search features.'); + return $output; +} diff --git a/sites/all/modules/advanced_help/help_example/translations/help_example.de.po b/sites/all/modules/advanced_help/help_example/translations/help_example.de.po new file mode 100644 index 0000000000000000000000000000000000000000..777d7d8b14b649d024e99f2b4313f5ab40cc58ec --- /dev/null +++ b/sites/all/modules/advanced_help/help_example/translations/help_example.de.po @@ -0,0 +1,35 @@ +msgid "" +msgstr "" +"Project-Id-Version: German translation for Advanced Help module\n" +"POT-Creation-Date: 2008-10-18 17:11+0200\n" +"PO-Revision-Date: 2008-10-18 17:12+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: Frank Tartler <rastatt@drupal.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: help_example/help_example.module:24 +msgid "Click the help icon to view some example help about the PHP programming language (from wikipedia.org). Be sure to run cron to update the index if you want to try out the search features." +msgstr "Auf das Hilfe-Icon klicken, um ein Hilfe-Beispiel über die PHP-Programmiersprache anzuzeigen (von wikipedia.org). Um die Funktionen der Suche auszuprobieren muss Cron den Index aktualisiert haben." + +#: help_example/help_example.module:14 +msgid "Example help" +msgstr "Hilfe-Beispiel" + +#: help_example/help_example.module:0 +msgid "help_example" +msgstr "help_example" + +#: help_example/help_example.info:0 +msgid "Advanced help example" +msgstr "Beispiel für die erweiterte Hilfe" + +#: help_example/help_example.info:0 +msgid "A example help module to demonstrate the advanced help module." +msgstr "Ein beispielhaftes Hilfe-Modul, um die Fähigkeiten des ‚Erweiterte Hilfe‘-Moduls vorzustellen." + diff --git a/sites/all/modules/advanced_help/help_example/translations/help_example.pot b/sites/all/modules/advanced_help/help_example/translations/help_example.pot new file mode 100644 index 0000000000000000000000000000000000000000..57292ee640fd6cce92ad7ed9ea413afefc879656 --- /dev/null +++ b/sites/all/modules/advanced_help/help_example/translations/help_example.pot @@ -0,0 +1,41 @@ +# $Id: help_example.pot,v 1.2 2008/10/18 15:12:43 hass Exp $ +# +# LANGUAGE translation of Drupal (help_example) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# help_example.module,v 1.2 2008/04/19 16:45:57 merlinofchaos +# help_example.info,v 1.3 2008/05/10 17:32:14 merlinofchaos +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2008-10-18 17:11+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" + +#: help_example/help_example.module:24 +msgid "Click the help icon to view some example help about the PHP programming language (from wikipedia.org). Be sure to run cron to update the index if you want to try out the search features." +msgstr "" + +#: help_example/help_example.module:14 +msgid "Example help" +msgstr "" + +#: help_example/help_example.module:0 +msgid "help_example" +msgstr "" + +#: help_example/help_example.info:0 +msgid "Advanced help example" +msgstr "" + +#: help_example/help_example.info:0 +msgid "A example help module to demonstrate the advanced help module." +msgstr "" + diff --git a/sites/all/modules/advanced_help/translations/advanced_help.da.po b/sites/all/modules/advanced_help/translations/advanced_help.da.po new file mode 100644 index 0000000000000000000000000000000000000000..1846f1b01250429c01f7a046fd73f52599f12591 --- /dev/null +++ b/sites/all/modules/advanced_help/translations/advanced_help.da.po @@ -0,0 +1,137 @@ +# Dansk translation of advanced_help (6.x-1.2) +# Copyright (c) 2009 by the Dansk translation team +# Generated from files: +# advanced_help.module,v 1.41 2008/10/28 17:33:47 merlinofchaos +# advanced_help.info,v 1.2 2008/04/19 16:45:57 merlinofchaos +# advanced_help.install,v 1.3 2008/04/19 16:45:57 merlinofchaos +# help_example.module,v 1.2 2008/04/19 16:45:57 merlinofchaos +# help_example.info,v 1.3 2008/05/10 17:32:14 merlinofchaos +# +# +msgid "" +msgstr "" +"Project-Id-Version: advanced_help (6.x-1.2)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-05-28 07:04-0700\n" +"PO-Revision-Date: 2009-05-28 16:04+0200\n" +"Last-Translator: Morten Wulff <wulff@ratatosk.net>\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);" + +#: advanced_help.module:415 +msgid "Home" +msgstr "Hjem" + +#: advanced_help.module:129,196,399,447,735,53 +msgid "Help" +msgstr "Hjælp" + +#: advanced_help.module:141 +msgid "Search results" +msgstr "Søgeresultater" + +#: advanced_help.module:144 +msgid "Your search yielded no results" +msgstr "Din søgning gav ingen resultater." + +#: advanced_help.module:325 +msgid "Please enter some keywords." +msgstr "Indtast søgeord." + +#: advanced_help.module:610 +msgid "Up" +msgstr "Op" + +#: advanced_help.module:184 +msgid "Enable the search module to search help." +msgstr "Aktiver søgemodulet for at søge i hjælpeteksten." + +#: advanced_help.module:198 +msgid "@module help index" +msgstr "@module hjælp" + +#: advanced_help.module:228 +msgid "Module help index" +msgstr "Hjælp til modul" + +#: advanced_help.module:310,60 +msgid "Search help" +msgstr "Søg i hjælp" + +#: advanced_help.module:403 +msgid "Missing help topic." +msgstr "Manglende emne." + +#: advanced_help.module:424 +msgid "view advanced help topic" +msgstr "vis hjælp" + +#: advanced_help.module:424 +msgid "view advanced help popup" +msgstr "vis hjælp popup" + +#: advanced_help.module:424 +msgid "view advanced help index" +msgstr "vis oversigt" + +#: advanced_help.module:45; advanced_help.info:0 +msgid "Advanced help" +msgstr "Avanceret hjælp" + +#: advanced_help.module:0 +msgid "advanced_help" +msgstr "advanced_help" + +#: advanced_help.install:23 +msgid "Stores search index correlations for advanced help topics." +msgstr "Gemmer søgeindekskorrelationer for avancerede hjælpetekster." + +#: advanced_help.install:29 +msgid "The primary key to give to the search engine for this topic." +msgstr "Den primære nøgle som gives til søgemaskinen for denne tekst." + +#: advanced_help.install:37 +msgid "The module that owns this topic." +msgstr "Modulet som ejer denne tekst." + +#: advanced_help.install:44 +msgid "The topic id." +msgstr "Emne ID" + +#: advanced_help.install:51 +msgid "The language this search index relates to." +msgstr "Sproget som søgeindekset hører til." + +#: advanced_help.info:0 +msgid "Allow advanced help and documentation." +msgstr "Tilbyd avanceret hjælp og dokumentation." + +#: help_example/help_example.module:24 +msgid "" +"Click the help icon to view some example help about the PHP " +"programming language (from wikipedia.org). Be sure to run cron to " +"update the index if you want to try out the search features." +msgstr "" +"Klik på ikonet for at se et eksempel på hjælp til PHP " +"programmeringssproget (fra wikipedia.org). Husk at køre cron for at " +"opdatere indekset hvis du vil prøve søgefunktionen." + +#: help_example/help_example.module:14 +msgid "Example help" +msgstr "Eksempel på hjælp" + +#: help_example/help_example.module:0 +msgid "help_example" +msgstr "help_example" + +#: help_example/help_example.info:0 +msgid "Advanced help example" +msgstr "Advanced Help eksempel" + +#: help_example/help_example.info:0 +msgid "A example help module to demonstrate the advanced help module." +msgstr "Et modul som demonstrerer brugen af Advanced Help modulet." + diff --git a/sites/all/modules/advanced_help/translations/advanced_help.de.po b/sites/all/modules/advanced_help/translations/advanced_help.de.po new file mode 100644 index 0000000000000000000000000000000000000000..072af17ebbadd290b1af6520c9ead58ff5203e37 --- /dev/null +++ b/sites/all/modules/advanced_help/translations/advanced_help.de.po @@ -0,0 +1,107 @@ +msgid "" +msgstr "" +"Project-Id-Version: German translation for Advanced Help module\n" +"POT-Creation-Date: 2008-10-18 17:11+0200\n" +"PO-Revision-Date: 2009-10-13 17:02+0100\n" +"Last-Translator: Thomas Zahreddin <thomas@voicehero.net>\n" +"Language-Team: Frank Tartler <rastatt@drupal.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" + +#: advanced_help.module:120;186;389;437;689;53 +msgid "Help" +msgstr "Hilfe" + +#: advanced_help.module:132 +msgid "Search results" +msgstr "Suchergebnisse" + +#: advanced_help.module:135 +msgid "Your search yielded no results" +msgstr "Diese Suche lieferte keine Ergebnisse." + +#: advanced_help.module:174 +msgid "Enable the search module to search help." +msgstr "Das Suchmodul aktivieren, um die Hilfetexte zu durchsuchen." + +#: advanced_help.module:188 +msgid "@module help index" +msgstr "@module-Hilfe-Index" + +#: advanced_help.module:218 +msgid "Module help index" +msgstr "Modul-Hilfe-Index" + +#: advanced_help.module:300;60 +msgid "Search help" +msgstr "Hilfe durchsuchen" + +# formal +#: advanced_help.module:315 +msgid "Please enter some keywords." +msgstr "Stichwörter, nach denen gesucht werden soll." + +#: advanced_help.module:393 +msgid "Missing help topic." +msgstr "Keine Hilfe zu diesem Thema vorhanden." + +#: advanced_help.module:405 +msgid "Home" +msgstr "Startseite" + +#: advanced_help.module:584 +msgid "Up" +msgstr "nach oben" + +#: advanced_help.module:414 +#, fuzzy +msgid "view advanced help topic" +msgstr "Erweiterten Hilfe zum Thema" + +#: advanced_help.module:414 +msgid "view advanced help popup" +msgstr "Popup-Fenster für Advanced help" + +#: advanced_help.module:414 +msgid "view advanced help index" +msgstr "Index der erweiterten Hilfe" + +#: advanced_help.module:45 +#: advanced_help.info:0 +msgid "Advanced help" +msgstr "Advanced help" + +#: advanced_help.module:0 +msgid "advanced_help" +msgstr "advanced_help" + +#: advanced_help.install:23 +#, fuzzy +msgid "Stores search index correlations for advanced help topics." +msgstr "Speichert Suchindex-Übereinstimmungen für Themen der erweiterten Hilfe." + +#: advanced_help.install:29 +msgid "The primary key to give to the search engine for this topic." +msgstr "Der Primärschlüssel, der für dieses Thema an die Suchmaschine übergeben wird." + +#: advanced_help.install:37 +msgid "The module that owns this topic." +msgstr "Das Modul zu dem dieses Thema gehört." + +#: advanced_help.install:44 +msgid "The topic id." +msgstr "Die Themen-ID." + +#: advanced_help.install:51 +msgid "The language this search index relates to." +msgstr "Die Sprache auf den sich dieser Index bezieht." + +#: advanced_help.info:0 +msgid "Allow advanced help and documentation." +msgstr "Ermöglicht eine erweiterte Hilfe und Dokumentation." + diff --git a/sites/all/modules/advanced_help/translations/advanced_help.es.po b/sites/all/modules/advanced_help/translations/advanced_help.es.po new file mode 100644 index 0000000000000000000000000000000000000000..fb2657271c6bebc5bbcfd93180327d8632146a5c --- /dev/null +++ b/sites/all/modules/advanced_help/translations/advanced_help.es.po @@ -0,0 +1,111 @@ +# $Id: advanced_help.es.po,v 1.1 2009/10/11 05:59:41 redndahead Exp $ +# +# LANGUAGE translation of Drupal (root) +# Copyright 2009 David Moreno Fernández <david.moreno@gmail.com> +# Generated from files: +# advanced_help.module,v 1.24 2008/09/15 19:16:10 merlinofchaos +# advanced_help.install,v 1.3 2008/04/19 16:45:57 merlinofchaos +# advanced_help.info,v 1.2 2008/04/19 16:45:57 merlinofchaos +# Sponsored by Ingenia.es +# +msgid "" +msgstr "" +"Project-Id-Version: 1.2\n" +"POT-Creation-Date: 2008-10-18 17:11+0200\n" +"PO-Revision-Date: 2009-03-23 09:59+0100\n" +"Last-Translator: afernandez <afernandez@ingenia.es>\n" +"Language-Team: IngeniaTeam <david.moreno@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" + +#: advanced_help.module:120;186;389;437;689;53 +msgid "Help" +msgstr "Ayuda" + +#: advanced_help.module:132 +msgid "Search results" +msgstr "Resultados de búsqueda" + +#: advanced_help.module:135 +msgid "Your search yielded no results" +msgstr "Su búsqueda no produjo ningun resultado" + +#: advanced_help.module:174 +msgid "Enable the search module to search help." +msgstr "Activar la búsqueda de módulos para la búsqueda de ayuda." + +#: advanced_help.module:188 +msgid "@module help index" +msgstr "índice de ayuda de @module" + +#: advanced_help.module:218 +msgid "Module help index" +msgstr "Índice de ayuda de módulos" + +#: advanced_help.module:300;60 +msgid "Search help" +msgstr "Buscar ayuda" + +#: advanced_help.module:315 +msgid "Please enter some keywords." +msgstr "Por favor, introduzca alguna palabra clave." + +#: advanced_help.module:393 +msgid "Missing help topic." +msgstr "Olvida algún tema de ayuda." + +#: advanced_help.module:405 +msgid "Home" +msgstr "Inicio" + +#: advanced_help.module:584 +msgid "Up" +msgstr "Arriba" + +#: advanced_help.module:414 +msgid "view advanced help topic" +msgstr "ver tema de ayuda avanzada" + +#: advanced_help.module:414 +msgid "view advanced help popup" +msgstr "ver emergente de ayuda avanzada" + +#: advanced_help.module:414 +msgid "view advanced help index" +msgstr "ver índice de ayuda avanzado" + +#: advanced_help.module:45 advanced_help.info:0 +msgid "Advanced help" +msgstr "Ayuda avanzada" + +#: advanced_help.module:0 +msgid "advanced_help" +msgstr "advanced_help" + +#: advanced_help.install:23 +msgid "Stores search index correlations for advanced help topics." +msgstr "" +"Almacena las correlaciones de índice de búsqueda para temas de ayuda " +"avanzados." + +#: advanced_help.install:29 +msgid "The primary key to give to the search engine for this topic." +msgstr "La clave primaria para dar al motor de búsqueda para este tema." + +#: advanced_help.install:37 +msgid "The module that owns this topic." +msgstr "El módulo que posee el tema." + +#: advanced_help.install:44 +msgid "The topic id." +msgstr "El id del tema." + +#: advanced_help.install:51 +msgid "The language this search index relates to." +msgstr "La lenguaje de este índice de búsqueda se relaciona con." + +#: advanced_help.info:0 +msgid "Allow advanced help and documentation." +msgstr "Permitir ayuda avanzada y documentación." diff --git a/sites/all/modules/advanced_help/translations/advanced_help.hu.po b/sites/all/modules/advanced_help/translations/advanced_help.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..36ddbb6c152b1016c9d1d447bdf115e414bd7d0b --- /dev/null +++ b/sites/all/modules/advanced_help/translations/advanced_help.hu.po @@ -0,0 +1,142 @@ +# Hungarian translation of advanced_help (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# Generated from files: +# advanced_help.module,v 1.41 2008/10/28 17:33:47 merlinofchaos +# advanced_help.info,v 1.2 2008/04/19 16:45:57 merlinofchaos +# advanced_help.install,v 1.3 2008/04/19 16:45:57 merlinofchaos +# help_example.module,v 1.2 2008/04/19 16:45:57 merlinofchaos +# help_example.info,v 1.3 2008/05/10 17:32:14 merlinofchaos +# +msgid "" +msgstr "" +"Project-Id-Version: advanced_help (6.x-1.2)\n" +"POT-Creation-Date: 2009-05-29 00:41+0200\n" +"PO-Revision-Date: 2009-05-28 19:51+0200\n" +"Last-Translator: Balogh Zoltán\n" +"Language-Team: Hungarian http://forditas.mindworks.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" + +#: advanced_help.module:415 +msgid "Home" +msgstr "Címlap" + +#: advanced_help.module:129,196,399,447,735,53 +msgid "Help" +msgstr "Súgó" + +#: advanced_help.module:141 +msgid "Search results" +msgstr "Találatok" + +#: advanced_help.module:144 +msgid "Your search yielded no results" +msgstr "Nincs találat." + +#: advanced_help.module:325 +msgid "Please enter some keywords." +msgstr "A kulcsszavakat itt kell megadni." + +#: advanced_help.module:610 +msgid "Up" +msgstr "Fel" + +#: advanced_help.module:184 +msgid "Enable the search module to search help." +msgstr "" +"A súgóban való kereséshez engedélyezni kell a <em>Search</em> " +"modult." + +#: advanced_help.module:198 +msgid "@module help index" +msgstr "@module tárgymutató" + +#: advanced_help.module:228 +msgid "Module help index" +msgstr "Modul tárgymutató" + +#: advanced_help.module:310,60 +msgid "Search help" +msgstr "Keresés a súgóban" + +#: advanced_help.module:403 +msgid "Missing help topic." +msgstr "Hiányzó súgó téma." + +#: advanced_help.module:424 +msgid "view advanced help topic" +msgstr "bővített súgó téma megtekintése" + +#: advanced_help.module:424 +msgid "view advanced help popup" +msgstr "bővített súgó megtekintése" + +#: advanced_help.module:424 +msgid "view advanced help index" +msgstr "bővített súgó tárgymutató megtekintése" + +#: advanced_help.module:45; advanced_help.info:0 +msgid "Advanced help" +msgstr "Advanced help" + +#: advanced_help.module:0 +msgid "advanced_help" +msgstr "advanced_help" + +#: advanced_help.install:23 +msgid "Stores search index correlations for advanced help topics." +msgstr "" +"A keresési index és a kibővített súgó témák közötti " +"kapcsolatot tartalmazza." + +#: advanced_help.install:29 +msgid "The primary key to give to the search engine for this topic." +msgstr "Az elsődleges kulcs a keresőmotor számára a súgó témához." + +#: advanced_help.install:37 +msgid "The module that owns this topic." +msgstr "A modul amely a témát tartalmazza." + +#: advanced_help.install:44 +msgid "The topic id." +msgstr "Téma azonosító." + +#: advanced_help.install:51 +msgid "The language this search index relates to." +msgstr "A nyelv amihez ez a keresési index kapcsolódik." + +#: advanced_help.info:0 +msgid "Allow advanced help and documentation." +msgstr "Bővített súgó és dokumentáció engedélyezése." + +#: help_example/help_example.module:24 +msgid "" +"Click the help icon to view some example help about the PHP " +"programming language (from wikipedia.org). Be sure to run cron to " +"update the index if you want to try out the search features." +msgstr "" +"A súgó ikonra kattintva egy példa súgó téma jelenik meg, ami a " +"PHP programozási nyelvet mutatja be (wikipedia.org). A keresési " +"funkciók kipróbálása előtt a keresési indexeket újra kell " +"építeni az időzítő futtatásával." + +#: help_example/help_example.module:14 +msgid "Example help" +msgstr "Súgó példa" + +#: help_example/help_example.module:0 +msgid "help_example" +msgstr "help_example" + +#: help_example/help_example.info:0 +msgid "Advanced help example" +msgstr "Advanced help példa" + +#: help_example/help_example.info:0 +msgid "A example help module to demonstrate the advanced help module." +msgstr "" +"Példa modul, amely az <em>Advanced help</em> modul lehetőségeit " +"mutatja be." + diff --git a/sites/all/modules/advanced_help/translations/advanced_help.pot b/sites/all/modules/advanced_help/translations/advanced_help.pot new file mode 100644 index 0000000000000000000000000000000000000000..aec223483536e88adc50d9549dd985fd682a83cc --- /dev/null +++ b/sites/all/modules/advanced_help/translations/advanced_help.pot @@ -0,0 +1,124 @@ +# $Id: advanced_help.pot,v 1.4 2009/10/13 15:43:33 thomaszahreddin Exp $ +# +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# advanced_help.module,v 1.41 2008/10/28 17:33:47 merlinofchaos +# advanced_help.info,v 1.2 2008/04/19 16:45:57 merlinofchaos +# advanced_help.install,v 1.3 2008/04/19 16:45:57 merlinofchaos +# help_example.module,v 1.2 2008/04/19 16:45:57 merlinofchaos +# help_example.info,v 1.3 2008/05/10 17:32:14 merlinofchaos +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-10-13 17:13+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" + +#: advanced_help.module:129;196;399;447;735;53 +msgid "Help" +msgstr "" + +#: advanced_help.module:141 +msgid "Search results" +msgstr "" + +#: advanced_help.module:144 +msgid "Your search yielded no results" +msgstr "" + +#: advanced_help.module:184 +msgid "Enable the search module to search help." +msgstr "" + +#: advanced_help.module:198 +msgid "@module help index" +msgstr "" + +#: advanced_help.module:228 +msgid "Module help index" +msgstr "" + +#: advanced_help.module:310;60 +msgid "Search help" +msgstr "" + +#: advanced_help.module:325 +msgid "Please enter some keywords." +msgstr "" + +#: advanced_help.module:403 +msgid "Missing help topic." +msgstr "" + +#: advanced_help.module:415 +msgid "Home" +msgstr "" + +#: advanced_help.module:610 +msgid "Up" +msgstr "" + +#: advanced_help.module:424 +msgid "view advanced help topic" +msgstr "" + +#: advanced_help.module:424 +msgid "view advanced help popup" +msgstr "" + +#: advanced_help.module:424 +msgid "view advanced help index" +msgstr "" + +#: advanced_help.module:45 advanced_help.info:0 +msgid "Advanced help" +msgstr "" + +#: advanced_help.install:23 +msgid "Stores search index correlations for advanced help topics." +msgstr "" + +#: advanced_help.install:29 +msgid "The primary key to give to the search engine for this topic." +msgstr "" + +#: advanced_help.install:37 +msgid "The module that owns this topic." +msgstr "" + +#: advanced_help.install:44 +msgid "The topic id." +msgstr "" + +#: advanced_help.install:51 +msgid "The language this search index relates to." +msgstr "" + +#: advanced_help.info:0 +msgid "Allow advanced help and documentation." +msgstr "" + +#: help_example/help_example.module:24 +msgid "Click the help icon to view some example help about the PHP programming language (from wikipedia.org). Be sure to run cron to update the index if you want to try out the search features." +msgstr "" + +#: help_example/help_example.module:14 +msgid "Example help" +msgstr "" + +#: help_example/help_example.info:0 +msgid "Advanced help example" +msgstr "" + +#: help_example/help_example.info:0 +msgid "A example help module to demonstrate the advanced help module." +msgstr "" + diff --git a/sites/all/modules/advanced_help/translations/fr.po b/sites/all/modules/advanced_help/translations/fr.po new file mode 100644 index 0000000000000000000000000000000000000000..6458d78349779bd1e5e1d21a03e9eefc5ad83996 --- /dev/null +++ b/sites/all/modules/advanced_help/translations/fr.po @@ -0,0 +1,96 @@ +# French translation of Advanced Help +msgid "" +msgstr "" +"Project-Id-Version: advanced_help (6.x-1.1)\n" +"POT-Creation-Date: 2008-10-05 22:43+0200\n" +"PO-Revision-Date: \n" +"Last-Translator: Mimoune Walid <mi.walid@gmail.com>\n" +"Language-Team: French\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: ALGERIA\n" +"X-Poedit-SourceCharset: utf8\n" + +#: advanced_help.module:121 +msgid "Search results" +msgstr "Résultats de la recherche" + +#: advanced_help.module:124 +msgid "Your search yielded no results" +msgstr "Votre recherche n'a donné aucun résultat" + +#: advanced_help.module:163 +msgid "Enable the search module to search help." +msgstr "Activez le module Search pour chercher l'aide." + +#: advanced_help.module:177 +msgid "@module help index" +msgstr "index d'aide de @module" + +#: advanced_help.module:207 +msgid "Module help index" +msgstr "Index d'aide de module" + +#: advanced_help.module:289;49 +msgid "Search help" +msgstr "Chercher l'aide" + +#: advanced_help.module:304 +msgid "Please enter some keywords." +msgstr "Veuillez entrer des mots-clés." + +#: advanced_help.module:378;426;668 +msgid "Help" +msgstr "Aide" + +#: advanced_help.module:382 +msgid "Missing help topic." +msgstr "Sujet d'aide manquant." + +#: advanced_help.module:403 +msgid "view advanced help topic" +msgstr "accéder au rubrique d'aide avancé" + +#: advanced_help.module:403 +msgid "view advanced help popup" +msgstr "accéder au popup d'aide avancé" + +#: advanced_help.module:403 +msgid "view advanced help index" +msgstr "accéder à l'index d'aide avancé" + +#: advanced_help.module:0 +msgid "advanced_help" +msgstr "advanced_help" + +#: advanced_help.install:23 +msgid "Stores search index correlations for advanced help topics." +msgstr "Sauvegarde les corrélations de l'index de recherche pour les rubriques d'aide." + +#: advanced_help.install:29 +msgid "The primary key to give to the search engine for this topic." +msgstr "La clé primaire à donner au moteur de recherche pour ce sujet." + +#: advanced_help.install:37 +msgid "The module that owns this topic." +msgstr "Le module propriétaire de ce sujet." + +#: advanced_help.install:44 +msgid "The topic id." +msgstr "Id de sujet" + +#: advanced_help.install:51 +msgid "The language this search index relates to." +msgstr "La langue reliée à cet index de recherche." + +#: advanced_help.info:0 +msgid "Advanced help" +msgstr "Aide Avancé" + +#: advanced_help.info:0 +msgid "Allow advanced help and documentation." +msgstr "Permet l'aide avancé et la documentation." + diff --git a/sites/all/modules/advanced_help/translations/help/de/advanced_help.help.ini b/sites/all/modules/advanced_help/translations/help/de/advanced_help.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..73bed4c807731af2690d61145b548976aa0a7c45 --- /dev/null +++ b/sites/all/modules/advanced_help/translations/help/de/advanced_help.help.ini @@ -0,0 +1,16 @@ +; $Id: advanced_help.help.ini,v 1.1 2008/10/27 20:50:21 merlinofchaos Exp $ + +[using-advanced-help] +title = Erweiterte Hilfe verwenden +weight = -10 + +[translation] +title = Erweiterte Hilfe übersetzen + +[ini-file] +title = Format der .ini-Hilfedatei +line break = TRUE + +[why-advanced-help] +title = Erweiterte Hilfe - warum? +line break = TRUE diff --git a/sites/all/modules/advanced_help/translations/help/de/ini-file.html b/sites/all/modules/advanced_help/translations/help/de/ini-file.html new file mode 100644 index 0000000000000000000000000000000000000000..32a8d7fd1e7f708b497f901baea6f98f895556a0 --- /dev/null +++ b/sites/all/modules/advanced_help/translations/help/de/ini-file.html @@ -0,0 +1,52 @@ +<!-- $Id: ini-file.html,v 1.2 2008/10/27 22:27:03 merlinofchaos Exp $ --> +Die Konfigurationsdatei der erweiterten Hilfe hat ein einfaches ini-Dateiformat, unterteilt in Bereiche für jede Hilfedatei sowie einen optionalen Bereich für globale Einstellungen, die für jede Hilfedatei vererbt werden können + +Die erste Zeile einer ini-Datei der erweiterten Hilfe sollte ;$Id $ sein, was ein Kommentar mit dem CVS-Identifier für die Datei darstellt. Das ; stellt ein Kommentarzeichen dar. Alles nach dem ; wird ignoriert. + +Globale Einstellungen können in einem Abschnitt mit dem Namen <strong>[advanced help settings]</strong> abgelegt werden -- dies bedeutet, dass dieser Name reserviert ist und it cannot be a help file in any module. Die folgenden Einstellungen können in diesem Abschnitt eingestellt werden: +<dl> +<dt><strong>line break</strong></dt> +<dd>Wenn auf irgendeinen Wert gesetzt, wird der Zeilenumbruchfilter auf alle Hilfedateien angewendet, die durch dieses Modul definiert sind, solange diese Hilfedatei nicht ausdrücklich anders eingestellt ist. Standardmäßig wird der Zeilenumbruchfilter nicht angewendet; Hilfedateien können aber einfacher zu schreiben sein, wenn der Zeilenumbruchfilter eingeschaltet ist.</dd> +<dt><strong>navigation</strong></dt> +<dd>Wenn auf wahr gesetzt, wird die Navigation am ende des Hilfethemas angezeigt: vorheriges Thema, nächstes Thema und untergeordnete Themen.</dd> +<dt><strong>CSS</strong></dt> +<dd>Es kann eine CSS-Datei (einschließlich der Erweiterung .css) angegeben werden, die für alle Hilfedateien verwendet wird (wenn sie nicht ersetzt wird). Diese CSS-Datei muss im Hilfe-Verzeichnis zusammen mit den HTML-Dateien vorhanden sein und wird von der Übersetzung nicht beeinflusst.</dd> +<dt><strong>name</strong></dt> +<dd>May be set to override the module name as displayed in both the module index as well as the navigation and breadcrumb trail. In general this does not need to be set, but a few modules may want to use a more friendly name than appears in the .info file.</dd> +<dt><strong>index name</strong></dt> +<dd>This may be set to change the name of the module in the module index. It overrides the 'name' setting above, as well as the module name in its .info file.</dd> +</dl> + +Jeder Abschnitt danach bezieht sich auf eine einzelne Hilfedatei, und jede davon kann die folgenden Einstellungen haben: +<dl> +<dt><strong>title</strong></dt> +<dd>Der Titel des Themas, das dem Benutzer angezeigt und in Links verwendet wird. Wenn es besondere Zeichen im Titel gibt müssen sie mit in Anführungszeichen gesetzt werden.</dd> +<dt><strong>file</strong></dt> +<dd>Der Dateiname ohne die Erweiterung .html, der für das Thema verwendet wird. Dies ist optional; wenn er nicht angegeben wird, ist der Name des Themas der Dateiname.</dd> +<dt><strong>weight</strong></dt> +<dd>Die Gewichtung, die für das Sortieren von Themen auf der Verwaltungsseite verwendet wird. Standardmäßig 0 wenn nicht angegeben. Elemente mit der gleichen Gewichtung werden alphabetisch sortiert.</dd> +<dt><strong>parent</strong></dt> +<dd>The topic ID to use in a hierarchy; children will be listed beneath parents in the topic list, and will have the parent in their breadcrumb trail. You may parent this topic to another module's topic by using module%topic as the identifier. For example, 'views%display' will make this a child of the 'display' topic in the 'views' module.</dd> +<dt><strong>line break</strong></dt> +<dd>Wenn auf wahr gesetzt, werden Zeilenumbrüche automatisch in br- und p-Tags konvertiert. Wenn nicht angegeben, ist der Standard AUS. Kann auf 0 gesetzt werden um den Filter zu deaktivieren, falls er in den globalen Einstellungen eingeschaltet ist.</dd> +<dt><strong>css</strong></dt> +<dd>Es kann eine CSS-Datei angegeben werden, die für diese Datei verwendet wird. Diese CSS-Datei muss im Hilfe-Verzeichnis zusammen mit den HTML-Dateien vorhanden sein. Dies überlagert eine CSS-Datei, die im globalen System hinzugefügt wurdeThis will override any .css file added by the global system.</dd> +<dt><strong>popup width</strong></dt> +<dd>Die Breite des Popup-Fensters in Pixel. Standardmäßig 500 wenn nicht angegeben.</dd> +<dt><strong>popup height</strong></dt> +<dd>Die Höhe des Popup-Fensters in Pixel. Standardmäßig 500 wenn nicht angegeben.</dd> +</dl> + +Hier ist zum Beispiel eine Version der Datei <strong>advanced_help.help.ini</strong>: +<pre> +[using-advanced-help] +title = "Using advanced help" +weight = -10 + +[translation] +title = Translating advanced help + +[ini-file] +title = Help .ini file format +line break = TRUE +</pre> \ No newline at end of file diff --git a/sites/all/modules/advanced_help/translations/help/de/translation.html b/sites/all/modules/advanced_help/translations/help/de/translation.html new file mode 100644 index 0000000000000000000000000000000000000000..881c40c5dc1e80af4ba38863f83a0142fe267e00 --- /dev/null +++ b/sites/all/modules/advanced_help/translations/help/de/translation.html @@ -0,0 +1,6 @@ +<!-- $Id: translation.html,v 1.1 2008/10/27 20:50:21 merlinofchaos Exp $ --> +<p>Um die erweiterte Hilfe zu übersetzen muss zuerst ein Verzeichnis <b>translations/help/$language</b> im Modulverzeichnis erstellt werden. Dann müssen die INI-Datei und alle HTML-Dateien aus dem Verzeichnis help kopiert werden. </p> + +<p>Die INI-Datei muss nur die Titel beinhalten; diese sollten übersetzt werden. Der Rest der Daten in der INI-Datei kann weggeworfen oder ignoriert werden.</p> + +<p>Jede Datei sollte dann an dieser Stelle übersetzt werden.</p> \ No newline at end of file diff --git a/sites/all/modules/advanced_help/translations/help/de/using-advanced-help.html b/sites/all/modules/advanced_help/translations/help/de/using-advanced-help.html new file mode 100644 index 0000000000000000000000000000000000000000..a728a223bc4ba4fb30540630749a26467eeecea9 --- /dev/null +++ b/sites/all/modules/advanced_help/translations/help/de/using-advanced-help.html @@ -0,0 +1,39 @@ +<!-- $Id: using-advanced-help.html,v 1.1 2008/10/27 20:50:21 merlinofchaos Exp $ --> +<p>Das System der <em>erweiterten Hilfe</em> ist ein modulares System, das erweiterte Hilfemöglichkeiten für Drupal und seine Module bereitstellt. Obwohl die erweiterte Hilfe selbst keine allgemeine Hilfe bereitstellt, stellt es ein mächtiges und einfaches Rahmenwerk zur Verfügung, das Module verwenden können, um ihre eigene Hilfe bereitzustellen. +</p> + +<p> +Module die die <em>erweiterte Hilfe</em> verwenden sollten ein Unterverzeichnis 'help' innerhalb des Modulverzeichnisses bereitstellen. Die Datei MODULENAME.help.ini muss in diesem Unterverzeichnis platziert werden, formatiert entsprechend dem nachfolgenden Beispiel: +</p> +<pre> +[buses] +title = "How buses are tied into the system" +file = buses + +[TOPIC_ID] +title = "Title of topic". +file = filename of topic, without the .html extension. +weight = How important the topic is on the index page. +parent = The optional topic parent to use in the breadcrumb, + either topic or module%topic. +</pre> + +<p> +Alle Themen werden durch das Modul, das die Hilfe bereitstellt, und die Themen-ID adressiert. Um Links einzubetten muss das folgende Format verwendet werden: +</p> +<code> +$output .= theme('advanced_help_topic', $module, $topic); +</code> + +<p>Innerhalb der Hilfedatei können andere Hilfethemen durch Verwendung des Formats <strong><a href="topic:module/topic"></strong> verlinkt werden. Dieses Format stellt sicher, dass der Popup-Status konsistent bleibt, wenn zwischen Links umgeschaltet wird.</p> + +<p>Mit <strong><a href="path:example.jpg"></strong> können Elemente innerhalb des Hilfe-Verzeichnisses referenziert werden wie z.B. Bilder, die im Hilfetext eingebettet werden sollen.</p> + +<p>Mit <strong><a href="base_url:admin/settings/site-configuration"></strong> kann jeder normale Pfad der Website referenziert werden.</p> + +<p>Wenn das Modul Search aktiviert ist, werden die Inhalte des Hilfesystems von Cron indexiert. Wenn neue Module aktiviert werden und der Hilfetext sofort indexiert werden soll, muss "Verwalten -> Berichte -> Statusreport" aufgerufen und der Link "Cron von hand starten" aufgerufen werden.</p> + +<p>Beispiel: <a href="path:nowhere.jpg">Nicht anklicken!</a></p> + +<p>Siehe: <a href="topic:advanced_help/ini-file">ini file format</a></p> +<p><strong>Hinweis: </strong> In älteren Versionen der erweiterten Hilfe war es nicht erforderlich &'s wrapped around the topic:, path:, and base_url: links. Dies wird momentan noch unterstützt, wird in einer zukünftigen Version aber möglicherweise entfernt. Durch das Hinzufügen der &'s sind diese Token jetzt nicht auf href=""- and src=""-Paramater begrenzt.</p> diff --git a/sites/all/modules/advanced_help/translations/help/de/why-advanced-help.html b/sites/all/modules/advanced_help/translations/help/de/why-advanced-help.html new file mode 100644 index 0000000000000000000000000000000000000000..c38574514e153acd81fc81c2af03e4e266980cdd --- /dev/null +++ b/sites/all/modules/advanced_help/translations/help/de/why-advanced-help.html @@ -0,0 +1,42 @@ +Das System der erweiterten Hilfe wurde entworfen um das Original-Hilfesystem von Drupal zu ersetzen, das mehrere FLAWS hat die es erschweren, neue Hilfe zu erstellen und existierende Hilfen zu pflegen und es besonders erschweren, auf die Hilfe zuzugreifen. + +Das primäre Ziel ist daher, die Zugänglichkeit der Hilfe zu verbessern, was die Fähigkeit sowohl für den Benutzer als auch den Hilfetext-Autor die Fähigkeit bedeutet, auf die erforderlichen Werkzeuge zuzugreifen um die Hilfe zu verwenden, zu erstellen, zu pflegen und zu übersetzen. + +Dieses System ist völlig getrnnt von Drupals hook_help(). In Drupal 6 koexistiert es damit; in Zukunft wird es hoffentlich hook_help() vollständig ersetzen, so dass es abgekündigt und ersetzt werden kann. + +Nachrichten am Anfang der Seite sind oft keine echte Hilfe. Oft sind diese Meldungen eine Einleitung in ein Formular oder EINE KURZE BLURB DIE dem Benutzer sagt was mit einer bestimmten Seite erledigt werden soll. Das Problen ist, dass diese Meldungen immer erscheinen, sie werden leicht ignoriert und sie erscheinen vor der eigentlichen Seite. Im Allgemeinen wollen Benutzer, wenn sie lernen, die Seite zuerst sehen und dann Fragen stellen. Die umgekehrte Reihenfolge is much less conducive to actually teaching a user how to use something. Durch die Möglichkeit, Hilfe auf Anfrage bereitzustellen, passt es mehr zur Arbeitsweise der meisten Personen. + +<h3><strong>Die erweiterte Hilfe ist nach Themen organisiert</strong></h3> +Mit der hook_help()-Methode ist der Hilfetext nach dem URL-Pfad organisiert. Dies ist gut wenn der Hilfetext beschreibt, wie eine bestimmte Seite zu verwenden ist oder was eine bestimmte Seite tut, es ist aber letztlich einschränken, weil Handbücher und Dokumentationen gewöhnlich nach Themen gruppiert sind und diese Themen vom Material selbst bestimmt werden. +Die erweiterte Hilfe ermöglicht dem Autor einer Dokumentation, Themen nach eigener Vorstellung zu organisieren; die wirklich einzige Einschränkung ist, dass jeder individuelle CHUNK OF TEXT als eigenes Thema STANDS ON. +Des weiteren können Module ihre Themen in die Hierarchie eines anderen Moduls einfügen. Dies würde dem Drupal-Kern ermöglichen, eine aufgabenbasiertes Hilfenavigationssystem zu erstellen, das Modulen erlaubt fließend Themen in diese Navigation einzufügen. Dies ermöglicht MOdulen, ihre Systeme getrennt zu halten und doch sich in das Hauptsystem zu integrieren. + +<h3><strong>Advanced help topics are processed HTML in their own files</strong></h3> +Diese Trennung vereinfacht das Finden und Anpassen. Momentan ist alles LUMPED TOGETER in hook_HELP() in PHP-Zeichenketten die durch t() laufen und es eine größere Menge PHP-Code in diesem System erforderlich, that actually gets in the way of writing good, explanatory text. + +In fact, requiring a documentation author to understand PHP at all is a detriment. The idea that documentation writers need to have PHP development as a skill seriously reduces the number of available contributors. HTML, on the other hand, is a much more common skill, is relatively easy to learn, and the amount of HTML needed to write documentation is only a little bit more than the HTML used in forum posts. + +Ein anderer Vorteil, PHP nicht zu verwenden ist dass die Dateien selbst sicher sind. Sie enthalten sehr wahrscheinlich keinen schädlichen PHP-Code der auf dem Server schlimme Dinger anrichtet. Dies bedeutet dass diese Dateien relativ einfach auf drupal.org-Hardware verwendet werden kann, so dass die Hilfedateien eines MOduls sofort verfügbar gemacht werden können ohne das Modul herunterladen zu müssen. Es bedeutet auch, dass Beschreibungen des Moduls auf drupal.org erstellt werden können, die VERSION AWARE sind, in CVS einfach mit Patches korrigiert werden können, aber auch zusammen mit dem Modul verfügbar gemacht werden können, so dass drupal.org nicht benötigt wird. + +Dies bedeutet, dass - falls gewünscht - die drupal.org-Handbücher oder eine Teilmenge davon, direkt in eine Drupal-Distribution oder ein Drupal-AddOn gepackt werden können, so dass Drupal-Administratoren ohne einen Besuch von Drupal.org Hilfe erhalten können. Dies kann in abgeschotteten Firmenumgebungen oder in Flugzeugen wertvoll sein. Aber noch wichtiger, die Handbücher können einfacher VERSION AWARE gemacht werden als die momentane Methode auf drupal.org. + +Die Kehrseite dieser Methode ist, dass diese Bücher nicht einfacch dynamisch gemacht werden können. Though the use of alter hooks could allow a module to make modifications to the help as needed, doing this could make the help files less useful when you take them out of context. + +<h3><strong>Die Dateien der weiterten Hilfe werden als Datei übersetzt</strong></h3> +Es ist momentan nicht einfach, Dokumente als Zeichenketten zu übersetzen, besonders wenn die verwendete Sprache sich sehr von Englisch unterscheidet. Beim Übersetzen eines Dokuments kann sich der Satzaufbau tatsächlich deutlich ändern. Es ist auch eine Last für die CPA, dies zu tun, da sehr lange Zeichenketten indiziert werden. + +Übersetzer haben es sehr viel einfacher, das Dokument als Einheit zu übersetzen, weil der gesamte Kontext gegenwärtig ist. + +<h3><strong>Die erweiterte Hilfe hat ihr eigenes Navigationssystem</strong></h3> +Mit Hilfe eines in einer INI-Datei angegebenen Navigationssystems (das kein PHP-Code ist daher sicher auf *.drupal.org -Websites verwendet werden kann), kann die Hilfe wie ein Buch strukturiert werden, wass typisch für Online-Handbücher ist. Dies ist Benutzern vertraut, kann organisiert (und umorganisiert) werden und ermöglicht einem Modul deutlich reichhaltigeren Text zu beinhalten ohne den PHP-Code damit zu überlasten, unnötig Hilfe zu laden. + +Durch dieses Buch kann auch hierarchisch navigiert werden, was es einfacher macht, aufeinander bezogene Themen miteinander zu verbinden. +<h3><strong>Die erweiterte Hilfe wird von der Suche-Engine indexiert</strong></h3> +Ein wichtige Ziel dieses Systems war, die Hilfe durchsuchbar zu machen. Die Fähigkeit, Schlüsselwörter in die Suchmaske einzugeben und relevante Themen zu finden, erhalten wir ein System das RESEMBLES die Art von Hilfe die mit vielen Betriebssytemen geliefert wird. Dies ist sehr wertvoll, wenn Handbücher danach durchsucht werden müssen, wie etwas bestimmtes gemacht wird. + +Diese Suche ist hilfespezifisch, was bedeuetet, dass die Hilfe nicht mit der globalen Suche in Beiträgen vermischt wird. Dies kann sowohl als Vorteil als auch als Nachteil betrachtet werden. Dieses Hilfesystem soll meistens Hilfe für Website-Administratoren bereitstellen, und Suchen in Inhalt soll sie nicht finden. Der Nachteil ist natürlich, dass sie nicht als Hilfe für Endanwender verwendet werden kann. + +<h3><strong>Eingebettete Hilfe kann via Popups aufgerufen werden</strong></h3> +Zusätzlich zur handbuchartigen hierarchischen Navigation kann die erweiterte Hilfe auch zusätzliche kontextsensitive Hilfe mittels Popup bereitstellen. Während Popups kontrovers betrachtet werden, ist das Argument für die Verwendung, dass die Hilfe erscheint während ein Formular angezeigt wird <i>und das Popup nicht die Daten des Benutzers verwirft</i>. Browser sind nicht sehr bedienerfreundlich bei der Eingabe von Formularen, wenn sie nicht gespeichert werden, und das Wegnavigieren von einem Formular kann gefährlich sein. Es gibt verschiedene andere Lösungen dieses Problems, aber jede hat ein DRAWBACK. DRAWBACKs von Popups sind recht bekannt, aber meistens irritiert es, ein neues Fenster zu erhalten. Wenn Hilfe angeforder wird ist ein Popup aber meistens erwünscht. Hilfe soll nicht den Vorgang stören, den der Benutzer abschließen möchte. Es unterscheidet sich wesentlich von einem unerwünschten Popup, das normalerweise Anzeigen oder Popups aufruft, die Benutzer vom Verlassen einer Website abhalten soll + +Diese Popus können einer Seite hinzugefügt werden mit Text- oder Icon-Links. \ No newline at end of file diff --git a/sites/all/modules/ctools/API.txt b/sites/all/modules/ctools/API.txt new file mode 100644 index 0000000000000000000000000000000000000000..2187e8a56cbfbf55e72a311a2fba0ba5914bd5b2 --- /dev/null +++ b/sites/all/modules/ctools/API.txt @@ -0,0 +1,12 @@ +API.txt: $Id: API.txt,v 1.16 2010/10/11 22:18:22 sdboyer Exp $ + +This file contains a log of changes to the API. +API Version 2.0 + Remove the deprecated callback-based behavior of the 'defaults' property on + plugin types; array addition is now the only option. If you need more + complex logic, do it with the 'process' callback. + Introduce a global plugin type registration hook and remove the per-plugin + type magic callbacks. + +Versions prior to 2.0 have been removed from this document. See the D6 version +for that information. diff --git a/sites/all/modules/ctools/CHANGELOG.txt b/sites/all/modules/ctools/CHANGELOG.txt new file mode 100644 index 0000000000000000000000000000000000000000..28967f3e7a1a85623f4e543e3ab38f6f014e2ff6 --- /dev/null +++ b/sites/all/modules/ctools/CHANGELOG.txt @@ -0,0 +1,75 @@ +Current API VERSION: 2.0. See API.txt for more information. + +ctools 7.x-1.x-alpha2 (05-Jan-2011) +=================================== + +#911396 by alex_b: Prevent notices in export UI. +#919768 by mikey_p: Allow url options to be sent to ctools_ajax_command_url(). +#358953 by cedarm: Allow term context to return lowercase, spaces to dashes versions of terms. +#931434 by EclipseGc: Argument plugin for node revision ID. +#910656: CTools AJAX sample wizard demo "domesticated" checkbox value not stored. +#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. +#938778 by dereine: Fix profile content type for D7 updates. +Add detach event to modal close so that wysiwyg can detach the editor. +Variant titles showing up as blank if more than one variant on a page. +#940016: token support was not yet updated for D7. +#940446: Skip validation on back and cancel buttons in all wizards. +#954492: Redirect not always working in wizard.inc +#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. +#955070 by EclipseGc: Update ctools internal page tokens to work properly on content all content. +#956890 by EclipseGc: Update views_content to not use views dependency since that is gone. +#954728 by EclipseGc: Update node template page function name to not collide with new hook_node_view(). +#946534 by EclipseGc: Add support for field content on all entitities. +#952586 by EclipseGc: Fix node_author content type. +#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.) +#961654 by benshell: drupal_alter() only supports 4 arguments. +#911362 by alex_b: Facilitate plugin cache resets for tests. +#945360 by naxoc: node_tag_new() not updated to D7. +#953804 by EclipseGc: Fix node comment rendering. +#953542 by EclipseGc: Fix node rendering. +#953776 by EclipseGc: Fix node link rendering. +#954772 by EclipseGc: Fix node build mode selection in node content type. +#954762 by EclipseGc: Fix comment forbidden theme call. +#954894 by EclipseGc: Fix breadcrumb content type. +#955180 by EclipseGc: Fix page primary navigation type. +#957190 by EclipseGc: Fix page secondary navigation type. +#957194 by EclipseGc: Remove mission content type, since D7 no longer has a site mission. +#957348 by EclipseGc: Fix search form URL path. +#952586 by andypost: Use format_username for displaying unlinked usernames. +#963800 by benshell: Fix query to fetch custom block title. +#983496 by Amitaibu: Fix term argument to use proper load function. +#989484 by Amitaibu: Fix notice in views plugin. +#982496: Fix token context. +#995026: Fix export UI during enable/disable which would throw notices and not properly set/unset menu items. +#998870 by Amitaibu: Fix notice when content has no icon by using function already designed for that. +#983576 by Amitaibu: Node view fallback task showed white screen. +#1004644 by pillarsdotnet: Update a missed theme() call to D7. +#1006162 by aspilicious: .info file cleanup. +#998312 by dereine: Support the expanded/hidden options that Views did for dependent.js +#955030: Remove no longer supported footer message content type. +Fix broken query in term context config. +#992022 by pcambra: Fix node autocomplete. +#946302 by BerdArt and arywyr: Fix PHP 5.3 reference error. +#980528 by das-peter: Notice fix with entity settings. +#999302 by troky: ctools_jump_menu() needed updating to new form parameters. +#964174: stylizer plugin theme delegation was in the wrong place, causing errors. +#991658 by burlap: Fully load the "user" context for the logged in user because not all fields are in $user. +#1014866 by das-peter: Smarter title panes, notice fix on access plugin descriptions. +#1015662 by troky: plugin .info files were not using correct filepaths. +#941780 by EclipseGc: Restore the "No blocks" functionality. +#951048 by EclipseGc: Tighter entity integration so that new entities are automatic contexts and relationships. +#941800 by me and aspilicious: Use Drupal 7 #machine_name automation on page manager pages and all export_ui defaults. +Disabled exportables and pages not properly greyed out. +#969208 by me and benshell: Get user_view and user profile working. +#941796: Recategorize blocks + +ctools 7.x-1.x-alpha1 +===================== + +Changelog reset for 7.x +Basic conversion done during sprint. diff --git a/sites/all/modules/ctools/LICENSE.txt b/sites/all/modules/ctools/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..2c095c8d3f42488e8168f9710a4ffbfc4125a159 --- /dev/null +++ b/sites/all/modules/ctools/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/sites/all/modules/ctools/UPGRADE.txt b/sites/all/modules/ctools/UPGRADE.txt new file mode 100644 index 0000000000000000000000000000000000000000..844ecce42ad4cff3ccb01a86ad83aa8ec656cd74 --- /dev/null +++ b/sites/all/modules/ctools/UPGRADE.txt @@ -0,0 +1,63 @@ +Upgrading from ctools-6.x-1.x to ctools-7.x-2.x: + + - Remove ctools_ajax_associate_url_to_element as it shouldn't be necessary + with the new AJAX api's in Drupal core. + + - All calls to the ctools_ajax_command_prepend() should be replace with + the core function ajax_command_prepend(); + This is also the case for append, insert, after, before, replace, html, + and remove commands. + Each of these commands have been incorporated into the + Drupal.ajax.prototype.commands.insert + function with a corresponding parameter specifying which method to use. + + - All calls to ctools_ajax_render() should be replaced with calls to core + ajax_render(). Note that ctools_ajax_render() printed the json object and + exited, ajax_render() gives you this responsibility. + + ctools_ajax_render() + + becomes + + print ajax_render(); + exit; + + - All calls to ctools_static*() should be replaced with corresponding calls + to drupal_static*(). + + - All calls to ctools_css_add_css should be replaced with calls to + drupal_add_css(). Note that the arguments to drupal_add_css() have changed. + + - All wizard form builder functions must now return a form array(). + + - ctools_build_form is very close to being removed. In anticipation of this, + all $form_state['wrapper callback']s must now be + $form_state['wrapper_callback']. In addition to this $form_state['args'] + must now be $form_state['build_info']['args']. + + NOTE: Previously checking to see if the return from ctools_build_form() + is empty would be enough to see if the form was submitted. This is no + longer true. Please check for $form_state['executed']. If using a wizard + check for $form_state['complete']. + + - Plugin types now must be explicitly registered via a registration hook, + hook_ctools_plugin_type(); info once provided in magically-named functions + (e.g., ctools_ctools_plugin_content_types() was the old function to + provide plugin type info for ctools' content_type plugins) now must be + provided in that global hook. See http://drupal.org/node/910538 for more + details. + + - Plugins that use 'theme arguments' now use 'theme variables' instead. + + - Context, argument and relationship plugins now use 'add form' and/or + 'edit form' rather than 'settings form'. These plugins now support + form wizards just like content plugins. These forms now all take + $form, &$form_state as arguments, and the configuration for the plugin + can be found in $form_state['conf']. + + For all these forms, the submit handler MUST put appropriate data in + $form_state['conf']. Data will no longer be stored automatically. + + For all of these forms, the separate settings #trees in the form are now + gone, so form ids may be adjusted. Also, these are now all real forms + using CTools form wizard instead of fake subforms as previously. \ No newline at end of file diff --git a/sites/all/modules/ctools/bulk_export/bulk_export.css b/sites/all/modules/ctools/bulk_export/bulk_export.css new file mode 100644 index 0000000000000000000000000000000000000000..a7df2cf5c168adb301022b4bc104a6a3f045dc4f --- /dev/null +++ b/sites/all/modules/ctools/bulk_export/bulk_export.css @@ -0,0 +1,18 @@ +/* $Id: bulk_export.css,v 1.1 2009/07/12 11:32:30 sdboyer Exp $ */ + +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/sites/all/modules/ctools/bulk_export/bulk_export.info b/sites/all/modules/ctools/bulk_export/bulk_export.info new file mode 100644 index 0000000000000000000000000000000000000000..12f230b25bca6c10e8311fe26a50b32233fc5c87 --- /dev/null +++ b/sites/all/modules/ctools/bulk_export/bulk_export.info @@ -0,0 +1,13 @@ +; $Id: bulk_export.info,v 1.4 2011/01/01 00:01:46 merlinofchaos Exp $ +name = Bulk Export +description = Performs bulk exporting of data objects known about by Chaos tools. +core = 7.x +dependencies[] = ctools +package = Chaos tool suite + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-1.0-alpha2" +core = "7.x" +project = "ctools" +datestamp = "1294276864" + diff --git a/sites/all/modules/ctools/bulk_export/bulk_export.module b/sites/all/modules/ctools/bulk_export/bulk_export.module new file mode 100644 index 0000000000000000000000000000000000000000..9ac962ce07294618045f357292c522bc7b7b8e37 --- /dev/null +++ b/sites/all/modules/ctools/bulk_export/bulk_export.module @@ -0,0 +1,205 @@ +<?php +// $Id: bulk_export.module,v 1.6 2010/10/11 22:18:24 sdboyer Exp $ + +/** + * @file + * Perform bulk exports. + */ + +/** + * Implements hook_permission(). + */ +function bulk_export_permission() { + return array( + 'use bulk exporter' => array( + 'title' => t('Access Bulk Exporter'), + 'description' => t('Export various system objects into code.'), + ), + ); +} + +/** + * Implements hook_menu(). + */ +function bulk_export_menu() { + $items['admin/structure/bulk-export'] = 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/structure/bulk-export/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) { + $form_state = array( + 're_render' => FALSE, + 'no_redirect' => TRUE, + 'exportables' => $exportables, + 'export_tables' => $export_tables, + ); + $output = drupal_build_form('bulk_export_export_form', $form_state); + if (!empty($form_state['submitted'])) { + 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 .= "// \$Id" . ": $\n\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_render(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 .= "// \$Id" . ": $\n\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_render(drupal_get_form('ctools_export_form', $module, t('Place this in @file', array('@file' => $form_state['module'] . '.module')))) . $output; + } + + $info = "; \$Id" . ": $\n"; // The break in the string prevents CVS from subbing the ID. + $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 = 7.x\n"; + $info .= "files[] = " . check_plain($form_state['module'] . '.info') . "\n"; + $output = drupal_render(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, &$form_state) { + $form['tables'] = array( + '#prefix' => '<div class="clearfix">', + '#suffix' => '</div>', + '#tree' => TRUE, + ); + + $files = system_rebuild_module_data(); + + $options = array(); + foreach ($form_state['exportables'] as $table => $list) { + if (empty($list)) { + continue; + } + + foreach ($list as $id => $title) { + $options[$table][$id] = array($title); + } + + $module = $form_state['export_tables'][$table]; + $header = array("{$files[$module]->info['name']}: $table"); + + $form['tables'][$table] = array( + '#prefix' => '<div class="export-container">', + '#suffix' => '</div>', + '#type' => 'tableselect', + '#header' => $header, + '#options' => $options[$table], + ); + } + + $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/structure/bulk-export/results'); + $form['#attached']['css'][] = drupal_get_path('module', 'bulk_export') . '/bulk_export.css'; + return $form; +} + +/** + * 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/sites/all/modules/ctools/bulk_export/translations/bulk_export.hu.po b/sites/all/modules/ctools/bulk_export/translations/bulk_export.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..02b0ae1e84b6bb561970a6285ecdac57bcea947c --- /dev/null +++ b/sites/all/modules/ctools/bulk_export/translations/bulk_export.hu.po @@ -0,0 +1,40 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-11-30 12:52+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 "Module name" +msgstr "Modulnév" +msgid "Enter the module name to export code to." +msgstr "A modul nevének megadása amibe a kódot exportálni kell." +msgid "Bulk export results" +msgstr "Tömeges export eredményei" +msgid "Place this in @file" +msgstr "Elhelyézés ide: @file" +msgid "There are no objects to be exported at this time." +msgstr "Jelenleg nincsenek exportált objektumok." +msgid "There are no objects in your system that may be exported at this time." +msgstr "" +"Jelenleg nincsenek olyan objektumok a rendszerben amiket exportálni " +"lehetne." +msgid "use bulk exporter" +msgstr "tömeges exportáló használata" +msgid "Bulk Exporter" +msgstr "Tömeges exportáló" +msgid "Bulk-export multiple CTools-handled data objects to code." +msgstr "Több CTools által kezelt adatobjektum tömeges exportálása kódba." +msgid "Bulk Export" +msgstr "Bulk Export" +msgid "Performs bulk exporting of data objects known about by Chaos tools." +msgstr "" +"A <em>Chaos tools</em> modul által ismert adatobjektumok tömeges " +"exportálása." diff --git a/sites/all/modules/ctools/bulk_export/translations/bulk_export.pot b/sites/all/modules/ctools/bulk_export/translations/bulk_export.pot new file mode 100644 index 0000000000000000000000000000000000000000..ee251d16233dad04d4adbcb98fdcd1389e9c347d --- /dev/null +++ b/sites/all/modules/ctools/bulk_export/translations/bulk_export.pot @@ -0,0 +1,69 @@ +# $Id: bulk_export.pot,v 1.1 2009/08/16 19:13:58 hass Exp $ +# +# LANGUAGE translation of Drupal (bulk_export) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# bulk_export.module,v 1.3 2009/07/22 21:12:07 merlinofchaos +# bulk_export.info,v 1.2 2009/07/12 18:11:58 merlinofchaos +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-08-16 20:47+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" + +#: bulk_export/bulk_export.module:68 +msgid "Bulk export results" +msgstr "" + +#: bulk_export/bulk_export.module:92;116;127 +msgid "Place this in @file" +msgstr "" + +#: bulk_export/bulk_export.module:133 +msgid "There are no objects to be exported at this time." +msgstr "" + +#: bulk_export/bulk_export.module:159 +msgid "Module name" +msgstr "" + +#: bulk_export/bulk_export.module:160 +msgid "Enter the module name to export code to." +msgstr "" + +#: bulk_export/bulk_export.module:200 +msgid "There are no objects in your system that may be exported at this time." +msgstr "" + +#: bulk_export/bulk_export.module:13 +msgid "use bulk exporter" +msgstr "" + +#: bulk_export/bulk_export.module:31 +msgid "Bulk Exporter" +msgstr "" + +#: bulk_export/bulk_export.module:32 +msgid "Bulk-export multiple CTools-handled data objects to code." +msgstr "" + +#: bulk_export/bulk_export.module:0 +msgid "bulk_export" +msgstr "" + +#: bulk_export/bulk_export.info:0 +msgid "Bulk Export" +msgstr "" + +#: bulk_export/bulk_export.info:0 +msgid "Performs bulk exporting of data objects known about by Chaos tools." +msgstr "" + diff --git a/sites/all/modules/ctools/css/collapsible-div.css b/sites/all/modules/ctools/css/collapsible-div.css new file mode 100644 index 0000000000000000000000000000000000000000..b1fc6e1a8947c5a218f3f5b18fb51028886e560f --- /dev/null +++ b/sites/all/modules/ctools/css/collapsible-div.css @@ -0,0 +1,19 @@ +/* $Id: collapsible-div.css,v 1.2 2008/11/27 17:29:34 merlinofchaos Exp $ */ + +.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/sites/all/modules/ctools/css/context.css b/sites/all/modules/ctools/css/context.css new file mode 100644 index 0000000000000000000000000000000000000000..8522156bafa7c60564728d430af95b483a584bc7 --- /dev/null +++ b/sites/all/modules/ctools/css/context.css @@ -0,0 +1,11 @@ +/* $Id: context.css,v 1.2 2008/12/05 00:15:36 merlinofchaos Exp $ */ +.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/sites/all/modules/ctools/css/ctools.css b/sites/all/modules/ctools/css/ctools.css new file mode 100644 index 0000000000000000000000000000000000000000..4dede743a68b3336d639a7955ae25e86784ba5ab --- /dev/null +++ b/sites/all/modules/ctools/css/ctools.css @@ -0,0 +1,26 @@ +/* $Id: ctools.css,v 1.5 2010/09/07 09:02:50 sdboyer Exp $ */ +.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/sites/all/modules/ctools/css/dropdown.css b/sites/all/modules/ctools/css/dropdown.css new file mode 100644 index 0000000000000000000000000000000000000000..f1ad4792ea5b7689606cfb05f2ebf701b8193de3 --- /dev/null +++ b/sites/all/modules/ctools/css/dropdown.css @@ -0,0 +1,74 @@ +/* $Id: dropdown.css,v 1.6 2010/10/11 22:18:23 sdboyer Exp $ */ +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; + margin: 0; + padding: 0; +} + +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/sites/all/modules/ctools/css/export-ui-list.css b/sites/all/modules/ctools/css/export-ui-list.css new file mode 100644 index 0000000000000000000000000000000000000000..f53d886d1c097cea13001840c7d7c911952ce9f3 --- /dev/null +++ b/sites/all/modules/ctools/css/export-ui-list.css @@ -0,0 +1,33 @@ +/* $Id: export-ui-list.css,v 1.3 2011/01/05 23:16:59 merlinofchaos Exp $ */ +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 td { + color: #999; +} + +th.ctools-export-ui-operations, +td.ctools-export-ui-operations { + text-align: right; /* LTR */ +} diff --git a/sites/all/modules/ctools/css/modal.css b/sites/all/modules/ctools/css/modal.css new file mode 100644 index 0000000000000000000000000000000000000000..c3faf2d7272a650b2a3acace607b7cc43ea2207d --- /dev/null +++ b/sites/all/modules/ctools/css/modal.css @@ -0,0 +1,128 @@ +/* $Id: modal.css,v 1.9 2011/01/01 00:31:27 merlinofchaos Exp $ */ +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; +} + +div.ctools-modal-content label.hidden-options { + background: transparent url(../images/arrow-active.png) no-repeat right; + height: 12px; + padding-right: 12px; +} + +div.ctools-modal-content label.expanded-options { + background: transparent url(../images/expanded-options.png) no-repeat right; + height: 12px; + padding-right: 16px; +} + +div.ctools-modal-content .option-text-aligner label.expanded-options, +div.ctools-modal-content .option-text-aligner label.hidden-options { + background: none; +} + + +div.ctools-modal-content .dependent-options { + padding-left: 30px; +} diff --git a/sites/all/modules/ctools/css/ruleset.css b/sites/all/modules/ctools/css/ruleset.css new file mode 100644 index 0000000000000000000000000000000000000000..891455f019994aeb4732a2b20a5c517929e93a2d --- /dev/null +++ b/sites/all/modules/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/sites/all/modules/ctools/css/stylizer.css b/sites/all/modules/ctools/css/stylizer.css new file mode 100644 index 0000000000000000000000000000000000000000..4a63f408700aba7b9efb407fe996ce52788fa1a6 --- /dev/null +++ b/sites/all/modules/ctools/css/stylizer.css @@ -0,0 +1,130 @@ +/* $Id: stylizer.css,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ */ + +/* 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/sites/all/modules/ctools/css/wizard.css b/sites/all/modules/ctools/css/wizard.css new file mode 100644 index 0000000000000000000000000000000000000000..ce305f8655b7c7f8611b3025066bafae25c54cde --- /dev/null +++ b/sites/all/modules/ctools/css/wizard.css @@ -0,0 +1,9 @@ +/* $Id: wizard.css,v 1.1 2008/12/06 02:13:48 merlinofchaos Exp $ */ + +.wizard-trail { + font-size: 120%; +} + +.wizard-trail-current { + font-weight: bold; +} diff --git a/sites/all/modules/ctools/ctools.api.php b/sites/all/modules/ctools/ctools.api.php new file mode 100644 index 0000000000000000000000000000000000000000..78ae15c9b2030c6178bad628665268bf8d0b5258 --- /dev/null +++ b/sites/all/modules/ctools/ctools.api.php @@ -0,0 +1,87 @@ +<?php +// $Id: ctools.api.php,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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). +} + +/** + * @} End of "addtogroup hooks". + */ \ No newline at end of file diff --git a/sites/all/modules/ctools/ctools.info b/sites/all/modules/ctools/ctools.info new file mode 100644 index 0000000000000000000000000000000000000000..81a66f2f34fd7e3eb1083edacf82c335cc166e0c --- /dev/null +++ b/sites/all/modules/ctools/ctools.info @@ -0,0 +1,15 @@ +; $Id: ctools.info,v 1.10 2011/01/01 00:01:46 merlinofchaos Exp $ +name = Chaos tools +description = A library of helpful tools by Merlin of Chaos. +core = 7.x +package = Chaos tool suite +files[] = includes/context.inc +files[] = includes/math-expr.inc +files[] = includes/stylizer.inc + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-1.0-alpha2" +core = "7.x" +project = "ctools" +datestamp = "1294276864" + diff --git a/sites/all/modules/ctools/ctools.install b/sites/all/modules/ctools/ctools.install new file mode 100644 index 0000000000000000000000000000000000000000..c050f2283926957061899cb88bc02e53b64feb4c --- /dev/null +++ b/sites/all/modules/ctools/ctools.install @@ -0,0 +1,198 @@ +<?php +// $Id: ctools.install,v 1.15 2010/09/07 09:02:50 sdboyer Exp $ + +/** + * @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') { + $requirements['ctools_css_cache'] = array( + 'title' => t('CTools CSS Cache'), + 'severity' => REQUIREMENT_OK, + 'value' => t('Exists'), + ); + + $path = 'public://ctools/css'; + if (!file_prepare_directory($path, FILE_CREATE_DIRECTORY)) { + $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' => file_uri_target($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; +} + +/** + * Implements 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() { + // Perform updates like this to reduce code duplication. + $schema = ctools_schema_2(); + + db_change_field('ctools_object_cache', 'name', 'name', $schema['ctools_object_cache']['fields']['name']); +} + +/** + * Add the new css cache table. + */ +function ctools_update_6002() { + // Schema 2 is locked and should not be changed. + $schema = ctools_schema_2(); + + db_create_table('ctools_css_cache', $schema['ctools_css_cache']); +} + +/** + * Take over for the panels_views module if it was on. + */ +function ctools_update_6003() { + $result = db_query('SELECT status FROM {system} WHERE name = :name', array(':name' => 'panels_views'))->fetchField(); + if ($result) { + db_delete('system')->condition('name', 'panels_views')->execute(); + drupal_install_modules(array('views_content')); + } +} + +/** + * Add primary key to the ctools_object_cache table. + */ +function ctools_update_6004() { + db_add_primary_key('ctools_object_cache', array('sid', 'obj', 'name')); + db_drop_index('ctools_object_cache', 'sid_obj_name'); +} + +/** + * 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/sites/all/modules/ctools/ctools.module b/sites/all/modules/ctools/ctools.module new file mode 100644 index 0000000000000000000000000000000000000000..3b90bb7393298e7914f864ff7b4e01147dfa9eaf --- /dev/null +++ b/sites/all/modules/ctools/ctools.module @@ -0,0 +1,743 @@ +<?php +// $Id: ctools.module,v 1.40 2011/01/05 20:06:57 merlinofchaos Exp $ + +/** + * @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', '2.0-alpha1'); + +/** + * 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_ROOT . '/' . 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"); +} + +/** + * Format a javascript file name for use with $form['#attached']['js']. + * + * 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. + * + * @code + * $form['#attached']['js'] = array(ctools_attach_js('auto-submit')); + * @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_attach_js($file, $module = 'ctools', $dir = 'js') { + return drupal_get_path('module', $module) . "/$dir/$file.js"; +} + +/** + * 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 = user_roles(TRUE); + unset($roles[DRUPAL_AUTHENTICATED_RID]); + } + + 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) { + $string = '<!-- ctools-page-' . $token . ' -->'; + ctools_set_page_token($string, 'callback', $callback); + return $string; +} + +/** + * Tell CTools that sidebar blocks should not be rendered. + * + * It is often desirable to not display sidebars when rendering a page, + * particularly when using Panels. This informs CTools to alter out any + * sidebar regions during block render. + */ +function ctools_set_no_blocks($blocks = FALSE) { + $status = &drupal_static(__FUNCTION__, TRUE); + $status = $blocks; +} + +// ----------------------------------------------------------------------- +// 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/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); + } + } +} + +/** + * Implements hook_theme(). + */ +function ctools_theme() { + ctools_include('utility'); + $items = array(); + _ctools_passthrough($items, 'theme'); + return $items; +} + +/** + * Implements hook_menu(). + */ +function ctools_menu() { + ctools_include('utility'); + $items = array(); + _ctools_passthrough($items, 'menu'); + return $items; +} + +/** + * Implementation of hook_cron. Clean up old caches. + */ +function ctools_cron() { + ctools_include('utility'); + _ctools_passthrough($items, 'cron'); +} + +/** + * 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; +} + +/** + * 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); + } + } +} + +/** + * Implements hook_registry_files_alter(). + * + * Alter the registry of files to automagically include all classes in + * class-based plugins. + */ +function ctools_registry_files_alter(&$files, $indexed_modules) { + ctools_include('registry'); + return _ctools_registry_files_alter($files, $indexed_modules); +} + +// ----------------------------------------------------------------------- +// 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; + } +} + +/** + * Implements hook_ctools_plugin_type(). + */ +function ctools_ctools_plugin_type() { + ctools_include('utility'); + $items = array(); + // Add all the plugins that have their own declaration space elsewhere. + _ctools_passthrough($items, 'plugin-type'); + + return $items; +} + +// ----------------------------------------------------------------------- +// Drupal theme preprocess hooks that must be in the .module file. + +/** + * 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); + } +} + +function ctools_page_alter(&$page) { + $page['#post_render'][] = 'ctools_page_token_processing'; +} + +/** + * A theme post_render callback to allow content type plugins to use page + * template variables which are not yet available when the content type is + * rendered. + */ +function ctools_page_token_processing($children, $elements) { + $tokens = ctools_set_page_token(); + if (!empty($tokens)) { + foreach ($tokens as $token => $key) { + list($type, $argument) = $key; + switch ($type) { + case 'variable': + $tokens[$token] = isset($variables[$argument]) ? $variables[$argument] : ''; + break; + case 'callback': + if (is_string($argument) && function_exists($argument)) { + $tokens[$token] = $argument($variables); + } + if (is_array($argument) && function_exists($argument[0])) { + $function = array_shift($argument); + $argument = array_merge(array(&$variables), $argument); + $tokens[$token] = call_user_func_array($function, $argument); + } + break; + } + } + $children = strtr($children, $tokens); + } + return $children; +} + +// ----------------------------------------------------------------------- +// 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 = &drupal_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) { + dsm('should not be called!'); + return; +} + +/** + * Cache callback on behalf of ctools_export_ui. + */ +function ctools_export_ui_context_cache_set($plugin_name, $key, $item) { + dsm('should not be called!'); + return; +} + +/** + * 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, 2); + + $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, 2); + + $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); + } +} + +/** + * Implements hook_menu_local_tasks_alter(). + */ +function ctools_menu_local_tasks_alter(&$data, $router_item, $root_path) { + ctools_include('menu'); + _ctools_menu_add_dynamic_items($data, $router_item, $root_path); +} + +/** + * Implement hook_block_list_alter() to potentially remove blocks. + * + * This exists in order to replicate Drupal 6's "no blocks" functionality. + */ +function ctools_block_list_alter(&$blocks) { + $check = drupal_static('ctools_set_no_blocks', TRUE); + if (!$check) { + foreach ($blocks as $block_id => $block) { + // @todo -- possibly we can set configuration for this so that users can + // specify which blocks will not get rendered. + if (substr_compare($block->region, 'sidebar', 0)) { + unset($blocks[$block_id]); + } + } + } +} + diff --git a/sites/all/modules/ctools/ctools_access_ruleset/ctools_access_ruleset.info b/sites/all/modules/ctools/ctools_access_ruleset/ctools_access_ruleset.info new file mode 100644 index 0000000000000000000000000000000000000000..34697927ca949dc1e84bbde684b99963962fb9c3 --- /dev/null +++ b/sites/all/modules/ctools/ctools_access_ruleset/ctools_access_ruleset.info @@ -0,0 +1,13 @@ +; $Id: ctools_access_ruleset.info,v 1.3 2011/01/01 00:01:46 merlinofchaos Exp $ +name = Custom rulesets +description = Create custom, exportable, reusable access rulesets for applications like Panels. +core = 7.x +package = Chaos tool suite +dependencies[] = ctools + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-1.0-alpha2" +core = "7.x" +project = "ctools" +datestamp = "1294276864" + diff --git a/sites/all/modules/ctools/ctools_access_ruleset/ctools_access_ruleset.install b/sites/all/modules/ctools/ctools_access_ruleset/ctools_access_ruleset.install new file mode 100644 index 0000000000000000000000000000000000000000..b5278fa85022b8ae430f68eb24e0f3acdddfd488 --- /dev/null +++ b/sites/all/modules/ctools/ctools_access_ruleset/ctools_access_ruleset.install @@ -0,0 +1,83 @@ +<?php +// $Id: ctools_access_ruleset.install,v 1.2 2010/10/11 22:18:24 sdboyer Exp $ + +/** + * 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; +} diff --git a/sites/all/modules/ctools/ctools_access_ruleset/ctools_access_ruleset.module b/sites/all/modules/ctools/ctools_access_ruleset/ctools_access_ruleset.module new file mode 100644 index 0000000000000000000000000000000000000000..6d320e277863f326105eafcf9c9daf552b60663d --- /dev/null +++ b/sites/all/modules/ctools/ctools_access_ruleset/ctools_access_ruleset.module @@ -0,0 +1,86 @@ +<?php +// $Id: ctools_access_ruleset.module,v 1.3 2011/01/05 22:57:26 merlinofchaos Exp $ + +/** + * @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_permission() + */ +function ctools_access_ruleset_permission() { + return array( + 'administer ctools access ruleset' => array( + 'title' => t('Administer access rulesets'), + 'description' => t('Add, delete and edit custom access rulesets.'), + ), + ); +} + +/** + * 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/structure/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/structure/ctools-rulesets/list/$item->name/edit"), + 'class' => 'links', + ), + ); + + // Only show 10. + if (++$count >= 10) { + break; + } + } + + if ($rows) { + $content = theme('table', array('rows' => $rows, 'attributes' => 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/structure/ctools-rulesets'), + 'content' => $content, + 'class' => 'dashboard-ruleset', + 'section' => 'right', + ); +} diff --git a/sites/all/modules/ctools/ctools_access_ruleset/plugins/access/ruleset.inc b/sites/all/modules/ctools/ctools_access_ruleset/plugins/access/ruleset.inc new file mode 100644 index 0000000000000000000000000000000000000000..d8de9c212d34064318f8abab2e8941499742e42e --- /dev/null +++ b/sites/all/modules/ctools/ctools_access_ruleset/plugins/access/ruleset.inc @@ -0,0 +1,101 @@ +<?php +// $Id: ruleset.inc,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/ctools_access_ruleset/plugins/export_ui/ctools_access_ruleset.inc b/sites/all/modules/ctools/ctools_access_ruleset/plugins/export_ui/ctools_access_ruleset.inc new file mode 100644 index 0000000000000000000000000000000000000000..a1a2db47cd1f002cac81253684fcd3a89b851338 --- /dev/null +++ b/sites/all/modules/ctools/ctools_access_ruleset/plugins/export_ui/ctools_access_ruleset.inc @@ -0,0 +1,30 @@ +<?php +// $Id: ctools_access_ruleset.inc,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ + +$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' => 'ctools_access_ruleset_ui', + + 'use wizard' => TRUE, + 'form info' => array( + 'order' => array( + 'basic' => t('Basic information'), + 'context' => t('Contexts'), + 'rules' => t('Rules'), + ), + ), +); + diff --git a/sites/all/modules/ctools/ctools_access_ruleset/plugins/export_ui/ctools_access_ruleset_ui.class.php b/sites/all/modules/ctools/ctools_access_ruleset/plugins/export_ui/ctools_access_ruleset_ui.class.php new file mode 100644 index 0000000000000000000000000000000000000000..540e3d2a644f3c00d3d4554ac3948470e7ddc722 --- /dev/null +++ b/sites/all/modules/ctools/ctools_access_ruleset/plugins/export_ui/ctools_access_ruleset_ui.class.php @@ -0,0 +1,54 @@ +<?php +// $Id: ctools_access_ruleset_ui.class.php,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ + +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 clearfix">', + '#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 = '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 = ctools_access_admin_form($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/sites/all/modules/ctools/ctools_ajax_sample/css/ctools-ajax-sample.css b/sites/all/modules/ctools/ctools_ajax_sample/css/ctools-ajax-sample.css new file mode 100644 index 0000000000000000000000000000000000000000..dc83b0b0f95e0350306f28f02cc43315fdcd61f5 --- /dev/null +++ b/sites/all/modules/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/sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.info b/sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.info new file mode 100644 index 0000000000000000000000000000000000000000..79e33ffe6038c5449a52074166ac66be67103437 --- /dev/null +++ b/sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.info @@ -0,0 +1,13 @@ +; $Id: ctools_ajax_sample.info,v 1.3 2011/01/01 00:01:46 merlinofchaos Exp $ +name = Chaos Tools (CTools) AJAX Example +description = Shows how to use the power of Chaos AJAX. +package = Chaos tool suite +dependencies[] = ctools +core = 7.x + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-1.0-alpha2" +core = "7.x" +project = "ctools" +datestamp = "1294276864" + diff --git a/sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.install b/sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.install new file mode 100644 index 0000000000000000000000000000000000000000..ee2b6d90aacf6206a69cbfd30734e38311b376a3 --- /dev/null +++ b/sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.install @@ -0,0 +1,20 @@ +<?php +// $Id: ctools_ajax_sample.install,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * @file + */ + +/** + * Implementation of hook_install() + */ +function ctools_ajax_sample_install() { + +} + +/** + * Implementation of hook_uninstall() + */ +function ctools_ajax_sample_uninstall() { + +} diff --git a/sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.module b/sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.module new file mode 100644 index 0000000000000000000000000000000000000000..c261d9c831fc3ec987dae5169942df9cad19cf6a --- /dev/null +++ b/sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.module @@ -0,0 +1,745 @@ +<?php +// $Id: ctools_ajax_sample.module,v 1.5 2010/12/31 23:58:52 merlinofchaos Exp $ + +/** + * @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/simple_form'] = array( + 'title' => 'Simple Form', + 'page callback' => 'ctools_ajax_simple_form', + '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, + ); + $items['ctools_ajax_sample/jumped'] = array( + 'title' => 'Successful Jumping', + 'page callback' => 'ctools_ajax_sample_jump_menu_page', + 'access callback' => TRUE, + 'type' => MENU_NORMAL_ITEM, + ); + + return $items; +} + +function ctools_ajax_simple_form() { + ctools_include('content'); + ctools_include('context'); + $node = node_load(1); + $context = ctools_context_create('node', $node); + $context = array('context_node_1' => $context); + return ctools_content_render('node_comment_form', 'node_comment_form', ctools_ajax_simple_form_pane(), array(), array(), $context); +} + +function ctools_ajax_simple_form_pane() { + $configuration = array( + 'anon_links' => 0, + 'context' => 'context_node_1', + 'override_title' => 0, + 'override_title_text' => '', + ); + return $configuration; +} + +/** + * 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', array('path' => ctools_image_path('ajax-loader.gif', 'ctools_ajax_sample'), 'alt' => t('Loading...'), 'title' => 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'); + } + + // Four ways to do our animal picking wizard. + $button_form = ctools_ajax_sample_ajax_button_form(); + $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[] = drupal_render($button_form); + + $links[] = ctools_ajax_text_button(t('Hello world!'), "ctools_ajax_sample/nojs/hello", t('Replace text with "hello world"')); + + $output = theme('item_list', array('items' => $links, 'title' => t('Actions'))); + + // This container will have data AJAXed into it. + $output .= theme('ctools_ajax_sample_container', array('content' => '<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' => array('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', array('header' => $header, 'rows' => $rows, array('class' => array('ajax-sample-table')))); + + // Show examples of ctools javascript widgets + $output .= '<h2>'. t('CTools Javascript Widgets') .'</h2>'; + + // Create a drop down menu + $links = array(); + $links[] = array('title' => t('Link 1'), 'href' => $_GET['q']); + $links[] = array('title' => t('Link 2'), 'href' => $_GET['q']); + $links[] = array('title' => t('Link 3'), 'href' => $_GET['q']); + + $output .= '<h3>' . t('Drop Down Menu') . '</h3>'; + $output .= theme('ctools_dropdown', array('title' => t('Click to Drop Down'), 'links' => $links)); + + // Create a collapsible div + $handle = t('Click to Collapse'); + $content = 'Nulla ligula ante, aliquam at adipiscing egestas, varius vel arcu. Etiam laoreet elementum mi vel consequat. Etiam scelerisque lorem vel neque consequat quis bibendum libero congue. Nulla facilisi. Mauris a elit a leo feugiat porta. Phasellus placerat cursus est vitae elementum.'; + $output .= '<h3>'. t('Collapsible Div') .'</h3>'; + $output .= theme('ctools_collapsible', array('handle' => $handle, 'content' => $content, 'collapsed' => FALSE)); + + // Create a jump menu + ctools_include('jump-menu'); + $form = drupal_get_form('ctools_ajax_sample_jump_menu_form'); + $output .= '<h3>'. t('Jump Menu') .'</h3>'; + $output .= drupal_render($form); + + return array('markup' => array('#markup' => $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[] = ajax_command_html('#ctools-sample', $output); + print ajax_render($commands); // this function exits. + exit; + } + 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[] = ajax_command_remove("tr.ajax-sample-row-$row"); + $commands[] = ajax_command_restripe("table.ajax-sample-table"); + print ajax_render($commands); + exit; +} + +/** + * 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>'); + } + print ajax_render($output); + exit; +} + +/** + * 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'); + } + print ajax_render($commands); + exit; +} + +/** + * 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'); + $form = ctools_wizard_multistep_form($form_info, $step, $form_state); + $output = drupal_render($form); + + 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[] = 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); + } + print ajax_render($commands); + exit; + } + 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($vars) { + $output = '<div id="ctools-sample">'; + $output .= $vars['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, + ); + return $form; +} + +/** + * 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, + ); + return $form; +} + +/** + * 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), + ); + return $form; +} + +/** + * 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), + ); + return $form; +} + +/** + * 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, + )); +} + +/** + * Helper function to provide a sample jump menu form + */ +function ctools_ajax_sample_jump_menu_form() { + $url = url('ctools_ajax_sample/jumped'); + $form = ctools_jump_menu(array(), array($url => t('Jump!')), array()); + return $form; +} + +/** + * Provide a message to the user that the jump menu worked + */ +function ctools_ajax_sample_jump_menu_page() { + $return_link = l(t('Return to the examples page.'), 'ctools_ajax_sample'); + $output = t('You successfully jumped! !return_link', array('!return_link' => $return_link)); + return $output; +} + +/** + * Provide a form for an example ajax modal button + */ +function ctools_ajax_sample_ajax_button_form() { + $form = array(); + + $form['url'] = array( + '#type' => 'hidden', + '#attributes' => array('class' => array('ctools-ajax-sample-button-url')), + '#value' => 'ctools_ajax_sample/nojs/animal', + ); + + $form['ajax_button'] = array( + '#type' => 'button', + '#value' => 'Wizard (button modal)', + '#attributes' => array('class' => array('ctools-use-modal')), + '#id' => 'ctools-ajax-sample-button', + ); + + return $form; +} diff --git a/sites/all/modules/ctools/ctools_ajax_sample/js/ctools-ajax-sample.js b/sites/all/modules/ctools/ctools_ajax_sample/js/ctools-ajax-sample.js new file mode 100644 index 0000000000000000000000000000000000000000..0273bc1588838d0d75d8439a4129ff3c7dc3e49b --- /dev/null +++ b/sites/all/modules/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/sites/all/modules/ctools/ctools_custom_content/ctools_custom_content.info b/sites/all/modules/ctools/ctools_custom_content/ctools_custom_content.info new file mode 100644 index 0000000000000000000000000000000000000000..320a6232229d2d835841f07737cd67b053638a11 --- /dev/null +++ b/sites/all/modules/ctools/ctools_custom_content/ctools_custom_content.info @@ -0,0 +1,13 @@ +; $Id: ctools_custom_content.info,v 1.3 2011/01/01 00:01:46 merlinofchaos Exp $ +name = Custom content panes +description = Create custom, exportable, reusable content panes for applications like Panels. +core = 7.x +package = Chaos tool suite +dependencies[] = ctools + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-1.0-alpha2" +core = "7.x" +project = "ctools" +datestamp = "1294276864" + diff --git a/sites/all/modules/ctools/ctools_custom_content/ctools_custom_content.install b/sites/all/modules/ctools/ctools_custom_content/ctools_custom_content.install new file mode 100644 index 0000000000000000000000000000000000000000..4ff0f874bbcab25d1c3025046f0eefad287d2cb6 --- /dev/null +++ b/sites/all/modules/ctools/ctools_custom_content/ctools_custom_content.install @@ -0,0 +1,68 @@ +<?php +// $Id: ctools_custom_content.install,v 1.2 2010/10/11 22:18:21 sdboyer Exp $ + +/** + * 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; +} diff --git a/sites/all/modules/ctools/ctools_custom_content/ctools_custom_content.module b/sites/all/modules/ctools/ctools_custom_content/ctools_custom_content.module new file mode 100644 index 0000000000000000000000000000000000000000..9676540c045c42591c5b19435a8037031ad452ad --- /dev/null +++ b/sites/all/modules/ctools/ctools_custom_content/ctools_custom_content.module @@ -0,0 +1,99 @@ +<?php +// $Id: ctools_custom_content.module,v 1.3 2011/01/05 22:57:26 merlinofchaos Exp $ + +/** + * @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_permission() + */ +function ctools_custom_content_permission() { + return array( + 'administer custom content' => array( + 'title' => t('Administer custom content'), + 'description' => t('Add, edit and delete CTools custom stored 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/structure/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/structure/ctools-content/list/$item->name/edit"), + 'class' => 'links', + ), + ); + + // Only show 10. + if (++$count >= 10) { + break; + } + } + + if ($rows) { + $content = theme('table', array('rows' => $rows, 'attributes' => 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/structure/ctools-content'), + 'content' => $content, + 'class' => 'dashboard-content', + 'section' => 'right', + ); +} diff --git a/sites/all/modules/ctools/ctools_custom_content/plugins/export_ui/ctools_custom_content.inc b/sites/all/modules/ctools/ctools_custom_content/plugins/export_ui/ctools_custom_content.inc new file mode 100644 index 0000000000000000000000000000000000000000..fe634f4e6855b9fea5c2980b80ffb4ed0dea9032 --- /dev/null +++ b/sites/all/modules/ctools/ctools_custom_content/plugins/export_ui/ctools_custom_content.inc @@ -0,0 +1,21 @@ +<?php +// $Id: ctools_custom_content.inc,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ + +$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' => 'ctools_custom_content_ui', +); + diff --git a/sites/all/modules/ctools/ctools_custom_content/plugins/export_ui/ctools_custom_content_ui.class.php b/sites/all/modules/ctools/ctools_custom_content/plugins/export_ui/ctools_custom_content_ui.class.php new file mode 100644 index 0000000000000000000000000000000000000000..9f8928271df43ff0dd997f062e90b8717da27b5f --- /dev/null +++ b/sites/all/modules/ctools/ctools_custom_content/plugins/export_ui/ctools_custom_content_ui.class.php @@ -0,0 +1,123 @@ +<?php +// $Id: ctools_custom_content_ui.class.php,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ + +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'] = array( + '#type' => 'text_format', + '#title' => t('Body'), + '#default_value' => $form_state['item']->settings['body'], + '#format' => $form_state['item']->settings['format'], + ); + + $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']['value']; + $form_state['item']->settings['format'] = $form_state['values']['body']['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' => array('ctools-export-ui-name')), + array('data' => check_plain($item->admin_title), 'class' => array('ctools-export-ui-title')), + array('data' => check_plain($item->category), 'class' => array('ctools-export-ui-category')), + array('data' => theme('links', array('links' => $operations)), 'class' => array('ctools-export-ui-operations')), + ), + 'title' => check_plain($item->admin_description), + 'class' => array(!empty($item->disabled) ? 'ctools-export-ui-disabled' : 'ctools-export-ui-enabled'), + ); + } + + function list_table_header() { + return array( + array('data' => t('Name'), 'class' => array('ctools-export-ui-name')), + array('data' => t('Title'), 'class' => array('ctools-export-ui-title')), + array('data' => t('Category'), 'class' => array('ctools-export-ui-category')), + array('data' => t('Operations'), 'class' => array('ctools-export-ui-operations')), + ); + } + +} diff --git a/sites/all/modules/ctools/ctools_plugin_example/README.txt b/sites/all/modules/ctools/ctools_plugin_example/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..e13b9457351d93bccda02c234e7bce2d70c5dd6e --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/README.txt @@ -0,0 +1,15 @@ +// $Id: README.txt,v 1.2 2010/10/11 22:18:24 sdboyer Exp $ + +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/sites/all/modules/ctools/ctools_plugin_example/ctools_plugin_example.info b/sites/all/modules/ctools/ctools_plugin_example/ctools_plugin_example.info new file mode 100644 index 0000000000000000000000000000000000000000..7b43c9d3cdc2e8a2f34206dcbcf1408004647678 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/ctools_plugin_example.info @@ -0,0 +1,16 @@ +; $Id: ctools_plugin_example.info,v 1.3 2011/01/01 00:01:46 merlinofchaos Exp $ +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 = 7.x + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-1.0-alpha2" +core = "7.x" +project = "ctools" +datestamp = "1294276864" + diff --git a/sites/all/modules/ctools/ctools_plugin_example/ctools_plugin_example.module b/sites/all/modules/ctools/ctools_plugin_example/ctools_plugin_example.module new file mode 100644 index 0000000000000000000000000000000000000000..8ac4d6aaf59931b7ea9605bff2d4aba3f4ee1fcc --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/ctools_plugin_example.module @@ -0,0 +1,95 @@ +<?php +// $Id: ctools_plugin_example.module,v 1.2 2009/10/17 22:58:24 sdboyer Exp $ + +/* + * @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 + */ + +/** + * Implements 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; +} + +/** + * Implements 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/sites/all/modules/ctools/ctools_plugin_example/ctools_plugin_example.pages_default.inc b/sites/all/modules/ctools/ctools_plugin_example/ctools_plugin_example.pages_default.inc new file mode 100644 index 0000000000000000000000000000000000000000..751a8ada9d31a79779a93ef2753295cfc2dec2cf --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/ctools_plugin_example.pages_default.inc @@ -0,0 +1,452 @@ +<?php +// $Id: ctools_plugin_example.pages_default.inc,v 1.2 2010/01/29 19:53:48 merlinofchaos Exp $ + +/** + * @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/sites/all/modules/ctools/ctools_plugin_example/help/Access-Plugins--Determining-access-and-visibility.html b/sites/all/modules/ctools/ctools_plugin_example/help/Access-Plugins--Determining-access-and-visibility.html new file mode 100644 index 0000000000000000000000000000000000000000..781260ed1cd942a4836742e782a8ce3d32bed499 --- /dev/null +++ b/sites/all/modules/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/sites/all/modules/ctools/ctools_plugin_example/help/Argument-Plugins--Starting-at-the-beginning.html b/sites/all/modules/ctools/ctools_plugin_example/help/Argument-Plugins--Starting-at-the-beginning.html new file mode 100644 index 0000000000000000000000000000000000000000..4dd569d7114f504b6774efadcdf2cb2e5b02b5ab --- /dev/null +++ b/sites/all/modules/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/sites/all/modules/ctools/ctools_plugin_example/help/Chaos-Tools--CTools--Plugin-Examples.html b/sites/all/modules/ctools/ctools_plugin_example/help/Chaos-Tools--CTools--Plugin-Examples.html new file mode 100644 index 0000000000000000000000000000000000000000..7576c80bc55959f9a83fe183b6c79b3ae8a51f22 --- /dev/null +++ b/sites/all/modules/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/sites/all/modules/ctools/ctools_plugin_example/help/Content-Type-Plugins--Displaying-content-using-a-context.html b/sites/all/modules/ctools/ctools_plugin_example/help/Content-Type-Plugins--Displaying-content-using-a-context.html new file mode 100644 index 0000000000000000000000000000000000000000..918a13cb83170a2191a9c99bddff16badc6788ec --- /dev/null +++ b/sites/all/modules/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/sites/all/modules/ctools/ctools_plugin_example/help/Context-plugins--Creating-a--context--from-an-argument.html b/sites/all/modules/ctools/ctools_plugin_example/help/Context-plugins--Creating-a--context--from-an-argument.html new file mode 100644 index 0000000000000000000000000000000000000000..e8efbb3908de50431af06e99c685eaea3c8fdc87 --- /dev/null +++ b/sites/all/modules/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/sites/all/modules/ctools/ctools_plugin_example/help/Module-setup-and-hooks.html b/sites/all/modules/ctools/ctools_plugin_example/help/Module-setup-and-hooks.html new file mode 100644 index 0000000000000000000000000000000000000000..f816917dd1747a452143485f91efd19252400b42 --- /dev/null +++ b/sites/all/modules/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/sites/all/modules/ctools/ctools_plugin_example/help/Relationships--Letting-one-context-take-us-to-another.html b/sites/all/modules/ctools/ctools_plugin_example/help/Relationships--Letting-one-context-take-us-to-another.html new file mode 100644 index 0000000000000000000000000000000000000000..7691245adb5345691ce093339171103dade288c6 --- /dev/null +++ b/sites/all/modules/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/sites/all/modules/ctools/ctools_plugin_example/help/ctools_plugin_example.help.ini b/sites/all/modules/ctools/ctools_plugin_example/help/ctools_plugin_example.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..6fb3d4c0829b007acf32b3d9a6f3ae8f3cc68718 --- /dev/null +++ b/sites/all/modules/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/sites/all/modules/ctools/ctools_plugin_example/plugins/access/arg_length.inc b/sites/all/modules/ctools/ctools_plugin_example/plugins/access/arg_length.inc new file mode 100644 index 0000000000000000000000000000000000000000..11d065c681be693954354ebb5e3c6e1c4809bdd5 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/access/arg_length.inc @@ -0,0 +1,66 @@ +<?php +// $Id: arg_length.inc,v 1.3 2010/09/07 09:02:50 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/ctools_plugin_example/plugins/access/example_role.inc b/sites/all/modules/ctools/ctools_plugin_example/plugins/access/example_role.inc new file mode 100644 index 0000000000000000000000000000000000000000..63f8dd98000f3764ee1bfec2e603b3e0d844650f --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/access/example_role.inc @@ -0,0 +1,77 @@ +<?php +// $Id: example_role.inc,v 1.3 2010/09/07 09:02:50 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/ctools_plugin_example/plugins/access/translations/ctools_plugin_example-plugins-access.hu.po b/sites/all/modules/ctools/ctools_plugin_example/plugins/access/translations/ctools_plugin_example-plugins-access.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..708184633b2ab65a9801c746f3b3b4ecc32a1934 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/access/translations/ctools_plugin_example-plugins-access.hu.po @@ -0,0 +1,40 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 12:33+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 "Greater than" +msgstr "Nagyobb jel" +msgid "Less than or equal to" +msgstr "Kevesebb mint, vagy egyenlő" +msgid "Arg length" +msgstr "Argumentum hossza" +msgid "Control access by length of simplecontext argument." +msgstr "" +"Hozzáférés szabályozása a <em>simplecontext</em> argumentum " +"hossza által." +msgid "Grant access if simplecontext argument length is" +msgstr "Hozzáférés biztosítása, ha a simplecontext argumentum hossza" +msgid "Length of simplecontext argument" +msgstr "A <em>simplecontext</em> argumentum hossza" +msgid "Access/visibility will be granted based on arg length." +msgstr "" +"Hozzáférés/láthatóság biztosítva lesz az argumentum hossza " +"alapján." +msgid "Simpletext argument must be !comp @length characters" +msgstr "Simpletext argumentumnak !comp @length karakternek kell lennie" +msgid "CTools example: role" +msgstr "A <em>CTools</em> példa: csoport" +msgid "@identifier must have role \"@roles\"" +msgid_plural "@identifier can be one of \"@roles\"" +msgstr[0] "@identifier „@roles” csoport tagja kell legyen" +msgstr[1] "@identifier „@roles” csoportok egyikének tagja kell legyen" diff --git a/sites/all/modules/ctools/ctools_plugin_example/plugins/arguments/simplecontext_arg.inc b/sites/all/modules/ctools/ctools_plugin_example/plugins/arguments/simplecontext_arg.inc new file mode 100644 index 0000000000000000000000000000000000000000..fe245b6ac310d2e07d4fe0f18a8ffbae0d602c67 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/arguments/simplecontext_arg.inc @@ -0,0 +1,53 @@ +<?php +// $Id: simplecontext_arg.inc,v 1.2 2010/01/29 19:53:48 merlinofchaos Exp $ + +/** + * @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/sites/all/modules/ctools/ctools_plugin_example/plugins/arguments/translations/ctools_plugin_example-plugins-arguments.hu.po b/sites/all/modules/ctools/ctools_plugin_example/plugins/arguments/translations/ctools_plugin_example-plugins-arguments.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..84ceb8be6c81aabdbacd3193a49959fab9f741d2 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/arguments/translations/ctools_plugin_example-plugins-arguments.hu.po @@ -0,0 +1,20 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-11-30 08:07+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 "Simplecontext arg" +msgstr "<em>Simplecontext</em> argumentum" +msgid "Creates a \"simplecontext\" from the arg." +msgstr "Egy <em>simplecontext</em> létrehozása az argumentumból." +msgid "Enter the simplecontext arg" +msgstr "Ssimplecontext argumentum megadása" diff --git a/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/icon_example.png b/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/icon_example.png new file mode 100644 index 0000000000000000000000000000000000000000..58c6bee4fde937b4f09ca13cfdf2d90d49cdad64 Binary files /dev/null and b/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/icon_example.png differ diff --git a/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/no_context_content_type.inc b/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/no_context_content_type.inc new file mode 100644 index 0000000000000000000000000000000000000000..ffe9438eb0531d8aa4d31c644acef7b3fc283689 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/no_context_content_type.inc @@ -0,0 +1,117 @@ +<?php +// $Id: no_context_content_type.inc,v 1.2 2010/01/29 19:53:48 merlinofchaos Exp $ + +/** + * @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/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/relcontext_content_type.inc b/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/relcontext_content_type.inc new file mode 100644 index 0000000000000000000000000000000000000000..60ef7bc49898b24b9e45f353c43e7d345e3bfa8f --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/relcontext_content_type.inc @@ -0,0 +1,104 @@ +<?php +// $Id: relcontext_content_type.inc,v 1.3 2010/01/29 19:53:48 merlinofchaos Exp $ + + +/** + * @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/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc b/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc new file mode 100644 index 0000000000000000000000000000000000000000..0759aecb44c8671f1c54f2e2948850acca860f8d --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc @@ -0,0 +1,130 @@ +<?php +// $Id: simplecontext_content_type.inc,v 1.3 2010/01/29 19:53:48 merlinofchaos Exp $ + + +/** + * @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/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/translations/ctools_plugin_example-plugins-content_types.hu.po b/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/translations/ctools_plugin_example-plugins-content_types.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..fe04db52a2644f42eeb27ef3b28faca8bec0e1c3 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/content_types/translations/ctools_plugin_example-plugins-content_types.hu.po @@ -0,0 +1,95 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 12:37+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 "Item1" +msgstr "Elem1" +msgid "The stuff for item 1." +msgstr "Valami az elem 1-hez." +msgid "Item2" +msgstr "Elem2" +msgid "CTools example no context content type" +msgstr "CTools példa környezetnélküli tartalomtípusra" +msgid "No context content type - requires and uses no context." +msgstr "" +"Környezetnélküli tartalomtípus - nem szükséges hozzá és nem " +"használ környezetet." +msgid "The setting for item 1." +msgstr "Elem 1 beállításai" +msgid "The setting for item 2" +msgstr "Elem 2 beállításai" +msgid "CTools example relcontext content type" +msgstr "CTools példa relcontext tartalomtípusra" +msgid "Relcontext content type - works with relcontext context." +msgstr "Relcontext tartalomtípus - a relcontext környezettel működik." +msgid "Config Item 1 (relcontext)" +msgstr "Elem 1 beállítása (relcontext)" +msgid "Setting for relcontext." +msgstr "Relcontext beállítása" +msgid "Simplecontext content type" +msgstr "Simplecontext tartalomtípus" +msgid "Simplecontext content type - works with a simplecontext context." +msgstr "Simplecontext tartalomtípus - simplecontext környezetben működik." +msgid "Config Item 1 for simplecontext content type" +msgstr "Elem 1 beállítása a simplecontext tartalomtípushoz" +msgid "" +"\n" +" This is a block of data created by the Relcontent content type.\n" +" Data in the block may be assembled from static text (like this) or " +"from the\n" +" content type settings form ($conf) for the content type, or from " +"the context\n" +" that is passed in. <br />\n" +" In our case, the configuration form ($conf) has just one field, " +"'config_item_1;\n" +" and it's configured with:\n" +" " +msgstr "" +"\n" +" Ez egy adatblokk, amit a Relcontent tartalomtípus hozott " +"létre.\r\n" +" A blokk adatainak összeállítása történhet statikus " +"szövegekből (mint ez)\r\n" +" vagy a tartalomtípus beállításainak űrlapjából ($conf), " +"esetleg a beállított\r\n" +" környezetből. <br />\r\n" +" Jelen esetben a beállítási űrlapon ($conf) csak egy mező van, " +"'config_item_1;\r\n" +" ezzel lett beállítva:\n" +" " +msgid "" +"\n" +" This is a block of data created by the Simplecontext content " +"type.\n" +" Data in the block may be assembled from static text (like this) or " +"from the\n" +" content type settings form ($conf) for the content type, or from " +"the context\n" +" that is passed in. <br />\n" +" In our case, the configuration form ($conf) has just one field, " +"'config_item_1;\n" +" and it's configured with:\n" +" " +msgstr "" +"\n" +" Ez egy adatblokk, amit a Simplecontext tartalomtípus hozott " +"létre.\r\n" +" A blokk adatainak összeállítása történhet statikus " +"szövegekből (mint ez)\r\n" +" vagy a tartalomtípus beállításainak űrlapjából ($conf), " +"esetleg a beállított\r\n" +" környezetből. <br />\r\n" +" Jelen esetben a beállítási űrlapon ($conf) csak egy mező van, " +"'config_item_1;\r\n" +" ezzel lett beállítva:\n" +" " diff --git a/sites/all/modules/ctools/ctools_plugin_example/plugins/contexts/relcontext.inc b/sites/all/modules/ctools/ctools_plugin_example/plugins/contexts/relcontext.inc new file mode 100644 index 0000000000000000000000000000000000000000..313d6346b14543f377730deb7345a7fd48ecca33 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/contexts/relcontext.inc @@ -0,0 +1,84 @@ +<?php +// $Id: relcontext.inc,v 1.2 2010/01/29 19:53:48 merlinofchaos Exp $ + +/** + * @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/sites/all/modules/ctools/ctools_plugin_example/plugins/contexts/simplecontext.inc b/sites/all/modules/ctools/ctools_plugin_example/plugins/contexts/simplecontext.inc new file mode 100644 index 0000000000000000000000000000000000000000..2ddf50c0837cb2d079983491895d18461b5c57f6 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/contexts/simplecontext.inc @@ -0,0 +1,135 @@ +<?php +// $Id: simplecontext.inc,v 1.2 2010/01/29 19:53:48 merlinofchaos Exp $ + + +/** + * @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/sites/all/modules/ctools/ctools_plugin_example/plugins/contexts/translations/ctools_plugin_example-plugins-contexts.hu.po b/sites/all/modules/ctools/ctools_plugin_example/plugins/contexts/translations/ctools_plugin_example-plugins-contexts.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..f029f63a0baa913adb302fc5ab00818c448d3817 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/contexts/translations/ctools_plugin_example-plugins-contexts.hu.po @@ -0,0 +1,34 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 12:39+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 "A relcontext object." +msgstr "Egy relcontext objektum." +msgid "Relcontext context from simplecontext" +msgstr "Relcontext környezet simplecontextből" +msgid "Relcontext setting" +msgstr "Relcontext beállítás" +msgid "Just an example setting." +msgstr "Csak egy példa beállítás." +msgid "A single \"simplecontext\" context, or data element." +msgstr "Egy egyszerű „simplecontext” környezet vagy adatelem." +msgid "Enter some data to represent this \"simplecontext\"." +msgstr "Ezt a „simplecontext”-et képviselő néhány adat megadása." +msgid "Simplecontext context from config" +msgstr "Simplecontext környezet a beállításokból" +msgid "Setting for simplecontext" +msgstr "Simplecontext beállítása" +msgid "An example setting that could be used to configure a context" +msgstr "" +"Egy példa beállítás, ami a környezet beállításához " +"használható" diff --git a/sites/all/modules/ctools/ctools_plugin_example/plugins/panels.pages.inc b/sites/all/modules/ctools/ctools_plugin_example/plugins/panels.pages.inc new file mode 100644 index 0000000000000000000000000000000000000000..8807f75396d3b1ce6f4b35e2874afe390fb22cd4 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/panels.pages.inc @@ -0,0 +1,215 @@ +<?php +// $Id: panels.pages.inc,v 1.3 2009/10/17 22:58:26 sdboyer Exp $ + +/** + * @file + * Holds the panels pages export. + */ + +/** + * Implements 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/sites/all/modules/ctools/ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc b/sites/all/modules/ctools/ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc new file mode 100644 index 0000000000000000000000000000000000000000..6e24ed76d48987e239e9f807c3285d8570b307e6 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc @@ -0,0 +1,51 @@ +<?php +// $Id: relcontext_from_simplecontext.inc,v 1.2 2010/01/29 19:53:48 merlinofchaos Exp $ + + +/** + * @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/sites/all/modules/ctools/ctools_plugin_example/plugins/relationships/translations/ctools_plugin_example-plugins-relationships.hu.po b/sites/all/modules/ctools/ctools_plugin_example/plugins/relationships/translations/ctools_plugin_example-plugins-relationships.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..d520ab0577ab22a7e35bcce463835f28a58128f3 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/plugins/relationships/translations/ctools_plugin_example-plugins-relationships.hu.po @@ -0,0 +1,18 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 12:39+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 "Adds a relcontext from existing simplecontext." +msgstr "Hozzáad egy relcontextet egy létező simplecontextből." +msgid "Relcontext from simplecontext" +msgstr "Relcontext simplecontextből" diff --git a/sites/all/modules/ctools/ctools_plugin_example/translations/ctools_plugin_example.hu.po b/sites/all/modules/ctools/ctools_plugin_example/translations/ctools_plugin_example.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..c18ccb44787122111fbc9196257735290117ba68 --- /dev/null +++ b/sites/all/modules/ctools/ctools_plugin_example/translations/ctools_plugin_example.hu.po @@ -0,0 +1,56 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 12:37+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 "" +"Demonstration code, advanced help, and a demo panel to show how to " +"build ctools plugins." +msgstr "" +"Bemutató kód, haladó segítség és egy demó panel annak " +"bemutatására, hogy miként lehet ctools beépülőket építeni." +msgid "" +"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." +msgstr "" +"A CTools Plugin Example egyszerűen egy fejlesztői bemutató arról, " +"hogy miként lehet beépülőket létrehozni CTools-hoz. Hétköznapi " +"felhasználónak nem nyújt semmilyen hasznos funkciót." +msgid "" +"There is a demo panel demonstrating much of the functionality provided " +"at\n" +" <a href=\"@demo_url\">CTools demo panel</a>, and you can find " +"documentation on the examples at\n" +" !ctools_plugin_example_help.\n" +" CTools itself provides documentation at !ctools_help. Mostly, " +"though, the code itself is intended to be the teacher.\n" +" You can find it in %path." +msgstr "" +"Ez egy demó panel a <a href=\"@demo_url\">CTools bemutató panel</a> " +"által biztosított funkciók többségének bemutatására,\r\n" +" dokumentáció a !ctools_plugin_example_help oldalon " +"található.\r\n" +" Magának a CTools-nak a dokumentációja a !ctools_help oldalon " +"található. Többnyire, mert inkább magának a kódnak a feladata, " +"hogy magyarázó legyen.\r\n" +" Megtalálható itt: %path." +msgid "CTools plugin example" +msgstr "<em>CTools</em> beépülő példa" +msgid "Chaos Tools (CTools) Plugin Example" +msgstr "<em>Chaos Tools</em> (<em>CTools</em>) beépülő példa" +msgid "" +"Shows how an external module can provide ctools plugins (for Panels, " +"etc.)." +msgstr "" +"Bemutatja, hogy egy külső modul miként biztosíthat <em>CTools</em> " +"beépülőket (például a <em>Panels</em> modulhoz, stb...)." diff --git a/sites/all/modules/ctools/help/about.html b/sites/all/modules/ctools/help/about.html new file mode 100644 index 0000000000000000000000000000000000000000..c5b8ec0ce476c2e8b8daf058b1e1fba6ce9b58c2 --- /dev/null +++ b/sites/all/modules/ctools/help/about.html @@ -0,0 +1,31 @@ +<!-- $Id: about.html,v 1.1 2009/01/22 01:57:18 merlinofchaos Exp $ --> +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/sites/all/modules/ctools/help/ajax.html b/sites/all/modules/ctools/help/ajax.html new file mode 100644 index 0000000000000000000000000000000000000000..8745e398f2f33136075c5a40abcc2e181cd5d4bf --- /dev/null +++ b/sites/all/modules/ctools/help/ajax.html @@ -0,0 +1 @@ +<!-- $Id: ajax.html,v 1.1 2009/01/22 01:57:18 merlinofchaos Exp $ --> diff --git a/sites/all/modules/ctools/help/context-access.html b/sites/all/modules/ctools/help/context-access.html new file mode 100644 index 0000000000000000000000000000000000000000..24a182bee11479244911931364f108a60d62823c --- /dev/null +++ b/sites/all/modules/ctools/help/context-access.html @@ -0,0 +1,15 @@ +<!-- $Id: context-access.html,v 1.1 2008/12/17 08:29:20 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/help/context-arguments.html b/sites/all/modules/ctools/help/context-arguments.html new file mode 100644 index 0000000000000000000000000000000000000000..d9910bb793499a0a66ecdf1190c9150477b14901 --- /dev/null +++ b/sites/all/modules/ctools/help/context-arguments.html @@ -0,0 +1,20 @@ +<!-- $Id: context-arguments.html,v 1.3 2008/12/19 17:35:57 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/help/context-content.html b/sites/all/modules/ctools/help/context-content.html new file mode 100644 index 0000000000000000000000000000000000000000..b3becf12f7d813d10938b706bd512e3c6548fc85 --- /dev/null +++ b/sites/all/modules/ctools/help/context-content.html @@ -0,0 +1,247 @@ +<!-- $Id: context-content.html,v 1.3 2009/07/18 22:06:33 merlinofchaos Exp $ --> +<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/sites/all/modules/ctools/help/context-context.html b/sites/all/modules/ctools/help/context-context.html new file mode 100644 index 0000000000000000000000000000000000000000..9d8c1d8dcf1bea53b2ed901066a612a7aeae2189 --- /dev/null +++ b/sites/all/modules/ctools/help/context-context.html @@ -0,0 +1,13 @@ +<!-- $Id: context-context.html,v 1.1 2008/12/04 22:22:40 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/help/context-relationships.html b/sites/all/modules/ctools/help/context-relationships.html new file mode 100644 index 0000000000000000000000000000000000000000..9fc8a9b59e86c8eb70e5c058895ff01ade7c6395 --- /dev/null +++ b/sites/all/modules/ctools/help/context-relationships.html @@ -0,0 +1,11 @@ +<!-- $Id: context-relationships.html,v 1.1 2008/12/04 22:22:40 merlinofchaos Exp $ --> + + '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/sites/all/modules/ctools/help/context.html b/sites/all/modules/ctools/help/context.html new file mode 100644 index 0000000000000000000000000000000000000000..bf5ebeea09697b74bd6f73847bd1264438377cc4 --- /dev/null +++ b/sites/all/modules/ctools/help/context.html @@ -0,0 +1 @@ +<!-- $Id: context.html,v 1.1 2008/12/04 22:22:40 merlinofchaos Exp $ --> diff --git a/sites/all/modules/ctools/help/ctools.help.ini b/sites/all/modules/ctools/help/ctools.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..9de6e3b6a4facaf6d314d6df56eae1a36d6381b2 --- /dev/null +++ b/sites/all/modules/ctools/help/ctools.help.ini @@ -0,0 +1,94 @@ +; $Id: ctools.help.ini,v 1.4 2010/09/07 09:02:50 sdboyer Exp $ +[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/sites/all/modules/ctools/help/export-ui.html b/sites/all/modules/ctools/help/export-ui.html new file mode 100644 index 0000000000000000000000000000000000000000..3ebeb647022503148d29686202f975d12ae6e941 --- /dev/null +++ b/sites/all/modules/ctools/help/export-ui.html @@ -0,0 +1,85 @@ +<!-- $Id: export-ui.html,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ --> +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/structure and the item will default to the plugin name. + 'menu' => array( + 'menu prefix' => 'admin/structure', + '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/sites/all/modules/ctools/help/export.html b/sites/all/modules/ctools/help/export.html new file mode 100644 index 0000000000000000000000000000000000000000..0e6b4f8386b4ed29ab7262332f281385e75b82a2 --- /dev/null +++ b/sites/all/modules/ctools/help/export.html @@ -0,0 +1,235 @@ +<!-- $Id: export.html,v 1.4 2010/10/11 22:18:22 sdboyer Exp $ --> +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 a callback to add custom conditions or + // alter the query as necessary. The callback function takes 3 args: + // + // myjoincallback(&$query, $schema, $join_schema); + // + // where $query is the database query object, $schema is the schema for + // the export base table and $join_schema is the schema for the current + // join table. + 'callback' => 'myjoincallback', + + // 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. Defaults as stdClass.</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>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> +</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/sites/all/modules/ctools/help/modal.html b/sites/all/modules/ctools/help/modal.html new file mode 100644 index 0000000000000000000000000000000000000000..60985929f85a5196ca2365a54d434f905b0ea55a --- /dev/null +++ b/sites/all/modules/ctools/help/modal.html @@ -0,0 +1,221 @@ +<!-- $Id: modal.html,v 1.4 2010/12/31 23:58:52 merlinofchaos Exp $ --> +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', array('path' => $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 $text + * The text to display as the link. + * @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', array('path' => ctools_image_path('icon-close-window.png'), 'alt' => t('Close window'), 'title' => 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', array('path' => ctools_image_path('throbber.gif'), 'alt' => t('Loading...'), 'title' => 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. + print ajax_render($commands); + exit; + } + + // 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/sites/all/modules/ctools/help/object-cache.html b/sites/all/modules/ctools/help/object-cache.html new file mode 100644 index 0000000000000000000000000000000000000000..e810b17d0a0cc393b5ec19e5dc573eddd7fc56f7 --- /dev/null +++ b/sites/all/modules/ctools/help/object-cache.html @@ -0,0 +1,133 @@ +<!-- $Id: object-cache.html,v 1.1 2009/01/23 23:14:04 merlinofchaos Exp $ --> +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/sites/all/modules/ctools/help/plugins-api.html b/sites/all/modules/ctools/help/plugins-api.html new file mode 100644 index 0000000000000000000000000000000000000000..4392cb4374baf5b7e7d3ee3d20db60d89367a907 --- /dev/null +++ b/sites/all/modules/ctools/help/plugins-api.html @@ -0,0 +1,55 @@ +<!-- $Id: plugins-api.html,v 1.3 2009/04/17 19:16:21 merlinofchaos Exp $ --> +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/sites/all/modules/ctools/help/plugins-creating.html b/sites/all/modules/ctools/help/plugins-creating.html new file mode 100644 index 0000000000000000000000000000000000000000..b1242f291cd0b23e9a061f1d24e30583a6709b24 --- /dev/null +++ b/sites/all/modules/ctools/help/plugins-creating.html @@ -0,0 +1,190 @@ +<!-- $Id: plugins-creating.html,v 1.10 2010/09/07 09:02:50 sdboyer Exp $ --> +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/sites/all/modules/ctools/help/plugins-implementing.html b/sites/all/modules/ctools/help/plugins-implementing.html new file mode 100644 index 0000000000000000000000000000000000000000..2ee4ce785625f7c34ab17e2a3bbe260868e9e4af --- /dev/null +++ b/sites/all/modules/ctools/help/plugins-implementing.html @@ -0,0 +1,59 @@ +<!-- $Id: plugins-implementing.html,v 1.4 2009/11/13 00:49:28 merlinofchaos Exp $ --> +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/sites/all/modules/ctools/help/plugins.html b/sites/all/modules/ctools/help/plugins.html new file mode 100644 index 0000000000000000000000000000000000000000..caf699a0f99e5aef6b1791c9784cdda2537236a3 --- /dev/null +++ b/sites/all/modules/ctools/help/plugins.html @@ -0,0 +1,6 @@ +<!-- $Id: plugins.html,v 1.2 2010/09/07 09:02:50 sdboyer Exp $ --> +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/sites/all/modules/ctools/help/wizard.html b/sites/all/modules/ctools/help/wizard.html new file mode 100644 index 0000000000000000000000000000000000000000..5fbc55b6025006c4bad0010e59ed8f3edd62ff93 --- /dev/null +++ b/sites/all/modules/ctools/help/wizard.html @@ -0,0 +1,288 @@ +<!-- $Id: wizard.html,v 1.8 2010/10/15 22:13:37 merlinofchaos Exp $ --> +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/structure/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/sites/all/modules/ctools/images/arrow-active.png b/sites/all/modules/ctools/images/arrow-active.png new file mode 100644 index 0000000000000000000000000000000000000000..3bbd3c27f29f9a1781276a2ae8faa7afd5d2d36e Binary files /dev/null and b/sites/all/modules/ctools/images/arrow-active.png differ diff --git a/sites/all/modules/ctools/images/collapsible-collapsed.png b/sites/all/modules/ctools/images/collapsible-collapsed.png new file mode 100644 index 0000000000000000000000000000000000000000..95a214a6e6d17fee2f098804997f3826ffc9d4ca Binary files /dev/null and b/sites/all/modules/ctools/images/collapsible-collapsed.png differ diff --git a/sites/all/modules/ctools/images/collapsible-expanded.png b/sites/all/modules/ctools/images/collapsible-expanded.png new file mode 100644 index 0000000000000000000000000000000000000000..46f39ecb351cff65243fa9a614a69d039e1302a5 Binary files /dev/null and b/sites/all/modules/ctools/images/collapsible-expanded.png differ diff --git a/sites/all/modules/ctools/images/expanded-options.png b/sites/all/modules/ctools/images/expanded-options.png new file mode 100644 index 0000000000000000000000000000000000000000..b7b755c0a44f7ebae4972e9489f7d004c0ab82c7 Binary files /dev/null and b/sites/all/modules/ctools/images/expanded-options.png differ diff --git a/sites/all/modules/ctools/images/icon-close-window.png b/sites/all/modules/ctools/images/icon-close-window.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0cf695b0cac487efecfd7eae66e7492a2ba306 Binary files /dev/null and b/sites/all/modules/ctools/images/icon-close-window.png differ diff --git a/sites/all/modules/ctools/images/icon-configure.png b/sites/all/modules/ctools/images/icon-configure.png new file mode 100644 index 0000000000000000000000000000000000000000..e23d67cc04b84880d0437e23ffcba837d2dc4121 Binary files /dev/null and b/sites/all/modules/ctools/images/icon-configure.png differ diff --git a/sites/all/modules/ctools/images/icon-delete.png b/sites/all/modules/ctools/images/icon-delete.png new file mode 100644 index 0000000000000000000000000000000000000000..5f0cf695b0cac487efecfd7eae66e7492a2ba306 Binary files /dev/null and b/sites/all/modules/ctools/images/icon-delete.png differ diff --git a/sites/all/modules/ctools/images/no-icon.png b/sites/all/modules/ctools/images/no-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fa78ec179a83428e5b8e247890278cdf91a8cb3e Binary files /dev/null and b/sites/all/modules/ctools/images/no-icon.png differ diff --git a/sites/all/modules/ctools/images/status-active.gif b/sites/all/modules/ctools/images/status-active.gif new file mode 100644 index 0000000000000000000000000000000000000000..207e95c3fa8cc31a89af150ad74059b1667922b6 Binary files /dev/null and b/sites/all/modules/ctools/images/status-active.gif differ diff --git a/sites/all/modules/ctools/images/throbber.gif b/sites/all/modules/ctools/images/throbber.gif new file mode 100644 index 0000000000000000000000000000000000000000..8a084b8447d506e9b655ad52405cbf7a73034550 Binary files /dev/null and b/sites/all/modules/ctools/images/throbber.gif differ diff --git a/sites/all/modules/ctools/includes/ajax.inc b/sites/all/modules/ctools/includes/ajax.inc new file mode 100644 index 0000000000000000000000000000000000000000..2f4637799f7d1e2dd2041305e6ea0d8f2c0171b0 --- /dev/null +++ b/sites/all/modules/ctools/includes/ajax.inc @@ -0,0 +1,126 @@ +<?php +// $Id: ajax.inc,v 1.22 2010/12/31 23:58:52 merlinofchaos Exp $ + +// Set this so we can tell that the file has been included at some point. +define('CTOOLS_AJAX_INCLUDED', 1); + +/** + * @file + * Extend core AJAX with some of our own stuff. + */ + +/** + * 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', array('path' => $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 $text + * The text that will be displayed as the link. + * @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 = 'use-ajax') { + drupal_add_js('misc/ajax.js'); + return l($text, $dest, array('html' => TRUE, 'attributes' => array('class' => array($type, $class), 'title' => $alt))); +} + +/** + * 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 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. + */ +function ctools_ajax_command_redirect($url, $delay = 0, $options = array()) { + return array( + 'command' => 'redirect', + 'url' => url($url, $options), + 'delay' => $delay, + ); +} + +/** + * 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, + ); +} + +/** + * Send an error response back via AJAX and immediately exit. + */ +function ctools_ajax_render_error($error = '') { + $commands = array(); + $commands[] = ajax_command_alert($error); + print ajax_render($commands); + exit; +} + diff --git a/sites/all/modules/ctools/includes/cache.inc b/sites/all/modules/ctools/includes/cache.inc new file mode 100644 index 0000000000000000000000000000000000000000..437acefc662536957d11fd90eb7c334bc9cfe050 --- /dev/null +++ b/sites/all/modules/ctools/includes/cache.inc @@ -0,0 +1,170 @@ +<?php +// $Id: cache.inc,v 1.1 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @file + * + * Plugins to handle cache-indirection. + * + * Simple plugin management to allow clients to more tightly control where + * object caches are stored. + * + * CTools provides an object cache mechanism, and it also provides a number + * of subsystems that are designed to plug into larger systems. When doing + * caching on multi-step forms (in particular during AJAX operations) these + * subsystems often need to operate their own cache. In reality, its best + * for everyone if they are able to piggyback off of the larger cache. + * + * This system allows this by registering plugins to control where caches + * are actually stored. For the most part, the subsystems could care less + * where the data is fetched from and stored to. All it needs to know is + * that it can 'get', 'set' and 'clear' caches. Additionally, some caches + * might need extra operations such as 'lock' and 'finalize', and other + * operations may be needed based upon the specific uses for the cache + * plugins. + * + * To utilize cache plugins, there are two pieces of data. First, there is + * the mechanism, which is simply the name of the plugin to use. CTools + * provides a 'simple' mechanism which goes straight through to the object + * cache. The second piece of data is the 'key' which is a unique identifier + * that can be used to find the data needed. Keys can be generated any number + * of ways, and the plugin must be agnostic about the key itself. + * + * That said, the 'mechanism' can be specified as pluginame::data and that + * data can be used to derive additional data. For example, it is often + * desirable to NOT store any cached data until original data (i.e, user + * input) has been received. The data can be used to derive this original + * data so that when a 'get' is called, if the cache is missed it can create + * the data needed. This can help prevent unwanted cache entries from + * building up just by visiting edit UIs without actually modifying anything. + * + * Modules wishing to implement cache indirection mechanisms need to implement + * a plugin of type 'cache' for the module 'ctools' and provide the .inc file. + * It should provide callbacks for 'cache set', 'cache get', and 'cache clear'. + * It can provide callbacks for 'break' and 'finalize' if these are relevant + * to the caching mechanism (i.e, for use with locking caches such as the page + * manager cache). Other operations may be utilized but at this time are not part + * of CTools. + */ + +/** + * Fetch data from an indirect cache. + * + * @param string $mechanism + * A string containing the plugin name, and an optional data element to + * send to the plugin separated by two colons. + * + * @param string $key + * The key used to identify the cache. + * + * @return mixed + * The cached data. This can be any format as the plugin does not necessarily + * have knowledge of what is being cached. + */ +function ctools_cache_get($mechanism, $key) { + return ctools_cache_operation($mechanism, $key, 'get'); +} + +/** + * Store data in an indirect cache. + * + * @param string $mechanism + * A string containing the plugin name, and an optional data element to + * send to the plugin separated by two colons. + * + * @param string $key + * The key used to identify the cache. + * + * @param mixed $object + * The data to cache. This can be any format as the plugin does not + * necessarily have knowledge of what is being cached. + */ +function ctools_cache_set($mechanism, $key, $object) { + return ctools_cache_operation($mechanism, $key, 'set', $object); +} + +/** + * Clear data from an indirect cache. + * + * @param string $mechanism + * A string containing the plugin name, and an optional data element to + * send to the plugin separated by two colons. + * + * @param string $key + * The key used to identify the cache. + */ +function ctools_cache_clear($mechanism, $key) { + return ctools_cache_operation($mechanism, $key, 'clear', $object); + +} + +/** + * Perform a secondary operation on an indirect cache. + * + * Additional operations, beyond get, set and clear may be items + * such as 'break' and 'finalize', which are needed to support cache + * locking. Other operations may be added by users of the indirect + * caching functions as needed. + * + * @param string $mechanism + * A string containing the plugin name, and an optional data element to + * send to the plugin separated by two colons. + * + * @param string $key + * The key used to identify the cache. + * + * @param string $op + * The operation to call, such as 'break' or 'finalize'. + * + * @param mixed $object + * The cache data being operated on, in case it is necessary. This is + * optional so no references should be used. + * + * @return mixed + * The operation may or may not return a value. + */ +function ctools_cache_operation($mechanism, $key, $op, $object = NULL) { + list($plugin, $data) = ctools_cache_find_plugin($mechanism); + if (empty($plugin)) { + return; + } + + $function = ctools_plugin_get_function($plugin, "cache $op"); + if (empty($function)) { + return; + } + + return $function($data, $key, $object, $op); +} + +/** + * Take a mechanism and return a plugin and data. + * + * @param string $mechanism + * A string containing the plugin name, and an optional data element to + * send to the plugin separated by two colons. + * + * @return array + * An array, the first element will be the plugin and the second element + * will be the data. If the plugin could not be found, the $plugin will + * be NULL. + */ +function ctools_cache_find_plugin($mechanism) { + if (strpos($mechanism, '::') !== FALSE) { + // use explode(2) to ensure that the data can contain double + // colons, just in case. + list($name, $data) = explode('::', $mechanism, 2); + } + else { + $name = $mechanism; + $data = ''; + } + + if (empty($name)) { + return array(NULL, $data); + } + + ctools_include('plugins'); + $plugin = ctools_get_plugins('ctools', 'cache', $name); + return array($plugin, $data); +} diff --git a/sites/all/modules/ctools/includes/cache.plugin-type.inc b/sites/all/modules/ctools/includes/cache.plugin-type.inc new file mode 100644 index 0000000000000000000000000000000000000000..0e8e8c815364bcc05a170d139c2be007d99eda8f --- /dev/null +++ b/sites/all/modules/ctools/includes/cache.plugin-type.inc @@ -0,0 +1,12 @@ +<?php +// $Id: cache.plugin-type.inc,v 1.1 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @file + * Contains plugin type registration information for the cache tool. + */ + +function ctools_cache_plugin_type(&$items) { + // There are no options to declare on this plugin at this time. + $items['cache'] = array(); +} diff --git a/sites/all/modules/ctools/includes/cleanstring.inc b/sites/all/modules/ctools/includes/cleanstring.inc new file mode 100644 index 0000000000000000000000000000000000000000..baed9e3b0af46449e5ac6385763dda0f2109f684 --- /dev/null +++ b/sites/all/modules/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{d800}-\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/sites/all/modules/ctools/includes/collapsible.theme.inc b/sites/all/modules/ctools/includes/collapsible.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..c2a91762874ffb5fc6c92f4d49a741ba98aa18c3 --- /dev/null +++ b/sites/all/modules/ctools/includes/collapsible.theme.inc @@ -0,0 +1,80 @@ +<?php +// $Id: collapsible.theme.inc,v 1.6 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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( + 'variables' => array('handle' => NULL, 'content' => NULL, 'collapsed' => FALSE), + 'file' => 'includes/collapsible.theme.inc', + ); + $items['ctools_collapsible_remembered'] = array( + 'variables' => 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($vars) { + ctools_add_js('collapsible-div'); + ctools_add_css('collapsible-div'); + + $class = $vars['collapsed'] ? ' ctools-collapsed' : ''; + $output = '<div class="ctools-collapsible-container' . $class . '">'; + $output .= '<div class="ctools-collapsible-handle">' . $vars['handle'] . '</div>'; + $output .= '<div class="ctools-collapsible-content">' . $vars['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($vars) { + $id = $vars['id']; + $handle = $vars['handle']; + $content = $vars['content']; + $collapsed = $vars['collapsed']; + 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/sites/all/modules/ctools/includes/content.inc b/sites/all/modules/ctools/includes/content.inc new file mode 100644 index 0000000000000000000000000000000000000000..39ec1abe52b27147e215f1b57a5a8c49cb361499 --- /dev/null +++ b/sites/all/modules/ctools/includes/content.inc @@ -0,0 +1,774 @@ +<?php +// $Id: content.inc,v 1.21 2010/12/31 23:53:34 merlinofchaos Exp $ + +/** + * @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. + */ + +/** + * 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'; + } + + // 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); + + // 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' => array(), 'query' => array(), 'fragment' => '', '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; + } + + if ($function = ctools_plugin_get_function($subtype, 'check editable')) { + 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( + '#markup' => '<div class="option-text-aligner clearfix">', + ); + $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( + '#markup' => '</div>', + ); + if (is_array($contexts)) { + $form['override_title_markup'] = array( + '#prefix' => '<div class="description">', + '#suffix' => '</div>', + '#markup' => 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/sites/all/modules/ctools/includes/content.menu.inc b/sites/all/modules/ctools/includes/content.menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..02169f2f5ddd16b4f6e544253ff11076bdbcaf41 --- /dev/null +++ b/sites/all/modules/ctools/includes/content.menu.inc @@ -0,0 +1,73 @@ +<?php +// $Id: content.menu.inc,v 1.9 2011/01/05 20:34:46 merlinofchaos Exp $ + +/** + * @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/%'] = array( + 'page callback' => 'ctools_content_autocomplete_entity', + 'page arguments' => array(2), + ) + $base; +} + +/** + * Helper function for autocompletion of entity titles. + */ +function ctools_content_autocomplete_entity($type, $string = '') { + $entity = entity_get_info($type); + if ($string != '') { + // @todo verify the query logic here, it's untested. + // Set up the query + $query = db_select($entity['base table'], 'b'); + if ($entity['entity keys']['label']) { + $query->fields('b', array($entity['entity keys']['id'], $entity['entity keys']['label']))->range(0, 10); + } + else { + $query->fields('b', array($entity['entity keys']['id']))->range(0, 10); + } + + $preg_matches = array(); + $match = preg_match('/\[id: (\d+)\]/', $string, $preg_matches); + if (!$match) { + $match = preg_match('/^id: (\d+)/', $string, $preg_matches); + } + if ($match) { + $query->condition('b.' . $entity['entity keys']['id'], $preg_matches[1]); + } + elseif ($entity['entity keys']['label']) { + $query->condition('b.' . $entity['entity keys']['label'], '%' . db_like($string) . '%', 'LIKE'); + } + + $matches = array(); + if ($type == 'node') { + $query->addTag('node_access'); + foreach ($query->execute() as $nodeish) { + $name = empty($nodeish->name) ? variable_get('anonymous', t('Anonymous')) : check_plain($nodeish->name); + $matches[$nodeish->title . " [id: $nodeish->nid]"] = '<span class="autocomplete_title">' . check_plain($nodeish->title) . '</span> <span class="autocomplete_user">(' . t('by @user', array('@user' => $name)) . ')</span>'; + } + } + else { + foreach ($query->execute() as $item) { + $id = $item->{$entity['entity keys']['id']}; + if ($entity['entity keys']['label']) { + $matches[$item->{$entity['entity keys']['label']} . " [id: $id]"] = '<span class="autocomplete_title">' . check_plain($item->{$entity['entity keys']['label']}) . '</span>'; + } + else { + $matches["[id: $id]"] = '<span class="autocomplete_title">' . check_plain($item->{$entity['entity keys']['id']}) . '</span>'; + } + } + } + drupal_json_output($matches); + } +} diff --git a/sites/all/modules/ctools/includes/content.plugin-type.inc b/sites/all/modules/ctools/includes/content.plugin-type.inc new file mode 100644 index 0000000000000000000000000000000000000000..66b330e4c063e9b8f449112b852f9f6a7cc9d50a --- /dev/null +++ b/sites/all/modules/ctools/includes/content.plugin-type.inc @@ -0,0 +1,18 @@ +<?php +// $Id: content.plugin-type.inc,v 1.1 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @file + * Contains plugin type registration information for the content tool. + */ + +function ctools_content_plugin_type(&$items) { + $items['content_types'] = array( + 'cache' => FALSE, + 'process' => array( + 'function' => 'ctools_content_process', + 'file' => 'export-ui.inc', + 'path' => drupal_get_path('module', 'ctools') . '/includes', + ), + ); +} \ No newline at end of file diff --git a/sites/all/modules/ctools/includes/content.theme.inc b/sites/all/modules/ctools/includes/content.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..f3a34f60e251ecde6923bb6dfc4b5e0618dd6308 --- /dev/null +++ b/sites/all/modules/ctools/includes/content.theme.inc @@ -0,0 +1,22 @@ +<?php +// $Id: content.theme.inc,v 1.4 2009/10/17 22:58:25 sdboyer Exp $ + +/** + * @file + * Contains theme registry and theme implementations for the content types. + */ + +/** + * Implements 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/sites/all/modules/ctools/includes/context-access-admin.inc b/sites/all/modules/ctools/includes/context-access-admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..7b458983333f0e7d4b62eaab9280b3cda223bdbd --- /dev/null +++ b/sites/all/modules/ctools/includes/context-access-admin.inc @@ -0,0 +1,487 @@ +<?php +// $Id: context-access-admin.inc,v 1.12 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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'); + * $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 = drupal_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, &$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( + '#markup' => 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' => array("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' => array("ctools-access-add-url")), + '#type' => 'select', + '#options' => $options, + '#required' => FALSE, + ); + + $form['add-button']['add'] = array( + '#type' => 'submit', + '#attributes' => array('class' => array('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' => array('ctools-access-title')); + + $description = ctools_access_summary($plugin, $contexts, $test); + $row[] = array('data' => $description, 'class' => array('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' => array('ctools-access-operations'), 'align' => 'right'); + + $rows[] = $row; + } + + $header = array( + array('data' => t('Title'), 'class' => array('ctools-access-title')), + array('data' => t('Description'), 'class' => array('ctools-access-description')), + array('data' => '', 'class' => array('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', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'ctools-access-table'))); +} + +/** + * Theme the 'add' portion of the access form into a table. + */ +function theme_ctools_access_admin_add($vars) { + $rows = array(array(drupal_render_children($vars['form']))); + $output = '<div class="container-inline">'; + $output .= theme('table', array('rows' => $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, + 'modal' => TRUE, + 'modal return' => TRUE, + ); + + $output = ctools_modal_form_wrapper('ctools_access_ajax_edit_item', $form_state); + if (!isset($output[0])) { + $function = $module . '_ctools_access_set'; + if (function_exists($function)) { + $function($argument, $access); + } + + $table = ctools_access_admin_render_table($access, $fragment, $contexts); + $output = array(); + $output[] = ajax_command_replace('table#ctools-access-table', $table); + $output[] = ctools_modal_command_dismiss(); + } + + print 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, + 'ajax' => TRUE, + 'modal' => TRUE, + 'modal return' => TRUE, + ); + + $output = ctools_modal_form_wrapper('ctools_access_ajax_edit_item', $form_state); + if (!isset($output[0])) { + $function = $module . '_ctools_access_set'; + if (function_exists($function)) { + $function($argument, $access); + } + + $table = ctools_access_admin_render_table($access, $fragment, $contexts); + $output = array(); + $output[] = ajax_command_replace('table#ctools-access-table', $table); + $output[] = ctools_modal_command_dismiss(); + } + + print ajax_render($output); +} + +/** + * Form to edit the settings of an access test. + */ +function ctools_access_ajax_edit_item($form, &$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')) { + $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)) { + 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)) { + 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[] = ajax_command_replace('table#ctools-access-table', $table); + + print ajax_render($output); +} diff --git a/sites/all/modules/ctools/includes/context-admin.inc b/sites/all/modules/ctools/includes/context-admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..1fba7bbe376caa3eeb9d79982551c1a52ee7a7b4 --- /dev/null +++ b/sites/all/modules/ctools/includes/context-admin.inc @@ -0,0 +1,783 @@ +<?php +// $Id: context-admin.inc,v 1.14 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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', + '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', + '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', + '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', + 'key' => 'requiredcontexts', + 'sortable' => FALSE, + ), + ); + } + + if ($type === NULL) { + return $info; + } + + return $info[$type]; +} + + +/** + * Get the data belonging to a particular context. + */ +function ctools_context_get_plugin($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, $cache_key = NULL) { + if (empty($cache_key)) { + $cache_key = $object->name; + } + + $form_location = array( + '#prefix' => '<div id="ctools-arguments-table">', + '#suffix' => '</div>', + '#theme' => 'ctools_context_item_form', + '#cache_key' => $cache_key, + '#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, $cache_key = NULL) { + if (empty($cache_key)) { + $cache_key = $object->name; + } + + $form_location = array( + '#prefix' => '<div id="ctools-contexts-table">', + '#suffix' => '</div>', + '#theme' => 'ctools_context_item_form', + '#cache_key' => $cache_key, + '#ctools_context_type' => 'context', + '#ctools_context_module' => $module, + ); + + // Store the order the choices are in so javascript can manipulate it. + $form_location['markup'] = array( + '#markup' => ' ', + ); + + $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, $cache_key = NULL) { + if (empty($cache_key)) { + $cache_key = $object->name; + } + + $form_location = array( + '#prefix' => '<div id="ctools-requiredcontexts-table">', + '#suffix' => '</div>', + '#theme' => 'ctools_context_item_form', + '#cache_key' => $cache_key, + '#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, $cache_key = NULL) { + if (empty($cache_key)) { + $cache_key = $object->name; + } + + $form_location = array( + '#prefix' => '<div id="ctools-relationships-table">', + '#suffix' => '</div>', + '#theme' => 'ctools_context_item_form', + '#cache_key' => $cache_key, + '#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']; + $cache_key = $form['#cache_key']; + + if (isset($items) && is_array($items)) { + foreach ($items as $position => $context) { + ctools_context_add_item_to_form($module, $type, $cache_key, $form[$type][$position], $position, $context); + } + } + + $type_info = ctools_context_info($type); + $form['description'] = array( + '#prefix' => '<div class="description">', + '#suffix' => '</div>', + '#markup' => $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) { + drupal_add_js('misc/ajax.js'); + $form['buttons'] = array( + '#tree' => TRUE, + ); + + if (!empty($available_contexts)) { + $type_info = ctools_context_info($type); + + $module = $form['#ctools_context_module']; + $cache_key = $form['#cache_key']; + + // The URL for this ajax button + $form['buttons'][$type]['add-url'] = array( + '#attributes' => array('class' => array("ctools-$type-add-url")), + '#type' => 'hidden', + '#value' => url("ctools/context/ajax/add/$module/$type/$cache_key", array('absolute' => TRUE)), + ); + + // This also will be in the URL. + $form['buttons'][$type]['item'] = array( + '#attributes' => array('class' => array("ctools-$type-add-url")), + '#type' => 'select', + '#options' => $available_contexts, + '#required' => FALSE, + ); + + $form['buttons'][$type]['add'] = array( + '#type' => 'submit', + '#attributes' => array('class' => array('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, $cache_key, &$form, $position, $item) { + // This is the single function way to load any plugin by variable type. + $info = ctools_context_get_plugin($type, $item['name']); + $form['title'] = array( + '#markup' => 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' => array('drag-position')), + ); + } + + $form['remove'] = array( + '#markup' => ctools_ajax_image_button(ctools_image_path('icon-delete.png'), "ctools/context/ajax/delete/$module/$type/$cache_key/$position", t('Remove this item.')), + ); + + $form['settings'] = array( + '#markup' => ctools_modal_image_button(ctools_image_path('icon-configure.png'), "ctools/context/ajax/configure/$module/$type/$cache_key/$position", t('Configure settings for this item.')), + ); +} + + +// --------------------------------------------------------------------------- +// AJAX forms and stuff. + +/** + * Ajax entry point to add an context + */ +function ctools_context_ajax_item_add($mechanism = NULL, $type = NULL, $cache_key = NULL, $name = NULL, $step = NULL) { + ctools_include('ajax'); + ctools_include('modal'); + ctools_include('context'); + ctools_include('cache'); + ctools_include('plugins-admin'); + + if (!$name) { + return ctools_ajax_render_error(); + } + + // Load stored object from cache. + if (!($object = ctools_cache_get($mechanism, $cache_key))) { + ctools_ajax_render_error(t('Invalid object name.')); + } + + // Get info about what we're adding, i.e, relationship, context, argument, etc. + $plugin_definition = ctools_context_get_plugin($type, $name); + if (empty($plugin_definition)) { + ctools_ajax_render_error(t('Invalid context type')); + } + + // Set up the $conf array for this plugin + if (empty($step) || empty($object->temporary)) { + // Create the basis for our new context. + $conf = ctools_context_get_defaults($plugin_definition); + $object->temporary = &$conf; + } + else { + $conf = &$object->temporary; + } + + // Load the contexts that may be used. + $base_contexts = isset($object->base_contexts) ? $object->base_contexts : array(); + $contexts = ctools_context_load_contexts($object, TRUE, $base_contexts); + + $type_info = ctools_context_info($type); + $form_state = array( + 'ajax' => TRUE, + 'modal' => TRUE, + 'modal return' => TRUE, + 'object' => &$object, + 'conf' => &$conf, + 'plugin' => $plugin_definition, + 'type' => $type, + 'contexts' => $contexts, + 'title' => t('Add @type "@context"', array('@type' => $type_info['singular title'], '@context' => $plugin_definition['title'])), + 'type info' => $type_info, + 'op' => 'add', + 'step' => $step, + ); + + $form_info = array( + 'path' => "ctools/context/ajax/add/$mechanism/$type/$cache_key/$name/%step", + 'show cancel' => TRUE, + 'default form' => 'ctools_edit_context_form_defaults', + 'auto caching' => TRUE, + 'cache mechanism' => $mechanism, + 'cache key' => $cache_key, + // This is stating what the cache will be referred to in $form_state + 'cache storage' => 'object', + ); + + $output = ctools_plugin_configure_form($form_info, $form_state); + + // If $rc is FALSE, there was no actual form. + if ($output === FALSE || !empty($form_state['complete'])) { + // Successful submit -- move temporary data to location. + + // 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']}; + + // Figure out the position for our new context. + $position = empty($ref) ? 0 : max(array_keys($ref)) + 1; + + $conf['id'] = ctools_context_next_id($ref, $name); + $ref[$position] = $conf; + + if (isset($object->temporary)) { + unset($object->temporary); + } + + ctools_cache_operation($mechanism, $cache_key, 'finalize', $object); + + // Very irritating way to update the form for our contexts. + $arg_form_state = array('values' => 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($mechanism, $type, $cache_key, $arg_form[$type][$position], $position, $ref[$position]); + $arg_form = form_builder('ctools_context_form', $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', + '#cache_key' => $cache_key, + '#ctools_context_type' => 'relationship', + '#ctools_context_module' => $mechanism, + '#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', $mechanism, $rel_form, $available_relationships); + $rel_form = form_builder('dummy_form_id', $rel_form, $arg_form_state); + $output[] = ajax_command_replace('div#ctools-relationships-table div.buttons', drupal_render($rel_form)); + } + + $theme_vars = array(); + $theme_vars['type'] = $type; + $theme_vars['form'] = $arg_form[$type][$position]; + $theme_vars['position'] = $position; + $theme_vars['count'] = $position; + $text = theme('ctools_context_item_row', $theme_vars); + $output[] = ajax_command_append('#' . $type . '-table tbody', $text); + $output[] = ajax_command_changed('#' . $type . '-row-' . $position, '.title'); + $output[] = ctools_modal_command_dismiss(); + } + else { + $output = ctools_modal_form_render($form_state, $output); + } + print ajax_render($output); + exit; +} + +/** + * Ajax entry point to edit an item + */ +function ctools_context_ajax_item_edit($mechanism = NULL, $type = NULL, $cache_key = NULL, $position = NULL, $step = NULL) { + ctools_include('ajax'); + ctools_include('modal'); + ctools_include('context'); + ctools_include('cache'); + ctools_include('plugins-admin'); + + if (!isset($position)) { + return ctools_ajax_render_error(); + } + + // Load stored object from cache. + if (!($object = ctools_cache_get($mechanism, $cache_key))) { + 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 (empty($step) || empty($object->temporary)) { + // Create the basis for our new context. + $conf = $object->{$type_info['key']}[$position]; + $object->temporary = &$conf; + } + else { + $conf = &$object->temporary; + } + + $name = $ref[$position]['name']; + if (empty($name)) { + ctools_ajax_render_error(); + } + + // load the plugin definition + $plugin_definition = ctools_context_get_plugin($type, $name); + if (empty($plugin_definition)) { + ctools_ajax_render_error(t('Invalid context type')); + } + + // Load the contexts + $base_contexts = isset($object->base_contexts) ? $object->base_contexts : array(); + $contexts = ctools_context_load_contexts($object, TRUE, $base_contexts); + + $form_state = array( + 'ajax' => TRUE, + 'modal' => TRUE, + 'modal return' => TRUE, + 'object' => &$object, + 'conf' => &$conf, + 'position' => $position, + 'plugin' => $plugin_definition, + 'type' => $type, + 'contexts' => $contexts, + 'title' => t('Edit @type "@context"', array('@type' => $type_info['singular title'], '@context' => $plugin_definition['title'])), + 'type info' => $type_info, + 'op' => 'add', + 'step' => $step, + ); + + $form_info = array( + 'path' => "ctools/context/ajax/configure/$mechanism/$type/$cache_key/$position/%step", + 'show cancel' => TRUE, + 'default form' => 'ctools_edit_context_form_defaults', + 'auto caching' => TRUE, + 'cache mechanism' => $mechanism, + 'cache key' => $cache_key, + // This is stating what the cache will be referred to in $form_state + 'cache storage' => 'object', + ); + + $output = ctools_plugin_configure_form($form_info, $form_state); + + // If $rc is FALSE, there was no actual form. + if ($output === FALSE || !empty($form_state['complete'])) { + // successful submit + $ref[$position] = $conf; + if (isset($object->temporary)) { + unset($object->temporary); + } + + ctools_cache_operation($mechanism, $cache_key, 'finalize', $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($mechanism, $type, $cache_key, $arg_form[$type][$position], $position, $ref[$position]); + $arg_form = form_builder('ctools_context_form', $arg_form, $arg_form_state); + + $theme_vars = array(); + $theme_vars['type'] = $type; + $theme_vars['form'] = $arg_form[$type][$position]; + $theme_vars['position'] = $position; + $theme_vars['count'] = $position; + $output[] = ajax_command_replace('#' . $type . '-row-' . $position, theme('ctools_context_item_row', $theme_vars)); + $output[] = ajax_command_changed('#' . $type . '-row-' . $position, '.title'); + } + else { + $output = ctools_modal_form_render($form_state, $output); + } + print ajax_render($output); + exit; +} + +function ctools_context_get_defaults($plugin_definition) { + $conf = array( + 'identifier' => $plugin_definition['title'] . ($id > 1 ? ' ' . $id : ''), + 'keyword' => ctools_get_keyword($object, $plugin_definition['keyword']), + 'name' => $plugin_definition['name'], + ); + + 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 ($settings = $defaults($plugin_definition)) { + $conf += $settings; + } + } + else if (is_array($defaults)) { + $conf += $defaults; + } + } + + return $conf; +} + +/** + * Form wrapper for the edit context form. + * + * @todo: We should uncombine these. + */ +function ctools_edit_context_form_defaults($form, &$form_state) { + // Basic values required to orient ourselves + $object = $form_state['object']; + $plugin_definition = $form_state['plugin']; + $type_info = $form_state['type info']; + $position = $form_state['position']; + $contexts = $form_state['contexts']; + $conf = $form_state['conf']; + + if ($type_info['key'] == 'arguments' && !isset($conf['default'])) { + $conf['default'] = 'ignore'; + $conf['title'] = ''; + } + + $form['description'] = array( + '#prefix' => '<div class="description">', + '#suffix' => '</div>', + '#markup' => check_plain($plugin_definition['description']), + ); + + if ($type_info['key'] == 'relationships') { + $form['context'] = ctools_context_selector($contexts, $plugin_definition['required context'], isset($conf['context']) ? $conf['context'] : ''); + } + if ($type_info['key'] == 'arguments') { + $form['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' => $conf['default'], + '#description' => t('If the argument is missing or is not valid, select how this should behave.'), + ); + + $form['title'] = array( + '#type' => 'textfield', + '#title' => t('Title'), + '#default_value' => $conf['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['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' => $conf['identifier'], + ); + + $form['keyword'] = array( + '#type' => 'textfield', + '#title' => t('Keyword'), + '#description' => t('Enter a keyword to use for substitution in titles.'), + '#default_value' => $conf['keyword'], + ); + + $form['#submit'][] = 'ctools_edit_context_form_defaults_submit'; + + return $form; +} + +/** + * Submit handler to store context identifier and keyword info. + */ +function ctools_edit_context_form_defaults_submit(&$form, &$form_state) { + if ($form_state['type info']['key'] == 'relationships') { + $form_state['conf']['context'] = $form_state['values']['context']; + } + if ($form_state['type info']['key'] == 'arguments') { + $form_state['conf']['default'] = $form_state['values']['default']; + $form_state['conf']['title'] = $form_state['values']['title']; + } + + $form_state['conf']['identifier'] = $form_state['values']['identifier']; + $form_state['conf']['keyword'] = $form_state['values']['keyword']; +} + +/** + * Ajax entry point to edit an item + */ +function ctools_context_ajax_item_delete($mechanism = NULL, $type = NULL, $cache_key = NULL, $position = NULL) { + ctools_include('ajax'); + ctools_include('context'); + ctools_include('cache'); + + if (!isset($position)) { + return ctools_ajax_render_error(); + } + + // Load stored object from cache. + if (!($object = ctools_cache_get($mechanism, $cache_key))) { + 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_cache_operation($mechanism, $cache_key, 'finalize', $object); + + $output = array(); + $output[] = ajax_command_replace('#' . $type . '-row-' . $position, ''); + $output[] = ajax_command_restripe("#$type-table"); + print ajax_render($output); + exit; +} + +// --- 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/sites/all/modules/ctools/includes/context-task-handler.inc b/sites/all/modules/ctools/includes/context-task-handler.inc new file mode 100644 index 0000000000000000000000000000000000000000..cc51292145669b6ea596db7158c655eaae245076 --- /dev/null +++ b/sites/all/modules/ctools/includes/context-task-handler.inc @@ -0,0 +1,487 @@ +<?php +// $Id: context-task-handler.inc,v 1.35 2011/01/05 20:06:57 merlinofchaos Exp $ + +/** + * @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) { + // Load the landlers, choosing only enabled handlers. + $handlers = page_manager_load_sorted_handlers($task, $subtask ? $subtask['name'] : '', TRUE); + + $id = ctools_context_handler_get_render_handler($task, $subtask, $handlers, $contexts, $args); + if ($id) { + return ctools_context_handler_render_handler($task, $subtask, $handlers[$id], $contexts, $args); + } +} + +/** + * Figure out which of the listed handlers should be used to render. + */ +function ctools_context_handler_get_render_handler($task, $subtask, $handlers, $contexts, $args) { + // Try each handler. + foreach ($handlers as $id => $handler) { + $plugin = page_manager_get_task_handler($handler->handler); + // First, see if the handler has a tester. + $function = ctools_plugin_get_function($plugin, 'test'); + if ($function) { + $test = $function($handler, $contexts, $args); + if ($test) { + return $id; + } + } + else { + // If not, if it's a 'context' type handler, use the default tester. + if ($plugin['handler type'] == 'context') { + $test = ctools_context_handler_default_test($handler, $contexts, $args); + } + if ($test) { + return $id; + } + } + } + + return FALSE; +} + +/** + * Default test function to see if a task handler should be rendered. + * + * This tests against the standard selection criteria that most task + * handlers should be implementing. + */ +function ctools_context_handler_default_test($handler, $base_contexts, $args) { + ctools_include('context'); + // Add my contexts + $contexts = ctools_context_handler_get_handler_contexts($base_contexts, $handler); + + // Test. + return ctools_context_handler_select($handler, $contexts); +} + +/** + * Render a task handler. + */ +function ctools_context_handler_render_handler($task, $subtask, $handler, $contexts, $args, $page = TRUE) { + $function = page_manager_get_renderer($handler); + if (!$function) { + return NULL; + } + + $info = $function($handler, $contexts, $args); + if (!$info) { + return NULL; + } + + $context = array( + 'args' => $args, + 'contexts' => $contexts, + 'task' => $task, + 'subtask' => $subtask, + 'handler' => $handler + ); + drupal_alter('ctools_render', $info, $page, $context); + + // 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' => '', + ); + $options = array( + 'query' => $info['query'], + 'fragment' => $info['fragment'], + ); + return drupal_goto($info['destination'], $options, $info['response code']); + // @todo -- should other response codes be supported here? + } + } + + 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'])) { + ctools_set_no_blocks(FALSE); + } + return $info['content']; +} + +/** + * 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), + 'type' => MENU_LOCAL_ACTION + )); + } +} + +/** + * 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( + '#markup' => '<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 meets its criteria (as specified below) will be used.') . + '</div>', + ); + $form = ctools_access_admin_form($form, $form_state); + return $form; +} + +/** + * 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="clearfix"><div class="right-container">', + '#suffix' => '</div>', + ); + + $form['left'] = array( + '#prefix' => '<div class="left-container">', + '#suffix' => '</div></div>', + ); + + $module = 'page_manager_context::' . $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); + + $theme_vars = array(); + $theme_vars['object'] = $cache; + $theme_vars['header'] = t('Summary of contexts'); + $form['left']['summary'] = array( + '#prefix' => '<div class="page-manager-contexts">', + '#suffix' => '</div>', + '#markup' => theme('ctools_context_list', $theme_vars), + ); + + $form_state['context_object'] = &$cache; + return $form; +} + +/** + * 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/sites/all/modules/ctools/includes/context.inc b/sites/all/modules/ctools/includes/context.inc new file mode 100644 index 0000000000000000000000000000000000000000..97c3e1a38ee19ad6430b907d96a88a34abb44adf --- /dev/null +++ b/sites/all/modules/ctools/includes/context.inc @@ -0,0 +1,1543 @@ +<?php +// $Id: context.inc,v 1.44 2011/01/05 20:34:46 merlinofchaos Exp $ + +/** + * @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($plugin); + } + + 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) { + // Contexts without plugins might be optional placeholders. + if (empty($context->plugin)) { + return; + } + + $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'); + $plugin = ctools_get_context($type); + if ($function = ctools_plugin_load_function('ctools', 'contexts', $type, 'context')) { + return $function(FALSE, $data, $conf, $plugin); + } +} + +/** + * 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) { + $plugin = ctools_get_context($type); + if ($function = ctools_plugin_get_function($plugin, 'context')) { + $context = $function(TRUE, NULL, FALSE, $plugin); + 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')) { + // Backward compatibility: Merge old style settings into new style: + if (!empty($argument['settings'])) { + $argument += $argument['settings']; + unset($argument['settings']); + } + + $context = $function($arg, $argument, $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')) { + // Backward compatibility: Merge old style settings into new style: + if (!empty($relationship['relationship_settings'])) { + $relationship += $relationship['relationship_settings']; + unset($relationship['relationship_settings']); + } + + $context = $function($source_context, $relationship, $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')) { + // Backward compatibility: Merge old style settings into new style: + if (!empty($context['context_settings'])) { + $context += $context['context_settings']; + unset($context['context_settings']); + } + + if (isset($argument) && isset($plugin['placeholder name'])) { + $context[$plugin['placeholder name']] = $argument; + } + + $return = $function($type == 'requiredcontext', $context, TRUE, $plugin); + 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, 'requiredcontext', $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']); + break; + + case 'context': + $info = $context->placeholder['conf']; + $plugin = ctools_get_context($info['name']); + 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); + 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('entity: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/sites/all/modules/ctools/includes/context.menu.inc b/sites/all/modules/ctools/includes/context.menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..39bcd9b25daf218696075095e4a940718cfa1769 --- /dev/null +++ b/sites/all/modules/ctools/includes/context.menu.inc @@ -0,0 +1,40 @@ +<?php +// $Id: context.menu.inc,v 1.2 2008/12/30 18:21:34 merlinofchaos Exp $ + +/** + * @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/sites/all/modules/ctools/includes/context.plugin-type.inc b/sites/all/modules/ctools/includes/context.plugin-type.inc new file mode 100644 index 0000000000000000000000000000000000000000..fd28c34e5e20c6b2bac103671ad0c022d87550c4 --- /dev/null +++ b/sites/all/modules/ctools/includes/context.plugin-type.inc @@ -0,0 +1,25 @@ +<?php +// $Id: context.plugin-type.inc,v 1.2 2011/01/05 20:34:46 merlinofchaos Exp $ + +/** + * @file + * Contains plugin type registration information for the context tool. + * + * Don't actually need to declare anything for these plugin types right now, + * apart from the fact that they exist. So, an empty array. + */ + +function ctools_context_plugin_type(&$items) { + $items['contexts'] = array( + 'child plugins' => TRUE, + ); + $items['arguments'] = array( + 'child plugins' => TRUE, + ); + $items['relationships'] = array( + 'child plugins' => TRUE, + ); + $items['access'] = array( + 'child plugins' => TRUE, + ); +} diff --git a/sites/all/modules/ctools/includes/context.theme.inc b/sites/all/modules/ctools/includes/context.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..1b437d8ed3b452e6645041885bbb771ea704025c --- /dev/null +++ b/sites/all/modules/ctools/includes/context.theme.inc @@ -0,0 +1,345 @@ +<?php +// $Id: context.theme.inc,v 1.15 2011/01/05 19:56:46 merlinofchaos Exp $ + +/** + * @file + * Contains theme registry and theme implementations for the context tool. + */ + +/** + * Implements hook_theme() + */ +function ctools_context_theme(&$theme) { + $theme['ctools_context_list'] = array( + 'variables' => array('object' => NULL), + 'file' => 'includes/context.theme.inc', + ); + $theme['ctools_context_list_no_table'] = array( + 'variables' => array('object' => NULL), + 'file' => 'includes/context.theme.inc', + ); + $theme['ctools_context_item_form'] = array( + 'render element' => 'form', +// 'variables' => array('form' => NULL), + 'file' => 'includes/context.theme.inc', + ); + $theme['ctools_context_item_row'] = array( + 'variables' => array('type' => NULL, 'form' => NULL, 'position' => NULL, 'count' => NULL, 'with_tr' => TRUE), + 'file' => 'includes/context.theme.inc', + ); + + // For the access plugin + $theme['ctools_access_admin_add'] = array( + 'render element' => 'form', + 'file' => 'includes/context-access-admin.inc', + ); +} + +/** + * Theme the form item for the context entry. + */ +function theme_ctools_context_item_row($vars) { + $type = $vars['type']; + $form = $vars['form']; + $position = $vars['position']; + $count = $vars['count']; + $with_tr = $vars['with_tr']; + $output = '<td class="title"> ' . render($form['title']) . '</td>'; + if (!empty($form['position'])) { + $output .= '<td class="position"> ' . render($form['position']) . '</td>'; + } + $output .= '<td class="operation">' . render($form['settings']); + $output .= 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($vars) { + $form = $vars['form']; + + $output = ''; + $type = $form['#ctools_context_type']; + $module = $form['#ctools_context_module']; + $cache_key = $form['#cache_key']; + + $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; + } + $theme_vars = array(); + $theme_vars['type'] = $type; + $theme_vars['form'] = $form[$type][$id]; + $theme_vars['position'] = $id; + $theme_vars['count'] = $count++; + $rows .= theme('ctools_context_item_row', $theme_vars); + } + + $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' => render($form['buttons'][$type]['item']), 'class' => array('title')); + $row[] = array('data' => render($form['buttons'][$type]['add']), 'class' => array('add'), 'width' => "60%"); + $output .= '<div class="buttons">'; + $output .= render($form['buttons'][$type]); + $theme_vars = array(); + $theme_vars['header'] = array(); + $theme_vars['rows'] = array($row); + $theme_vars['attributes'] = array('id' => $type . '-add-table'); + $output .= theme('table', $theme_vars); + $output .= '</div>'; + } + if (!empty($form['description'])) { + $output .= 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($vars) { + $object = $vars['object']; + $header = $vars['header']; + $description = (!empty($vars['description'])) ? $vars['description'] : NULL; + $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($vars) { + $object = $vars['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 clearfix">'; + $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 clearfix">'; + $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 clearfix">'; + $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 clearfix">'; + 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/sites/all/modules/ctools/includes/css.inc b/sites/all/modules/ctools/includes/css.inc new file mode 100644 index 0000000000000000000000000000000000000000..47a17c2d81219301c77e4d06350b2bdb2eae5bfa --- /dev/null +++ b/sites/all/modules/ctools/includes/css.inc @@ -0,0 +1,563 @@ +<?php +/* $Id: css.inc,v 1.18 2010/10/15 20:54:24 merlinofchaos Exp $ */ + +/* + * @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); + * drupal_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_query('SELECT filename FROM {ctools_css_cache} WHERE cid = :cid', array(':cid' => $id))->fetchField(); + if ($filename && file_exists($filename)) { + file_unmanaged_delete($filename); + } + // Remove any previous records. + db_delete('ctools_css_cache') + ->condition('cid', $id) + ->execute(); + + $filename = ctools_css_cache($css, $filter); + + db_insert('ctools_css_cache') + ->fields(array( + 'cid' => $id, + 'filename' => $filename, + 'css' => $css, + 'filter' => intval($filter), + )) + ->execute(); + + 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_query('SELECT * FROM {ctools_css_cache} WHERE cid = :cid', array(':cid' => $id))->fetchObject(); + if (!$cache) { + return; + } + + if (!file_exists($cache->filename)) { + $filename = ctools_css_cache($cache->css, $cache->filter); + if ($filename != $cache->filename) { + db_update('ctools_css_cache') + ->fields(array('filename' => $filename)) + ->condition('cid', $id) + ->execute(); + $cache->filename = $filename; + } + } + + return $cache->filename; +} + +/** + * Remove stored CSS and any associated file. + */ +function ctools_css_clear($id) { + $cache = db_query('SELECT * FROM {ctools_css_cache} WHERE cid = :cid', array(':cid' => $id))->fetchObject(); + if (!$cache) { + return; + } + + if (file_exists($cache->filename)) { + file_unmanaged_delete($cache->filename); + // If we remove an existing file, there may be cached pages that refer + // to it. We must get rid of them: FIXME same format in D7? + cache_clear_all(); + } + + db_delete('ctools_css_cache') + ->condition('cid', $id) + ->execute(); +} + +/** + * 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 drupal_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 = 'public://ctools/css'; + if (!file_prepare_directory($path, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) { +// if (!file_prepare_directory($path, FILE_CREATE_DIRECTORY)) { + 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_unmanaged_save_data($css, $filename); + + return $filename; +} + +/** + * 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 + $statements = explode("}", $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. + $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() { + // Remove all generated files. + // @see http://drupal.org/node/573292 + // file_unmanaged_delete_recursive('public://render'); + $filedir = file_default_scheme() . '://ctools/css'; + file_unmanaged_delete_recursive($filedir); + + db_delete('ctools_css_cache')->execute(); +} diff --git a/sites/all/modules/ctools/includes/dependent.inc b/sites/all/modules/ctools/includes/dependent.inc new file mode 100644 index 0000000000000000000000000000000000000000..2e866dceb2bcb74b2d25550b6f1ba32869d1bedc --- /dev/null +++ b/sites/all/modules/ctools/includes/dependent.inc @@ -0,0 +1,155 @@ +<?php +// $Id: dependent.inc,v 1.9 2011/01/04 01:21:30 merlinofchaos Exp $ + +/** + * @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, &$form_state, &$form) { + if (isset($element['#dependency'])) { + // Don't actually add any javascript until render time. + $element['#pre_render'][] = 'ctools_dependent_pre_render'; + } + + return $element; +} + +function ctools_dependent_pre_render($element) { + 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'], + ); + + ctools_add_js('dependent'); + $options['CTools']['dependent'][$element['#id']] = $js; + drupal_add_js($options, 'setting'); + + return $element; +} diff --git a/sites/all/modules/ctools/includes/dropdown.theme.inc b/sites/all/modules/ctools/includes/dropdown.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..3e030d3d42ce27599c6f6a1d19ce384d011b6fa7 --- /dev/null +++ b/sites/all/modules/ctools/includes/dropdown.theme.inc @@ -0,0 +1,88 @@ +<?php +// $Id: dropdown.theme.inc,v 1.7 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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( + 'variables' => 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($vars) { + // Provide a unique identifier for every dropdown on the page. + static $id = 0; + $id++; + + $class = 'ctools-dropdown-no-js ctools-dropdown' . ($vars['class'] ? (' ' . $vars['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 ($vars['image']) { + $output .= '<a href="#" class="ctools-dropdown-link ctools-dropdown-image-link">' . $vars['title'] . '</a>'; + } + else { + $output .= '<a href="#" class="ctools-dropdown-link ctools-dropdown-text-link">' . check_plain($vars['title']) . '</a>'; + } + + $output .= '</div>'; // wrapper + $output .= '<div class="ctools-dropdown-container-wrapper">'; + $output .= '<div class="ctools-dropdown-container">'; + $output .= theme_links(array('links' => $vars['links'], 'attributes' => array(), 'heading' => '')); + $output .= '</div>'; // container + $output .= '</div>'; // container wrapper + $output .= '</div>'; // dropdown + return $output; +} + diff --git a/sites/all/modules/ctools/includes/export-ui.inc b/sites/all/modules/ctools/includes/export-ui.inc new file mode 100644 index 0000000000000000000000000000000000000000..0a13ba56a85eb9a07e87d3725ecf78a7b2c0cd7a --- /dev/null +++ b/sites/all/modules/ctools/includes/export-ui.inc @@ -0,0 +1,467 @@ +<?php +// $Id: export-ui.inc,v 1.3 2010/12/31 23:50:25 merlinofchaos Exp $ + +/** + * @file + * Provide a tool for creating UIs for exportable objects. + * + * See Advanced Help for documentation. + */ + +/** + * 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', + ); + + // 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 (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/structure', + '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_ACTION, + ), + '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_ACTION, + ), + ); + } + + 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(), + ); + + // 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'])), + ); +} + +/** + * 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 = &drupal_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['js']); + + // 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/sites/all/modules/ctools/includes/export-ui.menu.inc b/sites/all/modules/ctools/includes/export-ui.menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..bc8130e2c38fa35311132976c81188560d78143c --- /dev/null +++ b/sites/all/modules/ctools/includes/export-ui.menu.inc @@ -0,0 +1,25 @@ +<?php +// $Id: export-ui.menu.inc,v 1.4 2011/01/01 01:14:24 merlinofchaos Exp $ + +/** + * Delegated implementation of hook_menu(). + */ +function ctools_export_ui_menu(&$items) { + ctools_include('export-ui'); + + // If a menu rebuild is triggered because of module enable/disable, + // this might be out of date. Reset the cache. + ctools_include('plugins'); + ctools_get_plugins_reset(); + + foreach (ctools_get_export_uis() as $plugin) { + // We also need to make sure that the module hasn't been disabled. During + // the disable process, the module's plugins still still appear. + if ($plugin['has menu'] && module_exists($plugin['module'])) { + $handler = ctools_export_ui_get_handler($plugin); + if ($handler) { + $handler->hook_menu($items); + } + } + } +} diff --git a/sites/all/modules/ctools/includes/export-ui.plugin-type.inc b/sites/all/modules/ctools/includes/export-ui.plugin-type.inc new file mode 100644 index 0000000000000000000000000000000000000000..06e84a6fc088e7596f428af0809ee12df8d08391 --- /dev/null +++ b/sites/all/modules/ctools/includes/export-ui.plugin-type.inc @@ -0,0 +1,21 @@ +<?php +// $Id: export-ui.plugin-type.inc,v 1.1 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @file + * Contains plugin type registration information for the context tool. + * + * Don't actually need to declare anything for these plugin types right now, + * apart from the fact that they exist. So, an empty array. + */ + +function ctools_export_ui_plugin_type(&$items) { + $items['export_ui'] = array( + 'process' => array( + 'function' => 'ctools_export_ui_process', + 'file' => 'export-ui.inc', + 'path' => drupal_get_path('module', 'ctools') . '/includes', + ), + 'classes' => array('handler'), + ); +} \ No newline at end of file diff --git a/sites/all/modules/ctools/includes/export.inc b/sites/all/modules/ctools/includes/export.inc new file mode 100644 index 0000000000000000000000000000000000000000..16bf635402f36f87b4a22ad068af027141d92fbb --- /dev/null +++ b/sites/all/modules/ctools/includes/export.inc @@ -0,0 +1,1013 @@ +<?php +// $Id: export.inc,v 1.31 2010/12/31 23:50:25 merlinofchaos Exp $ + +/** + * @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_delete($table) + ->condition($export['key'], $value) + ->execute(); + } +} + +/** + * 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->type = 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 = &drupal_static(__FUNCTION__); + $cached_database = &drupal_static('ctools_export_load_object_all'); + + $schema = ctools_export_get_schema($table); + if (empty($schema)) { + return 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 = db_select($table, 't__0')->fields('t__0'); + $alias_count = 1; + if (!empty($schema['join'])) { + foreach ($schema['join'] as $join_key => $join) { + if ($join_schema = drupal_get_schema($join['table'])) { + $query->join($join['table'], 't__' . $alias_count, 't__0' . $join['left_key'] . ' = ' . 't__' . $alias_count . '.' . $join['right_key']); + $query->fields('t__' . $alias_count); + $alias_count++; + + // Allow joining tables to alter the query through a callback. + if (isset($join['callback']) && function_exists($join['callback'])) { + $join['callback']($query, $schema, $join_schema); + } + } + } + } + + $conditions = array(); + $query_args = array(); + + // If they passed in names, add them to the query. + if ($type == 'names') { + $query->condition($export['key'], $args, 'IN'); + } + else if ($type == 'conditions') { + foreach ($args as $key => $value) { + if (isset($schema['fields'][$key])) { + $query->condition($key, $value); + } + } + } + + $result = $query->execute(); + + $status = variable_get($export['status'], array()); + // Unpack the results of the query onto objects and cache them. + foreach ($result as $data) { + $object = _ctools_export_unpack_object($schema, $data, $export['object']); + $object->table = $table; + $object->type = 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; + } + } + + // @todo Load subrecords. + + 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']}]->type = 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->type = 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)) { + drupal_static_reset('ctools_export_load_object'); + drupal_static_reset('ctools_export_load_object_all'); + drupal_static_reset('_ctools_export_get_defaults'); + } + else { + $cache = &drupal_static('ctools_export_load_object'); + $cached_database = &drupal_static('ctools_export_load_object_all'); + $cached_defaults = &drupal_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->type = 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 = &drupal_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. + $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 from the database. + * @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) { + $object->$field = empty($info['serialize']) ? $data->$field : unserialize($data->$field); + } + + 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 from the database. + */ +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); + } + 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, $value, $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 = &drupal_static(__FUNCTION__); + if (empty($cache[$table])) { + $schema = drupal_get_schema($table); + + // If our schema isn't loaded, it's possible we're in a state where it + // simply hasn't been cached. If we've been asked, let's force the + // issue. + if (!$schema) { + // force a schema reset: + $schema = drupal_get_schema($table, TRUE); + } + + 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", + ); + + // 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, &$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->type = 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 .= " * Implementation of 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/sites/all/modules/ctools/includes/fields.inc b/sites/all/modules/ctools/includes/fields.inc new file mode 100644 index 0000000000000000000000000000000000000000..6a9e632d08f05bfbf1ae7d3b411f90ff1e66f645 --- /dev/null +++ b/sites/all/modules/ctools/includes/fields.inc @@ -0,0 +1,103 @@ +<?php +// $Id: fields.inc,v 1.1 2010/11/01 19:07:10 merlinofchaos Exp $ + +/** + * @file + * Extend core fields with some helper functions to reduce code complexity within views and ctools plugins. + */ + + +/** + * Fake an instance of a field. + * + * @param $field_name + * The unique name for this field no matter what entity/bundle it may be used on. + * @param $view_mode + * We're building a new view mode for this function. Defaults to ctools, but we expect developers to actually name this something meaningful. + * @param $formatter + * The formatter key selected from the options provided by field_ui_formatter_options(). + * @param $formatter_settings + * An array of key value pairs. These will be used as #default_value for the form elements generated by a call to hook_field_formatter_settings_form() for this field type. + * Typically we'll pass an empty array to begin with and then pass this information back to ourselves on form submit so that we can set the values for later edit sessions. + */ +function ctools_fields_fake_field_instance($field_name, $view_mode = 'ctools', $formatter, $formatter_settings) { + $field = field_read_field($field_name); + + $field_type = field_info_field_types($field['type']); + + return array( + // Build a fake entity type and bundle. + 'field_name' => $field_name, + 'entity_type' => 'ctools', + 'bundle' => 'ctools', + + // Use the default field settings for settings and widget. + 'settings' => field_info_instance_settings($field['type']), + 'widget' => array( + 'type' => $field_type['default_widget'], + 'settings' => array(), + ), + + // Build a dummy display mode. + 'display' => array( + $view_mode => array( + 'type' => $formatter, + 'settings' => $formatter_settings, + ), + ), + + // Set the other fields to their default values. + // @see _field_write_instance(). + 'required' => FALSE, + 'label' => $field_name, + 'description' => '', + 'deleted' => 0, + ); +} + +/** + * Helper function for calling hook_field_formatter_settings_form() without needing to load an instance of the field. + * + * @param $field + * A fully loaded field. + * @param $formatter_type + * The formatter key selected from the options provided by field_ui_formatter_options(). + * @param $form + * The full form from the function that's calling this function. + * @param $form_state + * The full form_state from the function that's calling this function. + * @param $view_mode + * We're passing a view mode from this function to the fake instance we're creating. Defaults to ctools, but we expect developers to actually name this something meaningful. + */ +function ctools_fields_get_field_formatter_settings_form($field, $formatter_type, &$form, $form_state, $view_mode = 'ctools') { + $conf = $form_state['conf']; + $formatter = field_info_formatter_types($formatter_type); + $function = $formatter['module'] . '_field_formatter_settings_form'; + if (function_exists($function)) { + $instance = ctools_fields_fake_field_instance($field['field_name'], $view_mode, $formatter_type, $conf['formatter_settings']); + $settings_form = $function($field, $instance, $view_mode, $form, $form_state); + if ($settings_form) { + $form['ctools_field_list']['#value'][] = $field; + $form += $settings_form; + } + } +} + +/** + * Helper function for generating all the formatter information associated with any fields. Especially useful for determining the fields that will be added to form that executes hook_ield_formatter_settings_form(). + * + * @param $fields + * An array of fully loaded fields. + */ + +function ctools_fields_get_field_formatter_info($fields) { + $info = array(); + foreach ($fields as $field) { + $field_info = module_invoke($field['module'], 'field_formatter_info'); + if ($field_info) { + $info += $field_info; + } + } + drupal_alter('field_formatter_info', $info); + return $info; +} diff --git a/sites/all/modules/ctools/includes/jump-menu.inc b/sites/all/modules/ctools/includes/jump-menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..9acd8b7157b6471fecc9d0b14ab90714fa1e543a --- /dev/null +++ b/sites/all/modules/ctools/includes/jump-menu.inc @@ -0,0 +1,121 @@ +<?php +// $Id: jump-menu.inc,v 1.3 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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' => array('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' => array('ctools-jump-menu-button'), + ), + ); + } + else { + $form['go'] = array( + '#type' => 'submit', + '#value' => $options['button'], + '#attributes' => array( + 'class' => array('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/sites/all/modules/ctools/includes/math-expr.inc b/sites/all/modules/ctools/includes/math-expr.inc new file mode 100644 index 0000000000000000000000000000000000000000..325d444000420ea9b157cfed55560941414a36ff --- /dev/null +++ b/sites/all/modules/ctools/includes/math-expr.inc @@ -0,0 +1,385 @@ +<?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'); + + function ctools_math_expr() { + // make the variables a little more accurate + $this->v['pi'] = pi(); + $this->v['e'] = exp(1); + } + + 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/sites/all/modules/ctools/includes/menu.inc b/sites/all/modules/ctools/includes/menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..8a81a5191c1e0f8e3dcfc103a5ffff5e2ee0bfdf --- /dev/null +++ b/sites/all/modules/ctools/includes/menu.inc @@ -0,0 +1,99 @@ +<?php +// $Id: menu.inc,v 1.7 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @file + * General menu helper functions. + */ + +/** + * Dynamically add a tab to the current path. + * + * This function is a simplified interface for adding tabs to the current path. + * Some considerations when doing this: + * + * - First, 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. + * - Second, 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) { + $links = &drupal_static(__FUNCTION__, array()); + if (isset($link)) { + $links[$link['href']] = $link; + } + + return $links; +} + +/** + * Re-sort menu items after we have modified them. + */ +function ctools_menu_sort($a, $b) { + $a_weight = (is_array($a) && isset($a['#link']['weight'])) ? $a['#link']['weight'] : 0; + $b_weight = (is_array($b) && isset($b['#link']['weight'])) ? $b['#link']['weight'] : 0; + if ($a_weight == $b_weight) { + $a_title = (is_array($a) && isset($a['#link']['title'])) ? $a['#link']['title'] : 0; + $b_title = (is_array($b) && isset($b['#link']['title'])) ? $b['#link']['title'] : 0; + if ($a_title == $b_title) { + return 0; + } + + return ($a_title < $b_title) ? -1 : 1; + } + + return ($a_weight < $b_weight) ? -1 : 1; +} + +function _ctools_menu_add_dynamic_items(&$data, &$router_item, &$root_path) { + if ($additions = ctools_menu_add_tab()) { + // If none of the static local tasks are active allow one of the dynamic + // active tasks to be marked as such. + $has_active = FALSE; + if (!empty($data['tabs'][0]['output'])) { + foreach ($data['tabs'][0]['output'] as $element) { + if (!empty($element['#link']['#active'])) { + $has_active = TRUE; + } + } + } + foreach ($additions as $addition) { + $addition['localized_options'] = isset($addition['options']) ? $addition['options'] : array(); + if (isset($addition['type']) && $addition['type'] == MENU_LOCAL_ACTION) { + $data['actions']['output'][] = array( + '#theme' => 'menu_local_action', + '#link' => $addition, + ); + } + else { + $data['tabs'][0]['output'][] = array( + '#theme' => 'menu_local_task', + '#link' => $addition, + '#active' => (!$has_active && $root_path === $addition['href']), + ); + } + } + if (!empty($data['tabs'][0]['output'])) { + uasort($data['tabs'][0]['output'], 'ctools_menu_sort'); + $data['tabs'][0]['count'] = count($data['tabs'][0]['output']); + } + + if (!empty($data['actions']['output'])) { + uasort($data['actions']['output'], 'ctools_menu_sort'); + $data['actions']['count'] = count($data['actions']['output']); + } + } +} diff --git a/sites/all/modules/ctools/includes/modal.inc b/sites/all/modules/ctools/includes/modal.inc new file mode 100644 index 0000000000000000000000000000000000000000..a680f15ebc7a9aae23d357b486f0189e216d5d4c --- /dev/null +++ b/sites/all/modules/ctools/includes/modal.inc @@ -0,0 +1,250 @@ +<?php +// $Id: modal.inc,v 1.13 2010/12/31 23:58:52 merlinofchaos Exp $ + +/** + * @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', array( + 'path' => ctools_image_path('icon-close-window.png'), + 'title' => t('Close window'), + 'alt' => t('Close window'), + )), + 'throbber' => theme('image', array( + 'path' => ctools_image_path('throbber.gif'), + 'title' => t('Loading...'), + 'alt' => t('Loading'), + )), + ), + ); + + drupal_add_js($settings, 'setting'); + drupal_add_js('misc/jquery.form.js'); + drupal_add_js('misc/progress.js'); + drupal_add_js('misc/ajax.js'); + 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) { + if (is_array($html)) { + $html = drupal_render($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', array('path' => $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 $text + * The text that will be displayed as the link. + * @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 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) { + // This won't override settings already in. + $form_state += array( + 're_render' => FALSE, + 'no_redirect' => !empty($form_state['ajax']), + ); + + $output = drupal_build_form($form_id, $form_state); + if (!empty($form_state['ajax']) && empty($form_state['executed'])) { + 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) { + if (is_array($output)) { + $output = drupal_render($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 = '<div class="messages">' . $messages . '</div>' . $output; + } + + $commands = array(); + // If the form has not yet been rendered, render it. + $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); + ajax_render($commands); +} diff --git a/sites/all/modules/ctools/includes/object-cache.cron.inc b/sites/all/modules/ctools/includes/object-cache.cron.inc new file mode 100644 index 0000000000000000000000000000000000000000..d306b60d31e1af446bffad83265928e001545b38 --- /dev/null +++ b/sites/all/modules/ctools/includes/object-cache.cron.inc @@ -0,0 +1,17 @@ +<?php +// $Id: object-cache.cron.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/includes/object-cache.inc b/sites/all/modules/ctools/includes/object-cache.inc new file mode 100644 index 0000000000000000000000000000000000000000..baefd943690cc6995b818e2dcfc9213205afd37a --- /dev/null +++ b/sites/all/modules/ctools/includes/object-cache.inc @@ -0,0 +1,175 @@ +<?php +// $Id: object-cache.inc,v 1.15 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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. + * + * @deprecated $skip_cache is deprecated in favor of drupal_static* + * @return + * The data that was cached. + */ +function ctools_object_cache_get($obj, $name, $skip_cache = FALSE) { + $cache = &drupal_static(__FUNCTION__, array()); + $key = "$obj:$name"; + if ($skip_cache) { + unset($cache[$key]); + } + + if (!array_key_exists($key, $cache)) { + $data = db_query('SELECT * FROM {ctools_object_cache} WHERE sid = :session_id AND obj = :object AND name = :name', array(':session_id' => session_id(), ':object' => $obj, ':name' => $name)) + ->fetchObject(); + if ($data) { + $cache[$key] = unserialize($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_insert('ctools_object_cache') + ->fields(array( + 'sid' => session_id(), + 'obj' => $obj, + 'name' => $name, + 'data' => serialize($cache), + 'updated' => REQUEST_TIME, + )) + ->execute(); +} + +/** + * 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_delete('ctools_object_cache') + ->condition('sid', session_id()) + ->condition('obj', $obj) + ->condition('name', $name) + ->execute(); + // Ensure the static cache is emptied of this obj:name set. + drupal_static_reset('ctools_object_cache_get'); +} + + +/** + * 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_query('SELECT s.uid, c.updated FROM {ctools_object_cache} c INNER JOIN {sessions} s ON c.sid = s.sid WHERE s.sid <> :session_id AND c.obj = :obj AND c.name = :name ORDER BY c.updated ASC', array(':session_id' => session_id(), ':obj' => $obj, ':name' => $name)) + ->fetchObject(); +} + +/** + * 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) { + return 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 = :obj AND c.name IN (:names) ORDER BY c.updated ASC", array(':obj' => $obj, ':names' => $names)) + ->fetchAllAssoc('name'); +} + +/** + * 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_delete('ctools_object_cache') + ->condition('obj', $obj) + ->condition('name', $name) + ->execute(); + // Ensure the static cache is emptied of this obj:name set. + $cache = &drupal_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_delete('ctools_object_cache') + ->condition('updated', REQUEST_TIME - $age, '<') + ->execute(); +} diff --git a/sites/all/modules/ctools/includes/page-wizard.inc b/sites/all/modules/ctools/includes/page-wizard.inc new file mode 100644 index 0000000000000000000000000000000000000000..ec5a87b8c0ca031628469dfc3e3fef77dcc60fff --- /dev/null +++ b/sites/all/modules/ctools/includes/page-wizard.inc @@ -0,0 +1,195 @@ +<?php +// $Id: page-wizard.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * 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/structure/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, + 'wizard 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['wizard 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['wizard 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(); + if (empty($plugins)) { + return '<p>' . t('There are no wizards available at this time.') . '</p>'; + } + + 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/structure/pages/wizard/' . $id) . '</dt>'; + $output .= '<dd class="description">' . $plugin['description'] . '</dd>'; + } + } + $output .= '</dl>'; + + return $output; +} diff --git a/sites/all/modules/ctools/includes/page-wizard.menu.inc b/sites/all/modules/ctools/includes/page-wizard.menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..0b8b2f63d1f8033c8b3d8f7bcfed39d4adbf0273 --- /dev/null +++ b/sites/all/modules/ctools/includes/page-wizard.menu.inc @@ -0,0 +1,33 @@ +<?php +// $Id: page-wizard.menu.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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/structure/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/structure/pages/wizard/%'] = array( + 'title' => 'Wizard', + 'page callback' => 'page_manager_page_wizard', + 'page arguments' => array(4), + ) + $base; +} diff --git a/sites/all/modules/ctools/includes/plugins-admin.inc b/sites/all/modules/ctools/includes/plugins-admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..7b2c69c9abb58fc08cf23bfd017aca019f3b2668 --- /dev/null +++ b/sites/all/modules/ctools/includes/plugins-admin.inc @@ -0,0 +1,197 @@ +<?php +// $Id: plugins-admin.inc,v 1.3 2011/01/05 22:57:26 merlinofchaos Exp $ + +/** + * @file + * Contains generic plugin administration functions. + * + * CTools includes the ability to (relatively) easily provide wizard based + * configuration for plugins, meaning plugins that need configuration can + * automatically allow multi-step forms. + * + * Implementing this + */ +/** + * Get a plugin configuration 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. + * + * @param array $form_info + * This form_info *must* contain at least the path. next and finish callbacks + * are advisable but not necessary if using wizard's auto caching. Setting + * a cache mechanism is advisable. If not using auto caching, next and finish + * callbacks will be necessary. + * + * Also be sure to set up things such as AJAX settings and any temporary + * data you will need. Simply setting 'modal' => TRUE and + * 'modal return' => TRUE should make this system work well in the modal. + * + * In addition to standard wizard fields, this supports one extra field: + * - 'default form': A callback to a 'wrapper' that will be applied to either + * the first or a marked form. This is useful for adding global features that + * are applicable to all instances of a plugin, such as identifiers, or + * contexts, or the like. + * + * @param array &$form_state + * This is a standard form state array. This system imposes some requirements + * on what will be in the form state: + * + * - 'plugin': The plugin definition being edited. + * - 'conf': The configuration that is being edited, presumed to be an array. + * Ultimately at the end, this is where the modified config will be + * found. + * - 'op': The operation, either 'add' or 'edit'. This is used to derive form + * names and can also be used to derive default values from the plugin. + * - 'step': The current step. May be null if it is the 'first' step, but + * generally needs to be defined in the path. + * + * @param string $default_form + * An optional default form that can be added. + * + * @return + * If this function returns false, no form exists. + */ +function ctools_plugin_configure_form($form_info, &$form_state) { + // Turn the forms defined in the plugin into the format the wizard needs. + _ctools_plugin_configure_create_form_info($form_info, $form_state['plugin'], $form_state['op']); + + if (empty($form_info['order'])) { + return FALSE; + } + + ctools_include('wizard'); + return ctools_wizard_multistep_form($form_info, $form_state['step'], $form_state); +} + +function _ctools_plugin_configure_create_form_info(&$form_info, $plugin_definition, $op) { + // Provide a few extra defaults. + $form_info += array( + 'id' => 'ctools_plugin_configure_form', + 'show back' => TRUE, + ); + + // Figure out what the forms should actually be. Since they can be specified + // in a couple of different ways (in order to support simple declarations for + // the minimal forms but more complex declarations for powerful wizards). + if ($op == 'add') { + if (!empty($plugin_definition['add form'])) { + $info = $plugin_definition['add form']; + } + } + if (!isset($info) || $op == 'edit') { + // Use the edit form for the add form if add form was completely left off. + if (!empty($plugin_definition['edit form'])) { + $info = $plugin_definition['edit form']; + } + } + + // If there is a default form wrapper, but no form is supplied, + // use the wrapper as the form. + if (empty($info) && !empty($form_info['default form'])) { + $info = $form_info['default form']; + } + + // @todo we may want to make these titles more settable? + if (is_string($info)) { + if (empty($plugin_definition['title'])) { + $title = t('Configure'); + } + else if ($op == 'add') { + $title = t('Configure new !plugin_title', array('!plugin_title' => $plugin_definition['title'])); + } + else { + $title = t('Configure !plugin_title', array('!plugin_title' => $plugin_definition['title'])); + } + $form_info['order'] = array('form' => $title); + $form_info['forms'] = array( + 'form' => array( + 'title' => $title, + 'form id' => $info, + ), + ); + + // Add the default form if one is specified. + if (!empty($form_info['default form']) && $form_info['forms']['form']['form id'] != $form_info['default form']) { + $form_info['forms']['form']['wrapper'] = $form_info['default form']; + } + + // If no submit is supplied, supply the default submit which will do the + // most obvious task. + if (!function_exists($form_info['forms']['form']['form id'] . '_submit')) { + // Store the original wrapper so we can chain it. + if (!empty($form_info['forms']['form']['wrapper'])) { + $form_info['forms']['form']['original wrapper'] = $form_info['forms']['form']['wrapper']; + } + $form_info['forms']['form']['wrapper'] = 'ctools_plugins_default_form_wrapper'; + } + } + 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) { + $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 && !empty($form_info['default form'])) { + $form_info['forms'][$wrapper]['wrapper'] = $form_info['default form']; + } + } +} + +/** + * A wrapper to provide a default submit so that plugins don't have to duplicate + * a whole bunch of code to do what most of them want to do anyway. + */ +function ctools_plugins_default_form_wrapper($form, &$form_state) { + $form_info = &$form_state['form_info']; + $info = $form_info['forms'][$form_state['step']]; + + if (isset($info['original wrapper']) && function_exists($info['original wrapper'])) { + $form = $info['original wrapper']($form, $form_state); + } + + if (isset($form['buttons']['next'])) { + if (empty($form['buttons']['next']['#submit'])) { + $form['buttons']['next']['#submit'] = $form['#submit']; + } + $form['buttons']['next']['#submit'][] = 'ctools_plugins_default_form_wrapper_submit'; + } + if (isset($form['buttons']['return'])) { + if (empty($form['buttons']['return']['#submit'])) { + $form['buttons']['return']['#submit'] = $form['#submit']; + } + $form['buttons']['return']['#submit'][] = 'ctools_plugins_default_form_wrapper_submit'; + } + return $form; +} + +/** + * Provide a default storage mechanism. + */ +function ctools_plugins_default_form_wrapper_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/sites/all/modules/ctools/includes/plugins.inc b/sites/all/modules/ctools/includes/plugins.inc new file mode 100644 index 0000000000000000000000000000000000000000..5f6364abb9b1fd66cef43e5408c9038a1489a663 --- /dev/null +++ b/sites/all/modules/ctools/includes/plugins.inc @@ -0,0 +1,845 @@ +<?php +// $Id: plugins.inc,v 1.33 2011/01/05 19:58:21 merlinofchaos Exp $ + +/** + * @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 = &drupal_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); + foreach ($info as $module => $plugin_info) { + if (!isset($already_done[$owner][$api][$module])) { + $file = isset($plugin_info['file']) ? $plugin_info['file'] : "$module.$api.inc"; + if (file_exists("./$plugin_info[path]/$file")) { + require_once "./$plugin_info[path]/$file"; + } + $already_done[$owner][$api][$module] = 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. + $plugins = &drupal_static('ctools_plugins', array()); + $info = ctools_plugin_get_plugin_type_info(); + + // Bail out noisily if an invalid module/type combination is requested. + if (!isset($info[$module][$type])) { + watchdog('ctools', 'Invalid plugin module/type combination requested: module @module and type @type', array('@module' => $module, '@type' => $type), WATCHDOG_ERROR); + return array(); + } + + // Make sure our plugins array is populated. + if (!isset($plugins[$module][$type])) { + $plugins[$module][$type] = array(); + } + + // Attempt to shortcut this whole piece of code if we already have + // the requested plugin: + if ($id && 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 = &drupal_static('ctools_plugin_setup', 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]; +} + +/** + * Return the full list of plugin type info for all plugin types registered in + * the current system. + * + * This function manages its own cache getting/setting, and should always be + * used as the way to initially populate the list of plugin types. Make sure you + * call this function to properly populate the ctools_plugin_type_info static + * variable. + * + * @return array + * A multilevel array of plugin type info, the outer array keyed on module + * name and each inner array keyed on plugin type name. + */ +function ctools_plugin_get_plugin_type_info($flush = FALSE) { + $info_loaded = &drupal_static('ctools_plugin_type_info_loaded', FALSE); + $all_type_info = &drupal_static('ctools_plugin_type_info', array()); + + // Only trigger info loading once. + if ($info_loaded && !$flush) { + return $all_type_info; + } + $info_loaded = TRUE; + + $cache = cache_get('ctools_plugin_type_info'); + if (!empty($cache->data) && !$flush) { + // Plugin type info cache is warm, use it. + $all_type_info = $cache->data; + } + else { + // Cache expired, refill it. + foreach (module_implements('ctools_plugin_type') as $module) { + $module_infos = array(); + $function = $module . '_ctools_plugin_type'; + $module_infos = $function(); + + foreach ($module_infos as $plugin_type_name => $plugin_type_info) { + // Apply defaults. Array addition will not overwrite pre-existing keys. + $plugin_type_info += array( + 'module' => $module, + 'type' => $plugin_type_name, + 'cache' => FALSE, + 'cache table' => 'cache', + 'classes' => array(), + 'use hooks' => FALSE, + 'defaults' => array(), + 'process' => '', + 'extension' => 'inc', + 'info file' => FALSE, + 'hook' => $module . '_' . $plugin_type_name, + 'load themes' => FALSE, + ); + $all_type_info[$module][$plugin_type_name] = $plugin_type_info; + } + } + cache_set('ctools_plugin_type_info', $all_type_info); + } + + return $all_type_info; +} + +/** + * Reset all static caches that affect the result of ctools_get_plugins(). + */ +function ctools_get_plugins_reset() { + drupal_static_reset('ctools_plugin_load_includes'); + drupal_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 = &drupal_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->uri])) { + $identifier = $plugin_arrays[$file->uri]; + } + else { + + require_once DRUPAL_ROOT . '/' . $file->uri; + // .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->uri] = $plugin; + $identifier = $plugin; + } + else { + $identifier = $module . '_' . $file->name; + } + } + + $result = ctools_plugin_process($info, $module, $identifier, dirname($file->uri), basename($file->uri), $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, $plugin_type_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' => $plugin_type_info['module'], + 'plugin type' => $plugin_type_info['type'], + ); + + // Fill in plugin-specific defaults, if they exist. + if (!empty($plugin_type_info['defaults'])) { + if (is_array($plugin_type_info['defaults'])) { + $result[$name] += $plugin_type_info['defaults']; + } + } + + // Allow the plugin owner to do additional processing. + if (!empty($plugin_type_info['process']) && $function = ctools_plugin_get_function($plugin_type_info, 'process')) { + $function($result[$name], $plugin_type_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->uri); + if ($result) { + $result = array($file->name => $result); + return _ctools_process_data($result, $info, $module, dirname($file->uri), basename($file->uri)); + } +} + +/** + * Ask a module for info about a particular plugin type. + */ +function ctools_plugin_get_info($module, $type) { + $all_info = ctools_plugin_get_plugin_type_info(); + return isset($all_info[$module][$type]) ? $all_info[$module][$type] : array(); +} + +/** + * 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 DRUPAL_ROOT . '/' . $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 DRUPAL_ROOT . '/' . $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'. + * + * @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) { + // 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 DRUPAL_ROOT . '/' . $plugin_definition['path'] . '/' . $plugin_definition['file']; + } + } + + $return = FALSE; + if (!isset($plugin_definition[$class_name])) { + return; + } + else if (is_string($plugin_definition[$class_name])) { + // Plugin uses the string form shorthand. + $return = $plugin_definition[$class_name]; + } + else if (isset($plugin_definition[$class_name]['class'])) { + // Plugin uses the verbose array form. + $return = $plugin_definition[$class_name]['class']; + } + // @todo consider adding an else {watchdog(...)} here + + return ($return && class_exists($return)) ? $return : NULL; +} + +/** + * 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'. + * + * @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) { + $plugin = ctools_get_plugins($module, $type, $id); + return ctools_plugin_get_class($plugin, $class_name); +} + +/** + * 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/sites/all/modules/ctools/includes/registry.inc b/sites/all/modules/ctools/includes/registry.inc new file mode 100644 index 0000000000000000000000000000000000000000..9d4328e693befc29c6d176de4bb940cec4203b95 --- /dev/null +++ b/sites/all/modules/ctools/includes/registry.inc @@ -0,0 +1,77 @@ +<?php + +/** + * @file + * + * Registry magic. In a separate file to minimize unnecessary code loading. + */ + +/** + * Implements (via delegation) hook_registry_files_alter(). + * + * Alter the registry of files to automagically include all classes in + * class-based plugins. + */ +function _ctools_registry_files_alter(&$files, $indexed_modules) { + ctools_include('plugins'); + + // Remap the passed indexed modules into a useful format. + $modules = array(); + foreach ($indexed_modules as $module_object) { + $modules[$module_object->name] = $module_object; + } + + $all_type_info = ctools_plugin_get_plugin_type_info(TRUE); + foreach ($all_type_info as $module => $plugin_types) { + foreach ($plugin_types as $plugin_type_name => $plugin_type_info) { + if (empty($plugin_type_info['classes'])) { + // This plugin type does not use classes, so skip it. + continue; + } + + // Retrieve the full list of plugins of this type. + $plugins = ctools_get_plugins($module, $plugin_type_name); + foreach ($plugins as $plugin_name => $plugin_definition) { + foreach ($plugin_type_info['classes'] as $class_key) { + if (empty($plugin_definition[$class_key])) { + // Plugin doesn't provide a class for this class key, so skip it. + continue; + } + + if (is_string($plugin_definition[$class_key])) { + // Plugin definition uses the shorthand for defining a class name + // and location; look for the containing file by following naming + // convention. + $path = $plugin_definition['path'] . '/' . $plugin_definition[$class_key] . '.class.php'; + } + else { + // Plugin uses the verbose definition to indicate where its class + // files are. + $class = $plugin_definition[$class_key]['class']; + // Use the filename if it's explicitly set, else follow the naming + // conventions. + $filename = isset($plugin_definition[$class_key]['file']) ? $plugin_definition[$class_key]['file'] : $class . '.class.php'; + $base_path = isset($plugin_definition[$class_key]['path']) ? $plugin_definition[$class_key]['path'] : $plugin_definition['path']; + $path = "$base_path/$filename"; + } + + if (file_exists($path)) { + // If the file exists, add it to the files for registry building. + $files[$path] = array('module' => $plugin_definition['module'], 'weight' => $modules[$plugin_definition['module']]->weight); + } + else { + // Else, watchdog that we've got some erroneous plugin info. + $args = array( + '@plugin' => $plugin_definition['name'], + '@owner' => $module, + '@type' => $plugin_type_name, + '@file' => $path, + '@class' => $class_key, + ); + watchdog('ctools', 'Plugin @plugin of plugin type @owner:@type points to nonexistent file @file for class handler @class.', $args); + } + } + } + } + } +} diff --git a/sites/all/modules/ctools/includes/stylizer.inc b/sites/all/modules/ctools/includes/stylizer.inc new file mode 100644 index 0000000000000000000000000000000000000000..5325eaab1915b0e69b6bcf270d9e38c15e5b0fa8 --- /dev/null +++ b/sites/all/modules/ctools/includes/stylizer.inc @@ -0,0 +1,1656 @@ +<?php +// $Id: stylizer.inc,v 1.3 2011/01/05 22:35:46 merlinofchaos Exp $ +/** + * @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('stylizer', '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('stylizer', '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', array('image' => theme('image', array('path' => $file)), 'title' => $title)); +} + +/** + * Theme the style icon image + */ +function theme_ctools_style_icon($vars) { + $image = $vars['image']; + ctools_add_css('stylizer'); + ctools_add_js('stylizer'); + $output = '<div class="ctools-style-icon">'; + $output .= $vars['image']; + if ($vars['title']) { + $output .= '<div class="caption">' . $vars['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 { + drupal_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) { + drupal_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) { + $path = 'public://ctools/style/' . $settings['name'] . '/' . md5(serialize($settings['palette'])); + if (!file_prepare_directory($path, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) { + 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, _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 = _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 = _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 = _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) = _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. + $temp_name = drupal_tempnam('temporary://', 'file'); + + imagepng($slice, drupal_realpath($temp_name)); + file_unmanaged_move($temp_name, $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, + 'base_style_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 clearfix">', + '#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 clearfix"><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' => drupal_clean_css_identifier('edit-style-base-' . $key), + '#return_value' => check_plain($key), + ); + } + } + + return $form; +} + +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']; + } + + return $form; +} + +/** + * 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['base_style_plugin']; + $settings = &$form_state['settings']; + + $form['top box'] = array( + '#prefix' => '<div id="ctools-stylizer-top-box" class="clearfix">', + '#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' => array('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); + } + + return $form; +} + +/** + * Theme the stylizer color scheme form. + */ +function theme_ctools_stylizer_color_scheme_form($vars) { + $form = &$vars['form']; + $output = ''; + + // Wrapper + $output .= '<div class="color-form clearfix">'; + + // Color schemes +// $output .= drupal_render($form['scheme']); + + // Palette + $output .= '<div id="palette" class="clearfix">'; + foreach (element_children($form['palette']) as $name) { + $output .= render($form['palette'][$name]); + } + $output .= '</div>'; // palette + + $output .= '</div>'; // color form + + return $output; +} + +/** + * Theme the stylizer preview form. + */ +function theme_ctools_stylizer_preview_form($vars) { + $form = &$vars['form']; + + $plugin = $form['#form_state']['base_style_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_children($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['base_style_plugin']['settings form validate']) && function_exists($form_state['base_style_plugin']['settings form validate'])) { + $form_state['base_style_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['base_style_plugin']['settings form submit']) && function_exists($form_state['base_style_plugin']['settings form submit'])) { + $form_state['base_style_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 clearfix">'; + $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 clearfix">'; + $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 clearfix">'; + $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"; + } + +} diff --git a/sites/all/modules/ctools/includes/stylizer.theme.inc b/sites/all/modules/ctools/includes/stylizer.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..8e320106a7c751a8de123aabc2abc01a70fc79df --- /dev/null +++ b/sites/all/modules/ctools/includes/stylizer.theme.inc @@ -0,0 +1,29 @@ +<?php +// $Id: stylizer.theme.inc,v 1.3 2011/01/05 19:41:11 merlinofchaos Exp $ + +/** + * @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( + 'render element' => 'form', + 'file' => 'includes/stylizer.inc', + ); + + $theme['ctools_stylizer_preview_form'] = array( + 'render element' => 'form', + 'file' => 'includes/stylizer.inc', + ); + + $theme['ctools_style_icon'] = array( + 'variables' => array('image' => NULL, 'title' => NULL), + 'file' => 'includes/stylizer.inc', + ); +} + diff --git a/sites/all/modules/ctools/includes/translations/includes.hu.po b/sites/all/modules/ctools/includes/translations/includes.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..051c4a3f4d89f039634c657a3f0af885a3de5d67 --- /dev/null +++ b/sites/all/modules/ctools/includes/translations/includes.hu.po @@ -0,0 +1,185 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 13:37+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 "Home" +msgstr "Címlap" +msgid "context" +msgstr "környezet" +msgid "Description" +msgstr "Leírás" +msgid "Back" +msgstr "Vissza" +msgid "Add" +msgstr "Hozzáadás" +msgid "Continue" +msgstr "Folytatás" +msgid "Override title" +msgstr "Cím felülírása" +msgid "Add criteria" +msgstr "Jellemző hozzáadása" +msgid "Relationships" +msgstr "Kapcsolatok" +msgid "Contexts" +msgstr "Környezetek" +msgid "Loading" +msgstr "Betöltés" +msgid "by @user" +msgstr "@user által" +msgid "Context" +msgstr "Környezet" +msgid "argument" +msgstr "argumentum" +msgid "Add argument" +msgstr "Argumentum hozzáadása" +msgid "relationship" +msgstr "kapcsolat" +msgid "Add relationship" +msgstr "Kapcsolat hozzáadása" +msgid "Add context" +msgstr "Környezet hozzáadása" +msgid "Required contexts" +msgstr "Szükséges környezetek" +msgid "required context" +msgstr "szükséges környezet" +msgid "Add required context" +msgstr "Szükséges környezet hozzáadása" +msgid "Close Window" +msgstr "Ablak bezárása" +msgid "Close window" +msgstr "Ablak bezárása" +msgid "Add @type \"@context\"" +msgstr "@type „@context” hozzáadása" +msgid "Edit @type \"@context\"" +msgstr "@type @context\" szerkesztése" +msgid "Enter a name to identify this !type on administrative screens." +msgstr "" +"Név megadása, ami !type azonosítására szolgál az " +"adminisztrációs oldalakon." +msgid "Enter a keyword to use for substitution in titles." +msgstr "Címekben helyettesítéshez használt kulcsszó megadása." +msgid "Ignore it; content that requires this context will not be available." +msgstr "" +"Mellőzve; nem elérhető olyan tartalom, amelyhez ez a környezet " +"szükséges." +msgid "" +"If the argument is missing or is not valid, select how this should " +"behave." +msgstr "" +"Ki kell választani a működést, ha az argumentum hiányzik vagy nem " +"érvényes." +msgid "Argument @count" +msgstr "Argumentum @count" +msgid "Context @count" +msgstr "Környezet @count" +msgid "Configure !subtype_title" +msgstr "!subtype_title beállítása" +msgid "Unknown context" +msgstr "Ismeretlen környezet" +msgid "" +"You may use %keywords from contexts, as well as %title to contain the " +"original title." +msgstr "" +"%kulcsszavak használhatóak a környezetekből, továbbá %title " +"tartalmazza az eredeti címet." +msgid "Context %count" +msgstr "Környezet %count" +msgid "Finish" +msgstr "Befejezés" +msgid "" +"Validation error, please try again. If this error persists, please " +"contact the site administrator." +msgstr "" +"Helyesség ellenőrzési hiba. Kérjük próbálkozzon újra! " +"Amennyiben a hiba továbbra is fennáll, javasolt felvenni a " +"kapcsolatot a webhely gazdájával." +msgid "Logged in user" +msgstr "Bejelentkezett felhasználó" +msgid "Server reports invalid input error." +msgstr "A kiszolgáló érvénytelen bemenet hibát jelzett." +msgid "@type:@subtype will not display due to missing context" +msgstr "@type:@subtype nem fog megjelenni a hiányzó környezet miatt" +msgid "No info" +msgstr "Nincs információ" +msgid "No info available." +msgstr "Nincs elérhető információ." +msgid "Configure new !subtype_title" +msgstr "Új !subtype_title beállítása" +msgid "All criteria must pass." +msgstr "Minden feltételnek meg kell felelni." +msgid "Only one criteria must pass." +msgstr "Csak egy feltételnek kell megfelelni." +msgid "Broken/missing access plugin %plugin" +msgstr "Hibás/hiányzó %plugin hozzáférési beépülő" +msgid "No criteria selected, this test will pass." +msgstr "Nincs kiválasztott feltétel, a teszt sikeres." +msgid "Missing callback hooks." +msgstr "Hiányzó callback hookok." +msgid "Edit criteria" +msgstr "Feltétel szerkesztése" +msgid "Invalid context type" +msgstr "Érvénytelen környezettípus" +msgid "Display page not found or display nothing at all." +msgstr "Az oldal nem található vagy üres oldal megjelenítése." +msgid "" +"Enter a title to use when this argument is present. You may use " +"%KEYWORD substitution, where the keyword is specified below." +msgstr "" +"Az argumentum jelenlétekor használt cím megadása. Lehet %KULCSSZO " +"helyettesítést használni, az elérhető kulcsszavak lentebb " +"találhatóak." +msgid "Unable to delete missing item!" +msgstr "Hiányzó elemet nem lehet törölni!" +msgid "Edit @type" +msgstr "@type szerkesztése" +msgid "Summary of contexts" +msgstr "Környezetek összefoglalója" +msgid "Please choose which context and how you would like it converted." +msgstr "" +"Ki kell választani a környezetet és, hogy miként kell azt " +"konvertálni." +msgid "@identifier (@keyword)" +msgstr "@identifier (@keyword)" +msgid ", and " +msgstr ", és " +msgid ", or " +msgstr ", vagy " +msgid "Built in context" +msgstr "Beépített környezet" +msgid "Keyword: %@keyword" +msgstr "Kulcsszó: %@keyword" +msgid "@keyword --> @title" +msgstr "@keyword --> @title" +msgid "From \"@title\"" +msgstr "Ebből: „@title”" +msgid "" +"Unable to create CTools CSS cache directory. Check the permissions on " +"your files directory." +msgstr "" +"Nem lehet létrehozni a CTools CSS gyorsítár könyvtárat. " +"Ellenőrizni kell a files könyvtár jogosultságait." +msgid "Update and return" +msgstr "Frissítés és viszatérés" +msgid "" +"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." +msgstr "" +"Ha egynél több változat van az oldalon, az oldal meglátogatásakor " +"minden változatnak lehetősége van megjelenni. Az első " +"változattól kezdve egészen az utolsóig mindegyik ellenőrizve " +"lesz, hogy megfelel-e a kiválasztási szabályoknak. Az első " +"változat ami megfelel a feltételnek (ahogy az fentebb meg lett " +"határozva) lesz használva." diff --git a/sites/all/modules/ctools/includes/utility.inc b/sites/all/modules/ctools/includes/utility.inc new file mode 100644 index 0000000000000000000000000000000000000000..6e4f46c8129e8ac2fd50d188e5f6f4a8d6db2ce8 --- /dev/null +++ b/sites/all/modules/ctools/includes/utility.inc @@ -0,0 +1,45 @@ +<?php +// $Id: utility.inc,v 1.3 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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(&$items, $type = 'theme') { + $files = drupal_system_listing('/\.' . $type . '\.inc$/', drupal_get_path('module', 'ctools') . '/includes', 'name', 0); + foreach ($files as $file) { + require_once DRUPAL_ROOT . '/' . $file->uri; + list($tool) = explode('.', $file->name, 2); + + $function = 'ctools_' . str_replace ('-', '_', $tool) . '_' . str_replace('-', '_', $type); + if (function_exists($function)) { + $function($items); + } + } +} + +/** + * Implementation of hook_theme_registry_alter() + */ +function ctools_theme_registry_alter(&$registry) { + // 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/sites/all/modules/ctools/includes/wizard.inc b/sites/all/modules/ctools/includes/wizard.inc new file mode 100644 index 0000000000000000000000000000000000000000..d8b604d9209021ee5713f60fe73f49710bf294a6 --- /dev/null +++ b/sites/all/modules/ctools/includes/wizard.inc @@ -0,0 +1,516 @@ +<?php +// $Id: wizard.inc,v 1.20 2010/10/27 20:07:10 merlinofchaos Exp $ + +/** + * @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 drupal_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); + + // If automated caching is enabled, ensure that everything is as it + // should be. + if (!empty($form_info['auto cache'])) { + // If the cache mechanism hasn't been set, default to the simple + // mechanism and use the wizard ID to ensure uniqueness so cache + // objects don't stomp on each other. + if (!isset($form_info['cache mechanism'])) { + $form_info['cache mechanism'] = 'simple::wizard::' . $form_info['id']; + } + + // If not set, default the cache key to the wizard ID. This is often + // a unique ID of the object being edited or similar. + if (!isset($form_info['cache key'])) { + $form_info['cache key'] = $form_info['id']; + } + + // If not set, default the cache location to storage. This is often + // somnething like 'conf'. + if (!isset($form_info['cache location'])) { + $form_info['cache location'] = 'storage'; + } + + // If absolutely nothing was set for the cache area to work on + if (!isset($form_state[$form_info['cache location']])) { + ctools_include('cache'); + $form_state[$form_info['cache location']] = ctools_cache_get($form_info['cache mechanism'], $form_info['cache key']); + } + } + + $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 DRUPAL_ROOT . '/' . $file; + } + } + else { + require_once DRUPAL_ROOT . '/' . $info['include']; + } + } + + // This tells drupal_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; + + $output = drupal_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 auto-caching is on, we need to write the cache on next and + // clear the cache on finish. + if (!empty($form_info['auto cache'])) { + if ($type == 'next') { + ctools_include('cache'); + ctools_cache_set($form_info['cache mechanism'], $form_info['cache key'], $form_state[$form_info['cache location']]); + } + elseif ($type == 'finish') { + ctools_include('cache'); + ctools_cache_clear($form_info['cache mechanism'], $form_info['cache key']); + } + } + + // Set a couple of niceties: + if ($type == 'finish') { + $form_state['complete'] = TRUE; + } + + if ($type == 'cancel') { + $form_state['cancel'] = TRUE; + } + + // 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']) { + if (is_array($form_state['redirect'])) { + call_user_func_array('drupal_goto', $form_state['redirect']); + } + else { + drupal_goto($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']) && isset($form_state['commands']) && empty($form_state['modal return'])) { + return 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[] = '<span class="' . $class . '">' . $title . '</span>'; + } + } + + // Display the trail if instructed to do so. + if (!empty($form_info['show trail'])) { + ctools_add_css('wizard'); + $form['ctools_trail'] = array( + '#markup' => theme(array('ctools_wizard_trail__' . $form_info['id'], 'ctools_wizard_trail'), array('trail' => $trail)), + '#weight' => -1000, + ); + } + + if (empty($form_info['no buttons'])) { + // Ensure buttons stay on the bottom. + $form['buttons'] = array( + '#prefix' => '<div class="clearfix">', + '#suffix' => '</div>', + '#weight' => 1000, + ); + + $button_attributes = array(); + if (!empty($form_state['ajax']) && empty($form_state['modal'])) { + $button_attributes = array('class' => array('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, + '#limit_validation_errors' => array(), + // 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. + '#limit_validation_errors' => array(), + '#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'])) { + $form = $info['wrapper']($form, $form_state); + } + + if (isset($form_info['wrapper']) && function_exists($form_info['wrapper'])) { + $form = $form_info['wrapper']($form, $form_state); + } + return $form; +} + +/** + * 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/sites/all/modules/ctools/includes/wizard.theme.inc b/sites/all/modules/ctools/includes/wizard.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..ab85e1e560fffb25397f258eaf690f07e5d21544 --- /dev/null +++ b/sites/all/modules/ctools/includes/wizard.theme.inc @@ -0,0 +1,26 @@ +<?php +// $Id: wizard.theme.inc,v 1.3 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @file + * Themable for the wizard tool. + */ + +function ctools_wizard_theme(&$theme) { + $theme['ctools_wizard_trail'] = array( + 'variables' => array('trail' => NULL), + 'file' => 'includes/wizard.theme.inc', + ); +} + +/** + * Themable display of the 'breadcrumb' trail to show the order of the + * forms. + */ +function theme_ctools_wizard_trail($vars) { + $trail = $vars['trail']; + if (!empty($trail)) { + return '<div class="wizard-trail">' . implode(' » ', $trail) . '</div>'; + } +} + diff --git a/sites/all/modules/ctools/js/ajax-responder.js b/sites/all/modules/ctools/js/ajax-responder.js new file mode 100644 index 0000000000000000000000000000000000000000..ce400220dcdf999e5026ad977b1a679cff6ae741 --- /dev/null +++ b/sites/all/modules/ctools/js/ajax-responder.js @@ -0,0 +1,123 @@ +// $Id: ajax-responder.js,v 1.25 2010/10/11 22:18:22 sdboyer Exp $ +/** + * @file + * + * CTools flexible AJAX responder object. + */ + +(function ($) { + /** + * Grab the response from the server and store it. + * + * @todo restore the warm cache functionality + */ + Drupal.CTools.AJAX.warmCache = function () { + // Store this expression for a minor speed improvement. + $this = $(this); + var 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.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 { + url = old_url.replace(/\/nojs(\/|$)/g, '/ajax$1'); + $.ajax({ + type: "POST", + url: url, + data: { 'js': 1, 'ctools_ajax': 1}, + global: true, + success: function (data) { + Drupal.CTools.AJAX.commandCache[old_url] = data; + $objects.addClass('ctools-cache-warmed').trigger('ctools-cache-warm', [data]); + }, + complete: function() { + $objects.removeClass('ctools-fetching'); + }, + dataType: 'json' + }); + } + 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 () { + $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); + } + } + }; + + /** + * 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 url; + }; + + + Drupal.CTools.AJAX.commands.attr = function(data) { + $(data.selector).attr(data.name, data.value); + }; + + + Drupal.CTools.AJAX.commands.redirect = function(data) { + if (data.delay > 0) { + setTimeout(function () { + location.href = data.url; + }, data.delay); + } + else { + location.href = data.url; + } + }; + + Drupal.CTools.AJAX.commands.reload = function(data) { + location.reload(); + }; + + Drupal.CTools.AJAX.commands.submit = function(data) { + $(data.selector).submit(); + } + +})(jQuery); diff --git a/sites/all/modules/ctools/js/auto-submit.js b/sites/all/modules/ctools/js/auto-submit.js new file mode 100644 index 0000000000000000000000000000000000000000..202b534155b59045fceee85b52e14eadc00b4887 --- /dev/null +++ b/sites/all/modules/ctools/js/auto-submit.js @@ -0,0 +1,75 @@ +// $Id: auto-submit.js,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ +(function($){ +/** + * 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 = { + attach: 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); + } + } + }); + } +} +})(jQuery); diff --git a/sites/all/modules/ctools/js/collapsible-div.js b/sites/all/modules/ctools/js/collapsible-div.js new file mode 100644 index 0000000000000000000000000000000000000000..4b177bf24160c7f366ebdf650c3c41a76db57df7 --- /dev/null +++ b/sites/all/modules/ctools/js/collapsible-div.js @@ -0,0 +1,241 @@ +// $Id: collapsible-div.js,v 1.11 2010/10/11 22:18:22 sdboyer Exp $ +/** + * @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 = { + attach: function(context) { + $('.ctools-collapsible-container:not(.ctools-collapsible-processed)', context) + .each(Drupal.CTools.bindCollapsible) + .addClass('ctools-collapsible-processed'); + } + } +})(jQuery); diff --git a/sites/all/modules/ctools/js/dependent.js b/sites/all/modules/ctools/js/dependent.js new file mode 100644 index 0000000000000000000000000000000000000000..264f714ecc3ce60df3bdf4bdbceb9f12c2776a0e --- /dev/null +++ b/sites/all/modules/ctools/js/dependent.js @@ -0,0 +1,216 @@ +// $Id: dependent.js,v 1.9 2011/01/01 00:19:17 merlinofchaos Exp $ +/** + * @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; + if (i > 0) { + do { + if (array[i] == search_term) { + return true; + } + } while (i--); + } + return false; + } + + + Drupal.CTools.dependent.autoAttach = function() { + // Clear active bindings and triggers. + for (i in Drupal.CTools.dependent.activeTriggers) { + $(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); + + if ($(trigger_id).attr('type') == 'checkbox') { + $(trigger_id).siblings('label').addClass('hidden-options'); + } + + var getValue = function(item, trigger) { + if (item.substring(0, 6) == 'radio:') { + var val = $(trigger + ':checked').val(); + } + else { + switch ($(trigger).attr('type')) { + case 'checkbox': + var val = $(trigger).attr('checked') || 0; + + if (val) { + $(trigger).siblings('label').removeClass('hidden-options').addClass('expanded-options'); + } + else { + $(trigger).siblings('label').removeClass('expanded-options').addClass('hidden-options'); + } + + break; + default: + var val = $(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 (val != null && 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 = $('#' + id + '-wrapper'); + if (!object.size()) { + object = $('#' + 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.addClass('dependent-options'); + 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); + } + 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'); + } + } + } + } + + $(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 = { + attach: 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/sites/all/modules/ctools/js/dropdown.js b/sites/all/modules/ctools/js/dropdown.js new file mode 100644 index 0000000000000000000000000000000000000000..5feea2d3fa5aeb3045b2a202246f9ea7755c6a94 --- /dev/null +++ b/sites/all/modules/ctools/js/dropdown.js @@ -0,0 +1,88 @@ +// $Id: dropdown.js,v 1.6 2010/10/11 22:18:22 sdboyer Exp $ +/** + * @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 = { + attach: 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/sites/all/modules/ctools/js/jump-menu.js b/sites/all/modules/ctools/js/jump-menu.js new file mode 100644 index 0000000000000000000000000000000000000000..3310022b59addaf4e206dc40884c49fc1079d8c2 --- /dev/null +++ b/sites/all/modules/ctools/js/jump-menu.js @@ -0,0 +1,35 @@ +// $Id: jump-menu.js,v 1.3 2010/10/11 22:18:22 sdboyer Exp $ + +(function($) { + Drupal.behaviors.CToolsJumpMenu = { + attach: 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); diff --git a/sites/all/modules/ctools/js/modal.js b/sites/all/modules/ctools/js/modal.js new file mode 100644 index 0000000000000000000000000000000000000000..7ad5524b3718a5a6ab627f3e7de4f6b66135ffe8 --- /dev/null +++ b/sites/all/modules/ctools/js/modal.js @@ -0,0 +1,495 @@ +// $Id: modal.js,v 1.27 2010/12/31 22:27:02 merlinofchaos Exp $ +/** + * @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); + }; + + /** + * Handler to prepare the modal for the response + */ + Drupal.CTools.Modal.clickAjaxLink = function () { + Drupal.CTools.Modal.show(Drupal.CTools.Modal.getSettings(this)); + 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 = { + attach: function(context) { + // Bind links + // Note that doing so in this order means that the two classes can be + // used together safely. + /* + * @todo remimplement the warm caching feature + $('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) + .each(function () { + // Create a drupal ajax object + var element_settings = {}; + if ($(this).attr('href')) { + element_settings.url = $(this).attr('href'); + element_settings.event = 'click'; + element_settings.progress = { type: 'throbber' }; + } + var base = $(this).attr('href'); + Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings); + + // Attach the display behavior to the ajax object + } + ); + + // 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.clickAjaxLink) + .each(function() { + var button = this; + var element_settings = {}; + + // AJAX submits specified in this manner automatically submit to the + // normal form action. + element_settings.url = Drupal.CTools.Modal.findURL(this); + element_settings.event = 'click'; + + var base = $(this).attr('id'); + Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings); + + // Make sure changes to settings are reflected in the URL. + $('.' + $(button).attr('id') + '-url').change(function() { + Drupal.ajax[base].options.url = Drupal.CTools.Modal.findURL(button); + }); + }); + + // Bind our custom event to the form submit + $('#modal-content form:not(.ctools-use-modal-processed)', context) + .addClass('ctools-use-modal-processed') + .each(function() { + $('input[type=submit], button', this).click(function() { + this.form.clk = this; + }); + + var element_settings = {}; + + element_settings.url = $(this).attr('action'); + element_settings.event = 'submit'; + element_settings.progress = { 'type': 'throbber' } + var base = $(this).attr('id'); + + Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings); + Drupal.ajax[base].form = $(this); + }); + } + }; + + // The following are implementations of AJAX responder commands. + + /** + * AJAX responder command to place HTML within the modal. + */ + Drupal.CTools.Modal.modal_display = function(ajax, response, status) { + $('#modal-title').html(response.title); + $('#modal-content').html(response.output); + Drupal.attachBehaviors(); + } + + /** + * AJAX responder command to dismiss the modal. + */ + Drupal.CTools.Modal.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.Modal.modal_loading = function(command) { + Drupal.CTools.Modal.modal_display({ + output: Drupal.theme(Drupal.CTools.Modal.currentSettings.throbberTheme), + title: Drupal.CTools.Modal.currentSettings.loadingText + }); + } + + /** + * 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.Modal.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 url; + }; + + + /** + * 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; + } + 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(); + } + } + }); + }; + +$(function() { + Drupal.ajax.prototype.commands.modal_display = Drupal.CTools.Modal.modal_display; + Drupal.ajax.prototype.commands.modal_dismiss = Drupal.CTools.Modal.modal_dismiss; +}); + +})(jQuery); diff --git a/sites/all/modules/ctools/js/stylizer.js b/sites/all/modules/ctools/js/stylizer.js new file mode 100644 index 0000000000000000000000000000000000000000..38727cff6900d80899d29382313606da9eacc1bd --- /dev/null +++ b/sites/all/modules/ctools/js/stylizer.js @@ -0,0 +1,220 @@ +// $Id: stylizer.js,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +(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 = { + attach: 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/sites/all/modules/ctools/page_manager/css/page-manager.css b/sites/all/modules/ctools/page_manager/css/page-manager.css new file mode 100644 index 0000000000000000000000000000000000000000..2ba23b9ffbf8280bb63927be6dea27b23bffe873 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/css/page-manager.css @@ -0,0 +1,342 @@ +/* $Id: page-manager.css,v 1.13 2011/01/05 23:16:59 merlinofchaos Exp $ */ +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 td { + 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/sites/all/modules/ctools/page_manager/help/about.html b/sites/all/modules/ctools/page_manager/help/about.html new file mode 100644 index 0000000000000000000000000000000000000000..5e6729c5b4b48013974b598097674050ec81b0e1 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/about.html @@ -0,0 +1,12 @@ +<!-- $Id: about.html,v 1.1 2009/07/22 23:42:47 merlinofchaos Exp $ --> +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/sites/all/modules/ctools/page_manager/help/api-task-handler.html b/sites/all/modules/ctools/page_manager/help/api-task-handler.html new file mode 100644 index 0000000000000000000000000000000000000000..64f594547b5959cf9573910a18ee9e54a091eb88 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/api-task-handler.html @@ -0,0 +1,44 @@ +<!-- $Id: api-task-handler.html,v 1.1 2009/07/09 00:07:04 merlinofchaos Exp $ --> +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/sites/all/modules/ctools/page_manager/help/api-task-type.html b/sites/all/modules/ctools/page_manager/help/api-task-type.html new file mode 100644 index 0000000000000000000000000000000000000000..f39ac11ddaa3dd0dafd124702e5fd57ec93d7fef --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/api-task-type.html @@ -0,0 +1,3 @@ +<!-- $Id: api-task-type.html,v 1.1 2009/07/09 00:07:04 merlinofchaos Exp $ --> + +defines a task type, grouping tasks together and providing a common UI for them. \ No newline at end of file diff --git a/sites/all/modules/ctools/page_manager/help/api-task.html b/sites/all/modules/ctools/page_manager/help/api-task.html new file mode 100644 index 0000000000000000000000000000000000000000..4eced0e2a44cbfb7e80e25d5e9cc1cfc232f8a73 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/api-task.html @@ -0,0 +1,39 @@ +<!-- $Id: api-task.html,v 1.1 2009/07/09 00:07:04 merlinofchaos Exp $ --> +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/sites/all/modules/ctools/page_manager/help/custom-pages-access.html b/sites/all/modules/ctools/page_manager/help/custom-pages-access.html new file mode 100644 index 0000000000000000000000000000000000000000..25ba63a268ef6c597ad43aef6b395913f703bf27 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/custom-pages-access.html @@ -0,0 +1,3 @@ +<!-- $Id: custom-pages-access.html,v 1.1 2009/07/22 23:42:47 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/page_manager/help/custom-pages-arguments.html b/sites/all/modules/ctools/page_manager/help/custom-pages-arguments.html new file mode 100644 index 0000000000000000000000000000000000000000..b0bdff51f89b1c626ac93f8da7c789ca7e5531cd --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/custom-pages-arguments.html @@ -0,0 +1,3 @@ +<!-- $Id: custom-pages-arguments.html,v 1.1 2009/07/22 23:42:47 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/page_manager/help/custom-pages-menu.html b/sites/all/modules/ctools/page_manager/help/custom-pages-menu.html new file mode 100644 index 0000000000000000000000000000000000000000..d3388bca1ea1578159e826e603b14ece47831c43 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/custom-pages-menu.html @@ -0,0 +1,3 @@ +<!-- $Id: custom-pages-menu.html,v 1.1 2009/07/22 23:42:47 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/page_manager/help/custom-pages.html b/sites/all/modules/ctools/page_manager/help/custom-pages.html new file mode 100644 index 0000000000000000000000000000000000000000..22ea381ea07cf6e8754cfae6560a8999d29c20df --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/custom-pages.html @@ -0,0 +1,3 @@ +<!-- $Id: custom-pages.html,v 1.1 2009/07/22 23:42:47 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/page_manager/help/getting-started-create.html b/sites/all/modules/ctools/page_manager/help/getting-started-create.html new file mode 100644 index 0000000000000000000000000000000000000000..3ba5ebc297c02d71116cf7a82059c897f9cad28a --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/getting-started-create.html @@ -0,0 +1,3 @@ +<!-- $Id: getting-started-create.html,v 1.1 2009/07/22 23:42:47 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/page_manager/help/getting-started-custom-nodes.html b/sites/all/modules/ctools/page_manager/help/getting-started-custom-nodes.html new file mode 100644 index 0000000000000000000000000000000000000000..a5d403b0eced5f62c8e16c6f8bb68b333fa60769 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/getting-started-custom-nodes.html @@ -0,0 +1,3 @@ +<!-- $Id: getting-started-custom-nodes.html,v 1.1 2009/07/22 23:42:47 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/page_manager/help/getting-started-custom-vocabulary.html b/sites/all/modules/ctools/page_manager/help/getting-started-custom-vocabulary.html new file mode 100644 index 0000000000000000000000000000000000000000..a14c0ea68b8ef358cc5b152422e73c6572ec99ea --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/getting-started-custom-vocabulary.html @@ -0,0 +1,3 @@ +<!-- $Id: getting-started-custom-vocabulary.html,v 1.1 2009/07/22 23:42:47 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/page_manager/help/getting-started-members.html b/sites/all/modules/ctools/page_manager/help/getting-started-members.html new file mode 100644 index 0000000000000000000000000000000000000000..73a4405ffe8cf1392e4eeecc3ff043f5c51110f9 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/getting-started-members.html @@ -0,0 +1,3 @@ +<!-- $Id: getting-started-members.html,v 1.1 2009/07/22 23:42:47 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/page_manager/help/getting-started-page-list.html b/sites/all/modules/ctools/page_manager/help/getting-started-page-list.html new file mode 100644 index 0000000000000000000000000000000000000000..ad330a7f529e66c9444e0ac99f7bd8f6dbeb80d6 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/getting-started-page-list.html @@ -0,0 +1,3 @@ +<!-- $Id: getting-started-page-list.html,v 1.1 2009/07/22 23:42:47 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/page_manager/help/getting-started.html b/sites/all/modules/ctools/page_manager/help/getting-started.html new file mode 100644 index 0000000000000000000000000000000000000000..d342751dfd1d14ea41be606f125c45940d68f506 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/getting-started.html @@ -0,0 +1,16 @@ +<!-- $Id: getting-started.html,v 1.2 2009/08/19 22:24:07 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/page_manager/help/page-task-type.html b/sites/all/modules/ctools/page_manager/help/page-task-type.html new file mode 100644 index 0000000000000000000000000000000000000000..c382c76ff2e76fde8653bc3ea72304e55ee92cba --- /dev/null +++ b/sites/all/modules/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/sites/all/modules/ctools/page_manager/help/page_manager.help.ini b/sites/all/modules/ctools/page_manager/help/page_manager.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..cd94653270d5171af16fa06fcefedbe5f96a6782 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/page_manager.help.ini @@ -0,0 +1,60 @@ +; $Id: page_manager.help.ini,v 1.1 2009/07/22 23:42:47 merlinofchaos Exp $ +[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/sites/all/modules/ctools/page_manager/help/variants.html b/sites/all/modules/ctools/page_manager/help/variants.html new file mode 100644 index 0000000000000000000000000000000000000000..389af3304b95b34612b19188e5a46c25e9cbbcee --- /dev/null +++ b/sites/all/modules/ctools/page_manager/help/variants.html @@ -0,0 +1,3 @@ +<!-- $Id: variants.html,v 1.1 2009/07/22 23:42:47 merlinofchaos Exp $ --> + +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/sites/all/modules/ctools/page_manager/images/arrow-active.png b/sites/all/modules/ctools/page_manager/images/arrow-active.png new file mode 100644 index 0000000000000000000000000000000000000000..3bbd3c27f29f9a1781276a2ae8faa7afd5d2d36e Binary files /dev/null and b/sites/all/modules/ctools/page_manager/images/arrow-active.png differ diff --git a/sites/all/modules/ctools/page_manager/images/locked-other.png b/sites/all/modules/ctools/page_manager/images/locked-other.png new file mode 100644 index 0000000000000000000000000000000000000000..b84a154e8b41ae4f0ce9ea97fa9de7ab8534284a Binary files /dev/null and b/sites/all/modules/ctools/page_manager/images/locked-other.png differ diff --git a/sites/all/modules/ctools/page_manager/images/locked.png b/sites/all/modules/ctools/page_manager/images/locked.png new file mode 100644 index 0000000000000000000000000000000000000000..2116eb1c810d4f76eefeebb920f3764ea443c0fb Binary files /dev/null and b/sites/all/modules/ctools/page_manager/images/locked.png differ diff --git a/sites/all/modules/ctools/page_manager/js/page-list.js b/sites/all/modules/ctools/page_manager/js/page-list.js new file mode 100644 index 0000000000000000000000000000000000000000..796862565834ac777b97553d440573d10432d31b --- /dev/null +++ b/sites/all/modules/ctools/page_manager/js/page-list.js @@ -0,0 +1,45 @@ +// $Id: page-list.js,v 1.3 2009/07/12 18:32:04 merlinofchaos Exp $ + +/** + * 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/sites/all/modules/ctools/page_manager/page_manager.admin.inc b/sites/all/modules/ctools/page_manager/page_manager.admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..4540cb51c2612a0e19384f17bb52fdbfcbfb97ad --- /dev/null +++ b/sites/all/modules/ctools/page_manager/page_manager.admin.inc @@ -0,0 +1,1850 @@ +<?php +// $Id: page_manager.admin.inc,v 1.45 2010/11/03 00:01:14 merlinofchaos Exp $ + +/** + * @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. + $form = drupal_build_form('page_manager_list_pages_form', $form_state); + + $header = array( + array('data' => t('Type'), 'class' => array('page-manager-page-type')), + array('data' => t('Name'), 'class' => array('page-manager-page-name')), + array('data' => t('Title'), 'class' => array('page-manager-page-title')), + array('data' => t('Path'), 'class' => array('page-manager-page-path')), + array('data' => t('Storage'), 'class' => array('page-manager-page-storage')), + ); + + $header[] = array('data' => t('Operations'), 'class' => array('page-manager-page-operations')); + $table = theme('table', array('header' => $header, 'rows' => $pages['rows'], 'attributes' => array('id' => 'page-manager-list-pages'))); + + $operations = '<div id="page-manager-links" class="links">' . theme('links', array('links' => $pages['operations'])) . '</div>'; + + drupal_add_css(drupal_get_path('module', 'page_manager') . '/css/page-manager.css'); + + + if (!$js) { + return array('#markup' => drupal_render($form) . $table . $operations); + } + + ctools_include('ajax'); + $commands = array(); + $commands[] = ajax_command_replace('#page-manager-list-pages', $table); + if (!empty($replace_form)) { + $commands[] = ajax_command_replace('#page-manager-list-pages-form', $form); + } + print ajax_render($commands); + ajax_footer(); +} + +/** + * 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 = array('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' => array('page-manager-page-type')); + + $row['data']['name'] = array('data' => $task_name, 'class' => array('page-manager-page-name')); + $row['data']['title'] = array('data' => $task['admin title'], 'class' => array('page-manager-page-title')); + $row['data']['path'] = array('data' => $visible_path, 'class' => array('page-manager-page-path')); + + $storage = isset($task['storage']) ? $task['storage'] : t('In code'); + $pages['storages'][$storage] = $storage; + $row['data']['storage'] = array('data' => $storage, 'class' => array('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/structure/pages/nojs/enable/' . $task_name, + 'query' => array('token' => drupal_get_token($task_name)), + ); + } + else { + $operations[] = array( + 'title' => t('Disable'), + 'href' => 'admin/structure/pages/nojs/disable/' . $task_name, + 'query' => array('token' => drupal_get_token($task_name)), + ); + } + } + + $row['data']['operations'] = array('data' => theme('links', array('links' => $operations)), 'class' => array('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, &$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/structure/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' => array('use-ajax-submit ctools-auto-submit-click')), + ); + + $form['reset'] = array( + '#type' => 'submit', + '#id' => 'edit-pages-reset', + '#value' => t('Reset'), + '#attributes' => array('class' => array('use-ajax-submit')), + ); + + $form['#attached']['js'] = array('misc/ajax.js', 'misc/progress.js', 'misc/jquery.form.js', ctools_attach_js('auto-submit'), ctools_attach_js('page-list', 'page_manager')); + $form['#prefix'] = '<div class="clearfix">'; + $form['#suffix'] = '</div>'; + $form['#attributes'] = array('class' => array('ctools-auto-submit-full-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) { + drupal_set_title($page->subtask['admin title']); + // Provide and process the save page form before anything else. + $form_state = array('page' => &$page); + $form = drupal_render(drupal_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' => array('operations-main')), 'nav'); + $content = page_manager_get_operation_content(FALSE, $page, $args, $operations); + $output = theme('page_manager_edit_page', array('page' => $page, 'save' => $form, 'operations' => $rendered_operations, 'content' => $content)); + return array('#markup' => $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' => array('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. + $form_state = array('page' => &$page); + $form = drupal_render(drupal_build_form('page_manager_save_page_form', $form_state)); + + $output = theme('page_manager_edit_page', array('page' => $page, 'save' => $form, 'operations' => $rendered_operations, 'content' => $content)); + + if ($js) { + $commands = array(); + $commands[] = ajax_command_replace('#page-manager-edit', $output); + + print ajax_render($commands); + ajax_footer(); + return; + } + + 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/structure/pages/edit', + 'ajax' => FALSE, + 'no operations' => TRUE, + 'form info' => array( + 'no buttons' => TRUE, + ), + 'form' => 'page_manager_page_summary', + ), + 'actions' => array( + 'type' => 'group', + 'title' => '', + 'class' => array('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 settings')) { + $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' => array('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' => array('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' => array('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 = drupal_render(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 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.'), + ); + } + + $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, + ); + } + + return $form; +} + +/** + * 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()) { + drupal_add_js('misc/ajax.js'); + + 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) { + if (!is_array($attributes['class'])) { + dsm($attributes['class']); + } + $class = empty($attributes['class']) || !is_array($attributes['class']) ? array() : $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="' . implode(' ', $class) . '">'; + } + + switch ($operation['type']) { + case 'text': + $output[$location] .= $operation['title']; + break; + case 'operation': + $path = isset($operation['path']) ? $operation['path'] : 'admin/structure/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 = array('page-manager-operation'); + if (!isset($operation['ajax']) || !empty($operation['ajax'])) { + $class[] = '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', array('handle' => $title, 'content' => $output[$location], 'collapsed' => 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, &$form_state) { + if (!empty($form_state['page']->changed)) { + $form['markup'] = array( + '#markup' => '<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/structure/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/structure/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. + return 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)), + ); + } + } + } + + return $form; +} + +/** + * 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 settings')) { + $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( + '#markup' => '<div>' . t('You do not have sufficient permissions to perform this action.') . '</div>', + ); + } + + return $form; +} + +/** + * Make sure that an import actually provides a handler. + */ +function page_manager_handler_import_validate($form, &$form_state) { + if (!user_access('use PHP for settings')) { + 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( + '#markup' => 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, + ); + } + + return $form; +} + +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( + '#markup' => '<p>' . $text . '</p>', + ); + + return $form; +} + +/** + * 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']); + return $form; +} + +/** + * 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.'), + ); + + return $form; +} + +/** + * 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( + '#markup' => 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.'), + ); + + return $form; +} + +/** + * 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( + '#markup' => 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.'), + ); + + return $form; +} + +/** + * 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( + '#markup' => page_manager_get_handler_summary($plugin, $handler, $page, FALSE), + ); + + return $form; +} + +/** + * 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( + '#markup' => 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?') + ); + + return $form; +} + +/** + * 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( + '#markup' => t('Enabling this page will immediately make it available in your system (there is no need to wait for a save.)'), + ); + + return $form; +} + +/** + * 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( + '#markup' => t('Disabling this page will immediately make it unavailable in your system (there is no need to wait for a save.)'), + ); + + return $form; +} + +/** + * 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', array('links' => $links)) . '</div>'; + $form['markup'] = array( + '#markup' => $output, + ); + + return $form; +} + +/** + * 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/structure/pages'); +} diff --git a/sites/all/modules/ctools/page_manager/page_manager.info b/sites/all/modules/ctools/page_manager/page_manager.info new file mode 100644 index 0000000000000000000000000000000000000000..16e36dfdd91e2d57d4e22c7eb834c6c405c984df --- /dev/null +++ b/sites/all/modules/ctools/page_manager/page_manager.info @@ -0,0 +1,13 @@ +; $Id: page_manager.info,v 1.5 2011/01/01 00:01:46 merlinofchaos Exp $ +name = Page manager +description = Provides a UI and API to manage pages within the site. +core = 7.x +dependencies[] = ctools +package = Chaos tool suite + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-1.0-alpha2" +core = "7.x" +project = "ctools" +datestamp = "1294276864" + diff --git a/sites/all/modules/ctools/page_manager/page_manager.install b/sites/all/modules/ctools/page_manager/page_manager.install new file mode 100644 index 0000000000000000000000000000000000000000..1771e48e995d064754897d7d520d1a2b62d7ee1b --- /dev/null +++ b/sites/all/modules/ctools/page_manager/page_manager.install @@ -0,0 +1,203 @@ +<?php +// $Id: page_manager.install,v 1.10 2010/09/07 09:02:50 sdboyer Exp $ + +/** + * @file + * Installation routines for page manager module. + */ + +/** + * Implements 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['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; +} + +/** + * Implements hook_install(). + */ +function page_manager_install() { + db_update('system') + ->fields(array('weight' => 99)) + ->condition('name', 'page_manager') + ->execute(); +} diff --git a/sites/all/modules/ctools/page_manager/page_manager.module b/sites/all/modules/ctools/page_manager/page_manager.module new file mode 100644 index 0000000000000000000000000000000000000000..e7ba2dabffe62fce13b6b5c39c25301443bb7c03 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/page_manager.module @@ -0,0 +1,1178 @@ +<?php +// $Id: page_manager.module,v 1.26 2010/11/03 00:08:04 merlinofchaos Exp $ + +/** + * @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 + +/** + * Implements hook_permission(). + */ +function page_manager_permission() { + return array( + 'use page manager' => array( + 'title' => t('Use Page Manager'), + 'description' => t("Allows users to use most of Page Manager's features, though restricts some of the most powerful, potentially site-damaging features. Note that even the reduced featureset still allows for enormous control over your website."), + 'restrict access' => TRUE, + ), + 'administer page manager' => array( + 'title' => t('Administer Page Manager'), + 'description' => t('Allows complete control over Page Manager, i.e., complete control over your site. Grant with extreme caution.'), + 'restrict access' => TRUE, + ), + ); + +} + +/** + * Implements 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; + } + if ($owner == 'ctools' && $plugin_type == 'cache') { + return 'plugins/' . $plugin_type; + } +} + +/** + * Implements hook_ctools_plugin_type() to inform the plugin system that Page + * Manager owns task, task_handler, and page_wizard plugin types. + * + * All of these are empty because the defaults all work. + */ +function page_manager_ctools_plugin_type() { + return array( + 'tasks' => array(), + 'task_handlers' => array(), + 'page_wizards' => array(), + ); +} + +/** + * 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/structure/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/structure/pages/list'] = array( + 'title' => 'List', + 'page callback' => 'page_manager_list_page', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ) + $base; + + $items['admin/structure/pages/edit/%page_manager_cache'] = array( + 'title' => 'Edit', + 'page callback' => 'page_manager_edit_page', + 'page arguments' => array(4), + 'type' => MENU_CALLBACK, + ) + $base; + + $items['admin/structure/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/structure/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/structure/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; +} + +/** + * Implements 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; +} + +/* + * Implements 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_handler_rearrange' => array( + 'render element' => 'form', + ) + $base, + 'page_manager_edit_page' => array( + 'template' => 'page-manager-edit-page', + 'variables' => array('page' => NULL, 'save' => NULL, 'operations' => array(), 'content' => array()), + ) + $base, + 'page_manager_lock' => array( + 'variables' => array('page' => array()), + ) + $base, + 'page_manager_changed' => array( + 'variables' => 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) { + $caches = drupal_static(__FUNCTION__, array()); + if (!isset($caches[$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; + } + + $caches[$task_name] = $cache; + } + + return $caches[$task_name]; +} + +/** + * 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 (:names)', array(':names' => $names)); + foreach ($result as $weight) { + $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_delete('page_manager_weights') + ->condition('name', $handler->name) + ->execute(); + + // 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_delete('page_manager_handlers') + ->condition('name', $handler->name) + ->execute(); + db_delete('page_manager_weights') + ->condition('name', $handler->name) + ->execute(); +} + +/** + * 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 = 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_delete('page_manager_weights') + ->condition('name', $handler->name) + ->execute(); + db_insert('page_manager_weights') + ->fields(array( + 'name' => $handler->name, + 'weight' => $weight, + )) + ->execute(); +} + + +/** + * 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')) { + $retval = $function($task); + if (is_array($retval)) { + return $retval; + } + else { + dsm($retval); + } + } + + 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); +} + +/** + * 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/structure/pages/edit/$task_name"; + } + + return 'admin/structure/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) { + 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_query('SELECT mlid FROM {menu_links} WHERE router_path = :path', array('path' => $item['parent_path']))->fetchField(); + 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)) { + $list[$handler->name] = check_plain("$handler->task: " . $handler->conf['title'] . " ($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 .= " * Implements 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/structure/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/structure/pages'), + 'content' => theme('table', array('header' => array(), 'rows' => $rows, 'attributes' => array('class' => 'panels-manage'))), + 'class' => 'dashboard-pages', + 'section' => 'right', + ); +} diff --git a/sites/all/modules/ctools/page_manager/plugins/cache/page_manager_context.inc b/sites/all/modules/ctools/page_manager/plugins/cache/page_manager_context.inc new file mode 100644 index 0000000000000000000000000000000000000000..f56f81c6a48912924ca98ff4c67803b24b5a05ac --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/cache/page_manager_context.inc @@ -0,0 +1,71 @@ +<?php +// $Id: page_manager_context.inc,v 1.1 2010/10/11 22:18:24 sdboyer Exp $ + +/** + * @file + * A page_manager cache indirection mechanism that just attaches context + * caching to the larger page cache. + */ + +$plugin = array( + // cache plugins are the rare plugin types that have no real UI but + // we're providing a title just in case. + 'title' => t('Page manager context'), + 'cache get' => 'page_manager_cache_page_manager_context_cache_get', + 'cache set' => 'page_manager_cache_page_manager_context_cache_set', + 'cache finalize' => 'page_manager_cache_page_manager_context_cache_finalize', + + // We don't support a clear because the general uses of clear have no effect + // on us. +); + +function page_manager_cache_page_manager_context_cache_get($data, $key) { + $page = page_manager_get_page_cache($data); + 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_cache_page_manager_context_cache_set($data, $key, $object) { + $page = page_manager_get_page_cache($data); + if ($page) { + $page->context_cache[$key] = $object; + return page_manager_set_page_cache($page); + } +} + +/** + * Copy temporary data from the page manager cache + */ +function page_manager_cache_page_manager_context_cache_finalize($data, $key, $object) { + // Statically cached so there shouldn't be any worries. It's an object so + // referencing ensures that we'll get the right one. + $page = page_manager_get_page_cache($data); + if ($page) { + if ($key == 'temp') { + $handler = $page->new_handler; + } + else { + $handler = $page->handlers[$key]; + } + $handler->conf['contexts'] = $object->contexts; + $handler->conf['relationships'] = $object->relationships; + + if (isset($page->context_cache[$key])) { + unset($page->context_cache[$key]); + } + return page_manager_set_page_cache($page); + } +} diff --git a/sites/all/modules/ctools/page_manager/plugins/task_handlers/http_response.inc b/sites/all/modules/ctools/page_manager/plugins/task_handlers/http_response.inc new file mode 100644 index 0000000000000000000000000000000000000000..bf3da17e94bdb4d2d0564e1539ec4cfe49c6e519 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/task_handlers/http_response.inc @@ -0,0 +1,287 @@ +<?php +// $Id: http_response.inc,v 1.2 2010/10/11 22:18:24 sdboyer Exp $ + +/** + * @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('Panel 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' => array('actions')), 'actions', $args); + + $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' => array('page-summary-label'), 'data' => t('Storage')), + array('class' => array('page-summary-data'), 'data' => $type), + array('class' => array('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' => array('page-summary-label'), 'data' => t('Status')), + array('class' => array('page-summary-data'), 'data' => $text), + array('class' => array('page-summary-operation'), 'data' => $link), + ); + + $link = l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'criteria'))); + $rows[] = array( + array('class' => array('page-summary-label'), 'data' => t('Selection rule')), + array('class' => array('page-summary-data'), 'data' => $access), + array('class' => array('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' => array('page-summary-label'), 'data' => t('Response code')), + array('class' => array('page-summary-data'), 'data' => $codes[$handler->conf['code']]), + array('class' => array('page-summary-operation'), 'data' => $link), + ); + + $info = theme('table', array('header' => array(), 'rows' => $rows, 'attributes' => array('class' => array('page-manager-handler-summary')))); + + $title = $handler->conf['title']; + if ($title != t('Panel')) { + $title = t('Panel: @title', array('@title' => $title)); + } + + $output .= '<div class="clearfix">'; + if ($show_title) { + $output .= '<div class="handler-title clearfix">'; + $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 panel 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 panel + */ +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).'), + ); + + return $form; +} + +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'] = $url['query']; + } + if (isset($url['fragment'])) { + $path = strtr($path, array('#' . $url['fragment'] => '')); + $info['fragment'] = $url['fragment']; + } + + $info['destination'] = $path; + } + + return $info; +} \ No newline at end of file diff --git a/sites/all/modules/ctools/page_manager/plugins/tasks/blog.inc b/sites/all/modules/ctools/page_manager/plugins/tasks/blog.inc new file mode 100644 index 0000000000000000000000000000000000000000..94d76feb39638d3d43c9817a003c564f1746940b --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/tasks/blog.inc @@ -0,0 +1,105 @@ +<?php +// $Id: blog.inc,v 1.3 2010/01/29 21:21:20 merlinofchaos Exp $ + +/** + * 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/sites/all/modules/ctools/page_manager/plugins/tasks/blog_user.inc b/sites/all/modules/ctools/page_manager/plugins/tasks/blog_user.inc new file mode 100644 index 0000000000000000000000000000000000000000..9332441b912765c62f0c4725044409ef040974a7 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/tasks/blog_user.inc @@ -0,0 +1,135 @@ +<?php +// $Id: blog_user.inc,v 1.3 2009/10/13 18:12:09 merlinofchaos Exp $ + +/** + * 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/sites/all/modules/ctools/page_manager/plugins/tasks/contact_site.inc b/sites/all/modules/ctools/page_manager/plugins/tasks/contact_site.inc new file mode 100644 index 0000000000000000000000000000000000000000..26fc8122ec4627dcfe68f66767a15e3fcd51dfd3 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/tasks/contact_site.inc @@ -0,0 +1,105 @@ +<?php +// $Id: contact_site.inc,v 1.3 2010/01/29 21:21:20 merlinofchaos Exp $ + +/** + * 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/sites/all/modules/ctools/page_manager/plugins/tasks/contact_user.inc b/sites/all/modules/ctools/page_manager/plugins/tasks/contact_user.inc new file mode 100644 index 0000000000000000000000000000000000000000..88e00ca9aaca2e243aafe10a7fc5483ab342f37e --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/tasks/contact_user.inc @@ -0,0 +1,134 @@ +<?php +// $Id: contact_user.inc,v 1.4 2010/01/21 05:59:29 sdboyer Exp $ + +/** + * 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/sites/all/modules/ctools/page_manager/plugins/tasks/node_edit.inc b/sites/all/modules/ctools/page_manager/plugins/tasks/node_edit.inc new file mode 100644 index 0000000000000000000000000000000000000000..43c70a6e0a4c5fd5f18c918487d2691ce3953c24 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/tasks/node_edit.inc @@ -0,0 +1,168 @@ +<?php +// $Id: node_edit.inc,v 1.4 2009/09/27 03:41:02 merlinofchaos Exp $ + +/** + * 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_type_get_types() 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_type_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/sites/all/modules/ctools/page_manager/plugins/tasks/node_view.inc b/sites/all/modules/ctools/page_manager/plugins/tasks/node_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..d5f4abdf9364dab29053e7bd06abaf8c07c3c2ff --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/tasks/node_view.inc @@ -0,0 +1,144 @@ +<?php +// $Id: node_view.inc,v 1.7 2010/12/31 23:56:41 merlinofchaos Exp $ + +/** + * @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_page'; + $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_page($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'); + $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); + 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/sites/all/modules/ctools/page_manager/plugins/tasks/page.admin.inc b/sites/all/modules/ctools/page_manager/plugins/tasks/page.admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..f23db8cefa660bafb30cb08115d93d91e240280c --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/tasks/page.admin.inc @@ -0,0 +1,1518 @@ +<?php +// $Id: page.admin.inc,v 1.30 2011/01/05 22:35:46 merlinofchaos Exp $ + +/** + * @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/structure/pages/add'] = array( + 'title' => 'Add custom page', + 'page callback' => 'page_manager_page_add_subtask', + 'page arguments' => array(), + 'type' => MENU_LOCAL_ACTION, + ) + $base; + + $items['admin/structure/pages/import'] = array( + 'title' => 'Import page', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('page_manager_page_import_subtask', 'page'), + 'type' => MENU_LOCAL_ACTION, + ) + $base; + if ($access_callback == 'user_access') { + $items['admin/structure/pages/import']['access callback'] = 'ctools_access_multiperm'; + $items['admin/structure/pages/import']['access arguments'][] = 'use PHP for settings'; + } + + // AJAX callbacks for argument modal. + $items['admin/structure/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 'action': + $item['type'] = MENU_LOCAL_ACTION; + 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/structure/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/structure/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' => 'machine_name', + '#title' => t('Machine name'), + '#machine_name' => array( + 'exists' => 'page_manager_page_load', + 'source' => array('admin_title'), + ), + '#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'); + $form = page_manager_handler_add_form($form, $form_state, $features); + } + + return $form; +} + +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 = :path', array(':path' => $path)); + foreach ($result as $router) { + 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) { + $alias = db_query('SELECT alias, source FROM {url_alias} WHERE alias = :path', array(':path' => $path))->fetchObject(); + if ($alias) { + 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="clearfix">', + '#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'), + 'action' => t('Local action'), + ), + '#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', 'action')), + ); + + list($major, $minor) = explode('.', VERSION, 2); + + // 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', 'action')), + ); + + $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('form_process_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, + ); + + return $form; +} + +/** + * 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 = ctools_access_admin_form($form, $form_state); + + return $form; +} + +/** + * 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' => array("page-manager-context-$keyword-change-url")), + '#type' => 'hidden', + '#value' => url("admin/structure/pages/argument/change/$task_name/$keyword", array('absolute' => TRUE)), + ); + $form['table']['argument'][$keyword]['change'] = array( + '#type' => 'submit', + '#value' => t('Change'), + '#attributes' => array('class' => array('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' => array("page-manager-context-$keyword-settings-url")), + '#type' => 'hidden', + '#value' => url("admin/structure/pages/argument/settings/$task_name/$keyword", array('absolute' => TRUE)), + ); + $form['table']['argument'][$keyword]['settings'] = array( + '#type' => 'submit', + '#value' => t('Settings'), + '#attributes' => array('class' => array('ctools-use-modal')), + '#id' => "page-manager-context-$keyword-settings", + ); + } + } + + return $form; +} + +/** + * Theme the table for this form. + */ +function theme_page_manager_page_form_argument_table($vars) { + $form = $vars['form']; + $header = array( + array('data' => t('Argument'), 'class' => array('page-manager-argument')), + array('data' => t('Position in path'), 'class' => array('page-manager-position')), + array('data' => t('Context assigned'), 'class' => array('page-manager-context')), + array('data' => t('Operations'), 'class' => array('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', array('header' => $header, 'rows' => $rows, 'attributes' => $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/structure/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, + 'modal return' => TRUE, + 'commands' => array(), + ); + + $output = ctools_wizard_multistep_form($form_info, $step, $form_state); + if (!empty($form_state['complete'])) { + 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($cache); + + // 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; + page_manager_page_form_argument($form, $clone_state); + $form = drupal_build_form('page_manager_page_form_argument', $form_state); + + // Render just the table portion. + $output = drupal_render($form['table']); + $commands = array( + ajax_command_replace('#page-manager-argument-table', $output), + ctools_modal_command_dismiss(), + ); + } + else { + $commands = ctools_modal_form_render($form_state, $output); + } + print ajax_render($commands); + ajax_footer(); + exit; +} + +/** + * Callback generated when the add page process is finished. + */ +function page_manager_page_argument_finish(&$form_state) { +} + +/** + * 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, + ); + + return $form; +} + +/** + * 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; + return $form; +} + +/** + * 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, &$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']); + return $form; +} + +/** + * 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['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' => 'machine_name', + '#title' => t('Page name'), + '#machine_name' => array( + 'exists' => 'page_manager_page_load', + 'source' => array('admin_title'), + ), + '#description' => t('Enter the name to the new page It must be unique and contain only alphanumeric characters and underscores.'), + ); + + // 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'), + ); + + return $form; +} + +/** + * 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'), + ); + } + + return $form; +} + +/** + * 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/structure/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/sites/all/modules/ctools/page_manager/plugins/tasks/page.inc b/sites/all/modules/ctools/page_manager/plugins/tasks/page.inc new file mode 100644 index 0000000000000000000000000000000000000000..79c03c8cb9b20e1834b2952cc037ed1f6e29b402 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/tasks/page.inc @@ -0,0 +1,771 @@ +<?php +// $Id: page.inc,v 1.24 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * @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/structure/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' => array('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( + 'render element' => 'form', + ); + $items['page_manager_page_lock'] = $base + array( + 'variables' => array('lock' => array(), 'task_name' => NULL), + ); + $items['page_manager_page_changed'] = $base + array( + 'variables' => 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 + $plugin = ctools_get_argument($argument['name']); + // 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++; + } + } + + 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_delete('page_manager_pages') + ->condition('name', $page->name) + ->execute(); + // 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' => array('page-summary-label'), 'data' => t('Storage')), + array('class' => array('page-summary-data'), 'data' => $subtask['storage']), + array('class' => array('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' => array('page-summary-label'), 'data' => t('Status')), + array('class' => array('page-summary-data'), 'data' => $text), + array('class' => array('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' => array('page-summary-data'), 'data' => $message, 'colspan' => 2), + array('class' => array('page-summary-operation'), 'data' => $link), + ); + } + + if (strpos($path, '%') === FALSE) { + $path = l('/' . $page->path, $path); + } + else { + $path = '/' . $page->path; + } + + $rows[] = array( + array('class' => array('page-summary-label'), 'data' => t('Path')), + array('class' => array('page-summary-data'), 'data' => $path), + array('class' => array('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' => array('page-summary-label'), 'data' => t('Access')), + array('class' => array('page-summary-data'), 'data' => $access), + array('class' => array('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.'), + 'action' => t('Local action'), + ); + + 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' => array('page-summary-label'), 'data' => t('Menu')), + array('class' => array('page-summary-data'), 'data' => $menu), + array('class' => array('page-summary-operation'), 'data' => $link), + ); + + $output .= theme('table', array('rows' => $rows, 'attributes' => 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/sites/all/modules/ctools/page_manager/plugins/tasks/poll.inc b/sites/all/modules/ctools/page_manager/plugins/tasks/poll.inc new file mode 100644 index 0000000000000000000000000000000000000000..e811e2996af3c59c10105ba04015ee614cf1033c --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/tasks/poll.inc @@ -0,0 +1,105 @@ +<?php +// $Id: poll.inc,v 1.2 2010/01/29 21:21:21 merlinofchaos Exp $ + +/** + * 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/sites/all/modules/ctools/page_manager/plugins/tasks/search.inc b/sites/all/modules/ctools/page_manager/plugins/tasks/search.inc new file mode 100644 index 0000000000000000000000000000000000000000..cc997c27db3fa9ea84acdb5781e318b168a7e71a --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/tasks/search.inc @@ -0,0 +1,293 @@ +<?php +// $Id: search.inc,v 1.4 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * @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')) { + 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') { + // @TODO: test that this actually works once page_manager is upgraded. + drupal_static_reset('menu_set_active_trail'); + drupal_static_reset('menu_tree_page_data'); + menu_set_active_trail(); + + 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) { + $return = array(); + 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/sites/all/modules/ctools/page_manager/plugins/tasks/term_view.inc b/sites/all/modules/ctools/page_manager/plugins/tasks/term_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..fabf6da1da70e771c170fe420ec1e3357bea07ac --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/tasks/term_view.inc @@ -0,0 +1,294 @@ +<?php +// $Id: term_view.inc,v 1.10 2011/01/06 00:16:28 merlinofchaos Exp $ + +/** + * @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; + } + + // @todo --fix. + variable_set('page_manager_term_view_disabled', TRUE); + drupal_set_message(t('Due to changes in taxonomy, the taxonomy integration with Page Manager is currently not implemented. See <a href="http://drupal.org/node/1016510">.'), 'error'); + return; + + // Override the term view handler for our purpose, but only if someone else + // has not already done so. + if (isset($items['taxonomy/term/%taxonomy_term']) && $items['taxonomy/term/%taxonomy_term']['page callback'] == 'taxonomy_term_page' || variable_get('page_manager_override_anyway', FALSE)) { + $items['taxonomy/term/%taxonomy_term']['page callback'] = 'page_manager_term_view_page'; + $items['taxonomy/term/%taxonomy_term']['file path'] = $task['path']; + $items['taxonomy/term/%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/%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_page($term) { + // 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' => array('page-summary-label'), 'data' => t('Path')), + array('class' => array('page-summary-data'), 'data' => 'taxonomy/term/%term'), + array('class' => array('page-summary-operation'), 'data' => ''), + ); + + $rows[] = array( + array('class' => array('page-summary-label'), 'data' => t('Access')), + array('class' => array('page-summary-data'), 'data' => t('This page is publicly accessible.')), + array('class' => array('page-summary-operation'), 'data' => ''), + ); + + $menu = t('No menu entry'); + + $rows[] = array( + array('class' => array('page-summary-label'), 'data' => t('Menu')), + array('class' => array('page-summary-data'), 'data' => $menu), + array('class' => array('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' => array('page-summary-label'), 'data' => t('%term')), + array('class' => array('page-summary-data'), 'data' => $message), + array('class' => array('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' => array('page-summary-label'), 'data' => t('Breadcrumb')), + array('class' => array('page-summary-data'), 'data' => $message), + array('class' => array('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/sites/all/modules/ctools/page_manager/plugins/tasks/translations/page_manager-plugins-tasks.hu.po b/sites/all/modules/ctools/page_manager/plugins/tasks/translations/page_manager-plugins-tasks.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..8dfb4fc0a54b3283c849ce01037d14e970e44f5f --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/tasks/translations/page_manager-plugins-tasks.hu.po @@ -0,0 +1,651 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 13:40+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 "Status" +msgstr "Állapot" +msgid "Access control" +msgstr "Hozzáférés szabályozás" +msgid "Depth" +msgstr "Mélység" +msgid "Import" +msgstr "Import" +msgid "Argument" +msgstr "Argumentum" +msgid "Normal menu item" +msgstr "Normál menüelem" +msgid "Basic settings" +msgstr "Alapbeállítások" +msgid "Node template" +msgstr "Tartalomsablon" +msgid "Change" +msgstr "Változtat" +msgid "All blogs" +msgstr "Minden blog" +msgid "Menu settings" +msgstr "Menübeállítások" +msgid "Parent menu item" +msgstr "Szülő menüpont" +msgid "Page name" +msgstr "Oldal neve" +msgid "Path is required." +msgstr "Az elérési út megadása szükséges." +msgid "Machine name" +msgstr "Programok által olvasható név" +msgid "Create @name" +msgstr "@name beküldése" +msgid "Custom pages" +msgstr "Egyéni oldalak" +msgid "Tab weight" +msgstr "Fül súlya" +msgid "The page has been deleted." +msgstr "Az oldal törölve lett." +msgid "Normal menu entry" +msgstr "Normál menübejegyzés" +msgid "Menu tab" +msgstr "Menü fül" +msgid "Default menu tab" +msgstr "Alapértelmezett menü fül" +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "" +"Ha a beállítás normál vagy fül, meg kell adni a menüelemhez " +"használt szöveget." +msgid "" +"Warning: Changing this item's menu will not work reliably in Drupal " +"6.4 or earlier. Please upgrade your copy of Drupal at !url." +msgstr "" +"Figyelmeztetés: Az ehhez az elemhez tartozó menü módosítása nem " +"működik megbízhatóan a Drupal 6.4 vagy korábbi változatokban. " +"Frissíteni kell a Drupalt erről a helyről: !url." +msgid "Insert item into an available menu." +msgstr "Elem beillesztése egy rendelkezésre álló menübe." +msgid "Menu selection requires the activation of menu module." +msgstr "A menü kiválasztásához szükséges a menu modul engedélyezése." +msgid "The lower the weight the higher/further left it will appear." +msgstr "Minél kisebb a súly, annál magasabban/balrább fog megjelenni." +msgid "Already exists" +msgstr "Már létezik" +msgid "If creating a parent menu item, enter the title of the item." +msgstr "Szülő menüpont létrehozásakor meg kell adni a menüpont címét." +msgid "" +"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." +msgstr "" +"Ha a szülő menüpont egy fül, meg kell adni a fül súlyát. Minél " +"kisebb, annál balrább fog megjelenni." +msgid "Node add/edit form" +msgstr "Tartalom hozzáadása/szerkesztése űrlap" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a tartalmak <em>node/%node/edit</em> és " +"<em>node/add/%node_type</em> oldalakon történő hozzáadásakor vagy " +"szerkesztésekor. Ha lett változat hozzáadva, a tartalom típusa, " +"nyelve vagy a felhasználói hozzáférés kiválasztási feltételek " +"használhatóak arra, hogy eltérő szerkesztési űrlapok legyenek " +"biztosítva a tartalmakhoz. Ha nincs kiválasztott változat, az " +"alapértelmezett Drupal tartalomszerkesztés lesz használva." +msgid "Node being edited" +msgstr "Szerkesztett tartalom" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a tartalmak <em>node/%node</em> oldalon történő " +"megjelenítésekor. Ha lett változat hozzáadva, a tartalom típusa, " +"nyelve vagy a felhasználói hozzáférés kiválasztási feltételek " +"használhatóak arra, hogy eltérő megjelenítések legyenek " +"biztosítva a tartalmakhoz. Ha nincs kiválasztott változat, az " +"alapértelmezett Drupal tartalommegjelenítés lesz használva. Ennek " +"az oldalnak csak az oldalként megtekintett tartalmakra van hatása, " +"nincs hatása a listákban vagy más helyeken megtekintett oldalakra. " +"Továbbá meg kell jegyezni, hogy a pathauto használatakor, az " +"álnevek valahova máshova helyezhetik a tartalmat, de amennyire a " +"Drupal érintett, megtalálhatóak a node/%node oldalakon." +msgid "Node being viewed" +msgstr "Megtekintett tartalom" +msgid "Argument settings" +msgstr "Argumentum beállítások" +msgid "A meaningless second page" +msgstr "Egy lényegtelen második oldal" +msgid "" +"The name of this page. This will appear in the administrative " +"interface to easily identify it." +msgstr "" +"Az oldal neve. Az adminisztratív felületen fog megjelenni a " +"könnyebb azonosíthatóság miatt." +msgid "" +"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!" +msgstr "" +"Az oldal egyedi, programok által olvasható neve. Csak betűket, " +"számokat és aláhúzást tartalmazhat. Ha egyszer létre lett hozva, " +"többé már nem lehet módosítani ezt az értéket!" +msgid "" +"A description of what this page is, does or is for, for administrative " +"use." +msgstr "Az oldal lehetőségeinek leírása adminisztratív használatra." +msgid "" +"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." +msgstr "" +"Az URL elérési út amin az oldal elérhető. Lehetőség van " +"nevesített helykitöltők használatára az elérési utak " +"változóihoz, a %név a szükséges elemekhez, a !név a nem " +"kötelező elemekhez használható. Például „node/%node/foo”, " +"„forum/%forum” vagy „dashboard/!input”. A nevesített " +"helykitöltők környezetekké válhatnak az argumentumok űrlapon." +msgid "Make this your site home page." +msgstr "Beállítás a webhely kezdőlapjaként." +msgid "This page is currently set to be your site home page." +msgstr "Ez az oldal jelenleg a webhely kezdőlapjaként van beállítva." +msgid "Visible menu item" +msgstr "Látható menüelem" +msgid "Name is required." +msgstr "A név megadása szükséges." +msgid "That name is used by another page: @page" +msgstr "Ezt a nevet egy másik oldal használja: @page" +msgid "Page name must be alphanumeric or underscores only." +msgstr "" +"Az oldal neve csak betűkből, számokból és aláhúzásból " +"állhat." +msgid "That path is used by another page: @page" +msgstr "Ezt az elérési utat egy másik oldal használja: @page" +msgid "You cannot have a dynamic path element after an optional path element." +msgstr "" +"Nem lehet egy dinamikus elérési út elem egy nem kötelező " +"elérési út elem után." +msgid "You cannot have a static path element after an optional path element." +msgstr "" +"Nem lehet egy statikus elérési út elem egy nem kötelező elérési " +"út elem után." +msgid "" +"That path is already in used. This system cannot override existing " +"paths." +msgstr "" +"Az elérési út már használatban van. Ez a rendszer nem tudja " +"felülírni a létező elérési utakat." +msgid "" +"That path is currently assigned to be an alias for @alias. This system " +"cannot override existing aliases." +msgstr "" +"Ez az elérési út jelenleg álnévként van rendelve ehhez: @alias. " +"Ez a rendszer nem tudja felülírni a létező álneveket." +msgid "" +"You cannot make this page your site home page if it uses % " +"placeholders." +msgstr "" +"Ez az oldal nem lehet a webhely kezdőlapja, ha % helykitöltőket " +"használ." +msgid "Duplicated argument %arg" +msgstr "%arg argumentum duplikálva van" +msgid "Invalid arg <em>%</em>. All arguments must be named with keywords." +msgstr "" +"Érvénytelen <em>%</em> argumentum. Minden argumentumot nevesíteni " +"kell kulcsszóval." +msgid "" +"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>." +msgstr "" +"Ha egy menüpont alpértelmezett fülként jelenik meg, a Drupalnak " +"tudnia kell, hogy mi lesz a fül szülő menüpontja. Néha a szülő " +"már létezik, de máskor létre kell hozni egyet. Egy szülőpont " +"elérési útja mindig ugyanaz az elérési út lesz, az utolsó rész " +"lehagyásával. Pl. ha ennek a nézetnek az elérési útja " +"<em>foo/bar/baz</em>, a szülő elérési út <em>foo/bar</em> lesz." +msgid "Parent item title" +msgstr "Szűlő menüpont címe" +msgid "Parent item menu" +msgstr "Szűlő menüpont menü" +msgid "" +"Access rules are used to test if the page is accessible and any menu " +"items associated with it are visible." +msgstr "" +"A hozzáférési szabályok alkalmazhatóak annak ellenőrzésére, " +"hogy az oldal hozzáférhető-e és a hozzá kapcsolódó menüpontok " +"láthatóak-e." +msgid "No context assigned" +msgstr "Nincs kijelölt környezet" +msgid "Position in path" +msgstr "Helyzet az elérési útban" +msgid "Context assigned" +msgstr "Hozzárendelt környezet" +msgid "The path %path has no arguments to configure." +msgstr "%path elérési útnak nincsenek beállítható argumentumai." +msgid "Invalid keyword." +msgstr "Érvénytelen kulcsszó." +msgid "Change context type" +msgstr "Környezettípus módosítása" +msgid "Change argument" +msgstr "Argumentum módosítása" +msgid "No context selected" +msgstr "Nincs kiválasztott környezet" +msgid "Error: missing argument." +msgstr "Hiba: hiányzó argumentum." +msgid "Context identifier" +msgstr "Környezet azonosítója" +msgid "" +"This is the title of the context used to identify it later in the " +"administrative process. This will never be shown to a user." +msgstr "" +"Ez a környezet neve, ami azonosításra szolgál a késöbbi " +"adminisztratív folyamatokban. Sosem fog megjelenni a " +"felhasználónak." +msgid "Error: missing or invalid argument plugin %argument." +msgstr "Hiba: hiányzó vagy érvénytelen %argument argumentum beépülő." +msgid "Import page" +msgstr "Import oldal" +msgid "" +"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." +msgstr "" +"Az oldalhoz használt név megadása, ha az eltér a " +"forrásoldalétól. Üresen hagyva az oldal eredeti neve lesz " +"használva." +msgid "" +"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." +msgstr "" +"Az oldalhoz használt elérési út megadása, ha az eltér a " +"forrásoldalétól. Üresen hagyva az oldal eredeti elérési útja " +"lesz használva." +msgid "Allow overwrite of an existing page" +msgstr "Engedélyezi egy létező oldal felülírását" +msgid "" +"If the name you selected already exists in the database, this page " +"will be allowed to overwrite the existing page." +msgstr "" +"Ha a választott név már szerepel az adatbázisban, ez az oldal " +"felülírhatja a létező oldalt." +msgid "Paste page code here" +msgstr "Oldal kódjának beillesztése" +msgid "No handler found." +msgstr "Nincs kezelő." +msgid "Unable to get a page from the import. Errors reported: @errors" +msgstr "Az importból nem lehet oldalt létrehozni. Jelentett hibák: @errors" +msgid "" +"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." +msgstr "" +"Ez az oldalnév használatban van és egy másik felhasználó " +"zárolta. Az oldalon fel kell <a href=\"!break\">oldani a " +"zárolást</a> a végrehajtás előtt, vagy egy eltérő nevet kell " +"választani." +msgid "" +"Enter the name to the new page It must be unique and contain only " +"alphanumeric characters and underscores." +msgstr "" +"Az új oldal neve. Egyedinek kell lennie és csak betűket, számokat " +"és aláhúzást tartalmazhat." +msgid "" +"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." +msgstr "" +"Az URL elérési út, amin az oldal elérhető. Lehetőség van " +"nevesített helykitöltők létrehozására az elérési utak " +"változóihoz, a szükséges elemekhez %név és a a nem kötelező " +"elemekhez !név használatával. Például: „node/%node/foo”, " +"„forum/%forum” vagy „dashboard/!input”. A nevesített " +"helykitöltők környezetekké válhatnak az argumentumok űrlapon. Az " +"elérési út nem egyezhet meg az eredeti oldal elérési útjával." +msgid "Clone variants" +msgstr "Változatok klónozása" +msgid "" +"If checked all variants associated with the page will be cloned as " +"well. If not checked the page will be cloned without variants." +msgstr "" +"Ha be van jelöle, az oldalhoz kapcsolt összes változat is másolva " +"lesz. Ha nincs bejelölve, az oldal változatok nélkül lesz " +"másolva." +msgid "" +"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." +msgstr "" +"Az oldal visszaállítása törli az oldalt az adatbázisból és " +"visszaállítja az eredeti alapértelmezett oldalt. Minden " +"változtatás el fog veszni és nem lesz visszaállítható." +msgid "" +"Are you sure you want to delete this page? Deleting a page cannot be " +"undone." +msgstr "" +"Biztosan törölhető az oldal? Az oldal törlése nem vonható " +"vissza." +msgid "The page has been reverted." +msgstr "Az oldal visszaállítása megtörtént." +msgid "" +"Administrator created pages that have a URL path, access control and " +"entries in the Drupal menu system." +msgstr "" +"Adminisztrátor által létrehozott oldalak, amikhez tartozhat " +"elérési út, hozzáférés szabályozás és bejegyzések a Drupal " +"menürendszerben." +msgid "Create a new page" +msgstr "Új oldal létrhozása" +msgid "Set up contexts for the arguments on this page." +msgstr "Környezetek beállítása az oldalon található argumentumokhoz." +msgid "Control what users can access this page." +msgstr "" +"Annak szabályozása, hogy mely felhasználók férhetnek hozzá ehhez " +"az oldalhoz." +msgid "Provide this page a visible menu or a menu tab." +msgstr "Egy látható menüt vagy menüfület biztosít az oldalhoz." +msgid "Make a copy of this page" +msgstr "Másolat készítése az oldalról" +msgid "" +"Export this page as code that can be imported or embedded into a " +"module." +msgstr "" +"Az oldal exportálása kódba, amit egy modulba lehet importálni vagy " +"ágyazni." +msgid "Remove all changes to this page and revert to the version in code." +msgstr "" +"Az oldal minden módosításának eltávolítása és " +"visszaállítása a kódban található verzióra." +msgid "Remove this page from your system completely." +msgstr "Az oldal teljes eltávolítása a rendszerből." +msgid "This is your site home page." +msgstr "Ez a webhely kezdőlapja." +msgid "This page is set to become your site home page." +msgstr "Az oldal a webhely kezdőlapjának lett beállítva." +msgid "Accessible only if @conditions." +msgstr "Hozzáférés csak ha @conditions." +msgid "No menu entry." +msgstr "Nincs menü bejegyzés." +msgid "Normal menu entry." +msgstr "Normál menü bejegyzés." +msgid "Menu tab." +msgstr "Menü fül." +msgid "Default menu tab." +msgstr "Alapértelmezett menü fül." +msgid "Title: %title." +msgstr "Cím: %title." +msgid "Parent title: %title." +msgstr "Szülő címe: %title." +msgid "Menu block: %title." +msgstr "Menüblokk: %title." +msgid "Taxonomy term template" +msgstr "Taxonómia kifejezés sablon" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a taxonómia kifejezések <em>taxonomy/term/%term</em> " +"oldalon történő megjelenítésekor. Ha lett változat hozzáadva, a " +"szótár vagy a felhasználói hozzáférés kiválasztási " +"feltételek használhatóak arra, hogy eltérő megjelenítések " +"legyenek biztosítva a taxonómia kifejezéshez és a kapcsolódó " +"tartalmakhoz. Ha nincs kiválasztott változat, az alapértelmezett " +"Drupal taxonómia kifejezés képernyő lesz használva. Ennek az " +"oldalnak csak a taxonomy/term/%term oldalon ténylegesen " +"megjelenített elemekre van hatása. Néhány taxonómia " +"kifejezésnek, mint amilyen a Fórumok, saját, máshol található " +"képernyőjük van. Továbbá meg kell jegyezni, hogy a pathauto " +"használatakor, az álnevek valahova máshova helyezhetik a taxonómia " +"kifejezéseket, de amennyire a Drupal érintett, megtalálhatóak a " +"taxonomy/term/%term oldalakon." +msgid "Update settings specific to the taxonomy term view." +msgstr "" +"Taxonómia kifejezés megtekintésére jellemző beállítások " +"frissítése." +msgid "Term(s) being viewed" +msgstr "Megtekintett kifejezések" +msgid "Term being viewed" +msgstr "Megtekintett kifejezés" +msgid "Allow multiple terms on taxonomy/term/%term" +msgstr "Több kifejezés engedélyezése itt: taxonomy/term/%term" +msgid "Single term" +msgstr "Egy kifejezés" +msgid "Multiple terms" +msgstr "Több kifejezés" +msgid "" +"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." +msgstr "" +"Alapértelmezés szerint a Drupal engedélyezi több kifejezés " +"argumentumként való használatát, vesszővel vagy összeadás " +"jellel elválasztva azokat. Ha ez egy kifejezésre van állítva, " +"akkor ez a lehetőség le lesz tiltva." +msgid "Multiple terms may be used, separated by , or +." +msgstr "Több kifejezés is használható , vagy + jellel elválasztva." +msgid "Only a single term may be used." +msgstr "Csak egy kifejezést lehet használni." +msgid "%term" +msgstr "%term" +msgid "Breadcrumb trail will contain taxonomy term hierarchy" +msgstr "A morzsasáv taxonómia kifejezés hierarchiát fog tartalmazni." +msgid "Breadcrumb trail will not contain taxonomy term hiearchy." +msgstr "A morzsasáv taxonómia kifejezés hierarchiát nem fog tartalmazni." +msgid "User profile template" +msgstr "Felhasználói profil sablon" +msgid "" +"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." +msgstr "" +"Ha ez engedélyezett, akkor felülírja a Drupal alapértelmezett " +"viselkedését a felhasználói profilok megjelenítésekor a " +"<em>user/%user</em> oldalakon. Ha lett változat hozzáadva, akkor a " +"csoportok, vagy a felhasználói hozzáférés kiválasztási " +"feltételek használhatóak arra, hogy eltérő megjelenítések " +"legyenek biztosítva a felhasználói profilokhoz. Ha nincs " +"kiválasztott változat, akkor az alapértelmezés szerinti Drupal " +"felhasználó megtekintés lesz felhasználva. Továbbá meg kell " +"jegyezni, hogy a <em>Pathauto</em> használatakor, az álnevek " +"valahova máshova is helyezhetik a tartalmat, de ami a Drupalt illeti, " +"megtalálhatóak maradnak a user/%user oldalakon." +msgid "" +"Page manager module is unable to enable node/%node/edit because some " +"other module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a " +"node/%node/edit elérési utat, mert néhány másik modul már " +"felülírta %callback segítségével." +msgid "" +"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." +msgstr "" +"A Page manager modul nem tudja felülírni a %path elérési utat, " +"mert néhány másik modul már felülírta %callback-el. A tartalom " +"szerkesztés engedélyezve lesz, de a szerkesztés elérési útja nem " +"lesz felülírva." +msgid "" +"Page manager module is unable to enable node/%node because some other " +"module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a node/%node " +"elérési utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "" +"To set this panel as your home page you must create a unique path name " +"with no % placeholders in the path. The current site home page is set " +"to %homepage." +msgstr "" +"Annak beállításához, hogy ez a panel legyen a kezdőlap, egy " +"egyedi elérési utat kell létrehozni és ebben nem szabad % " +"helykitöltőket használni. A webhely jelenlegi kezdőlapjának " +"beállítása %homepage." +msgid "" +"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." +msgstr "" +"A nem kötelező helykitöltőkkel rendelkező elérési utak nem " +"használhatóak normál menüpontkét, kivéve ha a kiválasztott " +"argumentumkezelő biztosít egy menüelemként használható " +"alapértelmezett argumentumot." +msgid "" +"Page manager module is unable to enable taxonomy/term/%term because " +"some other module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a " +"taxonomy/term/%term elérési utat, mert néhány másik modul már " +"felülírta %callback segítségével." +msgid "" +"Page manager module is unable to enable user/%user because some other " +"module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a user/%user " +"elérési utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a blogok <em>/blog</em> oldalon történő " +"megjelenítésekor. Ha nincs kiválasztott változat, az " +"alapértelmezett Drupal legfrissebb blogbejegyzések oldal fog " +"megjelenni." +msgid "" +"Page manager module is unable to enable blog because some other module " +"already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a blog elérési " +"utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "User blog" +msgstr "Felhasználói blog" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a felhasználói blogok <em>/blog/%user</em> oldalon " +"történő megjelenítésekor. Ha nincs kiválasztott változat, az " +"alapértelmezett Drupal felhasználói blog oldal lesz használva." +msgid "" +"Page manager module is unable to enable blog/%user because some other " +"module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a blog/%user " +"elérési utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "Site contact page" +msgstr "Webhely kapcsolat oldal" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a kapcsolatfelvételi oldal <em>/contact</em> oldalon " +"történő megjelenítésekor. Ha nincs kiválasztott változat, az " +"alapértelmezett Drupal kapcsolatfelvételi űrlap lesz használva." +msgid "" +"Page manager module is unable to enable contact because some other " +"module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a contact " +"elérési utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "User contact" +msgstr "Felhasználói kapcsolat" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, akkor felülírja a Drupal alapértelmezett " +"viselkedését a felhasználói kapcsolatfelvételi űrlap " +"<em>user/%user/contact</em> oldalon történő megjelenítésekor. Ha " +"nincs kiválasztott változat, akkor az alapértelmezés szerinti " +"Drupal felhasználói kapcsolatfelvételi űrlap lesz használva." +msgid "" +"Page manager module is unable to enable user/%user/contact because " +"some other module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a /%user/contact " +"elérési utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "" +"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." +msgstr "" +"Nem lehetnek nem nevesített helykitöltők (% vagy ! magában). El " +"kell nevezni a helykitöltőt a % vagy a ! után álló rövid leíró " +"szöveggel, például %user vagy %node." +msgid "All polls" +msgstr "Minden szavazás" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a szavazások <em>/poll</em> oldalon történő " +"megjelenítésekor. Ha nincs kiválasztott változat, akkor a " +"legutóbbi szavazások lesznek megjelenítve." +msgid "" +"Page manager module is unable to enable poll because some other module " +"already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a poll elérési " +"utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "" +"Page manager module is unable to enable search/@name/%menu_tail " +"because some other module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a " +"search/@name/%menu_tail elérési utat, mert néhány másik modul " +"már felülírta %callback segítségével." +msgid "Search @type" +msgstr "@type keresése" diff --git a/sites/all/modules/ctools/page_manager/plugins/tasks/user_view.inc b/sites/all/modules/ctools/page_manager/plugins/tasks/user_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..fcac5219f474b343eaf48ec77f5fe1277c54349a --- /dev/null +++ b/sites/all/modules/ctools/page_manager/plugins/tasks/user_view.inc @@ -0,0 +1,132 @@ +<?php +// $Id: user_view.inc,v 1.7 2011/01/06 00:06:18 merlinofchaos Exp $ + +/** + * @file + * Overrides the user profile display at user/%user. + * + * 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']['page callback'] == 'user_view_page' || variable_get('page_manager_override_anyway', FALSE)) { + $items['user/%user']['page callback'] = 'page_manager_user_view_page'; + $items['user/%user']['file path'] = $task['path']; + $items['user/%user']['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']['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_page($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)); + + // Build content. @todo -- this may not be right. + user_build_content($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 +// user_module_invoke('view', $array = 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/sites/all/modules/ctools/page_manager/theme/page-manager-edit-page.tpl.php b/sites/all/modules/ctools/page_manager/theme/page-manager-edit-page.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..90ed201d97d04a0f5f16e41631a3b6c43afaaa19 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/theme/page-manager-edit-page.tpl.php @@ -0,0 +1,54 @@ +<?php +// $Id: page-manager-edit-page.tpl.php,v 1.4 2010/10/11 22:18:23 sdboyer Exp $ +/** + * @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 clearfix actions"> + <?php print $operations['primary']; ?> + </div> + <?php endif; ?> + <div class="page-manager-tabs clearfix"> + <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 clearfix 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/sites/all/modules/ctools/page_manager/theme/page_manager.theme.inc b/sites/all/modules/ctools/page_manager/theme/page_manager.theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..c12dcebdc4a95badc028fb13cc539c109372aab7 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/theme/page_manager.theme.inc @@ -0,0 +1,119 @@ +<?php +// $Id: page_manager.theme.inc,v 1.9 2010/11/03 00:01:14 merlinofchaos Exp $ + +/** + * @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'); + + ctools_add_css('page-manager', 'page_manager'); + ctools_add_css('wizard'); + + $task = $vars['page']->task; + + $page = &$vars['page']; + + $vars['locked'] = ''; + $vars['changed'] = ''; + if (!empty($page->locked)) { + $vars['locked'] = theme('page_manager_lock', array('page' => $page)); + $vars['changed'] = theme('page_manager_changed', array('text' => t('Locked'), 'description' => 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', array('text' => t('New'), 'description' => 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', array('text' => t('Changed'), 'description' => 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]]; + } +} + +/** + * Turn the rearrange form into a table with tablesorting on. + */ +function theme_page_manager_handler_rearrange($vars) { + $form = &$vars['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' => render($element['title']), + 'class' => array('page-manager-handler'), + ); + + $element['weight']['#attributes']['class'][] = 'weight'; + $row[] = render($element['weight']); + + $rows[] = array('data' => $row, 'class' => array('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' => array('page-manager-handler')), + t('Weight'), + ); + + drupal_add_tabledrag('page-manager-arrange-handlers', 'order', 'sibling', 'weight'); + + $output = theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'page-manager-arrange-handlers'))); + $output .= drupal_render_children($form); + return $output; +} + +/** + * Draw the "this task is locked from editing" box. + */ +function theme_page_manager_lock($vars) { + $page = $vars['page']; + + $account = user_load($page->locked->uid); + $name = theme('username', array('account' => $account)); + $lock_age = format_interval(REQUEST_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($vars) { + $text = $vars['text']; + $description = $vars['description']; + + ctools_add_css('ctools'); + $output = '<div class="page-manager-changed" title="' . $description . '">'; + $output .= $text; + $output .= '</div>'; + + return $output; +} diff --git a/sites/all/modules/ctools/page_manager/theme/translations/page_manager-theme.hu.po b/sites/all/modules/ctools/page_manager/theme/translations/page_manager-theme.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..fa957215bc6ebdf68d3214a91109c95d957d129e --- /dev/null +++ b/sites/all/modules/ctools/page_manager/theme/translations/page_manager-theme.hu.po @@ -0,0 +1,52 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 13:23+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 "Changed" +msgstr "Módosított" +msgid "New" +msgstr "Új" +msgid "Locked" +msgstr "Zárolt" +msgid "" +"This page is being edited by another user and you cannot make changes " +"to it." +msgstr "" +"Az oldalt egy másik felhasználó szerkeszti, ezért nem lehet " +"módosítani." +msgid "" +"This page is newly created and has not yet been saved to the database. " +"It will not be available until you save it." +msgstr "" +"Ez az oldal újonnan lett létrehozva, ezért még nincs elmentve az " +"adatbázisba. Amíg ez meg nem történik, addig nem lesz elérhető." +msgid "" +"This page has been modified, but these modifications are not yet live. " +"While modifying this page, it is locked from modification by other " +"users." +msgstr "" +"Az oldal módosítva lett, de a módosítások még nem élnek. A " +"módosítás idejére ez az oldal zárolva lett más felhasználók " +"módosításai elől." +msgid "No task handlers are defined for this task." +msgstr "Ehhez a feladathoz nincsenek feladatkezelők meghatározva." +msgid "Variant" +msgstr "Változat" +msgid "" +"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>." +msgstr "" +"Ezt az oldalt !user felhasználó szerkeszti, ezért zárolva van " +"mások szerkesztése elől. A zárolás !age régi. Ide kattintva <a " +"href=\"!break\">feloldható a zárolás</a>." diff --git a/sites/all/modules/ctools/page_manager/translations/page_manager.de.po b/sites/all/modules/ctools/page_manager/translations/page_manager.de.po new file mode 100644 index 0000000000000000000000000000000000000000..c7570f168d2ab35fb74bcb97092ed98a9ac9fc89 --- /dev/null +++ b/sites/all/modules/ctools/page_manager/translations/page_manager.de.po @@ -0,0 +1,947 @@ +# $Id: page_manager.de.po,v 1.3 2009/08/29 12:13:40 hass Exp $ +# +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# panels.module,v 1.10.2.9 2007/03/15 23:13:41 merlinofchaos +# fourcol_25_25_25_25.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# threecol_33_33_33.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_25_75.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_33_66.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_38_62.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_50_50.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_62_38.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_66_33.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_75_25.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# threecol_25_50_25_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# threecol_33_34_33.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# threecol_33_34_33_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# twocol.inc,v 1.6 2006/08/22 23:54:20 merlinofchaos +# twocol_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# +msgid "" +msgstr "" +"Project-Id-Version: panels 5.x\n" +"POT-Creation-Date: 2009-08-16 20:47+0200\n" +"PO-Revision-Date: 2009-08-29 14:13+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: Alexander Hass\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" + +#: page_manager/plugins/tasks/node_edit.inc:13;14 +#, fuzzy +msgid "Node add/edit form" +msgstr "Beitragsbearbeitungsformular" + +#: page_manager/plugins/tasks/node_edit.inc:15 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:55 +msgid "Page manager module is unable to enable node/%node/edit because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:65 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:129 +msgid "Create @name" +msgstr "@name erstellen" + +#: page_manager/plugins/tasks/node_edit.inc:143 +msgid "Node being edited" +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:22;24 +msgid "Node template" +msgstr "Beitragsvorlage" + +#: page_manager/plugins/tasks/node_view.inc:25 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:66 +msgid "Page manager module is unable to enable node/%node because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:118 +msgid "Node being viewed" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:196;274 +msgid "Basic settings" +msgstr "Basiseinstellungen" + +#: page_manager/plugins/tasks/page.admin.inc:197;970;978 +msgid "Argument settings" +msgstr "Argumenteinstellungen" + +#: page_manager/plugins/tasks/page.admin.inc:198;434 +msgid "Access control" +msgstr "Zugriffskontrolle" + +#: page_manager/plugins/tasks/page.admin.inc:199 +msgid "Menu settings" +msgstr "Menüeinstellungen" + +#: page_manager/plugins/tasks/page.admin.inc:275 +msgid "A meaningless second page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:368;1359 +msgid "The name of this page. This will appear in the administrative interface to easily identify it." +msgstr "Der Titel von dieser Seite. Dieser wird zur leichteren Identifizierung in der Verwaltungsoberfläche angezeigt." + +#: page_manager/plugins/tasks/page.admin.inc:374 +#, fuzzy +msgid "Machine name" +msgstr "Maschinenlesbarer Name" + +#: page_manager/plugins/tasks/page.admin.inc:375 +msgid "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!" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:387 +msgid "A description of what this page is, does or is for, for administrative use." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:395 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:417 +msgid "Make this your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:418 +msgid "If this box is checked this page will become the site home page. Only paths that have no placeholders can be used as the site home page. The current site home page is set to %homepage." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:423 +msgid "This page is currently set to be your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:435 +msgid "Visible menu item" +msgstr "Sichtbarer Menüpunkt" + +#: page_manager/plugins/tasks/page.admin.inc:456 +msgid "Name is required." +msgstr "Der Name ist erforderlich." + +#: page_manager/plugins/tasks/page.admin.inc:463 +msgid "That name is used by another page: @page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:468 +msgid "Page name must be alphanumeric or underscores only." +msgstr "Der Seitenname darf nur alphanumerische Zeichen oder Unterstriche enthalten." + +#: page_manager/plugins/tasks/page.admin.inc:475 +msgid "That path is used by another page: @page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:483 +msgid "Path is required." +msgstr "Der Pfad ist erforderlich." + +#: page_manager/plugins/tasks/page.admin.inc:497 +msgid "You cannot have a dynamic path element after an optional path element." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:506 +msgid "You cannot have a static path element after an optional path element." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:517 +msgid "That path is already in used. This system cannot override existing paths." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:525 +msgid "That path is currently assigned to be an alias for @alias. This system cannot override existing aliases." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:530 +msgid "You cannot make this page your site home page if it uses % placeholders." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:538 +msgid "Duplicated argument %arg" +msgstr "Doppeltes Argument %arg" + +#: page_manager/plugins/tasks/page.admin.inc:543 +msgid "Invalid arg <em>%</em>. All arguments must be named with keywords." +msgstr "Ungültiges Argument <em>%</em>. Alle Argumente müssen mit Schlüsselwörtern benannt sein." + +#: page_manager/plugins/tasks/page.admin.inc:636 +#: page_manager/plugins/tasks/page.inc:680 +#: page_manager/plugins/tasks/term_view.inc:269 +msgid "No menu entry" +msgstr "Kein Menüpunkt" + +#: page_manager/plugins/tasks/page.admin.inc:637 +msgid "Normal menu entry" +msgstr "Normaler Menüpunkt" + +#: page_manager/plugins/tasks/page.admin.inc:638;700 +msgid "Menu tab" +msgstr "Menü-Reiter" + +#: page_manager/plugins/tasks/page.admin.inc:639 +msgid "Default menu tab" +msgstr "Standardmäßiger Reiter im Menü" + +#: page_manager/plugins/tasks/page.admin.inc:648 +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "Den zu verwendenden Text für den Menüpunkt eingeben, wenn dieser auf Normal oder Reiter eingestellt wird." + +#: page_manager/plugins/tasks/page.admin.inc:658 +msgid "Warning: Changing this item's menu will not work reliably in Drupal 6.4 or earlier. Please upgrade your copy of Drupal at !url." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:668 +#: page_manager/plugins/tasks/page.inc:171;685 +#: page_manager/plugins/tasks/term_view.inc:272 +msgid "Menu" +msgstr "Menü" + +#: page_manager/plugins/tasks/page.admin.inc:672;722 +msgid "Insert item into an available menu." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:683 +msgid "Menu selection requires the activation of menu module." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:690 +msgid "The lower the weight the higher/further left it will appear." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:698 +msgid "Parent menu item" +msgstr "Übergeordneter Menüpunkt" + +#: page_manager/plugins/tasks/page.admin.inc:700 +msgid "Already exists" +msgstr "Schon vorhanden" + +#: page_manager/plugins/tasks/page.admin.inc:700 +msgid "Normal menu item" +msgstr "Normaler Menüpunkt" + +#: page_manager/plugins/tasks/page.admin.inc:702 +msgid "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>." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:707 +msgid "Parent item title" +msgstr "Titel des übergeordneten Menüpunktes" + +#: page_manager/plugins/tasks/page.admin.inc:710 +msgid "If creating a parent menu item, enter the title of the item." +msgstr "Einen Titel für den Menüpunkt eingeben, wenn ein übergeordneter Menüpunkt erstellt wird." + +#: page_manager/plugins/tasks/page.admin.inc:718 +msgid "Parent item menu" +msgstr "Übergeordneter Menüpunkt" + +#: page_manager/plugins/tasks/page.admin.inc:735 +msgid "Tab weight" +msgstr "Reiterreihenfolge" + +#: page_manager/plugins/tasks/page.admin.inc:739 +msgid "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." +msgstr "Die Reihenfolge des Reiters eingeben, wenn der übergeordnete Menüpunkt ein Reiter ist. Umso niedriger die Zahl ist, desto weiter links wird er angezeigt." + +#: page_manager/plugins/tasks/page.admin.inc:774 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:807 +msgid "Access rules are used to test if the page is accessible and any menu items associated with it are visible." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:848 +msgid "No context assigned" +msgstr "Kein Kontext zugewiesen" + +#: page_manager/plugins/tasks/page.admin.inc:872 +msgid "Change" +msgstr "Ändern" + +#: page_manager/plugins/tasks/page.admin.inc:889 +#: page_manager/plugins/tasks/page.inc:143 +#: page_manager/plugins/tasks/term_view.inc:50;65 +msgid "Settings" +msgstr "Einstellungen" + +#: page_manager/plugins/tasks/page.admin.inc:902 +msgid "Argument" +msgstr "Argument" + +#: page_manager/plugins/tasks/page.admin.inc:903 +msgid "Position in path" +msgstr "Position im Pfad" + +#: page_manager/plugins/tasks/page.admin.inc:904 +msgid "Context assigned" +msgstr "Kontext wurde zugewiesen" + +#: page_manager/plugins/tasks/page.admin.inc:923 +msgid "The path %path has no arguments to configure." +msgstr "Der Pfad %path enthält keine konfigurierbaren Argumente." + +#: page_manager/plugins/tasks/page.admin.inc:957 +msgid "Invalid keyword." +msgstr "Ungültiges Schlüsselwort." + +#: page_manager/plugins/tasks/page.admin.inc:969 +msgid "Change context type" +msgstr "Kontexttyp ändern." + +#: page_manager/plugins/tasks/page.admin.inc:974 +msgid "Change argument" +msgstr "Argument ändern" + +#: page_manager/plugins/tasks/page.admin.inc:1080 +msgid "No context selected" +msgstr "Kein Kontext ausgewählt" + +#: page_manager/plugins/tasks/page.admin.inc:1163 +msgid "Error: missing argument." +msgstr "Fehler: Fehlendes Argument" + +#: page_manager/plugins/tasks/page.admin.inc:1176 +msgid "Context identifier" +msgstr "Kontext Bezeichner" + +#: page_manager/plugins/tasks/page.admin.inc:1177 +msgid "This is the title of the context used to identify it later in the administrative process. This will never be shown to a user." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1183 +msgid "Error: missing or invalid argument plugin %argument." +msgstr "Fehler: Fehlendes oder ungültiges Argument-Plugin %argument." + +#: page_manager/plugins/tasks/page.admin.inc:1231 +msgid "Import page" +msgstr "Import-Seite" + +#: page_manager/plugins/tasks/page.admin.inc:1234;1352 +msgid "Page name" +msgstr "Seiten-Name" + +#: page_manager/plugins/tasks/page.admin.inc:1235 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1241 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1246 +msgid "Allow overwrite of an existing page" +msgstr "Überschreiben einer vorhanden Seite zulassen" + +#: page_manager/plugins/tasks/page.admin.inc:1247 +msgid "If the name you selected already exists in the database, this page will be allowed to overwrite the existing page." +msgstr "Sollte der ausgewähle Namen in der Datenbank schon vorhanden sein, kann die vorhandene Seite überschrieben werden." + +#: page_manager/plugins/tasks/page.admin.inc:1252 +msgid "Paste page code here" +msgstr "Seiten-Code hier einfügen" + +#: page_manager/plugins/tasks/page.admin.inc:1258 +msgid "Import" +msgstr "Importieren" + +#: page_manager/plugins/tasks/page.admin.inc:1274 +msgid "No handler found." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1276 +msgid "Unable to get a page from the import. Errors reported: @errors" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1287 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1353 +#, fuzzy +msgid "Enter the name to the new page It must be unique and contain only alphanumeric characters and underscores." +msgstr "Einen einzigartigen Namen für diese Panel-Ansicht eingeben. Dieser darf nur Buchstaben und Zahlen enthalten." + +#: page_manager/plugins/tasks/page.admin.inc:1367 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1373 +msgid "Clone variants" +msgstr "Varianten duplizieren" + +#: page_manager/plugins/tasks/page.admin.inc:1374 +msgid "If checked all variants associated with the page will be cloned as well. If not checked the page will be cloned without variants." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1482 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1485 +msgid "Are you sure you want to delete this page? Deleting a page cannot be undone." +msgstr "Soll diese Seite wirklich gelöscht werden? Das Löschen einer Seite kann nicht rückgängig gemacht werden." + +#: page_manager/plugins/tasks/page.admin.inc:1508 +msgid "The page has been deleted." +msgstr "Die Seite wurde gelöscht." + +#: page_manager/plugins/tasks/page.admin.inc:1512 +msgid "The page has been reverted." +msgstr "Die Seite wurde zurückgesetzt." + +#: page_manager/plugins/tasks/page.inc:22 +msgid "Custom pages" +msgstr "Benutzerdefinierte Seiten" + +#: page_manager/plugins/tasks/page.inc:23 +msgid "Administrator created pages that have a URL path, access control and entries in the Drupal menu system." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:39 +msgid "Create a new page" +msgstr "Neue Seite erstellen" + +#: page_manager/plugins/tasks/page.inc:150 +#: page_manager/plugins/tasks/term_view.inc:68 +msgid "Basic" +msgstr "Basis" + +#: page_manager/plugins/tasks/page.inc:151 +#: page_manager/plugins/tasks/term_view.inc:69 +msgid "Edit name, path and other basic settings for the page." +msgstr "Den Namen, Pfad und andere Basiseinstellungen für die Seite bearbeiten." + +#: page_manager/plugins/tasks/page.inc:159 +msgid "Set up contexts for the arguments on this page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:165;650 +#: page_manager/plugins/tasks/term_view.inc:264 +msgid "Access" +msgstr "Zugriff" + +#: page_manager/plugins/tasks/page.inc:166 +msgid "Control what users can access this page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:172 +msgid "Provide this page a visible menu or a menu tab." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:178 +msgid "Make a copy of this page" +msgstr "Eine Kopie dieser Seite erstellen" + +#: page_manager/plugins/tasks/page.inc:183 +msgid "Export this page as code that can be imported or embedded into a module." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:189 +msgid "Remove all changes to this page and revert to the version in code." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:196 +msgid "Remove this page from your system completely." +msgstr "" + +# Better do not translate CSS class names +#: page_manager/plugins/tasks/page.inc:574;589;629;650;685 +#: page_manager/plugins/tasks/term_view.inc:258;264;272;285;298 +#, fuzzy +msgid "page-summary-label" +msgstr "page-summary-label" + +# Better do not translate CSS class names +#: page_manager/plugins/tasks/page.inc:575;590;616;630;651;686 +#: page_manager/plugins/tasks/term_view.inc:259;265;273;286;299 +#, fuzzy +msgid "page-summary-data" +msgstr "page-summary-data" + +# Better do not translate CSS class names +#: page_manager/plugins/tasks/page.inc:576;591;617;631;652;687 +#: page_manager/plugins/tasks/term_view.inc:260;266;274;287;300 +#, fuzzy +msgid "page-summary-operation" +msgstr "page-summary-operation" + +#: page_manager/plugins/tasks/page.inc:589 +msgid "Status" +msgstr "Status" + +#: page_manager/plugins/tasks/page.inc:608 +msgid "This is your site home page." +msgstr "Dies ist die Startseite der Website." + +#: page_manager/plugins/tasks/page.inc:611 +msgid "This page is set to become your site home page." +msgstr "Diese Seite ist als Startseite der Website eingestellt." + +#: page_manager/plugins/tasks/page.inc:641 +msgid "Accessible only if @conditions." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:644 +#: page_manager/plugins/tasks/term_view.inc:265 +msgid "This page is publicly accessible." +msgstr "Die Seite ist öffentlich erreichbar." + +#: page_manager/plugins/tasks/page.inc:656 +msgid "No menu entry." +msgstr "Kein Menüpunkt." + +#: page_manager/plugins/tasks/page.inc:657 +msgid "Normal menu entry." +msgstr "Normaler Menüpunkt." + +#: page_manager/plugins/tasks/page.inc:658 +msgid "Menu tab." +msgstr "Menü-Reiter." + +#: page_manager/plugins/tasks/page.inc:659 +msgid "Default menu tab." +msgstr "Standardmäßiger Reiter im Menü." + +#: page_manager/plugins/tasks/page.inc:665 +msgid "Title: %title." +msgstr "Titel: %title." + +#: page_manager/plugins/tasks/page.inc:668 +msgid "Parent title: %title." +msgstr "Übergeordneter Titel: %title." + +#: page_manager/plugins/tasks/page.inc:673 +msgid "Menu block: %title." +msgstr "Menüblock: %title." + +#: page_manager/plugins/tasks/term_view.inc:23;24 +#, fuzzy +msgid "Taxonomy term template" +msgstr "Taxonomie-Begriff-Vorlage" + +#: page_manager/plugins/tasks/term_view.inc:25 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:51 +msgid "Update settings specific to the taxonomy term view." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:101 +msgid "Page manager module is unable to enable taxonomy/term/%term because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:161 +msgid "Term(s) being viewed" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:161 +msgid "Term being viewed" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:169 +msgid "Depth" +msgstr "Tiefe" + +#: page_manager/plugins/tasks/term_view.inc:224 +msgid "Allow multiple terms on taxonomy/term/%term" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:225 +msgid "Single term" +msgstr "Einzellner Begriff" + +#: page_manager/plugins/tasks/term_view.inc:225 +msgid "Multiple terms" +msgstr "Mehrere Begriffe" + +#: page_manager/plugins/tasks/term_view.inc:226 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:278 +msgid "Multiple terms may be used, separated by , or +." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:281 +msgid "Only a single term may be used." +msgstr "Nur ein einzelner Begriff kann verwendet werden." + +#: page_manager/plugins/tasks/term_view.inc:285 +msgid "%term" +msgstr "%term" + +#: page_manager/plugins/tasks/term_view.inc:291 +msgid "Breadcrumb trail will contain taxonomy term hierarchy" +msgstr "Die Pfadnavigation wird die Taxonomie-Begriffs-Hierarchie enthalten" + +#: page_manager/plugins/tasks/term_view.inc:294 +msgid "Breadcrumb trail will not contain taxonomy term hiearchy." +msgstr "Die Pfadnavigation wird die Taxonomie-Begriffs-Hierarchie nicht enthalten." + +#: page_manager/plugins/tasks/term_view.inc:298 +msgid "Breadcrumb" +msgstr "Pfadnavigation" + +#: page_manager/plugins/tasks/user_view.inc:12;13 +#, fuzzy +msgid "User profile template" +msgstr "Benutzer-Profil-Vorlage" + +#: page_manager/plugins/tasks/user_view.inc:14 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/user_view.inc:56 +msgid "Page manager module is unable to enable user/%user because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/user_view.inc:97 +msgid "User being viewed" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:42 +msgid "Locked" +msgstr "Gesperrt" + +#: page_manager/theme/page_manager.theme.inc:42 +msgid "This page is being edited by another user and you cannot make changes to it." +msgstr "An dieser Seite können derzeit keine Änderungen vorgenommen werden, da diese Seite von einem anderen Benutzer bearbeitet wird." + +#: page_manager/theme/page_manager.theme.inc:45 +msgid "New" +msgstr "Neu" + +# Rewrite second sentence +#: page_manager/theme/page_manager.theme.inc:45 +#, fuzzy +msgid "This page is newly created and has not yet been saved to the database. It will not be available until you save it." +msgstr "Diese Seite wurde neu erstellt und noch nicht in der Datenbank gespeichert. Sie ist nicht verfügbar, solange sie nicht gespeichert wurde." + +#: page_manager/theme/page_manager.theme.inc:48 +msgid "Changed" +msgstr "Geändert" + +#: page_manager/theme/page_manager.theme.inc:48 +msgid "This page has been modified, but these modifications are not yet live. While modifying this page, it is locked from modification by other users." +msgstr "Diese Seite wurde geändert, aber die Änderungen sind noch nicht Live. Während der Änderung dieser Seite, wird diese für die Änderung durch andere Benutzer gesperrt." + +#: page_manager/theme/page_manager.theme.inc:98 +msgid "No task handlers are defined for this task." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:102 +msgid "Variant" +msgstr "Variante" + +#: page_manager/theme/page_manager.theme.inc:124 +msgid "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>." +msgstr "" + +#: page_manager/page_manager.admin.inc:34;278 +msgid "Reset" +msgstr "Zurücksetzen" + +#: page_manager/page_manager.admin.inc:71;249 +msgid "Name" +msgstr "Name" + +#: page_manager/page_manager.admin.inc:145 +msgid "System" +msgstr "System" + +#: page_manager/page_manager.admin.inc:215 +msgid "<All>" +msgstr "<Alle>" + +#: page_manager/page_manager.admin.inc:240 +msgid "Search" +msgstr "Suchen" + +#: page_manager/page_manager.admin.inc:245 +msgid "Sort by" +msgstr "Sortieren nach" + +#: page_manager/page_manager.admin.inc:247 +msgid "Enabled, title" +msgstr "Aktiviert, Titel" + +#: page_manager/page_manager.admin.inc:259 +msgid "Order" +msgstr "Reihenfolge" + +#: page_manager/page_manager.admin.inc:261 +msgid "Up" +msgstr "Nach oben" + +#: page_manager/page_manager.admin.inc:262 +msgid "Down" +msgstr "Nach unten" + +#: page_manager/page_manager.admin.inc:271 +msgid "Apply" +msgstr "Anwenden" + +#: page_manager/page_manager.admin.inc:451;643 +msgid "Summary" +msgstr "Zusammenfassung" + +#: page_manager/page_manager.admin.inc:452 +msgid "Get a summary of the information about this page." +msgstr "Eine Zusammenfassung der Information über diese Seite anzeigen." + +#: page_manager/page_manager.admin.inc:505 +msgid "Activate this page so that it will be in use in your system." +msgstr "Diese Seite aktivieren, damit diese im System verwendet wird." + +#: page_manager/page_manager.admin.inc:518 +msgid "De-activate this page. The data will remain but the page will not be in use on your system." +msgstr "Diese Seite deaktivieren. Die Daten werden behalten, aber die Seite wird auf dem System nicht mehr verwendet." + +#: page_manager/page_manager.admin.inc:529 +msgid "Add variant" +msgstr "Variante hinzufügen" + +#: page_manager/page_manager.admin.inc:530 +msgid "Add a new variant to this page." +msgstr "Eine neue Variante zu dieser Seite hinzufügen." + +#: page_manager/page_manager.admin.inc:535;568 +msgid "Create variant" +msgstr "Variante erstellen" + +#: page_manager/page_manager.admin.inc:540 +msgid "Import variant" +msgstr "Variante importieren" + +#: page_manager/page_manager.admin.inc:541 +msgid "Add a new variant to this page from code exported from another page." +msgstr "Aus exportiertem Code einer anderen Seite, eine neue Variante zu dieser Seite hinzufügen." + +#: page_manager/page_manager.admin.inc:547 +msgid "Reorder variants" +msgstr "Varianten neu sortieren" + +#: page_manager/page_manager.admin.inc:549 +msgid "Change the priority of the variants to ensure that the right one gets selected." +msgstr "" + +#: page_manager/page_manager.admin.inc:560 +msgid "Configure a newly created variant prior to actually adding it to the page." +msgstr "" + +#: page_manager/page_manager.admin.inc:587;592 +msgid "Break lock" +msgstr "Sperre aufheben" + +#: page_manager/page_manager.admin.inc:588 +msgid "Break the lock on this page so that you can edit it." +msgstr "Die Sperre auf diese Seite aufheben, damit diese bearbeitet werden kann." + +#: page_manager/page_manager.admin.inc:611 +msgid "Variants" +msgstr "Varianten" + +#: page_manager/page_manager.admin.inc:636 +msgid "Variant operations" +msgstr "Varianten-Operationen" + +#: page_manager/page_manager.admin.inc:644 +msgid "Get a summary of the information about this variant." +msgstr "Eine Zusammenfassung der Information über diese Variante anzeigen." + +#: page_manager/page_manager.admin.inc:659 +msgid "Make an exact copy of this variant." +msgstr "Eine genaue Kopie dieser Variante erstellen." + +#: page_manager/page_manager.admin.inc:664 +msgid "Export this variant into code to import into another page." +msgstr "Diese Variante in Code exportieren, damit diese in eine andere Seite importiert werden kann." + +#: page_manager/page_manager.admin.inc:670 +msgid "Remove all changes to this variant and revert to the version in code." +msgstr "" + +#: page_manager/page_manager.admin.inc:680 +msgid "Remove this variant from the page completely." +msgstr "Diese Variante vollständig aus der Seite entfernen." + +#: page_manager/page_manager.admin.inc:690 +msgid "Activate this variant so that it will be in use in your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:701 +msgid "De-activate this variant. The data will remain but the variant will not be in use on your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:713 +msgid "No variants" +msgstr "Keine Varianten" + +#: page_manager/page_manager.admin.inc:907 +msgid "This operation trail does not exist." +msgstr "" + +#: page_manager/page_manager.admin.inc:924 +msgid "The page has been updated. Changes will not be permanent until you save." +msgstr "" + +#: page_manager/page_manager.admin.inc:941 +#, fuzzy +msgid "Unable to update changes due to lock." +msgstr "Die Änderungen konnten aufgrund einer Sperre nicht aktualisiert werden." + +#: page_manager/page_manager.admin.inc:1091 +msgid "This setting contains unsaved changes." +msgstr "Diese Einstellung enthält nicht gespeicherte Änderungen." + +#: page_manager/page_manager.admin.inc:1149 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1180 +msgid "All pending changes have been discarded, and the page is now unlocked." +msgstr "" + +#: page_manager/page_manager.admin.inc:1231 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1296 +msgid "Administrative title of this variant. If you leave blank it will be automatically assigned." +msgstr "Administrativer Titel dieser Variante. Solllte dieser leer gelassen werden, wird er automatisch zugewiesen." + +#: page_manager/page_manager.admin.inc:1301 +msgid "Variant type" +msgstr "Variantentyp" + +#: page_manager/page_manager.admin.inc:1310 +msgid "Optional features" +msgstr "Optionale Funktionen" + +#: page_manager/page_manager.admin.inc:1312 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1340;1496 +msgid "Variant name" +msgstr "Varianten-Name" + +#: page_manager/page_manager.admin.inc:1341;1497 +msgid "Enter the name of the new variant." +msgstr "Den Namen einer neuen Variante eingeben." + +#: page_manager/page_manager.admin.inc:1346 +msgid "Paste variant code here" +msgstr "Varianten-Code hier einfügen" + +#: page_manager/page_manager.admin.inc:1363 +msgid "No variant found." +msgstr "Keine Variante gefunden" + +#: page_manager/page_manager.admin.inc:1366 +msgid "Unable to get a variant from the import. Errors reported: @errors" +msgstr "" + +#: page_manager/page_manager.admin.inc:1454 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1457 +msgid "Are you sure you want to delete this variant? This deletion will not be made permanent until you click Save." +msgstr "" + +#: page_manager/page_manager.admin.inc:1523 +msgid "This variant is currently disabled. Enabling it will make it available in your system. This will not take effect until you save this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:1542 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1574 +msgid "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?" +msgstr "" + +#: page_manager/page_manager.admin.inc:1586 +msgid "The lock has been cleared and all changes discarded. You may now make changes to this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:1594 +msgid "Enabling this page will immediately make it available in your system (there is no need to wait for a save.)" +msgstr "" + +#: page_manager/page_manager.admin.inc:1621 +msgid "Disabling this page will immediately make it unavailable in your system (there is no need to wait for a save.)" +msgstr "" + +#: page_manager/page_manager.admin.inc:1677 +msgid "This page has no variants and thus no output of its own." +msgstr "" + +#: page_manager/page_manager.admin.inc:1682 +msgid "Add a new variant" +msgstr "Neue Variante hinzufügen" + +#: page_manager/page_manager.admin.inc:1700 +msgid "Unable to disable due to lock." +msgstr "Konnte wegen Sperre nicht deaktiviert werden." + +#: page_manager/page_manager.admin.inc:1703 +msgid "Unable to enable due to lock." +msgstr "Konnte wegen Sperre nicht aktiviert werden." + +#: page_manager/page_manager.module:42 +msgid "use page manager" +msgstr "Seiten-Manager verwenden" + +#: page_manager/page_manager.module:42 +msgid "administer page manager" +msgstr "Seiten-Manager verwalten" + +#: page_manager/page_manager.module:66 +msgid "Pages" +msgstr "Seiten" + +#: page_manager/page_manager.module:67 +msgid "Add, edit and remove overridden system pages and user defined pages from the system." +msgstr "" + +#: page_manager/page_manager.module:72 +msgid "List" +msgstr "Alle anzeigen" + +#: page_manager/page_manager.module:0 +msgid "page_manager" +msgstr "page_manager" + +#: page_manager/page_manager.install:222 +msgid "Panel" +msgstr "Panel" + +#: page_manager/page_manager.info:0 +msgid "Page manager" +msgstr "Seiten-Manager" + +#: page_manager/page_manager.info:0 +msgid "Provides a UI and API to manage pages within the site." +msgstr "" + diff --git a/sites/all/modules/ctools/page_manager/translations/page_manager.fr.po b/sites/all/modules/ctools/page_manager/translations/page_manager.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..dbe58aa15c8b4f68e100618fe8a3301e55071a0d --- /dev/null +++ b/sites/all/modules/ctools/page_manager/translations/page_manager.fr.po @@ -0,0 +1,1091 @@ +# $Id: page_manager.fr.po,v 1.1 2009/08/16 20:10:09 hass Exp $ +# +# French translation of Drupal (general) +# Copyright 2009 Jérémy Chatard <jchatard@breek.fr> +# Generated from files: +# page_manager.admin.inc,v 1.25 2009/08/13 22:24:02 merlinofchaos +# page.admin.inc,v 1.16 2009/08/07 23:40:39 merlinofchaos +# page.inc,v 1.16 2009/08/13 23:35:26 merlinofchaos +# term_view.inc,v 1.5 2009/08/04 21:43:06 merlinofchaos +# page_manager.module,v 1.15 2009/08/09 16:25:02 merlinofchaos +# page_manager.install,v 1.7 2009/07/12 11:32:30 sdboyer +# page_manager.info,v 1.2 2009/07/12 18:11:58 merlinofchaos +# node_edit.inc,v 1.3 2009/08/04 21:43:06 merlinofchaos +# node_view.inc,v 1.4 2009/08/04 21:43:06 merlinofchaos +# theme/page_manager.theme.inc: n/a +# user_view.inc,v 1.3 2009/08/04 21:43:06 merlinofchaos +# +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-08-15 10:56+0200\n" +"PO-Revision-Date: 2009-08-16 10:38+0100\n" +"Last-Translator: Jérémy Chatard <jchatard@breek.fr>\n" +"Language-Team: French <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" + +#: page_manager.admin.inc:34;278 +msgid "Reset" +msgstr "Réinitialiser" + +#: page_manager.admin.inc:70;219;251 +#: plugins/tasks/page.admin.inc:633 +msgid "Type" +msgstr "Type" + +#: page_manager.admin.inc:71;249 +msgid "Name" +msgstr "Nom" + +#: page_manager.admin.inc:72;248;1295 +#: plugins/tasks/page.admin.inc:645 +msgid "Title" +msgstr "Titre" + +#: page_manager.admin.inc:73;250 +#: plugins/tasks/page.admin.inc:394;1240;1366 +#: plugins/tasks/page.inc:629 +#: plugins/tasks/term_view.inc:258 +msgid "Path" +msgstr "Chemin" + +#: page_manager.admin.inc:74;226;252 +#: plugins/tasks/page.inc:46;574 +msgid "Storage" +msgstr "Stockage" + +#: page_manager.admin.inc:77 +#: plugins/tasks/page.admin.inc:905 +msgid "Operations" +msgstr "Opérations" + +#: page_manager.admin.inc:145 +msgid "System" +msgstr "Système" + +#: page_manager.admin.inc:153 +#: plugins/tasks/page.inc:216 +msgid "In code" +msgstr "Dans le code" + +#: page_manager.admin.inc:171 +#: page_manager.module:79 +#: plugins/tasks/page.inc:605;647;683 +msgid "Edit" +msgstr "Modifier" + +#: page_manager.admin.inc:179;504;510;689;694 +#: plugins/tasks/page.inc:580 +msgid "Enable" +msgstr "Activer" + +#: page_manager.admin.inc:185;517;523;700;705 +#: plugins/tasks/page.inc:584 +msgid "Disable" +msgstr "Désactiver" + +#: page_manager.admin.inc:215 +msgid "<All>" +msgstr "<Tout>" + +#: page_manager.admin.inc:233;234 +#: plugins/tasks/page.inc:585 +msgid "Enabled" +msgstr "Activé" + +#: page_manager.admin.inc:234 +#: plugins/tasks/page.inc:581 +msgid "Disabled" +msgstr "Désactivé" + +#: page_manager.admin.inc:240 +msgid "Search" +msgstr "Recherche" + +#: page_manager.admin.inc:245 +msgid "Sort by" +msgstr "Trier par" + +#: page_manager.admin.inc:247 +msgid "Enabled, title" +msgstr "Activées, titre" + +#: page_manager.admin.inc:259 +msgid "Order" +msgstr "Ordre" + +#: page_manager.admin.inc:261 +msgid "Up" +msgstr "Haut" + +#: page_manager.admin.inc:262 +msgid "Down" +msgstr "Bas" + +#: page_manager.admin.inc:271 +msgid "Apply" +msgstr "Appliquer" + +#: page_manager.admin.inc:451;643 +msgid "Summary" +msgstr "Résumé" + +#: page_manager.admin.inc:452 +msgid "Get a summary of the information about this page." +msgstr "Obtenir un résumé des informations sur cette page." + +#: page_manager.admin.inc:505 +msgid "Activate this page so that it will be in use in your system." +msgstr "Activez cette page afin qu'elle soit utilisée dans votre système." + +#: page_manager.admin.inc:518 +msgid "De-activate this page. The data will remain but the page will not be in use on your system." +msgstr "Désactiver cette page. Les données seront conservées mais la page ne sera plus utilisée par votre système." + +#: page_manager.admin.inc:529 +msgid "Add variant" +msgstr "Ajouter une variante" + +#: page_manager.admin.inc:530 +msgid "Add a new variant to this page." +msgstr "Ajouter une nouvelle variante de cette page." + +#: page_manager.admin.inc:535;568 +msgid "Create variant" +msgstr "Créer la variante" + +#: page_manager.admin.inc:540 +msgid "Import variant" +msgstr "Importer une variante" + +#: page_manager.admin.inc:541 +msgid "Add a new variant to this page from code exported from another page." +msgstr "Ajouter une variante de cette page à partir de code exporté d'une autre page." + +#: page_manager.admin.inc:547 +msgid "Reorder variants" +msgstr "Ré-ordonner les variantes" + +#: page_manager.admin.inc:549 +msgid "Change the priority of the variants to ensure that the right one gets selected." +msgstr "Changer la priorité des variantes pour s'assurer que la sélection s'opère de façon correcte." + +#: page_manager.admin.inc:559 +msgid "Configure" +msgstr "Configurer" + +#: page_manager.admin.inc:560 +msgid "Configure a newly created variant prior to actually adding it to the page." +msgstr "Configurer une nouvelle variante avant de l'ajouter réellement à la page." + +#: page_manager.admin.inc:587;592 +msgid "Break lock" +msgstr "Faire sauter le verrou" + +#: page_manager.admin.inc:588 +msgid "Break the lock on this page so that you can edit it." +msgstr "Casser le verrou de cette page afin de pouvoir l'éditer." + +#: page_manager.admin.inc:611 +msgid "Variants" +msgstr "Variantes" + +#: page_manager.admin.inc:636 +msgid "Variant operations" +msgstr "Opérations sur les variantes" + +#: page_manager.admin.inc:644 +msgid "Get a summary of the information about this variant." +msgstr "Obtenir un résumé des informations de cette variante." + +#: page_manager.admin.inc:658 +#: plugins/tasks/page.admin.inc:1380 +#: plugins/tasks/page.inc:177 +msgid "Clone" +msgstr "Cloner" + +#: page_manager.admin.inc:659 +msgid "Make an exact copy of this variant." +msgstr "Faire une copie exacte de cette variante." + +#: page_manager.admin.inc:663 +#: plugins/tasks/page.inc:182 +msgid "Export" +msgstr "Exporter" + +#: page_manager.admin.inc:664 +msgid "Export this variant into code to import into another page." +msgstr "Exporter cette variante sous forme de code pour l'importer dans une autre page." + +#: page_manager.admin.inc:669;673 +#: plugins/tasks/page.admin.inc:1495 +#: plugins/tasks/page.inc:188 +msgid "Revert" +msgstr "Revenir" + +#: page_manager.admin.inc:670 +msgid "Remove all changes to this variant and revert to the version in code." +msgstr "Supprimer tous les changements apportés à cette variante et revenir à la version fournie par le code source." + +#: page_manager.admin.inc:679;683 +#: plugins/tasks/page.admin.inc:1495 +#: plugins/tasks/page.inc:195 +msgid "Delete" +msgstr "Supprimer" + +#: page_manager.admin.inc:680 +msgid "Remove this variant from the page completely." +msgstr "Supprimer cette variante de la page." + +#: page_manager.admin.inc:690 +msgid "Activate this variant so that it will be in use in your system." +msgstr "Activer cette variante afin qu'elle soit utilisée par votre système." + +#: page_manager.admin.inc:701 +msgid "De-activate this variant. The data will remain but the variant will not be in use on your system." +msgstr "Désactiver cette variante. Les données seront conservées mais la variante ne sera plus utilisée par votre système." + +#: page_manager.admin.inc:713 +msgid "No variants" +msgstr "Aucune variante" + +#: page_manager.admin.inc:795 +msgid "Update" +msgstr "Mise à jour" + +#: page_manager.admin.inc:906 +msgid "Error" +msgstr "Erreur" + +#: page_manager.admin.inc:907 +#, fuzzy +msgid "This operation trail does not exist." +msgstr "Cette opération n'existe pas." + +#: page_manager.admin.inc:924 +msgid "The page has been updated. Changes will not be permanent until you save." +msgstr "Cette page a été mise à jour. Les changements ne seront pas sauvegardés tant que vous n'aurez enregistré." + +#: page_manager.admin.inc:941 +msgid "Unable to update changes due to lock." +msgstr "Impossible d'appliquer les changements, un verrou est présent." + +#: page_manager.admin.inc:1091 +msgid "This setting contains unsaved changes." +msgstr "Ces paramètres contiennent des changements non sauvegardés." + +#: page_manager.admin.inc:1149 +msgid "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." +msgstr "Vous avez effectué des changements sur cette page qui ne sont pas sauvegardés. Vous devez cliquer sur Enregistrer pour sauvegarder les changements dans la base de données, ou sur Annuler pour ne pas prendre en compte ces changements. Veuillez notez que si vous avez changé les valeurs d'un formulaire, vous devez cliquer sur le bouton Mise à jour avant d'enregistrer votre page." + +#: page_manager.admin.inc:1156 +msgid "Save" +msgstr "Enregistrer" + +#: page_manager.admin.inc:1162 +msgid "Cancel" +msgstr "Annuler" + +#: page_manager.admin.inc:1180 +msgid "All pending changes have been discarded, and the page is now unlocked." +msgstr "Tous les changements ont été annulés, la page est maintenant déverrouillée." + +#: page_manager.admin.inc:1231 +msgid "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." +msgstr "Avant que cette variante ne puisse être ajoutée, elle doit être configurée. Lorsque vous avez terminé, cliquez sur \"Créer la variante\" à la fin de l'assistant pour l'ajouter à votre page." + +#: page_manager.admin.inc:1296 +msgid "Administrative title of this variant. If you leave blank it will be automatically assigned." +msgstr "Le titre administratif de cette variante. Si vous laissez ce champ vide il sera automatiquement renseigné." + +#: page_manager.admin.inc:1301 +msgid "Variant type" +msgstr "Type de variante" + +#: page_manager.admin.inc:1310 +msgid "Optional features" +msgstr "Fonctionnalités optionnelles" + +#: page_manager.admin.inc:1312 +msgid "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." +msgstr "Sélectionnez les fonctionnalités facultatives dont vous avez besoin pour quelles soient présentes dans les formulaires de configuration. Si vous ne sélectionnez pas ces options ici vous pourrez toujours les activer une fois que votre page sera créée. Si vous n'êtes pas sûr, laissez ces options décochées." + +#: page_manager.admin.inc:1340;1496 +msgid "Variant name" +msgstr "Nom de la variante" + +#: page_manager.admin.inc:1341;1497 +msgid "Enter the name of the new variant." +msgstr "Saisissez le nom de la nouvelle variante." + +#: page_manager.admin.inc:1346 +msgid "Paste variant code here" +msgstr "Collez le code de la variante ici" + +#: page_manager.admin.inc:1363 +msgid "No variant found." +msgstr "Aucune variante trouvée." + +#: page_manager.admin.inc:1366 +msgid "Unable to get a variant from the import. Errors reported: @errors" +msgstr "Impossible d'importer une variante. Rapport d'erreurs : @errors" + +#: page_manager.admin.inc:1453 +#: page_manager.module:508 +#: plugins/tasks/page.admin.inc:1481;1495;1506 +msgid "Overridden" +msgstr "Supplantée" + +#: page_manager.admin.inc:1454 +msgid "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." +msgstr "Ré-initialiser la variante va la supprimer de la base de données, la ramenant à sa variante d'origine, celle par défaut. Cette suppression ne sera effective que lorsque vous aurez cliqué sur le bouton Enregistrer." + +#: page_manager.admin.inc:1457 +msgid "Are you sure you want to delete this variant? This deletion will not be made permanent until you click Save." +msgstr "Êtes-vous sûr(e) de vouloir supprimer cette variante ? Cette suppression ne sera effective que lorsque vous aurez cliqué sur Enregistrer." + +#: page_manager.admin.inc:1523 +msgid "This variant is currently disabled. Enabling it will make it available in your system. This will not take effect until you save this page." +msgstr "Cette variante est désactivée. L'activer la rendra disponible dans votre système. Cela ne prendra effet que lorsque vous aurez enregistré cette page." + +#: page_manager.admin.inc:1542 +msgid "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." +msgstr "Cette variante est activée. La désactiver la rendra indisponible pour le système, et elle ne sera pas utilisée. Cela ne prendra effet que lorsque vous aurez enregistré cette page." + +#: page_manager.admin.inc:1574 +msgid "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?" +msgstr "Faire sauter le verrou de cet page va <strong>annuler</strong> tout changement réalisé par l'utilisateur qui a verrouillé cette page. Êtes-vous SÛR de vouloir le faire ?" + +#: page_manager.admin.inc:1586 +msgid "The lock has been cleared and all changes discarded. You may now make changes to this page." +msgstr "Le verrou a été effacé ainsi que tous les changements. Vous pouvez maintenant faire des changements sur cette page." + +#: page_manager.admin.inc:1594 +msgid "Enabling this page will immediately make it available in your system (there is no need to wait for a save.)" +msgstr "Activer cette page la rendra disponible immédiatement dans votre système (il n'y a pas besoin d'attendre pour une sauvegarde)." + +#: page_manager.admin.inc:1621 +msgid "Disabling this page will immediately make it unavailable in your system (there is no need to wait for a save.)" +msgstr "Désactiver cette page la rendra indisponible immédiatement dans votre système (il n'y a pas besoin d'attendre pour une sauvegarde)." + +#: page_manager.admin.inc:1677 +msgid "This page has no variants and thus no output of its own." +msgstr "Cette page n'a pas de variante et donc aucun sortie à générer." + +#: page_manager.admin.inc:1682 +msgid "Add a new variant" +msgstr "Ajouter une nouvelle variante" + +#: page_manager.admin.inc:1700 +msgid "Unable to disable due to lock." +msgstr "Impossible de désactiver, un verrou est présent." + +#: page_manager.admin.inc:1703 +msgid "Unable to enable due to lock." +msgstr "Impossible d'activer, un verrou est présent." + +#: page_manager.module:365 +#: plugins/tasks/page.admin.inc:1452 +msgid "Normal" +msgstr "Normal" + +#: page_manager.module:499;514 +#: plugins/tasks/page.inc:216 +msgid "Default" +msgstr "Par défaut" + +#: page_manager.module:635 +msgid "Local" +msgstr "Locale" + +#: page_manager.module:42 +msgid "use page manager" +msgstr "utiliser le gestionnaire de pages" + +#: page_manager.module:42 +msgid "administer page manager" +msgstr "administrer le gestionnaire de pages" + +#: page_manager.module:66 +msgid "Pages" +msgstr "Pages" + +#: page_manager.module:67 +msgid "Add, edit and remove overridden system pages and user defined pages from the system." +msgstr "Ajouter, modifier et supprimer des pages de surchargement et des pages définies par l'utilisateur." + +#: page_manager.module:72 +msgid "List" +msgstr "Liste" + +#: page_manager.install:222 +msgid "Panel" +msgstr "Panel" + +#: page_manager.info:0 +msgid "Page manager" +msgstr "Page manager" + +#: page_manager.info:0 +msgid "Provides a UI and API to manage pages within the site." +msgstr "Fournit une interface utilisateur et une API pour gérer les pages dans le site." + +#: page_manager.info:0 +msgid "Chaos tool suite" +msgstr "Chaos tool suite" + +#: plugins/tasks/node_edit.inc:13;14 +msgid "Node add/edit form" +msgstr "Formulaire de création/édition d'un noeud" + +#: plugins/tasks/node_edit.inc:15 +msgid "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." +msgstr "Lorsque activé, ceci surcharge le comportement par défaut de Drupal pour créer ou modifier des noeuds sur les chemins <em>node/%node/edit</em> et <em>node/add/%node_type</em>. Si vous ajouté des variantes, vous pouvez utiliser les critères de sélection tel que le type de noeud ou la langue ou les permissions pour fournir des formulaires différents pour les noeuds. Si aucune variante n'est sélectionnée, le formulaire d'édition de noeud standard de Drupal sera utilisé." + +#: plugins/tasks/node_edit.inc:55 +msgid "Page manager module is unable to enable node/%node/edit because some other module already has overridden with %callback." +msgstr "Le module Page manager est incapable d'activer node/%node/edit parce que d'autres modules l'on déjà surchargé avec %callback." + +#: plugins/tasks/node_edit.inc:65 +msgid "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." +msgstr "Le module Page manager est incapable de surcharger le chemin @path parce que d'autres modules l'on déjà surchargé avec %callback. L'édition de noeud sera activé mais le chemin d'édition ne sera pas surchargé." + +#: plugins/tasks/node_edit.inc:129 +msgid "Create @name" +msgstr "Créer '@name'" + +#: plugins/tasks/node_edit.inc:143 +msgid "Node being edited" +msgstr "Noeud en cours d'édition" + +#: plugins/tasks/node_view.inc:22;24 +msgid "Node template" +msgstr "Template du noeud" + +#: plugins/tasks/node_view.inc:25 +msgid "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." +msgstr "Lorsque activé, ceci surcharge le comportement par défaut de Drupal pour afficher les noeuds sur le chemin <em>node/%node</em>. Si vous ajoutez des variantes, vous pourrez utiliser des critères de sélection tel que le type de noeud, la langue ou les permissions pour fournir différents types d'affichage à ces noeuds. Si vous ne sélectionnez pas de variante, l'affichage par défaut de Drupal sera utilisé pour les noeuds. Cette page affecte seulement les noeuds affichés en tant que page, elle n'affectera pas les listes de noeuds ou les noeuds affichés dans d'autres endroits. Veuillez également noter que si vous utilisez Pathauto, les alias d'URLs peuvent laisser paraître qu'un noeud est affiché ailleurs, mais pour Drupal ils sont toujours sur un chemin du type node/%node." + +#: plugins/tasks/node_view.inc:66 +msgid "Page manager module is unable to enable node/%node because some other module already has overridden with %callback." +msgstr "Le module Page manager est incapable d'activer node/%node car d'autres modules l'ont déjà surchargé avec %callback." + +#: plugins/tasks/node_view.inc:118 +msgid "Node being viewed" +msgstr "Noeud en cours d'affichage" + +#: plugins/tasks/page.admin.inc:196;274 +msgid "Basic settings" +msgstr "Paramètres de base" + +#: plugins/tasks/page.admin.inc:197;970;978 +msgid "Argument settings" +msgstr "Paramètres des arguments" + +#: plugins/tasks/page.admin.inc:198;434 +msgid "Access control" +msgstr "Droits d'accès" + +#: plugins/tasks/page.admin.inc:199 +msgid "Menu settings" +msgstr "Paramètres du menu" + +#: plugins/tasks/page.admin.inc:275 +msgid "A meaningless second page" +msgstr "" + +#: plugins/tasks/page.admin.inc:367;1358 +msgid "Administrative title" +msgstr "Titre pour l'administration" + +#: plugins/tasks/page.admin.inc:368;1359 +msgid "The name of this page. This will appear in the administrative interface to easily identify it." +msgstr "Le nom de cette page. Il apparaîtra dans l'interface d'administration afin de l'identifier facilement." + +#: plugins/tasks/page.admin.inc:374 +msgid "Machine name" +msgstr "Nom machine" + +#: plugins/tasks/page.admin.inc:375 +msgid "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!" +msgstr "Le nom machine de cette page. Il doit être unique et ne doit contenir que des caractères alphanumériques et des caractères de soulignement (_). Une fois créée, vous ne pourrez pas changer cette valeur !" + +#: plugins/tasks/page.admin.inc:386 +msgid "Administrative description" +msgstr "Description pour l'administration" + +#: plugins/tasks/page.admin.inc:387 +msgid "A description of what this page is, does or is for, for administrative use." +msgstr "Une description de ce qu'est cette page, ce qu'elle fait ou est faîte pour, pour l'administration." + +#: plugins/tasks/page.admin.inc:395 +msgid "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." +msgstr "Le chemin d'URL pour accéder à cette page. Vous pouvez créer des jetons nommés pour les parties variables du chemin en utilisant la syntaxe %name pour les parties obligatoires et !name pour les parties optionnelles. Par exemple : \"node/%node/foo\", \"forum/%forum\" ou \"dashboard/!input\". Ces jetons nommés peuvent être transformés en contextes sur le formulaire d'arguments." + +#: plugins/tasks/page.admin.inc:417 +msgid "Make this your site home page." +msgstr "Définir comme page d'accueil du site." + +#: plugins/tasks/page.admin.inc:418 +msgid "If this box is checked this page will become the site home page. Only paths that have no placeholders can be used as the site home page. The current site home page is set to %homepage." +msgstr "Si vous cochez cette option, cette page deviendra la page d'accueil du site. Seuls les alias qui ne contiennent pas de caractères de remplecement peuvent être utilisés pour la page d'accueil. La page d'accueil acutelle du site est %homepage." + +#: plugins/tasks/page.admin.inc:423 +msgid "This page is currently set to be your site home page." +msgstr "Cette page est actuellement votre page d'accueil." + +#: plugins/tasks/page.admin.inc:435 +msgid "Visible menu item" +msgstr "Elément de menu visible" + +#: plugins/tasks/page.admin.inc:456 +msgid "Name is required." +msgstr "Le nom est obligatoire." + +#: plugins/tasks/page.admin.inc:463 +msgid "That name is used by another page: @page" +msgstr "Ce nom est déjà utilisé par une autre page : @page" + +#: plugins/tasks/page.admin.inc:468 +msgid "Page name must be alphanumeric or underscores only." +msgstr "Le nom d'une page ne peut contenir que des caractères alphanumériques et des caractères de soulignements (_)." + +#: plugins/tasks/page.admin.inc:475 +msgid "That path is used by another page: @page" +msgstr "Ce chemin est déjà utilisé par une autre page : @page" + +#: plugins/tasks/page.admin.inc:483 +msgid "Path is required." +msgstr "Le chemin est obligatoire" + +#: plugins/tasks/page.admin.inc:497 +msgid "You cannot have a dynamic path element after an optional path element." +msgstr "Vous ne pouvez pas utiliser de partie de chemin dynamique après une partie de chemin optionnelle." + +#: plugins/tasks/page.admin.inc:506 +msgid "You cannot have a static path element after an optional path element." +msgstr "Vous ne pouvez pas utiliser de partie de chemin statique après une partie de chemin optionnelle." + +#: plugins/tasks/page.admin.inc:517 +msgid "That path is already in used. This system cannot override existing paths." +msgstr "Ce chemin est déjà utilisé. Ce système ne peut surcharger des chemins existants." + +#: plugins/tasks/page.admin.inc:525 +msgid "That path is currently assigned to be an alias for @alias. This system cannot override existing aliases." +msgstr "Ce chemin est actuellement assigné à l'alias @alias. Ce système ne peut pas surcharger les alias existants." + +#: plugins/tasks/page.admin.inc:530 +msgid "You cannot make this page your site home page if it uses % placeholders." +msgstr "Vous ne pouvez pas faire de cette page votre page d'accueil du site si elle utilise des jetons % ." + +#: plugins/tasks/page.admin.inc:538 +msgid "Duplicated argument %arg" +msgstr "Argument dupliqué %arg" + +#: plugins/tasks/page.admin.inc:543 +msgid "Invalid arg <em>%</em>. All arguments must be named with keywords." +msgstr "Argument non valide <em>%</em>. Tous les arguments doivent être nommé avec des mots clés." + +#: plugins/tasks/page.admin.inc:636 +#: plugins/tasks/page.inc:680 +#: plugins/tasks/term_view.inc:269 +msgid "No menu entry" +msgstr "Aucune entrée de menu" + +#: plugins/tasks/page.admin.inc:637 +msgid "Normal menu entry" +msgstr "Entrée de menu normale" + +#: plugins/tasks/page.admin.inc:638;700 +msgid "Menu tab" +msgstr "Onglet de menu" + +#: plugins/tasks/page.admin.inc:639 +msgid "Default menu tab" +msgstr "Onglet de menu par défaut" + +#: plugins/tasks/page.admin.inc:648 +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "Si positionné à normal ou onglet, saisissez le texte à utiliser pour l'élément de menu." + +#: plugins/tasks/page.admin.inc:658 +msgid "Warning: Changing this item's menu will not work reliably in Drupal 6.4 or earlier. Please upgrade your copy of Drupal at !url." +msgstr "Attention : changer le menu de cet élément ne fonctionnera pas correctement avec Drupal 6.4 ou inférieur. Veuillez mettre à jour votre installation de Drupal ici !url." + +#: plugins/tasks/page.admin.inc:668 +#: plugins/tasks/page.inc:171;685 +#: plugins/tasks/term_view.inc:272 +msgid "Menu" +msgstr "Menu" + +#: plugins/tasks/page.admin.inc:672;722 +msgid "Insert item into an available menu." +msgstr "Insérer l'élément dans un menu disponible." + +#: plugins/tasks/page.admin.inc:683 +msgid "Menu selection requires the activation of menu module." +msgstr "La sélection du menu requiert l'activation du module menu." + +#: plugins/tasks/page.admin.inc:687 +#: theme/page_manager.theme.inc:103 +msgid "Weight" +msgstr "Poids" + +#: plugins/tasks/page.admin.inc:690 +msgid "The lower the weight the higher/further left it will appear." +msgstr "" + +#: plugins/tasks/page.admin.inc:698 +msgid "Parent menu item" +msgstr "Élément de menu parent" + +#: plugins/tasks/page.admin.inc:700 +msgid "Already exists" +msgstr "Existe déjà" + +#: plugins/tasks/page.admin.inc:700 +msgid "Normal menu item" +msgstr "Élément de menu normal" + +#: plugins/tasks/page.admin.inc:702 +msgid "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>." +msgstr "Lorsque vous définissez un élément de menu comme un onglet par défaut, Drupal a besoin de savoir quel sera son élément parent. Des fois le parent existera déjà, mais dans certains cas vous devez le créer. Le chemin d'un élément parent doit toujours être le même chemin avec la dernière partie supprimée, càd si le chemin de cette vue est <em>foo/bar/baz</em>, le chemin du parent doit être <em>foo/bar</em>." + +#: plugins/tasks/page.admin.inc:707 +msgid "Parent item title" +msgstr "Titre de l'élément parent" + +#: plugins/tasks/page.admin.inc:710 +msgid "If creating a parent menu item, enter the title of the item." +msgstr "Si vous créez un élément de menu parent, saisissez le titre de l'élément." + +#: plugins/tasks/page.admin.inc:718 +#, fuzzy +msgid "Parent item menu" +msgstr "Menu parent de l'élément" + +#: plugins/tasks/page.admin.inc:735 +msgid "Tab weight" +msgstr "Poids de l'onglet" + +#: plugins/tasks/page.admin.inc:739 +msgid "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." +msgstr "Si l'élément de menu parent est un onglet, saisissez le poids de l'onglet. Plus le nombre est faible, plus l'élément apparaîtra à gauche." + +#: plugins/tasks/page.admin.inc:774 +msgid "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." +msgstr "Les chemins avec des jetons obligatoires ne peuvent pas être des éléments de menu normaux à moins que le gestionnaire d'argument fournisse une valeur par défaut pour utiliser cet élément de menu." + +#: plugins/tasks/page.admin.inc:807 +msgid "Access rules are used to test if the page is accessible and any menu items associated with it are visible." +msgstr "Les règles d'accès sont utilisées pour tester si la page est accessible et rendre ou non visible les éléments de menu correspondants." + +#: plugins/tasks/page.admin.inc:848 +msgid "No context assigned" +msgstr "Aucun contexte assigné" + +#: plugins/tasks/page.admin.inc:872 +msgid "Change" +msgstr "Changer" + +#: plugins/tasks/page.admin.inc:889 +#: plugins/tasks/page.inc:143 +#: plugins/tasks/term_view.inc:50;65 +msgid "Settings" +msgstr "Paramètres" + +#: plugins/tasks/page.admin.inc:902 +msgid "Argument" +msgstr "Argument" + +#: plugins/tasks/page.admin.inc:903 +msgid "Position in path" +msgstr "Position dans le chemin" + +#: plugins/tasks/page.admin.inc:904 +msgid "Context assigned" +msgstr "Context assigné" + +#: plugins/tasks/page.admin.inc:923 +msgid "The path %path has no arguments to configure." +msgstr "Le chemin %path n'a pas d'argument à configurer" + +#: plugins/tasks/page.admin.inc:948 +msgid "Invalid object name." +msgstr "Nom d'objet non valide." + +#: plugins/tasks/page.admin.inc:957 +msgid "Invalid keyword." +msgstr "Mot clé non valide." + +#: plugins/tasks/page.admin.inc:969 +msgid "Change context type" +msgstr "Changer le type de contexte" + +#: plugins/tasks/page.admin.inc:974 +msgid "Change argument" +msgstr "Changer l'argument" + +#: plugins/tasks/page.admin.inc:1080 +msgid "No context selected" +msgstr "Pas de contexte sélectionné" + +#: plugins/tasks/page.admin.inc:1116;1136 +msgid "No context" +msgstr "Pas de contexte" + +#: plugins/tasks/page.admin.inc:1163 +msgid "Error: missing argument." +msgstr "Erreur : argument manquant." + +#: plugins/tasks/page.admin.inc:1176 +msgid "Context identifier" +msgstr "Identifiant du context" + +#: plugins/tasks/page.admin.inc:1177 +msgid "This is the title of the context used to identify it later in the administrative process. This will never be shown to a user." +msgstr "Ceci est le titre du contexte utilisé pour l'identifier plus tard dans la partie administration. Il ne sera jamais affiché à l'utilisateur." + +#: plugins/tasks/page.admin.inc:1183 +msgid "Error: missing or invalid argument plugin %argument." +msgstr "Erreur : plugin d'argument %argument manquant ou non valide." + +#: plugins/tasks/page.admin.inc:1231 +msgid "Import page" +msgstr "Importer une page" + +#: plugins/tasks/page.admin.inc:1234;1352 +msgid "Page name" +msgstr "Nom de la page" + +#: plugins/tasks/page.admin.inc:1235 +msgid "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." +msgstr "Saisissez le nom à utiliser pour cette page si il est différent de la page source. Laissez le champ vide pour utiliser le nom original de la page." + +#: plugins/tasks/page.admin.inc:1241 +msgid "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." +msgstr "Saisissez le chemin à utiliser pour cette page si il est différent de la page source. Laissez le champ vide pour utiliser le chemin original de la page." + +#: plugins/tasks/page.admin.inc:1246 +msgid "Allow overwrite of an existing page" +msgstr "Permettre l'écrasement d'une page existante" + +#: plugins/tasks/page.admin.inc:1247 +msgid "If the name you selected already exists in the database, this page will be allowed to overwrite the existing page." +msgstr "Si le nom que vous sélectionnez existe déjà dans la base de données, cette page pourra écraser celle déjà existante." + +#: plugins/tasks/page.admin.inc:1252 +msgid "Paste page code here" +msgstr "Coller le code de la page ici" + +#: plugins/tasks/page.admin.inc:1258 +msgid "Import" +msgstr "Importer" + +#: plugins/tasks/page.admin.inc:1274 +msgid "No handler found." +msgstr "Pas de gestionnaire trouvé." + +#: plugins/tasks/page.admin.inc:1276 +msgid "Unable to get a page from the import. Errors reported: @errors" +msgstr "Impossible de récupérer une page à partir de l'import. Erreurs rapportées : @erros" + +#: plugins/tasks/page.admin.inc:1287 +msgid "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." +msgstr "Ce nom de page est actuellement utilisé et verrouillé par un autre utilisateur. Vous devez <a href=\"!break\">casser le verrou</a> de cette page avant de pouvoir continuer, ou choisir un nom différent." + +#: plugins/tasks/page.admin.inc:1353 +msgid "Enter the name to the new page It must be unique and contain only alphanumeric characters and underscores." +msgstr "Entrez le nom de la nouvelle page. Il doit être unique et ne contenir que des caractères alphanumériques et des caractères de soulignements (_)." + +#: plugins/tasks/page.admin.inc:1367 +msgid "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." +msgstr "Le chemin d'URL pour accéder à cette page. Vous pouvez créer des jetons nommés pour les parties variables du chemin en utilisant la syntaxe %name pour les parties obligatoires et !name pour les parties optionnelles. Par exemple : \"node/%node/foo\", \"forum/%forum\" ou \"dashboard/!input\". Ces jetons nommés peuvent être transformés en contextes sur le formulaire d'arguments. Vous ne pouvez pas utiliser le même chemin que l'original." + +#: plugins/tasks/page.admin.inc:1373 +msgid "Clone variants" +msgstr "Cloner les variantes" + +#: plugins/tasks/page.admin.inc:1374 +msgid "If checked all variants associated with the page will be cloned as well. If not checked the page will be cloned without variants." +msgstr "Si sélectionné toutes les variantes associées à cette page seront également clonées. Si non sélectionné la page sera clonée sans ses variantes." + +#: plugins/tasks/page.admin.inc:1482 +msgid "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." +msgstr "Ré-initialiser la page va la supprimer de la base de données, la ramenant à sa version d'origine, celle par défaut. Tout changement effectué sera perdu et ne pourra être récupéré." + +#: plugins/tasks/page.admin.inc:1485 +msgid "Are you sure you want to delete this page? Deleting a page cannot be undone." +msgstr "Êtes-vous sûr de vouloir supprimer cette page ? Supprimer une page est irréversible." + +#: plugins/tasks/page.admin.inc:1508 +msgid "The page has been deleted." +msgstr "La page a été supprimée." + +#: plugins/tasks/page.admin.inc:1512 +msgid "The page has been reverted." +msgstr "La page a été réinitialisée." + +#: plugins/tasks/page.inc:22 +msgid "Custom pages" +msgstr "Pages personnalisées" + +#: plugins/tasks/page.inc:23 +msgid "Administrator created pages that have a URL path, access control and entries in the Drupal menu system." +msgstr "Des pages créées par l'administrateur qui ont une chemin (URL), un contrôle d'accès et des entrées dans le système de menu de Drupal." + +#: plugins/tasks/page.inc:39 +msgid "Create a new page" +msgstr "Créer une nouvelle page" + +#: plugins/tasks/page.inc:150 +#: plugins/tasks/term_view.inc:68 +msgid "Basic" +msgstr "Basique" + +#: plugins/tasks/page.inc:151 +#: plugins/tasks/term_view.inc:69 +msgid "Edit name, path and other basic settings for the page." +msgstr "Modifier le nom, le chemin et les paramètres de base de cette page." + +#: plugins/tasks/page.inc:158 +msgid "Arguments" +msgstr "Arguments" + +#: plugins/tasks/page.inc:159 +msgid "Set up contexts for the arguments on this page." +msgstr "Définir les contextes pour les arguments de cette page." + +#: plugins/tasks/page.inc:165;650 +#: plugins/tasks/term_view.inc:264 +msgid "Access" +msgstr "Accès" + +#: plugins/tasks/page.inc:166 +msgid "Control what users can access this page." +msgstr "Contrôler quels utilisateurs peuvent accéder à cette page." + +#: plugins/tasks/page.inc:172 +msgid "Provide this page a visible menu or a menu tab." +msgstr "Fournir à cette page un menu visible ou un onglet." + +#: plugins/tasks/page.inc:178 +msgid "Make a copy of this page" +msgstr "Créer une copie de cette page" + +#: plugins/tasks/page.inc:183 +msgid "Export this page as code that can be imported or embedded into a module." +msgstr "Exporter cette page sous forme de code qu'il sera possible d'importer ou d'encapsuler dans un module." + +#: plugins/tasks/page.inc:189 +msgid "Remove all changes to this page and revert to the version in code." +msgstr "Supprimer tous les changements de cette page et revenir à la version fournie par son code source." + +#: plugins/tasks/page.inc:196 +msgid "Remove this page from your system completely." +msgstr "Supprimer entièrement cette page du système." + +#: plugins/tasks/page.inc:207 +msgid "Custom" +msgstr "Personnalisé" + +#: plugins/tasks/page.inc:304 +#: plugins/tasks/term_view.inc:133 +msgid "View" +msgstr "Voir" + +#: plugins/tasks/page.inc:574;589;629;650;685 +#: plugins/tasks/term_view.inc:258;264;272;285;298 +msgid "page-summary-label" +msgstr "page-summary-label" + +#: plugins/tasks/page.inc:575;590;616;630;651;686 +#: plugins/tasks/term_view.inc:259;265;273;286;299 +msgid "page-summary-data" +msgstr "page-summary-data" + +#: plugins/tasks/page.inc:576;591;617;631;652;687 +#: plugins/tasks/term_view.inc:260;266;274;287;300 +msgid "page-summary-operation" +msgstr "page-summary-operation" + +#: plugins/tasks/page.inc:589 +msgid "Status" +msgstr "Statut" + +#: plugins/tasks/page.inc:608 +msgid "This is your site home page." +msgstr "C'est la page d'accueil de votre site." + +#: plugins/tasks/page.inc:611 +msgid "This page is set to become your site home page." +msgstr "Cette page est définie pour devenir votre page d'accueil." + +#: plugins/tasks/page.inc:641 +msgid "Accessible only if @conditions." +msgstr "Accessible seulement si @conditions." + +#: plugins/tasks/page.inc:644 +#: plugins/tasks/term_view.inc:265 +msgid "This page is publicly accessible." +msgstr "Cette page est accessible publiquement." + +#: plugins/tasks/page.inc:656 +msgid "No menu entry." +msgstr "Pas d'entrée dans le menu." + +#: plugins/tasks/page.inc:657 +msgid "Normal menu entry." +msgstr "Entrée de menu normale." + +#: plugins/tasks/page.inc:658 +msgid "Menu tab." +msgstr "Onglet." + +#: plugins/tasks/page.inc:659 +msgid "Default menu tab." +msgstr "Onglet par défaut." + +#: plugins/tasks/page.inc:665 +msgid "Title: %title." +msgstr "Titre : %title." + +#: plugins/tasks/page.inc:668 +msgid "Parent title: %title." +msgstr "Titre du parent : %title" + +#: plugins/tasks/page.inc:673 +msgid "Menu block: %title." +msgstr "Bloc de menu : %title" + +#: plugins/tasks/term_view.inc:23;24 +msgid "Taxonomy term template" +msgstr "Template des termes de taxinomie" + +#: plugins/tasks/term_view.inc:25 +msgid "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." +msgstr "Si activé, ceci surcharge le comportement par défaut de Drupal de l'affichage des pages de termes de taxinomie <em>taxonomy/term/%term</em>. Si vous aviez des variantes, vous pourriez utiliser des critères de sélection tel que le vocabulaire ou les permissions pour afficher différentes vues de la page des termes de taxinomies et des noeuds affichés. Si aucune variante n'est sélectionnée, l'affichage par défaut des pages de termes de taxinomie sera utilisée. Cette page affecte uniquement les éléments affichés au chemin taxonomy/term/%term. Certains termes, tel que les forums, ont leur affichage gérer ailleurs. Veuillez également noter que si vous utilisez Pathauto, les alias peuvent donner le sentiment qu'un terme de taxinomie est affiché ailleurs, mais pour Drupal ceci sont toujours au chemin taxonomy/term/%term." + +#: plugins/tasks/term_view.inc:51 +msgid "Update settings specific to the taxonomy term view." +msgstr "Mettre à jour les paramètres spécifiques de la vue des termes de taxinomie." + +#: plugins/tasks/term_view.inc:101 +msgid "Page manager module is unable to enable taxonomy/term/%term because some other module already has overridden with %callback." +msgstr "Le module Page manager est incapable d'activer la page taxonomy/term/%term parce que d'autres modules l'ont déjà surchargé avec %callback." + +#: plugins/tasks/term_view.inc:161 +msgid "Term(s) being viewed" +msgstr "Les termes en cours d'affichage" + +#: plugins/tasks/term_view.inc:161 +msgid "Term being viewed" +msgstr "Le terme en cours d'affichage" + +#: plugins/tasks/term_view.inc:169 +msgid "Depth" +msgstr "Profondeur" + +#: plugins/tasks/term_view.inc:224 +msgid "Allow multiple terms on taxonomy/term/%term" +msgstr "Permettre plusieurs termes sur taxonomy/term/%term" + +#: plugins/tasks/term_view.inc:225 +msgid "Single term" +msgstr "Un seul term" + +#: plugins/tasks/term_view.inc:225 +msgid "Multiple terms" +msgstr "Plusieurs termes" + +#: plugins/tasks/term_view.inc:226 +msgid "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." +msgstr "Par défaut Drupal permet d'avoir plusieurs termes en argument en les séparant par des virgules ou des plus (+). Si vous sélectionnez un seul, cette fonctionnalité sera désactivée." + +#: plugins/tasks/term_view.inc:230 +msgid "Inject hierarchy of first term into breadcrumb trail" +msgstr "Injecte la hiérarchie du premier terme dans le fil d'Arianne" + +#: plugins/tasks/term_view.inc:233 +msgid "If checked, taxonomy term parents will appear in the breadcrumb trail." +msgstr "Si sélectionné, les parents du terme de taxinomie apparaîtra dans le fil d'Arianne." + +#: plugins/tasks/term_view.inc:278 +msgid "Multiple terms may be used, separated by , or +." +msgstr "Plusieurs termes peuvent être utilisés, séparés par des virgules (,) ou des plus (+)." + +#: plugins/tasks/term_view.inc:281 +msgid "Only a single term may be used." +msgstr "Seul un terme peut être utilisé" + +#: plugins/tasks/term_view.inc:285 +msgid "%term" +msgstr "" + +#: plugins/tasks/term_view.inc:291 +msgid "Breadcrumb trail will contain taxonomy term hierarchy" +msgstr "Le fil d'Arianne va contenir la hiérarchie des termes de la taxinomie" + +#: plugins/tasks/term_view.inc:294 +msgid "Breadcrumb trail will not contain taxonomy term hiearchy." +msgstr "Le fil d'Arianne ne va pas contenir la hiérarchie des termes de la taxinomie" + +#: plugins/tasks/term_view.inc:298 +msgid "Breadcrumb" +msgstr "Fil d'Arianne" + +#: plugins/tasks/user_view.inc:12;13 +msgid "User profile template" +msgstr "Template profile utilisateur" + +#: plugins/tasks/user_view.inc:14 +msgid "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." +msgstr "Si activé, ceci surcharge l'affichage par défaut de Drupal pour afficher le profile des utilisateurs <em>user/%user</em>. Si vous ajoutez des variantes, vous pourrez sélectionner des critères de sélection tel que les rôles ou les permissions pour fournir des affichages différents des profiles utilisateurs. Si aucune variante n'est sélectionnée, l'affichage par défaut de Drupal sera utilisé. Notez que si vous utilisez Pathauto, les alias peuvent donner l'impression que les profiles utilisateurs sont affichés ailleurs, mais pour Drupal ils sont toujours affiché au chemin user/%user." + +#: plugins/tasks/user_view.inc:56 +msgid "Page manager module is unable to enable user/%user because some other module already has overridden with %callback." +msgstr "Le module Page manager est incapable d'activer la page user/%user car d'autres modules l'ont déjà surchargé avec %callback." + +#: plugins/tasks/user_view.inc:97 +msgid "User being viewed" +msgstr "L'utilisateur en cours d'affichage" + +#: theme/page_manager.theme.inc:42 +msgid "Locked" +msgstr "Vérouillé" + +#: theme/page_manager.theme.inc:42 +msgid "This page is being edited by another user and you cannot make changes to it." +msgstr "Cette page est en cours d'édition par un autre utilisateur, vous ne pouvez donc pas la modifier." + +#: theme/page_manager.theme.inc:45 +msgid "New" +msgstr "Nouveau" + +#: theme/page_manager.theme.inc:45 +msgid "This page is newly created and has not yet been saved to the database. It will not be available until you save it." +msgstr "Cette page vient d'être créée et n'a pas été enregistrée dans la base de données. Elle ne sera pas disponible tant que vous ne l'aurez pas sauvegardée." + +#: theme/page_manager.theme.inc:48 +msgid "Changed" +msgstr "Modifiée" + +#: theme/page_manager.theme.inc:48 +msgid "This page has been modified, but these modifications are not yet live. While modifying this page, it is locked from modification by other users." +msgstr "Cette page a été modifiée, mais ces changements ne sont pas encore actifs. Lors de la modification de cette page, celle-ci est verrouillée et ne peut pas être modifiée par les autres utilisateurs." + +#: theme/page_manager.theme.inc:98 +msgid "No task handlers are defined for this task." +msgstr "Aucun gestionnaire de tâche n'est définie pour cette tâche." + +#: theme/page_manager.theme.inc:102 +msgid "Variant" +msgstr "Variante" + +#: theme/page_manager.theme.inc:124 +msgid "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>." +msgstr "Cette page est en cours d'édition par l'utilisateur !user, et est donc verrouillée. Ce verrou est actif depuis !age. Cliquez ici pour <a href=\"!break\">cassé ce verrou</a>." + diff --git a/sites/all/modules/ctools/page_manager/translations/page_manager.hu.po b/sites/all/modules/ctools/page_manager/translations/page_manager.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..1a0f4a96ff6109461877972fb2b6d4542871963f --- /dev/null +++ b/sites/all/modules/ctools/page_manager/translations/page_manager.hu.po @@ -0,0 +1,268 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 13:40+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 "Pages" +msgstr "Oldalak" +msgid "List" +msgstr "Lista" +msgid "Reset" +msgstr "Alaphelyzet" +msgid "Name" +msgstr "Név" +msgid "Summary" +msgstr "Összegzés" +msgid "Up" +msgstr "Fel" +msgid "<All>" +msgstr "< Mind >" +msgid "Down" +msgstr "Le" +msgid "Order" +msgstr "Sorrend" +msgid "Sort by" +msgstr "Rendezés" +msgid "Apply" +msgstr "Alkalmaz" +msgid "Panel" +msgstr "Panel" +msgid "Variants" +msgstr "Változatok" +msgid "Break lock" +msgstr "Zárolás feloldása" +msgid "Enabled, title" +msgstr "Engedélyezett, cím" +msgid "Get a summary of the information about this page." +msgstr "Az oldalinformációk összefoglalója." +msgid "Activate this page so that it will be in use in your system." +msgstr "Az oldalt aktiválni kell, hogy a rendszerben használni lehessen." +msgid "" +"De-activate this page. The data will remain but the page will not be " +"in use on your system." +msgstr "" +"Oldal deaktiválása. Az adat megmarad, de az oldal nem lesz " +"használva a rendszerben." +msgid "Add variant" +msgstr "Változat hozzáadása" +msgid "Add a new variant to this page." +msgstr "Új változat hozzáadása az oldalhoz." +msgid "Create variant" +msgstr "Változat létrehozása" +msgid "Import variant" +msgstr "Változat importálása" +msgid "Add a new variant to this page from code exported from another page." +msgstr "" +"Új változat hozzáadása az oldalhoz egy másik oldalból exportált " +"kódból." +msgid "Reorder variants" +msgstr "Változatok újrarendezése" +msgid "" +"Change the priority of the variants to ensure that the right one gets " +"selected." +msgstr "" +"A változatok fontosságának módosítása, hogy biztosan a " +"megfelelő legyen kiválasztva." +msgid "" +"Configure a newly created variant prior to actually adding it to the " +"page." +msgstr "" +"Egy újonnan létrehozott változat hozzáadása azelőtt, hogy az " +"ténylegesen hozzá lenne adva az oldalhoz." +msgid "Break the lock on this page so that you can edit it." +msgstr "Az oldal zárolása meg lett szüntetve, így az már szerkeszthető." +msgid "Variant operations" +msgstr "Változatok műveletei" +msgid "Get a summary of the information about this variant." +msgstr "Változatinformációk összefoglalója." +msgid "Make an exact copy of this variant." +msgstr "A változat egy pontos másolatának létrehozása." +msgid "Export this variant into code to import into another page." +msgstr "" +"A változat kódjának egy másik oldalba importálható " +"exportálása." +msgid "Remove all changes to this variant and revert to the version in code." +msgstr "" +"A változat összes módosításának eltávolítása és " +"visszaállítása a kódban lévő változatra." +msgid "Remove this variant from the page completely." +msgstr "A változat teljes eltávolítása az oldalról." +msgid "Activate this variant so that it will be in use in your system." +msgstr "A változatot aktiválni kell, hogy a rendszerben használni lehessen." +msgid "" +"De-activate this variant. The data will remain but the variant will " +"not be in use on your system." +msgstr "" +"Változat deaktiválása. Az adat megmarad, de a változat nem lesz " +"használva a rendszerben." +msgid "No variants" +msgstr "Nincsenek változatok" +msgid "This operation trail does not exist." +msgstr "Ez a műveleti nyomvonal nem létezik." +msgid "" +"The page has been updated. Changes will not be permanent until you " +"save." +msgstr "" +"Az oldal frissítve lett. A változások nem véglegesek, amíg nincs " +"elmentve." +msgid "Unable to update changes due to lock." +msgstr "Zárolás miatt nem lehett frissíteni a módosításokat." +msgid "This setting contains unsaved changes." +msgstr "Ez a beállítás el nem mentett módosításokat tartalmaz." +msgid "" +"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." +msgstr "" +"Nem mentett módosítások vannak az oldalon. A „Mentés”-t kell " +"választani az adatbázisba íráshoz vagy a „Mégsem”-et a " +"módosítások eldobásához. Meg kell jegyezni, hogy az űrlapokat " +"módosítás után be kell küldeni a mentés előtt." +msgid "All pending changes have been discarded, and the page is now unlocked." +msgstr "" +"Minden függőben lévő módosítás el lett dobva és az oldal " +"zárolása fel lett oldva." +msgid "" +"Administrative title of this variant. If you leave blank it will be " +"automatically assigned." +msgstr "" +"A változat adminisztratív címe. Üresen hagyva automatikusan lesz " +"meghatározva." +msgid "Variant type" +msgstr "Változat típusa" +msgid "Optional features" +msgstr "Választható lehetőségek" +msgid "" +"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." +msgstr "" +"További választható lehetőségek beállítása, amik űrlapokkal " +"jelennek meg a beállításhoz. Ha itt nincsenek bejelölve, akkor is " +"lehet használni ezeket a lehetőségeket amint az új oldal " +"létrejött. Kétség esetén bejelöletlenül kell hagyni ezeket." +msgid "Variant name" +msgstr "Változat neve" +msgid "Enter the name of the new variant." +msgstr "Az új változat nevének megadása." +msgid "Paste variant code here" +msgstr "Változat kódjának beillesztése" +msgid "No variant found." +msgstr "Nincs változat." +msgid "Unable to get a variant from the import. Errors reported: @errors" +msgstr "" +"Nem lehet változatot létrehozni az importból. A jelentett hibák: " +"@errors" +msgid "" +"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." +msgstr "" +"A változat visszaállítása törli a változatot az adatbázisból, " +"visszaállítva az eredeti alapértelmezett változatot. A mentésre " +"kattintásig ez a törlés nem lesz végleges." +msgid "" +"Are you sure you want to delete this variant? This deletion will not " +"be made permanent until you click Save." +msgstr "" +"Biztosan törölhető ez a változat? A törlés a mentésre " +"kattintásig nem lesz véglegesítve." +msgid "" +"This variant is currently disabled. Enabling it will make it available " +"in your system. This will not take effect until you save this page." +msgstr "" +"Ez a változat jelenleg le van tiltva. Engedélyezése elérhetővé " +"teszi a rendszerben. Az oldal elmentése előtt nem lép érvénybe." +msgid "" +"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." +msgstr "" +"Ez a változat jelenleg engedélyezve van. A letiltása " +"elérhetetlenné teszi a rendszerben és nem lesz használva. Addig " +"nem lép érvénybe, amíg nincs az oldal elmentve." +msgid "" +"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?" +msgstr "" +"Az oldal zárolásának feloldása <strong>el fog dobni</strong> " +"minden, a zároló felhasználó által végrehajtott, függőben " +"lévő változást. VALÓBAN végrehajtható a feloldás?" +msgid "" +"The lock has been cleared and all changes discarded. You may now make " +"changes to this page." +msgstr "" +"A zárolás törölve lett és minden módosítás el lett dobva. Most " +"már lehet módosítani az oldalt." +msgid "" +"Enabling this page will immediately make it available in your system " +"(there is no need to wait for a save.)" +msgstr "" +"Az oldal engedélyezése azonnal elérhetővé teszi azt a rendszerben " +"(nincs szükség mentésre)." +msgid "" +"Disabling this page will immediately make it unavailable in your " +"system (there is no need to wait for a save.)" +msgstr "" +"Az oldal tiltása azonnal elérhetetlenné teszi azt a rendszerben " +"(nincs szükség mentésre)." +msgid "This page has no variants and thus no output of its own." +msgstr "Ennek az oldalnak nincsenek változatai, ezért nincs saját kimenete." +msgid "Add a new variant" +msgstr "Új változat hozzáadása" +msgid "Unable to disable due to lock." +msgstr "Zárolás miatt nem tiltható le." +msgid "Unable to enable due to lock." +msgstr "Zárolás miatt nem engedélyezhető." +msgid "use page manager" +msgstr "oldalkezelő használata" +msgid "administer page manager" +msgstr "oldalkezelő adminisztrációja" +msgid "" +"Add, edit and remove overridden system pages and user defined pages " +"from the system." +msgstr "" +"A rendszer felülírt rendszeroldalainak és a felhasználók által " +"meghatározott oldalaknak a hozzáadása, szerkesztése és " +"eltávolítása." +msgid "Page manager" +msgstr "Oldalkezelő" +msgid "Provides a UI and API to manage pages within the site." +msgstr "" +"Egy felhasználói-, és egy API felületet biztosít a webhelyen " +"belüli oldalak kezeléséshez." +msgid "See the getting started guide for more information." +msgstr "A Kezdeti segítség útmutató megtekintése a részletekért." +msgid "" +"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." +msgstr "" +"A változat hozzáadása előtt ezt be kell állítani. A " +"befejezésekor a „Változat létrehozása” gombra kattintás " +"befejezi a varázslót és hozzáadja a változatot az oldalhoz." +msgid "" +"This page is currently locked for editing by you. Nobody else may edit " +"this page until these changes are saved or canceled." +msgstr "" +"Ez az oldal jelenleg zárolva van mert ön szerkeszti. Senki más nem " +"szerkesztheti ezt az oldalt, a módosítások mentése vagy " +"visszavonása előtt." +msgid "" +"This page is currently locked for editing by another user. You may not " +"edit this page without breaking the lock." +msgstr "" +"Ez az oldal jelenleg zárolva van, mert egy másik felhasználó " +"szerkeszti. A zárolás feloldása előtt nem szerkeszthető az oldal." diff --git a/sites/all/modules/ctools/page_manager/translations/page_manager.pot b/sites/all/modules/ctools/page_manager/translations/page_manager.pot new file mode 100644 index 0000000000000000000000000000000000000000..427228b84c02d8122109cb90bf8abed730b2373a --- /dev/null +++ b/sites/all/modules/ctools/page_manager/translations/page_manager.pot @@ -0,0 +1,921 @@ +# $Id: page_manager.pot,v 1.1 2009/08/16 19:13:58 hass Exp $ +# +# LANGUAGE translation of Drupal (page_manager-plugins-tasks) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# node_edit.inc,v 1.3 2009/08/04 21:43:06 merlinofchaos +# node_view.inc,v 1.4 2009/08/04 21:43:06 merlinofchaos +# page.admin.inc,v 1.16 2009/08/07 23:40:39 merlinofchaos +# page.inc,v 1.16 2009/08/13 23:35:26 merlinofchaos +# term_view.inc,v 1.5 2009/08/04 21:43:06 merlinofchaos +# user_view.inc,v 1.3 2009/08/04 21:43:06 merlinofchaos +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-08-16 20:47+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" + +#: page_manager/plugins/tasks/node_edit.inc:13;14 +msgid "Node add/edit form" +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:15 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:55 +msgid "Page manager module is unable to enable node/%node/edit because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:65 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:129 +msgid "Create @name" +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:143 +msgid "Node being edited" +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:22;24 +msgid "Node template" +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:25 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:66 +msgid "Page manager module is unable to enable node/%node because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:118 +msgid "Node being viewed" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:196;274 +msgid "Basic settings" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:197;970;978 +msgid "Argument settings" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:198;434 +msgid "Access control" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:199 +msgid "Menu settings" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:275 +msgid "A meaningless second page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:368;1359 +msgid "The name of this page. This will appear in the administrative interface to easily identify it." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:374 +msgid "Machine name" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:375 +msgid "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!" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:387 +msgid "A description of what this page is, does or is for, for administrative use." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:395 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:417 +msgid "Make this your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:418 +msgid "If this box is checked this page will become the site home page. Only paths that have no placeholders can be used as the site home page. The current site home page is set to %homepage." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:423 +msgid "This page is currently set to be your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:435 +msgid "Visible menu item" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:456 +msgid "Name is required." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:463 +msgid "That name is used by another page: @page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:468 +msgid "Page name must be alphanumeric or underscores only." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:475 +msgid "That path is used by another page: @page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:483 +msgid "Path is required." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:497 +msgid "You cannot have a dynamic path element after an optional path element." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:506 +msgid "You cannot have a static path element after an optional path element." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:517 +msgid "That path is already in used. This system cannot override existing paths." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:525 +msgid "That path is currently assigned to be an alias for @alias. This system cannot override existing aliases." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:530 +msgid "You cannot make this page your site home page if it uses % placeholders." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:538 +msgid "Duplicated argument %arg" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:543 +msgid "Invalid arg <em>%</em>. All arguments must be named with keywords." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:636 +#: page_manager/plugins/tasks/page.inc:680 +#: page_manager/plugins/tasks/term_view.inc:269 +msgid "No menu entry" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:637 +msgid "Normal menu entry" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:638;700 +msgid "Menu tab" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:639 +msgid "Default menu tab" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:648 +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:658 +msgid "Warning: Changing this item's menu will not work reliably in Drupal 6.4 or earlier. Please upgrade your copy of Drupal at !url." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:668 +#: page_manager/plugins/tasks/page.inc:171;685 +#: page_manager/plugins/tasks/term_view.inc:272 +msgid "Menu" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:672;722 +msgid "Insert item into an available menu." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:683 +msgid "Menu selection requires the activation of menu module." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:690 +msgid "The lower the weight the higher/further left it will appear." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:698 +msgid "Parent menu item" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:700 +msgid "Already exists" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:700 +msgid "Normal menu item" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:702 +msgid "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>." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:707 +msgid "Parent item title" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:710 +msgid "If creating a parent menu item, enter the title of the item." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:718 +msgid "Parent item menu" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:735 +msgid "Tab weight" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:739 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:774 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:807 +msgid "Access rules are used to test if the page is accessible and any menu items associated with it are visible." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:848 +msgid "No context assigned" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:872 +msgid "Change" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:889 +#: page_manager/plugins/tasks/page.inc:143 +#: page_manager/plugins/tasks/term_view.inc:50;65 +msgid "Settings" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:902 +msgid "Argument" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:903 +msgid "Position in path" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:904 +msgid "Context assigned" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:923 +msgid "The path %path has no arguments to configure." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:957 +msgid "Invalid keyword." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:969 +msgid "Change context type" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:974 +msgid "Change argument" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1080 +msgid "No context selected" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1163 +msgid "Error: missing argument." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1176 +msgid "Context identifier" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1177 +msgid "This is the title of the context used to identify it later in the administrative process. This will never be shown to a user." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1183 +msgid "Error: missing or invalid argument plugin %argument." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1231 +msgid "Import page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1234;1352 +msgid "Page name" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1235 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1241 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1246 +msgid "Allow overwrite of an existing page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1247 +msgid "If the name you selected already exists in the database, this page will be allowed to overwrite the existing page." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1252 +msgid "Paste page code here" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1258 +msgid "Import" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1274 +msgid "No handler found." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1276 +msgid "Unable to get a page from the import. Errors reported: @errors" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1287 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1353 +msgid "Enter the name to the new page It must be unique and contain only alphanumeric characters and underscores." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1367 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1373 +msgid "Clone variants" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1374 +msgid "If checked all variants associated with the page will be cloned as well. If not checked the page will be cloned without variants." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1482 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1485 +msgid "Are you sure you want to delete this page? Deleting a page cannot be undone." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1508 +msgid "The page has been deleted." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1512 +msgid "The page has been reverted." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:22 +msgid "Custom pages" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:23 +msgid "Administrator created pages that have a URL path, access control and entries in the Drupal menu system." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:39 +msgid "Create a new page" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:150 +#: page_manager/plugins/tasks/term_view.inc:68 +msgid "Basic" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:151 +#: page_manager/plugins/tasks/term_view.inc:69 +msgid "Edit name, path and other basic settings for the page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:159 +msgid "Set up contexts for the arguments on this page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:165;650 +#: page_manager/plugins/tasks/term_view.inc:264 +msgid "Access" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:166 +msgid "Control what users can access this page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:172 +msgid "Provide this page a visible menu or a menu tab." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:178 +msgid "Make a copy of this page" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:183 +msgid "Export this page as code that can be imported or embedded into a module." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:189 +msgid "Remove all changes to this page and revert to the version in code." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:196 +msgid "Remove this page from your system completely." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:574;589;629;650;685 +#: page_manager/plugins/tasks/term_view.inc:258;264;272;285;298 +msgid "page-summary-label" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:575;590;616;630;651;686 +#: page_manager/plugins/tasks/term_view.inc:259;265;273;286;299 +msgid "page-summary-data" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:576;591;617;631;652;687 +#: page_manager/plugins/tasks/term_view.inc:260;266;274;287;300 +msgid "page-summary-operation" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:589 +msgid "Status" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:608 +msgid "This is your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:611 +msgid "This page is set to become your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:641 +msgid "Accessible only if @conditions." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:644 +#: page_manager/plugins/tasks/term_view.inc:265 +msgid "This page is publicly accessible." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:656 +msgid "No menu entry." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:657 +msgid "Normal menu entry." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:658 +msgid "Menu tab." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:659 +msgid "Default menu tab." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:665 +msgid "Title: %title." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:668 +msgid "Parent title: %title." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:673 +msgid "Menu block: %title." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:23;24 +msgid "Taxonomy term template" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:25 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:51 +msgid "Update settings specific to the taxonomy term view." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:101 +msgid "Page manager module is unable to enable taxonomy/term/%term because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:161 +msgid "Term(s) being viewed" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:161 +msgid "Term being viewed" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:169 +msgid "Depth" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:224 +msgid "Allow multiple terms on taxonomy/term/%term" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:225 +msgid "Single term" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:225 +msgid "Multiple terms" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:226 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:278 +msgid "Multiple terms may be used, separated by , or +." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:281 +msgid "Only a single term may be used." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:285 +msgid "%term" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:291 +msgid "Breadcrumb trail will contain taxonomy term hierarchy" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:294 +msgid "Breadcrumb trail will not contain taxonomy term hiearchy." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:298 +msgid "Breadcrumb" +msgstr "" + +#: page_manager/plugins/tasks/user_view.inc:12;13 +msgid "User profile template" +msgstr "" + +#: page_manager/plugins/tasks/user_view.inc:14 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/user_view.inc:56 +msgid "Page manager module is unable to enable user/%user because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/user_view.inc:97 +msgid "User being viewed" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:42 +msgid "Locked" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:42 +msgid "This page is being edited by another user and you cannot make changes to it." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:45 +msgid "New" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:45 +msgid "This page is newly created and has not yet been saved to the database. It will not be available until you save it." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:48 +msgid "Changed" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:48 +msgid "This page has been modified, but these modifications are not yet live. While modifying this page, it is locked from modification by other users." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:98 +msgid "No task handlers are defined for this task." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:102 +msgid "Variant" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:124 +msgid "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>." +msgstr "" + +#: page_manager/page_manager.admin.inc:34;278 +msgid "Reset" +msgstr "" + +#: page_manager/page_manager.admin.inc:71;249 +msgid "Name" +msgstr "" + +#: page_manager/page_manager.admin.inc:145 +msgid "System" +msgstr "" + +#: page_manager/page_manager.admin.inc:215 +msgid "<All>" +msgstr "" + +#: page_manager/page_manager.admin.inc:240 +msgid "Search" +msgstr "" + +#: page_manager/page_manager.admin.inc:245 +msgid "Sort by" +msgstr "" + +#: page_manager/page_manager.admin.inc:247 +msgid "Enabled, title" +msgstr "" + +#: page_manager/page_manager.admin.inc:259 +msgid "Order" +msgstr "" + +#: page_manager/page_manager.admin.inc:261 +msgid "Up" +msgstr "" + +#: page_manager/page_manager.admin.inc:262 +msgid "Down" +msgstr "" + +#: page_manager/page_manager.admin.inc:271 +msgid "Apply" +msgstr "" + +#: page_manager/page_manager.admin.inc:451;643 +msgid "Summary" +msgstr "" + +#: page_manager/page_manager.admin.inc:452 +msgid "Get a summary of the information about this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:505 +msgid "Activate this page so that it will be in use in your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:518 +msgid "De-activate this page. The data will remain but the page will not be in use on your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:529 +msgid "Add variant" +msgstr "" + +#: page_manager/page_manager.admin.inc:530 +msgid "Add a new variant to this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:535;568 +msgid "Create variant" +msgstr "" + +#: page_manager/page_manager.admin.inc:540 +msgid "Import variant" +msgstr "" + +#: page_manager/page_manager.admin.inc:541 +msgid "Add a new variant to this page from code exported from another page." +msgstr "" + +#: page_manager/page_manager.admin.inc:547 +msgid "Reorder variants" +msgstr "" + +#: page_manager/page_manager.admin.inc:549 +msgid "Change the priority of the variants to ensure that the right one gets selected." +msgstr "" + +#: page_manager/page_manager.admin.inc:560 +msgid "Configure a newly created variant prior to actually adding it to the page." +msgstr "" + +#: page_manager/page_manager.admin.inc:587;592 +msgid "Break lock" +msgstr "" + +#: page_manager/page_manager.admin.inc:588 +msgid "Break the lock on this page so that you can edit it." +msgstr "" + +#: page_manager/page_manager.admin.inc:611 +msgid "Variants" +msgstr "" + +#: page_manager/page_manager.admin.inc:636 +msgid "Variant operations" +msgstr "" + +#: page_manager/page_manager.admin.inc:644 +msgid "Get a summary of the information about this variant." +msgstr "" + +#: page_manager/page_manager.admin.inc:659 +msgid "Make an exact copy of this variant." +msgstr "" + +#: page_manager/page_manager.admin.inc:664 +msgid "Export this variant into code to import into another page." +msgstr "" + +#: page_manager/page_manager.admin.inc:670 +msgid "Remove all changes to this variant and revert to the version in code." +msgstr "" + +#: page_manager/page_manager.admin.inc:680 +msgid "Remove this variant from the page completely." +msgstr "" + +#: page_manager/page_manager.admin.inc:690 +msgid "Activate this variant so that it will be in use in your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:701 +msgid "De-activate this variant. The data will remain but the variant will not be in use on your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:713 +msgid "No variants" +msgstr "" + +#: page_manager/page_manager.admin.inc:907 +msgid "This operation trail does not exist." +msgstr "" + +#: page_manager/page_manager.admin.inc:924 +msgid "The page has been updated. Changes will not be permanent until you save." +msgstr "" + +#: page_manager/page_manager.admin.inc:941 +msgid "Unable to update changes due to lock." +msgstr "" + +#: page_manager/page_manager.admin.inc:1091 +msgid "This setting contains unsaved changes." +msgstr "" + +#: page_manager/page_manager.admin.inc:1149 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1180 +msgid "All pending changes have been discarded, and the page is now unlocked." +msgstr "" + +#: page_manager/page_manager.admin.inc:1231 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1296 +msgid "Administrative title of this variant. If you leave blank it will be automatically assigned." +msgstr "" + +#: page_manager/page_manager.admin.inc:1301 +msgid "Variant type" +msgstr "" + +#: page_manager/page_manager.admin.inc:1310 +msgid "Optional features" +msgstr "" + +#: page_manager/page_manager.admin.inc:1312 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1340;1496 +msgid "Variant name" +msgstr "" + +#: page_manager/page_manager.admin.inc:1341;1497 +msgid "Enter the name of the new variant." +msgstr "" + +#: page_manager/page_manager.admin.inc:1346 +msgid "Paste variant code here" +msgstr "" + +#: page_manager/page_manager.admin.inc:1363 +msgid "No variant found." +msgstr "" + +#: page_manager/page_manager.admin.inc:1366 +msgid "Unable to get a variant from the import. Errors reported: @errors" +msgstr "" + +#: page_manager/page_manager.admin.inc:1454 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1457 +msgid "Are you sure you want to delete this variant? This deletion will not be made permanent until you click Save." +msgstr "" + +#: page_manager/page_manager.admin.inc:1523 +msgid "This variant is currently disabled. Enabling it will make it available in your system. This will not take effect until you save this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:1542 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1574 +msgid "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?" +msgstr "" + +#: page_manager/page_manager.admin.inc:1586 +msgid "The lock has been cleared and all changes discarded. You may now make changes to this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:1594 +msgid "Enabling this page will immediately make it available in your system (there is no need to wait for a save.)" +msgstr "" + +#: page_manager/page_manager.admin.inc:1621 +msgid "Disabling this page will immediately make it unavailable in your system (there is no need to wait for a save.)" +msgstr "" + +#: page_manager/page_manager.admin.inc:1677 +msgid "This page has no variants and thus no output of its own." +msgstr "" + +#: page_manager/page_manager.admin.inc:1682 +msgid "Add a new variant" +msgstr "" + +#: page_manager/page_manager.admin.inc:1700 +msgid "Unable to disable due to lock." +msgstr "" + +#: page_manager/page_manager.admin.inc:1703 +msgid "Unable to enable due to lock." +msgstr "" + +#: page_manager/page_manager.module:42 +msgid "use page manager" +msgstr "" + +#: page_manager/page_manager.module:42 +msgid "administer page manager" +msgstr "" + +#: page_manager/page_manager.module:66 +msgid "Pages" +msgstr "" + +#: page_manager/page_manager.module:67 +msgid "Add, edit and remove overridden system pages and user defined pages from the system." +msgstr "" + +#: page_manager/page_manager.module:72 +msgid "List" +msgstr "" + +#: page_manager/page_manager.module:0 +msgid "page_manager" +msgstr "" + +#: page_manager/page_manager.install:222 +msgid "Panel" +msgstr "" + +#: page_manager/page_manager.info:0 +msgid "Page manager" +msgstr "" + +#: page_manager/page_manager.info:0 +msgid "Provides a UI and API to manage pages within the site." +msgstr "" diff --git a/sites/all/modules/ctools/plugins/access/compare_users.inc b/sites/all/modules/ctools/plugins/access/compare_users.inc new file mode 100644 index 0000000000000000000000000000000000000000..59e794e97f3b11d7fc214c5743579cb4a0696959 --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/compare_users.inc @@ -0,0 +1,71 @@ +<?php +// $Id: compare_users.inc,v 1.6 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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'], + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/access/context_exists.inc b/sites/all/modules/ctools/plugins/access/context_exists.inc new file mode 100644 index 0000000000000000000000000000000000000000..bdf593c106f03acb7856d3ed49b6d1ba5fd0f329 --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/context_exists.inc @@ -0,0 +1,52 @@ +<?php +// $Id: context_exists.inc,v 1.4 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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'], + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/access/node.inc b/sites/all/modules/ctools/plugins/access/node.inc new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/sites/all/modules/ctools/plugins/access/node_access.inc b/sites/all/modules/ctools/plugins/access/node_access.inc new file mode 100644 index 0000000000000000000000000000000000000000..3e6320ee601d0b0a86976e9a6bb61a92cce6852c --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/node_access.inc @@ -0,0 +1,90 @@ +<?php +// $Id: node_access.inc,v 1.10 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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'], + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/access/node_language.inc b/sites/all/modules/ctools/plugins/access/node_language.inc new file mode 100644 index 0000000000000000000000000000000000000000..662203b84787c0a3be9703a634617086d9a2f696 --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/node_language.inc @@ -0,0 +1,115 @@ +<?php +// $Id: node_language.inc,v 1.11 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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'], + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/access/node_type.inc b/sites/all/modules/ctools/plugins/access/node_type.inc new file mode 100644 index 0000000000000000000000000000000000000000..5646626d89271ba740f769117c2a5027a14f5bfd --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/node_type.inc @@ -0,0 +1,101 @@ +<?php +// $Id: node_type.inc,v 1.12 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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_type_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'], + ); + return $form; +} + +/** + * 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_type_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/sites/all/modules/ctools/plugins/access/path_visibility.inc b/sites/all/modules/ctools/plugins/access/path_visibility.inc new file mode 100644 index 0000000000000000000000000000000000000000..160f8bfbf06bdc56579b47b6ccca6fe0eb03d43e --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/path_visibility.inc @@ -0,0 +1,89 @@ +<?php +// $Id: path_visibility.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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>')), + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/access/perm.inc b/sites/all/modules/ctools/plugins/access/perm.inc new file mode 100644 index 0000000000000000000000000000000000000000..eca4ac7ccd4229f4927fb852bcbf8b94a0baa39e --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/perm.inc @@ -0,0 +1,74 @@ +<?php +// $Id: perm.inc,v 1.10 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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, 'permission')) { + foreach ($permissions as $id => $permission) { + $perms[$module][$id] = $permission['title']; + } + } + } + + $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.'), + ); + + return $form; +} + +/** + * 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'); + } + + $permissions = module_invoke_all('permission'); + return t('@identifier has "@perm"', array('@identifier' => $context->identifier, '@perm' => $permissions[$conf['perm']]['title'])); +} + diff --git a/sites/all/modules/ctools/plugins/access/php.inc b/sites/all/modules/ctools/plugins/access/php.inc new file mode 100644 index 0000000000000000000000000000000000000000..71d9f91ac38dfd413f0af71f9a50364fdda84eeb --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/php.inc @@ -0,0 +1,65 @@ +<?php +// $Id: php.inc,v 1.7 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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 settings')) { + $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.'); + } + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/access/role.inc b/sites/all/modules/ctools/plugins/access/role.inc new file mode 100644 index 0000000000000000000000000000000000000000..2e5875e00e69a614f8ae719dae6c5db19fbe99f7 --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/role.inc @@ -0,0 +1,80 @@ +<?php +// $Id: role.inc,v 1.11 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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.'), + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/access/site_language.inc b/sites/all/modules/ctools/plugins/access/site_language.inc new file mode 100644 index 0000000000000000000000000000000000000000..1c4357476de7c9b296e7cf8f89ecab1008236cd0 --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/site_language.inc @@ -0,0 +1,88 @@ +<?php +// $Id: site_language.inc,v 1.10 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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'], + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/access/string_equal.inc b/sites/all/modules/ctools/plugins/access/string_equal.inc new file mode 100644 index 0000000000000000000000000000000000000000..4a9ff45ace2136f0c7814f273a99c213c7ddc62a --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/string_equal.inc @@ -0,0 +1,95 @@ +<?php +// $Id: string_equal.inc,v 1.3 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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'], + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/access/string_length.inc b/sites/all/modules/ctools/plugins/access/string_length.inc new file mode 100644 index 0000000000000000000000000000000000000000..56e8c9d252626d6b0b9071babe6fbf280550f3d5 --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/string_length.inc @@ -0,0 +1,79 @@ +<?php +// $Id: string_length.inc,v 1.3 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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.'), + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/access/term.inc b/sites/all/modules/ctools/plugins/access/term.inc new file mode 100644 index 0000000000000000000000000000000000000000..c49dc927532e2c90405599a0a2c85b5f172960c9 --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/term.inc @@ -0,0 +1,153 @@ +<?php +// $Id: term.inc,v 1.8 2011/01/05 20:34:46 merlinofchaos Exp $ + +/** + * @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('taxonomy_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; + return $form; +} + +/** + * 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_term_load($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/sites/all/modules/ctools/plugins/access/term_parent.inc b/sites/all/modules/ctools/plugins/access/term_parent.inc new file mode 100644 index 0000000000000000000000000000000000000000..15a71a85986974225b9cd46f47a19904cf4f465c --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/term_parent.inc @@ -0,0 +1,87 @@ +<?php +// $Id: term_parent.inc,v 1.3 2011/01/05 20:34:46 merlinofchaos Exp $ + +/** + * @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('taxonomy_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; + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/access/term_vocabulary.inc b/sites/all/modules/ctools/plugins/access/term_vocabulary.inc new file mode 100644 index 0000000000000000000000000000000000000000..8bb7e2a36e98652adc2affd21841329acd65b14c --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/term_vocabulary.inc @@ -0,0 +1,88 @@ +<?php +// $Id: term_vocabulary.inc,v 1.9 2011/01/05 20:34:46 merlinofchaos Exp $ + +/** + * @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('taxonomy_term', 'terms', 'taxonomy_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'], + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/access/theme.inc b/sites/all/modules/ctools/plugins/access/theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..eaff131df3e3df3a8c4bb471fdac07dd939eaeb8 --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/theme.inc @@ -0,0 +1,71 @@ +<?php +// $Id: theme.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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.'), + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/access/translations/plugins-access.hu.po b/sites/all/modules/ctools/plugins/access/translations/plugins-access.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..2cfb5fa0b99b0ab3b3df88c879cd70541e558885 --- /dev/null +++ b/sites/all/modules/ctools/plugins/access/translations/plugins-access.hu.po @@ -0,0 +1,184 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 13:23+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 "Vocabularies" +msgstr "Szótárak" +msgid "Terms" +msgstr "Kifejezések" +msgid "PHP Code" +msgstr "PHP kód" +msgid "Permission" +msgstr "Jogosultság" +msgid "No language" +msgstr "Nincs nyelv" +msgid "Equal" +msgstr "Egyenlő" +msgid "User: compare" +msgstr "Felhasználó: összehasonlítás" +msgid "Compare two users (logged-in user and user being viewed, for example)" +msgstr "" +"Két felhasználó összehasonlítása (például: bejelentkezett " +"felhasználó és megtekintett felhasználó)" +msgid "First User" +msgstr "Első felhasználó" +msgid "Second User" +msgstr "Második felhasználó" +msgid "" +"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." +msgstr "" +"Hozzáférés biztosítása két felhasználó környezeteinek " +"összehasonlítása alapján. Például, ahhoz, hogy egy felhasználó " +"hozzáférhessen a saját profiljához, a „bejelentkezett " +"felhasználó”-t és a „megtekintett felhasználó”-t kell " +"választani valamint a hozzáférés biztosítását „egyenlő”-re " +"kell állítani." +msgid "Grant access if user contexts are" +msgstr "Hozzáférés biztosítása, ha a felhasználó környezetei" +msgid "Not equal" +msgstr "Nem egyenlő" +msgid "@id1 @comp @id2" +msgstr "@id1 @comp @id2" +msgid "Node: accessible" +msgstr "Tartalom: elérhető" +msgid "Control access with built in Drupal node access test." +msgstr "" +"Hozzáférés szabályozása a Drupal beépített " +"tartalomhozzáférés ellenőrzésével." +msgid "Create nodes of the same type" +msgstr "Tartalmak létrehozása ugyanabból a típusból" +msgid "" +"Using built in Drupal node access rules, determine if the user can " +"perform the selected operation on the node." +msgstr "" +"A Drupal beépített tartalom-hozzáférési szabályainak használata " +"annak meghatározására, hogy a felhasználó végrehajthatja-e a " +"kiválasztott műveletet a tartalmon." +msgid "@user can view @node." +msgstr "@user megtekintheti ezt: @node." +msgid "@user can edit @node." +msgstr "@user szerkesztheti ezt: @node." +msgid "@user can delete @node." +msgstr "@user törölheti ezt: @node." +msgid "@user can create nodes of the same type as @node." +msgstr "@user létrehozhat @node típusával megegyező típusú tartalmakat." +msgid "Node: language" +msgstr "Tartalom: nyelv" +msgid "Control access by node language." +msgstr "Hozzáférés szabályozása a tartalom nyelve alapján." +msgid "Current site language" +msgstr "A webhely jelenlegi nyelve" +msgid "Pass only if the node is in one of the selected languages." +msgstr "" +"Csak akkor sikeres, ha a tartalom az egyik kiválasztott nyelvet " +"használja." +msgid "@identifier is in any language" +msgstr "@identifier bármelyik nyelven lehet" +msgid "@identifier language is \"@languages\"" +msgid_plural "@identifier language is one of \"@languages\"" +msgstr[0] "@identifier nyelve „@languages”" +msgstr[1] "@identifier nyelve „@languages” egyike" +msgid "Node: type" +msgstr "Tartalom: típus" +msgid "Control access by node_type." +msgstr "Hozzáférés szabályozása tartalomtípus alapján." +msgid "Only the checked node types will be valid." +msgstr "Csak a bejelölt tartalomtípusok lesznek érvényesek." +msgid "@identifier is any node type" +msgstr "@identifier bármilyen tartalomtípus lehet" +msgid "@identifier is type \"@types\"" +msgid_plural "@identifier type is one of \"@types\"" +msgstr[0] "@identifie típusa „@types”" +msgstr[1] "@identifier típusa „@types” egyike" +msgid "User: permission" +msgstr "Felhasználó: jogosultságok" +msgid "Control access by permission string." +msgstr "Hozzáférés szabályozása jogosultsági kifejezés alapján." +msgid "" +"Only users with the selected permission flag will be able to access " +"this." +msgstr "" +"Csak a kiválasztott jogosultsági jelzővel rendelkező " +"felhasználók fogják tudni elérni." +msgid "Error, unset permission" +msgstr "Hiba, nem beállított jogosultság" +msgid "@identifier has \"@perm\"" +msgstr "@identifier jogosultságai: „@perm”" +msgid "Control access through arbitrary PHP code." +msgstr "Hozzáférés szabályozása tetszés szerinti PHP kód alapján." +msgid "Administrative desc" +msgstr "Adminisztratív leírás" +msgid "A description for this test for administrative purposes." +msgstr "Az ellenőrzés adminisztratív célú leírása." +msgid "" +"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." +msgstr "" +"A hozzáférés meg lesz adva, ha a következő PHP kód " +"<code>IGAZ</code> értékkel tér vissza. Nem szabad használni a " +"<?php ?>-t. Meg kell említeni, hogy a hibás PHP kód az " +"tönkreteheti a Drupal webhelyet. Minden környezet elérhető a " +"<em>$contexts</em> változóban." +msgid "You do not have sufficient permissions to edit PHP code." +msgstr "Nincs elegendő jog a PHP kód szerkesztéséhez." +msgid "User: role" +msgstr "Felhasználó: csoport" +msgid "@identifier has role \"@roles\"" +msgid_plural "@identifier has one of \"@roles\"" +msgstr[0] "@identifier „@roles” csoport tagja" +msgstr[1] "@identifier „@roles” csoportok egyikének a tagja" +msgid "User: language" +msgstr "Felhasználó: nyelv" +msgid "Control access by the language the user or site currently uses." +msgstr "" +"A hozzáférés szabályozása a felhasználó vagy a webhely által " +"jelenleg használt nyelv alapján." +msgid "" +"Pass only if the current site language is one of the selected " +"languages." +msgstr "" +"Csak akkor sikeres, ha a webhely jelenlegi nyelve egyike a " +"kiválasztott nyelveknek." +msgid "Site language is any language" +msgstr "Az oldal nyelve bármelyik nyelv." +msgid "Site language is \"@languages\"" +msgid_plural "Site language is one of \"@languages\"" +msgstr[0] "A webhely nyelve „@languages”" +msgstr[1] "A webhely nyelve „@languages” nyelvek egyike" +msgid "Taxonomy: vocabulary" +msgstr "Taxonómia: szótár" +msgid "Control access by term vocabulary." +msgstr "Hozzáférés szabályozása szótár kifejezés által." +msgid "Only terms in the checked vocabularies will be valid." +msgstr "Csak a kijelölt szótárak kifejezései lesznek érvényesek." +msgid "@identifier is any vocabulary" +msgstr "@identifier bármelyik szótár" +msgid "@identifier vocabulary is \"@vids\"" +msgid_plural "@identifier vocabulary is one of \"@vids\"" +msgstr[0] "@identifier szótára „@vids”" +msgstr[1] "@identifier szótára „@vids” egyike" +msgid "Taxonomy: term" +msgstr "Taxonómia: kifejezés" +msgid "Control access by a specific term." +msgstr "Hozzáférés szabályozása meghatározott kifejezés alapján." +msgid "Select a term or terms from @vocabulary." +msgstr "Egy vagy több kifejezés kiválasztása @vocabulary szótárból." +msgid "@term can be the term \"@terms\"" +msgid_plural "@term can be one of these terms: @terms" +msgstr[0] "@term lehet „@terms”" +msgstr[1] "@term ezen kifejezések egyike lehet: @terms" diff --git a/sites/all/modules/ctools/plugins/arguments/entity_id.inc b/sites/all/modules/ctools/plugins/arguments/entity_id.inc new file mode 100644 index 0000000000000000000000000000000000000000..63cf4c683fcb487d942b2e6be1199a20b798e00e --- /dev/null +++ b/sites/all/modules/ctools/plugins/arguments/entity_id.inc @@ -0,0 +1,67 @@ +<?php +// $Id: entity_id.inc,v 1.1 2011/01/05 20:34:46 merlinofchaos Exp $ + +/** + * @file + * + * Plugin to provide an argument handler for all entity ids + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t("Entity: ID"), + 'description' => t('Creates an entity context from an entity ID argument.'), + 'context' => 'ctools_argument_entity_id_context', + 'get child' => 'ctools_argument_entity_id_get_child', + 'get children' => 'ctools_argument_entity_id_get_children', +); + +function ctools_argument_entity_id_get_child($plugin, $parent, $child) { + $plugins = ctools_argument_entity_id_get_children($plugin, $parent); + return $plugins[$parent . ':' . $child]; +} + +function ctools_argument_entity_id_get_children($plugin, $parent) { + $entities = entity_get_info(); + $plugins = array(); + foreach ($entities as $entity_type => $entity) { + $plugin['title'] = t('@entity: ID', array('@entity' => $entity['label'])); + $plugin['keyword'] = $entity_type; + $plugin['description'] = t('Creates @entity context from an ID argument.', array('@entity' => $entity_type)); + $plugin['name'] = $parent . ':' . $entity_type; + $plugins[$parent . ':' . $entity_type] = $plugin; + } + + return $plugins; +} + +/** + * Discover if this argument gives us the entity we crave. + */ +function ctools_argument_entity_id_context($arg = NULL, $conf = NULL, $empty = FALSE) { + $entity_type = $conf['keyword']; + // If unset it wants a generic, unfilled context. + if ($empty) { + return ctools_context_create_empty('entity:' . $entity_type); + } + + // We can accept either an entity object or a pure id. + if (is_object($arg)) { + return ctools_context_create('entity:' . $entity_type, $arg); + } + + if (!is_numeric($arg)) { + return FALSE; + } + + $entity = entity_load($entity_type, array($arg)); + if (!$entity) { + return FALSE; + } + + return ctools_context_create('entity:' . $entity_type, $entity[$arg]); +} + diff --git a/sites/all/modules/ctools/plugins/arguments/nid.inc b/sites/all/modules/ctools/plugins/arguments/nid.inc new file mode 100644 index 0000000000000000000000000000000000000000..e0caf8829d121c25a041729f39687e9ec8c6b847 --- /dev/null +++ b/sites/all/modules/ctools/plugins/arguments/nid.inc @@ -0,0 +1,50 @@ +<?php +// $Id: nid.inc,v 1.10 2010/01/29 20:18:01 merlinofchaos Exp $ + +/** + * @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/sites/all/modules/ctools/plugins/arguments/node_add.inc b/sites/all/modules/ctools/plugins/arguments/node_add.inc new file mode 100644 index 0000000000000000000000000000000000000000..3282b82d7314f529bcfad61c9b72926eefc0a173 --- /dev/null +++ b/sites/all/modules/ctools/plugins/arguments/node_add.inc @@ -0,0 +1,33 @@ +<?php +// $Id: node_add.inc,v 1.6 2010/10/15 22:56:51 merlinofchaos Exp $ + +/** + * @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/sites/all/modules/ctools/plugins/arguments/node_edit.inc b/sites/all/modules/ctools/plugins/arguments/node_edit.inc new file mode 100644 index 0000000000000000000000000000000000000000..422b6ffc79d346289b84c7ba0b1e8515b3e12728 --- /dev/null +++ b/sites/all/modules/ctools/plugins/arguments/node_edit.inc @@ -0,0 +1,52 @@ +<?php +// $Id: node_edit.inc,v 1.7 2010/01/29 20:18:01 merlinofchaos Exp $ + +/** + * @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/sites/all/modules/ctools/plugins/arguments/rid.inc b/sites/all/modules/ctools/plugins/arguments/rid.inc new file mode 100644 index 0000000000000000000000000000000000000000..fbad0553fb11c41b18c7f4d459e4a3f4fd9fcbeb --- /dev/null +++ b/sites/all/modules/ctools/plugins/arguments/rid.inc @@ -0,0 +1,51 @@ +<?php +// $Id: rid.inc,v 1.2 2010/10/15 21:13:04 merlinofchaos Exp $ + +/** + * @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/sites/all/modules/ctools/plugins/arguments/string.inc b/sites/all/modules/ctools/plugins/arguments/string.inc new file mode 100644 index 0000000000000000000000000000000000000000..09048aa34adefcb86a4b27e5bee7318145067a5f --- /dev/null +++ b/sites/all/modules/ctools/plugins/arguments/string.inc @@ -0,0 +1,65 @@ +<?php +// $Id: string.inc,v 1.7 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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".'), + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/arguments/term.inc b/sites/all/modules/ctools/plugins/arguments/term.inc new file mode 100644 index 0000000000000000000000000000000000000000..f3efd4677e093a773fad407285360f21c504d697 --- /dev/null +++ b/sites/all/modules/ctools/plugins/arguments/term.inc @@ -0,0 +1,148 @@ +<?php +// $Id: term.inc,v 1.12 2010/12/31 21:31:50 merlinofchaos Exp $ + +/** + * @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_term_load($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="clearfix">', + '#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.'), + ); + return $form; +} + +/** + * 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'])) { + 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/sites/all/modules/ctools/plugins/arguments/terms.inc b/sites/all/modules/ctools/plugins/arguments/terms.inc new file mode 100644 index 0000000000000000000000000000000000000000..126504ee1604a02e9797f7c1eb26727d3fbfdbf7 --- /dev/null +++ b/sites/all/modules/ctools/plugins/arguments/terms.inc @@ -0,0 +1,78 @@ +<?php +// $Id: terms.inc,v 1.6 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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.'), + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/arguments/translations/plugins-arguments.hu.po b/sites/all/modules/ctools/plugins/arguments/translations/plugins-arguments.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..14e79abff8efa9b53823d09398c632aa40164f3e --- /dev/null +++ b/sites/all/modules/ctools/plugins/arguments/translations/plugins-arguments.hu.po @@ -0,0 +1,108 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 13:23+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 "Node: ID" +msgstr "Tartalom: azonosító" +msgid "Argument type" +msgstr "Argumentumtípus" +msgid "User: ID" +msgstr "Felhasználó: azonosító" +msgid "Creates a node context from a node ID argument." +msgstr "" +"Tartalomkörnyezet létrehozása egy tartalomazonosító " +"argumentumból." +msgid "Creates a node add form context from a node type argument." +msgstr "" +"Tartalom hozzáadása űrlap létrehozása egy tartalomtípus " +"argumentumból." +msgid "Creates a node edit form context from a node ID argument." +msgstr "" +"Tartalom szerkesztése űrlap létrehozása egy node ID " +"argumentumból." +msgid "" +"A string is a minimal context that simply holds a string that can be " +"used for some other purpose." +msgstr "" +"A kifejezés egy egyszerű környezet ami más célokra használható " +"kifejezést tartalmaz." +msgid "Enter a value for this argument" +msgstr "Argumentum értékének megadása" +msgid "" +"Creates a single taxonomy term from a taxonomy ID or taxonomy term " +"name." +msgstr "" +"Egy egyszerű taxonómia kifejezés létrehozása egy " +"kifejezésazonosítóból vagy egy kifejezés nevéből." +msgid "Inject hierarchy into breadcrumb trail" +msgstr "Hierarchia beillesztése a morzsasávba." +msgid "Enter a taxonomy term ID." +msgstr "Kifejezés azonosítójának megadása." +msgid "Enter a taxonomy term name." +msgstr "Kifejezés nevének megadása." +msgid "" +"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." +msgstr "" +"Taxonómia kifejezések csopotjának létrehozása egy " +"kifejezésazonosító listából, vesszővel vagy összeadás jellel " +"elválasztva. Általában a lista első kifejezése lesz használva a " +"táblában." +msgid "Enter a term ID or a list of term IDs separated by a + or a ," +msgstr "" +"Egy vagy több kifejezésazonosító listájának megadása, „+” " +"vagy „,” jellel elválasztva." +msgid "Creates a user context from a user ID argument." +msgstr "" +"Felhasználói környezet hoz létre egy felhasználói azonosító " +"argumentumból." +msgid "Enter the user ID of a user for this argument" +msgstr "A felhasználó azonosítójának megadása ehhez az argumentumhoz." +msgid "Creates a vocabulary context from a vocabulary ID argument." +msgstr "" +"Egy szótár környezet hoz létre egy szótárazonosíŧó " +"argumentumból." +msgid "Enter the vocabulary ID for this argument" +msgstr "Szótárazonosító megadása ehhez az argumentumhoz." +msgid "Node add form: node type" +msgstr "Tartalom hozzáadása űrlap: tartalomtípus" +msgid "Node edit form: node ID" +msgstr "Tartalom szerkesztése űrlap: tartalomazonosító" +msgid "Get all arguments after this one" +msgstr "Összes argumentum elhelyezése ez után" +msgid "" +"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\"." +msgstr "" +"Ha be van jelölve, ez a karaktersorozat minden argumentumot " +"tartalmazni fog. Például ha az elérési út „path/%” és a " +"felhasználó meglátogatja a „path/foo/bar” oldalt, akkor ha " +"nincs bejelölve, a karaktersorozat „foo” lesz. Ha be van jelölve " +"a karaktersorozat „foo/bar” lesz." +msgid "Taxonomy term: ID" +msgstr "Taxonómia kifejezés: ID" +msgid "Taxonomy term (multiple): ID" +msgstr "Taxonómia kifejezés (több): azonosító" +msgid "User: name" +msgstr "Felhasználó: név" +msgid "Creates a user context from a user name." +msgstr "Felhasználói környezet létrehozása egy felhasználói névből." +msgid "Enter the username of a user for this argument" +msgstr "" +"Egy felhasználó felhasználónevének megadása ehhez az " +"argumentumhoz." +msgid "Vocabulary: ID" +msgstr "Szótár: azonosító" diff --git a/sites/all/modules/ctools/plugins/arguments/uid.inc b/sites/all/modules/ctools/plugins/arguments/uid.inc new file mode 100644 index 0000000000000000000000000000000000000000..69be25b04ddab33a4320f738a7d463c9954a8839 --- /dev/null +++ b/sites/all/modules/ctools/plugins/arguments/uid.inc @@ -0,0 +1,53 @@ +<?php +// $Id: uid.inc,v 1.12 2010/01/29 20:18:01 merlinofchaos Exp $ + +/** + * @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/sites/all/modules/ctools/plugins/arguments/user_name.inc b/sites/all/modules/ctools/plugins/arguments/user_name.inc new file mode 100644 index 0000000000000000000000000000000000000000..87fccf9b44d5d00795c53f5a63f36df9eaa7ebee --- /dev/null +++ b/sites/all/modules/ctools/plugins/arguments/user_name.inc @@ -0,0 +1,48 @@ +<?php +// $Id: user_name.inc,v 1.3 2010/01/29 20:18:01 merlinofchaos Exp $ + +/** + * @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/sites/all/modules/ctools/plugins/arguments/vid.inc b/sites/all/modules/ctools/plugins/arguments/vid.inc new file mode 100644 index 0000000000000000000000000000000000000000..1dd4088d0170444ec992ec64cf6de43460e6e3a7 --- /dev/null +++ b/sites/all/modules/ctools/plugins/arguments/vid.inc @@ -0,0 +1,46 @@ +<?php +// $Id: vid.inc,v 1.6 2010/01/29 20:18:01 merlinofchaos Exp $ + +/** + * @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/sites/all/modules/ctools/plugins/cache/export_ui.inc b/sites/all/modules/ctools/plugins/cache/export_ui.inc new file mode 100644 index 0000000000000000000000000000000000000000..4f9d0828c257ad38ce89f61818770c3892d41206 --- /dev/null +++ b/sites/all/modules/ctools/plugins/cache/export_ui.inc @@ -0,0 +1,40 @@ +<?php +// $Id: export_ui.inc,v 1.1 2010/10/11 22:18:24 sdboyer Exp $ + +/** + * @file + * A caching mechanism for use with subsystems that use the export ui. + */ + +$plugin = array( + // cache plugins are the rare plugin types that have no real UI but + // we're providing a title just in case. + 'title' => t('Export UI wizard cache'), + 'cache get' => 'ctools_cache_export_ui_cache_get', + 'cache set' => 'ctools_cache_export_ui_cache_set', + // Some operations use a 'finalize' but that really just means set + // for us, since we're not using temporary storage for subsystems. + 'cache finalize' => 'ctools_cache_export_ui_cache_set', +); + +function ctools_cache_export_ui_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; + } +} + +function ctools_cache_export_ui_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); + } +} diff --git a/sites/all/modules/ctools/plugins/cache/simple.inc b/sites/all/modules/ctools/plugins/cache/simple.inc new file mode 100644 index 0000000000000000000000000000000000000000..69c98abecb33d986a4a0ea009fc56342be7e72df --- /dev/null +++ b/sites/all/modules/ctools/plugins/cache/simple.inc @@ -0,0 +1,46 @@ +<?php +// $Id: simple.inc,v 1.1 2010/10/11 22:18:24 sdboyer Exp $ + +/** + * @file + * A simple cache indirection mechanism that just uses the basic object cache. + */ + +$plugin = array( + // cache plugins are the rare plugin types that have no real UI but + // we're providing a title just in case. + 'title' => t('Simple'), + 'cache get' => 'ctools_cache_simple_cache_get', + 'cache set' => 'ctools_cache_simple_cache_set', + 'cache clear' => 'ctools_cache_simple_cache_clear', +); + +function ctools_cache_simple_cache_get($data, $key) { + // Ensure that if there is somehow no data, we at least don't stomp on other + // people's caches. + if (empty($data)) { + $data = 'simple_cache_plugin'; + } + + return ctools_object_cache_get($data, $key); +} + +function ctools_cache_simple_cache_set($data, $key, $object) { + // Ensure that if there is somehow no data, we at least don't stomp on other + // people's caches. + if (empty($data)) { + $data = 'simple_cache_plugin'; + } + + return ctools_object_cache_set($data, $key, $object); +} + +function ctools_cache_simple_cache_clear($data, $key) { + // Ensure that if there is somehow no data, we at least don't stomp on other + // people's caches. + if (empty($data)) { + $data = 'simple_cache_plugin'; + } + + return ctools_object_cache_clear($data, $key); +} diff --git a/sites/all/modules/ctools/plugins/content_types/block/block.inc b/sites/all/modules/ctools/plugins/content_types/block/block.inc new file mode 100644 index 0000000000000000000000000000000000000000..2e4569fe35f3c62c17a995a6da47d9a5c236b98a --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/block/block.inc @@ -0,0 +1,416 @@ +<?php +// $Id: block.inc,v 1.17 2011/01/06 00:42:03 merlinofchaos Exp $ + +/** + * @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_info'); + 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_implements('block_info') as $module) { + $module_blocks = module_invoke($module, 'block_info'); + 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); + $info = (object) array( + 'module' => $module, + 'delta' => $delta, + ); + $block = module_invoke($module, 'block_view', $delta); + // Allow modules to modify the block before it is viewed, via either + // hook_block_view_alter() or hook_block_view_MODULE_DELTA_alter(). + drupal_alter(array('block_view', "block_view_{$module}_{$delta}"), $block, $info); + $block = (object) $block; + + 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. + global $theme_key; + $result = db_query("SELECT title FROM {block} + WHERE module = :module AND delta = :delta AND theme = :theme", array( + ':module' => 'block', ':delta' => $delta, ':theme' => $theme_key + ) + ); + $block->subject = check_plain($result->fetchObject()->title); + } + + 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'), + 'href' => "admin/structure/block/manage/$module/$delta/configure", + 'query' => drupal_get_destination(), + ), + ); + } + + return $block; +} + +/** + * Empty form so we can have the default override title. + */ +function ctools_block_content_type_edit_form($form, &$form_state) { + // Does nothing! + return $form; +} + +/** + * 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_info'); + 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 'active': + $info['icon'] = 'icon_core_activeforumtopics.png'; + break; + + case 'new': + $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('Custom blocks'); +} + +function user_ctools_block_info($module, $delta, &$info) { + $info['category'] = t('Activity'); + switch ($delta) { + case 'login': + $info['icon'] = 'icon_core_userlogin.png'; + $info['category'] = t('Widgets'); + break; + + case 'new': + $info['icon'] = 'icon_core_whosnew.png'; + break; + + case 'online': + $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) { + // Remove the main content fake block. + if ($delta == 'main') { + $info = NULL; + return; + } + + $menus = array('main-menu', 'management', 'navigation', 'user-menu'); + + if (in_array($delta, $menus)) { + $info['icon'] = 'icon_core_block_menu.png'; + $info['category'] = t('Menus'); + + if ($delta == 'navigation') { + $info['icon'] = 'icon_core_navigation.png'; + } + + return; + } + + $info['icon'] = 'icon_core_drupal.png'; + if ($delta == 'help') { + $info['category'] = t('Page elements'); + return; + } + + $info['category'] = t('Widgets'); +} diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_contrib_block.png b/sites/all/modules/ctools/plugins/content_types/block/icon_contrib_block.png new file mode 100644 index 0000000000000000000000000000000000000000..fa78ec179a83428e5b8e247890278cdf91a8cb3e Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_contrib_block.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_contrib_block_empty.png b/sites/all/modules/ctools/plugins/content_types/block/icon_contrib_block_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..6d0891b03d97142074cabbe5ed47175ad01c838e Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_contrib_block_empty.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_contrib_menu.png b/sites/all/modules/ctools/plugins/content_types/block/icon_contrib_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..38cf72090abaa16000c9dceedee8196df1c5251e Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_contrib_menu.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_contrib_page.png b/sites/all/modules/ctools/plugins/content_types/block/icon_contrib_page.png new file mode 100644 index 0000000000000000000000000000000000000000..4a2fa51d3856f366098978742cfe13e9389b487e Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_contrib_page.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_activeforumtopics.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_activeforumtopics.png new file mode 100644 index 0000000000000000000000000000000000000000..8414a8f8829be40a052814087e24c5800dcc6e4b Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_activeforumtopics.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_authorinformation.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_authorinformation.png new file mode 100644 index 0000000000000000000000000000000000000000..ab248f3f1bb62536bbf23296a949bfe05cd56bc7 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_authorinformation.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_block.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_block.png new file mode 100644 index 0000000000000000000000000000000000000000..b0d9628adf19efed3b30c847a7511fc093d469b9 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_block.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_block_empty.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_block_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..da08c64c64f2c6f7c5c34a442d4c1e3287f17053 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_block_empty.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_block_menu.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_block_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..84594431b705009714e569d99bf3a2739c42b7f5 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_block_menu.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_booknavigation.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_booknavigation.png new file mode 100644 index 0000000000000000000000000000000000000000..52dfca5369bfd5cabe1b46b7ab9ff54b7c8dc14c Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_booknavigation.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_languageswitcher.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_languageswitcher.png new file mode 100644 index 0000000000000000000000000000000000000000..dc4521fffadb3b58e0d6d8a4463e0f99ba17f4a7 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_languageswitcher.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_navigation.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_navigation.png new file mode 100644 index 0000000000000000000000000000000000000000..fb4c1f84f8261e47110d3414be92f9aa910c8646 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_navigation.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_newforumtopics.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_newforumtopics.png new file mode 100644 index 0000000000000000000000000000000000000000..70bbde26bbe02b474b610658a8a97f51707a4ea1 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_newforumtopics.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_page.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_page.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_page.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_popularcontent.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_popularcontent.png new file mode 100644 index 0000000000000000000000000000000000000000..70bbde26bbe02b474b610658a8a97f51707a4ea1 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_popularcontent.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_primarylinks.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_primarylinks.png new file mode 100644 index 0000000000000000000000000000000000000000..6dafb99ed084232acc18dfccb2b8f8327051245a Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_primarylinks.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_recentblogposts.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_recentblogposts.png new file mode 100644 index 0000000000000000000000000000000000000000..785207ac49e311f1716220982f79afe382c861bb Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_recentblogposts.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_recentcomments.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_recentcomments.png new file mode 100644 index 0000000000000000000000000000000000000000..ba96e32a31863c59c6ecab8df957c0da95437532 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_recentcomments.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_recentpoll.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_recentpoll.png new file mode 100644 index 0000000000000000000000000000000000000000..c23fa23e65cc833643971cf2fe2bdbbb0a800348 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_recentpoll.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_searchform.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_searchform.png new file mode 100644 index 0000000000000000000000000000000000000000..3ad1deb65c4a1cada8cdedb7619f3ed5e8ff0587 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_searchform.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_syndicate.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_syndicate.png new file mode 100644 index 0000000000000000000000000000000000000000..27c54bf00c8ef49996f633cef4f998aa6445833b Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_syndicate.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_userlogin.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_userlogin.png new file mode 100644 index 0000000000000000000000000000000000000000..dc4521fffadb3b58e0d6d8a4463e0f99ba17f4a7 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_userlogin.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_whosnew.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_whosnew.png new file mode 100644 index 0000000000000000000000000000000000000000..51303e7fae68ef81eb001d8231f486bcf02afee2 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_whosnew.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/icon_core_whosonline.png b/sites/all/modules/ctools/plugins/content_types/block/icon_core_whosonline.png new file mode 100644 index 0000000000000000000000000000000000000000..a5896e3a54bbe148beddc5ef31aa4f93329b60a2 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/block/icon_core_whosonline.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/block/translations/plugins-content_types-block.hu.po b/sites/all/modules/ctools/plugins/content_types/block/translations/plugins-content_types-block.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..c375de65032d0f7821ad16fce5ec6272fc677df2 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/block/translations/plugins-content_types-block.hu.po @@ -0,0 +1,34 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 12:48+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 "Block" +msgstr "Blokk" +msgid "Feeds" +msgstr "Hírcsatornák" +msgid "Activity" +msgstr "Tevékenység" +msgid "Configure block" +msgstr "Blokk beállítása" +msgid "Menus" +msgstr "Menük" +msgid "Miscellaneous" +msgstr "Egyéb" +msgid "Deleted/missing block @module-@delta" +msgstr "Törölt/hiányzó @module-@delta blokk" +msgid "" +"Configure this block's 'block settings' in administer >> site building " +">> blocks" +msgstr "" +"Ennek a blokknak a beállításait az Adminisztráció\r\n" +" >> Webhelyépítés >> Blokkok oldalon lehet módosítani" diff --git a/sites/all/modules/ctools/plugins/content_types/contact/contact.inc b/sites/all/modules/ctools/plugins/content_types/contact/contact.inc new file mode 100644 index 0000000000000000000000000000000000000000..10c81e93ff012137c3a2db7c4b0ba5b918bede2a --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/contact/contact.inc @@ -0,0 +1,61 @@ +<?php +// $Id: contact.inc,v 1.4 2010/10/11 22:18:24 sdboyer Exp $ + +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. + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/content_types/contact/icon_contact.png b/sites/all/modules/ctools/plugins/content_types/contact/icon_contact.png new file mode 100644 index 0000000000000000000000000000000000000000..ab248f3f1bb62536bbf23296a949bfe05cd56bc7 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/contact/icon_contact.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/contact/translations/plugins-content_types-contact.hu.po b/sites/all/modules/ctools/plugins/content_types/contact/translations/plugins-content_types-contact.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..4cd35aaa6005d35979a9436d75e92b17a4eede0d --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/contact/translations/plugins-content_types-contact.hu.po @@ -0,0 +1,32 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-11-30 07:50+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 "User contact form" +msgstr "Felhasználói kapcsolatfelvételi űrlap" +msgid "Contact" +msgstr "Kapcsolat" +msgid "Contact form" +msgstr "Kapcsolatfelvételi űrlap" +msgid "" +"The site contact form that allows users to send a message to site " +"administrators." +msgstr "" +"A webhely kapcsolatfelvételi űrlapja, amely lehetővé teszi, hogy a " +"felhasználók üzenetet küldjenek a webhely adminisztrátorainak." +msgid "The site contact form that allows users to contact other users." +msgstr "" +"A webhely kapcsolatfelvételi űrlapja, amely lehetővé teszi, hogy a " +"felhasználók felvegyék a kapcsolatot más felhasználókkal." +msgid "Contact @name" +msgstr "Kapcsolatfelvétel @name felhasználóval" diff --git a/sites/all/modules/ctools/plugins/content_types/contact/user_contact.inc b/sites/all/modules/ctools/plugins/content_types/contact/user_contact.inc new file mode 100644 index 0000000000000000000000000000000000000000..a558981645467acaa82f8fbfa53bf24df6d11654 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/contact/user_contact.inc @@ -0,0 +1,66 @@ +<?php +// $Id: user_contact.inc,v 1.3 2010/01/29 20:18:01 merlinofchaos Exp $ + +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/sites/all/modules/ctools/plugins/content_types/custom/custom.inc b/sites/all/modules/ctools/plugins/content_types/custom/custom.inc new file mode 100644 index 0000000000000000000000000000000000000000..54460d05ba4e433c94287baa0ae294bcd9fd0c52 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/custom/custom.inc @@ -0,0 +1,408 @@ +<?php +// $Id: custom.inc,v 1.17 2011/01/05 22:57:26 merlinofchaos Exp $ + +/** + * @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_fallback_format(), '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_fallback_format(), + '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); + } + + $block->content = check_markup($content, $settings['format']); + 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) { + $filter = filter_format_load($settings['format']); + if (!filter_access($filter)) { + 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'] = array( + '#type' => 'text_format', + '#title' => t('Body'), + '#default_value' => $settings['body'], + '#format' => $settings['format'], + ); + + 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)), + ); + return $form; +} + +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. + // Because of changes in filter form, these two keys are out of position: + $form_state['conf']['body'] = $form_state['values']['body']['value']; + $form_state['conf']['format'] = $form_state['values']['body']['format']; + + foreach (array_keys($form_state['plugin']['defaults']) as $key) { + if (isset($form_state['values'][$key]) && $key != 'body' && $key != 'format') { + $form_state['conf'][$key] = $form_state['values'][$key]; + } + } + } +} diff --git a/sites/all/modules/ctools/plugins/content_types/custom/icon_block_custom.png b/sites/all/modules/ctools/plugins/content_types/custom/icon_block_custom.png new file mode 100644 index 0000000000000000000000000000000000000000..bbde4bd57c4731ddcb109da8aed4398bc587a8fd Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/custom/icon_block_custom.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/custom/translations/plugins-content_types-custom.hu.po b/sites/all/modules/ctools/plugins/content_types/custom/translations/plugins-content_types-custom.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..8e21689d2fcbd5ede20e838a48cd70b81ac80b8a --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/custom/translations/plugins-content_types-custom.hu.po @@ -0,0 +1,40 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-11-30 10:48+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 "Body" +msgstr "Törzs" +msgid "Value" +msgstr "Érték" +msgid "New custom content" +msgstr "Új egyedi tartalom" +msgid "Create a completely custom piece of HTML content." +msgstr "Egy teljesen egyedi HTML tartalom létrehozása." +msgid "Use context keywords" +msgstr "Környezetkulcsszavak használata" +msgid "If checked, context keywords will be substituted in this content." +msgstr "" +"Ha be van jelölve, a környezetkulcsszavak behelyettesíthetőek " +"lesznek ebbe a tartalomba." +msgid "Substitutions" +msgstr "Helyettesítések" +msgid "@identifier: @title" +msgstr "@identifier: @title" +msgid "Custom: @title" +msgstr "Egyedi: @title" +msgid "" +"This title will be used administratively to identify this pane. If " +"blank, the regular title will be used." +msgstr "" +"A cím adminisztratív célból lesz használva a tábla " +"azonosításához. Ha üres, akkor a rendes cím lesz használva." diff --git a/sites/all/modules/ctools/plugins/content_types/entity_context/entity_field.inc b/sites/all/modules/ctools/plugins/content_types/entity_context/entity_field.inc new file mode 100644 index 0000000000000000000000000000000000000000..1b967fd52a53679a045d7b5865da0161bd7c146c --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/entity_context/entity_field.inc @@ -0,0 +1,171 @@ +<?php +// $Id: entity_field.inc,v 1.3 2011/01/05 22:57:26 merlinofchaos Exp $ + +$plugin = array( + 'title' => t('Entity field'), + 'defaults' => array('label' => '', 'formatter' => ''), + 'content type' => 'ctools_entity_field_content_type_content_type', +); + +/** + * 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 ctools_entity_field_content_type_content_type($subtype) { + $types = ctools_entity_field_content_type_content_types(); + if (isset($types[$subtype])) { + return $types[$subtype]; + } +} + +/** + * Return all field content types available. + */ +function ctools_entity_field_content_type_content_types() { + // This will hold all the individual field content types. + $types = array(); + $context_types = array(); + $entities = entity_get_info(); + + foreach ($entities as $entity_type => $entity) { + foreach ($entity['bundles'] as $type => $bundle) { + foreach (field_info_instances($entity_type, $type) as $field_name => $field) { + if (!isset($types[$entity_type .':'. $field_name])) { + $types[$entity_type .':'. $field_name] = array( + 'category' => t(ucfirst($entity_type)), + 'icon' => 'icon_field.png', + 'title' => t('Field: @widget_label (@field_name) - @field_type', array( + '@widget_label' => t($field['label']), + '@field_name' => $field_name, + '@field_type' => t($field['widget']['type']), + )), + 'description' => t('Field on the referenced entity.'), + 'edit form' => array( + 'ctools_entity_field_content_type_formatter_options' => array( + 'default' => TRUE, + 'title' => t('Formatter Options'), + ), + 'ctools_entity_field_content_type_formatter_styles' => t('Formatter Styles'), + ), + ); + } + $context_types[$entity_type .':'. $field_name]['types'][$type] = $bundle['label']; + } + } + } + + // Create the required context for each field related to the bundle types. + foreach ($types as $key => $field_content_type) { + list($entity_type, $field_name) = explode(':', $key, 2); + $types[$key]['required context'] = new ctools_context_required(t(ucfirst($entity_type)), $entity_type, array( + 'type' => array_keys($context_types[$key]['types']), + )); + unset($context_types[$key]['types']); + } + return $types; +} + +/** +* Render the custom content type. +*/ +function ctools_entity_field_content_type_render($subtype, $conf, $panel_args, $context) { + if (empty($context) || empty($context->data)) { + return; + } + + // Get a shortcut to the entity. + $entity = $context->data; + list($entity_type, $field_name) = explode(':', $subtype, 2); + + // Load the entity type's information for this field. + $ids = entity_extract_ids($entity_type, $entity); + $field = field_info_instance($entity_type, $field_name, $ids[2]); + + // Do not render if the entity type does not have this field. + if (empty($field)) { + return; + } + $language = field_language($entity_type, $entity, $field_name); + + // Build the content type block. + $block = new stdClass(); + $block->module = 'entity_field'; + $block->title = $field['label']; + $block->content = field_view_field($entity_type, $entity, $field_name, ($conf['formatter_settings'] ? array('label' => 'hidden', 'type' => $conf['formatter'], 'settings' => $conf['formatter_settings']) : array('label' => 'hidden', 'type' => $conf['formatter'])), $language); + $block->delta = $ids[0]; + + return $block; +} + +/** +* Returns an edit form for custom type settings. +*/ +function ctools_entity_field_content_type_formatter_options($form, &$form_state) { + if (empty($form_state['conf']['formatter_settings'])) { + $form_state['conf']['formatter_settings'] = array(); + } + $conf = $form_state['conf']; + $subtype = $form_state['subtype_name']; + list($entity_type, $field_name) = explode(':', $subtype, 2); + + $field = field_info_field($field_name); + module_load_include('inc', 'field_ui', 'field_ui.admin'); + $formatter_options = field_ui_formatter_options($field['type']); + + $form['formatter'] = array( + '#type' => 'select', + '#title' => t('Select a formatter'), + '#options' => $formatter_options, + '#default_value' => $conf['formatter'], + ); + + return $form; +} + +function ctools_entity_field_content_type_formatter_options_submit($form, &$form_state) { + $form_state['conf']['formatter'] = $form_state['values']['formatter']; +} + +function ctools_entity_field_content_type_formatter_styles($form, &$form_state) { + if (!$form_state['conf']['formatter_settings']) { + $form_state['conf']['formatter_settings'] = array(); + } + $conf = $form_state['conf']; + $subtype = $form_state['subtype_name']; + list($entity_type, $field_name) = explode(':', $subtype, 2); + $field = field_info_field($field_name); + module_load_include('inc', 'field_ui', 'field_ui.admin'); + + ctools_include('fields'); + $form['ctools_field_list'] = array( + '#type' => 'value', + '#value' => array(), + ); + + ctools_fields_get_field_formatter_settings_form($field, $conf['formatter'], $form, $form_state); + return $form; +} + +function ctools_entity_field_content_type_formatter_styles_submit($form, &$form_state) { + $fields = $form_state['values']['ctools_field_list']; + $formatter_info = ctools_fields_get_field_formatter_info($fields); + foreach ($formatter_info as $info) { + if (!empty($info['settings'])) { + foreach ($info['settings'] as $field_name => $value) { + if (!empty($form_state['values'][$field_name])) { + $form_state['conf']['formatter_settings'][$field_name] = $form_state['values'][$field_name]; + } + } + } + } +} + +/** +* Returns the administrative title for a type. +*/ +function ctools_entity_field_content_type_admin_title($subtype, $conf, $context) { + return t('"@s" @field', array('@s' => $context->identifier, '@field' => $subtype)); +} diff --git a/sites/all/modules/ctools/plugins/content_types/form/form.inc b/sites/all/modules/ctools/plugins/content_types/form/form.inc new file mode 100644 index 0000000000000000000000000000000000000000..4fb0380c6395d7f6d5b2893d238c3492fa9fbee9 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/form/form.inc @@ -0,0 +1,57 @@ +<?php +// $Id: form.inc,v 1.3 2010/10/11 22:18:24 sdboyer Exp $ + +/** + * 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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/form/icon_form.png b/sites/all/modules/ctools/plugins/content_types/form/icon_form.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/form/icon_form.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/form/translations/plugins-content_types-form.hu.po b/sites/all/modules/ctools/plugins/content_types/form/translations/plugins-content_types-form.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..0f3425b6a878b62b77822b02e7b724145ceb9ded --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/form/translations/plugins-content_types-form.hu.po @@ -0,0 +1,22 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-11-12 20:02+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 "General form" +msgstr "Általános űrlap" +msgid "Form goes here." +msgstr "Ide jön az űrlap." +msgid "\"@s\" base form" +msgstr "„@s” alap űrlap" +msgid "Everything in the form that is not displayed by other content." +msgstr "Minden az űrlapon, amit más környezetek nem jelenítenek meg." diff --git a/sites/all/modules/ctools/plugins/content_types/node/icon_node.png b/sites/all/modules/ctools/plugins/content_types/node/icon_node.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/node/icon_node.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/node/node.inc b/sites/all/modules/ctools/plugins/content_types/node/node.inc new file mode 100644 index 0000000000000000000000000000000000000000..33a24ae3b3b834f6d270d7fbd02f5ff89c85d215 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node/node.inc @@ -0,0 +1,243 @@ +<?php +// $Id: node.inc,v 1.11 2010/12/31 21:09:56 merlinofchaos Exp $ + +/** + * @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; + } + + $block->module = 'node'; + $block->delta = $node->nid; + + if (!empty($conf['link_node_title'])) { + $block->title = l($node->title, 'node/' . $node->nid); + } + else { + $block->title = check_plain($node->title); + } + + 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'; + } + + $block->content = node_view($node, $conf['build_mode']); + 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.'), + ); + + $entity = entity_get_info('node'); + $build_mode_options = array(); + foreach ($entity['view modes'] as $mode => $option) { + $build_mode_options[$mode] = $option['label']; + } + + // 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; +} + +/** + * 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_query('SELECT nid FROM {node} WHERE nid = :nid', array(':nid' => $nid))->fetchObject(); + } + else { + $node = db_query('SELECT nid FROM {node} WHERE LOWER(title) = LOWER(:title)', array(':title' => $nid))->fetchObject(); + } + 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/sites/all/modules/ctools/plugins/content_types/node/translations/plugins-content_types-node.hu.po b/sites/all/modules/ctools/plugins/content_types/node/translations/plugins-content_types-node.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..d13fd24365d57aefb8650db121e020a10d17b9bd --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node/translations/plugins-content_types-node.hu.po @@ -0,0 +1,32 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-10 10:17+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 "Add a node from your site as content." +msgstr "A webhely egy tarlamának hozzáadása tartalomként." +msgid "" +"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." +msgstr "" +"A webcímben található tartalomazonosító kinyeréséhez a %0, %1, " +"..., %N hasznáható, illetve @0, @1, @2, ..., @N a panelnak átadott " +"argumentumok használatához." +msgid "Invalid node" +msgstr "Érvénytelen tartalom" +msgid "Node loaded from @var" +msgstr "A tartalom betöltve innen: @var" +msgid "Deleted/missing node @nid" +msgstr "Törölt/hiányzó tartalom @nid" +msgid "Existing node" +msgstr "Létező tartalom" diff --git a/sites/all/modules/ctools/plugins/content_types/node_context/icon_node.png b/sites/all/modules/ctools/plugins/content_types/node_context/icon_node.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/node_context/icon_node.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/node_context/node_attachments.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_attachments.inc new file mode 100644 index 0000000000000000000000000000000000000000..97eb6aa0df84f5a81385dc13b1dafa01291b1c93 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_attachments.inc @@ -0,0 +1,45 @@ +<?php +// $Id: node_attachments.inc,v 1.4 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * 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) ? 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. + return $form; +} + diff --git a/sites/all/modules/ctools/plugins/content_types/node_context/node_author.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_author.inc new file mode 100644 index 0000000000000000000000000000000000000000..75f5376ccaaccaeefd84824e0998dcf3399f3c63 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_author.inc @@ -0,0 +1,72 @@ +<?php +// $Id: node_author.inc,v 1.6 2011/01/02 16:44:11 merlinofchaos Exp $ + +/** + * 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; + $user = user_load($node->uid); + + // Build the content type block. + $block = new stdClass(); + $block->module = 'node_author'; + $block->title = t('Author'); + $block->content = !empty($conf['link']) ? theme('username', array('account' => $user, 'link_path' => 'user/'. $node->uid)) : check_plain(format_username($node)); + $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.'), + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/content_types/node_context/node_body.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_body.inc new file mode 100644 index 0000000000000000000000000000000000000000..0923c988e2467c171a0ab0cacfa540566bda2c80 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_body.inc @@ -0,0 +1,61 @@ +<?php +// $Id: node_body.inc,v 1.6 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * 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_type_get_type($node); + + // 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. + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/content_types/node_context/node_book_children.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_book_children.inc new file mode 100644 index 0000000000000000000000000000000000000000..3336719241bbc17b5f9302b6a01fbb48f9b601a8 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_book_children.inc @@ -0,0 +1,43 @@ +<?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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_context/node_book_nav.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_book_nav.inc new file mode 100644 index 0000000000000000000000000000000000000000..9b93a6bf2d8664e8eb4e846dbc647bd6b867699e --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_book_nav.inc @@ -0,0 +1,44 @@ +<?php +// $Id: node_book_nav.inc,v 1.4 2010/10/11 22:18:22 sdboyer Exp $ + +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) ? 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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_context/node_comment_form.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_comment_form.inc new file mode 100644 index 0000000000000000000000000000000000000000..6706e450a087fe6b513cc1f269adbd12855c6b5e --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_comment_form.inc @@ -0,0 +1,97 @@ +<?php +// $Id: node_comment_form.inc,v 1.6 2010/12/31 21:16:51 merlinofchaos Exp $ + +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) ? 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 == COMMENT_NODE_OPEN) { + $comment = new stdClass(); + $comment->nid = $node->nid; + $comment->pid = NULL; + $form_state = array( + 'ctools comment alter' => TRUE, + 'node' => $node, + 'build_info' => array( + 'args' => array( + $comment, + ), + ), + ); + $block->content = drupal_build_form('comment_node_'. $node->type .'_form', $form_state); + } + else if (!empty($conf['anon_links'])) { + $block->content = theme('comment_post_forbidden', array('node' => $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'], + ); + return $form; +} + +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/sites/all/modules/ctools/plugins/content_types/node_context/node_comments.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_comments.inc new file mode 100644 index 0000000000000000000000000000000000000000..5aa9770597cbb524838a540ea95c589fc73370fc --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_comments.inc @@ -0,0 +1,130 @@ +<?php +// $Id: node_comments.inc,v 1.9 2010/12/31 21:04:28 merlinofchaos Exp $ + +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), + 'comments_per_page' => variable_get('comment_default_per_page', '50'), + ), + ); +} + +function ctools_node_comments_content_type_render($subtype, $conf, $panel_args, $context) { + $node = isset($context->data) ? 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); + } + + return $block; +} + +function ctools_node_comments_content_type_edit_form($form, &$form_state) { + $conf = $form_state['conf']; + $form['mode'] = array( + '#type' => 'select', + '#title' => t('Mode'), + '#default_value' => $conf['mode'], + '#options' => _comment_get_modes(), + '#weight' => 1, + ); + 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' => 3, + ); + return $form; +} + +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']; + $comments_per_page = $conf['comments_per_page']; + + // Multiple comment view + $query = db_select('comment', 'c')->extend('PagerDefault'); + $query->addField('c', 'cid'); + $query + ->condition('c.nid', $node->nid) + ->addTag('node_access') + ->limit($comments_per_page); + + $count_query = db_select('comment', 'c'); + $count_query->addExpression('COUNT(*)'); + $count_query + ->condition('c.nid', $node->nid) + ->addTag('node_access'); + + if (!user_access('administer comments')) { + $query->condition('c.status', COMMENT_PUBLISHED); + $count_query->condition('c.status', COMMENT_PUBLISHED); + } + if ($mode === COMMENT_MODE_FLAT) { + $query->orderBy('c.cid', 'ASC'); + } + else { + // See comment above. Analysis reveals that this doesn't cost too + // much. It scales much much better than having the whole comment + // structure. + $query->orderBy('SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))', 'ASC'); + } + + $query->setCountQuery($count_query); + $cids = $query->execute()->fetchCol(); + + $comments = comment_load_multiple($cids); + + if ($comments) { + drupal_add_css(drupal_get_path('module', 'comment') .'/comment.css'); + comment_prepare_thread($comments); + $build = comment_view_multiple($comments, $node); + $build['pager']['#theme'] = 'pager'; + return drupal_render($build); + } + return; +} + diff --git a/sites/all/modules/ctools/plugins/content_types/node_context/node_content.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_content.inc new file mode 100644 index 0000000000000000000000000000000000000000..a4a49f33219f4545976995682ee3151bdd91f920 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_content.inc @@ -0,0 +1,204 @@ +<?php +// $Id: node_content.inc,v 1.9 2010/12/31 21:05:24 merlinofchaos Exp $ + +/** + * 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, + '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) ? 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 (!empty($conf['link']) && $node) { + $block->title_link = "node/$node->nid"; + } + + return $block; +} + +function ctools_node_content_render_node($node, $conf) { + if (empty($node->content)) { + // Copied from node_build_content() so we can fiddle with it as we render. + $node->content = array(); + + // The 'view' hook can be implemented to overwrite the default function + // to display nodes. + if (node_hook($node, 'view')) { + $node = node_invoke($node, 'view', $conf['build_mode']); + } + + // Build fields content. + // In case of a multiple view, node_view_multiple() already ran the + // 'prepare_view' step. An internal flag prevents the operation from running + // twice. + field_attach_prepare_view('node', array($node->nid => $node), $conf['build_mode']); + entity_prepare_view('node', array($node->nid => $node)); + $node->content += field_attach_view('node', $node, $conf['build_mode']); + + // Always display a read more link on teasers because we have no way + // to know when a teaser view is different than a full view. + $links = array(); + if ($conf['build_mode'] == 'teaser') { + $links['node-readmore'] = array( + 'title' => t('Read more'), + 'href' => 'node/' . $node->nid, + 'attributes' => array('rel' => 'tag', 'title' => strip_tags($node->title)) + ); + } + + $node->content['links'] = array( + '#theme' => 'links__node', + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + ); + + if (empty($conf['no_extras'])) { + // Allow modules to make their own additions to the node. + module_invoke_all('node_view', $node, $conf['build_mode']); + module_invoke_all('entity_view', $node, 'node', $conf['build_mode']); + } + } + + // Set the proper node part, then unset unused $node part so that a bad + // theme can not open a security hole. + $content = $node->content; + + $content += array( + '#theme' => 'node', + '#node' => $node, + '#view_mode' => $conf['build_mode'], + '#language' => NULL, + ); + + // Add contextual links for this node, except when the node is already being + // displayed on its own page. Modules may alter this behavior (for example, + // to restrict contextual links to certain view modes) by implementing + // hook_node_view_alter(). + if (!empty($node->nid) && !($conf['build_mode'] == 'full' && node_is_page($node))) { + $content['#contextual_links']['node'] = array('node', array($node->nid)); + } + + // Allow modules to modify the structured node. + $type = 'node'; + drupal_alter(array('node_view', 'entity_view'), $content, $type); + + // Kill the links if not requested. + if (!$conf['links']) { + $content['links']['#access'] = FALSE; + } + + return $content; +} + +/** + * 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['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.'), + ); + + $entity = entity_get_info('node'); + $build_mode_options = array(); + foreach ($entity['view modes'] as $mode => $option) { + $build_mode_options[$mode] = $option['label']; + } + + $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/sites/all/modules/ctools/plugins/content_types/node_context/node_created.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_created.inc new file mode 100644 index 0000000000000000000000000000000000000000..789d6c86f9450dfed683ae552fea6f0f809326aa --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_created.inc @@ -0,0 +1,75 @@ +<?php +// $Id: node_created.inc,v 1.4 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * 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']; + + $form['format'] = array( + '#title' => t('Date format'), + '#type' => 'select', + '#options' => array( + 'small' => format_date(REQUEST_TIME, 'small'), + 'medium' => format_date(REQUEST_TIME, 'medium'), + 'large' => format_date(REQUEST_TIME, 'large'), + ), + '#default_value' => $conf['format'], + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/content_types/node_context/node_links.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_links.inc new file mode 100644 index 0000000000000000000000000000000000000000..a2da7b22871d7995b1606baf54ca118d95322a7c --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_links.inc @@ -0,0 +1,106 @@ +<?php +// $Id: node_links.inc,v 1.6 2010/12/31 21:06:18 merlinofchaos Exp $ + +/** + * 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' => '', + 'build_mode' => '', + '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) ? 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; + node_build_content($node, $conf['build_mode']); + $block->content = $node->content['links']; + } + + if (!empty($conf['link']) && $node) { + $block->title_link = "node/$node->nid"; + } + return $block; +} + +/** + * 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.'), + ); + + $entity = entity_get_info('node'); + $build_mode_options = array(); + foreach ($entity['view modes'] as $mode => $option) { + $build_mode_options[$mode] = $option['label']; + } + + $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'], + ); + + $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/sites/all/modules/ctools/plugins/content_types/node_context/node_terms.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_terms.inc new file mode 100644 index 0000000000000000000000000000000000000000..55620065fff91cab93cab5f6681ef0f8b8341750 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_terms.inc @@ -0,0 +1,188 @@ +<?php +// $Id: node_terms.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * 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="clearfix">', + '#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="clearfix">', + '#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="clearfix">', + '#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')), + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/content_types/node_context/node_title.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_title.inc new file mode 100644 index 0000000000000000000000000000000000000000..ef31a5374712d70539c854a87146bc6b772ec663 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_title.inc @@ -0,0 +1,74 @@ +<?php +// $Id: node_title.inc,v 1.5 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * 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_type_get_type($node); + + // 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.'), + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/content_types/node_context/node_type_desc.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_type_desc.inc new file mode 100644 index 0000000000000000000000000000000000000000..f1aff821d3fa99ae959dbc9322ae1d98caf34c88 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_type_desc.inc @@ -0,0 +1,48 @@ +<?php +// $Id: node_type_desc.inc,v 1.4 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * 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) ? clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'node_type'; + + if ($node) { + $type = node_type_get_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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_context/node_updated.inc b/sites/all/modules/ctools/plugins/content_types/node_context/node_updated.inc new file mode 100644 index 0000000000000000000000000000000000000000..a38a208977f296df4f124ddb8f561045989efe7e --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/node_updated.inc @@ -0,0 +1,75 @@ +<?php +// $Id: node_updated.inc,v 1.5 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * 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']; + + $form['format'] = array( + '#title' => t('Date format'), + '#type' => 'select', + '#options' => array( + 'small' => format_date(REQUEST_TIME, 'small'), + 'medium' => format_date(REQUEST_TIME, 'medium'), + 'large' => format_date(REQUEST_TIME, 'large'), + ), + '#default_value' => $conf['format'], + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/content_types/node_context/translations/plugins-content_types-node_context.hu.po b/sites/all/modules/ctools/plugins/content_types/node_context/translations/plugins-content_types-node_context.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..0f006701bb90c949319d2a66fe2a0077cd81747c --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_context/translations/plugins-content_types-node_context.hu.po @@ -0,0 +1,151 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 12:50+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 "Author" +msgstr "Szerző" +msgid "Comments" +msgstr "Hozzászólások" +msgid "Comment form" +msgstr "Hozzászólás űrlap" +msgid "Node links" +msgstr "Tartalom hivatkozások" +msgid "Mode" +msgstr "Mód" +msgid "Created date" +msgstr "Létrehozás dátuma" +msgid "Link to node" +msgstr "Hivatkozás tartalomra" +msgid "Node body" +msgstr "Tartalom törzse" +msgid "Node type description" +msgstr "Tartalom típusának leírása" +msgid "Attached files" +msgstr "Csatolt fájlok" +msgid "Attached files go here." +msgstr "Ide jönnek a csatolt fájlok." +msgid "A list of files attached to the node." +msgstr "Egy lista a tartalomhoz csatolt fájlokról." +msgid "\"@s\" attachments" +msgstr "„@s” csatolmány" +msgid "Book navigation" +msgstr "Könyv navigáció" +msgid "Book navigation goes here." +msgstr "Ide jön a könyv navigációja." +msgid "\"@s\" book navigation" +msgstr "„@s” könyv navigáció" +msgid "Add comment" +msgstr "Új hozzászólás" +msgid "Comment form here." +msgstr "Ide jön a hozzászólás űrlapja." +msgid "A form to add a new comment." +msgstr "Egy űrlap új hozzászólás hozzáadásához." +msgid "\"@s\" comment form" +msgstr "„@s” hozzászólás űrlap" +msgid "Node comments" +msgstr "Tartalom hozzászólásai" +msgid "Node comments go here." +msgstr "Ide jönnek a tartalom hozzászólásai." +msgid "The comments of the referenced node." +msgstr "A hivatkozott tartalom hozzászólásai." +msgid "Sort" +msgstr "Sorbarendezés" +msgid "!a comments per page" +msgstr "!a hozzászólás egy oldalon" +msgid "Pager" +msgstr "Lapozó" +msgid "\"@s\" comments" +msgstr "„@s” hozzászólásai" +msgid "Node content" +msgstr "Tartalom" +msgid "The content of the referenced node." +msgstr "A hivatkozott tartalom tartalma." +msgid "Node content goes here." +msgstr "Ide jön a tartalom." +msgid "No extras" +msgstr "Nincsenek extrák" +msgid "" +"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." +msgstr "" +"Bejelölve letiltja a modulok által a tartalomhoz biztosított olyan " +"kiegészítéseket, mint a csatolt fájlok és a CCK mezők; ez csak " +"az alap bevezetőt és törzset jeleníti meg." +msgid "\"@s\" content" +msgstr "„@s” tartalom" +msgid "Node type description goes here." +msgstr "Ide jön a tartalom típusának leírása." +msgid "Node type description." +msgstr "Tartalom típusának leírása." +msgid "\"@s\" type description" +msgstr "„@s” típusleírás" +msgid "The author of the referenced node." +msgstr "A hivatkozott tartalom szerzője." +msgid "Link to author profile" +msgstr "Hivatkozás a szerző profiljára" +msgid "Check here to link to the node author profile." +msgstr "" +"Be kell jelölni a tartalom szerzőjének profiljára történő " +"hivatkozáshoz." +msgid "\"@s\" author" +msgstr "„@s” szerző" +msgid "The body of the referenced node." +msgstr "A hivatkozott tartalom törzse." +msgid "\"@s\" body" +msgstr "„@s” törzs" +msgid "The navigation menu the book the node belongs to." +msgstr "A tartalomhoz tartozó könyv navigációs menü." +msgid "Node created date" +msgstr "Tartalom létrehozásának dátuma" +msgid "The date the referenced node was created." +msgstr "Az a dátum amikor a hivatkozott tartalom létrejött." +msgid "\"@s\" created date" +msgstr "„@s” létrehozás dátuma" +msgid "Node links of the referenced node." +msgstr "A hivatkozott tartalom tartalomhivatkozásai." +msgid "Node links go here." +msgstr "Ide jönnek a tartalom hivatkozások." +msgid "Teaser mode" +msgstr "Bevezető mód" +msgid "Check here to show links in teaser mode." +msgstr "" +"Be kell jelölni, hogy a hivatkozások megjelenjenek előnézeti " +"módban." +msgid "" +"Whatever is placed here will appear in $node->panel_identifier to help " +"theme node links displayed on the panel" +msgstr "" +"Bármi kerül ide, meg fog jelenni a $node->panel_identifier " +"változóban, hogy segítse a smink tartalomhivatkozásainak " +"megjelenítését a panelen." +msgid "\"@s\" links" +msgstr "„@s” hivatkozás" +msgid "The title of the referenced node." +msgstr "A hivatkozott tartalom címe." +msgid "\"@s\" title" +msgstr "„@s” cím" +msgid "Node last updated date" +msgstr "Tartalom utolsó frissítésének dátuma" +msgid "The date the referenced node was last updated." +msgstr "Az a dátum amikor a hivatkozott tartalom utoljára frissítve lett." +msgid "Last updated date" +msgstr "Utolsó frissítés dátuma" +msgid "\"@s\" last updated date" +msgstr "„@s” utolsó módosításának dátuma" +msgid "Treat this as the primary node page" +msgstr "Elsődleges tartalomoldalként kezelés" +msgid "This can affect title rendering and breadcrumbs from some node types." +msgstr "" +"Befolyásolhatja néhány tartalomtípusnál a cím létrehozását " +"és a morzsát." diff --git a/sites/all/modules/ctools/plugins/content_types/node_form/icon_node_form.png b/sites/all/modules/ctools/plugins/content_types/node_form/icon_node_form.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/node_form/icon_node_form.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/node_form/node_form_attachments.inc b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_attachments.inc new file mode 100644 index 0000000000000000000000000000000000000000..01d3f6344cc97b12fa02062498c1d9bb2c501f80 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_attachments.inc @@ -0,0 +1,46 @@ +<?php +// $Id: node_form_attachments.inc,v 1.4 2010/10/11 22:18:23 sdboyer Exp $ + +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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_form/node_form_author.inc b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_author.inc new file mode 100644 index 0000000000000000000000000000000000000000..507acd8719364f623db4d1752a2e228cd40b2a92 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_author.inc @@ -0,0 +1,46 @@ +<?php +// $Id: node_form_author.inc,v 1.4 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * 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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_form/node_form_book.inc b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_book.inc new file mode 100644 index 0000000000000000000000000000000000000000..f6c24cbbce2e330ee999ae0756fe7fecebb5dc93 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_book.inc @@ -0,0 +1,50 @@ +<?php +// $Id: node_form_book.inc,v 1.4 2010/10/11 22:18:23 sdboyer Exp $ + +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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_form/node_form_buttons.inc b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_buttons.inc new file mode 100644 index 0000000000000000000000000000000000000000..78bb9965ff823507c4939b76956b1c91bbb6b5af --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_buttons.inc @@ -0,0 +1,43 @@ +<?php +// $Id: node_form_buttons.inc,v 1.4 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * 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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_form/node_form_comment.inc b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_comment.inc new file mode 100644 index 0000000000000000000000000000000000000000..0b3e1cbadc4fbf57455840f98c7fdf8b6abe0ce2 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_comment.inc @@ -0,0 +1,46 @@ +<?php +// $Id: node_form_comment.inc,v 1.4 2010/10/11 22:18:23 sdboyer Exp $ + +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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_form/node_form_input_format.inc b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_input_format.inc new file mode 100644 index 0000000000000000000000000000000000000000..8a03586b784c16839380f094980491400cedf1a8 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_input_format.inc @@ -0,0 +1,44 @@ +<?php +// $Id: node_form_input_format.inc,v 1.4 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * 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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_form/node_form_log.inc b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_log.inc new file mode 100644 index 0000000000000000000000000000000000000000..0dfe7402dd256f67265b725f730cf989d10176c0 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_log.inc @@ -0,0 +1,33 @@ +<?php +// $Id: node_form_log.inc,v 1.3 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * 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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_form/node_form_menu.inc b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..d5ef59d58b44a4015fe678f39818b9558f7c8ae9 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_menu.inc @@ -0,0 +1,47 @@ +<?php +// $Id: node_form_menu.inc,v 1.4 2010/10/11 22:18:23 sdboyer Exp $ + +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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_form/node_form_path.inc b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_path.inc new file mode 100644 index 0000000000000000000000000000000000000000..f47e997348fb1022e0cd9b48638e6070d08b2fbe --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_path.inc @@ -0,0 +1,47 @@ +<?php +// $Id: node_form_path.inc,v 1.4 2010/10/11 22:18:23 sdboyer Exp $ + +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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_form/node_form_publishing.inc b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_publishing.inc new file mode 100644 index 0000000000000000000000000000000000000000..a45160f2959fef186684e16c132f80bb24144ce8 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_publishing.inc @@ -0,0 +1,50 @@ +<?php +// $Id: node_form_publishing.inc,v 1.4 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * @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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_form/node_form_taxonomy.inc b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_taxonomy.inc new file mode 100644 index 0000000000000000000000000000000000000000..694675b865ce7c711d74e77c60876b1e8e95d45d --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_form/node_form_taxonomy.inc @@ -0,0 +1,46 @@ +<?php +// $Id: node_form_taxonomy.inc,v 1.4 2010/10/11 22:18:23 sdboyer Exp $ + +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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/node_form/translations/plugins-content_types-node_form.hu.po b/sites/all/modules/ctools/plugins/content_types/node_form/translations/plugins-content_types-node_form.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..54124012240a040256ef3c57cd4f0fee5d4eac27 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/node_form/translations/plugins-content_types-node_form.hu.po @@ -0,0 +1,112 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-11-30 11: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 "Categories" +msgstr "Kategóriák" +msgid "Authoring information" +msgstr "Szerzői információk" +msgid "Publishing options" +msgstr "Közzétételi beállítások" +msgid "Attach files" +msgstr "Fájlok csatolása" +msgid "Node form publishing options" +msgstr "Tartalom űrlap közzétételi beállítások" +msgid "Node form author information" +msgstr "Tartalom űrlap szerzői információ" +msgid "Author information on the Node form." +msgstr "Szerzői információ a tartalom űrlapon." +msgid "Node form input format" +msgstr "Tartalom űrlap beviteli forma" +msgid "Input format for the body field on a node." +msgstr "A törzs mező beviteli formája egy tartalomban." +msgid "Node form comment settings" +msgstr "Tartalom űrlap hozzászólás beállítások" +msgid "Comment settings on the Node form." +msgstr "Hozzászólás beállítások a tartalom űrlapon." +msgid "Node form menu settings" +msgstr "Tartalom űrlap menü beállítások" +msgid "Node form file attachments" +msgstr "Tartalom űrlap csatolmányok" +msgid "File attachments on the Node form." +msgstr "Csatolmányok a tartalom űrlapon." +msgid "Node form categories" +msgstr "Tartalom űrlap kategóriák" +msgid "Taxonomy categories for the node." +msgstr "Taxonómia kategóriák a tartalomhoz." +msgid "Node form book options" +msgstr "Tartalom űrlap könyvvázlat beállítások" +msgid "Book options for the node." +msgstr "Könyvvázlat beállítások a tartalomhoz." +msgid "Publishing options." +msgstr "Közzétételi beállítások." +msgid "Comment options" +msgstr "Hozzászólás beállítások" +msgid "Comment options." +msgstr "Hozzászólás beállítások." +msgid "Authoring information." +msgstr "Szerzői információk." +msgid "Menu options" +msgstr "Menü beállítások" +msgid "Menu options." +msgstr "Menü beállítások." +msgid "URL path options" +msgstr "Webcímútvonal beállítások" +msgid "URL Path options." +msgstr "Webcímútvonal beállítások." +msgid "Attach files." +msgstr "Fájlok csatolása." +msgid "Categories." +msgstr "Kategóriák." +msgid "Book options" +msgstr "Könyvvázlat beállítások" +msgid "Book options." +msgstr "Könyvvázlat beállítások." +msgid "Input format." +msgstr "Beviteli forma." +msgid "\"@s\" node form attach files" +msgstr "„@s” tartalom űrlap csatolmányai" +msgid "\"@s\" node form publishing options" +msgstr "„@s” tartalom űrlap közzétételi beállítások" +msgid "\"@s\" node form book options" +msgstr "„@s” tartalom űrlap könyvvázlat beállítások" +msgid "Node form submit buttons" +msgstr "Tartalom űrlap beküldési nyomógombok" +msgid "Submit buttons for the node form." +msgstr "Beküldési nyomógombok a tartalom űrlaphoz." +msgid "Node form buttons." +msgstr "Tartalom űrlap nyomógombok." +msgid "\"@s\" node form submit buttons" +msgstr "„@s” tartalom űrlap beküldési nyomógombok" +msgid "\"@s\" node form comment settings" +msgstr "„@s” tartalom űrlap hozzászólás beállítások" +msgid "\"@s\" node form input format" +msgstr "„@s” tartalom űrlap beviteli forma" +msgid "Node form revision log message" +msgstr "Tartalom űrlap változatinformáció üzenet" +msgid "Revision log message for the node." +msgstr "Változatinformáció üzenet a tartalomhoz." +msgid "\"@s\" node form revision log" +msgstr "„@s” tartalom űrlap változatinformáció" +msgid "Menu settings on the Node form." +msgstr "Menü beállítások a tartalom űrlapon." +msgid "\"@s\" node form menu settings" +msgstr "„@s” tartalom űrlap menü beállítások" +msgid "Node form url path settings" +msgstr "Tartalom űrlap webcímútvonal beállítások" +msgid "\"@s\" node form path options" +msgstr "„@s” tartalom űrlap útvonal beállítások" +msgid "\"@s\" node form author information" +msgstr "„@s” tartalom űrlap szerzői információk" +msgid "\"@s\" node form select taxonomy" +msgstr "„@s” tartalom űrlap taxonómia kiválasztása" diff --git a/sites/all/modules/ctools/plugins/content_types/page/page_breadcrumb.inc b/sites/all/modules/ctools/plugins/content_types/page/page_breadcrumb.inc new file mode 100644 index 0000000000000000000000000000000000000000..56dabd052baa1a7cb3edadd23c998ab7921ca2aa --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/page/page_breadcrumb.inc @@ -0,0 +1,33 @@ +<?php +// $Id: page_breadcrumb.inc,v 1.4 2010/12/31 21:20:57 merlinofchaos Exp $ + +/** + * @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', array('breadcrumb' => drupal_get_breadcrumb())); + + return $block; +} diff --git a/sites/all/modules/ctools/plugins/content_types/page/page_feed_icons.inc b/sites/all/modules/ctools/plugins/content_types/page/page_feed_icons.inc new file mode 100644 index 0000000000000000000000000000000000000000..e7a38018e59b82638563998c71b41fdde9261bf7 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/page/page_feed_icons.inc @@ -0,0 +1,33 @@ +<?php +// $Id: page_feed_icons.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/plugins/content_types/page/page_help.inc b/sites/all/modules/ctools/plugins/content_types/page/page_help.inc new file mode 100644 index 0000000000000000000000000000000000000000..a813301f7ecdac73b7b86c1d6e34c2d03ee968c0 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/page/page_help.inc @@ -0,0 +1,34 @@ +<?php +// $Id: page_help.inc,v 1.3 2010/09/07 09:02:51 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/plugins/content_types/page/page_logo.inc b/sites/all/modules/ctools/plugins/content_types/page/page_logo.inc new file mode 100644 index 0000000000000000000000000000000000000000..589c989e153890982bfa7992443808bb94d56127 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/page/page_logo.inc @@ -0,0 +1,37 @@ +<?php +// $Id: page_logo.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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'); + if (!empty($logo)) { + $block = new stdClass(); + $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/sites/all/modules/ctools/plugins/content_types/page/page_messages.inc b/sites/all/modules/ctools/plugins/content_types/page/page_messages.inc new file mode 100644 index 0000000000000000000000000000000000000000..e9bbfee2d31215281e79a06a5e6899bb6b7958c0 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/page/page_messages.inc @@ -0,0 +1,34 @@ +<?php +// $Id: page_messages.inc,v 1.3 2010/09/07 09:02:51 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/plugins/content_types/page/page_primary_links.inc b/sites/all/modules/ctools/plugins/content_types/page/page_primary_links.inc new file mode 100644 index 0000000000000000000000000000000000000000..6b0bc9d15cda7d21562db192e517212a9be87f26 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/page/page_primary_links.inc @@ -0,0 +1,33 @@ +<?php +// $Id: page_primary_links.inc,v 1.3 2010/12/31 21:21:39 merlinofchaos Exp $ + +/** + * @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', array('links' => menu_main_menu(), 'attributes' => array('class' => 'links primary-links'))); + + return $block; +} diff --git a/sites/all/modules/ctools/plugins/content_types/page/page_secondary_links.inc b/sites/all/modules/ctools/plugins/content_types/page/page_secondary_links.inc new file mode 100644 index 0000000000000000000000000000000000000000..548c82d540cc7307acd7534c27e97f50f32baf7d --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/page/page_secondary_links.inc @@ -0,0 +1,33 @@ +<?php +// $Id: page_secondary_links.inc,v 1.3 2010/12/31 21:22:26 merlinofchaos Exp $ + +/** + * @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', array('links' => menu_secondary_menu(), 'attributes' => array('class' => 'links secondary-links'))); + + return $block; +} diff --git a/sites/all/modules/ctools/plugins/content_types/page/page_site_name.inc b/sites/all/modules/ctools/plugins/content_types/page/page_site_name.inc new file mode 100644 index 0000000000000000000000000000000000000000..306b0f6f2dd8b860d02c737eb4c592bf2e92fc9b --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/page/page_site_name.inc @@ -0,0 +1,33 @@ +<?php +// $Id: page_site_name.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/plugins/content_types/page/page_slogan.inc b/sites/all/modules/ctools/plugins/content_types/page/page_slogan.inc new file mode 100644 index 0000000000000000000000000000000000000000..e46a99037cc132548c422a8b3c0b86f6119794f2 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/page/page_slogan.inc @@ -0,0 +1,33 @@ +<?php +// $Id: page_slogan.inc,v 1.3 2010/09/07 09:02:51 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/plugins/content_types/page/page_tabs.inc b/sites/all/modules/ctools/plugins/content_types/page/page_tabs.inc new file mode 100644 index 0000000000000000000000000000000000000000..042520fb4282e965ec38fb9e3e0659863114d812 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/page/page_tabs.inc @@ -0,0 +1,71 @@ +<?php +// $Id: page_tabs.inc,v 1.4 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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'], + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/content_types/page/page_title.inc b/sites/all/modules/ctools/plugins/content_types/page/page_title.inc new file mode 100644 index 0000000000000000000000000000000000000000..4fa21009ca62b5909b70ad7e1ad7177360b05740 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/page/page_title.inc @@ -0,0 +1,119 @@ +<?php +// $Id: page_title.inc,v 1.4 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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'], + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/content_types/page/translations/plugins-content_types-page.hu.po b/sites/all/modules/ctools/plugins/content_types/page/translations/plugins-content_types-page.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..207e9cee0d5e6becb340356a6942ccd81546dfe8 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/page/translations/plugins-content_types-page.hu.po @@ -0,0 +1,44 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-11-30 08:03+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 "Help" +msgstr "Súgó" +msgid "Page title" +msgstr "Oldal címe" +msgid "Mission" +msgstr "Küldetés" +msgid "Tabs" +msgstr "Fülek" +msgid "Site Slogan" +msgstr "Jelmondat" +msgid "Add the breadcrumb trail as content." +msgstr "A morzsasáv hozzáadása tartalomként." +msgid "Add the help text of the current page as content." +msgstr "Az aktuális oldal súgószövegének hozzáadása tartalomként." +msgid "Status messages" +msgstr "Állapotüzenetek" +msgid "Add the status messages of the current page as content." +msgstr "Az aktuális oldal állapotüzeneteinek hozzáadása tartalomként." +msgid "Add the site mission statement as content." +msgstr "A webhely céljainak hozzáadása tartalomként." +msgid "Add the slogan trail as content." +msgstr "A jelmondat sáv hozzáadása tartalomként." +msgid "Add the tabs (local tasks) as content." +msgstr "A fülek (helyi feladatok) hozzáadása tartalomként." +msgid "Add the page title as content." +msgstr "Az oldal címének hozzáadása tartalomként." +msgid "Page footer message" +msgstr "Oldal lábléc üzenete" +msgid "Add the page footer message as content." +msgstr "Az oldal láblécüzenetének hozzáadása tartalomként." diff --git a/sites/all/modules/ctools/plugins/content_types/search/icon_search.png b/sites/all/modules/ctools/plugins/content_types/search/icon_search.png new file mode 100644 index 0000000000000000000000000000000000000000..3ad1deb65c4a1cada8cdedb7619f3ed5e8ff0587 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/search/icon_search.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/search/search_form.inc b/sites/all/modules/ctools/plugins/content_types/search/search_form.inc new file mode 100644 index 0000000000000000000000000000000000000000..4e1364656f4e27fde5dcbe6dfb6fe0efff21e55f --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/search/search_form.inc @@ -0,0 +1,171 @@ +<?php +// $Id: search_form.inc,v 1.5 2010/12/31 21:24:40 merlinofchaos Exp $ + +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, + 'build_info' => array( + 'args' => array($path, $keys, $conf['type'], $prompt), + ), + ); + + module_load_include('inc', 'search', 'search.pages'); + + $form_id = $conf['form'] == 'simple' ? 'ctools_search_form' : 'search_form'; + $block->content = drupal_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>', + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/content_types/search/search_result.inc b/sites/all/modules/ctools/plugins/content_types/search/search_result.inc new file mode 100644 index 0000000000000000000000000000000000000000..02684ea9c50f6802488a3cf5e046dfbd8760dcb3 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/search/search_result.inc @@ -0,0 +1,203 @@ +<?php +// $Id: search_result.inc,v 1.7 2010/10/11 22:18:24 sdboyer Exp $ + +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_fallback_format(), + 'override_no_key' => FALSE, + 'no_key_title' => '', + 'no_key' => '', + 'no_key_format' => filter_fallback_format(), + ), + ); +} + +/** + * 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>', + ); + return $form; +} + +/** + * 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/sites/all/modules/ctools/plugins/content_types/search/translations/plugins-content_types-search.hu.po b/sites/all/modules/ctools/plugins/content_types/search/translations/plugins-content_types-search.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..10c1a56ce0bb69b1644d394c511f64d5cbfe0238 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/search/translations/plugins-content_types-search.hu.po @@ -0,0 +1,63 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-11-12 15:24+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 "results" +msgstr "találatok" +msgid "search" +msgstr "keresés" +msgid "Advanced" +msgstr "Haladó" +msgid "Search results" +msgstr "Találatok" +msgid "Your search yielded no results" +msgstr "Nincs találat." +msgid "Simple" +msgstr "Egyszerű" +msgid "%keys (@type)." +msgstr "%keys (@type)." +msgid "Search form" +msgstr "Keresés űrlap" +msgid "Advanced search form" +msgstr "Haladó keresés űrlap" +msgid "A search form with advanced options." +msgstr "Egy keresés űrlap haladó beállításokkal." +msgid "" +"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." +msgstr "" +"A haladó űrlap további beállításokat biztosíthat a keresés " +"típusa alapján. Például a haladó tartalom(node) keresés űrlap " +"engedélyezi a tartalomtípus és a taxonómia kifejezés szerinti " +"keresést." +msgid "Same page" +msgstr "Ugyanolyan oldal" +msgid "Override default prompt" +msgstr "Alapértelmezett készenléti jel felülírása" +msgid "@type search form" +msgstr "@type keresési űrlap" +msgid "The results of a search using keywords." +msgstr "A kucsszavakat használó keresés eredményei." +msgid "Record a watchdog log entry when searches are made" +msgstr "Keresés feljegyzése az eseménynaplóba" +msgid "Override \"no result\" text" +msgstr "„Nincs eredmény” szöveg felülbírálata" +msgid "No result text" +msgstr "Nincs eredmény szövege" +msgid "Display text if no search keywords were submitted" +msgstr "A megjelenített szöveg, ha nem lett keresési kulcsszó megadva" +msgid "No keywords text" +msgstr "Nincs kulcsszó szöveg" +msgid "@type search result" +msgstr "@type keresési eredmény" diff --git a/sites/all/modules/ctools/plugins/content_types/term_context/icon_term.png b/sites/all/modules/ctools/plugins/content_types/term_context/icon_term.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/term_context/icon_term.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/term_context/term_description.inc b/sites/all/modules/ctools/plugins/content_types/term_context/term_description.inc new file mode 100644 index 0000000000000000000000000000000000000000..d939c922a35df0c0c05ed03ab278baf42179e8c8 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/term_context/term_description.inc @@ -0,0 +1,51 @@ +<?php +// $Id: term_description.inc,v 1.4 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * 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) ? 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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/term_context/term_list.inc b/sites/all/modules/ctools/plugins/content_types/term_context/term_list.inc new file mode 100644 index 0000000000000000000000000000000000000000..9fd2865b6e19e6c92396b6b54b7e32ef2cb19cdf --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/term_context/term_list.inc @@ -0,0 +1,119 @@ +<?php +// $Id: term_list.inc,v 1.8 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * 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) ? 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': + // FIXME this no longer exists, must be done with Field API + // $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_query('SELECT parent FROM {term_hierarchy} WHERE tid = :tid', array(':tid' => $term->tid))->fetchField(); + $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="clearfix 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'], + ); + return $form; +} + +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/sites/all/modules/ctools/plugins/content_types/term_context/translations/plugins-content_types-term_context.hu.po b/sites/all/modules/ctools/plugins/content_types/term_context/translations/plugins-content_types-term_context.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..799bbd6d8535c7e29e419169930dfe4bdd92cfcd --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/term_context/translations/plugins-content_types-term_context.hu.po @@ -0,0 +1,52 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-11-30 11:02+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 "Related terms" +msgstr "Kapcsolódó kifejezések" +msgid "List type" +msgstr "Lista típusa" +msgid "Term description" +msgstr "A kifejezés leírása" +msgid "Child terms" +msgstr "Gyerek kifejezések" +msgid "Edit term" +msgstr "Kifejezés szerkesztése" +msgid "Edit this term" +msgstr "Kifejezés szerkesztése" +msgid "\"@s\" @type" +msgstr "„@s” @type" +msgid "Term description." +msgstr "Kifejezés leírása." +msgid "\"@s\" term description" +msgstr "„@s” kifejezés leírása" +msgid "List of related terms" +msgstr "Kapcsolódó kifejezések listája" +msgid "" +"Terms related to an existing term; may be child, siblings or top " +"level." +msgstr "" +"Egy létező kifejezéshez kapcsolódó kifejezések. Lehet gyermek, " +"testvér vagy legfelső szintű." +msgid "Sibling terms" +msgstr "Testvér kifejezések" +msgid "Top level terms" +msgstr "Legfelső szintű kifejezés" +msgid "Term synonyms" +msgstr "Szinonimák" +msgid "Which terms" +msgstr "Mely kifejezések" +msgid "Unordered" +msgstr "Rendezetlen" +msgid "Ordered" +msgstr "Rendezett" diff --git a/sites/all/modules/ctools/plugins/content_types/user_context/icon_user.png b/sites/all/modules/ctools/plugins/content_types/user_context/icon_user.png new file mode 100644 index 0000000000000000000000000000000000000000..ab248f3f1bb62536bbf23296a949bfe05cd56bc7 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/user_context/icon_user.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/user_context/profile_fields.inc b/sites/all/modules/ctools/plugins/content_types/user_context/profile_fields.inc new file mode 100644 index 0000000000000000000000000000000000000000..f820c329a1340e583754ad76e55fb75be4b5cc5e --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/user_context/profile_fields.inc @@ -0,0 +1,130 @@ +<?php +// $Id: profile_fields.inc,v 1.9 2010/10/18 18:00:48 merlinofchaos Exp $ + +if (module_exists('profile') && !is_null(profile_user_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) ? 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'])) { + // @todo 'class' is *always* an array now. 04/10/2009 sun + $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="clearfix 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="clearfix 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( + 'variables' => array('category' => NULL, 'vars' => NULL), + 'path' => $plugin['path'], + 'template' => 'profile_fields_pane', + ); +} diff --git a/sites/all/modules/ctools/plugins/content_types/user_context/profile_fields_pane.tpl.php b/sites/all/modules/ctools/plugins/content_types/user_context/profile_fields_pane.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..375fbe0dc463dddfd92360abb340767f3f14cfca --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/user_context/profile_fields_pane.tpl.php @@ -0,0 +1,17 @@ +<?php +// $Id: profile_fields_pane.tpl.php,v 1.1 2009/04/18 02:00:35 merlinofchaos Exp $ +/** + * @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/sites/all/modules/ctools/plugins/content_types/user_context/translations/plugins-content_types-user_context.hu.po b/sites/all/modules/ctools/plugins/content_types/user_context/translations/plugins-content_types-user_context.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..9a917bbc28e7958a5295ef1a71c5f2b6d21272d2 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/user_context/translations/plugins-content_types-user_context.hu.po @@ -0,0 +1,42 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-09 14:11+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 "User picture" +msgstr "Felhasználó képe" +msgid "Profile content goes here." +msgstr "Ide jön a profil tartalma." +msgid "Which category" +msgstr "Melyik kategória" +msgid "" +"Text to display if category has no data. Note that title will not " +"display unless overridden." +msgstr "" +"A megjelenített szöveg, ha a kategória nem rendelkezik adattal. Meg " +"kell jegyezni, hogy a cím nem fog megjelenni felülírás nélkül." +msgid "\"@s\" profile fields" +msgstr "„@s” profilmezők" +msgid "The picture of a user." +msgstr "Egy kép a felhasználóról." +msgid "\"@s\" user picture" +msgstr "„@s” felhasználó képe" +msgid "User profile" +msgstr "Felhasználói profil" +msgid "The profile of a user." +msgstr "Egy felhasználó profilja." +msgid "\"@s\" user profile" +msgstr "„@s” felhasználói profil" +msgid "Profile category" +msgstr "Profil kategóriája" +msgid "Contents of a single profile category." +msgstr "Egy egyszerű profilkategória tartalmai." diff --git a/sites/all/modules/ctools/plugins/content_types/user_context/user_picture.inc b/sites/all/modules/ctools/plugins/content_types/user_context/user_picture.inc new file mode 100644 index 0000000000000000000000000000000000000000..3115bbc5ad937b79cac57029f43cd28f1dbe076d --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/user_context/user_picture.inc @@ -0,0 +1,42 @@ +<?php +// $Id: user_picture.inc,v 1.6 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * 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) ? clone($context->data) : NULL; + $block = new stdClass(); + $block->module = 'term-list'; + + if ($account === FALSE || ($account->access == 0 && !user_access('administer users'))) { + return drupal_not_found(); + } + + $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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/user_context/user_profile.inc b/sites/all/modules/ctools/plugins/content_types/user_context/user_profile.inc new file mode 100644 index 0000000000000000000000000000000000000000..33a6427ce4775e07b7c429cf24b02a78f8f1704d --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/user_context/user_profile.inc @@ -0,0 +1,66 @@ +<?php +// $Id: user_profile.inc,v 1.11 2011/01/06 00:06:18 merlinofchaos Exp $ + +/** + * 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) ? clone($context->data) : NULL; + if (!$account || ($account->access == 0 && !user_access('administer users'))) { + return NULL; + } + + // Retrieve all profile fields and attach to $account->content. + if (!isset($account->content)) { + user_build_content($account); + } + + $build = $account->content; + // We don't need duplicate rendering info in account->content. + unset($account->content); + + $build += array( + '#theme' => 'user_profile', + '#account' => $account, + // @todo support view mode + '#view_mode' => 'full', + // @todo do we need to support this? + '#language' => NULL, + ); + + // Allow modules to modify the structured user. + $type = 'user'; + drupal_alter(array('user_view', 'entity_view'), $build, $type); + + $block = new stdClass(); + $block->module = 'user-profile'; + $block->title = check_plain(format_username($account)); + $block->content = $build; + + 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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/user_context/user_signature.inc b/sites/all/modules/ctools/plugins/content_types/user_context/user_signature.inc new file mode 100644 index 0000000000000000000000000000000000000000..840210171348c5c8a1f10b74f5d8e0355e84a20e --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/user_context/user_signature.inc @@ -0,0 +1,40 @@ +<?php +// $Id: user_signature.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * 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. + return $form; +} diff --git a/sites/all/modules/ctools/plugins/content_types/vocabulary_context/icon_vocabulary.png b/sites/all/modules/ctools/plugins/content_types/vocabulary_context/icon_vocabulary.png new file mode 100644 index 0000000000000000000000000000000000000000..f0417cb6515aa7fb2856c90722b386ed99bfc501 Binary files /dev/null and b/sites/all/modules/ctools/plugins/content_types/vocabulary_context/icon_vocabulary.png differ diff --git a/sites/all/modules/ctools/plugins/content_types/vocabulary_context/translations/plugins-content_types-vocabulary_context.hu.po b/sites/all/modules/ctools/plugins/content_types/vocabulary_context/translations/plugins-content_types-vocabulary_context.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..f325f6bc8f25d3909dbdc2e200c7ab04549afc99 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/vocabulary_context/translations/plugins-content_types-vocabulary_context.hu.po @@ -0,0 +1,36 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-11-30 11:03+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 "unlimited" +msgstr "korlátlan" +msgid "Vocabulary terms" +msgstr "Szótárkifejezések" +msgid "All the terms in a vocabulary." +msgstr "Az összes kifejezés egy szótárban." +msgid "\"@s\" terms" +msgstr "„@s” kifejezés" +msgid "Maximum depth" +msgstr "Maximális mélység" +msgid "Define the maximum depth of terms being displayed." +msgstr "" +"A megjelenített kifejezések maximális mélységének " +"meghatározása." +msgid "Display as tree" +msgstr "Megjelenítés fa nézetben" +msgid "" +"If checked, the terms are displayed in a tree, otherwise in a flat " +"list." +msgstr "" +"Ha ez be van kapcsolva, akkor a kifejezések egy fában jelennek meg, " +"különben egy egyszerű listában." diff --git a/sites/all/modules/ctools/plugins/content_types/vocabulary_context/vocabulary_terms.inc b/sites/all/modules/ctools/plugins/content_types/vocabulary_context/vocabulary_terms.inc new file mode 100644 index 0000000000000000000000000000000000000000..5e7f5485036664fdaf447e90d4c7fd84820faf88 --- /dev/null +++ b/sites/all/modules/ctools/plugins/content_types/vocabulary_context/vocabulary_terms.inc @@ -0,0 +1,94 @@ +<?php +// $Id: vocabulary_terms.inc,v 1.7 2010/10/11 22:18:23 sdboyer Exp $ + +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) ? 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(); + $result = db_query('SELECT t.name, t.tid FROM {taxonomy_term_data} t INNER JOIN {taxonomy_term_hierarchy} h ON t.tid = h.tid WHERE t.vid = :vid AND h.parent = :parent ORDER BY t.weight ASC, t.name ASC', array(':vid' => $vid, ':parent' => $tid)); + foreach ($result as $term) { + $return[] = array( + 'data' => l($term->name, 'taxonomy/term/'. $term->tid), + 'children' => _ctools_content_vocabulary_terms($vid, $max_depth, $depth, $term->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/sites/all/modules/ctools/plugins/contexts/entity.inc b/sites/all/modules/ctools/plugins/contexts/entity.inc new file mode 100644 index 0000000000000000000000000000000000000000..08a50f144f52a9d59d515d9ca238b48f0b518896 --- /dev/null +++ b/sites/all/modules/ctools/plugins/contexts/entity.inc @@ -0,0 +1,253 @@ +<?php +// $Id: entity.inc,v 1.1 2011/01/05 20:34:46 merlinofchaos Exp $ + +/** + * @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("Entity"), + 'description' => t('Entity object.'), + 'context' => 'ctools_context_create_entity', + 'edit form' => 'ctools_context_entity_settings_form', + 'defaults' => array('id' => ''), + 'convert list' => 'ctools_context_entity_convert_list', + 'convert' => 'ctools_context_entity_convert', + 'placeholder form' => array( + '#type' => 'textfield', + '#description' => t('Enter the ID of an entity for this context.'), + ), + 'get child' => 'ctools_context_entity_get_child', + 'get children' => 'ctools_context_entity_get_children', +); + +function ctools_context_entity_get_child($plugin, $parent, $child) { + $plugins = ctools_context_entity_get_children($plugin, $parent); + return $plugins[$parent . ':' . $child]; +} + +function ctools_context_entity_get_children($plugin, $parent) { + $entities = entity_get_info(); + $plugins = array(); + foreach ($entities as $entity_type => $entity) { + $plugin['title'] = $entity['label']; + $plugin['keyword'] = $entity_type; + $plugin['context name'] = $entity_type; + $plugin['name'] = $parent . ':' . $entity_type; + $plugin['description'] = t('Creates @entity context from an entity ID.', array('@entity' => $entity_type)); + $plugins[$parent . ':' . $entity_type] = $plugin; + } + + return $plugins; +} + +/** + * It's important to remember that $conf is optional here, because contexts + * are not always created from the UI. + */ +function ctools_context_create_entity($empty, $data = NULL, $conf = FALSE, $plugin) { + $entity_type = $plugin['keyword']; + $entity = entity_get_info($entity_type); + $context = new ctools_context(array('entity:' . $entity_type, 'entity', $entity_type)); + $context->plugin = $plugin['name']; + $context->keyword = $entity_type; + + if ($empty) { + return $context; + } + + if (is_array($data) && isset($data['id'])) { + $id = $data['id']; + } + elseif (is_object($data)) { + $ids = entity_extract_ids($entity_type, $data); + $id = $ids[0]; + } + elseif (is_numeric($data)) { + $id = $data; + $data = entity_load($entity_type, array($id)); + $data = $data[$id]; + } + + if (is_array($data)) { + $data = entity_load($entity_type, array($id)); + $data = $data[$id]; + //$language = field_language($entity_type, $data); + } + + if (!empty($data)) { + $context->data = $data; + if (isset($entity['entity keys']['label'])) { + $context->title = $data->{$entity['entity keys']['label']}; + } + $context->argument = $id; + + if ($entity['entity keys']['bundle']) { + $context->restrictions['type'] = array($data->{$entity['entity keys']['bundle']}); + } + return $context; + } +} + +function ctools_context_entity_settings_form($form, &$form_state) { + $conf = &$form_state['conf']; + + $form['entity'] = array( + '#title' => t('Enter the title or ID of a @entity entity', array('@entity' => $conf['keyword'])), + '#type' => 'textfield', + '#maxlength' => 512, + '#autocomplete_path' => 'ctools/autocomplete/' . $conf['keyword'], + '#weight' => -10, + ); + + if (!empty($conf['id'])) { + $info = entity_load($conf['keyword'], array($conf['id'])); + $info = $info[$conf['id']]; + if ($info) { + $entity = entity_get_info($conf['keyword']); + $uri = entity_uri($conf['keyword'], $info); + if (is_array($uri) && $entity['entity keys']['label']) { + $link = l(t("'%title' [%type id %id]", array('%title' => $info->{$entity['entity keys']['label']}, '%type' => $conf['keyword'], '%id' => $conf['id'])), $uri['path'], array('attributes' => array('target' => '_blank', 'title' => t('Open in new window')), 'html' => TRUE)); + } + elseif (is_array($uri)) { + $link = l(t("[%type id %id]", array('%type' => $conf['keyword'], '%id' => $conf['id'])), $uri['path'], array('attributes' => array('target' => '_blank', 'title' => t('Open in new window')), 'html' => TRUE)); + } + elseif ($entity['entity keys']['label']) { + $link = l(t("'%title' [%type id %id]", array('%title' => $info->{$entity['entity keys']['label']}, '%type' => $conf['keyword'], '%id' => $conf['id'])), file_create_url($uri), array('attributes' => array('target' => '_blank', 'title' => t('Open in new window')), 'html' => TRUE)); + } + else { + $link = t("[%type id %id]", array('%type' => $conf['keyword'], '%id' => $conf['id'])); + } + $form['entity']['#description'] = t('Currently set to !link', array('!link' => $link)); + } + } + + $form['id'] = array( + '#type' => 'value', + '#value' => $conf['id'], + ); + + $form['entity_type'] = array( + '#type' => 'value', + '#value' => $conf['keyword'], + ); + + $form['set_identifier'] = array( + '#type' => 'checkbox', + '#default_value' => FALSE, + '#title' => t('Reset identifier to entity label'), + '#description' => t('If checked, the identifier will be reset to the entity label of the selected entity.'), + ); + + return $form; +} + +/** + * Validate a node. + */ +function ctools_context_entity_settings_form_validate($form, &$form_state) { + // Validate the autocomplete + if (empty($form_state['values']['id']) && empty($form_state['values']['entity'])) { + form_error($form['entity'], t('You must select an entity.')); + return; + } + + if (empty($form_state['values']['entity'])) { + return; + } + + $id = $form_state['values']['entity']; + $preg_matches = array(); + $match = preg_match('/\[id: (\d+)\]/', $id, $preg_matches); + if (!$match) { + $match = preg_match('/^id: (\d+)/', $id, $preg_matches); + } + + if ($match) { + $id = $preg_matches[1]; + } + if (is_numeric($id)) { + $entity = entity_load($form_state['values']['entity_type'], array($id)); + $entity = $entity[$id]; + } + else { + $entity_info = entity_get_info($form_state['values']['entity_type']); + $field = $entity_info['entity keys']['label']; + $entity = entity_load($form_state['values']['entity_type'], FALSE, array($field => $id)); + } + + // Do not allow unpublished nodes to be selected by unprivileged users + // || (empty($node->status) && !(user_access('administer nodes'))) need a new sanity check at some point. + if (!$entity) { + form_error($form['entity'], t('Invalid entity selected.')); + } + else { + $entity_id = entity_extract_ids($form_state['values']['entity_type'], $entity); + form_set_value($form['id'], $entity_id[0], $form_state); + } +} + +function ctools_context_entity_settings_form_submit($form, &$form_state) { + if ($form_state['values']['set_identifier']) { + $entity_info = entity_get_info($form_state['values']['entity_type']); + $entity = entity_load($form_state['values']['entity_type'], array($form_state['values']['id'])); + $entity = $entity[$form_state['values']['id']]; + $form_state['values']['identifier'] = $entity->{$entity_info['entity keys']['label']}; + } + + // This will either be the value set previously or a value set by the + // validator. + $form_state['conf']['id'] = $form_state['values']['id']; +} + +/** + * Provide a list of ways that this context can be converted to a string. + */ +function ctools_context_entity_convert_list($plugin) { + $list = array(); + + $entity = entity_get_info($plugin['context name']); + if (isset($entity['token type'])) { + $token = $entity['token type']; + } + else { + $token = $plugin['context name']; + } + $tokens = token_info(); + if (isset($tokens['tokens'][$token])) { + foreach ($tokens['tokens'][$token] as $id => $info) { + if (!isset($list[$id])) { + $list[$id] = $info['name']; + } + } + } + return $list; +} + +/** + * Convert a context into a string. + */ +function ctools_context_entity_convert($context, $type) { + $entity_type = $context->type[2]; + $entity = entity_get_info($entity_type); + if (isset($entity['token type'])) { + $token = $entity['token type']; + } + else { + $token = $entity_type; + } + $tokens = token_info(); + if (isset($tokens['tokens'][$token][$type])) { + $values = token_generate($token, array($type => $type), array($token => $context->data)); + if (isset($values[$type])) { + return $values[$type]; + } + } +} diff --git a/sites/all/modules/ctools/plugins/contexts/node.inc b/sites/all/modules/ctools/plugins/contexts/node.inc new file mode 100644 index 0000000000000000000000000000000000000000..28389cd397a899acf11b1ae05cf2782debf86325 --- /dev/null +++ b/sites/all/modules/ctools/plugins/contexts/node.inc @@ -0,0 +1,179 @@ +<?php +// $Id: node.inc,v 1.19 2010/10/26 23:40:43 merlinofchaos Exp $ + +/** + * @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', + 'edit form' => 'ctools_context_node_settings_form', + '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.'), + ), +); + +/** + * 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($form, &$form_state) { + $conf = &$form_state['conf']; + + $form['node'] = array( + '#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_query('SELECT * FROM {node} WHERE nid = :nid', array(':nid' => $conf['nid']))->fetchObject(); + 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_state) { + // Validate the autocomplete + if (empty($form_state['values']['nid']) && empty($form_state['values']['node'])) { + form_error($form['node'], t('You must select a node.')); + return; + } + + if (empty($form_state['values']['node'])) { + return; + } + + $nid = $form_state['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_query('SELECT nid FROM {node} WHERE nid = :nid', array(':nid' => $nid))->fetchObject(); + } + else { + $node = db_query('SELECT nid FROM {node} WHERE LOWER(title) = LOWER(:title)', array(':title' => $nid))->fetchObject(); + } + + // 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_state['values']['nid'] = $node->nid; + } +} + +function ctools_context_node_settings_form_submit($form, &$form_state) { + if ($form_state['values']['set_identifier']) { + $node = node_load($form_state['values']['nid']); + $form_state['values']['identifier'] = $node->title; + } + + // This will either be the value set previously or a value set by the + // validator. + $form_state['conf']['nid'] = $form_state['values']['nid']; +} + +/** + * Provide a list of ways that this context can be converted to a string. + */ +function ctools_context_node_convert_list() { + $tokens = token_info(); + foreach ($tokens['tokens']['node'] as $id => $info) { + if (!isset($list[$id])) { + $list[$id] = $info['name']; + } + } + + return $list; +} + +/** + * Convert a context into a string. + */ +function ctools_context_node_convert($context, $type) { + $tokens = token_info(); + if (isset($tokens['tokens']['node'][$type])) { + $values = token_generate('node', array($type => $type), array('node' => $context->data)); + if (isset($values[$type])) { + return $values[$type]; + } + } +} diff --git a/sites/all/modules/ctools/plugins/contexts/node_add_form.inc b/sites/all/modules/ctools/plugins/contexts/node_add_form.inc new file mode 100644 index 0000000000000000000000000000000000000000..139f57456d1bdeae36da5a62078a0dbadefb9fd4 --- /dev/null +++ b/sites/all/modules/ctools/plugins/contexts/node_add_form.inc @@ -0,0 +1,118 @@ +<?php +// $Id: node_add_form.inc,v 1.14 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * @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', + 'edit form' => 'ctools_context_node_add_form_settings_form', + 'defaults' => array('type' => ''), + '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 $created; + $context = new ctools_context(array('form', 'node_add', 'node_form')); + $context->plugin = 'node_add_form'; + + if ($empty || (isset($created) && $created)) { + return $context; + } + $created = 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); + + $form_id = $node['type'] . '_node_form'; + + $form_state = array('want form' => TRUE, 'build_info' => array('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 = drupal_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); + return $context; + } + } +} + +function ctools_context_node_add_form_settings_form($form, &$form_state) { + $conf = $form_state['conf']; + + foreach (node_get_types() as $type => $info) { + $options[$type] = $info->name; + } + asort($options); + + $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; +} + +function ctools_context_node_add_form_settings_form_submit($form, &$form_state) { + $form_state['conf']['type'] = $form_state['values']['type']; +} + +/** + * 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/sites/all/modules/ctools/plugins/contexts/node_edit_form.inc b/sites/all/modules/ctools/plugins/contexts/node_edit_form.inc new file mode 100644 index 0000000000000000000000000000000000000000..b613dac70f19dbc51b33c5aa66cfe2ff6b2d8ac2 --- /dev/null +++ b/sites/all/modules/ctools/plugins/contexts/node_edit_form.inc @@ -0,0 +1,184 @@ +<?php +// $Id: node_edit_form.inc,v 1.18 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * @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', + 'edit form' => 'ctools_context_node_edit_form_settings_form', + '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 $created; + $context = new ctools_context(array('form', 'node_edit', 'node_form', 'node', 'node_edit_form')); + $context->plugin = 'node_edit_form'; + + if ($empty || (isset($created) && $created)) { + return $context; + } + $created = 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)) { + $form_id = $node->type . '_node_form'; + + $form_state = array('want form' => TRUE, 'build_info' => array('args' => array($node))); + + $file = drupal_get_path('module', 'node') . '/node.pages.inc'; + require_once DRUPAL_ROOT . '/' . $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 = drupal_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); + return $context; + } +} + +function ctools_context_node_edit_form_settings_form($form, &$form_state) { + $conf = $form_state['conf']; + + $form['node'] = array( + '#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_query('SELECT * FROM {node} WHERE nid = :nid', array(':nid' => $conf['nid']))->fetchObject(); + 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['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_state) { + // Validate the autocomplete + if (empty($form_state['values']['nid']) && empty($form_state['values']['node'])) { + form_error($form['node'], t('You must select a node.')); + return; + } + + if (empty($form_state['values']['node'])) { + return; + } + + $nid = $form_state['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_query('SELECT nid FROM {node} WHERE nid = :nid', array(':nid' => $nid))->fetchObject(); + } + else { + $node = db_query('SELECT nid FROM {node} WHERE LOWER(title) = LOWER(:title)', array(':title' => $nid))->fetchObject(); + } + + if (!$node) { + form_error($form['node'], t('Invalid node selected.')); + } + else { + form_set_value($form['nid'], $node->nid, $form_state); + // $form_state['values']['nid'] = $node->nid; + } +} + +function ctools_context_node_edit_form_settings_form_submit($form, &$form_state) { + if ($form_state['values']['set_identifier']) { + $node = node_load($form_state['values']['nid']); + $form_state['values']['identifier'] = $node->title; + } + + // This will either be the value set previously or a value set by the + // validator. + $form_state['conf']['nid'] = $form_state['values']['nid']; +} + +/** + * 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/sites/all/modules/ctools/plugins/contexts/string.inc b/sites/all/modules/ctools/plugins/contexts/string.inc new file mode 100644 index 0000000000000000000000000000000000000000..1c78fab3489faf5767e60077b2ddaf8212588ab1 --- /dev/null +++ b/sites/all/modules/ctools/plugins/contexts/string.inc @@ -0,0 +1,65 @@ +<?php +// $Id: string.inc,v 1.8 2010/01/29 20:18:02 merlinofchaos Exp $ + +/** + * @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/sites/all/modules/ctools/plugins/contexts/term.inc b/sites/all/modules/ctools/plugins/contexts/term.inc new file mode 100644 index 0000000000000000000000000000000000000000..6a3524aa0f8a81d2e25e1de210971e6ac5dccd8e --- /dev/null +++ b/sites/all/modules/ctools/plugins/contexts/term.inc @@ -0,0 +1,165 @@ +<?php +// $Id: term.inc,v 1.13 2011/01/01 01:14:24 merlinofchaos Exp $ + +/** + * @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', + 'edit form' => 'ctools_context_term_settings_form', + 'defaults' => array( + 'vid' => '', + 'tid' => '', + ), + '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', +); + +/** + * 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_term_load($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($form, &$form_state) { + $conf = $form_state['conf']; + + $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_query('SELECT * FROM {taxonomy_term_data} WHERE tid = :tid', array(':tid' => $conf['tid']))->fetchObject(); + 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(); + + $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_state) { + // Validate the autocomplete + $vid = $form_state['values']['vid']; + if (empty($form_state['values']['tid']) && empty($form_state['values']['taxonomy'][$vid])) { + form_error($form['taxonomy'][$vid], t('You must select a term.')); + return; + } + + if (empty($form_state['values']['taxonomy'][$vid])) { + return; + } + + $term = db_query('SELECT tid FROM {taxonomy_term_data} WHERE LOWER(name) = LOWER(:name) AND vid = :vid', array(':name' => $form_state['values']['taxonomy'][$vid], ':vid' => $vid))->fetchObject(); + + 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_state) { + if ($form_state['values']['set_identifier']) { + $term = db_query('SELECT tid, name FROM {taxonomy_term_data} WHERE LOWER(tid) = :tid', array(':tid' => $form_state['values']['tid']))->fetchObject(); + $form_state['values']['identifier'] = $term->name; + } + + $form_state['conf']['tid'] = $form_state['values']['tid']; + $form_state['conf']['vid'] = $form_state['values']['vid']; +} + +/** + * 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/sites/all/modules/ctools/plugins/contexts/terms.inc b/sites/all/modules/ctools/plugins/contexts/terms.inc new file mode 100644 index 0000000000000000000000000000000000000000..6218d8017394894d48d4005c4e2094cd63e942c8 --- /dev/null +++ b/sites/all/modules/ctools/plugins/contexts/terms.inc @@ -0,0 +1,98 @@ +<?php +// $Id: terms.inc,v 1.10 2010/10/15 21:06:58 merlinofchaos Exp $ + +/** + * @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', + '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_term_load(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 { + $result = db_query('SELECT tid, name FROM {taxonomy_term_data} WHERE tid IN :tids', array(':tids' => $context->tids)); + foreach ($result as $term) { + $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/sites/all/modules/ctools/plugins/contexts/token.inc b/sites/all/modules/ctools/plugins/contexts/token.inc new file mode 100644 index 0000000000000000000000000000000000000000..150dc10db0af75cb6c6dba6f3f8873ef1757bf2f --- /dev/null +++ b/sites/all/modules/ctools/plugins/contexts/token.inc @@ -0,0 +1,62 @@ +<?php +// $Id: token.inc,v 1.4 2010/12/31 22:46:50 merlinofchaos Exp $ + +/** + * @file + * Provide a global context to allow for token support. + */ + +$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() { + $tokens = token_info(); + foreach ($tokens['types'] as $type => $type_info) { + if (empty($type_info['needs-data'])) { + $real_type = isset($type_info['type']) ? $type_info['type'] : $type; + foreach ($tokens['tokens'][$real_type] as $id => $info) { + $key = "$type:$id"; + if (!isset($list[$key])) { + $list[$key] = $type_info['name'] . ': ' . $info['name']; + } + } + } + } + + return $list; +} + +/** + * Implementation of hook_ctools_context_converter_alter(). + */ +function ctools_context_token_convert($context, $token) { + $tokens = token_info(); + list($type, $token) = explode(':', $token, 2); + $real_type = isset($tokens['types'][$type]['type']) ? $tokens['types'][$type]['type'] : $type; + if (isset($tokens['tokens'][$real_type][$token])) { + $values = token_generate($type, array($token => $token)); + if (isset($values[$token])) { + return $values[$token]; + } + } +} diff --git a/sites/all/modules/ctools/plugins/contexts/translations/plugins-contexts.hu.po b/sites/all/modules/ctools/plugins/contexts/translations/plugins-contexts.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..c45bfbdd8c97ebf8a8ee72913ff3eb7cf3949495 --- /dev/null +++ b/sites/all/modules/ctools/plugins/contexts/translations/plugins-contexts.hu.po @@ -0,0 +1,100 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-11-30 10:27+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 "Node ID" +msgstr "Tartalom azonosítója" +msgid "User ID" +msgstr "Felhasználó ID" +msgid "Node edit form" +msgstr "Tartalom szerkesztése űrlap" +msgid "Node add form" +msgstr "Tartalom hozzádása űrlap" +msgid "Submit @name" +msgstr "@name beküldése" +msgid "Taxonomy terms" +msgstr "Taxonómia kifejezések" +msgid "Node revision ID" +msgstr "A tartalom változatának azonosítója" +msgid "Vocabulary ID" +msgstr "Szótárazonosító" +msgid "User name" +msgstr "Felhasználónév" +msgid "A node object." +msgstr "Egy tartalom objektum." +msgid "A node add form." +msgstr "Tartalom hozzádása űrlap" +msgid "Select the node type for this form." +msgstr "Tartalomtípus kiválasztása ehhez az űrlaphoz." +msgid "A node edit form." +msgstr "Egy tartalom szerkesztése űrlap" +msgid "A single taxonomy term object." +msgstr "Egy egyszerű taxonómia kifejezésobjektum." +msgid "A single user object." +msgstr "Egy egyszerű felhasználó objektum." +msgid "Taxonomy vocabulary" +msgstr "Taxonómiaszótár" +msgid "A single taxonomy vocabulary object." +msgstr "Egy egyszerű taxonómia szótár objektum." +msgid "Author UID" +msgstr "Szerző felhasználói azonosítója" +msgid "Enter the node ID of a node for this context." +msgstr "Egy tartalom azonosítójának megadása ehhez a környezethez." +msgid "Enter the node type this context." +msgstr "Tartalomtípus megadása ehhez a környezethez." +msgid "Enter the node ID of a node for this argument:" +msgstr "Egy tartalom azonosítójának megadása ehhez az argumentumhoz:" +msgid "A context that is just a string." +msgstr "A környezet azaz csak egy kifejezés." +msgid "Raw string" +msgstr "Nyers karaktersorozat" +msgid "Enter the string for this context." +msgstr "Kifejezés megadása ehhez a környezethez." +msgid "" +"Currently set to @term. Enter another term if you wish to change the " +"term." +msgstr "" +"Currently set to @term. Enter another term if you wish to change the " +"term." +msgid "Select a term from @vocabulary." +msgstr "Kifejezés kiválasztása @vocabulary szótárból." +msgid "Reset identifier to term title" +msgstr "Azonosító visszaállítása a kifejezés címére." +msgid "" +"If checked, the identifier will be reset to the term name of the " +"selected term." +msgstr "" +"Ha be van jelölve, Az azonosító vissza lesz állítva a " +"kiválasztott kifejezés kifejezés nevére." +msgid "You must select a term." +msgstr "Ki kell választani egy kifejezést." +msgid "Invalid term selected." +msgstr "Érvénytelen a kiválasztott kifejezés." +msgid "Multiple taxonomy terms, as a group." +msgstr "Több taxonómia kifejezés, csoportként." +msgid "Term ID of first term" +msgstr "Az első kifejezés azonosítója" +msgid "Term ID of all term, separated by + or ," +msgstr "" +"Az összes kifejezés azonosítója „+” vagy „,” jellel " +"elválasztva" +msgid "Term name of first term" +msgstr "Az első kifejezés kifejezésneve" +msgid "Term name of all terms, separated by + or ," +msgstr "" +"Kifejezésnév minden kifejezéshez, „+” vagy „,” jellel " +"elválasztva." +msgid "Vocabulary ID of first term" +msgstr "Az első kifejezés szótárazonosítója" +msgid "HTML-safe string" +msgstr "HTML-biztos karaktersorozat" diff --git a/sites/all/modules/ctools/plugins/contexts/user.inc b/sites/all/modules/ctools/plugins/contexts/user.inc new file mode 100644 index 0000000000000000000000000000000000000000..a12aa828afca1aadaa8b39652f93bd6d17b8382c --- /dev/null +++ b/sites/all/modules/ctools/plugins/contexts/user.inc @@ -0,0 +1,169 @@ +<?php +// $Id: user.inc,v 1.12 2011/01/05 19:42:37 merlinofchaos Exp $ + +/** + * @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', + 'edit form' => 'ctools_context_user_settings_form', + 'defaults' => array('type' => 'select', 'uid' => ''), + 'keyword' => 'user', + '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_load($user->uid); + $data->logged_in_user = TRUE; + } + else { + $data = user_load($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($form, &$form_state) { + $conf = $form_state['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: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_state) { + if ($form_state['values']['type'] != 'select') { + return; + } + + // Validate the autocomplete + if (empty($form_state['values']['uid']) && empty($form_state['values']['user'])) { + form_error($form['user'], t('You must select a user.')); + return; + } + + if (empty($form_state['values']['user'])) { + return; + } + + $account = user_load_by_name($form_state['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_state) { + if ($form_state['values']['set_identifier']) { + $account = user_load($form_state['values']['uid']); + $form_state['values']['identifier'] = $account->name; + } + + $form_state['conf']['type'] = $form_state['values']['type']; + $form_state['conf']['uid'] = $form_state['values']['uid']; +} + +/** + * Provide a list of replacements. + */ +function ctools_context_user_convert_list() { + $tokens = token_info(); + foreach ($tokens['tokens']['user'] as $id => $info) { + if (!isset($list[$id])) { + $list[$id] = $info['name']; + } + } + + return $list; +} + +/** + * Convert a context into a string. + */ +function ctools_context_user_convert($context, $type) { + $tokens = token_info(); + if (isset($tokens['tokens']['user'][$type])) { + $values = token_generate('user', array($type => $type), array('user' => $context->data)); + if (isset($values[$type])) { + return $values[$type]; + } + } +} diff --git a/sites/all/modules/ctools/plugins/contexts/vocabulary.inc b/sites/all/modules/ctools/plugins/contexts/vocabulary.inc new file mode 100644 index 0000000000000000000000000000000000000000..38d00fde714d6a31a9ea465ad639458d083b7722 --- /dev/null +++ b/sites/all/modules/ctools/plugins/contexts/vocabulary.inc @@ -0,0 +1,69 @@ +<?php +// $Id: vocabulary.inc,v 1.7 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * @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', + 'edit form' => 'ctools_context_vocabulary_settings_form', + 'defaults' => array('vid' => ''), + '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($form, &$form_state) { + $conf = $form_state['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'], + '#description' => t('Select the vocabulary for this form.'), + ); + + return $form; +} + +function ctools_context_vocabulary_settings_form_submit($form, &$form_state) { + $form_state['conf']['vid'] = $form_state['values']['vid']; +} diff --git a/sites/all/modules/ctools/plugins/export_ui/ctools_export_ui.class.php b/sites/all/modules/ctools/plugins/export_ui/ctools_export_ui.class.php new file mode 100644 index 0000000000000000000000000000000000000000..10fc50d8bc0e4c70d124797a8d203a6574ffbea4 --- /dev/null +++ b/sites/all/modules/ctools/plugins/export_ui/ctools_export_ui.class.php @@ -0,0 +1,1448 @@ +<?php +// $Id: ctools_export_ui.class.php,v 1.5 2011/01/05 22:35:46 merlinofchaos Exp $ + +/** + * 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; + } + + // ------------------------------------------------------------------------ + // 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']); + } + + // 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, + ); + if (!isset($form_state['input']['form_id'])) { + $form_state['input']['form_id'] = 'ctools_export_ui_list_form'; + } + + $form = drupal_render(drupal_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 $form . $output; + } + + $commands = array(); + $commands[] = ajax_command_replace('#ctools-export-ui-list-items', $output); + if (!empty($replace_form)) { + $commands[] = ajax_command_replace('#ctools-export-ui-list-form', $form); + } + print ajax_render($commands); + ajax_footer(); + } + + /** + * 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 clearfix">', + '#suffix' => '</div>', + ); + + $form['bottom row'] = array( + '#prefix' => '<div class="ctools-export-ui-row ctools-export-ui-bottom-row clearfix">', + '#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' => array('use-ajax-submit ctools-auto-submit-click')), + ); + + $form['bottom row']['reset'] = array( + '#type' => 'submit', + '#id' => 'ctools-export-ui-list-items-apply', + '#value' => t('Reset'), + '#attributes' => array('class' => array('use-ajax-submit')), + ); + + $form['#prefix'] = '<div class="clearfix">'; + $form['#suffix'] = '</div>'; + $form['#attached']['js'] = array('misc/ajax.js', 'misc/progress.js', 'misc/jquery.form.js', ctools_attach_js('auto-submit')); + $form['#attributes'] = array('class' => array('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; + + $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->type == t('Normal')) { + $not_allowed_operations[] = 'revert'; + } + elseif ($item->type == 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' => array('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) { + if ($form_state['values']['storage'] != 'all' && $form_state['values']['storage'] != $item->type) { + 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']}; + + // Note: $item->type 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->type . $name; + break; + } + + $this->rows[$name]['data'] = array(); + $this->rows[$name]['class'] = !empty($item->disabled) ? array('ctools-export-ui-disabled') : array('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' => array('ctools-export-ui-title')); + } + $this->rows[$name]['data'][] = array('data' => check_plain($name), 'class' => array('ctools-export-ui-name')); + $this->rows[$name]['data'][] = array('data' => check_plain($item->type), 'class' => array('ctools-export-ui-storage')); + $this->rows[$name]['data'][] = array('data' => theme('links', array('links' => $operations)), 'class' => array('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' => array('ctools-export-ui-title')); + } + + $header[] = array('data' => t('Name'), 'class' => array('ctools-export-ui-name')); + $header[] = array('data' => t('Storage'), 'class' => array('ctools-export-ui-storage')); + $header[] = array('data' => t('Operations'), 'class' => array('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) { + $table = array( + 'header' => $this->list_table_header(), + 'rows' => $this->rows, + 'attributes' => array('id' => 'ctools-export-ui-list-items'), + ); + return theme('table', $table); + } + + /** + * 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. + // ...not sure this this is the best way. + $trail = menu_set_active_item(ctools_export_ui_plugin_base_path($this->plugin)); + + $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) { + $output = drupal_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 (!empty($this->plugin['export']['admin_title'])) { + $form['info'][$export_key]['#type'] = 'machine_name'; + $form['info'][$export_key]['#machine_name'] = array( + 'exists' => 'ctools_export_ui_edit_name_exists', + 'source' => array('info', $this->plugin['export']['admin_title']), + ); + } + + if ($form_state['op'] === 'edit') { + $form['info'][$export_key]['#disabled'] = TRUE; + $form['info'][$export_key]['#value'] = $item->{$export_key}; + } + + 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, + ); + + $output = drupal_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, $form_state) { + $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, &$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']))); + } +} + +/** + * Test for #machine_name type to see if an export exists. + */ +function ctools_export_ui_edit_name_exists($name, $element, &$form_state) { + $plugin = $form_state['plugin']; + + return (empty($form_state['item']->export_ui_allow_overwrite) && ctools_export_crud_load($plugin['schema'], $name)); +} + +/** + * Delete/Revert confirm form. + * + * @todo -- call back into the object instead. + */ +function ctools_export_ui_delete_confirm_form($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']) ? ctools_export_ui_plugin_base_path($plugin) : $_REQUEST['cancel_path']; + + $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/sites/all/modules/ctools/plugins/export_ui/ctools_export_ui.inc b/sites/all/modules/ctools/plugins/export_ui/ctools_export_ui.inc new file mode 100644 index 0000000000000000000000000000000000000000..fb204c3acbe676b0e228b012851f9f84e53a3aff --- /dev/null +++ b/sites/all/modules/ctools/plugins/export_ui/ctools_export_ui.inc @@ -0,0 +1,25 @@ +<?php +// $Id: ctools_export_ui.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * 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/sites/all/modules/ctools/plugins/relationships/book_parent.inc b/sites/all/modules/ctools/plugins/relationships/book_parent.inc new file mode 100644 index 0000000000000000000000000000000000000000..adc66edec2ea59a1004a3e393b66c8d3a6846206 --- /dev/null +++ b/sites/all/modules/ctools/plugins/relationships/book_parent.inc @@ -0,0 +1,67 @@ +<?php +// $Id: book_parent.inc,v 1.7 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * @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', + 'edit form' => 'ctools_book_parent_settings_form', + '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. + return ctools_context_create('node', $node); + } + } + else { + return ctools_context_create_empty('node'); + } +} + +/** + * Settings form for the relationship. + */ +function ctools_book_parent_settings_form($form, &$form_state) { + $conf = $form_state['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/sites/all/modules/ctools/plugins/relationships/entity_from_field.inc b/sites/all/modules/ctools/plugins/relationships/entity_from_field.inc new file mode 100644 index 0000000000000000000000000000000000000000..7e6ebcabf2cb3b4f124a8a2491e5fb6632f0cb5b --- /dev/null +++ b/sites/all/modules/ctools/plugins/relationships/entity_from_field.inc @@ -0,0 +1,95 @@ +<?php +// $Id: entity_from_field.inc,v 1.1 2011/01/05 20:34:46 merlinofchaos Exp $ + +/** + * @file + * Plugin to provide an relationship handler for an entity from a field. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Entity'), + 'description' => t('Creates an entity context from a foreign key on a field.'), + 'context' => 'ctools_entity_from_field_context', + 'get child' => 'ctools_entity_from_field_get_child', + 'get children' => 'ctools_entity_from_field_get_children', +); + +function ctools_entity_from_field_get_child($plugin, $parent, $child) { + $plugins = ctools_entity_from_field_get_children($plugin, $parent); + return $plugins[$parent . ':' . $child]; +} + +function ctools_entity_from_field_get_children($plugin, $parent) { + $entities = entity_get_info(); + $plugins = array(); + $context_types = array(); + + // Get the schema information for every field. + $fields_info = field_info_instances(); + foreach ($fields_info as $entity_type => $entity_info) { + foreach ($entity_info as $bundle => $fields) { + foreach ($fields as $field_name => $field) { + $field = field_info_field($field_name); + $module = $field['module']; + module_load_install($module); + $schema = module_invoke($module, 'field_schema', $field); + if (isset($schema['foreign keys'])) { + foreach ($schema['foreign keys'] as $key => $info) { + if (isset($info['table'])) { + foreach ($entities as $entity => $einfo) { + if ($einfo['base table'] == $info['table'] && isset($info['columns'][$einfo['entity keys']['id']])) { + $plugin['title'] = t('@field_entity from @entity on @field_name field', array('@field_entity' => $einfo['label'], '@entity' => $entities[$entity_type]['label'], '@field_name' => $field_name)); + $plugin['keyword'] = $entity; + $plugin['context name'] = $field_name . '-' . $entity_type . '-' . $entity; + $plugin['name'] = $parent . ':' . $field_name . '-' . $entity_type . '-' . $entity; + $plugin['description'] = t('Creates a @entity context from @base_entity field relationship on the @base_table table.', array('@entity' => $entity, '@base_entity' => $entity_type, '@base_table' => $einfo['base table'])); + $context_types[$parent . ':' . $field_name . '-' . $entity_type . '-' . $entity]['types'][$bundle] = $entities[$entity_type]['bundles'][$bundle]['label']; + $plugins[$parent . ':' . $field_name . '-' . $entity_type . '-' . $entity] = $plugin; + } + } + } + } + } + } + } + } + foreach ($context_types as $key => $context) { + list($parent, $plugin_name) = explode(':', $key); + list($field_name, $from_entity) = explode('-', $plugin_name); + $plugins[$key]['required context'] = new ctools_context_required(t(ucfirst($from_entity)), $from_entity, array('type' => array_keys($context['types']))); + } + return $plugins; +} + +/** + * Return a new context based on an existing context. + */ +function ctools_entity_from_field_context($context, $conf) { + $plugin = $conf['name']; + list($plugin, $plugin_name) = explode(':', $plugin); + list($field_name, $from_entity, $to_entity) = explode('-', $plugin_name); + // If unset it wants a generic, unfilled context, which is just NULL. + $entity_info = entity_get_info($from_entity); + if (empty($context->data) || !isset($context->data->{$entity_info['entity keys']['id']})) { + return ctools_context_create_empty('entity:' . $to_entity, NULL); + } + + if (isset($context->data->{$entity_info['entity keys']['id']})) { + // Load the entity. + $id = $context->data->{$entity_info['entity keys']['id']}; + $entity = entity_load($from_entity, array($id)); + $entity = $entity[$id]; + if (isset($entity->$field_name)) { + $language = field_language($from_entity, $entity, $field_name); + $to_entity_info = entity_get_info($to_entity); + $to_entity_id = $entity->{$field_name}[$language][0][$to_entity_info['entity keys']['id']]; + + // Send it to ctools. + return ctools_context_create('entity:' . $to_entity, $to_entity_id); + } + } +} diff --git a/sites/all/modules/ctools/plugins/relationships/entity_from_schema.inc b/sites/all/modules/ctools/plugins/relationships/entity_from_schema.inc new file mode 100644 index 0000000000000000000000000000000000000000..a5bfa506f6e8f34fbf3ecff84ad9c8aa47fbe6ed --- /dev/null +++ b/sites/all/modules/ctools/plugins/relationships/entity_from_schema.inc @@ -0,0 +1,90 @@ +<?php +// $Id: entity_from_schema.inc,v 1.1 2011/01/05 20:34:46 merlinofchaos Exp $ + +/** + * @file + * Plugin to provide an relationship handler for an entity from a field. + */ + +/** + * Plugins are described by creating a $plugin array which will be used + * by the system that includes this file. + */ +$plugin = array( + 'title' => t('Entity'), + 'description' => t('Creates an entity context from a foreign key on a field.'), + 'context' => 'ctools_entity_from_schema_context', + 'get child' => 'ctools_entity_from_schema_get_child', + 'get children' => 'ctools_entity_from_schema_get_children', +); + +function ctools_entity_from_schema_get_child($plugin, $parent, $child) { + $plugins = ctools_entity_from_schema_get_children($plugin, $parent); + return $plugins[$parent . ':' . $child]; +} + +function ctools_entity_from_schema_get_children($plugin, $parent) { + $entities = entity_get_info(); + $plugins = array(); + + foreach (module_implements('entity_info') as $module) { + module_load_install($module); + $schemas = module_invoke($module, 'schema'); + foreach ($schemas as $table => $schema) { + foreach ($entities as $from_entity => $from_entity_info) { + if ($table == $from_entity_info['base table'] && isset($schema['foreign keys'])) { + foreach ($schema['foreign keys'] as $relationship => $info) { + foreach ($entities as $to_entity => $to_entity_info) { + if ($info['table'] == $to_entity_info['base table'] && in_array($to_entity_info['entity keys']['id'], $info['columns'])) { + $this_col = ctools_entity_from_schema_columns_filter($info['columns'], $to_entity_info['entity keys']['id']); + $plugin['title'] = t('@to_entity @relationship relationship', array('@relationship' => $relationship, '@to_entity' => $to_entity)); + $plugin['keyword'] = $to_entity; + $plugin['context name'] = $this_col . '-' . $from_entity . '-' . $to_entity; + $plugin['name'] = $parent . ':' . $this_col . '-' . $from_entity . '-' . $to_entity; + $plugin['description'] = t('Builds a @relationship relationship from a @from_entity to a @to_entity', array('@relationship' => $relationship, '@from_entity' => $from_entity, '@to_entity' => $to_entity)); + $plugin['required context'] = new ctools_context_required(t(ucfirst($from_entity_info['label'])), $from_entity); + $plugins[$parent . ':' . $this_col . '-' . $from_entity . '-' . $to_entity] = $plugin; + } + } + } + } + } + } + } + return $plugins; +} + +function ctools_entity_from_schema_columns_filter($columns, $value) { + foreach ($columns as $this_col => $that_col) { + if ($value == $that_col) { + return $this_col; + } + } +} + +/** + * Return a new context based on an existing context. + */ +function ctools_entity_from_schema_context($context, $conf) { + $plugin = $conf['name']; + list($plugin, $plugin_name) = explode(':', $plugin); + list($this_col, $from_entity, $to_entity) = explode('-', $plugin_name); + // If unset it wants a generic, unfilled context, which is just NULL. + $entity_info = entity_get_info($from_entity); + if (empty($context->data) || !isset($context->data->{$entity_info['entity keys']['id']})) { + return ctools_context_create_empty('entity:' . $to_entity, NULL); + } + + if (isset($context->data->{$entity_info['entity keys']['id']})) { + // Load the entity. + $id = $context->data->{$entity_info['entity keys']['id']}; + $entity = entity_load($from_entity, array($id)); + $entity = $entity[$id]; + if (isset($entity->$this_col)) { + $to_entity_id = $entity->$this_col; + + // Send it to ctools. + return ctools_context_create('entity:' . $to_entity, $to_entity_id); + } + } +} diff --git a/sites/all/modules/ctools/plugins/relationships/node_edit_form_from_node.inc b/sites/all/modules/ctools/plugins/relationships/node_edit_form_from_node.inc new file mode 100644 index 0000000000000000000000000000000000000000..013d28b000cb976e9e08465ca1995b8fcfa38383 --- /dev/null +++ b/sites/all/modules/ctools/plugins/relationships/node_edit_form_from_node.inc @@ -0,0 +1,32 @@ +<?php +// $Id: node_edit_form_from_node.inc,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * @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', +); + +/** + * 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); + } +} diff --git a/sites/all/modules/ctools/plugins/relationships/term_from_node.inc b/sites/all/modules/ctools/plugins/relationships/term_from_node.inc new file mode 100644 index 0000000000000000000000000000000000000000..2eac8ffb723e1281eb0ab3320da7e954a1402a8b --- /dev/null +++ b/sites/all/modules/ctools/plugins/relationships/term_from_node.inc @@ -0,0 +1,61 @@ +<?php +// $Id: term_from_node.inc,v 1.6 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * @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', + 'edit form' => 'ctools_term_from_node_settings_form', + '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($form, &$form_state) { + $conf = $form_state['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="clearfix">', + '#suffix' => '</div>', + ); + + return $form; +} diff --git a/sites/all/modules/ctools/plugins/relationships/term_parent.inc b/sites/all/modules/ctools/plugins/relationships/term_parent.inc new file mode 100644 index 0000000000000000000000000000000000000000..e1a73c09fac4d202cc0002249e4116c67215be55 --- /dev/null +++ b/sites/all/modules/ctools/plugins/relationships/term_parent.inc @@ -0,0 +1,69 @@ +<?php +// $Id: term_parent.inc,v 1.7 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * @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', + 'edit form' => 'ctools_term_parent_settings_form', + 'defaults' => array('type' => 'top'), +); + +/** + * 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_query('SELECT t1.* FROM {taxonomy_term_hierarchy} t1 INNER JOIN {taxonomy_term_hierarchy} t2 ON t1.tid = t2.parent WHERE t2.tid = :tid', array(':tid' => $context->data->tid))->fetchAssoc(); + + // 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_query('SELECT * FROM {taxonomy_term_hierarchy} WHERE tid = :tid', array(':tid' => $result['parent']))->fetchAssoc(); + } + } + + // Load the term. + if ($result) { + $term = taxonomy_term_load($result['tid']); + return ctools_context_create('term', $term); + } + } +} + +/** + * Settings form for the relationship. + */ +function ctools_term_parent_settings_form($form, &$form_state) { + $conf = $form_state['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/sites/all/modules/ctools/plugins/relationships/terms_from_node.inc b/sites/all/modules/ctools/plugins/relationships/terms_from_node.inc new file mode 100644 index 0000000000000000000000000000000000000000..9d472380b29bfb655c4b444d6782833dbc918353 --- /dev/null +++ b/sites/all/modules/ctools/plugins/relationships/terms_from_node.inc @@ -0,0 +1,77 @@ +<?php +// $Id: terms_from_node.inc,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * @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', + 'edit form' => 'ctools_terms_from_node_settings_form', + '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($form, &$form_state) { + $conf = $form_state['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="clearfix">', + '#suffix' => '</div>', + ); + $form['concatenator'] = array( + '#title' => t('Concatenator'), + '#type' => 'select', + '#options' => array(',' => ', (AND)', '+' => '+ (OR)'), + '#default_value' => $conf['concatenator'], + '#prefix' => '<div class="clearfix">', + '#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/sites/all/modules/ctools/plugins/relationships/translations/plugins-relationships.hu.po b/sites/all/modules/ctools/plugins/relationships/translations/plugins-relationships.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..7ca822636db4a7c6312c9e1f3d3b03263b824314 --- /dev/null +++ b/sites/all/modules/ctools/plugins/relationships/translations/plugins-relationships.hu.po @@ -0,0 +1,41 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-11-30 10:28+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 "Book parent" +msgstr "Szülő könyv" +msgid "Adds a book parent from a node context." +msgstr "Egy könyv szülőjének hozzáadása egy tartalomkörnyezetből." +msgid "Top level book" +msgstr "Legfelső szintű könyv" +msgid "Term from node" +msgstr "Kifejezés tartalomból" +msgid "" +"Adds a taxonomy term from a node context; if multiple terms are " +"selected, this will get the \"first\" term only." +msgstr "" +"Taxónomia kifejezés hozzáadása egy tartalomkörnyezetből. Ha " +"több kifejezés van kiválasztva, akkor csak az „elsőt” fogja " +"megjeleníteni." +msgid "Term parent" +msgstr "Kifejezés szülője" +msgid "Adds a taxonomy term parent from a term context." +msgstr "" +"Egy taxonómia kifejezés szülőjének hozzáadása egy " +"kifejezéskörnyezetből." +msgid "Top level term" +msgstr "Legfelső szintű kifejezés" +msgid "Creates the author of a node as a user context." +msgstr "" +"Egy tartalom szerzőjének létrehozása felhasználói " +"környezetként." diff --git a/sites/all/modules/ctools/plugins/relationships/user_from_node.inc b/sites/all/modules/ctools/plugins/relationships/user_from_node.inc new file mode 100644 index 0000000000000000000000000000000000000000..dd79c95613b7b9b94b327f8733f4aff910ed3763 --- /dev/null +++ b/sites/all/modules/ctools/plugins/relationships/user_from_node.inc @@ -0,0 +1,38 @@ +<?php +// $Id: user_from_node.inc,v 1.7 2010/01/29 20:18:02 merlinofchaos Exp $ + +/** + * @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($uid); + + // Send it to ctools. + return ctools_context_create('user', $account); + } +} diff --git a/sites/all/modules/ctools/stylizer/plugins/export_ui/stylizer.inc b/sites/all/modules/ctools/stylizer/plugins/export_ui/stylizer.inc new file mode 100644 index 0000000000000000000000000000000000000000..7ddc492375c0dd3f908bde84b79ae1b2fce6e700 --- /dev/null +++ b/sites/all/modules/ctools/stylizer/plugins/export_ui/stylizer.inc @@ -0,0 +1,46 @@ +<?php +// $Id: stylizer.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +$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', + ), + + '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/sites/all/modules/ctools/stylizer/plugins/export_ui/stylizer_ui.class.php b/sites/all/modules/ctools/stylizer/plugins/export_ui/stylizer_ui.class.php new file mode 100644 index 0000000000000000000000000000000000000000..0e2b60cd2cc118b6eb04b2f1d307dfdacd33eec7 --- /dev/null +++ b/sites/all/modules/ctools/stylizer/plugins/export_ui/stylizer_ui.class.php @@ -0,0 +1,271 @@ +<?php +// $Id: stylizer_ui.class.php,v 1.3 2011/01/05 22:35:46 merlinofchaos Exp $ + +/** + * 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' => array('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' => array('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' => array('ctools-export-ui-type')), + array('data' => check_plain($item->name), 'class' => array('ctools-export-ui-name')), + array('data' => check_plain($item->admin_title), 'class' => array('ctools-export-ui-title')), + array('data' => check_plain($this->style_plugin['title']), 'class' => array('ctools-export-ui-base')), + array('data' => check_plain($item->type), 'class' => array('ctools-export-ui-storage')), + array('data' => theme('links', array('links' => $operations)), 'class' => array('ctools-export-ui-operations')), + ), + 'title' => check_plain($item->admin_description), + 'class' => array(!empty($item->disabled) ? 'ctools-export-ui-disabled' : 'ctools-export-ui-enabled'), + ); + } + + function list_table_header() { + return array( + array('data' => t('Type'), 'class' => array('ctools-export-ui-type')), + array('data' => t('Name'), 'class' => array('ctools-export-ui-name')), + array('data' => t('Title'), 'class' => array('ctools-export-ui-title')), + array('data' => t('Base'), 'class' => array('ctools-export-ui-base')), + array('data' => t('Storage'), 'class' => array('ctools-export-ui-storage')), + array('data' => t('Operations'), 'class' => array('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['base_style_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' => array('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/sites/all/modules/ctools/stylizer/stylizer.info b/sites/all/modules/ctools/stylizer/stylizer.info new file mode 100644 index 0000000000000000000000000000000000000000..72332ae0f3f192de38a783a9473dd8b55550a4ee --- /dev/null +++ b/sites/all/modules/ctools/stylizer/stylizer.info @@ -0,0 +1,14 @@ +; $Id: stylizer.info,v 1.3 2011/01/01 00:01:46 merlinofchaos Exp $ +name = Stylizer +description = Create custom styles for applications such as Panels. +core = 7.x +package = Chaos tool suite +dependencies[] = ctools +dependencies[] = color + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-1.0-alpha2" +core = "7.x" +project = "ctools" +datestamp = "1294276864" + diff --git a/sites/all/modules/ctools/stylizer/stylizer.install b/sites/all/modules/ctools/stylizer/stylizer.install new file mode 100644 index 0000000000000000000000000000000000000000..1f28515003216c77e51361e5a340c499f621a5e6 --- /dev/null +++ b/sites/all/modules/ctools/stylizer/stylizer.install @@ -0,0 +1,65 @@ +<?php +// $Id: stylizer.install,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ + +/** + * 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; +} diff --git a/sites/all/modules/ctools/stylizer/stylizer.module b/sites/all/modules/ctools/stylizer/stylizer.module new file mode 100644 index 0000000000000000000000000000000000000000..c68f77a498d08262d337c756332175194f9969bc --- /dev/null +++ b/sites/all/modules/ctools/stylizer/stylizer.module @@ -0,0 +1,136 @@ +<?php +// $Id: stylizer.module,v 1.4 2011/01/05 22:53:04 merlinofchaos Exp $ + +/** + * @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. + */ + +/** + * Implements hook_permission() + */ +function stylizer_permission() { + return array( + 'administer stylizer' => array( + 'title' => t("Use the Stylizer UI"), + 'description' => t("Allows a user to use the CTools Stylizer UI."), + ), + ); +} + +/** + * 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; + } +} + +/** + * Implements hook_ctools_plugin_type() to inform the plugin system that + * Stylizer style_base plugin types. + */ +function stylizer_ctools_plugin_type() { + return array( + 'style_bases' => array( + 'load themes' => TRUE, + ), + ); +} + +/** + * 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/structure/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/structure/stylizer/list/$item->name/edit"), + 'class' => 'links', + ), + ); + + // Only show 10. + if (++$count >= 10) { + break; + } + } + } + + if ($rows) { + $content = theme('table', array('rows' => $rows, 'attributes' => 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/structure/stylizer'), + 'content' => $content, + 'class' => 'dashboard-styles', + 'section' => 'left', + ); +} + +/** + * Implementation of hook_theme to load all content plugins and pass thru if + * necessary. + */ +function stylizer_theme() { + $theme = array(); + 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( + 'variables' => $base_type['theme variables'], + '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. + } + } + } + + return $theme; +} + diff --git a/sites/all/modules/ctools/tests/css.test b/sites/all/modules/ctools/tests/css.test new file mode 100644 index 0000000000000000000000000000000000000000..48a99d113ef13e36a70a063621a44848febf6fc3 --- /dev/null +++ b/sites/all/modules/ctools/tests/css.test @@ -0,0 +1,70 @@ +<?php +// $Id: css.test,v 1.1 2010/10/11 22:18:22 sdboyer Exp $ +/** + * @file + * Tests for different parts of the ctools plugin system. + */ + +/** + * Test menu links depending on user permissions. + */ +class CtoolsCssTestCase extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => 'CSS Tools tests', + 'description' => '...', + 'group' => 'Chaos Tools Suite', + ); + } + + function setUp() { + // Additionally enable contact module. + parent::setUp('ctools'); + } + + /** + * Test that cached plugins are loaded correctly. + */ + function testCssStuff() { + $css = "#some-id .some-class {\n color: black;\n illegal-key: foo;\n}"; + $filtered_css = '#some-id .some-class{color:black;}'; + + ctools_include('css'); + $filename1 = ctools_css_store('unfiltered-css-test', $css, FALSE); + $filename2 = ctools_css_store('filtered-css-test', $css, TRUE); + + $this->assertEqual($filename1, ctools_css_retrieve('unfiltered-css-test'), 'Unfiltered css file successfully fetched'); + $file_contents = file_get_contents($filename1); + $this->assertEqual($css, $file_contents, 'Unfiltered css file contents are correct'); +// $match = $filename1 == ctools_css_retrieve('unfiltered-css-test') ? 'Match' : 'No match'; +// $output .= '<pre>Unfiltered: ' . $filename1 . ' ' . $match . '</pre>'; +// $output .= '<pre>' . file_get_contents($filename1) . '</pre>'; + + $this->assertEqual($filename2, ctools_css_retrieve('filtered-css-test'), 'Filtered css file succcesfully fetched'); + $file_contents = file_get_contents($filename2); + $this->assertEqual($filtered_css, $file_contents, 'Filtered css file contents are correct'); + // $match = $filename2 == ctools_css_retrieve('filtered-css-test') ? 'Match' : 'No match'; +// $output .= '<pre>Filtered: ' . $filename2 . ' ' . $match . '</pre>'; +// $output .= '<pre>' . file_get_contents($filename2) . '</pre>'; +// +// drupal_add_css($filename2, array('type' => 'file')); +// return array('#markup' => $output); + + + // Test that in case that url can be used, the value surives when a colon is in it. + $css = "#some-id {\n background-image: url(http://example.com/example.gif);\n}"; + $css_data = ctools_css_disassemble($css); + $empty_array = array(); + $disallowed_values_regex = '/(expression)/'; + $filtered = ctools_css_assemble(ctools_css_filter_css_data($css_data, $empty_array, $empty_array, '', $disallowed_values_regex)); + $url = (strpos($filtered, 'http://example.com/example.gif') !== FALSE); + $this->assertTrue($url, 'CSS with multiple colons can survive.'); + + // Test that in case the CSS has two properties defined are merged. + $css = "#some-id {\n font-size: 12px;\n}\n#some-id {\n color: blue;\n}"; + $filtered = ctools_css_filter($css); + $font_size = (strpos($filtered, 'font-size:12px;') !== FALSE); + $color = (strpos($filtered, 'color:blue') !== FALSE); + $this->assertTrue($font_size && $color, 'Multiple properties are merged.'); + } +} diff --git a/sites/all/modules/ctools/tests/ctools.plugins.test b/sites/all/modules/ctools/tests/ctools.plugins.test new file mode 100644 index 0000000000000000000000000000000000000000..a752e15d636ec03e6d831e7b425330311d130ed9 --- /dev/null +++ b/sites/all/modules/ctools/tests/ctools.plugins.test @@ -0,0 +1,101 @@ +<?php +// $Id: ctools.plugins.test,v 1.3 2010/10/11 22:18:22 sdboyer Exp $ +/** + * @file + * Tests for different parts of the ctools plugin system. + */ + +/** + * Test menu links depending on user permissions. + */ +class CtoolsPluginsGetInfoTestCase extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Get plugin info', + 'description' => 'Verify that plugin type definitions can properly set and overide values.', + 'group' => 'Chaos Tools Suite', + ); + } + + function setUp() { + // Additionally enable contact module. + parent::setUp('ctools', 'ctools_plugin_test'); + } + + protected function assertPluginFunction($module, $type, $id, $function = 'function') { + $func = ctools_plugin_load_function($module, $type, $id, $function); + $this->assertTrue(function_exists($func), t('Plugin @plugin of plugin type @module:@type successfully retrieved @retrieved for @function.', array( + '@plugin' => $id, + '@module' => $module, + '@type' => $type, + '@function' => $function, + '@retrieved' => $func, + ))); + } + + protected function assertPluginMissingFunction($module, $type, $id, $function = 'function') { + $func = ctools_plugin_load_function($module, $type, $id, $function); + $this->assertEqual($func, NULL, t('Plugin @plugin of plugin type @module:@type for @function with missing function successfully failed.', array( + '@plugin' => $id, + '@module' => $module, + '@type' => $type, + '@function' => $func, + ))); + } + + protected function assertPluginClass($module, $type, $id, $class = 'handler') { + $class_name = ctools_plugin_load_class($module, $type, $id, $class); + $this->assertTrue(class_exists($class_name), t('Plugin @plugin of plugin type @module:@type successfully retrieved @retrieved for @class.', array( + '@plugin' => $id, + '@module' => $module, + '@type' => $type, + '@class' => $class, + '@retrieved' => $class_name, + ))); + } + + protected function assertPluginMissingClass($module, $type, $id, $class = 'handler') { + $class_name = ctools_plugin_load_class($module, $type, $id, $class); + $this->assertEqual($class_name, NULL, t('Plugin @plugin of plugin type @module:@type for @class with missing class successfully failed.', array( + '@plugin' => $id, + '@module' => $module, + '@type' => $type, + '@class' => $class, + ))); + } + + /** + * Test that plugins are loaded correctly. + */ + function testPluginLoading() { + ctools_include('plugins'); + $module = 'ctools_plugin_test'; + $type = 'not_cached'; + + // Test function retrieval for plugins using different definition methods. + $this->assertPluginFunction($module, $type, 'plugin_array', 'function'); + $this->assertPluginFunction($module, $type, 'plugin_array2', 'function'); + $this->assertPluginMissingFunction($module, $type, 'plugin_array_dne', 'function'); + $this->assertPluginFunction($module, "big_hook_$type", 'test1', 'function'); + + // Test class retrieval for plugins using different definition methods. + $this->assertPluginClass($module, $type, 'plugin_array', 'handler'); + $this->assertPluginClass($module, $type, 'plugin_array2', 'handler'); + $this->assertPluginMissingClass($module, $type, 'plugin_array_dne', 'handler'); + // TODO Test big hook plugins. + + $type = 'cached'; + + // Test function retrieval for plugins using different definition methods. + $this->assertPluginFunction($module, $type, 'plugin_array', 'function'); + $this->assertPluginFunction($module, $type, 'plugin_array2', 'function'); + $this->assertPluginMissingFunction($module, $type, 'plugin_array_dne', 'function'); + $this->assertPluginFunction($module, "big_hook_$type", 'test1', 'function'); + + // Test class retrieval for plugins using different definition methods. + $this->assertPluginClass($module, $type, 'plugin_array', 'handler'); + $this->assertPluginClass($module, $type, 'plugin_array2', 'handler'); + $this->assertPluginMissingClass($module, $type, 'plugin_array_dne', 'handler'); + // TODO Test big hook plugins. + } +} diff --git a/sites/all/modules/ctools/tests/ctools_plugin_test.info b/sites/all/modules/ctools/tests/ctools_plugin_test.info new file mode 100644 index 0000000000000000000000000000000000000000..3bc97fc0f04d30ca16ad058ed2d80448096c0399 --- /dev/null +++ b/sites/all/modules/ctools/tests/ctools_plugin_test.info @@ -0,0 +1,16 @@ +; $Id: ctools_plugin_test.info,v 1.2 2011/01/01 00:01:46 merlinofchaos Exp $ +name = Chaos tools plugins test +description = Provides hooks for testing ctools plugins. +package = Chaos tool suite +core = 7.x +dependencies[] = ctools +files[] = ctools.plugins.test +files[] = object_cache.test +hidden = TRUE + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-1.0-alpha2" +core = "7.x" +project = "ctools" +datestamp = "1294276864" + diff --git a/sites/all/modules/ctools/tests/ctools_plugin_test.module b/sites/all/modules/ctools/tests/ctools_plugin_test.module new file mode 100644 index 0000000000000000000000000000000000000000..f978dd48c20ae8adb8d64f6d634d8a9e6c0b6bf9 --- /dev/null +++ b/sites/all/modules/ctools/tests/ctools_plugin_test.module @@ -0,0 +1,73 @@ +<?php +// $Id: ctools_plugin_test.module,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ +/** + * Define some plugin systems to test ctools plugin includes. + */ + +/** + * Implementation of hook_ctools_plugin_dierctory() + */ +function ctools_plugin_test_ctools_plugin_directory($module, $plugin) { + if ($module == 'ctools_plugin_test') { + return 'plugins/' . $plugin; + } +} + +function ctools_plugin_test_ctools_plugin_type() { + return array( + 'extra_defaults' => array( + 'defaults' => array( + 'bool' => true, + 'string' => 'string', + 'array' => array('some value'), + ), + ), + 'cached' => array( + 'cache' => TRUE, + 'classes' => array( + 'handler', + ), + ), + 'not_cached' => array( + 'cache' => FALSE, + 'classes' => array( + 'handler', + ), + ), + 'big_hook_cached' => array( + 'cache' => TRUE, + 'use hooks' => TRUE, + 'classes' => array( + 'handler', + ), + ), + 'big_hook_not_cached' => array( + 'cache' => FALSE, + 'use hooks' => TRUE, + 'classes' => array( + 'handler', + ), + ), + ); +} + +function ctools_plugin_test_ctools_plugin_test_big_hook_cached() { + return array( + 'test1' => array( + 'function' => 'ctools_plugin_test_hook_cached_test', + 'handler' => 'class1', + ), + ); +} + +function ctools_plugin_test_ctools_plugin_test_big_hook_not_cached() { + return array( + 'test1' => array( + 'function' => 'ctools_plugin_test_hook_not_cached_test', + 'class' => 'class1', + ), + ); +} + +function ctools_plugin_test_hook_cached_test() {} +function ctools_plugin_test_hook_not_cached_test() {} diff --git a/sites/all/modules/ctools/tests/object_cache.test b/sites/all/modules/ctools/tests/object_cache.test new file mode 100644 index 0000000000000000000000000000000000000000..d46c7d20226c2ea1bfc5503ec7ad174db8dd94ec --- /dev/null +++ b/sites/all/modules/ctools/tests/object_cache.test @@ -0,0 +1,47 @@ +<?php +// $Id: object_cache.test,v 1.1 2010/10/11 22:18:22 sdboyer Exp $ +/** + * @file + * Tests for different parts of the ctools object caching system. + */ + +/** + * Test object cache storage. + */ +class CtoolsObjectCache extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Ctools object cache storage', + 'description' => 'Verify that objects are written, readable and lockable.', + 'group' => 'Chaos Tools Suite', + ); + } + + public function setUp() { + // Additionally enable ctools module. + parent::setUp('ctools'); + } + + public function testObjectStorage() { + $account1 = $this->drupalCreateUser(array()); + $this->drupalLogin($account1); + + $data = array( + 'test1' => 'foobar', + ); + + ctools_include('object-cache'); + ctools_object_cache_set('testdata', 'one', $data); + $this->assertEqual($data, ctools_object_cache_get('testdata', 'one'), 'Object cache data successfully stored'); + + // TODO Test object locking somehow. + // Object locking/testing works on session_id but simpletest uses + // $this->session_id so can't be tested ATM. + + ctools_object_cache_clear('testdata', 'one'); + $this->assertFalse(ctools_object_cache_get('testdata', 'one'), 'Object cache data successfully cleared'); + + // TODO Test ctools_object_cache_clear_all somehow... + // ctools_object_cache_clear_all requires session_id funtionality as well. + } +} diff --git a/sites/all/modules/ctools/tests/plugins/cached/ctoolsCachedPluginArray.class.php b/sites/all/modules/ctools/tests/plugins/cached/ctoolsCachedPluginArray.class.php new file mode 100644 index 0000000000000000000000000000000000000000..853582a4e9dac9c10bf52cb3fa51678fe85c538b --- /dev/null +++ b/sites/all/modules/ctools/tests/plugins/cached/ctoolsCachedPluginArray.class.php @@ -0,0 +1,8 @@ +<?php +// $Id: ctoolsCachedPluginArray.class.php,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ +/** + * @file + * A cached plugin object that tests inheritence including. + */ + +class ctoolsCachedPluginArray {} diff --git a/sites/all/modules/ctools/tests/plugins/cached/ctoolsCachedPluginArray2.class.php b/sites/all/modules/ctools/tests/plugins/cached/ctoolsCachedPluginArray2.class.php new file mode 100644 index 0000000000000000000000000000000000000000..4be0f4a1b1328c76f6faf11419a9d94b27d5052c --- /dev/null +++ b/sites/all/modules/ctools/tests/plugins/cached/ctoolsCachedPluginArray2.class.php @@ -0,0 +1,8 @@ +<?php +// $Id: ctoolsCachedPluginArray2.class.php,v 1.1 2010/10/11 22:18:23 sdboyer Exp $ +/** + * @file + * A cached plugin object that tests inheritence including. + */ + +class ctoolsCachedPluginArray2 extends ctoolsCachedPluginArray {} diff --git a/sites/all/modules/ctools/tests/plugins/cached/plugin_array.inc b/sites/all/modules/ctools/tests/plugins/cached/plugin_array.inc new file mode 100644 index 0000000000000000000000000000000000000000..609c7c0ed24454bdf304a06cc98c69d7e058b613 --- /dev/null +++ b/sites/all/modules/ctools/tests/plugins/cached/plugin_array.inc @@ -0,0 +1,21 @@ +<?php +// $Id: plugin_array.inc,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ +/** + * @file + * Chaos Tools plugin include using a plugin array to declare a plugin. + */ + +/** + * Plugin array plugin definition. + */ +$plugin = array( + 'function' => 'ctools_plugin_test_plugin_array_cached_test', + 'handler' => array( + 'class' => 'ctoolsCachedPluginArray', + ), +); + +/** + * Plugin array function plugin. + */ +function ctools_plugin_test_plugin_array_cached_test() {} diff --git a/sites/all/modules/ctools/tests/plugins/cached/plugin_array2.inc b/sites/all/modules/ctools/tests/plugins/cached/plugin_array2.inc new file mode 100644 index 0000000000000000000000000000000000000000..5c1d2ce8979259fd07dfae4369f1c81bd4396fa4 --- /dev/null +++ b/sites/all/modules/ctools/tests/plugins/cached/plugin_array2.inc @@ -0,0 +1,21 @@ +<?php +// $Id: plugin_array2.inc,v 1.1 2010/10/11 22:18:23 sdboyer Exp $ +/** + * @file + * Chaos Tools plugin include using a plugin array to declare a plugin. + */ + +/** + * Plugin array plugin definition. + */ +$plugin = array( + 'function' => 'ctools_plugin_test_plugin_array2_cached_test', + 'handler' => array( + 'class' => 'ctoolsCachedPluginArray2', + ), +); + +/** + * Plugin array function plugin. + */ +function ctools_plugin_test_plugin_array2_cached_test() {} diff --git a/sites/all/modules/ctools/tests/plugins/cached/plugin_array_dne.inc b/sites/all/modules/ctools/tests/plugins/cached/plugin_array_dne.inc new file mode 100644 index 0000000000000000000000000000000000000000..4f39ff04d0a9524ae25ab3d94c24e26c460da399 --- /dev/null +++ b/sites/all/modules/ctools/tests/plugins/cached/plugin_array_dne.inc @@ -0,0 +1,16 @@ +<?php +// $Id: plugin_array_dne.inc,v 1.1 2010/10/11 22:18:23 sdboyer Exp $ +/** + * @file + * Chaos Tools plugin include using a plugin array to declare a plugin. + */ + +/** + * Plugin array plugin definition. + */ +$plugin = array( + 'function' => 'ctools_plugin_test_plugin_array_dne_cached_test', + 'handler' => array( + 'class' => 'ctoolsCachedPluginArrayDNE', + ), +); diff --git a/sites/all/modules/ctools/tests/plugins/not_cached/ctoolsNotCachedPluginArray.class.php b/sites/all/modules/ctools/tests/plugins/not_cached/ctoolsNotCachedPluginArray.class.php new file mode 100644 index 0000000000000000000000000000000000000000..38666ce4a5a89a69ce88115d273b9c9bf5caf1e4 --- /dev/null +++ b/sites/all/modules/ctools/tests/plugins/not_cached/ctoolsNotCachedPluginArray.class.php @@ -0,0 +1,8 @@ +<?php +// $Id: ctoolsNotCachedPluginArray.class.php,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ +/** + * @file + * A cached plugin object that tests inheritence including. + */ + +class ctoolsNotCachedPluginArray extends ctoolsNotCachedPluginArray2 {} diff --git a/sites/all/modules/ctools/tests/plugins/not_cached/ctoolsNotCachedPluginArray2.class.php b/sites/all/modules/ctools/tests/plugins/not_cached/ctoolsNotCachedPluginArray2.class.php new file mode 100644 index 0000000000000000000000000000000000000000..5aa6db12629972c0005c5ce2ece1917e48b596e1 --- /dev/null +++ b/sites/all/modules/ctools/tests/plugins/not_cached/ctoolsNotCachedPluginArray2.class.php @@ -0,0 +1,8 @@ +<?php +// $Id: ctoolsNotCachedPluginArray2.class.php,v 1.1 2010/10/11 22:18:23 sdboyer Exp $ +/** + * @file + * A cached plugin object that tests including. + */ + +class ctoolsNotCachedPluginArray2 {} diff --git a/sites/all/modules/ctools/tests/plugins/not_cached/plugin_array.inc b/sites/all/modules/ctools/tests/plugins/not_cached/plugin_array.inc new file mode 100644 index 0000000000000000000000000000000000000000..a3c640e0badc86ee163e0a420ddb17f0d95c8bea --- /dev/null +++ b/sites/all/modules/ctools/tests/plugins/not_cached/plugin_array.inc @@ -0,0 +1,21 @@ +<?php +// $Id: plugin_array.inc,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ +/** + * @file + * Chaos Tools plugin include using a plugin array to declare a plugin. + */ + +/** + * Plugin array plugin definition. + */ +$plugin = array( + 'function' => 'ctools_plugin_test_plugin_array_not_cached_test', + 'handler' => array( + 'class' => 'ctoolsNotCachedPluginArray', + ), +); + +/** + * Plugin array function plugin. + */ +function ctools_plugin_test_plugin_array_not_cached_test() {} diff --git a/sites/all/modules/ctools/tests/plugins/not_cached/plugin_array2.inc b/sites/all/modules/ctools/tests/plugins/not_cached/plugin_array2.inc new file mode 100644 index 0000000000000000000000000000000000000000..e909cdcdcbf6fbb81367045e3ae061bc83f51220 --- /dev/null +++ b/sites/all/modules/ctools/tests/plugins/not_cached/plugin_array2.inc @@ -0,0 +1,21 @@ +<?php +// $Id: plugin_array2.inc,v 1.1 2010/10/11 22:18:23 sdboyer Exp $ +/** + * @file + * Chaos Tools plugin include using a plugin array to declare a plugin. + */ + +/** + * Plugin array plugin definition. + */ +$plugin = array( + 'function' => 'ctools_plugin_test_plugin_array2_not_cached_test', + 'handler' => array( + 'class' => 'ctoolsNotCachedPluginArray2', + ), +); + +/** + * Plugin array function plugin. + */ +function ctools_plugin_test_plugin_array2_not_cached_test() {} diff --git a/sites/all/modules/ctools/tests/plugins/not_cached/plugin_array_dne.inc b/sites/all/modules/ctools/tests/plugins/not_cached/plugin_array_dne.inc new file mode 100644 index 0000000000000000000000000000000000000000..c13245375f04b4c9f441d5b5261d1b73ed86092f --- /dev/null +++ b/sites/all/modules/ctools/tests/plugins/not_cached/plugin_array_dne.inc @@ -0,0 +1,16 @@ +<?php +// $Id: plugin_array_dne.inc,v 1.1 2010/10/11 22:18:23 sdboyer Exp $ +/** + * @file + * Chaos Tools plugin include using a plugin array to declare a plugin. + */ + +/** + * Plugin array plugin definition. + */ +$plugin = array( + 'function' => 'ctools_plugin_test_plugin_array_dne_not_cached_test', + 'handler' => array( + 'class' => 'ctoolsNotCachedPluginArrayDNE', + ), +); diff --git a/sites/all/modules/ctools/translations/ctools.de.po b/sites/all/modules/ctools/translations/ctools.de.po new file mode 100644 index 0000000000000000000000000000000000000000..8a161b6d4fd4055b1b30583e893a2a4c31f2d240 --- /dev/null +++ b/sites/all/modules/ctools/translations/ctools.de.po @@ -0,0 +1,4469 @@ +# $Id: ctools.de.po,v 1.2 2009/11/20 22:32:50 thomaszahreddin Exp $ +# +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# panels.module,v 1.10.2.9 2007/03/15 23:13:41 merlinofchaos +# fourcol_25_25_25_25.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# threecol_33_33_33.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_25_75.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_33_66.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_38_62.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_50_50.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_62_38.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_66_33.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_75_25.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# threecol_25_50_25_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# threecol_33_34_33.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# threecol_33_34_33_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# twocol.inc,v 1.6 2006/08/22 23:54:20 merlinofchaos +# twocol_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# +msgid "" +msgstr "" +"Project-Id-Version: ctools\n" +"POT-Creation-Date: 2009-10-22 21:56+0200\n" +"PO-Revision-Date: 2009-11-20 23:30+0100\n" +"Last-Translator: Thomas Zahreddin <tz@it-arts.org>\n" +"Language-Team: Thomas Zahreddin\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" + +#: ctools.install:25 +msgid "CTools CSS Cache" +msgstr "CTools-CSS-Cache" + +#: ctools.install:27 +msgid "Exists" +msgstr "Vorhanden" + +#: ctools.install:31 +msgid "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." +msgstr "" + +#: ctools.install:33 +msgid "Unable to create" +msgstr "Konnte nicht erstellt werden" + +#: ctools.install:113 +#, fuzzy +msgid "A special cache used to store objects that are being edited; it serves to save state in an ordinarily stateless environment." +msgstr "Ein spezieller Cache der zum Speichern von Objekten verwendet wird, die gerade bearbeitet werden. Dieser stellt den Status " + +#: ctools.info:0 +msgid "Chaos tools" +msgstr "Chaos-Tools" + +#: ctools.info:0 +msgid "A library of helpful tools by Merlin of Chaos." +msgstr "" + +#: ctools.info:0 +#: bulk_export/bulk_export.info:0 +#: ctools_plugin_example/ctools_plugin_example.info:0 +#: page_manager/page_manager.info:0 +#: views_content/views_content.info:0 +msgid "Chaos tool suite" +msgstr "Chaos Tool Suite" + +#: bulk_export/bulk_export.module:68 +#, fuzzy +msgid "Bulk export results" +msgstr "Massen-Export der Panels." + +#: bulk_export/bulk_export.module:92;116;127 +#, fuzzy +msgid "Place this in @file" +msgstr "%d Datei(en) in diesem Verzeichnis gefunden" + +#: bulk_export/bulk_export.module:133 +#, fuzzy +msgid "There are no objects to be exported at this time." +msgstr "Derzeit gibt es keine exportierbaren Panels." + +#: bulk_export/bulk_export.module:159 +#, fuzzy +msgid "Module name" +msgstr "Modulname" + +# English is missing "for this context" +#: bulk_export/bulk_export.module:160 +#, fuzzy +msgid "Enter the module name to export code to." +msgstr "Modulnamen eingeben, zu dem exportiert wird." + +#: bulk_export/bulk_export.module:165 +#: page_manager/page_manager.admin.inc:682 +#: page_manager/plugins/tasks/page.inc:183 +#, fuzzy +msgid "Export" +msgstr "Exportieren" + +#: bulk_export/bulk_export.module:200 +msgid "There are no objects in your system that may be exported at this time." +msgstr "" + +#: bulk_export/bulk_export.module:13 +#, fuzzy +msgid "use bulk exporter" +msgstr "Panels-Export verwenden" + +#: bulk_export/bulk_export.module:31 +#, fuzzy +msgid "Bulk Exporter" +msgstr "Panels-Export" + +#: bulk_export/bulk_export.module:32 +msgid "Bulk-export multiple CTools-handled data objects to code." +msgstr "" + +#: bulk_export/bulk_export.info:0 +#, fuzzy +msgid "Bulk Export" +msgstr "Massenexport" + +#: bulk_export/bulk_export.info:0 +msgid "Performs bulk exporting of data objects known about by Chaos tools." +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.module:36 +msgid "Demonstration code, advanced help, and a demo panel to show how to build ctools plugins." +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.module:79 +msgid "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." +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.module:81 +msgid "" +"There is a demo panel demonstrating much of the functionality provided at\n" +" <a href=\"@demo_url\">CTools demo panel</a>, and you can find documentation on the examples at\n" +" !ctools_plugin_example_help.\n" +" CTools itself provides documentation at !ctools_help. Mostly, though, the code itself is intended to be the teacher.\n" +" You can find it in %path." +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.module:35 +#, fuzzy +msgid "CTools plugin example" +msgstr "Neu aus Beispiel" + +#: ctools_plugin_example/ctools_plugin_example.info:0 +msgid "Chaos Tools (CTools) Plugin Example" +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.info:0 +msgid "Shows how an external module can provide ctools plugins (for Panels, etc.)." +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:15 +#, fuzzy +msgid "Arg length" +msgstr "Maximallänge" + +#: ctools_plugin_example/plugins/access/arg_length.inc:16 +#, fuzzy +msgid "Control access by length of simplecontext argument." +msgstr "Zugriff mit Beitragssprache kontrollieren." + +#: ctools_plugin_example/plugins/access/arg_length.inc:20 +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:33;42 +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:16 +#: ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc:22 +#, fuzzy +msgid "Simplecontext" +msgstr "Kontext" + +#: ctools_plugin_example/plugins/access/arg_length.inc:30 +msgid "Grant access if simplecontext argument length is" +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:31 +#, fuzzy +msgid "Greater than" +msgstr "Mehr als" + +#: ctools_plugin_example/plugins/access/arg_length.inc:31 +#, fuzzy +msgid "Less than or equal to" +msgstr "gleich oder weniger" + +#: ctools_plugin_example/plugins/access/arg_length.inc:36 +#, fuzzy +msgid "Length of simplecontext argument" +msgstr "Aus dem Panelargument" + +#: ctools_plugin_example/plugins/access/arg_length.inc:39 +msgid "Access/visibility will be granted based on arg length." +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:63 +msgid "Simpletext argument must be !comp @length characters" +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:16 +#, fuzzy +msgid "CTools example: role" +msgstr "Einstellungen für @role" + +#: ctools_plugin_example/plugins/access/example_role.inc:17 +#: plugins/access/role.inc:15 +msgid "Control access by role." +msgstr "Zugriff mit Rolle kontrollieren" + +#: ctools_plugin_example/plugins/access/example_role.inc:22 +#: plugins/access/node_access.inc:22 +#: plugins/access/perm.inc:20 +#: plugins/access/role.inc:21 +#: plugins/content_types/contact/user_contact.inc:17;18 +#: plugins/content_types/user_context/profile_fields.inc:15;16 +#: plugins/content_types/user_context/user_picture.inc:13;14 +#: plugins/content_types/user_context/user_profile.inc:13;14 +#: plugins/contexts/user.inc:15 +#, fuzzy +msgid "User" +msgstr "Benutzer" + +#: ctools_plugin_example/plugins/access/example_role.inc:32 +#: plugins/access/role.inc:31 +msgid "Role" +msgstr "Rolle" + +#: ctools_plugin_example/plugins/access/example_role.inc:35 +#: plugins/access/role.inc:34 +msgid "Only the checked roles will be granted access." +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:74 +#: plugins/access/role.inc:75 +msgid "@identifier can have any role" +msgstr "@identifier kann jede Rolle enthalten" + +#: ctools_plugin_example/plugins/access/example_role.inc:76 +#, fuzzy +msgid "@identifier must have role \"@roles\"" +msgid_plural "@identifier can be one of \"@roles\"" +msgstr[0] "@identifier kann jede Rolle enthalten" +msgstr[1] "@identifier kann jede Rolle enthalten" + +#: ctools_plugin_example/plugins/arguments/simplecontext_arg.inc:26 +#, fuzzy +msgid "Simplecontext arg" +msgstr "Argument: @arg" + +#: ctools_plugin_example/plugins/arguments/simplecontext_arg.inc:29 +#, fuzzy +msgid "Creates a \"simplecontext\" from the arg." +msgstr "Erstellt ein Benutzer-Objekt durch ein Argument." + +# English is missing "for this context" +#: ctools_plugin_example/plugins/arguments/simplecontext_arg.inc:37 +#, fuzzy +msgid "Enter the simplecontext arg" +msgstr "Variable @arg geladen" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:19 +msgid "CTools example no context content type" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:20 +msgid "No context content type - requires and uses no context." +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:37 +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:30 +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:37 +#, fuzzy +msgid "CTools Examples" +msgstr "Beispiele: lb, kg, %." + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:94 +msgid "Item1" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:96 +#, fuzzy +msgid "The setting for item 1." +msgstr " / Nach Objekt suchen" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:103 +msgid "Item2" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:105 +#, fuzzy +msgid "The setting for item 2" +msgstr " / Nach Objekt suchen" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:21 +msgid "CTools example relcontext content type" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:28 +msgid "Relcontext content type - works with relcontext context." +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:29 +#: ctools_plugin_example/plugins/contexts/relcontext.inc:16 +#, fuzzy +msgid "Relcontext" +msgstr "Kontext" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:55 +msgid "" +"\n" +" This is a block of data created by the Relcontent content type.\n" +" Data in the block may be assembled from static text (like this) or from the\n" +" content type settings form ($conf) for the content type, or from the context\n" +" that is passed in. <br />\n" +" In our case, the configuration form ($conf) has just one field, 'config_item_1;\n" +" and it's configured with:\n" +" " +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:87 +#, fuzzy +msgid "Config Item 1 (relcontext)" +msgstr "Menüpunkt hinzufügen" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:89 +#, fuzzy +msgid "Setting for relcontext." +msgstr "Setze Dateitype für @E auf %N.\n" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:23 +#, fuzzy +msgid "Simplecontext content type" +msgstr "Inhaltstyp hinzufügen" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:32 +msgid "Simplecontext content type - works with a simplecontext context." +msgstr "" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:82 +msgid "" +"\n" +" This is a block of data created by the Simplecontext content type.\n" +" Data in the block may be assembled from static text (like this) or from the\n" +" content type settings form ($conf) for the content type, or from the context\n" +" that is passed in. <br />\n" +" In our case, the configuration form ($conf) has just one field, 'config_item_1;\n" +" and it's configured with:\n" +" " +msgstr "" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:111 +msgid "Config Item 1 for simplecontext content type" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:113 +#, fuzzy +msgid "The stuff for item 1." +msgstr " / Nach Objekt suchen" + +#: ctools_plugin_example/plugins/contexts/relcontext.inc:17 +#, fuzzy +msgid "A relcontext object." +msgstr "Ein Beitragsobjekt." + +#: ctools_plugin_example/plugins/contexts/relcontext.inc:53 +#, fuzzy +msgid "Relcontext context from simplecontext" +msgstr "Fügt ein Profil aus dem Benutzer-Kontext hinzu" + +#: ctools_plugin_example/plugins/contexts/relcontext.inc:77 +#, fuzzy +msgid "Relcontext setting" +msgstr "Richte %s ein (%s) ...\n" + +#: ctools_plugin_example/plugins/contexts/relcontext.inc:79 +#, fuzzy +msgid "Just an example setting." +msgstr "Standard Kommentar-Einstellungen" + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:17 +msgid "A single \"simplecontext\" context, or data element." +msgstr "" + +# English is missing "for this context" +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:25 +#, fuzzy +msgid "Enter some data to represent this \"simplecontext\"." +msgstr "Die Beitragstyp für diesen Kontext eingeben." + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:58 +#, fuzzy +msgid "Simplecontext context from config" +msgstr "Fügt ein Profil aus dem Benutzer-Kontext hinzu" + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:87 +#, fuzzy +msgid "Setting for simplecontext" +msgstr "Setze Dateitype für @E auf %N.\n" + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:89 +msgid "An example setting that could be used to configure a context" +msgstr "" + +#: ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc:19 +#, fuzzy +msgid "Relcontext from simplecontext" +msgstr "Entfernen von @buddylist" + +#: ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc:21 +#, fuzzy +msgid "Adds a relcontext from existing simplecontext." +msgstr "Fügt ein übergeordnetes Buch aus einem Beitragskontext hinzu." + +#: includes/ajax.inc:137 +#: page_manager/page_manager.admin.inc:927 +#, fuzzy +msgid "Error" +msgstr "Fehler" + +#: includes/ajax.inc:138 +msgid "Server reports invalid input error." +msgstr "Der Server hat eine ungültige Eingabe festgestellt." + +#: includes/content.inc:337 +msgid "@type:@subtype will not display due to missing context" +msgstr "@type:@subtype wird wegen fehlendem Kontext nicht angezeigt" + +#: includes/content.inc:422 +msgid "No info" +msgstr "Keine Infos" + +#: includes/content.inc:423 +msgid "No info available." +msgstr "Keine Information verfügbar." + +#: includes/content.inc:454 +msgid "Override title" +msgstr "Titel überschreiben" + +#: includes/content.inc:473 +msgid "You may use %keywords from contexts, as well as %title to contain the original title." +msgstr "%keywords von Kontexten sowie der originale Titel %title können verwendet werden." + +#: includes/content.inc:544 +#: page_manager/page_manager.admin.inc:578 +#, fuzzy +msgid "Configure" +msgstr "Konfigurieren" + +#: includes/content.inc:547 +msgid "Configure new !subtype_title" +msgstr "Neuen !subtype_title konfigurieren" + +#: includes/content.inc:550 +msgid "Configure !subtype_title" +msgstr "!subtype_title konfigurieren" + +#: includes/content.menu.inc:45 +#: plugins/content_types/node_context/node_author.inc:36 +#: plugins/contexts/user.inc:49 +#, fuzzy +msgid "Anonymous" +msgstr "anonym" + +#: includes/content.menu.inc:46 +msgid "by @user" +msgstr "von @user" + +#: includes/context-access-admin.inc:159 +msgid "Add" +msgstr "Hinzufügen" + +#: includes/context-access-admin.inc:165 +msgid "All criteria must pass." +msgstr "Alle Kriterien müssen richtig sein." + +#: includes/context-access-admin.inc:166 +msgid "Only one criteria must pass." +msgstr "Ein Kriterium muss richtig sein." + +#: includes/context-access-admin.inc:174;405 +#: includes/context-admin.inc:622;701;772;883 +#: page_manager/page_manager.admin.inc:1177 +#, fuzzy +msgid "Save" +msgstr "Speichern" + +#: includes/context-access-admin.inc:198 +#, fuzzy +msgid "Broken/missing access plugin %plugin" +msgstr "Interner Fehler: beschädigtes Plugin." + +#: includes/context-access-admin.inc:205 +#: includes/context-admin.inc:342 +msgid "Configure settings for this item." +msgstr "Einstellungen für diesen Eintrag konfigurieren." + +#: includes/context-access-admin.inc:206 +#: includes/context-admin.inc:338 +msgid "Remove this item." +msgstr "Dieses Element entfernen" + +#: includes/context-access-admin.inc:214 +#: includes/context-admin.inc:850 +#: page_manager/page_manager.admin.inc:90;267;1316 +#: page_manager/plugins/tasks/page.admin.inc:654 +#: plugins/content_types/custom/custom.inc:113 +#: plugins/content_types/search/search_result.inc:117;155 +#, fuzzy +msgid "Title" +msgstr "Titel" + +#: includes/context-access-admin.inc:215 +msgid "Description" +msgstr "Beschreibung" + +#: includes/context-access-admin.inc:220 +msgid "No criteria selected, this test will pass." +msgstr "" + +#: includes/context-access-admin.inc:278;346;457 +#, fuzzy +msgid "Missing callback hooks." +msgstr "Client Callback-Fehler" + +#: includes/context-access-admin.inc:303 +msgid "Add criteria" +msgstr "Kriterium hinzufügen" + +#: includes/context-access-admin.inc:367 +msgid "Edit criteria" +msgstr "Kriterium bearbeiten" + +#: includes/context-admin.inc:26 +#: page_manager/plugins/tasks/page.inc:158 +#: views_content/plugins/content_types/views.inc:360 +#, fuzzy +msgid "Arguments" +msgstr "Argumente" + +#: includes/context-admin.inc:27;858 +msgid "argument" +msgstr "Argument" + +#: includes/context-admin.inc:29 +msgid "Add argument" +msgstr "Argument hinzufügen" + +#: includes/context-admin.inc:37 +msgid "Relationships" +msgstr "Beziehungen" + +#: includes/context-admin.inc:38;748 +msgid "relationship" +msgstr "Beziehung" + +#: includes/context-admin.inc:40 +msgid "Add relationship" +msgstr "Beziehung hinzufügen" + +#: includes/context-admin.inc:48 +msgid "Contexts" +msgstr "Kontexte" + +#: includes/context-admin.inc:49;598 +msgid "context" +msgstr "Kontext" + +#: includes/context-admin.inc:51 +msgid "Add context" +msgstr "Kontext hinzufügen" + +#: includes/context-admin.inc:59 +msgid "Required contexts" +msgstr "Erforderliche Kontexte" + +# English: uppercase first +#: includes/context-admin.inc:60;686 +msgid "required context" +msgstr "Erforderlicher Kontext" + +#: includes/context-admin.inc:62 +msgid "Add required context" +msgstr "Erforderlichen Kontext hinzufügen" + +#: includes/context-admin.inc:365;493;931 +#: page_manager/plugins/tasks/page.admin.inc:952 +#, fuzzy +msgid "Invalid object name." +msgstr "Ungültiger Objektname." + +#: includes/context-admin.inc:412 +msgid "Add @type \"@context\"" +msgstr "@type „@context“ hinzufügen" + +#: includes/context-admin.inc:511 +msgid "Invalid context type" +msgstr "Ungültiger Kontexttyp." + +#: includes/context-admin.inc:530 +msgid "Edit @type \"@context\"" +msgstr "@type „@context“ bearbeiten" + +#: includes/context-admin.inc:597;685;747;857 +#: plugins/content_types/node_context/node_links.inc:93 +#, fuzzy +msgid "Identifier" +msgstr "Bezeichner" + +#: includes/context-admin.inc:598;686;748;858 +msgid "Enter a name to identify this !type on administrative screens." +msgstr "Einen Namen eingeben, um diese(s) !type auf administrativen Seiten zu identifizieren." + +#: includes/context-admin.inc:604;692;754;864 +#: plugins/content_types/custom/custom.inc:147 +#, fuzzy +msgid "Keyword" +msgstr "Schlüsselwort" + +#: includes/context-admin.inc:605;693;755;865 +msgid "Enter a keyword to use for substitution in titles." +msgstr "Platzhalter zur Ersetzung in Titeln eingeben." + +#: includes/context-admin.inc:839 +#: includes/export.inc:191;275 +#: page_manager/page_manager.module:500;515 +#: page_manager/plugins/tasks/page.inc:217 +#: plugins/content_types/search/search_form.inc:117 +#: views_content/plugins/content_types/views.inc:432 +#, fuzzy +msgid "Default" +msgstr "Standard" + +#: includes/context-admin.inc:841 +msgid "Ignore it; content that requires this context will not be available." +msgstr "Ignorieren; Inhalt, der diesen Kontext erfordert, ist nicht verfügbar." + +#: includes/context-admin.inc:842 +msgid "Display page not found or display nothing at all." +msgstr "" + +#: includes/context-admin.inc:845 +msgid "If the argument is missing or is not valid, select how this should behave." +msgstr "Bestimmt das Verhalten, falls das Argument fehlt oder nicht gültig ist." + +#: includes/context-admin.inc:852 +#, fuzzy +msgid "Enter a title to use when this argument is present. You may use %KEYWORD substitution, where the keyword is specified below." +msgstr "Titel der verwendet wird, wenn das Argument vorhanden ist. %KEYWORD Ersetzung kann verwendet werden, sofern ein Platzhalter durch den Administrator definiert wurde." + +#: includes/context-admin.inc:942 +#, fuzzy +msgid "Unable to delete missing item!" +msgstr "Konnte fehlende Pakete nicht korrigieren." + +#: includes/context-task-handler.inc:118 +msgid "Edit @type" +msgstr "@type bearbeiten" + +#: includes/context-task-handler.inc:308 +msgid "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." +msgstr "" + +#: includes/context-task-handler.inc:356 +msgid "Summary of contexts" +msgstr "Zusammenfassung von Kontexten" + +#: includes/context.inc:49 +msgid "Unknown context" +msgstr "Unbekannter Kontext" + +#: includes/context.inc:195;196;400 +#: page_manager/plugins/tasks/page.admin.inc:1120;1140 +#, fuzzy +msgid "No context" +msgstr "Kein Kontext" + +#: includes/context.inc:311;418 +msgid "Context %count" +msgstr "Kontext %count" + +#: includes/context.inc:311;418 +msgid "Context" +msgstr "Kontext" + +#: includes/context.inc:425 +msgid "Please choose which context and how you would like it converted." +msgstr "" + +#: includes/context.inc:1233 +msgid "@identifier (@keyword)" +msgstr "@identifier (@keyword)" + +#: includes/context.inc:1297 +msgid "Logged in user" +msgstr "Angemeldeter Benutzer" + +# context sensitive string +#: includes/context.inc:1335 +#, fuzzy +msgid ", and " +msgstr ", und" + +# context sensitive +#: includes/context.inc:1335 +#, fuzzy +msgid ", or " +msgstr ", oder" + +#: includes/context.theme.inc:80 +#: page_manager/plugins/tasks/page.admin.inc:696 +#: page_manager/theme/page_manager.theme.inc:103 +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:196 +#, fuzzy +msgid "Weight" +msgstr "Reihenfolge" + +#: includes/context.theme.inc:82 +#: plugins/access/node_access.inc:33 +#, fuzzy +msgid "Operation" +msgstr "Operation" + +#: includes/context.theme.inc:131;237 +#, fuzzy +msgid "Built in context" +msgstr "Integrierte Oberfläche" + +#: includes/context.theme.inc:134;158;181;201;240;259;275;290 +msgid "Keyword: %@keyword" +msgstr "Schlüsselwort: %@keyword" + +#: includes/context.theme.inc:136;161;183;203 +msgid "@keyword --> @title" +msgstr "@keyword --> @title" + +#: includes/context.theme.inc:155;256 +msgid "Argument @count" +msgstr "Argument @count" + +#: includes/context.theme.inc:178;272 +msgid "Context @count" +msgstr "Kontext @count" + +#: includes/context.theme.inc:198;287 +msgid "From \"@title\"" +msgstr "Von „@title“" + +#: includes/css.inc:162 +msgid "Unable to create CTools CSS cache directory. Check the permissions on your files directory." +msgstr "" + +#: includes/export.inc:146 +#: page_manager/page_manager.module:366 +#: page_manager/plugins/tasks/page.admin.inc:1456 +#, fuzzy +msgid "Normal" +msgstr "Normal" + +#: includes/export.inc:184 +#: page_manager/page_manager.admin.inc:1473 +#: page_manager/page_manager.module:509 +#: page_manager/plugins/tasks/page.admin.inc:1485;1499;1510 +#, fuzzy +msgid "Overridden" +msgstr "Übersschrieben" + +#: includes/export.inc:608 +#: page_manager/page_manager.module:636 +#, fuzzy +msgid "Local" +msgstr "Lokal" + +#: includes/form.inc:303 +msgid "Validation error, please try again. If this error persists, please contact the site administrator." +msgstr "Bei der Gültigkeitsüberprüfung ist ein Fehler aufgetreten, bitte erneut versuchen. Falls der Fehler fortbesteht, wenden Sie sich bitte an den Administrator der Website." + +#: includes/menu.inc:58 +msgid "Home" +msgstr "Startseite" + +#: includes/modal.inc:52 +msgid "Close Window" +msgstr "Fenster schließen" + +#: includes/modal.inc:53;53 +msgid "Close window" +msgstr "Fenster schließen" + +#: includes/modal.inc:54 +#: js/modal.js:0;0 +#, fuzzy +msgid "Loading..." +msgstr "Laden..." + +#: includes/modal.inc:54 +msgid "Loading" +msgstr "Laden" + +#: includes/wizard.inc:373 +msgid "Continue" +msgstr "Fortfahren" + +#: includes/wizard.inc:374 +msgid "Back" +msgstr "Zurück" + +#: includes/wizard.inc:375 +msgid "Update and return" +msgstr "Aktualisieren und Zurück" + +#: includes/wizard.inc:376 +msgid "Finish" +msgstr "Abschließen" + +#: includes/wizard.inc:377 +#: page_manager/page_manager.admin.inc:1183 +#, fuzzy +msgid "Cancel" +msgstr "Abbrechen" + +#: page_manager/page_manager.admin.inc:25 +msgid "See the getting started guide for more information." +msgstr "" + +#: page_manager/page_manager.admin.inc:40 +msgid "This page is currently locked for editing by you. Nobody else may edit this page until these changes are saved or canceled." +msgstr "" + +#: page_manager/page_manager.admin.inc:44 +msgid "This page is currently locked for editing by another user. You may not edit this page without breaking the lock." +msgstr "" + +#: page_manager/page_manager.admin.inc:52;297 +#, fuzzy +msgid "Reset" +msgstr "Zurücksetzen" + +#: page_manager/page_manager.admin.inc:88;238;270 +#: page_manager/plugins/tasks/page.admin.inc:642 +#, fuzzy +msgid "Type" +msgstr "Typ" + +#: page_manager/page_manager.admin.inc:89;268 +#, fuzzy +msgid "Name" +msgstr "Name" + +#: page_manager/page_manager.admin.inc:91;269 +#: page_manager/plugins/tasks/page.admin.inc:399;1244;1370 +#: page_manager/plugins/tasks/page.inc:647 +#: page_manager/plugins/tasks/term_view.inc:258 +#: plugins/content_types/search/search_form.inc:115 +#, fuzzy +msgid "Path" +msgstr "Pfad" + +#: page_manager/page_manager.admin.inc:92;245;271 +#: page_manager/plugins/tasks/page.inc:46;592 +#, fuzzy +msgid "Storage" +msgstr "Speicherort" + +#: page_manager/page_manager.admin.inc:95 +#: page_manager/plugins/tasks/page.admin.inc:909 +#, fuzzy +msgid "Operations" +msgstr "Operationen" + +#: page_manager/page_manager.admin.inc:163 +#: page_manager/plugins/tasks/search.inc:213 +#, fuzzy +msgid "System" +msgstr "System" + +#: page_manager/page_manager.admin.inc:171 +#: page_manager/plugins/tasks/page.inc:217 +#: page_manager/plugins/tasks/search.inc:215 +#, fuzzy +msgid "In code" +msgstr "Im Code" + +#: page_manager/page_manager.admin.inc:189 +#: page_manager/page_manager.module:79 +#: page_manager/plugins/tasks/page.inc:623;665;701 +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:120 +#, fuzzy +msgid "Edit" +msgstr "Bearbeiten" + +#: page_manager/page_manager.admin.inc:197;523;529;708;713 +#: page_manager/plugins/tasks/page.inc:598 +#, fuzzy +msgid "Enable" +msgstr "Aktivieren" + +#: page_manager/page_manager.admin.inc:203;536;542;719;724 +#: page_manager/plugins/tasks/page.inc:602 +#, fuzzy +msgid "Disable" +msgstr "Deaktivieren" + +#: page_manager/page_manager.admin.inc:234 +#, fuzzy +msgid "<All>" +msgstr "<Alle>" + +#: page_manager/page_manager.admin.inc:252;253 +#: page_manager/plugins/tasks/page.inc:603 +#, fuzzy +msgid "Enabled" +msgstr "Aktiviert" + +#: page_manager/page_manager.admin.inc:253 +#: page_manager/plugins/tasks/page.inc:599 +#, fuzzy +msgid "Disabled" +msgstr "Deaktiviert" + +#: page_manager/page_manager.admin.inc:259 +#: page_manager/plugins/tasks/search.inc:25 +#, fuzzy +msgid "Search" +msgstr "Suchen" + +#: page_manager/page_manager.admin.inc:264 +#, fuzzy +msgid "Sort by" +msgstr "Sortieren nach" + +#: page_manager/page_manager.admin.inc:266 +#, fuzzy +msgid "Enabled, title" +msgstr "Aktiviert, Titel" + +#: page_manager/page_manager.admin.inc:278 +#, fuzzy +msgid "Order" +msgstr "Reihenfolge" + +#: page_manager/page_manager.admin.inc:280 +#, fuzzy +msgid "Up" +msgstr "nach oben" + +#: page_manager/page_manager.admin.inc:281 +#, fuzzy +msgid "Down" +msgstr "Herunter" + +#: page_manager/page_manager.admin.inc:290 +#, fuzzy +msgid "Apply" +msgstr "Übernehmen" + +#: page_manager/page_manager.admin.inc:470;662 +#, fuzzy +msgid "Summary" +msgstr "Übersicht" + +#: page_manager/page_manager.admin.inc:471 +#, fuzzy +msgid "Get a summary of the information about this page." +msgstr "Eine Zusammenfassung der Information über diese Seite anzeigen." + +#: page_manager/page_manager.admin.inc:524 +#, fuzzy +msgid "Activate this page so that it will be in use in your system." +msgstr "Diese Seite aktivieren, damit diese im System verwendet wird." + +#: page_manager/page_manager.admin.inc:537 +#, fuzzy +msgid "De-activate this page. The data will remain but the page will not be in use on your system." +msgstr "Diese Seite deaktivieren. Die Daten werden behalten, aber die Seite wird auf dem System nicht mehr verwendet." + +#: page_manager/page_manager.admin.inc:548 +#, fuzzy +msgid "Add variant" +msgstr "Variante hinzufügen" + +#: page_manager/page_manager.admin.inc:549 +#, fuzzy +msgid "Add a new variant to this page." +msgstr "Eine neue Variante zu dieser Seite hinzufügen." + +#: page_manager/page_manager.admin.inc:554;587 +#, fuzzy +msgid "Create variant" +msgstr "Variante erstellen" + +#: page_manager/page_manager.admin.inc:559 +#, fuzzy +msgid "Import variant" +msgstr "Variante importieren" + +#: page_manager/page_manager.admin.inc:560 +#, fuzzy +msgid "Add a new variant to this page from code exported from another page." +msgstr "Aus exportiertem Code einer anderen Seite, eine neue Variante zu dieser Seite hinzufügen." + +#: page_manager/page_manager.admin.inc:566 +#, fuzzy +msgid "Reorder variants" +msgstr "Varianten neu sortieren" + +#: page_manager/page_manager.admin.inc:568 +msgid "Change the priority of the variants to ensure that the right one gets selected." +msgstr "" + +#: page_manager/page_manager.admin.inc:579 +msgid "Configure a newly created variant prior to actually adding it to the page." +msgstr "" + +#: page_manager/page_manager.admin.inc:606;611 +#, fuzzy +msgid "Break lock" +msgstr "Sperre aufheben" + +#: page_manager/page_manager.admin.inc:607 +#, fuzzy +msgid "Break the lock on this page so that you can edit it." +msgstr "Die Sperre auf diese Seite aufheben, damit diese bearbeitet werden kann." + +#: page_manager/page_manager.admin.inc:630 +#, fuzzy +msgid "Variants" +msgstr "Varianten" + +#: page_manager/page_manager.admin.inc:655 +#, fuzzy +msgid "Variant operations" +msgstr "Varianten-Operationen" + +#: page_manager/page_manager.admin.inc:663 +#, fuzzy +msgid "Get a summary of the information about this variant." +msgstr "Eine Zusammenfassung der Information über diese Variante anzeigen." + +#: page_manager/page_manager.admin.inc:677 +#: page_manager/plugins/tasks/page.admin.inc:1384 +#: page_manager/plugins/tasks/page.inc:178 +#, fuzzy +msgid "Clone" +msgstr "Duplizieren" + +#: page_manager/page_manager.admin.inc:678 +#, fuzzy +msgid "Make an exact copy of this variant." +msgstr "Eine genaue Kopie dieser Variante erstellen." + +#: page_manager/page_manager.admin.inc:683 +#, fuzzy +msgid "Export this variant into code to import into another page." +msgstr "Diese Variante in Code exportieren, damit diese in eine andere Seite importiert werden kann." + +#: page_manager/page_manager.admin.inc:688;692 +#: page_manager/plugins/tasks/page.admin.inc:1499 +#: page_manager/plugins/tasks/page.inc:189 +#, fuzzy +msgid "Revert" +msgstr "Zurücksetzen" + +#: page_manager/page_manager.admin.inc:689 +msgid "Remove all changes to this variant and revert to the version in code." +msgstr "" + +#: page_manager/page_manager.admin.inc:698;702 +#: page_manager/plugins/tasks/page.admin.inc:1499 +#: page_manager/plugins/tasks/page.inc:196 +#: plugins/access/node_access.inc:38 +#, fuzzy +msgid "Delete" +msgstr "Löschen" + +#: page_manager/page_manager.admin.inc:699 +#, fuzzy +msgid "Remove this variant from the page completely." +msgstr "Diese Variante vollständig aus der Seite entfernen." + +#: page_manager/page_manager.admin.inc:709 +#, fuzzy +msgid "Activate this variant so that it will be in use in your system." +msgstr "Diese Seite aktivieren, damit diese im System verwendet wird." + +#: page_manager/page_manager.admin.inc:720 +#, fuzzy +msgid "De-activate this variant. The data will remain but the variant will not be in use on your system." +msgstr "Diese Seite deaktivieren. Die Daten werden behalten, aber die Seite wird auf dem System nicht mehr verwendet." + +#: page_manager/page_manager.admin.inc:732 +#, fuzzy +msgid "No variants" +msgstr "Keine Varianten" + +#: page_manager/page_manager.admin.inc:814 +#: plugins/access/node_access.inc:37 +#, fuzzy +msgid "Update" +msgstr "Aktualisieren" + +#: page_manager/page_manager.admin.inc:928 +#, fuzzy +msgid "This operation trail does not exist." +msgstr "Die angegebene ID ist in der Datenbank nicht vorhanden." + +#: page_manager/page_manager.admin.inc:945 +msgid "The page has been updated. Changes will not be permanent until you save." +msgstr "" + +#: page_manager/page_manager.admin.inc:962 +#, fuzzy +msgid "Unable to update changes due to lock." +msgstr "Die Änderungen konnten aufgrund einer Sperre nicht aktualisiert werden." + +#: page_manager/page_manager.admin.inc:1112 +#, fuzzy +msgid "This setting contains unsaved changes." +msgstr "Diese Einstellung enthält nicht gespeicherte Änderungen." + +#: page_manager/page_manager.admin.inc:1170 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1201 +msgid "All pending changes have been discarded, and the page is now unlocked." +msgstr "" + +#: page_manager/page_manager.admin.inc:1252 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1317 +#, fuzzy +msgid "Administrative title of this variant. If you leave blank it will be automatically assigned." +msgstr "Administrativer Titel dieser Variante. Solllte dieser leer gelassen werden, wird er automatisch zugewiesen." + +#: page_manager/page_manager.admin.inc:1322 +#, fuzzy +msgid "Variant type" +msgstr "Variantentyp" + +#: page_manager/page_manager.admin.inc:1331 +#, fuzzy +msgid "Optional features" +msgstr "Optionale Funktionen" + +#: page_manager/page_manager.admin.inc:1333 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1361;1516 +#, fuzzy +msgid "Variant name" +msgstr "Varianten-Name" + +#: page_manager/page_manager.admin.inc:1362;1517 +#, fuzzy +msgid "Enter the name of the new variant." +msgstr "Den Namen einer neuen Variante eingeben." + +#: page_manager/page_manager.admin.inc:1367 +#, fuzzy +msgid "Paste variant code here" +msgstr "Varianten-Code hier einfügen" + +#: page_manager/page_manager.admin.inc:1383 +#, fuzzy +msgid "No variant found." +msgstr "Keine Variante gefunden" + +#: page_manager/page_manager.admin.inc:1386 +msgid "Unable to get a variant from the import. Errors reported: @errors" +msgstr "" + +#: page_manager/page_manager.admin.inc:1474 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1477 +msgid "Are you sure you want to delete this variant? This deletion will not be made permanent until you click Save." +msgstr "" + +#: page_manager/page_manager.admin.inc:1543 +msgid "This variant is currently disabled. Enabling it will make it available in your system. This will not take effect until you save this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:1562 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1594 +msgid "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?" +msgstr "" + +#: page_manager/page_manager.admin.inc:1606 +msgid "The lock has been cleared and all changes discarded. You may now make changes to this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:1614 +msgid "Enabling this page will immediately make it available in your system (there is no need to wait for a save.)" +msgstr "" + +#: page_manager/page_manager.admin.inc:1641 +msgid "Disabling this page will immediately make it unavailable in your system (there is no need to wait for a save.)" +msgstr "" + +#: page_manager/page_manager.admin.inc:1699 +msgid "This page has no variants and thus no output of its own." +msgstr "" + +#: page_manager/page_manager.admin.inc:1704 +#, fuzzy +msgid "Add a new variant" +msgstr "Neue Variante hinzufügen" + +#: page_manager/page_manager.admin.inc:1722 +#, fuzzy +msgid "Unable to disable due to lock." +msgstr "Konnte wegen Sperre nicht deaktiviert werden." + +#: page_manager/page_manager.admin.inc:1725 +#, fuzzy +msgid "Unable to enable due to lock." +msgstr "Konnte wegen Sperre nicht aktiviert werden." + +#: page_manager/page_manager.module:42 +#, fuzzy +msgid "use page manager" +msgstr "Seiten-Manager verwenden" + +#: page_manager/page_manager.module:42 +#, fuzzy +msgid "administer page manager" +msgstr "Seiten-Manager verwalten" + +#: page_manager/page_manager.module:66 +#, fuzzy +msgid "Pages" +msgstr "Seiten" + +#: page_manager/page_manager.module:67 +msgid "Add, edit and remove overridden system pages and user defined pages from the system." +msgstr "" + +#: page_manager/page_manager.module:72 +#, fuzzy +msgid "List" +msgstr "Alle anzeigen" + +#: page_manager/page_manager.install:222 +#, fuzzy +msgid "Panel" +msgstr "Panel" + +#: page_manager/page_manager.info:0 +#, fuzzy +msgid "Page manager" +msgstr "Seiten-Manager" + +#: page_manager/page_manager.info:0 +msgid "Provides a UI and API to manage pages within the site." +msgstr "" + +#: page_manager/plugins/tasks/blog.inc:17;18 +#, fuzzy +msgid "All blogs" +msgstr "Alle Blogs" + +#: page_manager/plugins/tasks/blog.inc:19 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/blog.inc:56 +msgid "Page manager module is unable to enable blog because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/blog_user.inc:16;17 +#, fuzzy +msgid "User blog" +msgstr "Weblog von @name" + +#: page_manager/plugins/tasks/blog_user.inc:18 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/blog_user.inc:59 +msgid "Page manager module is unable to enable blog/%user because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/blog_user.inc:109 +#: page_manager/plugins/tasks/contact_user.inc:105 +#: page_manager/plugins/tasks/user_view.inc:97 +#, fuzzy +msgid "User being viewed" +msgstr "Alle Aktivitäten eines Benutzers anzeigen" + +#: page_manager/plugins/tasks/contact_site.inc:17;18 +#, fuzzy +msgid "Site contact page" +msgstr "Die Kontaktseite des Senders." + +#: page_manager/plugins/tasks/contact_site.inc:19 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/contact_site.inc:56 +msgid "Page manager module is unable to enable contact because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/contact_user.inc:12;13 +#, fuzzy +msgid "User contact" +msgstr "benutzer/[user-raw]/kontakt" + +#: page_manager/plugins/tasks/contact_user.inc:14 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/contact_user.inc:55 +msgid "Page manager module is unable to enable user/%user/contact because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:13;14 +#, fuzzy +msgid "Node add/edit form" +msgstr "Beitragsbearbeitungsformular" + +#: page_manager/plugins/tasks/node_edit.inc:15 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:55 +msgid "Page manager module is unable to enable node/%node/edit because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:65 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:129 +#, fuzzy +msgid "Create @name" +msgstr "@name erstellen" + +#: page_manager/plugins/tasks/node_edit.inc:143 +#, fuzzy +msgid "Node being edited" +msgstr "Zur Bearbeitung geöffnete Dateien" + +#: page_manager/plugins/tasks/node_view.inc:22;24 +#, fuzzy +msgid "Node template" +msgstr "Beitragsvorlage" + +#: page_manager/plugins/tasks/node_view.inc:25 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:66 +msgid "Page manager module is unable to enable node/%node because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:118 +#, fuzzy +msgid "Node being viewed" +msgstr "Kommentar wird angezeigt" + +#: page_manager/plugins/tasks/page.admin.inc:201;279 +#, fuzzy +msgid "Basic settings" +msgstr "Basiseinstellungen" + +#: page_manager/plugins/tasks/page.admin.inc:202;974;982 +#, fuzzy +msgid "Argument settings" +msgstr "Argumenteinstellungen" + +#: page_manager/plugins/tasks/page.admin.inc:203;439 +#, fuzzy +msgid "Access control" +msgstr "Zugriffskontrolle" + +#: page_manager/plugins/tasks/page.admin.inc:204 +#, fuzzy +msgid "Menu settings" +msgstr "Menüeinstellungen" + +#: page_manager/plugins/tasks/page.admin.inc:280 +#, fuzzy +msgid "A meaningless second page" +msgstr "!a Kommentare pro Seite" + +#: page_manager/plugins/tasks/page.admin.inc:372;1362 +#: plugins/content_types/custom/custom.inc:106 +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:166 +#, fuzzy +msgid "Administrative title" +msgstr "Administrativer Titel" + +#: page_manager/plugins/tasks/page.admin.inc:373;1363 +#, fuzzy +msgid "The name of this page. This will appear in the administrative interface to easily identify it." +msgstr "Der Titel von dieser Seite. Dieser wird zur leichteren Identifizierung in der Verwaltungsoberfläche angezeigt." + +#: page_manager/plugins/tasks/page.admin.inc:379 +#, fuzzy +msgid "Machine name" +msgstr "Maschinenlesbarer Name" + +#: page_manager/plugins/tasks/page.admin.inc:380 +msgid "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!" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:391 +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:176;186 +#, fuzzy +msgid "Administrative description" +msgstr "Administrative Beschreibung" + +#: page_manager/plugins/tasks/page.admin.inc:392 +#, fuzzy +msgid "A description of what this page is, does or is for, for administrative use." +msgstr "Einen Namen eingeben, um diese(s) !type auf administrativen Seiten zu identifizieren." + +#: page_manager/plugins/tasks/page.admin.inc:400 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:422 +#, fuzzy +msgid "Make this your site home page." +msgstr "Dies ist die Startseite der Website." + +#: page_manager/plugins/tasks/page.admin.inc:423 +msgid "To set this panel as your home page you must create a unique path name with no % placeholders in the path. The current site home page is set to %homepage." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:428 +msgid "This page is currently set to be your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:440 +#, fuzzy +msgid "Visible menu item" +msgstr "Sichtbarer Menüpunkt" + +#: page_manager/plugins/tasks/page.admin.inc:461 +#, fuzzy +msgid "Name is required." +msgstr "Der Name ist erforderlich." + +#: page_manager/plugins/tasks/page.admin.inc:468 +#, fuzzy +msgid "That name is used by another page: @page" +msgstr "Der maschinenlesbare Name %name wird schon von einem anderen Repository verwendet." + +#: page_manager/plugins/tasks/page.admin.inc:473 +#, fuzzy +msgid "Page name must be alphanumeric or underscores only." +msgstr "Der Seitenname darf nur alphanumerische Zeichen oder Unterstriche enthalten." + +#: page_manager/plugins/tasks/page.admin.inc:480 +msgid "That path is used by another page: @page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:488 +#, fuzzy +msgid "Path is required." +msgstr "Der Pfad ist erforderlich." + +#: page_manager/plugins/tasks/page.admin.inc:501 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:506 +msgid "You cannot have a dynamic path element after an optional path element." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:515 +msgid "You cannot have a static path element after an optional path element." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:526 +msgid "That path is already in used. This system cannot override existing paths." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:534 +msgid "That path is currently assigned to be an alias for @alias. This system cannot override existing aliases." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:539 +msgid "You cannot make this page your site home page if it uses % placeholders." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:547 +#, fuzzy +msgid "Duplicated argument %arg" +msgstr "Doppeltes Argument %arg" + +#: page_manager/plugins/tasks/page.admin.inc:552 +#, fuzzy +msgid "Invalid arg <em>%</em>. All arguments must be named with keywords." +msgstr "Ungültiges Argument <em>%</em>. Alle Argumente müssen mit Schlüsselwörtern benannt sein." + +#: page_manager/plugins/tasks/page.admin.inc:645 +#: page_manager/plugins/tasks/page.inc:698 +#: page_manager/plugins/tasks/term_view.inc:269 +#, fuzzy +msgid "No menu entry" +msgstr "Kein Menüeintrag" + +#: page_manager/plugins/tasks/page.admin.inc:646 +#, fuzzy +msgid "Normal menu entry" +msgstr "Normaler Menüeintrag" + +#: page_manager/plugins/tasks/page.admin.inc:647;709 +#, fuzzy +msgid "Menu tab" +msgstr "Menü als Karteireiter" + +#: page_manager/plugins/tasks/page.admin.inc:648 +#, fuzzy +msgid "Default menu tab" +msgstr "Standard-Menü als Karteireiter" + +#: page_manager/plugins/tasks/page.admin.inc:657 +#, fuzzy +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "Den zu verwendenden Text für den Menüpunkt eingeben, wenn dieser auf Normal oder Reiter eingestellt wird." + +#: page_manager/plugins/tasks/page.admin.inc:667 +msgid "Warning: Changing this item's menu will not work reliably in Drupal 6.4 or earlier. Please upgrade your copy of Drupal at !url." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:677 +#: page_manager/plugins/tasks/page.inc:172;703 +#: page_manager/plugins/tasks/term_view.inc:272 +#, fuzzy +msgid "Menu" +msgstr "Menü" + +#: page_manager/plugins/tasks/page.admin.inc:681;731 +#, fuzzy +msgid "Insert item into an available menu." +msgstr "Menüeintrag in ein vorhandenes Menü eintragen." + +#: page_manager/plugins/tasks/page.admin.inc:692 +msgid "Menu selection requires the activation of menu module." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:699 +#, fuzzy +msgid "The lower the weight the higher/further left it will appear." +msgstr "Je niedriger die Reihenfolge, umso höher bzw. weiter links wird es erscheinen." + +#: page_manager/plugins/tasks/page.admin.inc:707 +#, fuzzy +msgid "Parent menu item" +msgstr "Übergeordneter Menüpunkt" + +#: page_manager/plugins/tasks/page.admin.inc:709 +#, fuzzy +msgid "Already exists" +msgstr "Schon vorhanden" + +#: page_manager/plugins/tasks/page.admin.inc:709 +#, fuzzy +msgid "Normal menu item" +msgstr "Normaler Menüpunkt" + +#: page_manager/plugins/tasks/page.admin.inc:711 +msgid "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>." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:716 +#, fuzzy +msgid "Parent item title" +msgstr "Titel des übergeordneten Menüpunktes" + +#: page_manager/plugins/tasks/page.admin.inc:719 +#, fuzzy +msgid "If creating a parent menu item, enter the title of the item." +msgstr "Einen Titel für den Menüpunkt eingeben, wenn ein übergeordneter Menüpunkt erstellt wird." + +#: page_manager/plugins/tasks/page.admin.inc:727 +#, fuzzy +msgid "Parent item menu" +msgstr "Übergeordneter Menüpunkt" + +#: page_manager/plugins/tasks/page.admin.inc:744 +#, fuzzy +msgid "Tab weight" +msgstr "Karteireitergewichtung" + +#: page_manager/plugins/tasks/page.admin.inc:748 +#, fuzzy +msgid "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." +msgstr "Die Reihenfolge des Reiters eingeben, wenn der übergeordnete Menüpunkt ein Reiter ist. Umso niedriger die Zahl ist, desto weiter links wird er angezeigt." + +#: page_manager/plugins/tasks/page.admin.inc:783 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:852 +#, fuzzy +msgid "No context assigned" +msgstr "Kein Kontext zugewiesen" + +#: page_manager/plugins/tasks/page.admin.inc:876 +#, fuzzy +msgid "Change" +msgstr "Ändern" + +#: page_manager/plugins/tasks/page.admin.inc:893 +#: page_manager/plugins/tasks/page.inc:143 +#: page_manager/plugins/tasks/term_view.inc:50;65 +#, fuzzy +msgid "Settings" +msgstr "Einstellungen" + +#: page_manager/plugins/tasks/page.admin.inc:906 +#, fuzzy +msgid "Argument" +msgstr "Argument" + +#: page_manager/plugins/tasks/page.admin.inc:907 +#, fuzzy +msgid "Position in path" +msgstr "Position im Pfad" + +#: page_manager/plugins/tasks/page.admin.inc:908 +#, fuzzy +msgid "Context assigned" +msgstr "Kontext wurde zugewiesen" + +#: page_manager/plugins/tasks/page.admin.inc:927 +#, fuzzy +msgid "The path %path has no arguments to configure." +msgstr "Der Pfad %path enthält keine konfigurierbaren Argumente." + +#: page_manager/plugins/tasks/page.admin.inc:961 +#, fuzzy +msgid "Invalid keyword." +msgstr "Ungültiges Schlüsselwort." + +#: page_manager/plugins/tasks/page.admin.inc:973 +#, fuzzy +msgid "Change context type" +msgstr "Kontexttyp ändern." + +#: page_manager/plugins/tasks/page.admin.inc:978 +#, fuzzy +msgid "Change argument" +msgstr "Argument ändern" + +#: page_manager/plugins/tasks/page.admin.inc:1084 +#, fuzzy +msgid "No context selected" +msgstr "Kein Kontext ausgewählt" + +#: page_manager/plugins/tasks/page.admin.inc:1167 +#, fuzzy +msgid "Error: missing argument." +msgstr "Fehler: Fehlendes Argument" + +#: page_manager/plugins/tasks/page.admin.inc:1180 +#, fuzzy +msgid "Context identifier" +msgstr "Kontext Bezeichner" + +#: page_manager/plugins/tasks/page.admin.inc:1181 +msgid "This is the title of the context used to identify it later in the administrative process. This will never be shown to a user." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1187 +#, fuzzy +msgid "Error: missing or invalid argument plugin %argument." +msgstr "Fehler: Fehlendes oder ungültiges Argument-Plugin %argument." + +#: page_manager/plugins/tasks/page.admin.inc:1235 +#, fuzzy +msgid "Import page" +msgstr "Import-Seite" + +#: page_manager/plugins/tasks/page.admin.inc:1238;1356 +#, fuzzy +msgid "Page name" +msgstr "Seiten-Name" + +#: page_manager/plugins/tasks/page.admin.inc:1239 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1245 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1250 +#, fuzzy +msgid "Allow overwrite of an existing page" +msgstr "Überschreiben einer vorhanden Seite zulassen" + +#: page_manager/plugins/tasks/page.admin.inc:1251 +#, fuzzy +msgid "If the name you selected already exists in the database, this page will be allowed to overwrite the existing page." +msgstr "Sollte der ausgewähle Namen in der Datenbank schon vorhanden sein, kann die vorhandene Seite überschrieben werden." + +#: page_manager/plugins/tasks/page.admin.inc:1256 +#, fuzzy +msgid "Paste page code here" +msgstr "Seiten-Code hier einfügen" + +#: page_manager/plugins/tasks/page.admin.inc:1262 +#, fuzzy +msgid "Import" +msgstr "Importieren" + +#: page_manager/plugins/tasks/page.admin.inc:1278 +#, fuzzy +msgid "No handler found." +msgstr "Nichts gefunden" + +#: page_manager/plugins/tasks/page.admin.inc:1280 +msgid "Unable to get a page from the import. Errors reported: @errors" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1291 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1357 +#, fuzzy +msgid "Enter the name to the new page It must be unique and contain only alphanumeric characters and underscores." +msgstr "Einen einzigartigen Namen für diese Panel-Ansicht eingeben. Dieser darf nur Buchstaben und Zahlen enthalten." + +#: page_manager/plugins/tasks/page.admin.inc:1371 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1377 +#, fuzzy +msgid "Clone variants" +msgstr "Varianten duplizieren" + +#: page_manager/plugins/tasks/page.admin.inc:1378 +msgid "If checked all variants associated with the page will be cloned as well. If not checked the page will be cloned without variants." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1486 +#, fuzzy +msgid "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." +msgstr "Eine Ansicht zurückzusetzten wird die Ansicht in der Datenbank löschen und auf die Orginalansicht zurücksetzten. Alle vorgenommenen Änderungen gehen verloren und können nicht wiederhergestellt werden." + +#: page_manager/plugins/tasks/page.admin.inc:1489 +#, fuzzy +msgid "Are you sure you want to delete this page? Deleting a page cannot be undone." +msgstr "Soll diese Seite wirklich gelöscht werden? Das Löschen einer Seite kann nicht rückgängig gemacht werden." + +#: page_manager/plugins/tasks/page.admin.inc:1512 +#, fuzzy +msgid "The page has been deleted." +msgstr "Die Seite wurde gelöscht." + +#: page_manager/plugins/tasks/page.admin.inc:1516 +#, fuzzy +msgid "The page has been reverted." +msgstr "Die Seite wurde zurückgesetzt." + +#: page_manager/plugins/tasks/page.inc:22 +#, fuzzy +msgid "Custom pages" +msgstr "Benutzerdefinierte Seiten" + +#: page_manager/plugins/tasks/page.inc:23 +msgid "Administrator created pages that have a URL path, access control and entries in the Drupal menu system." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:39 +#, fuzzy +msgid "Create a new page" +msgstr "Neue Seite erstellen" + +#: page_manager/plugins/tasks/page.inc:150 +#: page_manager/plugins/tasks/term_view.inc:68 +#, fuzzy +msgid "Basic" +msgstr "Basis" + +#: page_manager/plugins/tasks/page.inc:151 +#: page_manager/plugins/tasks/term_view.inc:69 +#, fuzzy +msgid "Edit name, path and other basic settings for the page." +msgstr "Den Namen, Pfad und andere Basiseinstellungen für die Seite bearbeiten." + +#: page_manager/plugins/tasks/page.inc:159 +msgid "Set up contexts for the arguments on this page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:165;668 +#: page_manager/plugins/tasks/term_view.inc:264 +#, fuzzy +msgid "Access" +msgstr "Zugriff" + +#: page_manager/plugins/tasks/page.inc:166 +msgid "Control what users can access this page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:167 +msgid "Access rules are used to test if the page is accessible and any menu items associated with it are visible." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:173 +msgid "Provide this page a visible menu or a menu tab." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:179 +#, fuzzy +msgid "Make a copy of this page" +msgstr "Eine Kopie dieser Seite erstellen" + +#: page_manager/plugins/tasks/page.inc:184 +msgid "Export this page as code that can be imported or embedded into a module." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:190 +msgid "Remove all changes to this page and revert to the version in code." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:197 +msgid "Remove this page from your system completely." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:208 +#: plugins/content_types/custom/custom.inc:26;58 +#: plugins/content_types/node/node.inc:27 +#: plugins/content_types/search/search_form.inc:119 +#, fuzzy +msgid "Custom" +msgstr "Benutzerdefiniert" + +#: page_manager/plugins/tasks/page.inc:322 +#: page_manager/plugins/tasks/term_view.inc:133 +#: plugins/access/node_access.inc:36 +#, fuzzy +msgid "View" +msgstr "Anzeigen" + +#: page_manager/plugins/tasks/page.inc:592;607;647;668;703 +#: page_manager/plugins/tasks/term_view.inc:258;264;272;285;298 +#, fuzzy +msgid "page-summary-label" +msgstr "page-summary-label" + +#: page_manager/plugins/tasks/page.inc:593;608;634;648;669;704 +#: page_manager/plugins/tasks/term_view.inc:259;265;273;286;299 +#, fuzzy +msgid "page-summary-data" +msgstr "page-summary-data" + +#: page_manager/plugins/tasks/page.inc:594;609;635;649;670;705 +#: page_manager/plugins/tasks/term_view.inc:260;266;274;287;300 +#, fuzzy +msgid "page-summary-operation" +msgstr "page-summary-operation" + +#: page_manager/plugins/tasks/page.inc:607 +#, fuzzy +msgid "Status" +msgstr "Status" + +#: page_manager/plugins/tasks/page.inc:626 +#, fuzzy +msgid "This is your site home page." +msgstr "Dies ist die Startseite der Website." + +#: page_manager/plugins/tasks/page.inc:629 +#, fuzzy +msgid "This page is set to become your site home page." +msgstr "Diese Seite ist als Startseite der Website eingestellt." + +#: page_manager/plugins/tasks/page.inc:659 +#, fuzzy +msgid "Accessible only if @conditions." +msgstr "@type nur überprüfen wenn" + +#: page_manager/plugins/tasks/page.inc:662 +#: page_manager/plugins/tasks/term_view.inc:265 +#, fuzzy +msgid "This page is publicly accessible." +msgstr "Die Seite ist öffentlich erreichbar." + +#: page_manager/plugins/tasks/page.inc:674 +#, fuzzy +msgid "No menu entry." +msgstr "Kein Menüpunkt." + +#: page_manager/plugins/tasks/page.inc:675 +#, fuzzy +msgid "Normal menu entry." +msgstr "Normaler Menüpunkt." + +#: page_manager/plugins/tasks/page.inc:676 +#, fuzzy +msgid "Menu tab." +msgstr "Menü-Reiter." + +#: page_manager/plugins/tasks/page.inc:677 +#, fuzzy +msgid "Default menu tab." +msgstr "Standardmäßiger Reiter im Menü." + +#: page_manager/plugins/tasks/page.inc:683 +#, fuzzy +msgid "Title: %title." +msgstr "Titel: %title." + +#: page_manager/plugins/tasks/page.inc:686 +#, fuzzy +msgid "Parent title: %title." +msgstr "Übergeordneter Titel: %title." + +#: page_manager/plugins/tasks/page.inc:691 +#, fuzzy +msgid "Menu block: %title." +msgstr "Menüblock: %title." + +#: page_manager/plugins/tasks/poll.inc:17;18 +#, fuzzy +msgid "All polls" +msgstr "Frühere Umfragen" + +#: page_manager/plugins/tasks/poll.inc:19 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/poll.inc:56 +msgid "Page manager module is unable to enable poll because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/search.inc:91 +msgid "Page manager module is unable to enable search/@name/%menu_tail because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/search.inc:155 +#: plugins/content_types/search/search_form.inc:17 +#: plugins/content_types/search/search_result.inc:17 +#, fuzzy +msgid "Keywords" +msgstr "Schlüsselwörter" + +#: page_manager/plugins/tasks/search.inc:212 +#, fuzzy +msgid "Search @type" +msgstr "Suche Typ" + +#: page_manager/plugins/tasks/term_view.inc:23;24 +#, fuzzy +msgid "Taxonomy term template" +msgstr "Taxonomie-Begriff-Vorlage" + +#: page_manager/plugins/tasks/term_view.inc:25 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:51 +msgid "Update settings specific to the taxonomy term view." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:101 +msgid "Page manager module is unable to enable taxonomy/term/%term because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:161 +#, fuzzy +msgid "Term(s) being viewed" +msgstr "Kommentar wird angezeigt" + +#: page_manager/plugins/tasks/term_view.inc:161 +#, fuzzy +msgid "Term being viewed" +msgstr "Kommentar wird angezeigt" + +#: page_manager/plugins/tasks/term_view.inc:169 +#, fuzzy +msgid "Depth" +msgstr "Tiefe" + +#: page_manager/plugins/tasks/term_view.inc:224 +msgid "Allow multiple terms on taxonomy/term/%term" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:225 +#, fuzzy +msgid "Single term" +msgstr "Einzellner Begriff" + +#: page_manager/plugins/tasks/term_view.inc:225 +#, fuzzy +msgid "Multiple terms" +msgstr "Mehrere Begriffe" + +#: page_manager/plugins/tasks/term_view.inc:226 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:230 +#: plugins/arguments/terms.inc:54 +msgid "Inject hierarchy of first term into breadcrumb trail" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:233 +#: plugins/arguments/term.inc:93 +#: plugins/arguments/terms.inc:57 +#, fuzzy +msgid "If checked, taxonomy term parents will appear in the breadcrumb trail." +msgstr "Sobald aktiviert, werden übergeordnete Taxonomie-Begriffe in der Pfadnavigation erscheinen." + +#: page_manager/plugins/tasks/term_view.inc:278 +msgid "Multiple terms may be used, separated by , or +." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:281 +#, fuzzy +msgid "Only a single term may be used." +msgstr "Nur ein einzelner Begriff kann verwendet werden." + +#: page_manager/plugins/tasks/term_view.inc:285 +#, fuzzy +msgid "%term" +msgstr "%term" + +#: page_manager/plugins/tasks/term_view.inc:291 +#, fuzzy +msgid "Breadcrumb trail will contain taxonomy term hierarchy" +msgstr "Die Pfadnavigation wird die Taxonomie-Begriffs-Hierarchie enthalten" + +#: page_manager/plugins/tasks/term_view.inc:294 +#, fuzzy +msgid "Breadcrumb trail will not contain taxonomy term hiearchy." +msgstr "Die Pfadnavigation wird die Taxonomie-Begriffs-Hierarchie nicht enthalten." + +#: page_manager/plugins/tasks/term_view.inc:298 +#: plugins/content_types/page/page_breadcrumb.inc:15 +#, fuzzy +msgid "Breadcrumb" +msgstr "Pfadnavigation" + +#: page_manager/plugins/tasks/user_view.inc:12;13 +#, fuzzy +msgid "User profile template" +msgstr "Benutzer-Profil-Vorlage" + +#: page_manager/plugins/tasks/user_view.inc:14 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/user_view.inc:56 +msgid "Page manager module is unable to enable user/%user because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:42 +#, fuzzy +msgid "Locked" +msgstr "Gesperrt" + +#: page_manager/theme/page_manager.theme.inc:42 +#, fuzzy +msgid "This page is being edited by another user and you cannot make changes to it." +msgstr "An dieser Seite können derzeit keine Änderungen vorgenommen werden, da diese Seite von einem anderen Benutzer bearbeitet wird." + +#: page_manager/theme/page_manager.theme.inc:45 +#, fuzzy +msgid "New" +msgstr "Neu" + +#: page_manager/theme/page_manager.theme.inc:45 +#, fuzzy +msgid "This page is newly created and has not yet been saved to the database. It will not be available until you save it." +msgstr "Diese Seite wurde neu erstellt und noch nicht in der Datenbank gespeichert. Sie ist nicht verfügbar, solange sie nicht gespeichert wurde." + +#: page_manager/theme/page_manager.theme.inc:48 +#, fuzzy +msgid "Changed" +msgstr "Geändert" + +#: page_manager/theme/page_manager.theme.inc:48 +#, fuzzy +msgid "This page has been modified, but these modifications are not yet live. While modifying this page, it is locked from modification by other users." +msgstr "Diese Seite wurde geändert, aber die Änderungen sind noch nicht Live. Während der Änderung dieser Seite, wird diese für die Änderung durch andere Benutzer gesperrt." + +#: page_manager/theme/page_manager.theme.inc:98 +#, fuzzy +msgid "No task handlers are defined for this task." +msgstr "Dieser Arbeitsablauf hat keine Status." + +#: page_manager/theme/page_manager.theme.inc:102 +#, fuzzy +msgid "Variant" +msgstr "Variante" + +#: page_manager/theme/page_manager.theme.inc:124 +#, fuzzy +msgid "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>." +msgstr "Diese Ansicht wird gerade vom Benutzer !user bearbeitet und ist deshalb für die Bearbeitung durch andere gesperrt. Diese Sperre ist !age alt. Hier klicken um <a href=\"!break\">die Sperre aufzuheben</a>." + +#: plugins/access/compare_users.inc:14 +msgid "User: compare" +msgstr "Benutzer: Vergleich" + +#: plugins/access/compare_users.inc:15 +msgid "Compare two users (logged-in user and user being viewed, for example)" +msgstr "" + +#: plugins/access/compare_users.inc:23 +msgid "First User" +msgstr "Erster Benutzer" + +#: plugins/access/compare_users.inc:24 +msgid "Second User" +msgstr "Zweiter Benutzer" + +#: plugins/access/compare_users.inc:36 +msgid "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." +msgstr "" + +#: plugins/access/compare_users.inc:41 +msgid "Grant access if user contexts are" +msgstr "" + +#: plugins/access/compare_users.inc:42 +msgid "Equal" +msgstr "Gleich" + +#: plugins/access/compare_users.inc:42 +msgid "Not equal" +msgstr "Nicht gleich" + +#: plugins/access/compare_users.inc:70 +msgid "@id1 @comp @id2" +msgstr "@id1 @comp @id2" + +#: plugins/access/node_access.inc:14 +msgid "Node: accessible" +msgstr "Beitrag: Erreichbar" + +#: plugins/access/node_access.inc:15 +msgid "Control access with built in Drupal node access test." +msgstr "" + +#: plugins/access/node_access.inc:23 +#: plugins/access/node_language.inc:22 +#: plugins/access/node_type.inc:21 +#: plugins/content_types/node/node.inc:15 +#: plugins/content_types/node_context/node_attachments.inc:13;14 +#: plugins/content_types/node_context/node_author.inc:13;14 +#: plugins/content_types/node_context/node_body.inc:13;14 +#: plugins/content_types/node_context/node_book_nav.inc:14;15 +#: plugins/content_types/node_context/node_comment_form.inc:14;15 +#: plugins/content_types/node_context/node_comments.inc:15;16 +#: plugins/content_types/node_context/node_content.inc:13;14 +#: plugins/content_types/node_context/node_created.inc:13;14 +#: plugins/content_types/node_context/node_links.inc:14;15 +#: plugins/content_types/node_context/node_title.inc:13;14 +#: plugins/content_types/node_context/node_type_desc.inc:13;14 +#: plugins/content_types/node_context/node_updated.inc:13;14 +#: plugins/contexts/node.inc:16 +#: plugins/relationships/book_parent.inc:17 +#: plugins/relationships/term_from_node.inc:17 +#: plugins/relationships/user_from_node.inc:17 +#, fuzzy +msgid "Node" +msgstr "Node" + +#: plugins/access/node_access.inc:39 +#, fuzzy +msgid "Create nodes of the same type" +msgstr "!item_type erstellt" + +#: plugins/access/node_access.inc:41 +msgid "Using built in Drupal node access rules, determine if the user can perform the selected operation on the node." +msgstr "" + +#: plugins/access/node_access.inc:78 +msgid "@user can view @node." +msgstr "@user kann @node sehen." + +#: plugins/access/node_access.inc:81 +msgid "@user can edit @node." +msgstr "@user kann @node bearbeiten." + +#: plugins/access/node_access.inc:84 +msgid "@user can delete @node." +msgstr "@user kann @node löschen." + +#: plugins/access/node_access.inc:87 +msgid "@user can create nodes of the same type as @node." +msgstr "@user kann Beiträge von dem gleichen Typ wie @node erstellen." + +#: plugins/access/node_language.inc:15 +msgid "Node: language" +msgstr "Beitrag: Sprache" + +#: plugins/access/node_language.inc:16 +msgid "Control access by node language." +msgstr "Zugriff mit Beitragssprache kontrollieren." + +#: plugins/access/node_language.inc:32;94 +msgid "Current site language" +msgstr "Aktuelle Website-Sprache" + +#: plugins/access/node_language.inc:33;95 +#: plugins/access/site_language.inc:31;69 +msgid "Default site language" +msgstr "Standardmäßige Website-Sprache" + +#: plugins/access/node_language.inc:34;96 +msgid "No language" +msgstr "Keine Sprache" + +#: plugins/access/node_language.inc:38 +#: plugins/access/site_language.inc:35 +msgid "Language" +msgstr "Sprache" + +#: plugins/access/node_language.inc:41 +msgid "Pass only if the node is in one of the selected languages." +msgstr "" + +#: plugins/access/node_language.inc:110 +#, fuzzy +msgid "@identifier is in any language" +msgstr "@identifier ist ein beliebiger Beitragstyp" + +#: plugins/access/node_language.inc:113 +#, fuzzy +msgid "@identifier language is \"@languages\"" +msgid_plural "@identifier language is one of \"@languages\"" +msgstr[0] "Der Sprachcode. Verweist auf {languages}.language." +msgstr[1] "" + +#: plugins/access/node_type.inc:14 +msgid "Node: type" +msgstr "Beitrag: Typ" + +# English: node_type bug +#: plugins/access/node_type.inc:15 +msgid "Control access by node_type." +msgstr "Zugriff mit Beitragstyp kontrollieren" + +#: plugins/access/node_type.inc:36 +#: plugins/contexts/node.inc:170 +#: plugins/contexts/node_add_form.inc:21;100 +#, fuzzy +msgid "Node type" +msgstr "Beitragstyp" + +#: plugins/access/node_type.inc:39 +msgid "Only the checked node types will be valid." +msgstr "Nur die aktivierten Beitragstypen sind gültig." + +#: plugins/access/node_type.inc:96 +msgid "@identifier is any node type" +msgstr "@identifier ist ein beliebiger Beitragstyp" + +#: plugins/access/node_type.inc:99 +#, fuzzy +msgid "@identifier is type \"@types\"" +msgid_plural "@identifier type is one of \"@types\"" +msgstr[0] "@identifier ist ein beliebiger Beitragstyp" +msgstr[1] "" + +#: plugins/access/perm.inc:14 +msgid "User: permission" +msgstr "Benutzer: Berechtigung" + +#: plugins/access/perm.inc:15 +msgid "Control access by permission string." +msgstr "Zugriff mit Zugriffsberechtigung kontrollieren" + +#: plugins/access/perm.inc:41 +msgid "Permission" +msgstr "Berechtigung" + +#: plugins/access/perm.inc:43 +msgid "Only users with the selected permission flag will be able to access this." +msgstr "" + +#: plugins/access/perm.inc:65 +#, fuzzy +msgid "Error, unset permission" +msgstr "keine Berechtigungen vergeben" + +#: plugins/access/perm.inc:68 +msgid "@identifier has \"@perm\"" +msgstr "@identifier enthält „@perm“" + +#: plugins/access/php.inc:14;41 +msgid "PHP Code" +msgstr "PHP-Code" + +#: plugins/access/php.inc:15 +msgid "Control access through arbitrary PHP code." +msgstr "" + +#: plugins/access/php.inc:35 +msgid "Administrative desc" +msgstr "Administrative-Beschreibung" + +#: plugins/access/php.inc:37 +#, fuzzy +msgid "A description for this test for administrative purposes." +msgstr "Einen Namen eingeben, um diese(s) !type auf administrativen Seiten zu identifizieren." + +#: plugins/access/php.inc:43 +msgid "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." +msgstr "" + +#: plugins/access/php.inc:48 +msgid "You do not have sufficient permissions to edit PHP code." +msgstr "" + +#: plugins/access/role.inc:14 +msgid "User: role" +msgstr "Benutzer: Rolle" + +#: plugins/access/role.inc:78 +#, fuzzy +msgid "@identifier has role \"@roles\"" +msgid_plural "@identifier has one of \"@roles\"" +msgstr[0] "Die Rolle wurde hinzugefügt." +msgstr[1] "" + +#: plugins/access/site_language.inc:15 +msgid "User: language" +msgstr "Benutzer: Sprache" + +#: plugins/access/site_language.inc:16 +msgid "Control access by the language the user or site currently uses." +msgstr "" + +#: plugins/access/site_language.inc:38 +msgid "Pass only if the current site language is one of the selected languages." +msgstr "" + +#: plugins/access/site_language.inc:83 +#, fuzzy +msgid "Site language is any language" +msgstr "Website-Sprache ist jede Sprache" + +#: plugins/access/site_language.inc:86 +#, fuzzy +msgid "Site language is \"@languages\"" +msgid_plural "Site language is one of \"@languages\"" +msgstr[0] "Website-Sprache ist jede Sprache" +msgstr[1] "" + +#: plugins/access/term.inc:14 +#, fuzzy +msgid "Taxonomy: term" +msgstr "Taxonomie-Begriff" + +#: plugins/access/term.inc:15 +#, fuzzy +msgid "Control access by a specific term." +msgstr "Zugriff mit Begriffsvokabular kontrollieren" + +#: plugins/access/term.inc:22 +#: plugins/access/term_vocabulary.inc:21 +#: plugins/content_types/term_context/term_description.inc:13 +#: plugins/content_types/term_context/term_list.inc:13 +#: plugins/relationships/term_parent.inc:17 +#, fuzzy +msgid "Term" +msgstr "Begriff" + +#: plugins/access/term.inc:41 +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:14;15 +#: plugins/contexts/term.inc:67 +#: plugins/contexts/vocabulary.inc:57 +#: plugins/relationships/term_from_node.inc:53 +#, fuzzy +msgid "Vocabulary" +msgstr "Vokabular" + +#: plugins/access/term.inc:44 +#: plugins/contexts/term.inc:70 +#: plugins/contexts/vocabulary.inc:63 +msgid "Select the vocabulary for this form." +msgstr "Das Vokabular für dieses Formular auswählen." + +#: plugins/access/term.inc:63 +#, fuzzy +msgid "Terms" +msgstr "Begriffe" + +#: plugins/access/term.inc:64 +#, fuzzy +msgid "Select a term or terms from @vocabulary." +msgstr "Einen Begriff von @vocabulary auswählen." + +#: plugins/access/term.inc:148 +#, fuzzy +msgid "@term can be the term \"@terms\"" +msgid_plural "@term can be one of these terms: @terms" +msgstr[0] "Das Programm '%s' wurde nicht gefunden!" +msgstr[1] "" + +#: plugins/access/term_vocabulary.inc:14 +msgid "Taxonomy: vocabulary" +msgstr "Taxonomie: Vokabular" + +#: plugins/access/term_vocabulary.inc:15 +msgid "Control access by term vocabulary." +msgstr "Zugriff mit Begriffsvokabular kontrollieren" + +#: plugins/access/term_vocabulary.inc:37 +msgid "Vocabularies" +msgstr "Vokabulare" + +#: plugins/access/term_vocabulary.inc:39 +msgid "Only terms in the checked vocabularies will be valid." +msgstr "" + +#: plugins/access/term_vocabulary.inc:83 +msgid "@identifier is any vocabulary" +msgstr "@identifier ist ein beliebiges Vokabular." + +#: plugins/access/term_vocabulary.inc:86 +#, fuzzy +msgid "@identifier vocabulary is \"@vids\"" +msgid_plural "@identifier vocabulary is one of \"@vids\"" +msgstr[0] "@identifier ist ein beliebiges Vokabular." +msgstr[1] "" + +#: plugins/arguments/nid.inc:15 +#, fuzzy +msgid "Node: ID" +msgstr "Node: ID" + +#: plugins/arguments/nid.inc:17 +#, fuzzy +msgid "Creates a node context from a node ID argument." +msgstr "Erstellt einen Beitragskontext von einem Argument (nid)" + +#: plugins/arguments/nid.inc:21 +#: plugins/arguments/node_edit.inc:22 +#, fuzzy +msgid "Enter the node ID of a node for this argument" +msgstr "Bestimmt den Inhaltstyp für dieses Formular." + +#: plugins/arguments/node_add.inc:15 +#, fuzzy +msgid "Node add form: node type" +msgstr "Beitragserstellungsformular @id @type" + +#: plugins/arguments/node_add.inc:18 +#, fuzzy +msgid "Creates a node add form context from a node type argument." +msgstr "Erstellt ein Benutzer-Objekt durch ein Argument." + +#: plugins/arguments/node_edit.inc:15 +#, fuzzy +msgid "Node edit form: node ID" +msgstr "Beitragsbearbeitungsformular @id Standard" + +#: plugins/arguments/node_edit.inc:18 +#, fuzzy +msgid "Creates a node edit form context from a node ID argument." +msgstr "Erstellt ein Benutzer-Objekt durch ein Argument." + +#: plugins/arguments/string.inc:15 +#: plugins/contexts/string.inc:15 +#, fuzzy +msgid "String" +msgstr "Zeichenkette" + +#: plugins/arguments/string.inc:18 +msgid "A string is a minimal context that simply holds a string that can be used for some other purpose." +msgstr "" + +#: plugins/arguments/string.inc:23 +msgid "Enter a value for this argument" +msgstr "Einen Wert für dieses Argument eingeben" + +#: plugins/arguments/string.inc:49 +msgid "Get all arguments after this one" +msgstr "" + +#: plugins/arguments/string.inc:52 +msgid "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\"." +msgstr "" + +#: plugins/arguments/term.inc:15 +#, fuzzy +msgid "Taxonomy term: ID" +msgstr "Taxonomie: Begriff ID" + +#: plugins/arguments/term.inc:18 +msgid "Creates a single taxonomy term from a taxonomy ID or taxonomy term name." +msgstr "" + +#: plugins/arguments/term.inc:81 +msgid "Argument type" +msgstr "Argumenttyp" + +#: plugins/arguments/term.inc:83 +#: plugins/contexts/term.inc:24 +#, fuzzy +msgid "Term ID" +msgstr "Begriff ID" + +#: plugins/arguments/term.inc:83 +#: plugins/contexts/term.inc:25 +#, fuzzy +msgid "Term name" +msgstr "Begriff" + +#: plugins/arguments/term.inc:90 +#, fuzzy +msgid "Inject hierarchy into breadcrumb trail" +msgstr "Die Pfadnavigation wird die Taxonomie-Begriffs-Hierarchie enthalten" + +#: plugins/arguments/term.inc:106 +msgid "Enter a taxonomy term ID." +msgstr "Eine Taxonomie-Begriffs-ID eingeben." + +#: plugins/arguments/term.inc:111 +msgid "Enter a taxonomy term name." +msgstr "Einen Taxonomie-Begriff eingeben." + +#: plugins/arguments/terms.inc:15 +#, fuzzy +msgid "Taxonomy term (multiple): ID" +msgstr "ID des obersten Taxonomiebegriffs" + +#: plugins/arguments/terms.inc:18 +msgid "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." +msgstr "" + +#: plugins/arguments/terms.inc:24 +msgid "Enter a term ID or a list of term IDs separated by a + or a ," +msgstr "" + +#: plugins/arguments/uid.inc:15 +#, fuzzy +msgid "User: ID" +msgstr "Die ID des Benutzers" + +#: plugins/arguments/uid.inc:18 +#, fuzzy +msgid "Creates a user context from a user ID argument." +msgstr "Erstellt ein Benutzer-Objekt durch ein Argument." + +#: plugins/arguments/uid.inc:22 +#, fuzzy +msgid "Enter the user ID of a user for this argument" +msgstr "Den Titel oder die Beitrag-ID eines Beitrages eingeben" + +#: plugins/arguments/user_name.inc:15 +#, fuzzy +msgid "User: name" +msgstr "Der Name des Benutzers" + +#: plugins/arguments/user_name.inc:18 +#, fuzzy +msgid "Creates a user context from a user name." +msgstr "Erstellt ein Benutzer-Objekt durch ein Argument." + +#: plugins/arguments/user_name.inc:22 +#, fuzzy +msgid "Enter the username of a user for this argument" +msgstr "Den Titel oder die Beitrag-ID eines Beitrages eingeben" + +#: plugins/arguments/vid.inc:15 +#, fuzzy +msgid "Vocabulary: ID" +msgstr "Vokabular-ID" + +#: plugins/arguments/vid.inc:18 +#, fuzzy +msgid "Creates a vocabulary context from a vocabulary ID argument." +msgstr "Lädt ein Vokabular-Objekt durch ein Argument." + +#: plugins/arguments/vid.inc:22 +#, fuzzy +msgid "Enter the vocabulary ID for this argument" +msgstr "Das Vokabular für dieses Formular auswählen." + +#: plugins/content_types/block/block.inc:21 +msgid "Block" +msgstr "Block" + +#: plugins/content_types/block/block.inc:91 +msgid "Configure block" +msgstr "Block konfigurieren" + +#: plugins/content_types/block/block.inc:92 +msgid "Configure this block's 'block settings' in administer >> site building >> blocks" +msgstr "Die Einstellungen dieses Blocks unter Verwalten >> Strukturierung >> Blöcke konfigurieren" + +#: plugins/content_types/block/block.inc:229 +msgid "Deleted/missing block @module-@delta" +msgstr "Entfernter/fehlender Block @module-@delta" + +#: plugins/content_types/block/block.inc:267;271;346 +msgid "Miscellaneous" +msgstr "Diverses" + +#: plugins/content_types/block/block.inc:279;359 +msgid "Menus" +msgstr "Menüs" + +#: plugins/content_types/block/block.inc:286;316;321;326;350;383 +msgid "Activity" +msgstr "Aktivität" + +#: plugins/content_types/block/block.inc:331;336;354;378;388 +#: plugins/content_types/contact/contact.inc:17 +#: plugins/content_types/search/search_form.inc:18 +#: plugins/content_types/search/search_result.inc:18 +#: views_content/views_content.module:56 +#, fuzzy +msgid "Widgets" +msgstr "Steuerelement" + +#: plugins/content_types/block/block.inc:341 +msgid "Feeds" +msgstr "Newsfeeds" + +#: plugins/content_types/contact/contact.inc:14;62 +#, fuzzy +msgid "Contact form" +msgstr "Kontaktformular" + +#: plugins/content_types/contact/contact.inc:16 +msgid "The site contact form that allows users to send a message to site administrators." +msgstr "" + +#: plugins/content_types/contact/contact.inc:32 +#, fuzzy +msgid "Contact" +msgstr "Kontaktieren" + +#: plugins/content_types/contact/user_contact.inc:14;68 +#, fuzzy +msgid "User contact form" +msgstr "Pfadeinstellungen der Benutzer-Kontaktformulare" + +#: plugins/content_types/contact/user_contact.inc:16 +msgid "The site contact form that allows users to contact other users." +msgstr "" + +#: plugins/content_types/contact/user_contact.inc:38 +#, fuzzy +msgid "Contact @name" +msgstr "Name des Ereignisses (z.B. Kontakt)." + +#: plugins/content_types/custom/custom.inc:20 +msgid "New custom content" +msgstr "Neuer benutzerdefinierter Inhalt" + +#: plugins/content_types/custom/custom.inc:22 +msgid "Create a completely custom piece of HTML content." +msgstr "Vollständig individuellen HTML-Inhalt erstellen." + +#: plugins/content_types/custom/custom.inc:61 +#, fuzzy +msgid "Custom: @title" +msgstr "Benutzerdefinierte Titel" + +#: plugins/content_types/custom/custom.inc:107 +msgid "This title will be used administratively to identify this pane. If blank, the regular title will be used." +msgstr "" + +#: plugins/content_types/custom/custom.inc:117 +msgid "Body" +msgstr "Textkörper" + +#: plugins/content_types/custom/custom.inc:127 +msgid "Use context keywords" +msgstr "Kontextschlüsselwörter verwenden" + +#: plugins/content_types/custom/custom.inc:128 +msgid "If checked, context keywords will be substituted in this content." +msgstr "" + +#: plugins/content_types/custom/custom.inc:132 +msgid "Substitutions" +msgstr "Ersetzungen" + +#: plugins/content_types/custom/custom.inc:143 +msgid "@identifier: @title" +msgstr "@identifier: @title" + +#: plugins/content_types/custom/custom.inc:147 +msgid "Value" +msgstr "Wert" + +#: plugins/content_types/form/form.inc:13 +msgid "General form" +msgstr "Allgemeines Formular" + +#: plugins/content_types/form/form.inc:15 +msgid "Everything in the form that is not displayed by other content." +msgstr "" + +#: plugins/content_types/form/form.inc:16;17;43 +#: plugins/content_types/node_form/node_form_attachments.inc:14;15 +#: plugins/content_types/node_form/node_form_author.inc:13;14 +#: plugins/content_types/node_form/node_form_book.inc:14;15 +#: plugins/content_types/node_form/node_form_buttons.inc:13;14 +#: plugins/content_types/node_form/node_form_comment.inc:14;15 +#: plugins/content_types/node_form/node_form_input_format.inc:13;14 +#: plugins/content_types/node_form/node_form_log.inc:13;14 +#: plugins/content_types/node_form/node_form_menu.inc:14;15 +#: plugins/content_types/node_form/node_form_path.inc:14;15 +#: plugins/content_types/node_form/node_form_publishing.inc:19;20 +#: plugins/content_types/node_form/node_form_taxonomy.inc:14;15 +#, fuzzy +msgid "Form" +msgstr "Formular" + +#: plugins/content_types/form/form.inc:44 +msgid "Form goes here." +msgstr "Formular wird hier angezeigt." + +#: plugins/content_types/form/form.inc:52 +msgid "\"@s\" base form" +msgstr "„@s“ Basisformular" + +#: plugins/content_types/node/node.inc:24 +#, fuzzy +msgid "Existing node" +msgstr "Vollständiger Beitrag" + +#: plugins/content_types/node/node.inc:26 +msgid "Add a node from your site as content." +msgstr "Beitrag von dieser Webseite als Inhalt hinzufügen." + +#: plugins/content_types/node/node.inc:70 +#: plugins/content_types/node_context/node_content.inc:61 +#, fuzzy +msgid "Edit node" +msgstr "Beitrag bearbeiten" + +#: plugins/content_types/node/node.inc:71 +#: plugins/content_types/node_context/node_content.inc:62 +#, fuzzy +msgid "Edit this node" +msgstr "Diesen Beitrag bearbeiten" + +#: plugins/content_types/node/node.inc:106 +#: plugins/content_types/node_context/node_content.inc:130 +#, fuzzy +msgid "Leave node title" +msgstr "Beitragstitel beibehalten" + +#: plugins/content_types/node/node.inc:107 +#: plugins/content_types/node_context/node_content.inc:131 +#, fuzzy +msgid "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." +msgstr "Erweitert: Falls aktiviert, bleibt der Beitragstitel unberührt. Dies kann zur doppelten Darstellung in der Ausgabe führen, sofern die Theme dies nicht berücksichtigt." + +#: plugins/content_types/node/node.inc:113 +#: plugins/contexts/node.inc:81 +#: plugins/contexts/node_edit_form.inc:99 +#, fuzzy +msgid "Enter the title or NID of a node" +msgstr "Den Titel oder die Beitrag-ID eines Beitrages eingeben" + +#: plugins/content_types/node/node.inc:114 +msgid "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." +msgstr "Um eine NID aus der URL zu verwenden, %0, %1, ..., %N für die URL-Argumente verwenden. Oder @0, @1, @2, ..., @N für die Panel-Argumente verwenden." + +#: plugins/content_types/node/node.inc:130 +#: plugins/content_types/node_context/node_content.inc:141 +#, fuzzy +msgid "Show only node teaser" +msgstr "Nur Einträge anzeigen mit" + +#: plugins/content_types/node/node.inc:138 +#: plugins/content_types/node_context/node_content.inc:154 +msgid "Include node links for \"add comment\", \"read more\" etc." +msgstr "" + +#: plugins/content_types/node/node.inc:144 +#: plugins/content_types/node_context/node_content.inc:167 +#, fuzzy +msgid "Template identifier" +msgstr "Bezeichner erwartet." + +#: plugins/content_types/node/node.inc:145 +#: plugins/content_types/node_context/node_content.inc:168 +msgid "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." +msgstr "" + +#: plugins/content_types/node/node.inc:179 +msgid "Invalid node" +msgstr "Ungültiger Beitrag" + +#: plugins/content_types/node/node.inc:197 +msgid "Node loaded from @var" +msgstr "Beitrag wurde von @var geladen" + +#: plugins/content_types/node/node.inc:205 +msgid "Deleted/missing node @nid" +msgstr "Entfernter/fehlender Beitrag @nid" + +#: plugins/content_types/node_context/node_attachments.inc:10;23 +msgid "Attached files" +msgstr "Angehängte Dateien" + +#: plugins/content_types/node_context/node_attachments.inc:12 +msgid "A list of files attached to the node." +msgstr "Eine Liste der an einem Beitrag angehängten Dateien." + +#: plugins/content_types/node_context/node_attachments.inc:31 +msgid "Attached files go here." +msgstr "Angehängte Dateien erscheinen hier." + +#: plugins/content_types/node_context/node_attachments.inc:39 +msgid "\"@s\" attachments" +msgstr "„@s“ Dateianhänge" + +#: plugins/content_types/node_context/node_author.inc:10 +#: plugins/relationships/user_from_node.inc:14 +#, fuzzy +msgid "Node author" +msgstr "Beitragsauthor" + +#: plugins/content_types/node_context/node_author.inc:12 +msgid "The author of the referenced node." +msgstr "Der Autor des referenzierten Beitrages." + +#: plugins/content_types/node_context/node_author.inc:35 +msgid "Author" +msgstr "Autor" + +#: plugins/content_types/node_context/node_author.inc:49 +msgid "Link to author profile" +msgstr "Mit dem Profil des Autors verlinken" + +#: plugins/content_types/node_context/node_author.inc:52 +msgid "Check here to link to the node author profile." +msgstr "Aktivieren, um zum Autor des Beitrages zu verlinken." + +#: plugins/content_types/node_context/node_author.inc:70 +msgid "\"@s\" author" +msgstr "„@s“ Autor" + +#: plugins/content_types/node_context/node_body.inc:10 +msgid "Node body" +msgstr "Beitragstext" + +#: plugins/content_types/node_context/node_body.inc:12 +msgid "The body of the referenced node." +msgstr "Der Textkörper des referenzierten Beitrages." + +#: plugins/content_types/node_context/node_body.inc:58 +msgid "\"@s\" body" +msgstr "„@s“ Textkörper" + +#: plugins/content_types/node_context/node_book_nav.inc:11;25 +msgid "Book navigation" +msgstr "Buch-Navigation" + +#: plugins/content_types/node_context/node_book_nav.inc:13 +msgid "The navigation menu the book the node belongs to." +msgstr "" + +#: plugins/content_types/node_context/node_book_nav.inc:31 +msgid "Book navigation goes here." +msgstr "Buch-Navigation wird hier angezeigt." + +#: plugins/content_types/node_context/node_book_nav.inc:39 +msgid "\"@s\" book navigation" +msgstr "„@s“ Buch-Navigation" + +#: plugins/content_types/node_context/node_comment_form.inc:11 +msgid "Comment form" +msgstr "Kommentarformular" + +#: plugins/content_types/node_context/node_comment_form.inc:13 +msgid "A form to add a new comment." +msgstr "Ein Formular zum Hinzufügen eines neuen Kommentars." + +#: plugins/content_types/node_context/node_comment_form.inc:26 +msgid "Add comment" +msgstr "Kommentar hinzufügen" + +#: plugins/content_types/node_context/node_comment_form.inc:29 +msgid "Comment form here." +msgstr "Kommentarformular erscheint hier." + +#: plugins/content_types/node_context/node_comment_form.inc:47 +msgid "\"@s\" comment form" +msgstr "„@s“ Kommentarformular" + +#: plugins/content_types/node_context/node_comments.inc:12 +msgid "Node comments" +msgstr "Beitragskommentare" + +#: plugins/content_types/node_context/node_comments.inc:14 +msgid "The comments of the referenced node." +msgstr "Kommentare des referenzierten Beitrages." + +#: plugins/content_types/node_context/node_comments.inc:32 +msgid "Comments" +msgstr "Kommentare" + +#: plugins/content_types/node_context/node_comments.inc:34 +msgid "Node comments go here." +msgstr "Beitragskommentare erscheinen hier." + +#: plugins/content_types/node_context/node_comments.inc:49 +msgid "Mode" +msgstr "Modus" + +#: plugins/content_types/node_context/node_comments.inc:56 +msgid "Sort" +msgstr "Reihenfolge" + +#: plugins/content_types/node_context/node_comments.inc:62 +msgid "!a comments per page" +msgstr "!a Kommentare pro Seite" + +#: plugins/content_types/node_context/node_comments.inc:65 +msgid "Pager" +msgstr "Seitennavigation" + +#: plugins/content_types/node_context/node_comments.inc:80 +msgid "\"@s\" comments" +msgstr "„@s“ Kommentare" + +#: plugins/content_types/node_context/node_content.inc:10 +msgid "Node content" +msgstr "Beitragsinhalt" + +#: plugins/content_types/node_context/node_content.inc:12 +msgid "The content of the referenced node." +msgstr "Der Inhalt des referenzierten Beitrages." + +#: plugins/content_types/node_context/node_content.inc:44 +#: plugins/content_types/node_context/node_links.inc:41 +msgid "Node title." +msgstr "Titel des Beitrages." + +#: plugins/content_types/node_context/node_content.inc:45 +msgid "Node content goes here." +msgstr "Beitragsinhalt wird hier angezeigt." + +#: plugins/content_types/node_context/node_content.inc:135 +#: plugins/content_types/node_context/node_links.inc:78 +msgid "Link title to node" +msgstr "Den Titel mit dem Beitrag verlinken" + +#: plugins/content_types/node_context/node_content.inc:138 +#: plugins/content_types/node_context/node_links.inc:81 +#: plugins/content_types/node_context/node_title.inc:55 +msgid "Check here to make the title link to the node." +msgstr "Aktivieren, um den Titel mit dem Beitrag zu verlinken." + +#: plugins/content_types/node_context/node_content.inc:148 +msgid "Treat this as the primary node page" +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:149 +msgid "This can affect title rendering and breadcrumbs from some node types." +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:160 +msgid "No extras" +msgstr "Keine Zusätze" + +#: plugins/content_types/node_context/node_content.inc:161 +msgid "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." +msgstr "Aktivieren, um Zusätze von anderen Modulen zu deaktivieren, wie z.B. Dateianhänge und CCK-Felder; dies sollte nur den Anrisstext oder vollen Inhaltstext darstellen." + +#: plugins/content_types/node_context/node_content.inc:182 +msgid "\"@s\" content" +msgstr "„@s“ Inhalt" + +#: plugins/content_types/node_context/node_created.inc:10 +msgid "Node created date" +msgstr "Beitragserstellungsdatum" + +#: plugins/content_types/node_context/node_created.inc:12 +msgid "The date the referenced node was created." +msgstr "Der Zeitpunkt zu dem der referenzierte Beitrag erstellt wurde." + +#: plugins/content_types/node_context/node_created.inc:35 +msgid "Created date" +msgstr "Erstellungsdatum" + +#: plugins/content_types/node_context/node_created.inc:50 +#: plugins/content_types/node_context/node_updated.inc:50 +msgid "Date format" +msgstr "Datumsformat" + +#: plugins/content_types/node_context/node_created.inc:75 +msgid "\"@s\" created date" +msgstr "„@s“ erstellt" + +#: plugins/content_types/node_context/node_links.inc:11 +msgid "Node links" +msgstr "Beitraglinks" + +#: plugins/content_types/node_context/node_links.inc:13 +msgid "Node links of the referenced node." +msgstr "Beitrag verlinkt zum referenzierten Beitrag." + +#: plugins/content_types/node_context/node_links.inc:42 +msgid "Node links go here." +msgstr "Beitraglinks erscheinen hier." + +#: plugins/content_types/node_context/node_links.inc:84 +msgid "Teaser mode" +msgstr "Anrisstext-Modus" + +#: plugins/content_types/node_context/node_links.inc:87 +msgid "Check here to show links in teaser mode." +msgstr "Aktivieren, um Links im Anrisstext anzuzeigen." + +#: plugins/content_types/node_context/node_links.inc:94 +msgid "Whatever is placed here will appear in $node->panel_identifier to help theme node links displayed on the panel" +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:108 +msgid "\"@s\" links" +msgstr "„@s“ Links" + +#: plugins/content_types/node_context/node_title.inc:10 +#: plugins/contexts/node.inc:168 +#, fuzzy +msgid "Node title" +msgstr "Beitragtitel" + +#: plugins/content_types/node_context/node_title.inc:12 +msgid "The title of the referenced node." +msgstr "Der Titel des referenzierten Beitrages." + +#: plugins/content_types/node_context/node_title.inc:52 +msgid "Link to node" +msgstr "Mit dem Beitrag verlinken" + +#: plugins/content_types/node_context/node_title.inc:73 +msgid "\"@s\" title" +msgstr "„@s“ Titel" + +#: plugins/content_types/node_context/node_type_desc.inc:10;34 +msgid "Node type description" +msgstr "Beitragstyp-Beschreibung" + +#: plugins/content_types/node_context/node_type_desc.inc:12 +msgid "Node type description." +msgstr "Beschreibung des Inhaltstyps." + +#: plugins/content_types/node_context/node_type_desc.inc:35 +msgid "Node type description goes here." +msgstr "Inhaltstyp-Beschreibung wird hier angezeigt." + +#: plugins/content_types/node_context/node_type_desc.inc:43 +msgid "\"@s\" type description" +msgstr "„@s“ Typ-Beschreibung" + +#: plugins/content_types/node_context/node_updated.inc:10 +msgid "Node last updated date" +msgstr "Letzter Aktualisierungszeitpunkt des Beitrages" + +#: plugins/content_types/node_context/node_updated.inc:12 +msgid "The date the referenced node was last updated." +msgstr "Der Zeitpunkt zu dem der referenzierte Beitrag zuletzt aktualisiert wurde." + +#: plugins/content_types/node_context/node_updated.inc:35 +msgid "Last updated date" +msgstr "Letzter Aktualisierungszeitpunkt" + +#: plugins/content_types/node_context/node_updated.inc:75 +#, fuzzy +msgid "\"@s\" last updated date" +msgstr "Letzter Aktualisierungszeitpunkt" + +#: plugins/content_types/node_form/node_form_attachments.inc:12 +msgid "Node form file attachments" +msgstr "Beitragsformular-Dateianhänge" + +#: plugins/content_types/node_form/node_form_attachments.inc:13 +msgid "File attachments on the Node form." +msgstr "Dateianhänge im Beitragsformular." + +#: plugins/content_types/node_form/node_form_attachments.inc:22 +#: plugins/content_types/node_form/node_form_author.inc:20 +#: plugins/content_types/node_form/node_form_book.inc:22 +#: plugins/content_types/node_form/node_form_buttons.inc:20 +#: plugins/content_types/node_form/node_form_comment.inc:22 +#: plugins/content_types/node_form/node_form_input_format.inc:20 +#: plugins/content_types/node_form/node_form_log.inc:20 +#: plugins/content_types/node_form/node_form_menu.inc:22 +#: plugins/content_types/node_form/node_form_path.inc:22 +#: plugins/content_types/node_form/node_form_publishing.inc:28 +#: plugins/content_types/node_form/node_form_taxonomy.inc:22 +msgid "node_form" +msgstr "node_form" + +#: plugins/content_types/node_form/node_form_attachments.inc:24 +msgid "Attach files" +msgstr "Dateien anhängen" + +#: plugins/content_types/node_form/node_form_attachments.inc:35 +msgid "Attach files." +msgstr "Dateien anhängen." + +#: plugins/content_types/node_form/node_form_attachments.inc:41 +msgid "\"@s\" node form attach files" +msgstr "„@s“ Beitragsformular-Dateianhänge" + +#: plugins/content_types/node_form/node_form_author.inc:11 +msgid "Node form author information" +msgstr "Beitragsautor-Formular" + +#: plugins/content_types/node_form/node_form_author.inc:12 +msgid "Author information on the Node form." +msgstr "Autor-Informationen im Beitragsformular." + +#: plugins/content_types/node_form/node_form_author.inc:22 +msgid "Authoring information" +msgstr "Informationen zum Autor" + +#: plugins/content_types/node_form/node_form_author.inc:35 +msgid "Authoring information." +msgstr "Informationen zum Autor." + +#: plugins/content_types/node_form/node_form_author.inc:41 +msgid "\"@s\" node form publishing options" +msgstr "„@s“ Beitragsformular-Veröffentlichungsoptionen" + +#: plugins/content_types/node_form/node_form_book.inc:12 +msgid "Node form book options" +msgstr "Beitragsformular-Buchoptionen" + +#: plugins/content_types/node_form/node_form_book.inc:13 +msgid "Book options for the node." +msgstr "Buchoptionen für den Beitrag." + +#: plugins/content_types/node_form/node_form_book.inc:24 +msgid "Book options" +msgstr "Buchoptionen" + +#: plugins/content_types/node_form/node_form_book.inc:39 +msgid "Book options." +msgstr "Buchoptionen." + +#: plugins/content_types/node_form/node_form_book.inc:45 +msgid "\"@s\" node form book options" +msgstr "„@s“ Beitragsformular-Buchoptionen" + +#: plugins/content_types/node_form/node_form_buttons.inc:11 +msgid "Node form submit buttons" +msgstr "Beitragsformular Speichern-Schaltknöpfe" + +#: plugins/content_types/node_form/node_form_buttons.inc:12 +msgid "Submit buttons for the node form." +msgstr "Speichern-Schaltknöpfe für das Beitragsformular." + +#: plugins/content_types/node_form/node_form_buttons.inc:29 +msgid "Node form buttons." +msgstr "Beitragsformular-Schaltknöpfe" + +#: plugins/content_types/node_form/node_form_buttons.inc:35 +#, fuzzy +msgid "\"@s\" node form submit buttons" +msgstr "Beitragsformular Speichern-Schaltknöpfe" + +#: plugins/content_types/node_form/node_form_comment.inc:12 +msgid "Node form comment settings" +msgstr "Beitragsformular-Kommentareinstellungen" + +#: plugins/content_types/node_form/node_form_comment.inc:13 +msgid "Comment settings on the Node form." +msgstr "Kommentareinstellungen im Beitragsformular." + +#: plugins/content_types/node_form/node_form_comment.inc:24 +msgid "Comment options" +msgstr "Kommentareinstellungen" + +#: plugins/content_types/node_form/node_form_comment.inc:35 +msgid "Comment options." +msgstr "Kommentareinstellungen." + +#: plugins/content_types/node_form/node_form_comment.inc:41 +msgid "\"@s\" node form comment settings" +msgstr "„@s“ Beitragsformular-Kommentareinstellungen" + +#: plugins/content_types/node_form/node_form_input_format.inc:11 +msgid "Node form input format" +msgstr "Beitrag-Eingabeformat-Formular" + +#: plugins/content_types/node_form/node_form_input_format.inc:12 +msgid "Input format for the body field on a node." +msgstr "Eingabeformat für den Textkörper eines Beitrages." + +#: plugins/content_types/node_form/node_form_input_format.inc:22 +#: plugins/content_types/search/search_result.inc:135;173 +msgid "Input format" +msgstr "Eingabeformat" + +#: plugins/content_types/node_form/node_form_input_format.inc:33 +msgid "Input format." +msgstr "Eingabeformat." + +#: plugins/content_types/node_form/node_form_input_format.inc:39 +msgid "\"@s\" node form input format" +msgstr "„@s“ Beitragsformular-Eingabeformat" + +#: plugins/content_types/node_form/node_form_log.inc:11 +msgid "Node form revision log message" +msgstr "Protokollnachricht im Beitragsformular" + +#: plugins/content_types/node_form/node_form_log.inc:12 +msgid "Revision log message for the node." +msgstr "Protokollnachricht für den Beitrag." + +#: plugins/content_types/node_form/node_form_log.inc:28 +#, fuzzy +msgid "\"@s\" node form revision log" +msgstr "Protokollnachricht im Beitragsformular" + +#: plugins/content_types/node_form/node_form_menu.inc:12 +msgid "Node form menu settings" +msgstr "Beitragsformular-Menüeinstellungen" + +#: plugins/content_types/node_form/node_form_menu.inc:13 +msgid "Menu settings on the Node form." +msgstr "Menüeinstellungen im Beitragsformular." + +#: plugins/content_types/node_form/node_form_menu.inc:24 +msgid "Menu options" +msgstr "Menüeinstellungen" + +#: plugins/content_types/node_form/node_form_menu.inc:36 +msgid "Menu options." +msgstr "Menüeinstellungen." + +#: plugins/content_types/node_form/node_form_menu.inc:42 +msgid "\"@s\" node form menu settings" +msgstr "„@s“ Beitragsformular-Menüeinstellungen" + +#: plugins/content_types/node_form/node_form_path.inc:12 +msgid "Node form url path settings" +msgstr "Beitragsformular-URL-Pfad-Einstellungen" + +#: plugins/content_types/node_form/node_form_path.inc:13 +#: plugins/content_types/node_form/node_form_publishing.inc:18 +msgid "Publishing options on the Node form." +msgstr "Veröffentlichungsoptionen im Beitragsformular." + +#: plugins/content_types/node_form/node_form_path.inc:24 +msgid "URL path options" +msgstr "URL-Alias-Einstellungen" + +#: plugins/content_types/node_form/node_form_path.inc:36 +msgid "URL Path options." +msgstr "URL-Alias-Einstellungen." + +#: plugins/content_types/node_form/node_form_path.inc:42 +msgid "\"@s\" node form path options" +msgstr "„@s“ Beitragsformular-Pfadoptionen" + +#: plugins/content_types/node_form/node_form_publishing.inc:16 +msgid "Node form publishing options" +msgstr "Beitragsformular-Veröffentlichungsoptionen" + +#: plugins/content_types/node_form/node_form_publishing.inc:27 +msgid "Publishing options" +msgstr "Veröffentlichungseinstellungen" + +#: plugins/content_types/node_form/node_form_publishing.inc:39 +msgid "Publishing options." +msgstr "Veröffentlichungseinstellungen." + +#: plugins/content_types/node_form/node_form_publishing.inc:45 +msgid "\"@s\" node form author information" +msgstr "„@s“ Beitragsformular-Autoreninformation" + +#: plugins/content_types/node_form/node_form_taxonomy.inc:12 +msgid "Node form categories" +msgstr "Beitragsformular-Kategorien" + +#: plugins/content_types/node_form/node_form_taxonomy.inc:13 +msgid "Taxonomy categories for the node." +msgstr "Taxonomie-Kategorien für den Beitrag." + +#: plugins/content_types/node_form/node_form_taxonomy.inc:24 +msgid "Categories" +msgstr "Kategorien" + +#: plugins/content_types/node_form/node_form_taxonomy.inc:35 +msgid "Categories." +msgstr "Kategorien." + +#: plugins/content_types/node_form/node_form_taxonomy.inc:41 +#, fuzzy +msgid "\"@s\" node form select taxonomy" +msgstr "Bestimmt den Inhaltstyp für dieses Formular." + +#: plugins/content_types/page/page_breadcrumb.inc:18 +#, fuzzy +msgid "Add the breadcrumb trail as content." +msgstr "Beitrag von dieser Webseite als Inhalt hinzufügen." + +#: plugins/content_types/page/page_breadcrumb.inc:19 +#: plugins/content_types/page/page_footer_message.inc:19 +#: plugins/content_types/page/page_help.inc:19 +#: plugins/content_types/page/page_messages.inc:19 +#: plugins/content_types/page/page_mission.inc:19 +#: plugins/content_types/page/page_slogan.inc:19 +#: plugins/content_types/page/page_tabs.inc:19 +#: plugins/content_types/page/page_title.inc:19 +#, fuzzy +msgid "Page elements" +msgstr "Dummy-Elemente" + +#: plugins/content_types/page/page_footer_message.inc:16 +#, fuzzy +msgid "Page footer message" +msgstr "Fußbereich der Seite verwenden" + +#: plugins/content_types/page/page_footer_message.inc:18 +#, fuzzy +msgid "Add the page footer message as content." +msgstr "Beitrag von dieser Webseite als Inhalt hinzufügen." + +#: plugins/content_types/page/page_help.inc:15 +#, fuzzy +msgid "Help" +msgstr "Hilfe" + +#: plugins/content_types/page/page_help.inc:18 +msgid "Add the help text of the current page as content." +msgstr "" + +#: plugins/content_types/page/page_messages.inc:15 +#, fuzzy +msgid "Status messages" +msgstr "!type Nachrichten" + +#: plugins/content_types/page/page_messages.inc:18 +msgid "Add the status messages of the current page as content." +msgstr "" + +#: plugins/content_types/page/page_mission.inc:15 +#, fuzzy +msgid "Mission" +msgstr "Beschreibung" + +#: plugins/content_types/page/page_mission.inc:18 +#, fuzzy +msgid "Add the site mission statement as content." +msgstr "Beitrag von dieser Webseite als Inhalt hinzufügen." + +#: plugins/content_types/page/page_slogan.inc:15 +#, fuzzy +msgid "Site Slogan" +msgstr "Slogan der Website" + +#: plugins/content_types/page/page_slogan.inc:18 +#, fuzzy +msgid "Add the slogan trail as content." +msgstr "Beitrag von dieser Webseite als Inhalt hinzufügen." + +#: plugins/content_types/page/page_tabs.inc:15 +#, fuzzy +msgid "Tabs" +msgstr "Tabulator" + +#: plugins/content_types/page/page_tabs.inc:18 +msgid "Add the tabs (local tasks) as content." +msgstr "" + +#: plugins/content_types/page/page_title.inc:16 +#, fuzzy +msgid "Page title" +msgstr "Seitentitel" + +#: plugins/content_types/page/page_title.inc:18 +#, fuzzy +msgid "Add the page title as content." +msgstr "Inhalt wird als Seite angezeigt" + +#: plugins/content_types/search/search_form.inc:14 +#, fuzzy +msgid "Advanced search form" +msgstr "Erweiterte Suche" + +#: plugins/content_types/search/search_form.inc:16 +msgid "A search form with advanced options." +msgstr "" + +#: plugins/content_types/search/search_form.inc:96 +#: plugins/content_types/search/search_result.inc:99 +#, fuzzy +msgid "Search type" +msgstr "Suche Typ" + +#: plugins/content_types/search/search_form.inc:103 +#, fuzzy +msgid "Search form" +msgstr "Suchformular" + +#: plugins/content_types/search/search_form.inc:105 +#, fuzzy +msgid "Simple" +msgstr "Einfach" + +#: plugins/content_types/search/search_form.inc:106 +#, fuzzy +msgid "Advanced" +msgstr "Erweitert" + +#: plugins/content_types/search/search_form.inc:109 +msgid "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." +msgstr "" + +#: plugins/content_types/search/search_form.inc:118 +#, fuzzy +msgid "Same page" +msgstr "Buchseite" + +#: plugins/content_types/search/search_form.inc:136 +#, fuzzy +msgid "Override default prompt" +msgstr "(Standardtheme der Website)" + +#: plugins/content_types/search/search_form.inc:163 +#, fuzzy +msgid "@type search form" +msgstr "Typ des Formularfeldes." + +#: plugins/content_types/search/search_result.inc:14;69 +#, fuzzy +msgid "Search results" +msgstr "Suchergebnisse" + +#: plugins/content_types/search/search_result.inc:16 +#, fuzzy +msgid "The results of a search using keywords." +msgstr "Löscht alle Such-Ergebnisse" + +#: plugins/content_types/search/search_result.inc:62 +#, fuzzy +msgid "results" +msgstr "Ergebnisse" + +#: plugins/content_types/search/search_result.inc:74 +#, fuzzy +msgid "Your search yielded no results" +msgstr "Die Suche lieferte keine Ergebnisse." + +#: plugins/content_types/search/search_result.inc:107 +msgid "Record a watchdog log entry when searches are made" +msgstr "" + +#: plugins/content_types/search/search_result.inc:113 +#, fuzzy +msgid "Override \"no result\" text" +msgstr " %s hat keinen Eintrag in der Override-Liste.\n" + +#: plugins/content_types/search/search_result.inc:125 +#, fuzzy +msgid "No result text" +msgstr "Element hat keinen Text definiert" + +#: plugins/content_types/search/search_result.inc:151 +msgid "Display text if no search keywords were submitted" +msgstr "" + +#: plugins/content_types/search/search_result.inc:163 +#, fuzzy +msgid "No keywords text" +msgstr "Element hat keinen Text definiert" + +#: plugins/content_types/search/search_result.inc:202 +#, fuzzy +msgid "@type search result" +msgstr "Geben Sie hier Ihre Suchbegriffe ein" + +#: plugins/content_types/search/search_result.inc:62 +#, fuzzy +msgid "search" +msgstr "Suchen" + +#: plugins/content_types/search/search_result.inc:62 +#, fuzzy +msgid "%keys (@type)." +msgstr "%keys (@type)." + +#: plugins/content_types/term_context/term_description.inc:10 +msgid "Term description" +msgstr "Begriffsbeschreibung" + +#: plugins/content_types/term_context/term_description.inc:12 +msgid "Term description." +msgstr "Beschreibung des Begriffs." + +#: plugins/content_types/term_context/term_description.inc:14 +#: plugins/content_types/term_context/term_list.inc:14 +#: plugins/contexts/term.inc:15 +#, fuzzy +msgid "Taxonomy term" +msgstr "Taxonomie-Begriff" + +#: plugins/content_types/term_context/term_description.inc:30 +msgid "Edit term" +msgstr "Begriff bearbeiten" + +#: plugins/content_types/term_context/term_description.inc:31 +msgid "Edit this term" +msgstr "Diesen Begriff bearbeiten" + +#: plugins/content_types/term_context/term_description.inc:38 +#: plugins/content_types/term_context/term_list.inc:62 +msgid "Term description goes here." +msgstr "Begriffsbeschreibung wird hier angezeigt." + +#: plugins/content_types/term_context/term_description.inc:46 +msgid "\"@s\" term description" +msgstr "„@s“ Begriffsbeschreibung" + +#: plugins/content_types/term_context/term_list.inc:10 +msgid "List of related terms" +msgstr "Liste relevanter Begriffe" + +#: plugins/content_types/term_context/term_list.inc:12 +msgid "Terms related to an existing term; may be child, siblings or top level." +msgstr "Verwandte Begriffe für einen existierenden Begriff; Kinder, Nachbarn oder übergeordnete Begriffe." + +#: plugins/content_types/term_context/term_list.inc:71 +msgid "Child terms" +msgstr "Untergeordnete Begriffe" + +#: plugins/content_types/term_context/term_list.inc:72 +msgid "Related terms" +msgstr "Verwandte Begriffe" + +#: plugins/content_types/term_context/term_list.inc:73 +msgid "Sibling terms" +msgstr "Benachbarte Begriffe" + +#: plugins/content_types/term_context/term_list.inc:74 +msgid "Top level terms" +msgstr "Übergeordnete Begriffe" + +#: plugins/content_types/term_context/term_list.inc:75 +msgid "Term synonyms" +msgstr "Begriffssynonyme" + +# Kontext sensitive +#: plugins/content_types/term_context/term_list.inc:87 +msgid "Which terms" +msgstr "Welche Begriffe" + +#: plugins/content_types/term_context/term_list.inc:96 +msgid "List type" +msgstr "Listentyp" + +#: plugins/content_types/term_context/term_list.inc:97 +msgid "Unordered" +msgstr "Ungeordnet" + +#: plugins/content_types/term_context/term_list.inc:97 +msgid "Ordered" +msgstr "Geordnet" + +#: plugins/content_types/term_context/term_list.inc:104 +msgid "\"@s\" @type" +msgstr "„@s“ @type" + +#: plugins/content_types/user_context/profile_fields.inc:12 +msgid "Profile category" +msgstr "Profilkategorie" + +#: plugins/content_types/user_context/profile_fields.inc:14 +#, fuzzy +msgid "Contents of a single profile category." +msgstr "Profilfeld %field zur Kategorie %category hinzugefügt." + +#: plugins/content_types/user_context/profile_fields.inc:64 +msgid "Profile content goes here." +msgstr "Profilinhalt wird hier angezeigt." + +# Kontext sensitive +#: plugins/content_types/user_context/profile_fields.inc:91 +msgid "Which category" +msgstr "Welche Kategorie" + +#: plugins/content_types/user_context/profile_fields.inc:101 +msgid "Text to display if category has no data. Note that title will not display unless overridden." +msgstr "Angezeigter Text, wenn die Kategorie keine Daten enthält. Der Titel wird nicht dargestellt, sofern er nicht übersteuert wurde." + +#: plugins/content_types/user_context/profile_fields.inc:122 +msgid "\"@s\" profile fields" +msgstr "„@s“ Profilfelder" + +#: plugins/content_types/user_context/user_picture.inc:10 +msgid "User picture" +msgstr "Benutzerbild" + +#: plugins/content_types/user_context/user_picture.inc:12 +msgid "The picture of a user." +msgstr "Das Bild von einem Benutzer." + +#: plugins/content_types/user_context/user_picture.inc:37 +msgid "\"@s\" user picture" +msgstr "„@s“ Benutzerbild" + +#: plugins/content_types/user_context/user_profile.inc:10 +msgid "User profile" +msgstr "Benutzerprofil" + +#: plugins/content_types/user_context/user_profile.inc:12 +msgid "The profile of a user." +msgstr "Das Profil eines Benutzers." + +#: plugins/content_types/user_context/user_profile.inc:42 +msgid "\"@s\" user profile" +msgstr "„@s“ Benutzerprofil" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:11 +msgid "Vocabulary terms" +msgstr "Vokabularbegriffe" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:13 +msgid "All the terms in a vocabulary." +msgstr "Alle Begriffe in einem Vokabular." + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:66 +msgid "\"@s\" terms" +msgstr "„@s“ Begriffe" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:73 +msgid "Maximum depth" +msgstr "Maximale Tiefe" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:74 +msgid "unlimited" +msgstr "Unbegrenzt" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:76 +msgid "Define the maximum depth of terms being displayed." +msgstr "Maximale Tiefe der dargestellten Begriffe." + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:81 +msgid "Display as tree" +msgstr "Als Baum anzeigen" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:83 +msgid "If checked, the terms are displayed in a tree, otherwise in a flat list." +msgstr "Falls aktiviert, werden Begriffe in einem Baum dargestellt, ansonsten als einfache Liste." + +#: plugins/contexts/node.inc:17 +msgid "A node object." +msgstr "Ein Beitragsobjekt." + +#: plugins/contexts/node.inc:29 +#, fuzzy +msgid "Enter the node ID of a node for this context." +msgstr "Bestimmt den Inhaltstyp für dieses Formular." + +#: plugins/contexts/node.inc:91 +#: plugins/contexts/node_edit_form.inc:109 +msgid "'%title' [node id %nid]" +msgstr "‚%title‘ [Beitrag-ID %nid]" + +#: plugins/contexts/node.inc:91 +#: plugins/contexts/node_edit_form.inc:109 +msgid "Open in new window" +msgstr "In neuem Fenster öffnen" + +#: plugins/contexts/node.inc:92 +#: plugins/contexts/node_edit_form.inc:110 +msgid "Currently set to !link" +msgstr "Derzeit auf !link gesetzt" + +#: plugins/contexts/node.inc:104 +#: plugins/contexts/node_edit_form.inc:122 +#, fuzzy +msgid "Reset identifier to node title" +msgstr "Aktivieren, damit der Titel zu dem Beitrag verweist." + +#: plugins/contexts/node.inc:105 +#: plugins/contexts/node_edit_form.inc:123 +msgid "If checked, the identifier will be reset to the node title of the selected node." +msgstr "Sobald aktiviert, wird der Identifikator auf den Beitragstitel des ausgewählten Beitrages zurückgesetzt." + +#: plugins/contexts/node.inc:117 +#: plugins/contexts/node_edit_form.inc:135 +msgid "You must select a node." +msgstr "Ein Beitrag muss ausgewählt werden." + +#: plugins/contexts/node.inc:143 +#: plugins/contexts/node_edit_form.inc:161 +msgid "Invalid node selected." +msgstr "Ein ungültiger Beitrag wurde ausgewählt." + +#: plugins/contexts/node.inc:166 +#, fuzzy +msgid "Node ID" +msgstr "Beitrag ID" + +#: plugins/contexts/node.inc:167 +msgid "Node revision ID" +msgstr "Die Versions-ID der Beitragsversion." + +#: plugins/contexts/node.inc:169 +msgid "Author UID" +msgstr "Autor-UID" + +#: plugins/contexts/node_add_form.inc:15 +#, fuzzy +msgid "Node add form" +msgstr "Ein Formular zum Erstellen eines Beitrages." + +#: plugins/contexts/node_add_form.inc:16 +msgid "A node add form." +msgstr "Ein Formular zum Erstellen eines Beitrages." + +# English is missing "for this context" +#: plugins/contexts/node_add_form.inc:25 +msgid "Enter the node type this context." +msgstr "Die Beitragstyp für diesen Kontext eingeben." + +#: plugins/contexts/node_add_form.inc:78 +msgid "Submit @name" +msgstr "@name speichern" + +#: plugins/contexts/node_add_form.inc:104 +msgid "Select the node type for this form." +msgstr "Bestimmt den Inhaltstyp für dieses Formular." + +#: plugins/contexts/node_edit_form.inc:15 +#, fuzzy +msgid "Node edit form" +msgstr "Ein Formular zum Bearbeiten eines Beitrages." + +#: plugins/contexts/node_edit_form.inc:16 +msgid "A node edit form." +msgstr "Ein Formular zum Bearbeiten eines Beitrages." + +#: plugins/contexts/node_edit_form.inc:27 +#, fuzzy +msgid "Enter the node ID of a node for this argument:" +msgstr "Bestimmt den Inhaltstyp für dieses Formular." + +#: plugins/contexts/string.inc:16 +msgid "A context that is just a string." +msgstr "" + +#: plugins/contexts/string.inc:22 +#, fuzzy +msgid "Raw string" +msgstr "Zeichenkette löschen" + +#: plugins/contexts/string.inc:23 +#, fuzzy +msgid "HTML-safe string" +msgstr "Zeichenkette nicht gefunden." + +#: plugins/contexts/string.inc:28 +msgid "Enter the string for this context." +msgstr "Die Zeichenkette für diesen Kontext eingeben." + +#: plugins/contexts/term.inc:16 +msgid "A single taxonomy term object." +msgstr "Ein einzelnes Taxonomie-Begriff-Objekt." + +#: plugins/contexts/term.inc:26 +#, fuzzy +msgid "Vocabulary ID" +msgstr "Vokabular-ID" + +#: plugins/contexts/term.inc:79 +msgid "Currently set to @term. Enter another term if you wish to change the term." +msgstr "" + +#: plugins/contexts/term.inc:96 +msgid "Select a term from @vocabulary." +msgstr "Einen Begriff von @vocabulary auswählen." + +#: plugins/contexts/term.inc:114 +msgid "Reset identifier to term title" +msgstr "" + +#: plugins/contexts/term.inc:115 +msgid "If checked, the identifier will be reset to the term name of the selected term." +msgstr "Sobald aktiviert, wird der Identifikator auf den Begriffsnamen des ausgewählten Begriffes zurückgesetzt." + +#: plugins/contexts/term.inc:128 +msgid "You must select a term." +msgstr "Ein Beitrag muss ausgewählt werden." + +#: plugins/contexts/term.inc:139 +msgid "Invalid term selected." +msgstr "Ein ungültiger Begriff wurde ausgewählt." + +#: plugins/contexts/terms.inc:16 +msgid "Taxonomy terms" +msgstr "Taxonomie Begriffe" + +#: plugins/contexts/terms.inc:17 +msgid "Multiple taxonomy terms, as a group." +msgstr "Mehrere Taxonomie-Begriffe, als Gruppe." + +#: plugins/contexts/terms.inc:25 +#, fuzzy +msgid "Term ID of first term" +msgstr "Vokabular-ID des ersten Begriffs" + +#: plugins/contexts/terms.inc:26 +msgid "Term ID of all term, separated by + or ," +msgstr "" + +#: plugins/contexts/terms.inc:27 +#, fuzzy +msgid "Term name of first term" +msgstr "Vorname, Nachname" + +#: plugins/contexts/terms.inc:28 +msgid "Term name of all terms, separated by + or ," +msgstr "" + +#: plugins/contexts/terms.inc:29 +msgid "Vocabulary ID of first term" +msgstr "Vokabular-ID des ersten Begriffs" + +#: plugins/contexts/user.inc:16 +msgid "A single user object." +msgstr "Ein einzelnes Benutzerobjekt." + +#: plugins/contexts/user.inc:24 +#, fuzzy +msgid "User ID" +msgstr "Benutzer-ID" + +#: plugins/contexts/user.inc:25 +msgid "User name" +msgstr "Benutzername" + +#: plugins/contexts/vocabulary.inc:15 +msgid "Taxonomy vocabulary" +msgstr "Taxonomie-Vokabular" + +#: plugins/contexts/vocabulary.inc:16 +msgid "A single taxonomy vocabulary object." +msgstr "Ein einzelnes Taxonomie-Vokabular-Objekt." + +#: plugins/relationships/book_parent.inc:14 +msgid "Book parent" +msgstr "Übergeordnetes Buch" + +#: plugins/relationships/book_parent.inc:16 +msgid "Adds a book parent from a node context." +msgstr "Fügt ein übergeordnetes Buch aus einem Beitragskontext hinzu." + +#: plugins/relationships/book_parent.inc:63 +#: plugins/relationships/term_parent.inc:63 +msgid "Relationship type" +msgstr "Beziehungstyp" + +#: plugins/relationships/book_parent.inc:64 +#: plugins/relationships/term_parent.inc:64 +msgid "Immediate parent" +msgstr "Direktes, übergeordnetes Element" + +#: plugins/relationships/book_parent.inc:64 +msgid "Top level book" +msgstr "Buch auf oberster Ebene" + +#: plugins/relationships/term_from_node.inc:14 +msgid "Term from node" +msgstr "Begriff des Beitrages" + +#: plugins/relationships/term_from_node.inc:16 +msgid "Adds a taxonomy term from a node context; if multiple terms are selected, this will get the \"first\" term only." +msgstr "Fügt einen Taxonomie-Begriff aus einem Beitragskontext hinzu. Sollten mehrere Begriffe ausgewählt werden, wird nur der „erste“ Begriff verwendet." + +#: plugins/relationships/term_parent.inc:14 +msgid "Term parent" +msgstr "Übergeordneter Begriff" + +#: plugins/relationships/term_parent.inc:16 +msgid "Adds a taxonomy term parent from a term context." +msgstr "Fügt einen übergeordneten Taxonomie-Begriff aus einem Begriffskontext hinzu." + +#: plugins/relationships/term_parent.inc:64 +msgid "Top level term" +msgstr "Begriff auf oberster Ebene" + +#: plugins/relationships/user_from_node.inc:16 +#, fuzzy +msgid "Creates the author of a node as a user context." +msgstr "Fügt einen Benutzer aus dem Beitragsautor-Kontext hinzu." + +#: views_content/views_content.module:61 +#: views_content/plugins/content_types/views.inc:99 +#, fuzzy +msgid "Views" +msgstr "Ansichten" + +#: views_content/views_content.module:92 +#, fuzzy +msgid "Make all views available as panes" +msgstr "Alle Ansichten als Ausschnitte zu Verfügung stellen" + +#: views_content/views_content.module:93 +msgid "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." +msgstr "" + +#: views_content/views_content.module:20 +#, fuzzy +msgid "Views panes" +msgstr "Panel-Ansichten" + +#: views_content/views_content.module:24 +#, fuzzy +msgid "Configure Views to be used as CTools content." +msgstr "Ansichten konfigurieren, die als CTools-Inhalt verwendet werden." + +#: views_content/views_content.info:0 +#, fuzzy +msgid "Views content panes" +msgstr "Veraltete Panel-Ansichten-Inhalte" + +#: views_content/views_content.info:0 +msgid "Allows Views content to be used in Panels, Dashboard and other modules which use the CTools Content API." +msgstr "" + +#: views_content/plugins/content_types/views.inc:18 +#, fuzzy +msgid "All views" +msgstr "Alle Ansichten" + +#: views_content/plugins/content_types/views.inc:33 +#, fuzzy +msgid "Select display" +msgstr "Anzeige auswählen" + +#: views_content/plugins/content_types/views.inc:36 +#, fuzzy +msgid "Configure view" +msgstr "Ansicht konfigurieren" + +#: views_content/plugins/content_types/views.inc:226 +#, fuzzy +msgid "Display" +msgstr "Anzeige" + +#: views_content/plugins/content_types/views.inc:228 +msgid "Choose which display of this view you wish to use." +msgstr "" + +#: views_content/plugins/content_types/views.inc:249 +#: views_content/plugins/content_types/views_panes.inc:282 +#, fuzzy +msgid "Broken/missing/deleted view." +msgstr "Beschädigte/Fehlende/Gelöschte Ansicht." + +#: views_content/plugins/content_types/views.inc:253 +#, fuzzy +msgid "Configure view @view (@display)" +msgstr "Ansicht @view (@display) konfigurieren" + +#: views_content/plugins/content_types/views.inc:275 +#, fuzzy +msgid "Link title to view" +msgstr "Titel mit Ansicht verlinken" + +#: views_content/plugins/content_types/views.inc:281 +#, fuzzy +msgid "Provide a \"more\" link that links to the view" +msgstr "Stellt einen „Mehr“-Link bereit, der zur Ansicht verlinkt" + +#: views_content/plugins/content_types/views.inc:282 +#, fuzzy +msgid "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." +msgstr "Dies ist unabhängig von jeglichem Mehr-Link, welcher von der Ansicht selbst bereitgestellt wird; falls zwei Mehr-Links angezeigt werden, diesen hier deaktivieren. Ansichten stellen nur in der Block-Ausgabe einen Mehr-Link bereit. Für eingebettete Ansichten diesen verwenden." + +#: views_content/plugins/content_types/views.inc:288 +#: views_content/plugins/content_types/views_panes.inc:335 +#, fuzzy +msgid "Display feed icons" +msgstr "Feed-Icons anzeigen" + +#: views_content/plugins/content_types/views.inc:294 +#, fuzzy +msgid "Custom pager settings" +msgstr "Individuelle Sichtbarkeits-Einstellungen" + +#: views_content/plugins/content_types/views.inc:299 +msgid "Use different pager settings from view settings" +msgstr "" + +#: views_content/plugins/content_types/views.inc:306 +msgid "<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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:313 +#: views_content/plugins/content_types/views_panes.inc:343 +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:148 +#, fuzzy +msgid "Use pager" +msgstr "Seitennavigation verwenden" + +#: views_content/plugins/content_types/views.inc:322 +#: views_content/plugins/content_types/views_panes.inc:351 +#, fuzzy +msgid "Pager ID" +msgstr "Pager ID" + +#: views_content/plugins/content_types/views.inc:335 +#, fuzzy +msgid "Num posts" +msgstr "Anzahl Beiträge" + +#: views_content/plugins/content_types/views.inc:343 +#: views_content/plugins/content_types/views_panes.inc:372 +#, fuzzy +msgid "Offset" +msgstr "Offset" + +#: views_content/plugins/content_types/views.inc:345 +msgid "The number of items to skip and not display." +msgstr "" + +#: views_content/plugins/content_types/views.inc:352 +#, fuzzy +msgid "Send arguments" +msgstr "Argumente übergeben" + +#: views_content/plugins/content_types/views.inc:354 +msgid "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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:362 +msgid "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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:368 +#, fuzzy +msgid "Override URL" +msgstr "URL überschreiben" + +#: views_content/plugins/content_types/views.inc:370 +#, fuzzy +msgid "If this is set, override the View URL; this can sometimes be useful to set to the panel URL" +msgstr "Sobald aktiviert, wird die Ansichten URL überschrieben; Manchmal kann es sinnvoll sein, die Panel URL einzusetzten." + +#: views_content/plugins/content_types/views.inc:394;406 +#: views_content/plugins/content_types/views_panes.inc:411;414 +#, fuzzy +msgid "Deleted/missing view @view" +msgstr "Entfernte/fehlende Ansicht @view" + +#: views_content/plugins/content_types/views.inc:396 +#, fuzzy +msgid "View: @name" +msgstr "Ansicht: @name" + +#: views_content/plugins/content_types/views.inc:409 +#, fuzzy +msgid "View information" +msgstr "Ansichtsinformation" + +#: views_content/plugins/content_types/views.inc:412 +#, fuzzy +msgid "Using display @display." +msgstr "Anzeige @display wurd verwendet." + +#: views_content/plugins/content_types/views.inc:433 +msgid "Argument @arg using context @context converted into @converter" +msgstr "" + +#: views_content/plugins/content_types/views.inc:441 +#, fuzzy +msgid "@count items displayed." +msgstr "@count Einträge wurden angezeigt." + +#: views_content/plugins/content_types/views.inc:443 +#, fuzzy +msgid "With pager." +msgstr "Mit Seitennavigation." + +#: views_content/plugins/content_types/views.inc:446 +#, fuzzy +msgid "Without pager." +msgstr "Ohne Seitennavigation." + +#: views_content/plugins/content_types/views.inc:450 +#, fuzzy +msgid "Skipping first @count results" +msgstr "Überspringe die ersten @count Ergebnisse" + +#: views_content/plugins/content_types/views.inc:453 +#, fuzzy +msgid "With more link." +msgstr "Mit „Mehr“-Link" + +#: views_content/plugins/content_types/views.inc:456 +#, fuzzy +msgid "With feed icon." +msgstr "Mit Feed-Symbole." + +#: views_content/plugins/content_types/views.inc:459 +#, fuzzy +msgid "Sending arguments." +msgstr "Argumente übergeben." + +#: views_content/plugins/content_types/views.inc:462 +#, fuzzy +msgid "Using arguments: @args" +msgstr "Argumente verwenden: @arg" + +#: views_content/plugins/content_types/views.inc:465 +#, fuzzy +msgid "Using url: @url" +msgstr "Verwende URL: @url" + +#: views_content/plugins/content_types/views_panes.inc:15;94 +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:92 +#, fuzzy +msgid "View panes" +msgstr "Zugriff auf alle Panel-Inhalte" + +#: views_content/plugins/content_types/views_panes.inc:319 +#, fuzzy +msgid "Link title to page" +msgstr "Titel mit Seite verlinken" + +#: views_content/plugins/content_types/views_panes.inc:326 +#, fuzzy +msgid "Provide a \"more\" link." +msgstr "Stellt einen „Mehr“-Link bereit." + +#: views_content/plugins/content_types/views_panes.inc:363 +#, fuzzy +msgid "Num items" +msgstr "Anzahl Einträge" + +#: views_content/plugins/content_types/views_panes.inc:365 +#, fuzzy +msgid "Select the number of items to display, or 0 to display all results." +msgstr "Die Anzahl der anzuzeigenden Einträge auswählen, oder 0 um alle Ergebnisse anzuzeigen." + +#: views_content/plugins/content_types/views_panes.inc:374 +#, fuzzy +msgid "Enter the number of items to skip; enter 0 to skip no items." +msgstr "Die Anzahl der zu überspringenden Einträge eingeben, oder 0 um alle Einträge zu überspringen." + +#: views_content/plugins/content_types/views_panes.inc:381 +#, fuzzy +msgid "Override path" +msgstr "Pfad überschreiben" + +#: views_content/plugins/content_types/views_panes.inc:383 +#, fuzzy +msgid "If this is set, override the View URL path; this can sometimes be useful to set to the panel URL." +msgstr "Sobald aktiviert, wird die Ansichten-URL übersteuert; manchmal kann es sinnvoll sein, die Panel-URL einzusetzen." + +#: views_content/plugins/views/views_content.views.inc:16 +#, fuzzy +msgid "Content pane" +msgstr "Inhaltsausschnitt" + +#: views_content/plugins/views/views_content.views.inc:17 +msgid "Is available as content for a panel or dashboard display." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:56 +#, fuzzy +msgid "Pane settings" +msgstr "Ausschnitt-Einstellungen" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:61 +#, fuzzy +msgid "Use view name" +msgstr "Ansichtsname verwenden" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:70 +#, fuzzy +msgid "Admin title" +msgstr "Admin Titel" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:76 +#, fuzzy +msgid "Use view description" +msgstr "Ansichtsbeschreibung verwenden" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:85 +#, fuzzy +msgid "Admin desc" +msgstr "Admin-Beschreibung" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:101 +#, fuzzy +msgid "Category" +msgstr "Kategorie" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:107;151 +#, fuzzy +msgid "Link to view" +msgstr "Zur Ansicht verlinken" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:108;114;208;218 +#, fuzzy +msgid "Yes" +msgstr "Ja" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:108;114;208;218 +#, fuzzy +msgid "No" +msgstr "Nein" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:113 +#, fuzzy +msgid "Use Panel path" +msgstr "Panel-Pfad verwenden" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:119 +#, fuzzy +msgid "Argument input" +msgstr "Argumenteingabe" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:128;142 +#, fuzzy +msgid "Allow settings" +msgstr "Einstellungen zulassen" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +#, fuzzy +msgid "None" +msgstr "Keines" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +#, fuzzy +msgid "All" +msgstr "Alle" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +#, fuzzy +msgid "Some" +msgstr "Einige" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:144 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:149 +#, fuzzy +msgid "Items per page" +msgstr "Beträge pro Seite" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:150 +#, fuzzy +msgid "Pager offset" +msgstr "Offset der Seitennavigation" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:152 +#, fuzzy +msgid "More link" +msgstr "„Mehr“-Verweis?" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:153 +#, fuzzy +msgid "Path override" +msgstr "Pfad-Übersteuerung" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:154 +#, fuzzy +msgid "Title override" +msgstr "Titel-Übersteuerung" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:171 +#, fuzzy +msgid "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." +msgstr "Dies ist der Titel, der für diesen Ansichten-Ausschnitt im „Inhalt hinzufügen“-Dialog erscheint. Falls nicht gesetzt, wird der Ansichten-Name verwendet." + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:181 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:193 +#, fuzzy +msgid "This is category the pane will appear in on the add content dialog." +msgstr "Die ist die Kategorie, in welcher der Ausschnitt im „Inhalt hinzufügen“-Dialog erscheint." + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:199 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:204 +#, fuzzy +msgid "Link pane title to view" +msgstr "Ausschnitt-Titel mit Ansicht verlinken" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:214 +msgid "Inherit path from panel display" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:220 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:225 +#, fuzzy +msgid "Choose the data source for view arguments" +msgstr "Einen Wert für dieses Argument eingeben" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:242 +#, fuzzy +msgid "No argument" +msgstr "Kein Argument" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:243 +#, fuzzy +msgid "Argument wildcard" +msgstr "Argumentplatzhalter" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:244 +#, fuzzy +msgid "From context" +msgstr "Aus dem Zusammenhang" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:245 +#, fuzzy +msgid "From panel argument" +msgstr "Aus dem Panelargument" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:246 +#, fuzzy +msgid "Fixed" +msgstr "Statisch" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:247 +#, fuzzy +msgid "Input on pane config" +msgstr "Eingabe in Panel-Inhalt-Einstellungen" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:250 +#, fuzzy +msgid "@arg source" +msgstr "@arg-Quelle" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:256 +#, fuzzy +msgid "Required context" +msgstr "Zusammenhang erforderlich" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:257 +#, fuzzy +msgid "If \"From context\" is selected, which type of context to use." +msgstr "Das zu verwendende Panel-Argument, falls „Aus Panel-Argument“ ausgewählt wurde." + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:266 +#, fuzzy +msgid "Context is optional" +msgstr "Wahlweise Kontaktinformation" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:267 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:275 +#, fuzzy +msgid "Panel argument" +msgstr "Panelargument" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:276 +#, fuzzy +msgid "If \"From panel argument\" is selected, which panel argument to use." +msgstr "Das zu verwendende Panel-Argument, falls „Aus Panel-Argument“ ausgewählt wurde." + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +#, fuzzy +msgid "First" +msgstr "Erster" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +#, fuzzy +msgid "Second" +msgstr "Zweites" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +#, fuzzy +msgid "Third" +msgstr "Drittes" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +#, fuzzy +msgid "Fourth" +msgstr "Viertes" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +#, fuzzy +msgid "Fifth" +msgstr "Fünftes" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +#, fuzzy +msgid "Sixth" +msgstr "Sechstes" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:285 +#, fuzzy +msgid "Fixed argument" +msgstr "Statisches Argument" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:286 +#, fuzzy +msgid "If \"Fixed\" is selected, what to use as an argument." +msgstr "Das Argument, falls „Statisch“ ausgewählt wurde." + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:294 +#, fuzzy +msgid "Label" +msgstr "Bezeichnung" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:295 +#, fuzzy +msgid "If this argument is presented to the panels user, what label to apply to it." +msgstr "Die verwendete Bezeichnung, falls dieses Argument für den Benutzer erscheint." + +#~ msgid "ctools" +#~ msgstr "ctools" +#~ msgid "The filename this CSS is stored in." +#~ msgstr "Der Dateiname in dem dieses CSS gespeichert wird." + +#, fuzzy +#~ msgid "The session ID this cache object belongs to." +#~ msgstr "Die Session-ID zu der dieses Cacheobjekt gehört." + +#, fuzzy +#~ msgid "The name of the object this cache is attached to." +#~ msgstr "Der Name der Funktion, welche die Darstellung der Seite aufbaut." + +#, fuzzy +#~ msgid "The time this cache was created or updated." +#~ msgstr "Der Zeitpunkt zu dem der Cache erstellt oder aktualisiert wurde." + +#, fuzzy +#~ msgid "Serialized data being stored." +#~ msgstr "Die gespeicherten serialisierten Daten." +#~ msgid "Add a node" +#~ msgstr "Beitrag hinzufügen" +#~ msgid "Check here to show only the node teaser." +#~ msgstr "Aktivieren, um nur den Anrisstext des Beitrages anzuzeigen." +#~ msgid "Check here if the node is being displayed on a page by itself." +#~ msgstr "Aktivieren, falls der Beitrag auf einer eigenen Seite erscheint." + diff --git a/sites/all/modules/ctools/translations/ctools.fr.po b/sites/all/modules/ctools/translations/ctools.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..73bddc18b3d06c3df9ce785f7f15513fba7eea18 --- /dev/null +++ b/sites/all/modules/ctools/translations/ctools.fr.po @@ -0,0 +1,92 @@ +# $Id: ctools.fr.po,v 1.1 2009/08/16 20:10:09 hass Exp $ +# +# French translation of Drupal (general) +# Copyright 2009 Jérémy Chatard <jchatard@breek.fr> +# Generated from files: +# ctools.install,v 1.11 2009/08/09 19:33:12 merlinofchaos +# ctools.info,v 1.3 2009/07/12 18:11:58 merlinofchaos +# +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-08-15 10:42+0200\n" +"PO-Revision-Date: 2009-08-15 10:55+0100\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: French <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" + +#: ctools.install:25 +msgid "CTools CSS Cache" +msgstr "Cache CSS de CTools" + +#: ctools.install:27 +msgid "Exists" +msgstr "Présent" + +#: ctools.install:31 +msgid "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." +msgstr "Le répertoire de cache CSS de CTools, %path n'a pas pu être créé car il y a un problème de configuration sur le répertoire files. Veuillez vous assurez que le répertoire files est correctement configuré et que le serveur web dispose des permissions suffisantes pour créer des répertoires." + +#: ctools.install:33 +msgid "Unable to create" +msgstr "Création impossible" + +#: ctools.install:75 +msgid "A special cache used to store CSS that must be non-volatile." +msgstr "Un cache spécial utilisé pour stocker le code CSS qui ne doit pas être géré de façon volatile." + +#: ctools.install:80 +msgid "The CSS ID this cache object belongs to." +msgstr "L'ID CSS auquel cet objet mis en cache appartient." + +#: ctools.install:86 +msgid "The filename this CSS is stored in." +msgstr "Le nom du fichier dans lequel ce CSS est stocké." + +#: ctools.install:91 +msgid "CSS being stored." +msgstr "Règles CSS qui sont stockées." + +#: ctools.install:97 +msgid "Whether or not this CSS needs to be filtered." +msgstr "Ce CSS doit-il ou non être filtré." + +#: ctools.install:113 +msgid "A special cache used to store objects that are being edited; it serves to save state in an ordinarily stateless environment." +msgstr "Cache spécial utilisé pour enregistrer les objets en cours d'édition ; il sert à enregistrer l'état dans un environnement normalement sans état." + +#: ctools.install:119 +msgid "The session ID this cache object belongs to." +msgstr "L'identifiant de session auquel cet objet de cache appartient." + +#: ctools.install:125 +msgid "The name of the object this cache is attached to." +msgstr "Le nom de l'objet auquel ce cache est attaché." + +#: ctools.install:131 +msgid "The type of the object this cache is attached to; this essentially represents the owner so that several sub-systems can use this cache." +msgstr "Le type d'objet auquel ce cache est rattaché ; cela représente essentiellement le propriétaire afin que d'autres sous-systèmes puissent utiliser ce cache." + +#: ctools.install:138 +msgid "The time this cache was created or updated." +msgstr "Date de création ou de mise à jour de ce cache." + +#: ctools.install:143 +msgid "Serialized data being stored." +msgstr "Données sérialisées en cours d'enregistrement." + +#: ctools.info:0 +msgid "Chaos tools" +msgstr "Chaos tools" + +#: ctools.info:0 +msgid "A library of helpful tools by Merlin of Chaos." +msgstr "Une librairie d'outils par Merlin of Cahos" + +#: ctools.info:0 +msgid "Chaos tool suite" +msgstr "Chaos tool suite" + diff --git a/sites/all/modules/ctools/translations/ctools.hu.po b/sites/all/modules/ctools/translations/ctools.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..4a92c0bb34354a865f21aefcf7be6a8ff71aeb50 --- /dev/null +++ b/sites/all/modules/ctools/translations/ctools.hu.po @@ -0,0 +1,2794 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-17 17:26+0000\n" +"PO-Revision-Date: 2009-12-14 17:28+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 "Home" +msgstr "Címlap" +msgid "Title" +msgstr "Cím" +msgid "Body" +msgstr "Törzs" +msgid "Pages" +msgstr "Oldalak" +msgid "context" +msgstr "környezet" +msgid "Status" +msgstr "Állapot" +msgid "Delete" +msgstr "Törlés" +msgid "Operations" +msgstr "Műveletek" +msgid "Value" +msgstr "Érték" +msgid "Type" +msgstr "Típus" +msgid "Author" +msgstr "Szerző" +msgid "List" +msgstr "Lista" +msgid "Cancel" +msgstr "Mégsem" +msgid "Description" +msgstr "Leírás" +msgid "Language" +msgstr "Nyelv" +msgid "Enable" +msgstr "Engedélyezés" +msgid "Disable" +msgstr "Letilt" +msgid "Access control" +msgstr "Hozzáférés szabályozás" +msgid "Disabled" +msgstr "Tiltott" +msgid "Enabled" +msgstr "Engedélyezett" +msgid "Comments" +msgstr "Hozzászólások" +msgid "Yes" +msgstr "Igen" +msgid "No" +msgstr "Nem" +msgid "Categories" +msgstr "Kategóriák" +msgid "Edit" +msgstr "Szerkesztés" +msgid "Search" +msgstr "Keresés" +msgid "Reset" +msgstr "Alaphelyzet" +msgid "None" +msgstr "Nincs" +msgid "Comment form" +msgstr "Hozzászólás űrlap" +msgid "User contact form" +msgstr "Felhasználói kapcsolatfelvételi űrlap" +msgid "Weight" +msgstr "Súly" +msgid "Admin title" +msgstr "Adminisztratív cím" +msgid "Related terms" +msgstr "Kapcsolódó kifejezések" +msgid "Depth" +msgstr "Mélység" +msgid "Category" +msgstr "Kategória" +msgid "Settings" +msgstr "Beállítások" +msgid "Name" +msgstr "Név" +msgid "Import" +msgstr "Import" +msgid "Export" +msgstr "Export" +msgid "Taxonomy term" +msgstr "Taxonómia kifejezés" +msgid "Back" +msgstr "Vissza" +msgid "Node ID" +msgstr "Tartalom azonosítója" +msgid "Label" +msgstr "Címke" +msgid "Save" +msgstr "Mentés" +msgid "Help" +msgstr "Súgó" +msgid "Default" +msgstr "Alapértelmezés" +msgid "Summary" +msgstr "Összegzés" +msgid "Update" +msgstr "Frissítés" +msgid "Views" +msgstr "Nézetek" +msgid "Access" +msgstr "Hozzáférés" +msgid "Add" +msgstr "Hozzáadás" +msgid "View" +msgstr "Megtekintés" +msgid "Path" +msgstr "Útvonal" +msgid "Vocabularies" +msgstr "Szótárak" +msgid "Display" +msgstr "Megjelenítés" +msgid "Node type" +msgstr "Tartalomtípus" +msgid "Menu" +msgstr "Menü" +msgid "results" +msgstr "találatok" +msgid "search" +msgstr "keresés" +msgid "Keywords" +msgstr "Kulcsszavak" +msgid "User" +msgstr "Felhasználó" +msgid "Continue" +msgstr "Folytatás" +msgid "Configure" +msgstr "Beállítás" +msgid "User ID" +msgstr "Felhasználó ID" +msgid "Error" +msgstr "Hiba" +msgid "Contact" +msgstr "Kapcsolat" +msgid "Node" +msgstr "Tartalom" +msgid "Node edit form" +msgstr "Tartalom szerkesztése űrlap" +msgid "Node add form" +msgstr "Tartalom hozzádása űrlap" +msgid "All" +msgstr "Minden" +msgid "Submit @name" +msgstr "@name beküldése" +msgid "Date format" +msgstr "Dátumformátum" +msgid "Page title" +msgstr "Oldal címe" +msgid "Block" +msgstr "Blokk" +msgid "Override title" +msgstr "Cím felülírása" +msgid "Pager ID" +msgstr "Lapozó azonosító" +msgid "Override URL" +msgstr "URL felülbírálása" +msgid "" +"If this is set, override the View URL; this can sometimes be useful to " +"set to the panel URL" +msgstr "" +"Ha ez be van kapocsolva, akkor felülírja a nézet webcímét. Néha " +"hasznos lehet a panel webcímére állítani." +msgid "Node links" +msgstr "Tartalom hivatkozások" +msgid "Taxonomy terms" +msgstr "Taxonómia kifejezések" +msgid "User picture" +msgstr "Felhasználó képe" +msgid "Breadcrumb" +msgstr "Menümorzsa" +msgid "Mission" +msgstr "Küldetés" +msgid "Custom" +msgstr "Egyedi" +msgid "Input format" +msgstr "Beviteli forma" +msgid "Node revision ID" +msgstr "A tartalom változatának azonosítója" +msgid "Vocabulary" +msgstr "Szótár" +msgid "Vocabulary ID" +msgstr "Szótárazonosító" +msgid "Term" +msgstr "Kifejezés" +msgid "Term ID" +msgstr "Kifejezés azonosító" +msgid "Term name" +msgstr "Kifejezés neve" +msgid "Overridden" +msgstr "Felülírva" +msgid "Mode" +msgstr "Mód" +msgid "Normal" +msgstr "Normál" +msgid "Advanced" +msgstr "Haladó" +msgid "Up" +msgstr "Fel" +msgid "System" +msgstr "Rendszer" +msgid "Terms" +msgstr "Kifejezések" +msgid "All views" +msgstr "Összes nézet" +msgid "Basic" +msgstr "Alap" +msgid "List type" +msgstr "Lista típusa" +msgid "Role" +msgstr "Csoport" +msgid "String" +msgstr "Karaktersorozat" +msgid "Exists" +msgstr "Létezik" +msgid "Argument" +msgstr "Argumentum" +msgid "Anonymous" +msgstr "Anonymous" +msgid "<All>" +msgstr "< Mind >" +msgid "Clone" +msgstr "Klónozás" +msgid "Normal menu item" +msgstr "Normál menüelem" +msgid "Down" +msgstr "Le" +msgid "Arguments" +msgstr "Argumentumok" +msgid "Order" +msgstr "Sorrend" +msgid "Add criteria" +msgstr "Jellemző hozzáadása" +msgid "Node: ID" +msgstr "Tartalom: azonosító" +msgid "Basic settings" +msgstr "Alapbeállítások" +msgid "Node template" +msgstr "Tartalomsablon" +msgid "Term description" +msgstr "A kifejezés leírása" +msgid "Child terms" +msgstr "Gyerek kifejezések" +msgid "Operation" +msgstr "Művelet" +msgid "Sort by" +msgstr "Rendezés" +msgid "Created date" +msgstr "Létrehozás dátuma" +msgid "Authoring information" +msgstr "Szerzői információk" +msgid "Some" +msgstr "Néhány" +msgid "Link to node" +msgstr "Hivatkozás tartalomra" +msgid "Change" +msgstr "Változtat" +msgid "Edit term" +msgstr "Kifejezés szerkesztése" +msgid "Feeds" +msgstr "Hírcsatornák" +msgid "Node title" +msgstr "Tartalom címe" +msgid "Node body" +msgstr "Tartalom törzse" +msgid "Search results" +msgstr "Találatok" +msgid "Your search yielded no results" +msgstr "Nincs találat." +msgid "unlimited" +msgstr "korlátlan" +msgid "Activity" +msgstr "Tevékenység" +msgid "Publishing options" +msgstr "Közzétételi beállítások" +msgid "First" +msgstr "Első" +msgid "Configure block" +msgstr "Blokk beállítása" +msgid "Second" +msgstr "Másodperc" +msgid "Fixed" +msgstr "Rögzített" +msgid "Revert" +msgstr "Visszaállítás" +msgid "Greater than" +msgstr "Nagyobb jel" +msgid "Open in new window" +msgstr "Megnyitás új ablakban" +msgid "All blogs" +msgstr "Minden blog" +msgid "Changed" +msgstr "Módosított" +msgid "User name" +msgstr "Felhasználónév" +msgid "Menu settings" +msgstr "Menübeállítások" +msgid "New" +msgstr "Új" +msgid "Relationships" +msgstr "Kapcsolatok" +msgid "Parent menu item" +msgstr "Szülő menüpont" +msgid "Loading..." +msgstr "Betöltés..." +msgid "Tabs" +msgstr "Fülek" +msgid "Storage" +msgstr "Tárolás" +msgid "Page name" +msgstr "Oldal neve" +msgid "Apply" +msgstr "Alkalmaz" +msgid "You must select a node." +msgstr "Ki kell választani egy tartalmat." +msgid "PHP Code" +msgstr "PHP kód" +msgid "Simple" +msgstr "Egyszerű" +msgid "Relationship type" +msgstr "Kapcsolattípus" +msgid "Menus" +msgstr "Menük" +msgid "Third" +msgstr "Harmadik" +msgid "Fourth" +msgstr "Negyedik" +msgid "Fifth" +msgstr "Ötödik" +msgid "Form" +msgstr "Űrlap" +msgid "Override path" +msgstr "Elérési út felülbírálása" +msgid "Permission" +msgstr "Jogosultság" +msgid "Edit this term" +msgstr "Kifejezés szerkesztése" +msgid "Contexts" +msgstr "Környezetek" +msgid "Loading" +msgstr "Betöltés" +msgid "Node author" +msgstr "Tartalom szerzője" +msgid "Miscellaneous" +msgstr "Egyéb" +msgid "Attach files" +msgstr "Fájlok csatolása" +msgid "Views panes" +msgstr "Views táblák" +msgid "by @user" +msgstr "@user által" +msgid "Argument type" +msgstr "Argumentumtípus" +msgid "Deleted/missing block @module-@delta" +msgstr "Törölt/hiányzó @module-@delta blokk" +msgid "New custom content" +msgstr "Új egyedi tartalom" +msgid "Create a completely custom piece of HTML content." +msgstr "Egy teljesen egyedi HTML tartalom létrehozása." +msgid "Context" +msgstr "Környezet" +msgid "General form" +msgstr "Általános űrlap" +msgid "Form goes here." +msgstr "Ide jön az űrlap." +msgid "\"@s\" base form" +msgstr "„@s” alap űrlap" +msgid "Node type description" +msgstr "Tartalom típusának leírása" +msgid "Attached files" +msgstr "Csatolt fájlok" +msgid "Attached files go here." +msgstr "Ide jönnek a csatolt fájlok." +msgid "A list of files attached to the node." +msgstr "Egy lista a tartalomhoz csatolt fájlokról." +msgid "\"@s\" attachments" +msgstr "„@s” csatolmány" +msgid "Book navigation" +msgstr "Könyv navigáció" +msgid "Book navigation goes here." +msgstr "Ide jön a könyv navigációja." +msgid "\"@s\" book navigation" +msgstr "„@s” könyv navigáció" +msgid "Add comment" +msgstr "Új hozzászólás" +msgid "Comment form here." +msgstr "Ide jön a hozzászólás űrlapja." +msgid "A form to add a new comment." +msgstr "Egy űrlap új hozzászólás hozzáadásához." +msgid "\"@s\" comment form" +msgstr "„@s” hozzászólás űrlap" +msgid "Node comments" +msgstr "Tartalom hozzászólásai" +msgid "Node comments go here." +msgstr "Ide jönnek a tartalom hozzászólásai." +msgid "The comments of the referenced node." +msgstr "A hivatkozott tartalom hozzászólásai." +msgid "Sort" +msgstr "Sorbarendezés" +msgid "!a comments per page" +msgstr "!a hozzászólás egy oldalon" +msgid "Pager" +msgstr "Lapozó" +msgid "\"@s\" comments" +msgstr "„@s” hozzászólásai" +msgid "Node content" +msgstr "Tartalom" +msgid "The content of the referenced node." +msgstr "A hivatkozott tartalom tartalma." +msgid "Node title." +msgstr "Tartalom címe." +msgid "Node content goes here." +msgstr "Ide jön a tartalom." +msgid "Edit node" +msgstr "Tartalom szerkesztése" +msgid "Edit this node" +msgstr "Ennek a tartalomnak a szerkesztése" +msgid "Link title to node" +msgstr "A cím hivatkozzon a tartalomra" +msgid "Check here to make the title link to the node." +msgstr "Bejelölve a cím a tartalomra fog hivatkozni." +msgid "No extras" +msgstr "Nincsenek extrák" +msgid "" +"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." +msgstr "" +"Bejelölve letiltja a modulok által a tartalomhoz biztosított olyan " +"kiegészítéseket, mint a csatolt fájlok és a CCK mezők; ez csak " +"az alap bevezetőt és törzset jeleníti meg." +msgid "Identifier" +msgstr "Azonosító" +msgid "\"@s\" content" +msgstr "„@s” tartalom" +msgid "Node form publishing options" +msgstr "Tartalom űrlap közzétételi beállítások" +msgid "Publishing options on the Node form." +msgstr "Közzétételi beállítások a tartalom űrlapon." +msgid "Node form author information" +msgstr "Tartalom űrlap szerzői információ" +msgid "Author information on the Node form." +msgstr "Szerzői információ a tartalom űrlapon." +msgid "Node form input format" +msgstr "Tartalom űrlap beviteli forma" +msgid "Input format for the body field on a node." +msgstr "A törzs mező beviteli formája egy tartalomban." +msgid "Node form comment settings" +msgstr "Tartalom űrlap hozzászólás beállítások" +msgid "Comment settings on the Node form." +msgstr "Hozzászólás beállítások a tartalom űrlapon." +msgid "Node form menu settings" +msgstr "Tartalom űrlap menü beállítások" +msgid "Node form file attachments" +msgstr "Tartalom űrlap csatolmányok" +msgid "File attachments on the Node form." +msgstr "Csatolmányok a tartalom űrlapon." +msgid "Node form categories" +msgstr "Tartalom űrlap kategóriák" +msgid "Taxonomy categories for the node." +msgstr "Taxonómia kategóriák a tartalomhoz." +msgid "Node form book options" +msgstr "Tartalom űrlap könyvvázlat beállítások" +msgid "Book options for the node." +msgstr "Könyvvázlat beállítások a tartalomhoz." +msgid "Publishing options." +msgstr "Közzétételi beállítások." +msgid "Comment options" +msgstr "Hozzászólás beállítások" +msgid "Comment options." +msgstr "Hozzászólás beállítások." +msgid "Authoring information." +msgstr "Szerzői információk." +msgid "Menu options" +msgstr "Menü beállítások" +msgid "Menu options." +msgstr "Menü beállítások." +msgid "URL path options" +msgstr "Webcímútvonal beállítások" +msgid "URL Path options." +msgstr "Webcímútvonal beállítások." +msgid "Attach files." +msgstr "Fájlok csatolása." +msgid "Categories." +msgstr "Kategóriák." +msgid "Book options" +msgstr "Könyvvázlat beállítások" +msgid "Book options." +msgstr "Könyvvázlat beállítások." +msgid "Input format." +msgstr "Beviteli forma." +msgid "\"@s\" @type" +msgstr "„@s” @type" +msgid "Node type description goes here." +msgstr "Ide jön a tartalom típusának leírása." +msgid "Node type description." +msgstr "Tartalom típusának leírása." +msgid "\"@s\" type description" +msgstr "„@s” típusleírás" +msgid "Profile content goes here." +msgstr "Ide jön a profil tartalma." +msgid "Which category" +msgstr "Melyik kategória" +msgid "" +"Text to display if category has no data. Note that title will not " +"display unless overridden." +msgstr "" +"A megjelenített szöveg, ha a kategória nem rendelkezik adattal. Meg " +"kell jegyezni, hogy a cím nem fog megjelenni felülírás nélkül." +msgid "\"@s\" profile fields" +msgstr "„@s” profilmezők" +msgid "Term description goes here." +msgstr "Ide jön a kifejezés leírása." +msgid "Term description." +msgstr "Kifejezés leírása." +msgid "\"@s\" term description" +msgstr "„@s” kifejezés leírása" +msgid "List of related terms" +msgstr "Kapcsolódó kifejezések listája" +msgid "" +"Terms related to an existing term; may be child, siblings or top " +"level." +msgstr "" +"Egy létező kifejezéshez kapcsolódó kifejezések. Lehet gyermek, " +"testvér vagy legfelső szintű." +msgid "Sibling terms" +msgstr "Testvér kifejezések" +msgid "Top level terms" +msgstr "Legfelső szintű kifejezés" +msgid "Term synonyms" +msgstr "Szinonimák" +msgid "Which terms" +msgstr "Mely kifejezések" +msgid "Unordered" +msgstr "Rendezetlen" +msgid "Ordered" +msgstr "Rendezett" +msgid "The picture of a user." +msgstr "Egy kép a felhasználóról." +msgid "\"@s\" user picture" +msgstr "„@s” felhasználó képe" +msgid "User profile" +msgstr "Felhasználói profil" +msgid "The profile of a user." +msgstr "Egy felhasználó profilja." +msgid "\"@s\" user profile" +msgstr "„@s” felhasználói profil" +msgid "Vocabulary terms" +msgstr "Szótárkifejezések" +msgid "All the terms in a vocabulary." +msgstr "Az összes kifejezés egy szótárban." +msgid "\"@s\" terms" +msgstr "„@s” kifejezés" +msgid "Maximum depth" +msgstr "Maximális mélység" +msgid "Define the maximum depth of terms being displayed." +msgstr "" +"A megjelenített kifejezések maximális mélységének " +"meghatározása." +msgid "Display as tree" +msgstr "Megjelenítés fa nézetben" +msgid "" +"If checked, the terms are displayed in a tree, otherwise in a flat " +"list." +msgstr "" +"Ha ez be van kapcsolva, akkor a kifejezések egy fában jelennek meg, " +"különben egy egyszerű listában." +msgid "A node object." +msgstr "Egy tartalom objektum." +msgid "Currently set to !link" +msgstr "Jelenlegi beállítás: !link" +msgid "Invalid node selected." +msgstr "Érvénytelen tartalom lett kiválasztva." +msgid "A node add form." +msgstr "Tartalom hozzádása űrlap" +msgid "Select the node type for this form." +msgstr "Tartalomtípus kiválasztása ehhez az űrlaphoz." +msgid "A node edit form." +msgstr "Egy tartalom szerkesztése űrlap" +msgid "A single taxonomy term object." +msgstr "Egy egyszerű taxonómia kifejezésobjektum." +msgid "A single user object." +msgstr "Egy egyszerű felhasználó objektum." +msgid "Taxonomy vocabulary" +msgstr "Taxonómiaszótár" +msgid "A single taxonomy vocabulary object." +msgstr "Egy egyszerű taxonómia szótár objektum." +msgid "Select the vocabulary for this form." +msgstr "Szótár kiválasztása ehhez az űrlaphoz." +msgid "argument" +msgstr "argumentum" +msgid "Add argument" +msgstr "Argumentum hozzáadása" +msgid "relationship" +msgstr "kapcsolat" +msgid "Add relationship" +msgstr "Kapcsolat hozzáadása" +msgid "Add context" +msgstr "Környezet hozzáadása" +msgid "Required contexts" +msgstr "Szükséges környezetek" +msgid "required context" +msgstr "szükséges környezet" +msgid "Add required context" +msgstr "Szükséges környezet hozzáadása" +msgid "Close Window" +msgstr "Ablak bezárása" +msgid "Close window" +msgstr "Ablak bezárása" +msgid "Add @type \"@context\"" +msgstr "@type „@context” hozzáadása" +msgid "Edit @type \"@context\"" +msgstr "@type @context\" szerkesztése" +msgid "Enter a name to identify this !type on administrative screens." +msgstr "" +"Név megadása, ami !type azonosítására szolgál az " +"adminisztrációs oldalakon." +msgid "Keyword" +msgstr "Kulcsszó" +msgid "Enter a keyword to use for substitution in titles." +msgstr "Címekben helyettesítéshez használt kulcsszó megadása." +msgid "Ignore it; content that requires this context will not be available." +msgstr "" +"Mellőzve; nem elérhető olyan tartalom, amelyhez ez a környezet " +"szükséges." +msgid "" +"If the argument is missing or is not valid, select how this should " +"behave." +msgstr "" +"Ki kell választani a működést, ha az argumentum hiányzik vagy nem " +"érvényes." +msgid "Argument @count" +msgstr "Argumentum @count" +msgid "Context @count" +msgstr "Környezet @count" +msgid "Configure !subtype_title" +msgstr "!subtype_title beállítása" +msgid "Unknown context" +msgstr "Ismeretlen környezet" +msgid "No context" +msgstr "Nincs környezet." +msgid "" +"You may use %keywords from contexts, as well as %title to contain the " +"original title." +msgstr "" +"%kulcsszavak használhatóak a környezetekből, továbbá %title " +"tartalmazza az eredeti címet." +msgid "Context %count" +msgstr "Környezet %count" +msgid "Module name" +msgstr "Modulnév" +msgid "Enter the module name to export code to." +msgstr "A modul nevének megadása amibe a kódot exportálni kell." +msgid "Local" +msgstr "Helyi" +msgid "Panel" +msgstr "Panel" +msgid "Add a node from your site as content." +msgstr "A webhely egy tarlamának hozzáadása tartalomként." +msgid "" +"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." +msgstr "" +"A webcímben található tartalomazonosító kinyeréséhez a %0, %1, " +"..., %N hasznáható, illetve @0, @1, @2, ..., @N a panelnak átadott " +"argumentumok használatához." +msgid "Leave node title" +msgstr "Tartalom címének meghagyása" +msgid "" +"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." +msgstr "" +"Haladó: ha be van jelölve, nem nyúl a tartalom címéhez; a cím " +"kétszer jelenhet meg, kivéve ha a smink gondoskodik erről." +msgid "Invalid node" +msgstr "Érvénytelen tartalom" +msgid "Node loaded from @var" +msgstr "A tartalom betöltve innen: @var" +msgid "Deleted/missing node @nid" +msgstr "Törölt/hiányzó tartalom @nid" +msgid "Path is required." +msgstr "Az elérési út megadása szükséges." +msgid "Argument wildcard" +msgstr "Argumentumot helyettesítő karakter" +msgid "No argument" +msgstr "Nincs argumentum" +msgid "From context" +msgstr "Környezetből" +msgid "From panel argument" +msgstr "Panel argumentumból" +msgid "Input on pane config" +msgstr "Bemenet a táblabeállításon" +msgid "Required context" +msgstr "Szükséges környezet" +msgid "Panel argument" +msgstr "Panel argumentum" +msgid "If \"From panel argument\" is selected, which panel argument to use." +msgstr "" +"Ha a „Panel argumentumból” van kiválasztva, akkor melyik panel " +"argumentum legyen felhasználva." +msgid "Sixth" +msgstr "Hatodik" +msgid "Fixed argument" +msgstr "Rögzített argumentum" +msgid "If \"Fixed\" is selected, what to use as an argument." +msgstr "" +"Ha a „Rögzített” van kiválasztva, akkor mi legyen " +"argumentumként felhasználva." +msgid "" +"If this argument is presented to the panels user, what label to apply " +"to it." +msgstr "" +"Ha ez az argumentum a panels felhasználónak szól, akkor milyen " +"címke legyen alkalmazva hozzá." +msgid "Use pager" +msgstr "Lapozó használata" +msgid "Offset" +msgstr "Eltolás" +msgid "Link to view" +msgstr "Hivatkozás a nézetre" +msgid "More link" +msgstr "Tovább hivatkozás" +msgid "Link title to view" +msgstr "A cím hivatkozzon a nézetre" +msgid "Provide a \"more\" link that links to the view" +msgstr "Egy, a nézetre hivatkozó „tovább” hivatkozást biztosít" +msgid "" +"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." +msgstr "" +"Ez független bármilyen, a nézet által biztosított tovább " +"hivatkozástól; ha két tovább hivatkozás jelenik meg, ezt ki kell " +"kapcsolni. A nézetek csak a „blokk” típus használatakor " +"biztosítanak tovább hivatkozást, azonban ha be van ágyazva, akkor " +"ezt kell használni." +msgid "Display feed icons" +msgstr "Hírolvasó ikon megjelenítése" +msgid "Num posts" +msgstr "Beküldések száma" +msgid "Send arguments" +msgstr "Argumentumok küldése" +msgid "Deleted/missing view @view" +msgstr "Törölt/hiányzó @view nézet" +msgid "Book parent" +msgstr "Szülő könyv" +msgid "Adds a book parent from a node context." +msgstr "Egy könyv szülőjének hozzáadása egy tartalomkörnyezetből." +msgid "Immediate parent" +msgstr "Közvetlen szülő" +msgid "Top level book" +msgstr "Legfelső szintű könyv" +msgid "Term from node" +msgstr "Kifejezés tartalomból" +msgid "" +"Adds a taxonomy term from a node context; if multiple terms are " +"selected, this will get the \"first\" term only." +msgstr "" +"Taxónomia kifejezés hozzáadása egy tartalomkörnyezetből. Ha " +"több kifejezés van kiválasztva, akkor csak az „elsőt” fogja " +"megjeleníteni." +msgid "Term parent" +msgstr "Kifejezés szülője" +msgid "Adds a taxonomy term parent from a term context." +msgstr "" +"Egy taxonómia kifejezés szülőjének hozzáadása egy " +"kifejezéskörnyezetből." +msgid "Top level term" +msgstr "Legfelső szintű kifejezés" +msgid "Machine name" +msgstr "Programok által olvasható név" +msgid "%keys (@type)." +msgstr "%keys (@type)." +msgid "Locked" +msgstr "Zárolt" +msgid "Finish" +msgstr "Befejezés" +msgid "" +"Validation error, please try again. If this error persists, please " +"contact the site administrator." +msgstr "" +"Helyesség ellenőrzési hiba. Kérjük próbálkozzon újra! " +"Amennyiben a hiba továbbra is fennáll, javasolt felvenni a " +"kapcsolatot a webhely gazdájával." +msgid "Create @name" +msgstr "@name beküldése" +msgid "Widgets" +msgstr "Felületi elemek" +msgid "Custom pages" +msgstr "Egyéni oldalak" +msgid "Simplecontext arg" +msgstr "<em>Simplecontext</em> argumentum" +msgid "Item1" +msgstr "Elem1" +msgid "The stuff for item 1." +msgstr "Valami az elem 1-hez." +msgid "Item2" +msgstr "Elem2" +msgid "Relcontext" +msgstr "Relcontext" +msgid "Simplecontext" +msgstr "Simplecontext" +msgid "A relcontext object." +msgstr "Egy relcontext objektum." +msgid "Adds a relcontext from existing simplecontext." +msgstr "Hozzáad egy relcontextet egy létező simplecontextből." +msgid "Page elements" +msgstr "Oldalelemek" +msgid "Variants" +msgstr "Változatok" +msgid "Author UID" +msgstr "Szerző felhasználói azonosítója" +msgid "Search type" +msgstr "Keresés típusa" +msgid "Tab weight" +msgstr "Fül súlya" +msgid "Site Slogan" +msgstr "Jelmondat" +msgid "User: ID" +msgstr "Felhasználó: azonosító" +msgid "Logged in user" +msgstr "Bejelentkezett felhasználó" +msgid "Chaos tool suite" +msgstr "Chaos tool suite" +msgid "The page has been deleted." +msgstr "Az oldal törölve lett." +msgid "Break lock" +msgstr "Zárolás feloldása" +msgid "Server reports invalid input error." +msgstr "A kiszolgáló érvénytelen bemenet hibát jelzett." +msgid "Default site language" +msgstr "A webhely alapértelmezett nyelve" +msgid "No language" +msgstr "Nincs nyelv" +msgid "Items per page" +msgstr "Elemek oldalanként" +msgid "No menu entry" +msgstr "Nincs menübejegyzés" +msgid "Normal menu entry" +msgstr "Normál menübejegyzés" +msgid "Menu tab" +msgstr "Menü fül" +msgid "Default menu tab" +msgstr "Alapértelmezett menü fül" +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "" +"Ha a beállítás normál vagy fül, meg kell adni a menüelemhez " +"használt szöveget." +msgid "" +"Warning: Changing this item's menu will not work reliably in Drupal " +"6.4 or earlier. Please upgrade your copy of Drupal at !url." +msgstr "" +"Figyelmeztetés: Az ehhez az elemhez tartozó menü módosítása nem " +"működik megbízhatóan a Drupal 6.4 vagy korábbi változatokban. " +"Frissíteni kell a Drupalt erről a helyről: !url." +msgid "Insert item into an available menu." +msgstr "Elem beillesztése egy rendelkezésre álló menübe." +msgid "Menu selection requires the activation of menu module." +msgstr "A menü kiválasztásához szükséges a menu modul engedélyezése." +msgid "The lower the weight the higher/further left it will appear." +msgstr "Minél kisebb a súly, annál magasabban/balrább fog megjelenni." +msgid "Already exists" +msgstr "Már létezik" +msgid "If creating a parent menu item, enter the title of the item." +msgstr "Szülő menüpont létrehozásakor meg kell adni a menüpont címét." +msgid "" +"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." +msgstr "" +"Ha a szülő menüpont egy fül, meg kell adni a fül súlyát. Minél " +"kisebb, annál balrább fog megjelenni." +msgid "Contact form" +msgstr "Kapcsolatfelvételi űrlap" +msgid "Equal" +msgstr "Egyenlő" +msgid "Search form" +msgstr "Keresés űrlap" +msgid "Less than or equal to" +msgstr "Kevesebb mint, vagy egyenlő" +msgid "CTools CSS Cache" +msgstr "CTools CSS gyorstár" +msgid "" +"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." +msgstr "" +"A CTools CSS gyorstárának könyvtára, %path nem hozható létre a " +"„files” könyvtár hibás beállítása miatt. Meg kell győződni " +"arról, hogy a „files” könyvtár helyesen van beállítva és a " +"webszervernek joga van azon belül könyvtárakat létrehozni." +msgid "Unable to create" +msgstr "Nem lehet létrehozni" +msgid "" +"A special cache used to store objects that are being edited; it serves " +"to save state in an ordinarily stateless environment." +msgstr "" +"A szerkesztés alatt álló objektumok tárolására használt " +"speciális gyorstár; állapotok mentésére szolgál egy általában " +"állapot nélküli környezetben." +msgid "Chaos tools" +msgstr "Chaos eszközök" +msgid "A library of helpful tools by Merlin of Chaos." +msgstr "Merlin of Chaos hasznos eszközeinek könyvtára." +msgid "Bulk export results" +msgstr "Tömeges export eredményei" +msgid "Place this in @file" +msgstr "Elhelyézés ide: @file" +msgid "There are no objects to be exported at this time." +msgstr "Jelenleg nincsenek exportált objektumok." +msgid "There are no objects in your system that may be exported at this time." +msgstr "" +"Jelenleg nincsenek olyan objektumok a rendszerben amiket exportálni " +"lehetne." +msgid "use bulk exporter" +msgstr "tömeges exportáló használata" +msgid "Bulk Exporter" +msgstr "Tömeges exportáló" +msgid "Bulk-export multiple CTools-handled data objects to code." +msgstr "Több CTools által kezelt adatobjektum tömeges exportálása kódba." +msgid "Bulk Export" +msgstr "Bulk Export" +msgid "Performs bulk exporting of data objects known about by Chaos tools." +msgstr "" +"A <em>Chaos tools</em> modul által ismert adatobjektumok tömeges " +"exportálása." +msgid "@type:@subtype will not display due to missing context" +msgstr "@type:@subtype nem fog megjelenni a hiányzó környezet miatt" +msgid "No info" +msgstr "Nincs információ" +msgid "No info available." +msgstr "Nincs elérhető információ." +msgid "Configure new !subtype_title" +msgstr "Új !subtype_title beállítása" +msgid "All criteria must pass." +msgstr "Minden feltételnek meg kell felelni." +msgid "Only one criteria must pass." +msgstr "Csak egy feltételnek kell megfelelni." +msgid "Broken/missing access plugin %plugin" +msgstr "Hibás/hiányzó %plugin hozzáférési beépülő" +msgid "Configure settings for this item." +msgstr "Az elem beállításainak szerkesztése." +msgid "Remove this item." +msgstr "Elem eltávolítása." +msgid "No criteria selected, this test will pass." +msgstr "Nincs kiválasztott feltétel, a teszt sikeres." +msgid "Missing callback hooks." +msgstr "Hiányzó callback hookok." +msgid "Edit criteria" +msgstr "Feltétel szerkesztése" +msgid "Invalid object name." +msgstr "Érvénytelen objektumnév." +msgid "Invalid context type" +msgstr "Érvénytelen környezettípus" +msgid "Display page not found or display nothing at all." +msgstr "Az oldal nem található vagy üres oldal megjelenítése." +msgid "" +"Enter a title to use when this argument is present. You may use " +"%KEYWORD substitution, where the keyword is specified below." +msgstr "" +"Az argumentum jelenlétekor használt cím megadása. Lehet %KULCSSZO " +"helyettesítést használni, az elérhető kulcsszavak lentebb " +"találhatóak." +msgid "Unable to delete missing item!" +msgstr "Hiányzó elemet nem lehet törölni!" +msgid "Edit @type" +msgstr "@type szerkesztése" +msgid "Summary of contexts" +msgstr "Környezetek összefoglalója" +msgid "Please choose which context and how you would like it converted." +msgstr "" +"Ki kell választani a környezetet és, hogy miként kell azt " +"konvertálni." +msgid "@identifier (@keyword)" +msgstr "@identifier (@keyword)" +msgid ", and " +msgstr ", és " +msgid ", or " +msgstr ", vagy " +msgid "Built in context" +msgstr "Beépített környezet" +msgid "Keyword: %@keyword" +msgstr "Kulcsszó: %@keyword" +msgid "@keyword --> @title" +msgstr "@keyword --> @title" +msgid "From \"@title\"" +msgstr "Ebből: „@title”" +msgid "" +"Unable to create CTools CSS cache directory. Check the permissions on " +"your files directory." +msgstr "" +"Nem lehet létrehozni a CTools CSS gyorsítár könyvtárat. " +"Ellenőrizni kell a files könyvtár jogosultságait." +msgid "Update and return" +msgstr "Frissítés és viszatérés" +msgid "In code" +msgstr "Kódban" +msgid "Enabled, title" +msgstr "Engedélyezett, cím" +msgid "Get a summary of the information about this page." +msgstr "Az oldalinformációk összefoglalója." +msgid "Activate this page so that it will be in use in your system." +msgstr "Az oldalt aktiválni kell, hogy a rendszerben használni lehessen." +msgid "" +"De-activate this page. The data will remain but the page will not be " +"in use on your system." +msgstr "" +"Oldal deaktiválása. Az adat megmarad, de az oldal nem lesz " +"használva a rendszerben." +msgid "Add variant" +msgstr "Változat hozzáadása" +msgid "Add a new variant to this page." +msgstr "Új változat hozzáadása az oldalhoz." +msgid "Create variant" +msgstr "Változat létrehozása" +msgid "Import variant" +msgstr "Változat importálása" +msgid "Add a new variant to this page from code exported from another page." +msgstr "" +"Új változat hozzáadása az oldalhoz egy másik oldalból exportált " +"kódból." +msgid "Reorder variants" +msgstr "Változatok újrarendezése" +msgid "" +"Change the priority of the variants to ensure that the right one gets " +"selected." +msgstr "" +"A változatok fontosságának módosítása, hogy biztosan a " +"megfelelő legyen kiválasztva." +msgid "" +"Configure a newly created variant prior to actually adding it to the " +"page." +msgstr "" +"Egy újonnan létrehozott változat hozzáadása azelőtt, hogy az " +"ténylegesen hozzá lenne adva az oldalhoz." +msgid "Break the lock on this page so that you can edit it." +msgstr "Az oldal zárolása meg lett szüntetve, így az már szerkeszthető." +msgid "Variant operations" +msgstr "Változatok műveletei" +msgid "Get a summary of the information about this variant." +msgstr "Változatinformációk összefoglalója." +msgid "Make an exact copy of this variant." +msgstr "A változat egy pontos másolatának létrehozása." +msgid "Export this variant into code to import into another page." +msgstr "" +"A változat kódjának egy másik oldalba importálható " +"exportálása." +msgid "Remove all changes to this variant and revert to the version in code." +msgstr "" +"A változat összes módosításának eltávolítása és " +"visszaállítása a kódban lévő változatra." +msgid "Remove this variant from the page completely." +msgstr "A változat teljes eltávolítása az oldalról." +msgid "Activate this variant so that it will be in use in your system." +msgstr "A változatot aktiválni kell, hogy a rendszerben használni lehessen." +msgid "" +"De-activate this variant. The data will remain but the variant will " +"not be in use on your system." +msgstr "" +"Változat deaktiválása. Az adat megmarad, de a változat nem lesz " +"használva a rendszerben." +msgid "No variants" +msgstr "Nincsenek változatok" +msgid "This operation trail does not exist." +msgstr "Ez a műveleti nyomvonal nem létezik." +msgid "" +"The page has been updated. Changes will not be permanent until you " +"save." +msgstr "" +"Az oldal frissítve lett. A változások nem véglegesek, amíg nincs " +"elmentve." +msgid "Unable to update changes due to lock." +msgstr "Zárolás miatt nem lehett frissíteni a módosításokat." +msgid "This setting contains unsaved changes." +msgstr "Ez a beállítás el nem mentett módosításokat tartalmaz." +msgid "" +"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." +msgstr "" +"Nem mentett módosítások vannak az oldalon. A „Mentés”-t kell " +"választani az adatbázisba íráshoz vagy a „Mégsem”-et a " +"módosítások eldobásához. Meg kell jegyezni, hogy az űrlapokat " +"módosítás után be kell küldeni a mentés előtt." +msgid "All pending changes have been discarded, and the page is now unlocked." +msgstr "" +"Minden függőben lévő módosítás el lett dobva és az oldal " +"zárolása fel lett oldva." +msgid "" +"Administrative title of this variant. If you leave blank it will be " +"automatically assigned." +msgstr "" +"A változat adminisztratív címe. Üresen hagyva automatikusan lesz " +"meghatározva." +msgid "Variant type" +msgstr "Változat típusa" +msgid "Optional features" +msgstr "Választható lehetőségek" +msgid "" +"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." +msgstr "" +"További választható lehetőségek beállítása, amik űrlapokkal " +"jelennek meg a beállításhoz. Ha itt nincsenek bejelölve, akkor is " +"lehet használni ezeket a lehetőségeket amint az új oldal " +"létrejött. Kétség esetén bejelöletlenül kell hagyni ezeket." +msgid "Variant name" +msgstr "Változat neve" +msgid "Enter the name of the new variant." +msgstr "Az új változat nevének megadása." +msgid "Paste variant code here" +msgstr "Változat kódjának beillesztése" +msgid "No variant found." +msgstr "Nincs változat." +msgid "Unable to get a variant from the import. Errors reported: @errors" +msgstr "" +"Nem lehet változatot létrehozni az importból. A jelentett hibák: " +"@errors" +msgid "" +"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." +msgstr "" +"A változat visszaállítása törli a változatot az adatbázisból, " +"visszaállítva az eredeti alapértelmezett változatot. A mentésre " +"kattintásig ez a törlés nem lesz végleges." +msgid "" +"Are you sure you want to delete this variant? This deletion will not " +"be made permanent until you click Save." +msgstr "" +"Biztosan törölhető ez a változat? A törlés a mentésre " +"kattintásig nem lesz véglegesítve." +msgid "" +"This variant is currently disabled. Enabling it will make it available " +"in your system. This will not take effect until you save this page." +msgstr "" +"Ez a változat jelenleg le van tiltva. Engedélyezése elérhetővé " +"teszi a rendszerben. Az oldal elmentése előtt nem lép érvénybe." +msgid "" +"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." +msgstr "" +"Ez a változat jelenleg engedélyezve van. A letiltása " +"elérhetetlenné teszi a rendszerben és nem lesz használva. Addig " +"nem lép érvénybe, amíg nincs az oldal elmentve." +msgid "" +"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?" +msgstr "" +"Az oldal zárolásának feloldása <strong>el fog dobni</strong> " +"minden, a zároló felhasználó által végrehajtott, függőben " +"lévő változást. VALÓBAN végrehajtható a feloldás?" +msgid "" +"The lock has been cleared and all changes discarded. You may now make " +"changes to this page." +msgstr "" +"A zárolás törölve lett és minden módosítás el lett dobva. Most " +"már lehet módosítani az oldalt." +msgid "" +"Enabling this page will immediately make it available in your system " +"(there is no need to wait for a save.)" +msgstr "" +"Az oldal engedélyezése azonnal elérhetővé teszi azt a rendszerben " +"(nincs szükség mentésre)." +msgid "" +"Disabling this page will immediately make it unavailable in your " +"system (there is no need to wait for a save.)" +msgstr "" +"Az oldal tiltása azonnal elérhetetlenné teszi azt a rendszerben " +"(nincs szükség mentésre)." +msgid "This page has no variants and thus no output of its own." +msgstr "Ennek az oldalnak nincsenek változatai, ezért nincs saját kimenete." +msgid "Add a new variant" +msgstr "Új változat hozzáadása" +msgid "Unable to disable due to lock." +msgstr "Zárolás miatt nem tiltható le." +msgid "Unable to enable due to lock." +msgstr "Zárolás miatt nem engedélyezhető." +msgid "use page manager" +msgstr "oldalkezelő használata" +msgid "administer page manager" +msgstr "oldalkezelő adminisztrációja" +msgid "" +"Add, edit and remove overridden system pages and user defined pages " +"from the system." +msgstr "" +"A rendszer felülírt rendszeroldalainak és a felhasználók által " +"meghatározott oldalaknak a hozzáadása, szerkesztése és " +"eltávolítása." +msgid "Page manager" +msgstr "Oldalkezelő" +msgid "Provides a UI and API to manage pages within the site." +msgstr "" +"Egy felhasználói-, és egy API felületet biztosít a webhelyen " +"belüli oldalak kezeléséshez." +msgid "Node add/edit form" +msgstr "Tartalom hozzáadása/szerkesztése űrlap" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a tartalmak <em>node/%node/edit</em> és " +"<em>node/add/%node_type</em> oldalakon történő hozzáadásakor vagy " +"szerkesztésekor. Ha lett változat hozzáadva, a tartalom típusa, " +"nyelve vagy a felhasználói hozzáférés kiválasztási feltételek " +"használhatóak arra, hogy eltérő szerkesztési űrlapok legyenek " +"biztosítva a tartalmakhoz. Ha nincs kiválasztott változat, az " +"alapértelmezett Drupal tartalomszerkesztés lesz használva." +msgid "Node being edited" +msgstr "Szerkesztett tartalom" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a tartalmak <em>node/%node</em> oldalon történő " +"megjelenítésekor. Ha lett változat hozzáadva, a tartalom típusa, " +"nyelve vagy a felhasználói hozzáférés kiválasztási feltételek " +"használhatóak arra, hogy eltérő megjelenítések legyenek " +"biztosítva a tartalmakhoz. Ha nincs kiválasztott változat, az " +"alapértelmezett Drupal tartalommegjelenítés lesz használva. Ennek " +"az oldalnak csak az oldalként megtekintett tartalmakra van hatása, " +"nincs hatása a listákban vagy más helyeken megtekintett oldalakra. " +"Továbbá meg kell jegyezni, hogy a pathauto használatakor, az " +"álnevek valahova máshova helyezhetik a tartalmat, de amennyire a " +"Drupal érintett, megtalálhatóak a node/%node oldalakon." +msgid "Node being viewed" +msgstr "Megtekintett tartalom" +msgid "Argument settings" +msgstr "Argumentum beállítások" +msgid "A meaningless second page" +msgstr "Egy lényegtelen második oldal" +msgid "Administrative title" +msgstr "Adminisztratív cím" +msgid "" +"The name of this page. This will appear in the administrative " +"interface to easily identify it." +msgstr "" +"Az oldal neve. Az adminisztratív felületen fog megjelenni a " +"könnyebb azonosíthatóság miatt." +msgid "" +"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!" +msgstr "" +"Az oldal egyedi, programok által olvasható neve. Csak betűket, " +"számokat és aláhúzást tartalmazhat. Ha egyszer létre lett hozva, " +"többé már nem lehet módosítani ezt az értéket!" +msgid "Administrative description" +msgstr "Adminisztratív leírás" +msgid "" +"A description of what this page is, does or is for, for administrative " +"use." +msgstr "Az oldal lehetőségeinek leírása adminisztratív használatra." +msgid "" +"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." +msgstr "" +"Az URL elérési út amin az oldal elérhető. Lehetőség van " +"nevesített helykitöltők használatára az elérési utak " +"változóihoz, a %név a szükséges elemekhez, a !név a nem " +"kötelező elemekhez használható. Például „node/%node/foo”, " +"„forum/%forum” vagy „dashboard/!input”. A nevesített " +"helykitöltők környezetekké válhatnak az argumentumok űrlapon." +msgid "Make this your site home page." +msgstr "Beállítás a webhely kezdőlapjaként." +msgid "This page is currently set to be your site home page." +msgstr "Ez az oldal jelenleg a webhely kezdőlapjaként van beállítva." +msgid "Visible menu item" +msgstr "Látható menüelem" +msgid "Name is required." +msgstr "A név megadása szükséges." +msgid "That name is used by another page: @page" +msgstr "Ezt a nevet egy másik oldal használja: @page" +msgid "Page name must be alphanumeric or underscores only." +msgstr "" +"Az oldal neve csak betűkből, számokból és aláhúzásból " +"állhat." +msgid "That path is used by another page: @page" +msgstr "Ezt az elérési utat egy másik oldal használja: @page" +msgid "You cannot have a dynamic path element after an optional path element." +msgstr "" +"Nem lehet egy dinamikus elérési út elem egy nem kötelező " +"elérési út elem után." +msgid "You cannot have a static path element after an optional path element." +msgstr "" +"Nem lehet egy statikus elérési út elem egy nem kötelező elérési " +"út elem után." +msgid "" +"That path is already in used. This system cannot override existing " +"paths." +msgstr "" +"Az elérési út már használatban van. Ez a rendszer nem tudja " +"felülírni a létező elérési utakat." +msgid "" +"That path is currently assigned to be an alias for @alias. This system " +"cannot override existing aliases." +msgstr "" +"Ez az elérési út jelenleg álnévként van rendelve ehhez: @alias. " +"Ez a rendszer nem tudja felülírni a létező álneveket." +msgid "" +"You cannot make this page your site home page if it uses % " +"placeholders." +msgstr "" +"Ez az oldal nem lehet a webhely kezdőlapja, ha % helykitöltőket " +"használ." +msgid "Duplicated argument %arg" +msgstr "%arg argumentum duplikálva van" +msgid "Invalid arg <em>%</em>. All arguments must be named with keywords." +msgstr "" +"Érvénytelen <em>%</em> argumentum. Minden argumentumot nevesíteni " +"kell kulcsszóval." +msgid "" +"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>." +msgstr "" +"Ha egy menüpont alpértelmezett fülként jelenik meg, a Drupalnak " +"tudnia kell, hogy mi lesz a fül szülő menüpontja. Néha a szülő " +"már létezik, de máskor létre kell hozni egyet. Egy szülőpont " +"elérési útja mindig ugyanaz az elérési út lesz, az utolsó rész " +"lehagyásával. Pl. ha ennek a nézetnek az elérési útja " +"<em>foo/bar/baz</em>, a szülő elérési út <em>foo/bar</em> lesz." +msgid "Parent item title" +msgstr "Szűlő menüpont címe" +msgid "Parent item menu" +msgstr "Szűlő menüpont menü" +msgid "" +"Access rules are used to test if the page is accessible and any menu " +"items associated with it are visible." +msgstr "" +"A hozzáférési szabályok alkalmazhatóak annak ellenőrzésére, " +"hogy az oldal hozzáférhető-e és a hozzá kapcsolódó menüpontok " +"láthatóak-e." +msgid "No context assigned" +msgstr "Nincs kijelölt környezet" +msgid "Position in path" +msgstr "Helyzet az elérési útban" +msgid "Context assigned" +msgstr "Hozzárendelt környezet" +msgid "The path %path has no arguments to configure." +msgstr "%path elérési útnak nincsenek beállítható argumentumai." +msgid "Invalid keyword." +msgstr "Érvénytelen kulcsszó." +msgid "Change context type" +msgstr "Környezettípus módosítása" +msgid "Change argument" +msgstr "Argumentum módosítása" +msgid "No context selected" +msgstr "Nincs kiválasztott környezet" +msgid "Error: missing argument." +msgstr "Hiba: hiányzó argumentum." +msgid "Context identifier" +msgstr "Környezet azonosítója" +msgid "" +"This is the title of the context used to identify it later in the " +"administrative process. This will never be shown to a user." +msgstr "" +"Ez a környezet neve, ami azonosításra szolgál a késöbbi " +"adminisztratív folyamatokban. Sosem fog megjelenni a " +"felhasználónak." +msgid "Error: missing or invalid argument plugin %argument." +msgstr "Hiba: hiányzó vagy érvénytelen %argument argumentum beépülő." +msgid "Import page" +msgstr "Import oldal" +msgid "" +"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." +msgstr "" +"Az oldalhoz használt név megadása, ha az eltér a " +"forrásoldalétól. Üresen hagyva az oldal eredeti neve lesz " +"használva." +msgid "" +"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." +msgstr "" +"Az oldalhoz használt elérési út megadása, ha az eltér a " +"forrásoldalétól. Üresen hagyva az oldal eredeti elérési útja " +"lesz használva." +msgid "Allow overwrite of an existing page" +msgstr "Engedélyezi egy létező oldal felülírását" +msgid "" +"If the name you selected already exists in the database, this page " +"will be allowed to overwrite the existing page." +msgstr "" +"Ha a választott név már szerepel az adatbázisban, ez az oldal " +"felülírhatja a létező oldalt." +msgid "Paste page code here" +msgstr "Oldal kódjának beillesztése" +msgid "No handler found." +msgstr "Nincs kezelő." +msgid "Unable to get a page from the import. Errors reported: @errors" +msgstr "Az importból nem lehet oldalt létrehozni. Jelentett hibák: @errors" +msgid "" +"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." +msgstr "" +"Ez az oldalnév használatban van és egy másik felhasználó " +"zárolta. Az oldalon fel kell <a href=\"!break\">oldani a " +"zárolást</a> a végrehajtás előtt, vagy egy eltérő nevet kell " +"választani." +msgid "" +"Enter the name to the new page It must be unique and contain only " +"alphanumeric characters and underscores." +msgstr "" +"Az új oldal neve. Egyedinek kell lennie és csak betűket, számokat " +"és aláhúzást tartalmazhat." +msgid "" +"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." +msgstr "" +"Az URL elérési út, amin az oldal elérhető. Lehetőség van " +"nevesített helykitöltők létrehozására az elérési utak " +"változóihoz, a szükséges elemekhez %név és a a nem kötelező " +"elemekhez !név használatával. Például: „node/%node/foo”, " +"„forum/%forum” vagy „dashboard/!input”. A nevesített " +"helykitöltők környezetekké válhatnak az argumentumok űrlapon. Az " +"elérési út nem egyezhet meg az eredeti oldal elérési útjával." +msgid "Clone variants" +msgstr "Változatok klónozása" +msgid "" +"If checked all variants associated with the page will be cloned as " +"well. If not checked the page will be cloned without variants." +msgstr "" +"Ha be van jelöle, az oldalhoz kapcsolt összes változat is másolva " +"lesz. Ha nincs bejelölve, az oldal változatok nélkül lesz " +"másolva." +msgid "" +"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." +msgstr "" +"Az oldal visszaállítása törli az oldalt az adatbázisból és " +"visszaállítja az eredeti alapértelmezett oldalt. Minden " +"változtatás el fog veszni és nem lesz visszaállítható." +msgid "" +"Are you sure you want to delete this page? Deleting a page cannot be " +"undone." +msgstr "" +"Biztosan törölhető az oldal? Az oldal törlése nem vonható " +"vissza." +msgid "The page has been reverted." +msgstr "Az oldal visszaállítása megtörtént." +msgid "" +"Administrator created pages that have a URL path, access control and " +"entries in the Drupal menu system." +msgstr "" +"Adminisztrátor által létrehozott oldalak, amikhez tartozhat " +"elérési út, hozzáférés szabályozás és bejegyzések a Drupal " +"menürendszerben." +msgid "Create a new page" +msgstr "Új oldal létrhozása" +msgid "Edit name, path and other basic settings for the page." +msgstr "" +"Az oldal nevének, elérési útjának és egyéb " +"alapbeállításainak szerkesztése." +msgid "Set up contexts for the arguments on this page." +msgstr "Környezetek beállítása az oldalon található argumentumokhoz." +msgid "Control what users can access this page." +msgstr "" +"Annak szabályozása, hogy mely felhasználók férhetnek hozzá ehhez " +"az oldalhoz." +msgid "Provide this page a visible menu or a menu tab." +msgstr "Egy látható menüt vagy menüfület biztosít az oldalhoz." +msgid "Make a copy of this page" +msgstr "Másolat készítése az oldalról" +msgid "" +"Export this page as code that can be imported or embedded into a " +"module." +msgstr "" +"Az oldal exportálása kódba, amit egy modulba lehet importálni vagy " +"ágyazni." +msgid "Remove all changes to this page and revert to the version in code." +msgstr "" +"Az oldal minden módosításának eltávolítása és " +"visszaállítása a kódban található verzióra." +msgid "Remove this page from your system completely." +msgstr "Az oldal teljes eltávolítása a rendszerből." +msgid "page-summary-label" +msgstr "page-summary-label" +msgid "page-summary-data" +msgstr "page-summary-data" +msgid "page-summary-operation" +msgstr "page-summary-operation" +msgid "This is your site home page." +msgstr "Ez a webhely kezdőlapja." +msgid "This page is set to become your site home page." +msgstr "Az oldal a webhely kezdőlapjának lett beállítva." +msgid "Accessible only if @conditions." +msgstr "Hozzáférés csak ha @conditions." +msgid "This page is publicly accessible." +msgstr "Ez az oldal nyivánosan elérhető." +msgid "No menu entry." +msgstr "Nincs menü bejegyzés." +msgid "Normal menu entry." +msgstr "Normál menü bejegyzés." +msgid "Menu tab." +msgstr "Menü fül." +msgid "Default menu tab." +msgstr "Alapértelmezett menü fül." +msgid "Title: %title." +msgstr "Cím: %title." +msgid "Parent title: %title." +msgstr "Szülő címe: %title." +msgid "Menu block: %title." +msgstr "Menüblokk: %title." +msgid "Taxonomy term template" +msgstr "Taxonómia kifejezés sablon" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a taxonómia kifejezések <em>taxonomy/term/%term</em> " +"oldalon történő megjelenítésekor. Ha lett változat hozzáadva, a " +"szótár vagy a felhasználói hozzáférés kiválasztási " +"feltételek használhatóak arra, hogy eltérő megjelenítések " +"legyenek biztosítva a taxonómia kifejezéshez és a kapcsolódó " +"tartalmakhoz. Ha nincs kiválasztott változat, az alapértelmezett " +"Drupal taxonómia kifejezés képernyő lesz használva. Ennek az " +"oldalnak csak a taxonomy/term/%term oldalon ténylegesen " +"megjelenített elemekre van hatása. Néhány taxonómia " +"kifejezésnek, mint amilyen a Fórumok, saját, máshol található " +"képernyőjük van. Továbbá meg kell jegyezni, hogy a pathauto " +"használatakor, az álnevek valahova máshova helyezhetik a taxonómia " +"kifejezéseket, de amennyire a Drupal érintett, megtalálhatóak a " +"taxonomy/term/%term oldalakon." +msgid "Update settings specific to the taxonomy term view." +msgstr "" +"Taxonómia kifejezés megtekintésére jellemző beállítások " +"frissítése." +msgid "Term(s) being viewed" +msgstr "Megtekintett kifejezések" +msgid "Term being viewed" +msgstr "Megtekintett kifejezés" +msgid "Allow multiple terms on taxonomy/term/%term" +msgstr "Több kifejezés engedélyezése itt: taxonomy/term/%term" +msgid "Single term" +msgstr "Egy kifejezés" +msgid "Multiple terms" +msgstr "Több kifejezés" +msgid "" +"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." +msgstr "" +"Alapértelmezés szerint a Drupal engedélyezi több kifejezés " +"argumentumként való használatát, vesszővel vagy összeadás " +"jellel elválasztva azokat. Ha ez egy kifejezésre van állítva, " +"akkor ez a lehetőség le lesz tiltva." +msgid "Inject hierarchy of first term into breadcrumb trail" +msgstr "Az első kifejezés hierarchiájának beillesztése a morzsasávba" +msgid "If checked, taxonomy term parents will appear in the breadcrumb trail." +msgstr "" +"Ha be van jelölve, akkor a taxonómia kifejezés szülői megjelennek " +"a morzsasávban." +msgid "Multiple terms may be used, separated by , or +." +msgstr "Több kifejezés is használható , vagy + jellel elválasztva." +msgid "Only a single term may be used." +msgstr "Csak egy kifejezést lehet használni." +msgid "%term" +msgstr "%term" +msgid "Breadcrumb trail will contain taxonomy term hierarchy" +msgstr "A morzsasáv taxonómia kifejezés hierarchiát fog tartalmazni." +msgid "Breadcrumb trail will not contain taxonomy term hiearchy." +msgstr "A morzsasáv taxonómia kifejezés hierarchiát nem fog tartalmazni." +msgid "User profile template" +msgstr "Felhasználói profil sablon" +msgid "" +"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." +msgstr "" +"Ha ez engedélyezett, akkor felülírja a Drupal alapértelmezett " +"viselkedését a felhasználói profilok megjelenítésekor a " +"<em>user/%user</em> oldalakon. Ha lett változat hozzáadva, akkor a " +"csoportok, vagy a felhasználói hozzáférés kiválasztási " +"feltételek használhatóak arra, hogy eltérő megjelenítések " +"legyenek biztosítva a felhasználói profilokhoz. Ha nincs " +"kiválasztott változat, akkor az alapértelmezés szerinti Drupal " +"felhasználó megtekintés lesz felhasználva. Továbbá meg kell " +"jegyezni, hogy a <em>Pathauto</em> használatakor, az álnevek " +"valahova máshova is helyezhetik a tartalmat, de ami a Drupalt illeti, " +"megtalálhatóak maradnak a user/%user oldalakon." +msgid "User being viewed" +msgstr "Megtekintett felhasználó" +msgid "" +"This page is being edited by another user and you cannot make changes " +"to it." +msgstr "" +"Az oldalt egy másik felhasználó szerkeszti, ezért nem lehet " +"módosítani." +msgid "" +"This page is newly created and has not yet been saved to the database. " +"It will not be available until you save it." +msgstr "" +"Ez az oldal újonnan lett létrehozva, ezért még nincs elmentve az " +"adatbázisba. Amíg ez meg nem történik, addig nem lesz elérhető." +msgid "" +"This page has been modified, but these modifications are not yet live. " +"While modifying this page, it is locked from modification by other " +"users." +msgstr "" +"Az oldal módosítva lett, de a módosítások még nem élnek. A " +"módosítás idejére ez az oldal zárolva lett más felhasználók " +"módosításai elől." +msgid "No task handlers are defined for this task." +msgstr "Ehhez a feladathoz nincsenek feladatkezelők meghatározva." +msgid "Variant" +msgstr "Változat" +msgid "" +"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>." +msgstr "" +"Ezt az oldalt !user felhasználó szerkeszti, ezért zárolva van " +"mások szerkesztése elől. A zárolás !age régi. Ide kattintva <a " +"href=\"!break\">feloldható a zárolás</a>." +msgid "User: compare" +msgstr "Felhasználó: összehasonlítás" +msgid "Compare two users (logged-in user and user being viewed, for example)" +msgstr "" +"Két felhasználó összehasonlítása (például: bejelentkezett " +"felhasználó és megtekintett felhasználó)" +msgid "First User" +msgstr "Első felhasználó" +msgid "Second User" +msgstr "Második felhasználó" +msgid "" +"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." +msgstr "" +"Hozzáférés biztosítása két felhasználó környezeteinek " +"összehasonlítása alapján. Például, ahhoz, hogy egy felhasználó " +"hozzáférhessen a saját profiljához, a „bejelentkezett " +"felhasználó”-t és a „megtekintett felhasználó”-t kell " +"választani valamint a hozzáférés biztosítását „egyenlő”-re " +"kell állítani." +msgid "Grant access if user contexts are" +msgstr "Hozzáférés biztosítása, ha a felhasználó környezetei" +msgid "Not equal" +msgstr "Nem egyenlő" +msgid "@id1 @comp @id2" +msgstr "@id1 @comp @id2" +msgid "Node: accessible" +msgstr "Tartalom: elérhető" +msgid "Control access with built in Drupal node access test." +msgstr "" +"Hozzáférés szabályozása a Drupal beépített " +"tartalomhozzáférés ellenőrzésével." +msgid "Create nodes of the same type" +msgstr "Tartalmak létrehozása ugyanabból a típusból" +msgid "" +"Using built in Drupal node access rules, determine if the user can " +"perform the selected operation on the node." +msgstr "" +"A Drupal beépített tartalom-hozzáférési szabályainak használata " +"annak meghatározására, hogy a felhasználó végrehajthatja-e a " +"kiválasztott műveletet a tartalmon." +msgid "@user can view @node." +msgstr "@user megtekintheti ezt: @node." +msgid "@user can edit @node." +msgstr "@user szerkesztheti ezt: @node." +msgid "@user can delete @node." +msgstr "@user törölheti ezt: @node." +msgid "@user can create nodes of the same type as @node." +msgstr "@user létrehozhat @node típusával megegyező típusú tartalmakat." +msgid "Node: language" +msgstr "Tartalom: nyelv" +msgid "Control access by node language." +msgstr "Hozzáférés szabályozása a tartalom nyelve alapján." +msgid "Current site language" +msgstr "A webhely jelenlegi nyelve" +msgid "Pass only if the node is in one of the selected languages." +msgstr "" +"Csak akkor sikeres, ha a tartalom az egyik kiválasztott nyelvet " +"használja." +msgid "@identifier is in any language" +msgstr "@identifier bármelyik nyelven lehet" +msgid "@identifier language is \"@languages\"" +msgid_plural "@identifier language is one of \"@languages\"" +msgstr[0] "@identifier nyelve „@languages”" +msgstr[1] "@identifier nyelve „@languages” egyike" +msgid "Node: type" +msgstr "Tartalom: típus" +msgid "Control access by node_type." +msgstr "Hozzáférés szabályozása tartalomtípus alapján." +msgid "Only the checked node types will be valid." +msgstr "Csak a bejelölt tartalomtípusok lesznek érvényesek." +msgid "@identifier is any node type" +msgstr "@identifier bármilyen tartalomtípus lehet" +msgid "@identifier is type \"@types\"" +msgid_plural "@identifier type is one of \"@types\"" +msgstr[0] "@identifie típusa „@types”" +msgstr[1] "@identifier típusa „@types” egyike" +msgid "User: permission" +msgstr "Felhasználó: jogosultságok" +msgid "Control access by permission string." +msgstr "Hozzáférés szabályozása jogosultsági kifejezés alapján." +msgid "" +"Only users with the selected permission flag will be able to access " +"this." +msgstr "" +"Csak a kiválasztott jogosultsági jelzővel rendelkező " +"felhasználók fogják tudni elérni." +msgid "Error, unset permission" +msgstr "Hiba, nem beállított jogosultság" +msgid "@identifier has \"@perm\"" +msgstr "@identifier jogosultságai: „@perm”" +msgid "Control access through arbitrary PHP code." +msgstr "Hozzáférés szabályozása tetszés szerinti PHP kód alapján." +msgid "Administrative desc" +msgstr "Adminisztratív leírás" +msgid "A description for this test for administrative purposes." +msgstr "Az ellenőrzés adminisztratív célú leírása." +msgid "" +"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." +msgstr "" +"A hozzáférés meg lesz adva, ha a következő PHP kód " +"<code>IGAZ</code> értékkel tér vissza. Nem szabad használni a " +"<?php ?>-t. Meg kell említeni, hogy a hibás PHP kód az " +"tönkreteheti a Drupal webhelyet. Minden környezet elérhető a " +"<em>$contexts</em> változóban." +msgid "You do not have sufficient permissions to edit PHP code." +msgstr "Nincs elegendő jog a PHP kód szerkesztéséhez." +msgid "User: role" +msgstr "Felhasználó: csoport" +msgid "Control access by role." +msgstr "Hozzáférés szabályozása csoport alapján." +msgid "Only the checked roles will be granted access." +msgstr "Csak a bejelölt csoportok kapnak hozzáférési jogot." +msgid "@identifier can have any role" +msgstr "@identifier bármelyik csoportban lehet" +msgid "@identifier has role \"@roles\"" +msgid_plural "@identifier has one of \"@roles\"" +msgstr[0] "@identifier „@roles” csoport tagja" +msgstr[1] "@identifier „@roles” csoportok egyikének a tagja" +msgid "User: language" +msgstr "Felhasználó: nyelv" +msgid "Control access by the language the user or site currently uses." +msgstr "" +"A hozzáférés szabályozása a felhasználó vagy a webhely által " +"jelenleg használt nyelv alapján." +msgid "" +"Pass only if the current site language is one of the selected " +"languages." +msgstr "" +"Csak akkor sikeres, ha a webhely jelenlegi nyelve egyike a " +"kiválasztott nyelveknek." +msgid "Site language is any language" +msgstr "Az oldal nyelve bármelyik nyelv." +msgid "Site language is \"@languages\"" +msgid_plural "Site language is one of \"@languages\"" +msgstr[0] "A webhely nyelve „@languages”" +msgstr[1] "A webhely nyelve „@languages” nyelvek egyike" +msgid "Taxonomy: vocabulary" +msgstr "Taxonómia: szótár" +msgid "Control access by term vocabulary." +msgstr "Hozzáférés szabályozása szótár kifejezés által." +msgid "Only terms in the checked vocabularies will be valid." +msgstr "Csak a kijelölt szótárak kifejezései lesznek érvényesek." +msgid "@identifier is any vocabulary" +msgstr "@identifier bármelyik szótár" +msgid "@identifier vocabulary is \"@vids\"" +msgid_plural "@identifier vocabulary is one of \"@vids\"" +msgstr[0] "@identifier szótára „@vids”" +msgstr[1] "@identifier szótára „@vids” egyike" +msgid "Creates a node context from a node ID argument." +msgstr "" +"Tartalomkörnyezet létrehozása egy tartalomazonosító " +"argumentumból." +msgid "Enter the node ID of a node for this argument" +msgstr "Egy tartalom azonosítójának megadása ehhez az argumentumhoz" +msgid "Creates a node add form context from a node type argument." +msgstr "" +"Tartalom hozzáadása űrlap létrehozása egy tartalomtípus " +"argumentumból." +msgid "Creates a node edit form context from a node ID argument." +msgstr "" +"Tartalom szerkesztése űrlap létrehozása egy node ID " +"argumentumból." +msgid "" +"A string is a minimal context that simply holds a string that can be " +"used for some other purpose." +msgstr "" +"A kifejezés egy egyszerű környezet ami más célokra használható " +"kifejezést tartalmaz." +msgid "Enter a value for this argument" +msgstr "Argumentum értékének megadása" +msgid "" +"Creates a single taxonomy term from a taxonomy ID or taxonomy term " +"name." +msgstr "" +"Egy egyszerű taxonómia kifejezés létrehozása egy " +"kifejezésazonosítóból vagy egy kifejezés nevéből." +msgid "Inject hierarchy into breadcrumb trail" +msgstr "Hierarchia beillesztése a morzsasávba." +msgid "Enter a taxonomy term ID." +msgstr "Kifejezés azonosítójának megadása." +msgid "Enter a taxonomy term name." +msgstr "Kifejezés nevének megadása." +msgid "" +"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." +msgstr "" +"Taxonómia kifejezések csopotjának létrehozása egy " +"kifejezésazonosító listából, vesszővel vagy összeadás jellel " +"elválasztva. Általában a lista első kifejezése lesz használva a " +"táblában." +msgid "Enter a term ID or a list of term IDs separated by a + or a ," +msgstr "" +"Egy vagy több kifejezésazonosító listájának megadása, „+” " +"vagy „,” jellel elválasztva." +msgid "Creates a user context from a user ID argument." +msgstr "" +"Felhasználói környezet hoz létre egy felhasználói azonosító " +"argumentumból." +msgid "Enter the user ID of a user for this argument" +msgstr "A felhasználó azonosítójának megadása ehhez az argumentumhoz." +msgid "Creates a vocabulary context from a vocabulary ID argument." +msgstr "" +"Egy szótár környezet hoz létre egy szótárazonosíŧó " +"argumentumból." +msgid "Enter the vocabulary ID for this argument" +msgstr "Szótárazonosító megadása ehhez az argumentumhoz." +msgid "" +"Configure this block's 'block settings' in administer >> site building " +">> blocks" +msgstr "" +"Ennek a blokknak a beállításait az Adminisztráció\r\n" +" >> Webhelyépítés >> Blokkok oldalon lehet módosítani" +msgid "Use context keywords" +msgstr "Környezetkulcsszavak használata" +msgid "If checked, context keywords will be substituted in this content." +msgstr "" +"Ha be van jelölve, a környezetkulcsszavak behelyettesíthetőek " +"lesznek ebbe a tartalomba." +msgid "Substitutions" +msgstr "Helyettesítések" +msgid "@identifier: @title" +msgstr "@identifier: @title" +msgid "Everything in the form that is not displayed by other content." +msgstr "Minden az űrlapon, amit más környezetek nem jelenítenek meg." +msgid "The author of the referenced node." +msgstr "A hivatkozott tartalom szerzője." +msgid "Link to author profile" +msgstr "Hivatkozás a szerző profiljára" +msgid "Check here to link to the node author profile." +msgstr "" +"Be kell jelölni a tartalom szerzőjének profiljára történő " +"hivatkozáshoz." +msgid "\"@s\" author" +msgstr "„@s” szerző" +msgid "The body of the referenced node." +msgstr "A hivatkozott tartalom törzse." +msgid "\"@s\" body" +msgstr "„@s” törzs" +msgid "The navigation menu the book the node belongs to." +msgstr "A tartalomhoz tartozó könyv navigációs menü." +msgid "Node created date" +msgstr "Tartalom létrehozásának dátuma" +msgid "The date the referenced node was created." +msgstr "Az a dátum amikor a hivatkozott tartalom létrejött." +msgid "\"@s\" created date" +msgstr "„@s” létrehozás dátuma" +msgid "Node links of the referenced node." +msgstr "A hivatkozott tartalom tartalomhivatkozásai." +msgid "Node links go here." +msgstr "Ide jönnek a tartalom hivatkozások." +msgid "Teaser mode" +msgstr "Bevezető mód" +msgid "Check here to show links in teaser mode." +msgstr "" +"Be kell jelölni, hogy a hivatkozások megjelenjenek előnézeti " +"módban." +msgid "" +"Whatever is placed here will appear in $node->panel_identifier to help " +"theme node links displayed on the panel" +msgstr "" +"Bármi kerül ide, meg fog jelenni a $node->panel_identifier " +"változóban, hogy segítse a smink tartalomhivatkozásainak " +"megjelenítését a panelen." +msgid "\"@s\" links" +msgstr "„@s” hivatkozás" +msgid "The title of the referenced node." +msgstr "A hivatkozott tartalom címe." +msgid "\"@s\" title" +msgstr "„@s” cím" +msgid "Node last updated date" +msgstr "Tartalom utolsó frissítésének dátuma" +msgid "The date the referenced node was last updated." +msgstr "Az a dátum amikor a hivatkozott tartalom utoljára frissítve lett." +msgid "Last updated date" +msgstr "Utolsó frissítés dátuma" +msgid "\"@s\" last updated date" +msgstr "„@s” utolsó módosításának dátuma" +msgid "node_form" +msgstr "node_form" +msgid "\"@s\" node form attach files" +msgstr "„@s” tartalom űrlap csatolmányai" +msgid "\"@s\" node form publishing options" +msgstr "„@s” tartalom űrlap közzétételi beállítások" +msgid "\"@s\" node form book options" +msgstr "„@s” tartalom űrlap könyvvázlat beállítások" +msgid "Node form submit buttons" +msgstr "Tartalom űrlap beküldési nyomógombok" +msgid "Submit buttons for the node form." +msgstr "Beküldési nyomógombok a tartalom űrlaphoz." +msgid "Node form buttons." +msgstr "Tartalom űrlap nyomógombok." +msgid "\"@s\" node form submit buttons" +msgstr "„@s” tartalom űrlap beküldési nyomógombok" +msgid "\"@s\" node form comment settings" +msgstr "„@s” tartalom űrlap hozzászólás beállítások" +msgid "\"@s\" node form input format" +msgstr "„@s” tartalom űrlap beviteli forma" +msgid "Node form revision log message" +msgstr "Tartalom űrlap változatinformáció üzenet" +msgid "Revision log message for the node." +msgstr "Változatinformáció üzenet a tartalomhoz." +msgid "\"@s\" node form revision log" +msgstr "„@s” tartalom űrlap változatinformáció" +msgid "Menu settings on the Node form." +msgstr "Menü beállítások a tartalom űrlapon." +msgid "\"@s\" node form menu settings" +msgstr "„@s” tartalom űrlap menü beállítások" +msgid "Node form url path settings" +msgstr "Tartalom űrlap webcímútvonal beállítások" +msgid "\"@s\" node form path options" +msgstr "„@s” tartalom űrlap útvonal beállítások" +msgid "\"@s\" node form author information" +msgstr "„@s” tartalom űrlap szerzői információk" +msgid "\"@s\" node form select taxonomy" +msgstr "„@s” tartalom űrlap taxonómia kiválasztása" +msgid "Profile category" +msgstr "Profil kategóriája" +msgid "Contents of a single profile category." +msgstr "Egy egyszerű profilkategória tartalmai." +msgid "Enter the node ID of a node for this context." +msgstr "Egy tartalom azonosítójának megadása ehhez a környezethez." +msgid "'%title' [node id %nid]" +msgstr "'%title' [tartalomazonosító %nid]" +msgid "Reset identifier to node title" +msgstr "Azonosító visszaállítása a tartalom címére" +msgid "" +"If checked, the identifier will be reset to the node title of the " +"selected node." +msgstr "" +"Ha be van jelölve, akkor az azonosító a kiválasztott tartalom " +"címére lesz visszaállítva." +msgid "Enter the node type this context." +msgstr "Tartalomtípus megadása ehhez a környezethez." +msgid "Enter the node ID of a node for this argument:" +msgstr "Egy tartalom azonosítójának megadása ehhez az argumentumhoz:" +msgid "A context that is just a string." +msgstr "A környezet azaz csak egy kifejezés." +msgid "Raw string" +msgstr "Nyers karaktersorozat" +msgid "Enter the string for this context." +msgstr "Kifejezés megadása ehhez a környezethez." +msgid "" +"Currently set to @term. Enter another term if you wish to change the " +"term." +msgstr "" +"Currently set to @term. Enter another term if you wish to change the " +"term." +msgid "Select a term from @vocabulary." +msgstr "Kifejezés kiválasztása @vocabulary szótárból." +msgid "Reset identifier to term title" +msgstr "Azonosító visszaállítása a kifejezés címére." +msgid "" +"If checked, the identifier will be reset to the term name of the " +"selected term." +msgstr "" +"Ha be van jelölve, Az azonosító vissza lesz állítva a " +"kiválasztott kifejezés kifejezés nevére." +msgid "You must select a term." +msgstr "Ki kell választani egy kifejezést." +msgid "Invalid term selected." +msgstr "Érvénytelen a kiválasztott kifejezés." +msgid "Multiple taxonomy terms, as a group." +msgstr "Több taxonómia kifejezés, csoportként." +msgid "Term ID of first term" +msgstr "Az első kifejezés azonosítója" +msgid "Term ID of all term, separated by + or ," +msgstr "" +"Az összes kifejezés azonosítója „+” vagy „,” jellel " +"elválasztva" +msgid "Term name of first term" +msgstr "Az első kifejezés kifejezésneve" +msgid "Term name of all terms, separated by + or ," +msgstr "" +"Kifejezésnév minden kifejezéshez, „+” vagy „,” jellel " +"elválasztva." +msgid "Vocabulary ID of first term" +msgstr "Az első kifejezés szótárazonosítója" +msgid "Creates the author of a node as a user context." +msgstr "" +"Egy tartalom szerzőjének létrehozása felhasználói " +"környezetként." +msgid "Make all views available as panes" +msgstr "Legyen minden nézet elérhető táblaként" +msgid "" +"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." +msgstr "" +"Ha be van jelölve, minden nézet elérhető lesz tartalomtípusokhoz " +"hozzáadható tartalomtáblaként. Ha nincs bejelölve, csak a " +"„Tartalomtábla” megjelenítéssel rendelkező nézetek lesznek " +"elérhetőek tartalomtáblaként. Kikapcsolva gondosabban " +"szabályozható, hogy mely nézet tartalma lesz elérhető a panelek " +"elrendezési felületét használók számára." +msgid "Configure Views to be used as CTools content." +msgstr "Nézetek beállítása Ctools tartalomként történő használatra." +msgid "Views content panes" +msgstr "Views tartalomtáblák" +msgid "" +"Allows Views content to be used in Panels, Dashboard and other modules " +"which use the CTools Content API." +msgstr "" +"Engedélyezi a Views tartalmak használatát a Panels, a Dashboard és " +"egyéb, a CTools Content API-t használó modulokban." +msgid "Select display" +msgstr "Képernyő kiválasztása" +msgid "Configure view" +msgstr "Nézet beállítása" +msgid "Choose which display of this view you wish to use." +msgstr "A nézet használni kívánt képernyőjének kiválasztása." +msgid "Broken/missing/deleted view." +msgstr "Hibás/hiányzó/törölt nézet." +msgid "Configure view @view (@display)" +msgstr "@view (@display) nézet beállítása" +msgid "View: @name" +msgstr "Nézet: @name" +msgid "View information" +msgstr "Nézet adatai" +msgid "Using display @display." +msgstr "@display képernyő használata." +msgid "Argument @arg using context @context converted into @converter" +msgstr "" +"@context környezet által használt @arg argumentum konvertálva lett " +"ebbe: @converter" +msgid "@count items displayed." +msgstr "@count elem lett megjelenítve." +msgid "With pager." +msgstr "Lapozóval." +msgid "Without pager." +msgstr "Lapozó nélkül." +msgid "Skipping first @count results" +msgstr "Első @count eredmény átugrása" +msgid "With more link." +msgstr "Tovább hivatkozással." +msgid "With feed icon." +msgstr "Hírforrás ikonnal." +msgid "Sending arguments." +msgstr "Argumentumok küldése." +msgid "Using arguments: @args" +msgstr "Használt argumentumok: @args" +msgid "Using url: @url" +msgstr "Használt url: @url" +msgid "View panes" +msgstr "Nézettáblák" +msgid "Link title to page" +msgstr "A cím hivatkozzon az oldalra" +msgid "Provide a \"more\" link." +msgstr "Egy „tovább” hivatkozás biztosítása." +msgid "Num items" +msgstr "Elemek száma" +msgid "Select the number of items to display, or 0 to display all results." +msgstr "" +"A megjelenített elemek száma, vagy 0 az összes eredmény " +"megjelenítéséhez." +msgid "Enter the number of items to skip; enter 0 to skip no items." +msgstr "Az átugrott elemek száma; a 0 nem ugrik át elemet." +msgid "" +"If this is set, override the View URL path; this can sometimes be " +"useful to set to the panel URL." +msgstr "" +"Ha be van állítva, felülírja a nézet URL elérési útját; néha " +"hasznos lehet a panel URL címére beállítani." +msgid "Content pane" +msgstr "Tartalomtábla" +msgid "Is available as content for a panel or dashboard display." +msgstr "" +"Tartalomként elérhető egy panel, vagy egy irányítópult " +"képernyő számára." +msgid "Pane settings" +msgstr "Tábla beállítások" +msgid "Use view name" +msgstr "Nézetnév használata" +msgid "Use view description" +msgstr "Nézetleírás használata" +msgid "Admin desc" +msgstr "Adminisztratív leírás" +msgid "Use Panel path" +msgstr "Panel elérési út használata" +msgid "Argument input" +msgstr "Argumentum bemenet" +msgid "Allow settings" +msgstr "Beállítások engedélyezése" +msgid "" +"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." +msgstr "" +"A bejelölt beállítások elérhetőek lesznek a panel " +"táblabeállítás párbeszédablakában, ahol a panels felhasználó " +"módosítani tudja azokat. A be nem jelölt beállítások nem lesznek " +"elérhetőek, továbbá a beállítások csak ebben a képernyőben " +"lesznek használva." +msgid "Pager offset" +msgstr "Lapozó eltolása" +msgid "Path override" +msgstr "Elérési út felülbírálása" +msgid "Title override" +msgstr "Cím felülírása" +msgid "" +"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." +msgstr "" +"Ez az a cím, ami ebben a nézettáblában a tartalom hozzáadása " +"párbeszédablakban fog megjelenni. Üresen hagyva a nézet neve lesz " +"használva." +msgid "" +"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." +msgstr "" +"Ez a szöveg akkor fog megjelenni, amikor a felhasználó az egeret a " +"tartalom hozzáadása párbeszédablakban a tábla fölé viszi. " +"Üresen hagyva a nézet leírása lesz használva." +msgid "This is category the pane will appear in on the add content dialog." +msgstr "" +"Ez az a kategória, amiben a tábla megjelenik a tartalom hozzáadása " +"párbeszédablakban." +msgid "" +"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." +msgstr "" +"A kategória alapértelmezett súlya. Meg kell jegyezni, hogy ha a " +"kategória súlya több helyen is be van állítva, akkor csak az " +"első panelek fogják megkapni ezt a beállítást, vagyis ha a súly " +"nem tűnik működőnek, le kell ellenőrizni azokat a helyeket ahol a " +"súly be lett állítva." +msgid "Link pane title to view" +msgstr "A tábla címe hivatkozzon a nézetre" +msgid "Inherit path from panel display" +msgstr "Panel képernyőről örökölt elérési út" +msgid "" +"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." +msgstr "" +"Ha igen, minden a Views által létrehozott tovább, összefoglaló " +"és felfedett bemenet hivatkozás a panelek elérési útjába kerül " +"és nem a nézetébe, amennyiben a megjelenítésnek van elérési " +"útja." +msgid "Choose the data source for view arguments" +msgstr "Nézetargumentumok adatforrásának kiválasztása" +msgid "@arg source" +msgstr "@arg forrás" +msgid "" +"Demonstration code, advanced help, and a demo panel to show how to " +"build ctools plugins." +msgstr "" +"Bemutató kód, haladó segítség és egy demó panel annak " +"bemutatására, hogy miként lehet ctools beépülőket építeni." +msgid "" +"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." +msgstr "" +"A CTools Plugin Example egyszerűen egy fejlesztői bemutató arról, " +"hogy miként lehet beépülőket létrehozni CTools-hoz. Hétköznapi " +"felhasználónak nem nyújt semmilyen hasznos funkciót." +msgid "" +"There is a demo panel demonstrating much of the functionality provided " +"at\n" +" <a href=\"@demo_url\">CTools demo panel</a>, and you can find " +"documentation on the examples at\n" +" !ctools_plugin_example_help.\n" +" CTools itself provides documentation at !ctools_help. Mostly, " +"though, the code itself is intended to be the teacher.\n" +" You can find it in %path." +msgstr "" +"Ez egy demó panel a <a href=\"@demo_url\">CTools bemutató panel</a> " +"által biztosított funkciók többségének bemutatására,\r\n" +" dokumentáció a !ctools_plugin_example_help oldalon " +"található.\r\n" +" Magának a CTools-nak a dokumentációja a !ctools_help oldalon " +"található. Többnyire, mert inkább magának a kódnak a feladata, " +"hogy magyarázó legyen.\r\n" +" Megtalálható itt: %path." +msgid "CTools plugin example" +msgstr "<em>CTools</em> beépülő példa" +msgid "Chaos Tools (CTools) Plugin Example" +msgstr "<em>Chaos Tools</em> (<em>CTools</em>) beépülő példa" +msgid "" +"Shows how an external module can provide ctools plugins (for Panels, " +"etc.)." +msgstr "" +"Bemutatja, hogy egy külső modul miként biztosíthat <em>CTools</em> " +"beépülőket (például a <em>Panels</em> modulhoz, stb...)." +msgid "Arg length" +msgstr "Argumentum hossza" +msgid "Control access by length of simplecontext argument." +msgstr "" +"Hozzáférés szabályozása a <em>simplecontext</em> argumentum " +"hossza által." +msgid "Grant access if simplecontext argument length is" +msgstr "Hozzáférés biztosítása, ha a simplecontext argumentum hossza" +msgid "Length of simplecontext argument" +msgstr "A <em>simplecontext</em> argumentum hossza" +msgid "Access/visibility will be granted based on arg length." +msgstr "" +"Hozzáférés/láthatóság biztosítva lesz az argumentum hossza " +"alapján." +msgid "Simpletext argument must be !comp @length characters" +msgstr "Simpletext argumentumnak !comp @length karakternek kell lennie" +msgid "CTools example: role" +msgstr "A <em>CTools</em> példa: csoport" +msgid "@identifier must have role \"@roles\"" +msgid_plural "@identifier can be one of \"@roles\"" +msgstr[0] "@identifier „@roles” csoport tagja kell legyen" +msgstr[1] "@identifier „@roles” csoportok egyikének tagja kell legyen" +msgid "Creates a \"simplecontext\" from the arg." +msgstr "Egy <em>simplecontext</em> létrehozása az argumentumból." +msgid "Enter the simplecontext arg" +msgstr "Ssimplecontext argumentum megadása" +msgid "CTools example no context content type" +msgstr "CTools példa környezetnélküli tartalomtípusra" +msgid "No context content type - requires and uses no context." +msgstr "" +"Környezetnélküli tartalomtípus - nem szükséges hozzá és nem " +"használ környezetet." +msgid "CTools Examples" +msgstr "CTools példák" +msgid "The setting for item 1." +msgstr "Elem 1 beállításai" +msgid "The setting for item 2" +msgstr "Elem 2 beállításai" +msgid "CTools example relcontext content type" +msgstr "CTools példa relcontext tartalomtípusra" +msgid "Relcontext content type - works with relcontext context." +msgstr "Relcontext tartalomtípus - a relcontext környezettel működik." +msgid "Config Item 1 (relcontext)" +msgstr "Elem 1 beállítása (relcontext)" +msgid "Setting for relcontext." +msgstr "Relcontext beállítása" +msgid "Simplecontext content type" +msgstr "Simplecontext tartalomtípus" +msgid "Simplecontext content type - works with a simplecontext context." +msgstr "Simplecontext tartalomtípus - simplecontext környezetben működik." +msgid "Config Item 1 for simplecontext content type" +msgstr "Elem 1 beállítása a simplecontext tartalomtípushoz" +msgid "Relcontext context from simplecontext" +msgstr "Relcontext környezet simplecontextből" +msgid "Relcontext setting" +msgstr "Relcontext beállítás" +msgid "Just an example setting." +msgstr "Csak egy példa beállítás." +msgid "A single \"simplecontext\" context, or data element." +msgstr "Egy egyszerű „simplecontext” környezet vagy adatelem." +msgid "Enter some data to represent this \"simplecontext\"." +msgstr "Ezt a „simplecontext”-et képviselő néhány adat megadása." +msgid "Simplecontext context from config" +msgstr "Simplecontext környezet a beállításokból" +msgid "Setting for simplecontext" +msgstr "Simplecontext beállítása" +msgid "An example setting that could be used to configure a context" +msgstr "" +"Egy példa beállítás, ami a környezet beállításához " +"használható" +msgid "Relcontext from simplecontext" +msgstr "Relcontext simplecontextből" +msgid "" +"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." +msgstr "" +"Ha egynél több változat van az oldalon, az oldal meglátogatásakor " +"minden változatnak lehetősége van megjelenni. Az első " +"változattól kezdve egészen az utolsóig mindegyik ellenőrizve " +"lesz, hogy megfelel-e a kiválasztási szabályoknak. Az első " +"változat ami megfelel a feltételnek (ahogy az fentebb meg lett " +"határozva) lesz használva." +msgid "See the getting started guide for more information." +msgstr "A Kezdeti segítség útmutató megtekintése a részletekért." +msgid "" +"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." +msgstr "" +"A változat hozzáadása előtt ezt be kell állítani. A " +"befejezésekor a „Változat létrehozása” gombra kattintás " +"befejezi a varázslót és hozzáadja a változatot az oldalhoz." +msgid "" +"Page manager module is unable to enable node/%node/edit because some " +"other module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a " +"node/%node/edit elérési utat, mert néhány másik modul már " +"felülírta %callback segítségével." +msgid "" +"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." +msgstr "" +"A Page manager modul nem tudja felülírni a %path elérési utat, " +"mert néhány másik modul már felülírta %callback-el. A tartalom " +"szerkesztés engedélyezve lesz, de a szerkesztés elérési útja nem " +"lesz felülírva." +msgid "" +"Page manager module is unable to enable node/%node because some other " +"module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a node/%node " +"elérési utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "" +"To set this panel as your home page you must create a unique path name " +"with no % placeholders in the path. The current site home page is set " +"to %homepage." +msgstr "" +"Annak beállításához, hogy ez a panel legyen a kezdőlap, egy " +"egyedi elérési utat kell létrehozni és ebben nem szabad % " +"helykitöltőket használni. A webhely jelenlegi kezdőlapjának " +"beállítása %homepage." +msgid "" +"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." +msgstr "" +"A nem kötelező helykitöltőkkel rendelkező elérési utak nem " +"használhatóak normál menüpontkét, kivéve ha a kiválasztott " +"argumentumkezelő biztosít egy menüelemként használható " +"alapértelmezett argumentumot." +msgid "" +"Page manager module is unable to enable taxonomy/term/%term because " +"some other module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a " +"taxonomy/term/%term elérési utat, mert néhány másik modul már " +"felülírta %callback segítségével." +msgid "" +"Page manager module is unable to enable user/%user because some other " +"module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a user/%user " +"elérési utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "Existing node" +msgstr "Létező tartalom" +msgid "Enter the title or NID of a node" +msgstr "Egy tartalom címének vagy tartalomazonosítójának megadása" +msgid "Show only node teaser" +msgstr "Csak a tartalom bevezetőjének mutatása" +msgid "Include node links for \"add comment\", \"read more\" etc." +msgstr "" +"„Új hozzászólás”, „Tovább”, stb., tartalomhivatkozások " +"hozzáadása." +msgid "Template identifier" +msgstr "Sablonazonosító" +msgid "" +"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." +msgstr "" +"Ez az azonosító a tartalmat megjelenítő sablonjavaslataként lesz " +"hozzáadva: node-panel-IDENTIFIER.tpl.php. A sablonjavaslatokról " +"részletesen a Drupal smink kézikönyvben lehet olvasni." +msgid "Treat this as the primary node page" +msgstr "Elsődleges tartalomoldalként kezelés" +msgid "This can affect title rendering and breadcrumbs from some node types." +msgstr "" +"Befolyásolhatja néhány tartalomtípusnál a cím létrehozását " +"és a morzsát." +msgid "Add the breadcrumb trail as content." +msgstr "A morzsasáv hozzáadása tartalomként." +msgid "Add the help text of the current page as content." +msgstr "Az aktuális oldal súgószövegének hozzáadása tartalomként." +msgid "Status messages" +msgstr "Állapotüzenetek" +msgid "Add the status messages of the current page as content." +msgstr "Az aktuális oldal állapotüzeneteinek hozzáadása tartalomként." +msgid "Add the site mission statement as content." +msgstr "A webhely céljainak hozzáadása tartalomként." +msgid "Add the slogan trail as content." +msgstr "A jelmondat sáv hozzáadása tartalomként." +msgid "Add the tabs (local tasks) as content." +msgstr "A fülek (helyi feladatok) hozzáadása tartalomként." +msgid "Add the page title as content." +msgstr "Az oldal címének hozzáadása tartalomként." +msgid "" +"\n" +" This is a block of data created by the Relcontent content type.\n" +" Data in the block may be assembled from static text (like this) or " +"from the\n" +" content type settings form ($conf) for the content type, or from " +"the context\n" +" that is passed in. <br />\n" +" In our case, the configuration form ($conf) has just one field, " +"'config_item_1;\n" +" and it's configured with:\n" +" " +msgstr "" +"\n" +" Ez egy adatblokk, amit a Relcontent tartalomtípus hozott " +"létre.\r\n" +" A blokk adatainak összeállítása történhet statikus " +"szövegekből (mint ez)\r\n" +" vagy a tartalomtípus beállításainak űrlapjából ($conf), " +"esetleg a beállított\r\n" +" környezetből. <br />\r\n" +" Jelen esetben a beállítási űrlapon ($conf) csak egy mező van, " +"'config_item_1;\r\n" +" ezzel lett beállítva:\n" +" " +msgid "" +"\n" +" This is a block of data created by the Simplecontext content " +"type.\n" +" Data in the block may be assembled from static text (like this) or " +"from the\n" +" content type settings form ($conf) for the content type, or from " +"the context\n" +" that is passed in. <br />\n" +" In our case, the configuration form ($conf) has just one field, " +"'config_item_1;\n" +" and it's configured with:\n" +" " +msgstr "" +"\n" +" Ez egy adatblokk, amit a Simplecontext tartalomtípus hozott " +"létre.\r\n" +" A blokk adatainak összeállítása történhet statikus " +"szövegekből (mint ez)\r\n" +" vagy a tartalomtípus beállításainak űrlapjából ($conf), " +"esetleg a beállított\r\n" +" környezetből. <br />\r\n" +" Jelen esetben a beállítási űrlapon ($conf) csak egy mező van, " +"'config_item_1;\r\n" +" ezzel lett beállítva:\n" +" " +msgid "" +"This page is currently locked for editing by you. Nobody else may edit " +"this page until these changes are saved or canceled." +msgstr "" +"Ez az oldal jelenleg zárolva van mert ön szerkeszti. Senki más nem " +"szerkesztheti ezt az oldalt, a módosítások mentése vagy " +"visszavonása előtt." +msgid "" +"This page is currently locked for editing by another user. You may not " +"edit this page without breaking the lock." +msgstr "" +"Ez az oldal jelenleg zárolva van, mert egy másik felhasználó " +"szerkeszti. A zárolás feloldása előtt nem szerkeszthető az oldal." +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a blogok <em>/blog</em> oldalon történő " +"megjelenítésekor. Ha nincs kiválasztott változat, az " +"alapértelmezett Drupal legfrissebb blogbejegyzések oldal fog " +"megjelenni." +msgid "" +"Page manager module is unable to enable blog because some other module " +"already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a blog elérési " +"utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "User blog" +msgstr "Felhasználói blog" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a felhasználói blogok <em>/blog/%user</em> oldalon " +"történő megjelenítésekor. Ha nincs kiválasztott változat, az " +"alapértelmezett Drupal felhasználói blog oldal lesz használva." +msgid "" +"Page manager module is unable to enable blog/%user because some other " +"module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a blog/%user " +"elérési utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "Site contact page" +msgstr "Webhely kapcsolat oldal" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a kapcsolatfelvételi oldal <em>/contact</em> oldalon " +"történő megjelenítésekor. Ha nincs kiválasztott változat, az " +"alapértelmezett Drupal kapcsolatfelvételi űrlap lesz használva." +msgid "" +"Page manager module is unable to enable contact because some other " +"module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a contact " +"elérési utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "User contact" +msgstr "Felhasználói kapcsolat" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, akkor felülírja a Drupal alapértelmezett " +"viselkedését a felhasználói kapcsolatfelvételi űrlap " +"<em>user/%user/contact</em> oldalon történő megjelenítésekor. Ha " +"nincs kiválasztott változat, akkor az alapértelmezés szerinti " +"Drupal felhasználói kapcsolatfelvételi űrlap lesz használva." +msgid "" +"Page manager module is unable to enable user/%user/contact because " +"some other module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a /%user/contact " +"elérési utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "" +"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." +msgstr "" +"Nem lehetnek nem nevesített helykitöltők (% vagy ! magában). El " +"kell nevezni a helykitöltőt a % vagy a ! után álló rövid leíró " +"szöveggel, például %user vagy %node." +msgid "All polls" +msgstr "Minden szavazás" +msgid "" +"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." +msgstr "" +"Ha engedélyezett, felülírja a Drupal alapértelmezett " +"viselkedését a szavazások <em>/poll</em> oldalon történő " +"megjelenítésekor. Ha nincs kiválasztott változat, akkor a " +"legutóbbi szavazások lesznek megjelenítve." +msgid "" +"Page manager module is unable to enable poll because some other module " +"already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a poll elérési " +"utat, mert néhány másik modul már felülírta %callback " +"segítségével." +msgid "" +"Page manager module is unable to enable search/@name/%menu_tail " +"because some other module already has overridden with %callback." +msgstr "" +"A <em>Page manager</em> modul nem tudja engedélyezni a " +"search/@name/%menu_tail elérési utat, mert néhány másik modul " +"már felülírta %callback segítségével." +msgid "Search @type" +msgstr "@type keresése" +msgid "Taxonomy: term" +msgstr "Taxonómia: kifejezés" +msgid "Control access by a specific term." +msgstr "Hozzáférés szabályozása meghatározott kifejezés alapján." +msgid "Select a term or terms from @vocabulary." +msgstr "Egy vagy több kifejezés kiválasztása @vocabulary szótárból." +msgid "@term can be the term \"@terms\"" +msgid_plural "@term can be one of these terms: @terms" +msgstr[0] "@term lehet „@terms”" +msgstr[1] "@term ezen kifejezések egyike lehet: @terms" +msgid "Node add form: node type" +msgstr "Tartalom hozzáadása űrlap: tartalomtípus" +msgid "Node edit form: node ID" +msgstr "Tartalom szerkesztése űrlap: tartalomazonosító" +msgid "Get all arguments after this one" +msgstr "Összes argumentum elhelyezése ez után" +msgid "" +"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\"." +msgstr "" +"Ha be van jelölve, ez a karaktersorozat minden argumentumot " +"tartalmazni fog. Például ha az elérési út „path/%” és a " +"felhasználó meglátogatja a „path/foo/bar” oldalt, akkor ha " +"nincs bejelölve, a karaktersorozat „foo” lesz. Ha be van jelölve " +"a karaktersorozat „foo/bar” lesz." +msgid "Taxonomy term: ID" +msgstr "Taxonómia kifejezés: ID" +msgid "Taxonomy term (multiple): ID" +msgstr "Taxonómia kifejezés (több): azonosító" +msgid "User: name" +msgstr "Felhasználó: név" +msgid "Creates a user context from a user name." +msgstr "Felhasználói környezet létrehozása egy felhasználói névből." +msgid "Enter the username of a user for this argument" +msgstr "" +"Egy felhasználó felhasználónevének megadása ehhez az " +"argumentumhoz." +msgid "Vocabulary: ID" +msgstr "Szótár: azonosító" +msgid "" +"The site contact form that allows users to send a message to site " +"administrators." +msgstr "" +"A webhely kapcsolatfelvételi űrlapja, amely lehetővé teszi, hogy a " +"felhasználók üzenetet küldjenek a webhely adminisztrátorainak." +msgid "The site contact form that allows users to contact other users." +msgstr "" +"A webhely kapcsolatfelvételi űrlapja, amely lehetővé teszi, hogy a " +"felhasználók felvegyék a kapcsolatot más felhasználókkal." +msgid "Contact @name" +msgstr "Kapcsolatfelvétel @name felhasználóval" +msgid "Custom: @title" +msgstr "Egyedi: @title" +msgid "" +"This title will be used administratively to identify this pane. If " +"blank, the regular title will be used." +msgstr "" +"A cím adminisztratív célból lesz használva a tábla " +"azonosításához. Ha üres, akkor a rendes cím lesz használva." +msgid "Page footer message" +msgstr "Oldal lábléc üzenete" +msgid "Add the page footer message as content." +msgstr "Az oldal láblécüzenetének hozzáadása tartalomként." +msgid "Advanced search form" +msgstr "Haladó keresés űrlap" +msgid "A search form with advanced options." +msgstr "Egy keresés űrlap haladó beállításokkal." +msgid "" +"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." +msgstr "" +"A haladó űrlap további beállításokat biztosíthat a keresés " +"típusa alapján. Például a haladó tartalom(node) keresés űrlap " +"engedélyezi a tartalomtípus és a taxonómia kifejezés szerinti " +"keresést." +msgid "Same page" +msgstr "Ugyanolyan oldal" +msgid "Override default prompt" +msgstr "Alapértelmezett készenléti jel felülírása" +msgid "@type search form" +msgstr "@type keresési űrlap" +msgid "The results of a search using keywords." +msgstr "A kucsszavakat használó keresés eredményei." +msgid "Record a watchdog log entry when searches are made" +msgstr "Keresés feljegyzése az eseménynaplóba" +msgid "Override \"no result\" text" +msgstr "„Nincs eredmény” szöveg felülbírálata" +msgid "No result text" +msgstr "Nincs eredmény szövege" +msgid "Display text if no search keywords were submitted" +msgstr "A megjelenített szöveg, ha nem lett keresési kulcsszó megadva" +msgid "No keywords text" +msgstr "Nincs kulcsszó szöveg" +msgid "@type search result" +msgstr "@type keresési eredmény" +msgid "HTML-safe string" +msgstr "HTML-biztos karaktersorozat" +msgid "Custom pager settings" +msgstr "Egyéni lapozó beállításai" +msgid "Use different pager settings from view settings" +msgstr "" +"A lapozó eltérő beállításainak használata a nézet " +"beállításai alapján" +msgid "" +"<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." +msgstr "" +"<strong>Figyelmeztetés</strong>: ez a nézet AJAX-ot használ. A " +"lapozó beállítások felülírása kezdetben működni fog, de ahogy " +"a nézet frissítve lesz AJAX-on keresztül, az eredeti beállítások " +"lesznek használva. Nem kell felülírni a lapozó beállításokat " +"azokban a nézetekben, ahol az AJAX beállítások engedélyezve " +"vannak." +msgid "The number of items to skip and not display." +msgstr "Az átugrott és nem mutatott elemek száma." +msgid "" +"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." +msgstr "" +"Kiválasztva a panel összes argumentuma át lesz küldve " +"közvetlenül a nézetnek. Ha be van jelölve, a panel argumentumok a " +"környezet argumentumok után következnek és megelőznek bármilyen " +"további, a lenti Argumentumok mezőn keresztül átadott " +"argumentumot. Meg kell jegyezni, hogy az argumentumok nem " +"tartalmazzák az alap URL-t; csak az URL utáni vagy a " +"helykitöltőkkel beállított értékek lesznek argumentumként " +"figyelembe véve." +msgid "" +"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." +msgstr "" +"További, az URL részeként arg1/arg2/arg3 formában a nézetnek " +"küldött argumentumok. %0, %1, ..., %N használható az argumentumok " +"kinyerésére az URL-ből. Vagy @0, @1, @2, ..., @N használható a " +"panelben átadott argumentunokhoz. Megjegyzés: csak a legutolsó " +"megoldásként használható. A Panels következő verzióiban ezek " +"már nem lesznek benne." +msgid "If \"From context\" is selected, which type of context to use." +msgstr "" +"A „Környezetből” kiválasztása esetén melyik környezettípus " +"legyen használva." +msgid "Context is optional" +msgstr "A környezet nem kötelező" +msgid "" +"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." +msgstr "" +"Ennek a környezetnek jelen kell lennie a tábla működéséhez. Ha " +"szükség van a használatára, meg kell győződni róla, hogy az " +"argumentumkezelő tudja elegánsan kezelni az üres értékeket." diff --git a/sites/all/modules/ctools/translations/ctools.pot b/sites/all/modules/ctools/translations/ctools.pot new file mode 100644 index 0000000000000000000000000000000000000000..a1f663a34530c87175521f92404daa1484eb83e6 --- /dev/null +++ b/sites/all/modules/ctools/translations/ctools.pot @@ -0,0 +1,3850 @@ +# $Id: ctools.pot,v 1.2 2009/10/22 20:00:00 thomaszahreddin Exp $ +# +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# ctools.install,v 1.12 2009/08/16 21:59:42 merlinofchaos +# ctools.info,v 1.3 2009/07/12 18:11:58 merlinofchaos +# bulk_export.info,v 1.2 2009/07/12 18:11:58 merlinofchaos +# ctools_plugin_example/ctools_plugin_example.info: n/a +# page_manager.info,v 1.2 2009/07/12 18:11:58 merlinofchaos +# views_content.info,v 1.2 2009/07/12 18:11:59 merlinofchaos +# bulk_export.module,v 1.3 2009/07/22 21:12:07 merlinofchaos +# page_manager.admin.inc,v 1.27.2.4 2009/10/15 18:37:54 merlinofchaos +# page.inc,v 1.17.2.1 2009/10/09 22:35:56 merlinofchaos +# ctools_plugin_example.module,v 1.1 2009/08/17 22:07:14 merlinofchaos +# arg_length.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# simplecontext_content_type.inc,v 1.1.2.1 2009/10/13 20:55:30 merlinofchaos +# simplecontext.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# relcontext_from_simplecontext.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# example_role.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# role.inc,v 1.7.2.1 2009/10/01 22:00:08 merlinofchaos +# node_access.inc,v 1.7.2.1 2009/10/01 22:00:08 merlinofchaos +# perm.inc,v 1.6.2.1 2009/10/01 22:00:08 merlinofchaos +# user_contact.inc,v 1.1.2.1 2009/10/12 23:17:18 merlinofchaos +# profile_fields.inc,v 1.4 2009/08/13 22:24:02 merlinofchaos +# user_picture.inc,v 1.3 2009/08/05 18:11:05 merlinofchaos +# user_profile.inc,v 1.7 2009/09/08 21:25:04 merlinofchaos +# user.inc,v 1.4.2.1 2009/10/01 22:00:08 merlinofchaos +# simplecontext_arg.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# no_context_content_type.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# relcontext_content_type.inc,v 1.1.2.1 2009/10/13 20:55:30 merlinofchaos +# relcontext.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# ajax.inc,v 1.14.2.1 2009/10/01 21:34:36 merlinofchaos +# content.inc,v 1.12.2.3 2009/10/21 21:25:39 merlinofchaos +# content.menu.inc,v 1.2 2009/07/09 16:54:29 merlinofchaos +# node_author.inc,v 1.1 2009/07/18 22:10:48 merlinofchaos +# context-access-admin.inc,v 1.7 2009/08/16 21:59:42 merlinofchaos +# context-admin.inc,v 1.9.2.1 2009/10/06 18:08:23 merlinofchaos +# page.admin.inc,v 1.18.2.2 2009/10/13 20:38:17 merlinofchaos +# custom.inc,v 1.9.2.2 2009/10/06 17:42:07 merlinofchaos +# search_result.inc,v 1.1.2.2 2009/10/12 21:39:24 merlinofchaos +# views.inc,v 1.11.2.3 2009/10/21 20:18:09 merlinofchaos +# node_links.inc,v 1.2 2009/08/05 16:54:51 sdboyer +# export.inc,v 1.19.2.2 2009/10/08 16:12:17 merlinofchaos +# page_manager.module,v 1.17.2.2 2009/10/09 22:35:56 merlinofchaos +# search_form.inc,v 1.1.2.1 2009/10/12 21:35:54 merlinofchaos +# context-task-handler.inc,v 1.23.2.2 2009/10/01 22:26:30 merlinofchaos +# context.inc,v 1.33.2.4 2009/10/09 22:35:55 merlinofchaos +# context.theme.inc,v 1.7.2.1 2009/10/13 20:55:30 merlinofchaos +# page_manager/theme/page_manager.theme.inc: n/a +# views_content_plugin_display_panel_pane.inc,v 1.3 2009/09/09 18:25:03 merlinofchaos +# css.inc,v 1.10.2.1 2009/10/08 16:12:17 merlinofchaos +# form.inc,v 1.11 2009/08/13 22:24:02 merlinofchaos +# menu.inc,v 1.4 2009/07/12 05:28:31 merlinofchaos +# modal.inc,v 1.7.2.1 2009/10/13 20:06:36 merlinofchaos +# modal.js,v 1.17.2.2 2009/10/13 20:06:36 merlinofchaos +# wizard.inc,v 1.12 2009/09/08 21:44:52 merlinofchaos +# term_view.inc,v 1.5 2009/08/04 21:43:06 merlinofchaos +# search.inc,v 1.1.2.1 2009/10/12 21:35:54 merlinofchaos +# page_manager.install,v 1.7 2009/07/12 11:32:30 sdboyer +# blog.inc,v 1.1.2.1 2009/10/13 18:10:37 merlinofchaos +# blog_user.inc,v 1.1.2.2 2009/10/13 18:12:20 merlinofchaos +# contact_user.inc,v 1.1.2.2 2009/10/13 18:10:37 merlinofchaos +# user_view.inc,v 1.3 2009/08/04 21:43:06 merlinofchaos +# contact_site.inc,v 1.1.2.1 2009/10/12 23:17:18 merlinofchaos +# node_edit.inc,v 1.3 2009/08/04 21:43:06 merlinofchaos +# node_view.inc,v 1.4 2009/08/04 21:43:06 merlinofchaos +# node.inc,v 1.6 2009/08/18 04:36:53 merlinofchaos +# poll.inc,v 1.1.2.2 2009/10/13 18:27:42 merlinofchaos +# terms.inc,v 1.3.2.2 2009/10/01 22:39:02 merlinofchaos +# term.inc,v 1.6.2.2 2009/10/01 22:39:02 merlinofchaos +# page_breadcrumb.inc,v 1.1 2009/08/17 21:23:13 merlinofchaos +# compare_users.inc,v 1.3.2.1 2009/10/01 22:00:08 merlinofchaos +# node_language.inc,v 1.7.2.1 2009/10/01 22:00:08 merlinofchaos +# node_type.inc,v 1.7.2.1 2009/10/01 22:00:08 merlinofchaos +# node_attachments.inc,v 1.1 2009/04/18 02:00:34 merlinofchaos +# node_body.inc,v 1.2 2009/07/22 21:40:31 merlinofchaos +# node_book_nav.inc,v 1.1 2009/04/18 02:00:34 merlinofchaos +# node_comment_form.inc,v 1.1 2009/04/18 02:00:34 merlinofchaos +# node_comments.inc,v 1.2 2009/05/20 23:26:45 merlinofchaos +# node_content.inc,v 1.4 2009/08/18 04:36:53 merlinofchaos +# node_created.inc,v 1.1 2009/07/18 22:10:48 merlinofchaos +# node_title.inc,v 1.2 2009/07/18 22:10:48 merlinofchaos +# node_type_desc.inc,v 1.1 2009/04/18 02:00:34 merlinofchaos +# node_updated.inc,v 1.1 2009/07/18 22:10:48 merlinofchaos +# node.inc,v 1.11.2.2 2009/10/06 18:08:24 merlinofchaos +# book_parent.inc,v 1.2.2.1 2009/10/01 22:00:09 merlinofchaos +# term_from_node.inc,v 1.2.2.2 2009/10/21 21:25:39 merlinofchaos +# user_from_node.inc,v 1.3.2.1 2009/10/01 22:00:09 merlinofchaos +# site_language.inc,v 1.6.2.1 2009/10/01 22:00:08 merlinofchaos +# node_add_form.inc,v 1.9.2.1 2009/10/01 22:00:08 merlinofchaos +# php.inc,v 1.1.2.1 2009/10/01 22:00:08 merlinofchaos +# term.inc,v 1.1.2.3 2009/10/01 22:26:30 merlinofchaos +# term_vocabulary.inc,v 1.4.2.1 2009/10/01 22:00:08 merlinofchaos +# term_description.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# term_list.inc,v 1.3 2009/05/09 07:44:55 merlinofchaos +# term_parent.inc,v 1.2.2.1 2009/10/01 22:00:09 merlinofchaos +# vocabulary_terms.inc,v 1.3 2009/05/05 23:31:10 merlinofchaos +# term.inc,v 1.5.2.1 2009/10/01 22:00:08 merlinofchaos +# vocabulary.inc,v 1.3.2.1 2009/10/01 22:00:08 merlinofchaos +# nid.inc,v 1.8.2.2 2009/10/01 22:39:02 merlinofchaos +# node_edit.inc,v 1.5.2.2 2009/10/01 22:39:02 merlinofchaos +# node_add.inc,v 1.3.2.2 2009/10/01 22:39:02 merlinofchaos +# string.inc,v 1.3.2.2 2009/10/09 22:35:56 merlinofchaos +# string.inc,v 1.5.2.2 2009/10/09 22:35:57 merlinofchaos +# uid.inc,v 1.9.2.1 2009/10/01 22:39:02 merlinofchaos +# user_name.inc,v 1.1.2.1 2009/10/01 22:39:02 merlinofchaos +# vid.inc,v 1.4.2.2 2009/10/01 22:39:02 merlinofchaos +# block.inc,v 1.9 2009/07/17 21:53:41 merlinofchaos +# contact.inc,v 1.1.2.1 2009/10/12 23:17:18 merlinofchaos +# views_content.module,v 1.4 2009/08/07 19:58:33 merlinofchaos +# form.inc,v 1.1 2009/04/18 02:00:34 merlinofchaos +# node_form_attachments.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_author.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_book.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_buttons.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_comment.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_input_format.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_log.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_menu.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_path.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_publishing.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_taxonomy.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_edit_form.inc,v 1.10.2.2 2009/10/06 18:08:24 merlinofchaos +# page_footer_message.inc,v 1.1 2009/09/21 20:53:00 merlinofchaos +# page_help.inc,v 1.1 2009/08/17 21:23:13 merlinofchaos +# page_messages.inc,v 1.1 2009/08/17 21:23:13 merlinofchaos +# page_mission.inc,v 1.1 2009/08/19 01:18:35 merlinofchaos +# page_slogan.inc,v 1.1 2009/08/19 01:18:35 merlinofchaos +# page_tabs.inc,v 1.1 2009/08/17 21:23:13 merlinofchaos +# page_title.inc,v 1.1 2009/08/17 21:23:13 merlinofchaos +# terms.inc,v 1.4.2.1 2009/10/01 22:00:08 merlinofchaos +# views_panes.inc,v 1.14.2.3 2009/10/21 19:52:07 merlinofchaos +# views_content.views.inc,v 1.2 2009/04/30 22:37:52 merlinofchaos +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-10-22 21:56+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" + +#: ctools.install:25 +msgid "CTools CSS Cache" +msgstr "" + +#: ctools.install:27 +msgid "Exists" +msgstr "" + +#: ctools.install:31 +msgid "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." +msgstr "" + +#: ctools.install:33 +msgid "Unable to create" +msgstr "" + +#: ctools.install:113 +msgid "A special cache used to store objects that are being edited; it serves to save state in an ordinarily stateless environment." +msgstr "" + +#: ctools.info:0 +msgid "Chaos tools" +msgstr "" + +#: ctools.info:0 +msgid "A library of helpful tools by Merlin of Chaos." +msgstr "" + +#: ctools.info:0 bulk_export/bulk_export.info:0 ctools_plugin_example/ctools_plugin_example.info:0 page_manager/page_manager.info:0 views_content/views_content.info:0 +msgid "Chaos tool suite" +msgstr "" + +#: bulk_export/bulk_export.module:68 +msgid "Bulk export results" +msgstr "" + +#: bulk_export/bulk_export.module:92;116;127 +msgid "Place this in @file" +msgstr "" + +#: bulk_export/bulk_export.module:133 +msgid "There are no objects to be exported at this time." +msgstr "" + +#: bulk_export/bulk_export.module:159 +msgid "Module name" +msgstr "" + +#: bulk_export/bulk_export.module:160 +msgid "Enter the module name to export code to." +msgstr "" + +#: bulk_export/bulk_export.module:165 page_manager/page_manager.admin.inc:682 page_manager/plugins/tasks/page.inc:183 +msgid "Export" +msgstr "" + +#: bulk_export/bulk_export.module:200 +msgid "There are no objects in your system that may be exported at this time." +msgstr "" + +#: bulk_export/bulk_export.module:13 +msgid "use bulk exporter" +msgstr "" + +#: bulk_export/bulk_export.module:31 +msgid "Bulk Exporter" +msgstr "" + +#: bulk_export/bulk_export.module:32 +msgid "Bulk-export multiple CTools-handled data objects to code." +msgstr "" + +#: bulk_export/bulk_export.info:0 +msgid "Bulk Export" +msgstr "" + +#: bulk_export/bulk_export.info:0 +msgid "Performs bulk exporting of data objects known about by Chaos tools." +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.module:36 +msgid "Demonstration code, advanced help, and a demo panel to show how to build ctools plugins." +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.module:79 +msgid "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." +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.module:81 +msgid "There is a demo panel demonstrating much of the functionality provided at\n <a href=\"@demo_url\">CTools demo panel</a>, and you can find documentation on the examples at\n !ctools_plugin_example_help.\n CTools itself provides documentation at !ctools_help. Mostly, though, the code itself is intended to be the teacher.\n You can find it in %path." +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.module:35 +msgid "CTools plugin example" +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.info:0 +msgid "Chaos Tools (CTools) Plugin Example" +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.info:0 +msgid "Shows how an external module can provide ctools plugins (for Panels, etc.)." +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:15 +msgid "Arg length" +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:16 +msgid "Control access by length of simplecontext argument." +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:20 ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:33;42 ctools_plugin_example/plugins/contexts/simplecontext.inc:16 ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc:22 +msgid "Simplecontext" +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:30 +msgid "Grant access if simplecontext argument length is" +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:31 +msgid "Greater than" +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:31 +msgid "Less than or equal to" +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:36 +msgid "Length of simplecontext argument" +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:39 +msgid "Access/visibility will be granted based on arg length." +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:63 +msgid "Simpletext argument must be !comp @length characters" +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:16 +msgid "CTools example: role" +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:17 plugins/access/role.inc:15 +msgid "Control access by role." +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:22 plugins/access/node_access.inc:22 plugins/access/perm.inc:20 plugins/access/role.inc:21 plugins/content_types/contact/user_contact.inc:17;18 plugins/content_types/user_context/profile_fields.inc:15;16 plugins/content_types/user_context/user_picture.inc:13;14 plugins/content_types/user_context/user_profile.inc:13;14 plugins/contexts/user.inc:15 +msgid "User" +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:32 plugins/access/role.inc:31 +msgid "Role" +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:35 plugins/access/role.inc:34 +msgid "Only the checked roles will be granted access." +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:74 plugins/access/role.inc:75 +msgid "@identifier can have any role" +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:76 +msgid "@identifier must have role \"@roles\"" +msgid_plural "@identifier can be one of \"@roles\"" +msgstr[0] "" +msgstr[1] "" + +#: ctools_plugin_example/plugins/arguments/simplecontext_arg.inc:26 +msgid "Simplecontext arg" +msgstr "" + +#: ctools_plugin_example/plugins/arguments/simplecontext_arg.inc:29 +msgid "Creates a \"simplecontext\" from the arg." +msgstr "" + +#: ctools_plugin_example/plugins/arguments/simplecontext_arg.inc:37 +msgid "Enter the simplecontext arg" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:19 +msgid "CTools example no context content type" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:20 +msgid "No context content type - requires and uses no context." +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:37 ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:30 ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:37 +msgid "CTools Examples" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:94 +msgid "Item1" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:96 +msgid "The setting for item 1." +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:103 +msgid "Item2" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:105 +msgid "The setting for item 2" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:21 +msgid "CTools example relcontext content type" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:28 +msgid "Relcontext content type - works with relcontext context." +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:29 ctools_plugin_example/plugins/contexts/relcontext.inc:16 +msgid "Relcontext" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:55 +msgid "\n This is a block of data created by the Relcontent content type.\n Data in the block may be assembled from static text (like this) or from the\n content type settings form ($conf) for the content type, or from the context\n that is passed in. <br />\n In our case, the configuration form ($conf) has just one field, 'config_item_1;\n and it's configured with:\n " +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:87 +msgid "Config Item 1 (relcontext)" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:89 +msgid "Setting for relcontext." +msgstr "" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:23 +msgid "Simplecontext content type" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:32 +msgid "Simplecontext content type - works with a simplecontext context." +msgstr "" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:82 +msgid "\n This is a block of data created by the Simplecontext content type.\n Data in the block may be assembled from static text (like this) or from the\n content type settings form ($conf) for the content type, or from the context\n that is passed in. <br />\n In our case, the configuration form ($conf) has just one field, 'config_item_1;\n and it's configured with:\n " +msgstr "" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:111 +msgid "Config Item 1 for simplecontext content type" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:113 +msgid "The stuff for item 1." +msgstr "" + +#: ctools_plugin_example/plugins/contexts/relcontext.inc:17 +msgid "A relcontext object." +msgstr "" + +#: ctools_plugin_example/plugins/contexts/relcontext.inc:53 +msgid "Relcontext context from simplecontext" +msgstr "" + +#: ctools_plugin_example/plugins/contexts/relcontext.inc:77 +msgid "Relcontext setting" +msgstr "" + +#: ctools_plugin_example/plugins/contexts/relcontext.inc:79 +msgid "Just an example setting." +msgstr "" + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:17 +msgid "A single \"simplecontext\" context, or data element." +msgstr "" + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:25 +msgid "Enter some data to represent this \"simplecontext\"." +msgstr "" + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:58 +msgid "Simplecontext context from config" +msgstr "" + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:87 +msgid "Setting for simplecontext" +msgstr "" + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:89 +msgid "An example setting that could be used to configure a context" +msgstr "" + +#: ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc:19 +msgid "Relcontext from simplecontext" +msgstr "" + +#: ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc:21 +msgid "Adds a relcontext from existing simplecontext." +msgstr "" + +#: includes/ajax.inc:137 page_manager/page_manager.admin.inc:927 +msgid "Error" +msgstr "" + +#: includes/ajax.inc:138 +msgid "Server reports invalid input error." +msgstr "" + +#: includes/content.inc:337 +msgid "@type:@subtype will not display due to missing context" +msgstr "" + +#: includes/content.inc:422 +msgid "No info" +msgstr "" + +#: includes/content.inc:423 +msgid "No info available." +msgstr "" + +#: includes/content.inc:454 +msgid "Override title" +msgstr "" + +#: includes/content.inc:473 +msgid "You may use %keywords from contexts, as well as %title to contain the original title." +msgstr "" + +#: includes/content.inc:544 page_manager/page_manager.admin.inc:578 +msgid "Configure" +msgstr "" + +#: includes/content.inc:547 +msgid "Configure new !subtype_title" +msgstr "" + +#: includes/content.inc:550 +msgid "Configure !subtype_title" +msgstr "" + +#: includes/content.menu.inc:45 plugins/content_types/node_context/node_author.inc:36 plugins/contexts/user.inc:49 +msgid "Anonymous" +msgstr "" + +#: includes/content.menu.inc:46 +msgid "by @user" +msgstr "" + +#: includes/context-access-admin.inc:159 +msgid "Add" +msgstr "" + +#: includes/context-access-admin.inc:165 +msgid "All criteria must pass." +msgstr "" + +#: includes/context-access-admin.inc:166 +msgid "Only one criteria must pass." +msgstr "" + +#: includes/context-access-admin.inc:174;405 includes/context-admin.inc:622;701;772;883 page_manager/page_manager.admin.inc:1177 +msgid "Save" +msgstr "" + +#: includes/context-access-admin.inc:198 +msgid "Broken/missing access plugin %plugin" +msgstr "" + +#: includes/context-access-admin.inc:205 includes/context-admin.inc:342 +msgid "Configure settings for this item." +msgstr "" + +#: includes/context-access-admin.inc:206 includes/context-admin.inc:338 +msgid "Remove this item." +msgstr "" + +#: includes/context-access-admin.inc:214 includes/context-admin.inc:850 page_manager/page_manager.admin.inc:90;267;1316 page_manager/plugins/tasks/page.admin.inc:654 plugins/content_types/custom/custom.inc:113 plugins/content_types/search/search_result.inc:117;155 +msgid "Title" +msgstr "" + +#: includes/context-access-admin.inc:215 +msgid "Description" +msgstr "" + +#: includes/context-access-admin.inc:220 +msgid "No criteria selected, this test will pass." +msgstr "" + +#: includes/context-access-admin.inc:278;346;457 +msgid "Missing callback hooks." +msgstr "" + +#: includes/context-access-admin.inc:303 +msgid "Add criteria" +msgstr "" + +#: includes/context-access-admin.inc:367 +msgid "Edit criteria" +msgstr "" + +#: includes/context-admin.inc:26 page_manager/plugins/tasks/page.inc:158 views_content/plugins/content_types/views.inc:360 +msgid "Arguments" +msgstr "" + +#: includes/context-admin.inc:27;858 +msgid "argument" +msgstr "" + +#: includes/context-admin.inc:29 +msgid "Add argument" +msgstr "" + +#: includes/context-admin.inc:37 +msgid "Relationships" +msgstr "" + +#: includes/context-admin.inc:38;748 +msgid "relationship" +msgstr "" + +#: includes/context-admin.inc:40 +msgid "Add relationship" +msgstr "" + +#: includes/context-admin.inc:48 +msgid "Contexts" +msgstr "" + +#: includes/context-admin.inc:49;598 +msgid "context" +msgstr "" + +#: includes/context-admin.inc:51 +msgid "Add context" +msgstr "" + +#: includes/context-admin.inc:59 +msgid "Required contexts" +msgstr "" + +#: includes/context-admin.inc:60;686 +msgid "required context" +msgstr "" + +#: includes/context-admin.inc:62 +msgid "Add required context" +msgstr "" + +#: includes/context-admin.inc:365;493;931 page_manager/plugins/tasks/page.admin.inc:952 +msgid "Invalid object name." +msgstr "" + +#: includes/context-admin.inc:412 +msgid "Add @type \"@context\"" +msgstr "" + +#: includes/context-admin.inc:511 +msgid "Invalid context type" +msgstr "" + +#: includes/context-admin.inc:530 +msgid "Edit @type \"@context\"" +msgstr "" + +#: includes/context-admin.inc:597;685;747;857 plugins/content_types/node_context/node_links.inc:93 +msgid "Identifier" +msgstr "" + +#: includes/context-admin.inc:598;686;748;858 +msgid "Enter a name to identify this !type on administrative screens." +msgstr "" + +#: includes/context-admin.inc:604;692;754;864 plugins/content_types/custom/custom.inc:147 +msgid "Keyword" +msgstr "" + +#: includes/context-admin.inc:605;693;755;865 +msgid "Enter a keyword to use for substitution in titles." +msgstr "" + +#: includes/context-admin.inc:839 includes/export.inc:191;275 page_manager/page_manager.module:500;515 page_manager/plugins/tasks/page.inc:217 plugins/content_types/search/search_form.inc:117 views_content/plugins/content_types/views.inc:432 +msgid "Default" +msgstr "" + +#: includes/context-admin.inc:841 +msgid "Ignore it; content that requires this context will not be available." +msgstr "" + +#: includes/context-admin.inc:842 +msgid "Display page not found or display nothing at all." +msgstr "" + +#: includes/context-admin.inc:845 +msgid "If the argument is missing or is not valid, select how this should behave." +msgstr "" + +#: includes/context-admin.inc:852 +msgid "Enter a title to use when this argument is present. You may use %KEYWORD substitution, where the keyword is specified below." +msgstr "" + +#: includes/context-admin.inc:942 +msgid "Unable to delete missing item!" +msgstr "" + +#: includes/context-task-handler.inc:118 +msgid "Edit @type" +msgstr "" + +#: includes/context-task-handler.inc:308 +msgid "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." +msgstr "" + +#: includes/context-task-handler.inc:356 +msgid "Summary of contexts" +msgstr "" + +#: includes/context.inc:49 +msgid "Unknown context" +msgstr "" + +#: includes/context.inc:195;196;400 page_manager/plugins/tasks/page.admin.inc:1120;1140 +msgid "No context" +msgstr "" + +#: includes/context.inc:311;418 +msgid "Context %count" +msgstr "" + +#: includes/context.inc:311;418 +msgid "Context" +msgstr "" + +#: includes/context.inc:425 +msgid "Please choose which context and how you would like it converted." +msgstr "" + +#: includes/context.inc:1233 +msgid "@identifier (@keyword)" +msgstr "" + +#: includes/context.inc:1297 +msgid "Logged in user" +msgstr "" + +#: includes/context.inc:1335 +msgid ", and " +msgstr "" + +#: includes/context.inc:1335 +msgid ", or " +msgstr "" + +#: includes/context.theme.inc:80 page_manager/plugins/tasks/page.admin.inc:696 page_manager/theme/page_manager.theme.inc:103 views_content/plugins/views/views_content_plugin_display_panel_pane.inc:196 +msgid "Weight" +msgstr "" + +#: includes/context.theme.inc:82 plugins/access/node_access.inc:33 +msgid "Operation" +msgstr "" + +#: includes/context.theme.inc:131;237 +msgid "Built in context" +msgstr "" + +#: includes/context.theme.inc:134;158;181;201;240;259;275;290 +msgid "Keyword: %@keyword" +msgstr "" + +#: includes/context.theme.inc:136;161;183;203 +msgid "@keyword --> @title" +msgstr "" + +#: includes/context.theme.inc:155;256 +msgid "Argument @count" +msgstr "" + +#: includes/context.theme.inc:178;272 +msgid "Context @count" +msgstr "" + +#: includes/context.theme.inc:198;287 +msgid "From \"@title\"" +msgstr "" + +#: includes/css.inc:162 +msgid "Unable to create CTools CSS cache directory. Check the permissions on your files directory." +msgstr "" + +#: includes/export.inc:146 page_manager/page_manager.module:366 page_manager/plugins/tasks/page.admin.inc:1456 +msgid "Normal" +msgstr "" + +#: includes/export.inc:184 page_manager/page_manager.admin.inc:1473 page_manager/page_manager.module:509 page_manager/plugins/tasks/page.admin.inc:1485;1499;1510 +msgid "Overridden" +msgstr "" + +#: includes/export.inc:608 page_manager/page_manager.module:636 +msgid "Local" +msgstr "" + +#: includes/form.inc:303 +msgid "Validation error, please try again. If this error persists, please contact the site administrator." +msgstr "" + +#: includes/menu.inc:58 +msgid "Home" +msgstr "" + +#: includes/modal.inc:52 +msgid "Close Window" +msgstr "" + +#: includes/modal.inc:53;53 +msgid "Close window" +msgstr "" + +#: includes/modal.inc:54 js/modal.js:0;0 +msgid "Loading..." +msgstr "" + +#: includes/modal.inc:54 +msgid "Loading" +msgstr "" + +#: includes/wizard.inc:373 +msgid "Continue" +msgstr "" + +#: includes/wizard.inc:374 +msgid "Back" +msgstr "" + +#: includes/wizard.inc:375 +msgid "Update and return" +msgstr "" + +#: includes/wizard.inc:376 +msgid "Finish" +msgstr "" + +#: includes/wizard.inc:377 page_manager/page_manager.admin.inc:1183 +msgid "Cancel" +msgstr "" + +#: page_manager/page_manager.admin.inc:25 +msgid "See the getting started guide for more information." +msgstr "" + +#: page_manager/page_manager.admin.inc:40 +msgid "This page is currently locked for editing by you. Nobody else may edit this page until these changes are saved or canceled." +msgstr "" + +#: page_manager/page_manager.admin.inc:44 +msgid "This page is currently locked for editing by another user. You may not edit this page without breaking the lock." +msgstr "" + +#: page_manager/page_manager.admin.inc:52;297 +msgid "Reset" +msgstr "" + +#: page_manager/page_manager.admin.inc:88;238;270 page_manager/plugins/tasks/page.admin.inc:642 +msgid "Type" +msgstr "" + +#: page_manager/page_manager.admin.inc:89;268 +msgid "Name" +msgstr "" + +#: page_manager/page_manager.admin.inc:91;269 page_manager/plugins/tasks/page.admin.inc:399;1244;1370 page_manager/plugins/tasks/page.inc:647 page_manager/plugins/tasks/term_view.inc:258 plugins/content_types/search/search_form.inc:115 +msgid "Path" +msgstr "" + +#: page_manager/page_manager.admin.inc:92;245;271 page_manager/plugins/tasks/page.inc:46;592 +msgid "Storage" +msgstr "" + +#: page_manager/page_manager.admin.inc:95 page_manager/plugins/tasks/page.admin.inc:909 +msgid "Operations" +msgstr "" + +#: page_manager/page_manager.admin.inc:163 page_manager/plugins/tasks/search.inc:213 +msgid "System" +msgstr "" + +#: page_manager/page_manager.admin.inc:171 page_manager/plugins/tasks/page.inc:217 page_manager/plugins/tasks/search.inc:215 +msgid "In code" +msgstr "" + +#: page_manager/page_manager.admin.inc:189 page_manager/page_manager.module:79 page_manager/plugins/tasks/page.inc:623;665;701 views_content/plugins/views/views_content_plugin_display_panel_pane.inc:120 +msgid "Edit" +msgstr "" + +#: page_manager/page_manager.admin.inc:197;523;529;708;713 page_manager/plugins/tasks/page.inc:598 +msgid "Enable" +msgstr "" + +#: page_manager/page_manager.admin.inc:203;536;542;719;724 page_manager/plugins/tasks/page.inc:602 +msgid "Disable" +msgstr "" + +#: page_manager/page_manager.admin.inc:234 +msgid "<All>" +msgstr "" + +#: page_manager/page_manager.admin.inc:252;253 page_manager/plugins/tasks/page.inc:603 +msgid "Enabled" +msgstr "" + +#: page_manager/page_manager.admin.inc:253 page_manager/plugins/tasks/page.inc:599 +msgid "Disabled" +msgstr "" + +#: page_manager/page_manager.admin.inc:259 page_manager/plugins/tasks/search.inc:25 +msgid "Search" +msgstr "" + +#: page_manager/page_manager.admin.inc:264 +msgid "Sort by" +msgstr "" + +#: page_manager/page_manager.admin.inc:266 +msgid "Enabled, title" +msgstr "" + +#: page_manager/page_manager.admin.inc:278 +msgid "Order" +msgstr "" + +#: page_manager/page_manager.admin.inc:280 +msgid "Up" +msgstr "" + +#: page_manager/page_manager.admin.inc:281 +msgid "Down" +msgstr "" + +#: page_manager/page_manager.admin.inc:290 +msgid "Apply" +msgstr "" + +#: page_manager/page_manager.admin.inc:470;662 +msgid "Summary" +msgstr "" + +#: page_manager/page_manager.admin.inc:471 +msgid "Get a summary of the information about this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:524 +msgid "Activate this page so that it will be in use in your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:537 +msgid "De-activate this page. The data will remain but the page will not be in use on your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:548 +msgid "Add variant" +msgstr "" + +#: page_manager/page_manager.admin.inc:549 +msgid "Add a new variant to this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:554;587 +msgid "Create variant" +msgstr "" + +#: page_manager/page_manager.admin.inc:559 +msgid "Import variant" +msgstr "" + +#: page_manager/page_manager.admin.inc:560 +msgid "Add a new variant to this page from code exported from another page." +msgstr "" + +#: page_manager/page_manager.admin.inc:566 +msgid "Reorder variants" +msgstr "" + +#: page_manager/page_manager.admin.inc:568 +msgid "Change the priority of the variants to ensure that the right one gets selected." +msgstr "" + +#: page_manager/page_manager.admin.inc:579 +msgid "Configure a newly created variant prior to actually adding it to the page." +msgstr "" + +#: page_manager/page_manager.admin.inc:606;611 +msgid "Break lock" +msgstr "" + +#: page_manager/page_manager.admin.inc:607 +msgid "Break the lock on this page so that you can edit it." +msgstr "" + +#: page_manager/page_manager.admin.inc:630 +msgid "Variants" +msgstr "" + +#: page_manager/page_manager.admin.inc:655 +msgid "Variant operations" +msgstr "" + +#: page_manager/page_manager.admin.inc:663 +msgid "Get a summary of the information about this variant." +msgstr "" + +#: page_manager/page_manager.admin.inc:677 page_manager/plugins/tasks/page.admin.inc:1384 page_manager/plugins/tasks/page.inc:178 +msgid "Clone" +msgstr "" + +#: page_manager/page_manager.admin.inc:678 +msgid "Make an exact copy of this variant." +msgstr "" + +#: page_manager/page_manager.admin.inc:683 +msgid "Export this variant into code to import into another page." +msgstr "" + +#: page_manager/page_manager.admin.inc:688;692 page_manager/plugins/tasks/page.admin.inc:1499 page_manager/plugins/tasks/page.inc:189 +msgid "Revert" +msgstr "" + +#: page_manager/page_manager.admin.inc:689 +msgid "Remove all changes to this variant and revert to the version in code." +msgstr "" + +#: page_manager/page_manager.admin.inc:698;702 page_manager/plugins/tasks/page.admin.inc:1499 page_manager/plugins/tasks/page.inc:196 plugins/access/node_access.inc:38 +msgid "Delete" +msgstr "" + +#: page_manager/page_manager.admin.inc:699 +msgid "Remove this variant from the page completely." +msgstr "" + +#: page_manager/page_manager.admin.inc:709 +msgid "Activate this variant so that it will be in use in your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:720 +msgid "De-activate this variant. The data will remain but the variant will not be in use on your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:732 +msgid "No variants" +msgstr "" + +#: page_manager/page_manager.admin.inc:814 plugins/access/node_access.inc:37 +msgid "Update" +msgstr "" + +#: page_manager/page_manager.admin.inc:928 +msgid "This operation trail does not exist." +msgstr "" + +#: page_manager/page_manager.admin.inc:945 +msgid "The page has been updated. Changes will not be permanent until you save." +msgstr "" + +#: page_manager/page_manager.admin.inc:962 +msgid "Unable to update changes due to lock." +msgstr "" + +#: page_manager/page_manager.admin.inc:1112 +msgid "This setting contains unsaved changes." +msgstr "" + +#: page_manager/page_manager.admin.inc:1170 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1201 +msgid "All pending changes have been discarded, and the page is now unlocked." +msgstr "" + +#: page_manager/page_manager.admin.inc:1252 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1317 +msgid "Administrative title of this variant. If you leave blank it will be automatically assigned." +msgstr "" + +#: page_manager/page_manager.admin.inc:1322 +msgid "Variant type" +msgstr "" + +#: page_manager/page_manager.admin.inc:1331 +msgid "Optional features" +msgstr "" + +#: page_manager/page_manager.admin.inc:1333 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1361;1516 +msgid "Variant name" +msgstr "" + +#: page_manager/page_manager.admin.inc:1362;1517 +msgid "Enter the name of the new variant." +msgstr "" + +#: page_manager/page_manager.admin.inc:1367 +msgid "Paste variant code here" +msgstr "" + +#: page_manager/page_manager.admin.inc:1383 +msgid "No variant found." +msgstr "" + +#: page_manager/page_manager.admin.inc:1386 +msgid "Unable to get a variant from the import. Errors reported: @errors" +msgstr "" + +#: page_manager/page_manager.admin.inc:1474 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1477 +msgid "Are you sure you want to delete this variant? This deletion will not be made permanent until you click Save." +msgstr "" + +#: page_manager/page_manager.admin.inc:1543 +msgid "This variant is currently disabled. Enabling it will make it available in your system. This will not take effect until you save this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:1562 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1594 +msgid "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?" +msgstr "" + +#: page_manager/page_manager.admin.inc:1606 +msgid "The lock has been cleared and all changes discarded. You may now make changes to this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:1614 +msgid "Enabling this page will immediately make it available in your system (there is no need to wait for a save.)" +msgstr "" + +#: page_manager/page_manager.admin.inc:1641 +msgid "Disabling this page will immediately make it unavailable in your system (there is no need to wait for a save.)" +msgstr "" + +#: page_manager/page_manager.admin.inc:1699 +msgid "This page has no variants and thus no output of its own." +msgstr "" + +#: page_manager/page_manager.admin.inc:1704 +msgid "Add a new variant" +msgstr "" + +#: page_manager/page_manager.admin.inc:1722 +msgid "Unable to disable due to lock." +msgstr "" + +#: page_manager/page_manager.admin.inc:1725 +msgid "Unable to enable due to lock." +msgstr "" + +#: page_manager/page_manager.module:42 +msgid "use page manager" +msgstr "" + +#: page_manager/page_manager.module:42 +msgid "administer page manager" +msgstr "" + +#: page_manager/page_manager.module:66 +msgid "Pages" +msgstr "" + +#: page_manager/page_manager.module:67 +msgid "Add, edit and remove overridden system pages and user defined pages from the system." +msgstr "" + +#: page_manager/page_manager.module:72 +msgid "List" +msgstr "" + +#: page_manager/page_manager.install:222 +msgid "Panel" +msgstr "" + +#: page_manager/page_manager.info:0 +msgid "Page manager" +msgstr "" + +#: page_manager/page_manager.info:0 +msgid "Provides a UI and API to manage pages within the site." +msgstr "" + +#: page_manager/plugins/tasks/blog.inc:17;18 +msgid "All blogs" +msgstr "" + +#: page_manager/plugins/tasks/blog.inc:19 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/blog.inc:56 +msgid "Page manager module is unable to enable blog because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/blog_user.inc:16;17 +msgid "User blog" +msgstr "" + +#: page_manager/plugins/tasks/blog_user.inc:18 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/blog_user.inc:59 +msgid "Page manager module is unable to enable blog/%user because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/blog_user.inc:109 page_manager/plugins/tasks/contact_user.inc:105 page_manager/plugins/tasks/user_view.inc:97 +msgid "User being viewed" +msgstr "" + +#: page_manager/plugins/tasks/contact_site.inc:17;18 +msgid "Site contact page" +msgstr "" + +#: page_manager/plugins/tasks/contact_site.inc:19 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/contact_site.inc:56 +msgid "Page manager module is unable to enable contact because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/contact_user.inc:12;13 +msgid "User contact" +msgstr "" + +#: page_manager/plugins/tasks/contact_user.inc:14 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/contact_user.inc:55 +msgid "Page manager module is unable to enable user/%user/contact because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:13;14 +msgid "Node add/edit form" +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:15 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:55 +msgid "Page manager module is unable to enable node/%node/edit because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:65 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:129 +msgid "Create @name" +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:143 +msgid "Node being edited" +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:22;24 +msgid "Node template" +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:25 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:66 +msgid "Page manager module is unable to enable node/%node because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:118 +msgid "Node being viewed" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:201;279 +msgid "Basic settings" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:202;974;982 +msgid "Argument settings" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:203;439 +msgid "Access control" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:204 +msgid "Menu settings" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:280 +msgid "A meaningless second page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:372;1362 plugins/content_types/custom/custom.inc:106 views_content/plugins/views/views_content_plugin_display_panel_pane.inc:166 +msgid "Administrative title" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:373;1363 +msgid "The name of this page. This will appear in the administrative interface to easily identify it." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:379 +msgid "Machine name" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:380 +msgid "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!" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:391 views_content/plugins/views/views_content_plugin_display_panel_pane.inc:176;186 +msgid "Administrative description" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:392 +msgid "A description of what this page is, does or is for, for administrative use." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:400 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:422 +msgid "Make this your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:423 +msgid "To set this panel as your home page you must create a unique path name with no % placeholders in the path. The current site home page is set to %homepage." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:428 +msgid "This page is currently set to be your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:440 +msgid "Visible menu item" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:461 +msgid "Name is required." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:468 +msgid "That name is used by another page: @page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:473 +msgid "Page name must be alphanumeric or underscores only." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:480 +msgid "That path is used by another page: @page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:488 +msgid "Path is required." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:501 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:506 +msgid "You cannot have a dynamic path element after an optional path element." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:515 +msgid "You cannot have a static path element after an optional path element." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:526 +msgid "That path is already in used. This system cannot override existing paths." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:534 +msgid "That path is currently assigned to be an alias for @alias. This system cannot override existing aliases." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:539 +msgid "You cannot make this page your site home page if it uses % placeholders." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:547 +msgid "Duplicated argument %arg" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:552 +msgid "Invalid arg <em>%</em>. All arguments must be named with keywords." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:645 page_manager/plugins/tasks/page.inc:698 page_manager/plugins/tasks/term_view.inc:269 +msgid "No menu entry" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:646 +msgid "Normal menu entry" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:647;709 +msgid "Menu tab" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:648 +msgid "Default menu tab" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:657 +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:667 +msgid "Warning: Changing this item's menu will not work reliably in Drupal 6.4 or earlier. Please upgrade your copy of Drupal at !url." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:677 page_manager/plugins/tasks/page.inc:172;703 page_manager/plugins/tasks/term_view.inc:272 +msgid "Menu" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:681;731 +msgid "Insert item into an available menu." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:692 +msgid "Menu selection requires the activation of menu module." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:699 +msgid "The lower the weight the higher/further left it will appear." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:707 +msgid "Parent menu item" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:709 +msgid "Already exists" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:709 +msgid "Normal menu item" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:711 +msgid "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>." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:716 +msgid "Parent item title" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:719 +msgid "If creating a parent menu item, enter the title of the item." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:727 +msgid "Parent item menu" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:744 +msgid "Tab weight" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:748 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:783 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:852 +msgid "No context assigned" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:876 +msgid "Change" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:893 page_manager/plugins/tasks/page.inc:143 page_manager/plugins/tasks/term_view.inc:50;65 +msgid "Settings" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:906 +msgid "Argument" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:907 +msgid "Position in path" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:908 +msgid "Context assigned" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:927 +msgid "The path %path has no arguments to configure." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:961 +msgid "Invalid keyword." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:973 +msgid "Change context type" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:978 +msgid "Change argument" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1084 +msgid "No context selected" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1167 +msgid "Error: missing argument." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1180 +msgid "Context identifier" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1181 +msgid "This is the title of the context used to identify it later in the administrative process. This will never be shown to a user." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1187 +msgid "Error: missing or invalid argument plugin %argument." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1235 +msgid "Import page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1238;1356 +msgid "Page name" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1239 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1245 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1250 +msgid "Allow overwrite of an existing page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1251 +msgid "If the name you selected already exists in the database, this page will be allowed to overwrite the existing page." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1256 +msgid "Paste page code here" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1262 +msgid "Import" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1278 +msgid "No handler found." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1280 +msgid "Unable to get a page from the import. Errors reported: @errors" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1291 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1357 +msgid "Enter the name to the new page It must be unique and contain only alphanumeric characters and underscores." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1371 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1377 +msgid "Clone variants" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1378 +msgid "If checked all variants associated with the page will be cloned as well. If not checked the page will be cloned without variants." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1486 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1489 +msgid "Are you sure you want to delete this page? Deleting a page cannot be undone." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1512 +msgid "The page has been deleted." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1516 +msgid "The page has been reverted." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:22 +msgid "Custom pages" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:23 +msgid "Administrator created pages that have a URL path, access control and entries in the Drupal menu system." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:39 +msgid "Create a new page" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:150 page_manager/plugins/tasks/term_view.inc:68 +msgid "Basic" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:151 page_manager/plugins/tasks/term_view.inc:69 +msgid "Edit name, path and other basic settings for the page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:159 +msgid "Set up contexts for the arguments on this page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:165;668 page_manager/plugins/tasks/term_view.inc:264 +msgid "Access" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:166 +msgid "Control what users can access this page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:167 +msgid "Access rules are used to test if the page is accessible and any menu items associated with it are visible." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:173 +msgid "Provide this page a visible menu or a menu tab." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:179 +msgid "Make a copy of this page" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:184 +msgid "Export this page as code that can be imported or embedded into a module." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:190 +msgid "Remove all changes to this page and revert to the version in code." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:197 +msgid "Remove this page from your system completely." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:208 plugins/content_types/custom/custom.inc:26;58 plugins/content_types/node/node.inc:27 plugins/content_types/search/search_form.inc:119 +msgid "Custom" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:322 page_manager/plugins/tasks/term_view.inc:133 plugins/access/node_access.inc:36 +msgid "View" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:592;607;647;668;703 page_manager/plugins/tasks/term_view.inc:258;264;272;285;298 +msgid "page-summary-label" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:593;608;634;648;669;704 page_manager/plugins/tasks/term_view.inc:259;265;273;286;299 +msgid "page-summary-data" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:594;609;635;649;670;705 page_manager/plugins/tasks/term_view.inc:260;266;274;287;300 +msgid "page-summary-operation" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:607 +msgid "Status" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:626 +msgid "This is your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:629 +msgid "This page is set to become your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:659 +msgid "Accessible only if @conditions." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:662 page_manager/plugins/tasks/term_view.inc:265 +msgid "This page is publicly accessible." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:674 +msgid "No menu entry." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:675 +msgid "Normal menu entry." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:676 +msgid "Menu tab." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:677 +msgid "Default menu tab." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:683 +msgid "Title: %title." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:686 +msgid "Parent title: %title." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:691 +msgid "Menu block: %title." +msgstr "" + +#: page_manager/plugins/tasks/poll.inc:17;18 +msgid "All polls" +msgstr "" + +#: page_manager/plugins/tasks/poll.inc:19 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/poll.inc:56 +msgid "Page manager module is unable to enable poll because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/search.inc:91 +msgid "Page manager module is unable to enable search/@name/%menu_tail because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/search.inc:155 plugins/content_types/search/search_form.inc:17 plugins/content_types/search/search_result.inc:17 +msgid "Keywords" +msgstr "" + +#: page_manager/plugins/tasks/search.inc:212 +msgid "Search @type" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:23;24 +msgid "Taxonomy term template" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:25 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:51 +msgid "Update settings specific to the taxonomy term view." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:101 +msgid "Page manager module is unable to enable taxonomy/term/%term because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:161 +msgid "Term(s) being viewed" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:161 +msgid "Term being viewed" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:169 +msgid "Depth" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:224 +msgid "Allow multiple terms on taxonomy/term/%term" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:225 +msgid "Single term" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:225 +msgid "Multiple terms" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:226 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:230 plugins/arguments/terms.inc:54 +msgid "Inject hierarchy of first term into breadcrumb trail" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:233 plugins/arguments/term.inc:93 plugins/arguments/terms.inc:57 +msgid "If checked, taxonomy term parents will appear in the breadcrumb trail." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:278 +msgid "Multiple terms may be used, separated by , or +." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:281 +msgid "Only a single term may be used." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:285 +msgid "%term" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:291 +msgid "Breadcrumb trail will contain taxonomy term hierarchy" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:294 +msgid "Breadcrumb trail will not contain taxonomy term hiearchy." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:298 plugins/content_types/page/page_breadcrumb.inc:15 +msgid "Breadcrumb" +msgstr "" + +#: page_manager/plugins/tasks/user_view.inc:12;13 +msgid "User profile template" +msgstr "" + +#: page_manager/plugins/tasks/user_view.inc:14 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/user_view.inc:56 +msgid "Page manager module is unable to enable user/%user because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:42 +msgid "Locked" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:42 +msgid "This page is being edited by another user and you cannot make changes to it." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:45 +msgid "New" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:45 +msgid "This page is newly created and has not yet been saved to the database. It will not be available until you save it." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:48 +msgid "Changed" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:48 +msgid "This page has been modified, but these modifications are not yet live. While modifying this page, it is locked from modification by other users." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:98 +msgid "No task handlers are defined for this task." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:102 +msgid "Variant" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:124 +msgid "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>." +msgstr "" + +#: plugins/access/compare_users.inc:14 +msgid "User: compare" +msgstr "" + +#: plugins/access/compare_users.inc:15 +msgid "Compare two users (logged-in user and user being viewed, for example)" +msgstr "" + +#: plugins/access/compare_users.inc:23 +msgid "First User" +msgstr "" + +#: plugins/access/compare_users.inc:24 +msgid "Second User" +msgstr "" + +#: plugins/access/compare_users.inc:36 +msgid "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." +msgstr "" + +#: plugins/access/compare_users.inc:41 +msgid "Grant access if user contexts are" +msgstr "" + +#: plugins/access/compare_users.inc:42 +msgid "Equal" +msgstr "" + +#: plugins/access/compare_users.inc:42 +msgid "Not equal" +msgstr "" + +#: plugins/access/compare_users.inc:70 +msgid "@id1 @comp @id2" +msgstr "" + +#: plugins/access/node_access.inc:14 +msgid "Node: accessible" +msgstr "" + +#: plugins/access/node_access.inc:15 +msgid "Control access with built in Drupal node access test." +msgstr "" + +#: plugins/access/node_access.inc:23 plugins/access/node_language.inc:22 plugins/access/node_type.inc:21 plugins/content_types/node/node.inc:15 plugins/content_types/node_context/node_attachments.inc:13;14 plugins/content_types/node_context/node_author.inc:13;14 plugins/content_types/node_context/node_body.inc:13;14 plugins/content_types/node_context/node_book_nav.inc:14;15 plugins/content_types/node_context/node_comment_form.inc:14;15 plugins/content_types/node_context/node_comments.inc:15;16 plugins/content_types/node_context/node_content.inc:13;14 plugins/content_types/node_context/node_created.inc:13;14 plugins/content_types/node_context/node_links.inc:14;15 plugins/content_types/node_context/node_title.inc:13;14 plugins/content_types/node_context/node_type_desc.inc:13;14 plugins/content_types/node_context/node_updated.inc:13;14 plugins/contexts/node.inc:16 plugins/relationships/book_parent.inc:17 plugins/relationships/term_from_node.inc:17 plugins/relationships/user_from_node.inc:17 +msgid "Node" +msgstr "" + +#: plugins/access/node_access.inc:39 +msgid "Create nodes of the same type" +msgstr "" + +#: plugins/access/node_access.inc:41 +msgid "Using built in Drupal node access rules, determine if the user can perform the selected operation on the node." +msgstr "" + +#: plugins/access/node_access.inc:78 +msgid "@user can view @node." +msgstr "" + +#: plugins/access/node_access.inc:81 +msgid "@user can edit @node." +msgstr "" + +#: plugins/access/node_access.inc:84 +msgid "@user can delete @node." +msgstr "" + +#: plugins/access/node_access.inc:87 +msgid "@user can create nodes of the same type as @node." +msgstr "" + +#: plugins/access/node_language.inc:15 +msgid "Node: language" +msgstr "" + +#: plugins/access/node_language.inc:16 +msgid "Control access by node language." +msgstr "" + +#: plugins/access/node_language.inc:32;94 +msgid "Current site language" +msgstr "" + +#: plugins/access/node_language.inc:33;95 plugins/access/site_language.inc:31;69 +msgid "Default site language" +msgstr "" + +#: plugins/access/node_language.inc:34;96 +msgid "No language" +msgstr "" + +#: plugins/access/node_language.inc:38 plugins/access/site_language.inc:35 +msgid "Language" +msgstr "" + +#: plugins/access/node_language.inc:41 +msgid "Pass only if the node is in one of the selected languages." +msgstr "" + +#: plugins/access/node_language.inc:110 +msgid "@identifier is in any language" +msgstr "" + +#: plugins/access/node_language.inc:113 +msgid "@identifier language is \"@languages\"" +msgid_plural "@identifier language is one of \"@languages\"" +msgstr[0] "" +msgstr[1] "" + +#: plugins/access/node_type.inc:14 +msgid "Node: type" +msgstr "" + +#: plugins/access/node_type.inc:15 +msgid "Control access by node_type." +msgstr "" + +#: plugins/access/node_type.inc:36 plugins/contexts/node.inc:170 plugins/contexts/node_add_form.inc:21;100 +msgid "Node type" +msgstr "" + +#: plugins/access/node_type.inc:39 +msgid "Only the checked node types will be valid." +msgstr "" + +#: plugins/access/node_type.inc:96 +msgid "@identifier is any node type" +msgstr "" + +#: plugins/access/node_type.inc:99 +msgid "@identifier is type \"@types\"" +msgid_plural "@identifier type is one of \"@types\"" +msgstr[0] "" +msgstr[1] "" + +#: plugins/access/perm.inc:14 +msgid "User: permission" +msgstr "" + +#: plugins/access/perm.inc:15 +msgid "Control access by permission string." +msgstr "" + +#: plugins/access/perm.inc:41 +msgid "Permission" +msgstr "" + +#: plugins/access/perm.inc:43 +msgid "Only users with the selected permission flag will be able to access this." +msgstr "" + +#: plugins/access/perm.inc:65 +msgid "Error, unset permission" +msgstr "" + +#: plugins/access/perm.inc:68 +msgid "@identifier has \"@perm\"" +msgstr "" + +#: plugins/access/php.inc:14;41 +msgid "PHP Code" +msgstr "" + +#: plugins/access/php.inc:15 +msgid "Control access through arbitrary PHP code." +msgstr "" + +#: plugins/access/php.inc:35 +msgid "Administrative desc" +msgstr "" + +#: plugins/access/php.inc:37 +msgid "A description for this test for administrative purposes." +msgstr "" + +#: plugins/access/php.inc:43 +msgid "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." +msgstr "" + +#: plugins/access/php.inc:48 +msgid "You do not have sufficient permissions to edit PHP code." +msgstr "" + +#: plugins/access/role.inc:14 +msgid "User: role" +msgstr "" + +#: plugins/access/role.inc:78 +msgid "@identifier has role \"@roles\"" +msgid_plural "@identifier has one of \"@roles\"" +msgstr[0] "" +msgstr[1] "" + +#: plugins/access/site_language.inc:15 +msgid "User: language" +msgstr "" + +#: plugins/access/site_language.inc:16 +msgid "Control access by the language the user or site currently uses." +msgstr "" + +#: plugins/access/site_language.inc:38 +msgid "Pass only if the current site language is one of the selected languages." +msgstr "" + +#: plugins/access/site_language.inc:83 +msgid "Site language is any language" +msgstr "" + +#: plugins/access/site_language.inc:86 +msgid "Site language is \"@languages\"" +msgid_plural "Site language is one of \"@languages\"" +msgstr[0] "" +msgstr[1] "" + +#: plugins/access/term.inc:14 +msgid "Taxonomy: term" +msgstr "" + +#: plugins/access/term.inc:15 +msgid "Control access by a specific term." +msgstr "" + +#: plugins/access/term.inc:22 plugins/access/term_vocabulary.inc:21 plugins/content_types/term_context/term_description.inc:13 plugins/content_types/term_context/term_list.inc:13 plugins/relationships/term_parent.inc:17 +msgid "Term" +msgstr "" + +#: plugins/access/term.inc:41 plugins/content_types/vocabulary_context/vocabulary_terms.inc:14;15 plugins/contexts/term.inc:67 plugins/contexts/vocabulary.inc:57 plugins/relationships/term_from_node.inc:53 +msgid "Vocabulary" +msgstr "" + +#: plugins/access/term.inc:44 plugins/contexts/term.inc:70 plugins/contexts/vocabulary.inc:63 +msgid "Select the vocabulary for this form." +msgstr "" + +#: plugins/access/term.inc:63 +msgid "Terms" +msgstr "" + +#: plugins/access/term.inc:64 +msgid "Select a term or terms from @vocabulary." +msgstr "" + +#: plugins/access/term.inc:148 +msgid "@term can be the term \"@terms\"" +msgid_plural "@term can be one of these terms: @terms" +msgstr[0] "" +msgstr[1] "" + +#: plugins/access/term_vocabulary.inc:14 +msgid "Taxonomy: vocabulary" +msgstr "" + +#: plugins/access/term_vocabulary.inc:15 +msgid "Control access by term vocabulary." +msgstr "" + +#: plugins/access/term_vocabulary.inc:37 +msgid "Vocabularies" +msgstr "" + +#: plugins/access/term_vocabulary.inc:39 +msgid "Only terms in the checked vocabularies will be valid." +msgstr "" + +#: plugins/access/term_vocabulary.inc:83 +msgid "@identifier is any vocabulary" +msgstr "" + +#: plugins/access/term_vocabulary.inc:86 +msgid "@identifier vocabulary is \"@vids\"" +msgid_plural "@identifier vocabulary is one of \"@vids\"" +msgstr[0] "" +msgstr[1] "" + +#: plugins/arguments/nid.inc:15 +msgid "Node: ID" +msgstr "" + +#: plugins/arguments/nid.inc:17 +msgid "Creates a node context from a node ID argument." +msgstr "" + +#: plugins/arguments/nid.inc:21 plugins/arguments/node_edit.inc:22 +msgid "Enter the node ID of a node for this argument" +msgstr "" + +#: plugins/arguments/node_add.inc:15 +msgid "Node add form: node type" +msgstr "" + +#: plugins/arguments/node_add.inc:18 +msgid "Creates a node add form context from a node type argument." +msgstr "" + +#: plugins/arguments/node_edit.inc:15 +msgid "Node edit form: node ID" +msgstr "" + +#: plugins/arguments/node_edit.inc:18 +msgid "Creates a node edit form context from a node ID argument." +msgstr "" + +#: plugins/arguments/string.inc:15 plugins/contexts/string.inc:15 +msgid "String" +msgstr "" + +#: plugins/arguments/string.inc:18 +msgid "A string is a minimal context that simply holds a string that can be used for some other purpose." +msgstr "" + +#: plugins/arguments/string.inc:23 +msgid "Enter a value for this argument" +msgstr "" + +#: plugins/arguments/string.inc:49 +msgid "Get all arguments after this one" +msgstr "" + +#: plugins/arguments/string.inc:52 +msgid "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\"." +msgstr "" + +#: plugins/arguments/term.inc:15 +msgid "Taxonomy term: ID" +msgstr "" + +#: plugins/arguments/term.inc:18 +msgid "Creates a single taxonomy term from a taxonomy ID or taxonomy term name." +msgstr "" + +#: plugins/arguments/term.inc:81 +msgid "Argument type" +msgstr "" + +#: plugins/arguments/term.inc:83 plugins/contexts/term.inc:24 +msgid "Term ID" +msgstr "" + +#: plugins/arguments/term.inc:83 plugins/contexts/term.inc:25 +msgid "Term name" +msgstr "" + +#: plugins/arguments/term.inc:90 +msgid "Inject hierarchy into breadcrumb trail" +msgstr "" + +#: plugins/arguments/term.inc:106 +msgid "Enter a taxonomy term ID." +msgstr "" + +#: plugins/arguments/term.inc:111 +msgid "Enter a taxonomy term name." +msgstr "" + +#: plugins/arguments/terms.inc:15 +msgid "Taxonomy term (multiple): ID" +msgstr "" + +#: plugins/arguments/terms.inc:18 +msgid "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." +msgstr "" + +#: plugins/arguments/terms.inc:24 +msgid "Enter a term ID or a list of term IDs separated by a + or a ," +msgstr "" + +#: plugins/arguments/uid.inc:15 +msgid "User: ID" +msgstr "" + +#: plugins/arguments/uid.inc:18 +msgid "Creates a user context from a user ID argument." +msgstr "" + +#: plugins/arguments/uid.inc:22 +msgid "Enter the user ID of a user for this argument" +msgstr "" + +#: plugins/arguments/user_name.inc:15 +msgid "User: name" +msgstr "" + +#: plugins/arguments/user_name.inc:18 +msgid "Creates a user context from a user name." +msgstr "" + +#: plugins/arguments/user_name.inc:22 +msgid "Enter the username of a user for this argument" +msgstr "" + +#: plugins/arguments/vid.inc:15 +msgid "Vocabulary: ID" +msgstr "" + +#: plugins/arguments/vid.inc:18 +msgid "Creates a vocabulary context from a vocabulary ID argument." +msgstr "" + +#: plugins/arguments/vid.inc:22 +msgid "Enter the vocabulary ID for this argument" +msgstr "" + +#: plugins/content_types/block/block.inc:21 +msgid "Block" +msgstr "" + +#: plugins/content_types/block/block.inc:91 +msgid "Configure block" +msgstr "" + +#: plugins/content_types/block/block.inc:92 +msgid "Configure this block's 'block settings' in administer >> site building >> blocks" +msgstr "" + +#: plugins/content_types/block/block.inc:229 +msgid "Deleted/missing block @module-@delta" +msgstr "" + +#: plugins/content_types/block/block.inc:267;271;346 +msgid "Miscellaneous" +msgstr "" + +#: plugins/content_types/block/block.inc:279;359 +msgid "Menus" +msgstr "" + +#: plugins/content_types/block/block.inc:286;316;321;326;350;383 +msgid "Activity" +msgstr "" + +#: plugins/content_types/block/block.inc:331;336;354;378;388 plugins/content_types/contact/contact.inc:17 plugins/content_types/search/search_form.inc:18 plugins/content_types/search/search_result.inc:18 views_content/views_content.module:56 +msgid "Widgets" +msgstr "" + +#: plugins/content_types/block/block.inc:341 +msgid "Feeds" +msgstr "" + +#: plugins/content_types/contact/contact.inc:14;62 +msgid "Contact form" +msgstr "" + +#: plugins/content_types/contact/contact.inc:16 +msgid "The site contact form that allows users to send a message to site administrators." +msgstr "" + +#: plugins/content_types/contact/contact.inc:32 +msgid "Contact" +msgstr "" + +#: plugins/content_types/contact/user_contact.inc:14;68 +msgid "User contact form" +msgstr "" + +#: plugins/content_types/contact/user_contact.inc:16 +msgid "The site contact form that allows users to contact other users." +msgstr "" + +#: plugins/content_types/contact/user_contact.inc:38 +msgid "Contact @name" +msgstr "" + +#: plugins/content_types/custom/custom.inc:20 +msgid "New custom content" +msgstr "" + +#: plugins/content_types/custom/custom.inc:22 +msgid "Create a completely custom piece of HTML content." +msgstr "" + +#: plugins/content_types/custom/custom.inc:61 +msgid "Custom: @title" +msgstr "" + +#: plugins/content_types/custom/custom.inc:107 +msgid "This title will be used administratively to identify this pane. If blank, the regular title will be used." +msgstr "" + +#: plugins/content_types/custom/custom.inc:117 +msgid "Body" +msgstr "" + +#: plugins/content_types/custom/custom.inc:127 +msgid "Use context keywords" +msgstr "" + +#: plugins/content_types/custom/custom.inc:128 +msgid "If checked, context keywords will be substituted in this content." +msgstr "" + +#: plugins/content_types/custom/custom.inc:132 +msgid "Substitutions" +msgstr "" + +#: plugins/content_types/custom/custom.inc:143 +msgid "@identifier: @title" +msgstr "" + +#: plugins/content_types/custom/custom.inc:147 +msgid "Value" +msgstr "" + +#: plugins/content_types/form/form.inc:13 +msgid "General form" +msgstr "" + +#: plugins/content_types/form/form.inc:15 +msgid "Everything in the form that is not displayed by other content." +msgstr "" + +#: plugins/content_types/form/form.inc:16;17;43 plugins/content_types/node_form/node_form_attachments.inc:14;15 plugins/content_types/node_form/node_form_author.inc:13;14 plugins/content_types/node_form/node_form_book.inc:14;15 plugins/content_types/node_form/node_form_buttons.inc:13;14 plugins/content_types/node_form/node_form_comment.inc:14;15 plugins/content_types/node_form/node_form_input_format.inc:13;14 plugins/content_types/node_form/node_form_log.inc:13;14 plugins/content_types/node_form/node_form_menu.inc:14;15 plugins/content_types/node_form/node_form_path.inc:14;15 plugins/content_types/node_form/node_form_publishing.inc:19;20 plugins/content_types/node_form/node_form_taxonomy.inc:14;15 +msgid "Form" +msgstr "" + +#: plugins/content_types/form/form.inc:44 +msgid "Form goes here." +msgstr "" + +#: plugins/content_types/form/form.inc:52 +msgid "\"@s\" base form" +msgstr "" + +#: plugins/content_types/node/node.inc:24 +msgid "Existing node" +msgstr "" + +#: plugins/content_types/node/node.inc:26 +msgid "Add a node from your site as content." +msgstr "" + +#: plugins/content_types/node/node.inc:70 plugins/content_types/node_context/node_content.inc:61 +msgid "Edit node" +msgstr "" + +#: plugins/content_types/node/node.inc:71 plugins/content_types/node_context/node_content.inc:62 +msgid "Edit this node" +msgstr "" + +#: plugins/content_types/node/node.inc:106 plugins/content_types/node_context/node_content.inc:130 +msgid "Leave node title" +msgstr "" + +#: plugins/content_types/node/node.inc:107 plugins/content_types/node_context/node_content.inc:131 +msgid "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." +msgstr "" + +#: plugins/content_types/node/node.inc:113 plugins/contexts/node.inc:81 plugins/contexts/node_edit_form.inc:99 +msgid "Enter the title or NID of a node" +msgstr "" + +#: plugins/content_types/node/node.inc:114 +msgid "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." +msgstr "" + +#: plugins/content_types/node/node.inc:130 plugins/content_types/node_context/node_content.inc:141 +msgid "Show only node teaser" +msgstr "" + +#: plugins/content_types/node/node.inc:138 plugins/content_types/node_context/node_content.inc:154 +msgid "Include node links for \"add comment\", \"read more\" etc." +msgstr "" + +#: plugins/content_types/node/node.inc:144 plugins/content_types/node_context/node_content.inc:167 +msgid "Template identifier" +msgstr "" + +#: plugins/content_types/node/node.inc:145 plugins/content_types/node_context/node_content.inc:168 +msgid "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." +msgstr "" + +#: plugins/content_types/node/node.inc:179 +msgid "Invalid node" +msgstr "" + +#: plugins/content_types/node/node.inc:197 +msgid "Node loaded from @var" +msgstr "" + +#: plugins/content_types/node/node.inc:205 +msgid "Deleted/missing node @nid" +msgstr "" + +#: plugins/content_types/node_context/node_attachments.inc:10;23 +msgid "Attached files" +msgstr "" + +#: plugins/content_types/node_context/node_attachments.inc:12 +msgid "A list of files attached to the node." +msgstr "" + +#: plugins/content_types/node_context/node_attachments.inc:31 +msgid "Attached files go here." +msgstr "" + +#: plugins/content_types/node_context/node_attachments.inc:39 +msgid "\"@s\" attachments" +msgstr "" + +#: plugins/content_types/node_context/node_author.inc:10 plugins/relationships/user_from_node.inc:14 +msgid "Node author" +msgstr "" + +#: plugins/content_types/node_context/node_author.inc:12 +msgid "The author of the referenced node." +msgstr "" + +#: plugins/content_types/node_context/node_author.inc:35 +msgid "Author" +msgstr "" + +#: plugins/content_types/node_context/node_author.inc:49 +msgid "Link to author profile" +msgstr "" + +#: plugins/content_types/node_context/node_author.inc:52 +msgid "Check here to link to the node author profile." +msgstr "" + +#: plugins/content_types/node_context/node_author.inc:70 +msgid "\"@s\" author" +msgstr "" + +#: plugins/content_types/node_context/node_body.inc:10 +msgid "Node body" +msgstr "" + +#: plugins/content_types/node_context/node_body.inc:12 +msgid "The body of the referenced node." +msgstr "" + +#: plugins/content_types/node_context/node_body.inc:58 +msgid "\"@s\" body" +msgstr "" + +#: plugins/content_types/node_context/node_book_nav.inc:11;25 +msgid "Book navigation" +msgstr "" + +#: plugins/content_types/node_context/node_book_nav.inc:13 +msgid "The navigation menu the book the node belongs to." +msgstr "" + +#: plugins/content_types/node_context/node_book_nav.inc:31 +msgid "Book navigation goes here." +msgstr "" + +#: plugins/content_types/node_context/node_book_nav.inc:39 +msgid "\"@s\" book navigation" +msgstr "" + +#: plugins/content_types/node_context/node_comment_form.inc:11 +msgid "Comment form" +msgstr "" + +#: plugins/content_types/node_context/node_comment_form.inc:13 +msgid "A form to add a new comment." +msgstr "" + +#: plugins/content_types/node_context/node_comment_form.inc:26 +msgid "Add comment" +msgstr "" + +#: plugins/content_types/node_context/node_comment_form.inc:29 +msgid "Comment form here." +msgstr "" + +#: plugins/content_types/node_context/node_comment_form.inc:47 +msgid "\"@s\" comment form" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:12 +msgid "Node comments" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:14 +msgid "The comments of the referenced node." +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:32 +msgid "Comments" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:34 +msgid "Node comments go here." +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:49 +msgid "Mode" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:56 +msgid "Sort" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:62 +msgid "!a comments per page" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:65 +msgid "Pager" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:80 +msgid "\"@s\" comments" +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:10 +msgid "Node content" +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:12 +msgid "The content of the referenced node." +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:44 plugins/content_types/node_context/node_links.inc:41 +msgid "Node title." +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:45 +msgid "Node content goes here." +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:135 plugins/content_types/node_context/node_links.inc:78 +msgid "Link title to node" +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:138 plugins/content_types/node_context/node_links.inc:81 plugins/content_types/node_context/node_title.inc:55 +msgid "Check here to make the title link to the node." +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:148 +msgid "Treat this as the primary node page" +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:149 +msgid "This can affect title rendering and breadcrumbs from some node types." +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:160 +msgid "No extras" +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:161 +msgid "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." +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:182 +msgid "\"@s\" content" +msgstr "" + +#: plugins/content_types/node_context/node_created.inc:10 +msgid "Node created date" +msgstr "" + +#: plugins/content_types/node_context/node_created.inc:12 +msgid "The date the referenced node was created." +msgstr "" + +#: plugins/content_types/node_context/node_created.inc:35 +msgid "Created date" +msgstr "" + +#: plugins/content_types/node_context/node_created.inc:50 plugins/content_types/node_context/node_updated.inc:50 +msgid "Date format" +msgstr "" + +#: plugins/content_types/node_context/node_created.inc:75 +msgid "\"@s\" created date" +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:11 +msgid "Node links" +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:13 +msgid "Node links of the referenced node." +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:42 +msgid "Node links go here." +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:84 +msgid "Teaser mode" +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:87 +msgid "Check here to show links in teaser mode." +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:94 +msgid "Whatever is placed here will appear in $node->panel_identifier to help theme node links displayed on the panel" +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:108 +msgid "\"@s\" links" +msgstr "" + +#: plugins/content_types/node_context/node_title.inc:10 plugins/contexts/node.inc:168 +msgid "Node title" +msgstr "" + +#: plugins/content_types/node_context/node_title.inc:12 +msgid "The title of the referenced node." +msgstr "" + +#: plugins/content_types/node_context/node_title.inc:52 +msgid "Link to node" +msgstr "" + +#: plugins/content_types/node_context/node_title.inc:73 +msgid "\"@s\" title" +msgstr "" + +#: plugins/content_types/node_context/node_type_desc.inc:10;34 +msgid "Node type description" +msgstr "" + +#: plugins/content_types/node_context/node_type_desc.inc:12 +msgid "Node type description." +msgstr "" + +#: plugins/content_types/node_context/node_type_desc.inc:35 +msgid "Node type description goes here." +msgstr "" + +#: plugins/content_types/node_context/node_type_desc.inc:43 +msgid "\"@s\" type description" +msgstr "" + +#: plugins/content_types/node_context/node_updated.inc:10 +msgid "Node last updated date" +msgstr "" + +#: plugins/content_types/node_context/node_updated.inc:12 +msgid "The date the referenced node was last updated." +msgstr "" + +#: plugins/content_types/node_context/node_updated.inc:35 +msgid "Last updated date" +msgstr "" + +#: plugins/content_types/node_context/node_updated.inc:75 +msgid "\"@s\" last updated date" +msgstr "" + +#: plugins/content_types/node_form/node_form_attachments.inc:12 +msgid "Node form file attachments" +msgstr "" + +#: plugins/content_types/node_form/node_form_attachments.inc:13 +msgid "File attachments on the Node form." +msgstr "" + +#: plugins/content_types/node_form/node_form_attachments.inc:22 plugins/content_types/node_form/node_form_author.inc:20 plugins/content_types/node_form/node_form_book.inc:22 plugins/content_types/node_form/node_form_buttons.inc:20 plugins/content_types/node_form/node_form_comment.inc:22 plugins/content_types/node_form/node_form_input_format.inc:20 plugins/content_types/node_form/node_form_log.inc:20 plugins/content_types/node_form/node_form_menu.inc:22 plugins/content_types/node_form/node_form_path.inc:22 plugins/content_types/node_form/node_form_publishing.inc:28 plugins/content_types/node_form/node_form_taxonomy.inc:22 +msgid "node_form" +msgstr "" + +#: plugins/content_types/node_form/node_form_attachments.inc:24 +msgid "Attach files" +msgstr "" + +#: plugins/content_types/node_form/node_form_attachments.inc:35 +msgid "Attach files." +msgstr "" + +#: plugins/content_types/node_form/node_form_attachments.inc:41 +msgid "\"@s\" node form attach files" +msgstr "" + +#: plugins/content_types/node_form/node_form_author.inc:11 +msgid "Node form author information" +msgstr "" + +#: plugins/content_types/node_form/node_form_author.inc:12 +msgid "Author information on the Node form." +msgstr "" + +#: plugins/content_types/node_form/node_form_author.inc:22 +msgid "Authoring information" +msgstr "" + +#: plugins/content_types/node_form/node_form_author.inc:35 +msgid "Authoring information." +msgstr "" + +#: plugins/content_types/node_form/node_form_author.inc:41 +msgid "\"@s\" node form publishing options" +msgstr "" + +#: plugins/content_types/node_form/node_form_book.inc:12 +msgid "Node form book options" +msgstr "" + +#: plugins/content_types/node_form/node_form_book.inc:13 +msgid "Book options for the node." +msgstr "" + +#: plugins/content_types/node_form/node_form_book.inc:24 +msgid "Book options" +msgstr "" + +#: plugins/content_types/node_form/node_form_book.inc:39 +msgid "Book options." +msgstr "" + +#: plugins/content_types/node_form/node_form_book.inc:45 +msgid "\"@s\" node form book options" +msgstr "" + +#: plugins/content_types/node_form/node_form_buttons.inc:11 +msgid "Node form submit buttons" +msgstr "" + +#: plugins/content_types/node_form/node_form_buttons.inc:12 +msgid "Submit buttons for the node form." +msgstr "" + +#: plugins/content_types/node_form/node_form_buttons.inc:29 +msgid "Node form buttons." +msgstr "" + +#: plugins/content_types/node_form/node_form_buttons.inc:35 +msgid "\"@s\" node form submit buttons" +msgstr "" + +#: plugins/content_types/node_form/node_form_comment.inc:12 +msgid "Node form comment settings" +msgstr "" + +#: plugins/content_types/node_form/node_form_comment.inc:13 +msgid "Comment settings on the Node form." +msgstr "" + +#: plugins/content_types/node_form/node_form_comment.inc:24 +msgid "Comment options" +msgstr "" + +#: plugins/content_types/node_form/node_form_comment.inc:35 +msgid "Comment options." +msgstr "" + +#: plugins/content_types/node_form/node_form_comment.inc:41 +msgid "\"@s\" node form comment settings" +msgstr "" + +#: plugins/content_types/node_form/node_form_input_format.inc:11 +msgid "Node form input format" +msgstr "" + +#: plugins/content_types/node_form/node_form_input_format.inc:12 +msgid "Input format for the body field on a node." +msgstr "" + +#: plugins/content_types/node_form/node_form_input_format.inc:22 plugins/content_types/search/search_result.inc:135;173 +msgid "Input format" +msgstr "" + +#: plugins/content_types/node_form/node_form_input_format.inc:33 +msgid "Input format." +msgstr "" + +#: plugins/content_types/node_form/node_form_input_format.inc:39 +msgid "\"@s\" node form input format" +msgstr "" + +#: plugins/content_types/node_form/node_form_log.inc:11 +msgid "Node form revision log message" +msgstr "" + +#: plugins/content_types/node_form/node_form_log.inc:12 +msgid "Revision log message for the node." +msgstr "" + +#: plugins/content_types/node_form/node_form_log.inc:28 +msgid "\"@s\" node form revision log" +msgstr "" + +#: plugins/content_types/node_form/node_form_menu.inc:12 +msgid "Node form menu settings" +msgstr "" + +#: plugins/content_types/node_form/node_form_menu.inc:13 +msgid "Menu settings on the Node form." +msgstr "" + +#: plugins/content_types/node_form/node_form_menu.inc:24 +msgid "Menu options" +msgstr "" + +#: plugins/content_types/node_form/node_form_menu.inc:36 +msgid "Menu options." +msgstr "" + +#: plugins/content_types/node_form/node_form_menu.inc:42 +msgid "\"@s\" node form menu settings" +msgstr "" + +#: plugins/content_types/node_form/node_form_path.inc:12 +msgid "Node form url path settings" +msgstr "" + +#: plugins/content_types/node_form/node_form_path.inc:13 plugins/content_types/node_form/node_form_publishing.inc:18 +msgid "Publishing options on the Node form." +msgstr "" + +#: plugins/content_types/node_form/node_form_path.inc:24 +msgid "URL path options" +msgstr "" + +#: plugins/content_types/node_form/node_form_path.inc:36 +msgid "URL Path options." +msgstr "" + +#: plugins/content_types/node_form/node_form_path.inc:42 +msgid "\"@s\" node form path options" +msgstr "" + +#: plugins/content_types/node_form/node_form_publishing.inc:16 +msgid "Node form publishing options" +msgstr "" + +#: plugins/content_types/node_form/node_form_publishing.inc:27 +msgid "Publishing options" +msgstr "" + +#: plugins/content_types/node_form/node_form_publishing.inc:39 +msgid "Publishing options." +msgstr "" + +#: plugins/content_types/node_form/node_form_publishing.inc:45 +msgid "\"@s\" node form author information" +msgstr "" + +#: plugins/content_types/node_form/node_form_taxonomy.inc:12 +msgid "Node form categories" +msgstr "" + +#: plugins/content_types/node_form/node_form_taxonomy.inc:13 +msgid "Taxonomy categories for the node." +msgstr "" + +#: plugins/content_types/node_form/node_form_taxonomy.inc:24 +msgid "Categories" +msgstr "" + +#: plugins/content_types/node_form/node_form_taxonomy.inc:35 +msgid "Categories." +msgstr "" + +#: plugins/content_types/node_form/node_form_taxonomy.inc:41 +msgid "\"@s\" node form select taxonomy" +msgstr "" + +#: plugins/content_types/page/page_breadcrumb.inc:18 +msgid "Add the breadcrumb trail as content." +msgstr "" + +#: plugins/content_types/page/page_breadcrumb.inc:19 plugins/content_types/page/page_footer_message.inc:19 plugins/content_types/page/page_help.inc:19 plugins/content_types/page/page_messages.inc:19 plugins/content_types/page/page_mission.inc:19 plugins/content_types/page/page_slogan.inc:19 plugins/content_types/page/page_tabs.inc:19 plugins/content_types/page/page_title.inc:19 +msgid "Page elements" +msgstr "" + +#: plugins/content_types/page/page_footer_message.inc:16 +msgid "Page footer message" +msgstr "" + +#: plugins/content_types/page/page_footer_message.inc:18 +msgid "Add the page footer message as content." +msgstr "" + +#: plugins/content_types/page/page_help.inc:15 +msgid "Help" +msgstr "" + +#: plugins/content_types/page/page_help.inc:18 +msgid "Add the help text of the current page as content." +msgstr "" + +#: plugins/content_types/page/page_messages.inc:15 +msgid "Status messages" +msgstr "" + +#: plugins/content_types/page/page_messages.inc:18 +msgid "Add the status messages of the current page as content." +msgstr "" + +#: plugins/content_types/page/page_mission.inc:15 +msgid "Mission" +msgstr "" + +#: plugins/content_types/page/page_mission.inc:18 +msgid "Add the site mission statement as content." +msgstr "" + +#: plugins/content_types/page/page_slogan.inc:15 +msgid "Site Slogan" +msgstr "" + +#: plugins/content_types/page/page_slogan.inc:18 +msgid "Add the slogan trail as content." +msgstr "" + +#: plugins/content_types/page/page_tabs.inc:15 +msgid "Tabs" +msgstr "" + +#: plugins/content_types/page/page_tabs.inc:18 +msgid "Add the tabs (local tasks) as content." +msgstr "" + +#: plugins/content_types/page/page_title.inc:16 +msgid "Page title" +msgstr "" + +#: plugins/content_types/page/page_title.inc:18 +msgid "Add the page title as content." +msgstr "" + +#: plugins/content_types/search/search_form.inc:14 +msgid "Advanced search form" +msgstr "" + +#: plugins/content_types/search/search_form.inc:16 +msgid "A search form with advanced options." +msgstr "" + +#: plugins/content_types/search/search_form.inc:96 plugins/content_types/search/search_result.inc:99 +msgid "Search type" +msgstr "" + +#: plugins/content_types/search/search_form.inc:103 +msgid "Search form" +msgstr "" + +#: plugins/content_types/search/search_form.inc:105 +msgid "Simple" +msgstr "" + +#: plugins/content_types/search/search_form.inc:106 +msgid "Advanced" +msgstr "" + +#: plugins/content_types/search/search_form.inc:109 +msgid "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." +msgstr "" + +#: plugins/content_types/search/search_form.inc:118 +msgid "Same page" +msgstr "" + +#: plugins/content_types/search/search_form.inc:136 +msgid "Override default prompt" +msgstr "" + +#: plugins/content_types/search/search_form.inc:163 +msgid "@type search form" +msgstr "" + +#: plugins/content_types/search/search_result.inc:14;69 +msgid "Search results" +msgstr "" + +#: plugins/content_types/search/search_result.inc:16 +msgid "The results of a search using keywords." +msgstr "" + +#: plugins/content_types/search/search_result.inc:62 +msgid "results" +msgstr "" + +#: plugins/content_types/search/search_result.inc:74 +msgid "Your search yielded no results" +msgstr "" + +#: plugins/content_types/search/search_result.inc:107 +msgid "Record a watchdog log entry when searches are made" +msgstr "" + +#: plugins/content_types/search/search_result.inc:113 +msgid "Override \"no result\" text" +msgstr "" + +#: plugins/content_types/search/search_result.inc:125 +msgid "No result text" +msgstr "" + +#: plugins/content_types/search/search_result.inc:151 +msgid "Display text if no search keywords were submitted" +msgstr "" + +#: plugins/content_types/search/search_result.inc:163 +msgid "No keywords text" +msgstr "" + +#: plugins/content_types/search/search_result.inc:202 +msgid "@type search result" +msgstr "" + +#: plugins/content_types/search/search_result.inc:62 +msgid "search" +msgstr "" + +#: plugins/content_types/search/search_result.inc:62 +msgid "%keys (@type)." +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:10 +msgid "Term description" +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:12 +msgid "Term description." +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:14 plugins/content_types/term_context/term_list.inc:14 plugins/contexts/term.inc:15 +msgid "Taxonomy term" +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:30 +msgid "Edit term" +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:31 +msgid "Edit this term" +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:38 plugins/content_types/term_context/term_list.inc:62 +msgid "Term description goes here." +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:46 +msgid "\"@s\" term description" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:10 +msgid "List of related terms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:12 +msgid "Terms related to an existing term; may be child, siblings or top level." +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:71 +msgid "Child terms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:72 +msgid "Related terms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:73 +msgid "Sibling terms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:74 +msgid "Top level terms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:75 +msgid "Term synonyms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:87 +msgid "Which terms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:96 +msgid "List type" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:97 +msgid "Unordered" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:97 +msgid "Ordered" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:104 +msgid "\"@s\" @type" +msgstr "" + +#: plugins/content_types/user_context/profile_fields.inc:12 +msgid "Profile category" +msgstr "" + +#: plugins/content_types/user_context/profile_fields.inc:14 +msgid "Contents of a single profile category." +msgstr "" + +#: plugins/content_types/user_context/profile_fields.inc:64 +msgid "Profile content goes here." +msgstr "" + +#: plugins/content_types/user_context/profile_fields.inc:91 +msgid "Which category" +msgstr "" + +#: plugins/content_types/user_context/profile_fields.inc:101 +msgid "Text to display if category has no data. Note that title will not display unless overridden." +msgstr "" + +#: plugins/content_types/user_context/profile_fields.inc:122 +msgid "\"@s\" profile fields" +msgstr "" + +#: plugins/content_types/user_context/user_picture.inc:10 +msgid "User picture" +msgstr "" + +#: plugins/content_types/user_context/user_picture.inc:12 +msgid "The picture of a user." +msgstr "" + +#: plugins/content_types/user_context/user_picture.inc:37 +msgid "\"@s\" user picture" +msgstr "" + +#: plugins/content_types/user_context/user_profile.inc:10 +msgid "User profile" +msgstr "" + +#: plugins/content_types/user_context/user_profile.inc:12 +msgid "The profile of a user." +msgstr "" + +#: plugins/content_types/user_context/user_profile.inc:42 +msgid "\"@s\" user profile" +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:11 +msgid "Vocabulary terms" +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:13 +msgid "All the terms in a vocabulary." +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:66 +msgid "\"@s\" terms" +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:73 +msgid "Maximum depth" +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:74 +msgid "unlimited" +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:76 +msgid "Define the maximum depth of terms being displayed." +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:81 +msgid "Display as tree" +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:83 +msgid "If checked, the terms are displayed in a tree, otherwise in a flat list." +msgstr "" + +#: plugins/contexts/node.inc:17 +msgid "A node object." +msgstr "" + +#: plugins/contexts/node.inc:29 +msgid "Enter the node ID of a node for this context." +msgstr "" + +#: plugins/contexts/node.inc:91 plugins/contexts/node_edit_form.inc:109 +msgid "'%title' [node id %nid]" +msgstr "" + +#: plugins/contexts/node.inc:91 plugins/contexts/node_edit_form.inc:109 +msgid "Open in new window" +msgstr "" + +#: plugins/contexts/node.inc:92 plugins/contexts/node_edit_form.inc:110 +msgid "Currently set to !link" +msgstr "" + +#: plugins/contexts/node.inc:104 plugins/contexts/node_edit_form.inc:122 +msgid "Reset identifier to node title" +msgstr "" + +#: plugins/contexts/node.inc:105 plugins/contexts/node_edit_form.inc:123 +msgid "If checked, the identifier will be reset to the node title of the selected node." +msgstr "" + +#: plugins/contexts/node.inc:117 plugins/contexts/node_edit_form.inc:135 +msgid "You must select a node." +msgstr "" + +#: plugins/contexts/node.inc:143 plugins/contexts/node_edit_form.inc:161 +msgid "Invalid node selected." +msgstr "" + +#: plugins/contexts/node.inc:166 +msgid "Node ID" +msgstr "" + +#: plugins/contexts/node.inc:167 +msgid "Node revision ID" +msgstr "" + +#: plugins/contexts/node.inc:169 +msgid "Author UID" +msgstr "" + +#: plugins/contexts/node_add_form.inc:15 +msgid "Node add form" +msgstr "" + +#: plugins/contexts/node_add_form.inc:16 +msgid "A node add form." +msgstr "" + +#: plugins/contexts/node_add_form.inc:25 +msgid "Enter the node type this context." +msgstr "" + +#: plugins/contexts/node_add_form.inc:78 +msgid "Submit @name" +msgstr "" + +#: plugins/contexts/node_add_form.inc:104 +msgid "Select the node type for this form." +msgstr "" + +#: plugins/contexts/node_edit_form.inc:15 +msgid "Node edit form" +msgstr "" + +#: plugins/contexts/node_edit_form.inc:16 +msgid "A node edit form." +msgstr "" + +#: plugins/contexts/node_edit_form.inc:27 +msgid "Enter the node ID of a node for this argument:" +msgstr "" + +#: plugins/contexts/string.inc:16 +msgid "A context that is just a string." +msgstr "" + +#: plugins/contexts/string.inc:22 +msgid "Raw string" +msgstr "" + +#: plugins/contexts/string.inc:23 +msgid "HTML-safe string" +msgstr "" + +#: plugins/contexts/string.inc:28 +msgid "Enter the string for this context." +msgstr "" + +#: plugins/contexts/term.inc:16 +msgid "A single taxonomy term object." +msgstr "" + +#: plugins/contexts/term.inc:26 +msgid "Vocabulary ID" +msgstr "" + +#: plugins/contexts/term.inc:79 +msgid "Currently set to @term. Enter another term if you wish to change the term." +msgstr "" + +#: plugins/contexts/term.inc:96 +msgid "Select a term from @vocabulary." +msgstr "" + +#: plugins/contexts/term.inc:114 +msgid "Reset identifier to term title" +msgstr "" + +#: plugins/contexts/term.inc:115 +msgid "If checked, the identifier will be reset to the term name of the selected term." +msgstr "" + +#: plugins/contexts/term.inc:128 +msgid "You must select a term." +msgstr "" + +#: plugins/contexts/term.inc:139 +msgid "Invalid term selected." +msgstr "" + +#: plugins/contexts/terms.inc:16 +msgid "Taxonomy terms" +msgstr "" + +#: plugins/contexts/terms.inc:17 +msgid "Multiple taxonomy terms, as a group." +msgstr "" + +#: plugins/contexts/terms.inc:25 +msgid "Term ID of first term" +msgstr "" + +#: plugins/contexts/terms.inc:26 +msgid "Term ID of all term, separated by + or ," +msgstr "" + +#: plugins/contexts/terms.inc:27 +msgid "Term name of first term" +msgstr "" + +#: plugins/contexts/terms.inc:28 +msgid "Term name of all terms, separated by + or ," +msgstr "" + +#: plugins/contexts/terms.inc:29 +msgid "Vocabulary ID of first term" +msgstr "" + +#: plugins/contexts/user.inc:16 +msgid "A single user object." +msgstr "" + +#: plugins/contexts/user.inc:24 +msgid "User ID" +msgstr "" + +#: plugins/contexts/user.inc:25 +msgid "User name" +msgstr "" + +#: plugins/contexts/vocabulary.inc:15 +msgid "Taxonomy vocabulary" +msgstr "" + +#: plugins/contexts/vocabulary.inc:16 +msgid "A single taxonomy vocabulary object." +msgstr "" + +#: plugins/relationships/book_parent.inc:14 +msgid "Book parent" +msgstr "" + +#: plugins/relationships/book_parent.inc:16 +msgid "Adds a book parent from a node context." +msgstr "" + +#: plugins/relationships/book_parent.inc:63 plugins/relationships/term_parent.inc:63 +msgid "Relationship type" +msgstr "" + +#: plugins/relationships/book_parent.inc:64 plugins/relationships/term_parent.inc:64 +msgid "Immediate parent" +msgstr "" + +#: plugins/relationships/book_parent.inc:64 +msgid "Top level book" +msgstr "" + +#: plugins/relationships/term_from_node.inc:14 +msgid "Term from node" +msgstr "" + +#: plugins/relationships/term_from_node.inc:16 +msgid "Adds a taxonomy term from a node context; if multiple terms are selected, this will get the \"first\" term only." +msgstr "" + +#: plugins/relationships/term_parent.inc:14 +msgid "Term parent" +msgstr "" + +#: plugins/relationships/term_parent.inc:16 +msgid "Adds a taxonomy term parent from a term context." +msgstr "" + +#: plugins/relationships/term_parent.inc:64 +msgid "Top level term" +msgstr "" + +#: plugins/relationships/user_from_node.inc:16 +msgid "Creates the author of a node as a user context." +msgstr "" + +#: views_content/views_content.module:61 views_content/plugins/content_types/views.inc:99 +msgid "Views" +msgstr "" + +#: views_content/views_content.module:92 +msgid "Make all views available as panes" +msgstr "" + +#: views_content/views_content.module:93 +msgid "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." +msgstr "" + +#: views_content/views_content.module:20 +msgid "Views panes" +msgstr "" + +#: views_content/views_content.module:24 +msgid "Configure Views to be used as CTools content." +msgstr "" + +#: views_content/views_content.info:0 +msgid "Views content panes" +msgstr "" + +#: views_content/views_content.info:0 +msgid "Allows Views content to be used in Panels, Dashboard and other modules which use the CTools Content API." +msgstr "" + +#: views_content/plugins/content_types/views.inc:18 +msgid "All views" +msgstr "" + +#: views_content/plugins/content_types/views.inc:33 +msgid "Select display" +msgstr "" + +#: views_content/plugins/content_types/views.inc:36 +msgid "Configure view" +msgstr "" + +#: views_content/plugins/content_types/views.inc:226 +msgid "Display" +msgstr "" + +#: views_content/plugins/content_types/views.inc:228 +msgid "Choose which display of this view you wish to use." +msgstr "" + +#: views_content/plugins/content_types/views.inc:249 views_content/plugins/content_types/views_panes.inc:282 +msgid "Broken/missing/deleted view." +msgstr "" + +#: views_content/plugins/content_types/views.inc:253 +msgid "Configure view @view (@display)" +msgstr "" + +#: views_content/plugins/content_types/views.inc:275 +msgid "Link title to view" +msgstr "" + +#: views_content/plugins/content_types/views.inc:281 +msgid "Provide a \"more\" link that links to the view" +msgstr "" + +#: views_content/plugins/content_types/views.inc:282 +msgid "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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:288 views_content/plugins/content_types/views_panes.inc:335 +msgid "Display feed icons" +msgstr "" + +#: views_content/plugins/content_types/views.inc:294 +msgid "Custom pager settings" +msgstr "" + +#: views_content/plugins/content_types/views.inc:299 +msgid "Use different pager settings from view settings" +msgstr "" + +#: views_content/plugins/content_types/views.inc:306 +msgid "<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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:313 views_content/plugins/content_types/views_panes.inc:343 views_content/plugins/views/views_content_plugin_display_panel_pane.inc:148 +msgid "Use pager" +msgstr "" + +#: views_content/plugins/content_types/views.inc:322 views_content/plugins/content_types/views_panes.inc:351 +msgid "Pager ID" +msgstr "" + +#: views_content/plugins/content_types/views.inc:335 +msgid "Num posts" +msgstr "" + +#: views_content/plugins/content_types/views.inc:343 views_content/plugins/content_types/views_panes.inc:372 +msgid "Offset" +msgstr "" + +#: views_content/plugins/content_types/views.inc:345 +msgid "The number of items to skip and not display." +msgstr "" + +#: views_content/plugins/content_types/views.inc:352 +msgid "Send arguments" +msgstr "" + +#: views_content/plugins/content_types/views.inc:354 +msgid "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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:362 +msgid "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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:368 +msgid "Override URL" +msgstr "" + +#: views_content/plugins/content_types/views.inc:370 +msgid "If this is set, override the View URL; this can sometimes be useful to set to the panel URL" +msgstr "" + +#: views_content/plugins/content_types/views.inc:394;406 views_content/plugins/content_types/views_panes.inc:411;414 +msgid "Deleted/missing view @view" +msgstr "" + +#: views_content/plugins/content_types/views.inc:396 +msgid "View: @name" +msgstr "" + +#: views_content/plugins/content_types/views.inc:409 +msgid "View information" +msgstr "" + +#: views_content/plugins/content_types/views.inc:412 +msgid "Using display @display." +msgstr "" + +#: views_content/plugins/content_types/views.inc:433 +msgid "Argument @arg using context @context converted into @converter" +msgstr "" + +#: views_content/plugins/content_types/views.inc:441 +msgid "@count items displayed." +msgstr "" + +#: views_content/plugins/content_types/views.inc:443 +msgid "With pager." +msgstr "" + +#: views_content/plugins/content_types/views.inc:446 +msgid "Without pager." +msgstr "" + +#: views_content/plugins/content_types/views.inc:450 +msgid "Skipping first @count results" +msgstr "" + +#: views_content/plugins/content_types/views.inc:453 +msgid "With more link." +msgstr "" + +#: views_content/plugins/content_types/views.inc:456 +msgid "With feed icon." +msgstr "" + +#: views_content/plugins/content_types/views.inc:459 +msgid "Sending arguments." +msgstr "" + +#: views_content/plugins/content_types/views.inc:462 +msgid "Using arguments: @args" +msgstr "" + +#: views_content/plugins/content_types/views.inc:465 +msgid "Using url: @url" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:15;94 views_content/plugins/views/views_content_plugin_display_panel_pane.inc:92 +msgid "View panes" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:319 +msgid "Link title to page" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:326 +msgid "Provide a \"more\" link." +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:363 +msgid "Num items" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:365 +msgid "Select the number of items to display, or 0 to display all results." +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:374 +msgid "Enter the number of items to skip; enter 0 to skip no items." +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:381 +msgid "Override path" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:383 +msgid "If this is set, override the View URL path; this can sometimes be useful to set to the panel URL." +msgstr "" + +#: views_content/plugins/views/views_content.views.inc:16 +msgid "Content pane" +msgstr "" + +#: views_content/plugins/views/views_content.views.inc:17 +msgid "Is available as content for a panel or dashboard display." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:56 +msgid "Pane settings" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:61 +msgid "Use view name" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:70 +msgid "Admin title" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:76 +msgid "Use view description" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:85 +msgid "Admin desc" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:101 +msgid "Category" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:107;151 +msgid "Link to view" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:108;114;208;218 +msgid "Yes" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:108;114;208;218 +msgid "No" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:113 +msgid "Use Panel path" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:119 +msgid "Argument input" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:128;142 +msgid "Allow settings" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "None" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "All" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "Some" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:144 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:149 +msgid "Items per page" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:150 +msgid "Pager offset" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:152 +msgid "More link" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:153 +msgid "Path override" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:154 +msgid "Title override" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:171 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:181 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:193 +msgid "This is category the pane will appear in on the add content dialog." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:199 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:204 +msgid "Link pane title to view" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:214 +msgid "Inherit path from panel display" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:220 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:225 +msgid "Choose the data source for view arguments" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:242 +msgid "No argument" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:243 +msgid "Argument wildcard" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:244 +msgid "From context" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:245 +msgid "From panel argument" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:246 +msgid "Fixed" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:247 +msgid "Input on pane config" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:250 +msgid "@arg source" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:256 +msgid "Required context" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:257 +msgid "If \"From context\" is selected, which type of context to use." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:266 +msgid "Context is optional" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:267 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:275 +msgid "Panel argument" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:276 +msgid "If \"From panel argument\" is selected, which panel argument to use." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +msgid "First" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +msgid "Second" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +msgid "Third" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +msgid "Fourth" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +msgid "Fifth" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +msgid "Sixth" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:285 +msgid "Fixed argument" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:286 +msgid "If \"Fixed\" is selected, what to use as an argument." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:294 +msgid "Label" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:295 +msgid "If this argument is presented to the panels user, what label to apply to it." +msgstr "" + diff --git a/sites/all/modules/ctools/translations/general.de.po b/sites/all/modules/ctools/translations/general.de.po new file mode 100644 index 0000000000000000000000000000000000000000..e3ad38c2cfdfbf14e11b502e877c8d6c17996af2 --- /dev/null +++ b/sites/all/modules/ctools/translations/general.de.po @@ -0,0 +1,451 @@ +# $Id: general.de.po,v 1.1 2009/08/16 21:28:46 hass Exp $ +# +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# panels.module,v 1.10.2.9 2007/03/15 23:13:41 merlinofchaos +# fourcol_25_25_25_25.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# threecol_33_33_33.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_25_75.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_33_66.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_38_62.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_50_50.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_62_38.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_66_33.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_75_25.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# threecol_25_50_25_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# threecol_33_34_33.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# threecol_33_34_33_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# twocol.inc,v 1.6 2006/08/22 23:54:20 merlinofchaos +# twocol_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# +msgid "" +msgstr "" +"Project-Id-Version: panels 5.x\n" +"POT-Creation-Date: 2009-08-16 20:47+0200\n" +"PO-Revision-Date: 2009-08-16 22:16+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: Alexander Hass\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" + +#: bulk_export/bulk_export.module:165 +#: page_manager/page_manager.admin.inc:663 +#: page_manager/plugins/tasks/page.inc:182 +msgid "Export" +msgstr "Exportieren" + +#: includes/ajax.inc:123 +#: page_manager/page_manager.admin.inc:906 +msgid "Error" +msgstr "Fehler" + +#: includes/content.inc:539 +#: page_manager/page_manager.admin.inc:559 +msgid "Configure" +msgstr "Konfigurieren" + +#: includes/content.menu.inc:45 +#: plugins/content_types/node_context/node_author.inc:36 +#: plugins/contexts/user.inc:50 +msgid "Anonymous" +msgstr "Gast" + +#: includes/context-access-admin.inc:174;405 +#: includes/context-admin.inc:565;644;715;826 +#: page_manager/page_manager.admin.inc:1156 +msgid "Save" +msgstr "Speichern" + +#: includes/context-access-admin.inc:214 +#: includes/context-admin.inc:793 +#: page_manager/page_manager.admin.inc:72;248;1295 +#: page_manager/plugins/tasks/page.admin.inc:645 +#: plugins/content_types/custom/custom.inc:105 +msgid "Title" +msgstr "Titel" + +#: includes/context-admin.inc:26 +#: page_manager/plugins/tasks/page.inc:158 +#: views_content/plugins/content_types/views.inc:360 +msgid "Arguments" +msgstr "Argumente" + +#: includes/context-admin.inc:312;436;874 +#: page_manager/plugins/tasks/page.admin.inc:948 +msgid "Invalid object name." +msgstr "Ungültiger Objektname." + +#: includes/context-admin.inc:540;628;690;800 +#: plugins/content_types/node/node.inc:146 +#: plugins/content_types/node_context/node_content.inc:162 +#: plugins/content_types/node_context/node_links.inc:93 +msgid "Identifier" +msgstr "Bezeichner" + +#: includes/context-admin.inc:547;635;697;807 +#: plugins/content_types/custom/custom.inc:138 +msgid "Keyword" +msgstr "Platzhalter" + +#: includes/context-admin.inc:782 +#: includes/export.inc:191;254 +#: page_manager/page_manager.module:499;514 +#: page_manager/plugins/tasks/page.inc:216 +#: views_content/plugins/content_types/views.inc:449 +msgid "Default" +msgstr "Standard" + +#: includes/context.inc:195;196;400 +#: page_manager/plugins/tasks/page.admin.inc:1116;1136 +msgid "No context" +msgstr "Kein Kontext" + +#: includes/context.theme.inc:80 +#: page_manager/plugins/tasks/page.admin.inc:687 +#: page_manager/theme/page_manager.theme.inc:103 +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:196 +msgid "Weight" +msgstr "Reihenfolge" + +#: includes/context.theme.inc:82 +#: plugins/access/node_access.inc:35 +msgid "Operation" +msgstr "Operation" + +#: includes/export.inc:146 +#: page_manager/page_manager.module:365 +#: page_manager/plugins/tasks/page.admin.inc:1452 +msgid "Normal" +msgstr "Normal" + +#: includes/export.inc:184 +#: page_manager/page_manager.admin.inc:1453 +#: page_manager/page_manager.module:508 +#: page_manager/plugins/tasks/page.admin.inc:1481;1495;1506 +msgid "Overridden" +msgstr "Übersteuert" + +#: includes/export.inc:586 +#: page_manager/page_manager.module:635 +msgid "Local" +msgstr "Lokal" + +#: includes/modal.inc:54 +#: js/modal.js:0 +msgid "Loading..." +msgstr "Laden..." + +#: includes/wizard.inc:273 +#: page_manager/page_manager.admin.inc:1162 +msgid "Cancel" +msgstr "Abbrechen" + +#: page_manager/page_manager.admin.inc:70;219;251 +#: page_manager/plugins/tasks/page.admin.inc:633 +msgid "Type" +msgstr "Typ" + +#: page_manager/page_manager.admin.inc:73;250 +#: page_manager/plugins/tasks/page.admin.inc:394;1240;1366 +#: page_manager/plugins/tasks/page.inc:629 +#: page_manager/plugins/tasks/term_view.inc:258 +msgid "Path" +msgstr "Pfad" + +#: page_manager/page_manager.admin.inc:74;226;252 +#: page_manager/plugins/tasks/page.inc:46;574 +msgid "Storage" +msgstr "Speicher" + +#: page_manager/page_manager.admin.inc:77 +#: page_manager/plugins/tasks/page.admin.inc:905 +msgid "Operations" +msgstr "Operationen" + +#: page_manager/page_manager.admin.inc:153 +#: page_manager/plugins/tasks/page.inc:216 +msgid "In code" +msgstr "Im Code" + +#: page_manager/page_manager.admin.inc:171 +#: page_manager/page_manager.module:79 +#: page_manager/plugins/tasks/page.inc:605;647;683 +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:120 +msgid "Edit" +msgstr "Bearbeiten" + +#: page_manager/page_manager.admin.inc:179;504;510;689;694 +#: page_manager/plugins/tasks/page.inc:580 +msgid "Enable" +msgstr "Aktivieren" + +#: page_manager/page_manager.admin.inc:185;517;523;700;705 +#: page_manager/plugins/tasks/page.inc:584 +msgid "Disable" +msgstr "Deaktivieren" + +#: page_manager/page_manager.admin.inc:233;234 +#: page_manager/plugins/tasks/page.inc:585 +msgid "Enabled" +msgstr "Aktiviert" + +#: page_manager/page_manager.admin.inc:234 +#: page_manager/plugins/tasks/page.inc:581 +msgid "Disabled" +msgstr "Deaktiviert" + +#: page_manager/page_manager.admin.inc:658 +#: page_manager/plugins/tasks/page.admin.inc:1380 +#: page_manager/plugins/tasks/page.inc:177 +msgid "Clone" +msgstr "Duplizieren" + +#: page_manager/page_manager.admin.inc:669;673 +#: page_manager/plugins/tasks/page.admin.inc:1495 +#: page_manager/plugins/tasks/page.inc:188 +msgid "Revert" +msgstr "Zurücksetzen" + +#: page_manager/page_manager.admin.inc:679;683 +#: page_manager/plugins/tasks/page.admin.inc:1495 +#: page_manager/plugins/tasks/page.inc:195 +#: plugins/access/node_access.inc:40 +msgid "Delete" +msgstr "Löschen" + +#: page_manager/page_manager.admin.inc:795 +#: plugins/access/node_access.inc:39 +msgid "Update" +msgstr "Aktualisieren" + +#: page_manager/plugins/tasks/page.admin.inc:367;1358 +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:166 +msgid "Administrative title" +msgstr "Administrativer Titel" + +#: page_manager/plugins/tasks/page.admin.inc:386 +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:176;186 +msgid "Administrative description" +msgstr "Administrative Beschreibung" + +#: page_manager/plugins/tasks/page.inc:207 +#: plugins/content_types/custom/custom.inc:26;58 +#: plugins/content_types/node/node.inc:27 +msgid "Custom" +msgstr "Benutzerdefiniert" + +#: page_manager/plugins/tasks/page.inc:304 +#: page_manager/plugins/tasks/term_view.inc:133 +#: plugins/access/node_access.inc:38 +msgid "View" +msgstr "Anzeigen" + +#: page_manager/plugins/tasks/term_view.inc:230 +#: plugins/arguments/terms.inc:55 +msgid "Inject hierarchy of first term into breadcrumb trail" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:233 +#: plugins/arguments/term.inc:94 +#: plugins/arguments/terms.inc:58 +msgid "If checked, taxonomy term parents will appear in the breadcrumb trail." +msgstr "Sobald aktiviert, werden übergeordnete Taxonomie-Begriffe in der Pfadnavigation erscheinen." + +#: plugins/access/node_access.inc:22 +#: plugins/access/perm.inc:20 +#: plugins/access/role.inc:21 +#: plugins/content_types/user_context/profile_fields.inc:15;16 +#: plugins/content_types/user_context/user_picture.inc:13;14 +#: plugins/content_types/user_context/user_profile.inc:13;14 +#: plugins/contexts/user.inc:15 +msgid "User" +msgstr "Benutzer" + +#: plugins/access/node_access.inc:23 +#: plugins/access/node_language.inc:22 +#: plugins/access/node_type.inc:21 +#: plugins/content_types/node/node.inc:15 +#: plugins/content_types/node_context/node_attachments.inc:13;14 +#: plugins/content_types/node_context/node_author.inc:13;14 +#: plugins/content_types/node_context/node_body.inc:13;14 +#: plugins/content_types/node_context/node_book_nav.inc:14;15 +#: plugins/content_types/node_context/node_comment_form.inc:14;15 +#: plugins/content_types/node_context/node_comments.inc:15;16 +#: plugins/content_types/node_context/node_content.inc:13;14 +#: plugins/content_types/node_context/node_created.inc:13;14 +#: plugins/content_types/node_context/node_links.inc:14;15 +#: plugins/content_types/node_context/node_title.inc:13;14 +#: plugins/content_types/node_context/node_type_desc.inc:13;14 +#: plugins/content_types/node_context/node_updated.inc:13;14 +#: plugins/contexts/node.inc:16 +#: plugins/relationships/book_parent.inc:17 +#: plugins/relationships/term_from_node.inc:17 +#: plugins/relationships/user_from_node.inc:17 +msgid "Node" +msgstr "Beitrag" + +#: plugins/access/node_type.inc:38 +#: plugins/contexts/node.inc:170 +#: plugins/contexts/node_add_form.inc:21;101 +msgid "Node type" +msgstr "Inhaltstyp" + +#: plugins/access/term_vocabulary.inc:21 +#: plugins/content_types/term_context/term_description.inc:13 +#: plugins/content_types/term_context/term_list.inc:13 +#: plugins/relationships/term_parent.inc:17 +msgid "Term" +msgstr "Begriff" + +#: plugins/arguments/nid.inc:15 +#: plugins/contexts/node.inc:166 +msgid "Node ID" +msgstr "Beitrag-ID" + +#: plugins/arguments/node_add.inc:15 +#: plugins/contexts/node_add_form.inc:15 +msgid "Node add form" +msgstr "Beitragserstellungsformular" + +#: plugins/arguments/node_edit.inc:15 +#: plugins/contexts/node_edit_form.inc:15 +msgid "Node edit form" +msgstr "Beitragsbearbeitungsformular" + +#: plugins/arguments/string.inc:15 +#: plugins/contexts/string.inc:15 +msgid "String" +msgstr "Zeichenkette" + +#: plugins/arguments/term.inc:15 +#: plugins/content_types/term_context/term_description.inc:14 +#: plugins/content_types/term_context/term_list.inc:14 +#: plugins/contexts/term.inc:15 +msgid "Taxonomy term" +msgstr "Taxonomie-Begriff" + +#: plugins/arguments/term.inc:84 +#: plugins/contexts/term.inc:24 +msgid "Term ID" +msgstr "Begriffs-ID" + +#: plugins/arguments/term.inc:84 +#: plugins/contexts/term.inc:25 +msgid "Term name" +msgstr "Begriffsname" + +#: plugins/arguments/uid.inc:15 +#: plugins/contexts/user.inc:24 +msgid "User ID" +msgstr "Benutzer-ID" + +#: plugins/arguments/vid.inc:15 +#: plugins/contexts/term.inc:26 +msgid "Vocabulary ID" +msgstr "Vokabular-ID" + +#: plugins/content_types/block/block.inc:331;336;354;378;388 +#: views_content/views_content.module:56 +msgid "Widgets" +msgstr "Steuerelement" + +#: plugins/content_types/form/form.inc:16;17;43 +#: plugins/content_types/node_form/node_form_attachments.inc:14;15 +#: plugins/content_types/node_form/node_form_author.inc:13;14 +#: plugins/content_types/node_form/node_form_book.inc:14;15 +#: plugins/content_types/node_form/node_form_buttons.inc:13;14 +#: plugins/content_types/node_form/node_form_comment.inc:14;15 +#: plugins/content_types/node_form/node_form_input_format.inc:13;14 +#: plugins/content_types/node_form/node_form_log.inc:13;14 +#: plugins/content_types/node_form/node_form_menu.inc:14;15 +#: plugins/content_types/node_form/node_form_path.inc:14;15 +#: plugins/content_types/node_form/node_form_publishing.inc:19;20 +#: plugins/content_types/node_form/node_form_taxonomy.inc:14;15 +msgid "Form" +msgstr "Formular" + +#: plugins/content_types/node/node.inc:70 +#: plugins/content_types/node_context/node_content.inc:61 +msgid "Edit node" +msgstr "Beitrag bearbeiten" + +#: plugins/content_types/node/node.inc:71 +#: plugins/content_types/node_context/node_content.inc:62 +msgid "Edit this node" +msgstr "Diesen Beitrag bearbeiten" + +#: plugins/content_types/node/node.inc:106 +#: plugins/contexts/node.inc:81 +#: plugins/contexts/node_edit_form.inc:80 +msgid "Enter the title or NID of a node" +msgstr "Den Titel oder die Beitrag-ID eines Beitrages eingeben" + +#: plugins/content_types/node/node.inc:123 +#: plugins/content_types/node_context/node_content.inc:134 +msgid "Teaser" +msgstr "Anrisstext" + +#: plugins/content_types/node/node.inc:132 +#: plugins/content_types/node_context/node_content.inc:148 +msgid "Display links" +msgstr "Links anzeigen" + +#: plugins/content_types/node/node.inc:133 +#: plugins/content_types/node_context/node_content.inc:149 +msgid "Check here to display the links with the post." +msgstr "Aktivieren, um die Links mit dem Beitrag anzuzeigen." + +#: plugins/content_types/node/node.inc:139 +#: plugins/content_types/node_context/node_content.inc:169 +msgid "Leave node title" +msgstr "Beitragstitel beibehalten" + +#: plugins/content_types/node/node.inc:140 +#: plugins/content_types/node_context/node_content.inc:170 +msgid "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." +msgstr "Erweitert: Falls aktiviert, bleibt der Beitragstitel unberührt. Dies kann zur doppelten Darstellung in der Ausgabe führen, sofern die Theme dies nicht berücksichtigt." + +#: plugins/content_types/node/node.inc:147 +#: plugins/content_types/node_context/node_content.inc:163 +msgid "Whatever is placed here will appear in $node->panel_identifier in the node template to make it easier to theme a node or part of a node as necessary. This identifier will automatically be added as a node template suggestion: node-panel-IDENTIFIER.tpl.php" +msgstr "Was immer hier steht wird in $node->panel_identifier bereitgestellt, um die Gestaltung von Beiträgen oder Teilen von Beiträgen zu vereinfachen. Dieser Identifikator wird automatisch als Vorlagen-Vorschlag hinzugefügt: node-panel-IDENTIFIER.tpl.php" + +#: plugins/content_types/node_context/node_author.inc:10 +#: plugins/relationships/user_from_node.inc:14 +msgid "Node author" +msgstr "Beitragsauthor" + +#: plugins/content_types/node_context/node_title.inc:10 +#: plugins/contexts/node.inc:168 +msgid "Node title" +msgstr "Beitragstitel" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:14;15 +#: plugins/contexts/term.inc:68 +#: plugins/contexts/vocabulary.inc:58 +#: plugins/relationships/term_from_node.inc:52 +msgid "Vocabulary" +msgstr "Vokabular" + +#: views_content/views_content.module:61 +#: views_content/plugins/content_types/views.inc:99 +msgid "Views" +msgstr "Ansichten" + +#: views_content/plugins/content_types/views.inc:317 +#: views_content/plugins/content_types/views_panes.inc:341 +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:148 +msgid "Use pager" +msgstr "Seitennavigation verwenden" + +#: views_content/plugins/content_types/views_panes.inc:15;94 +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:92 +msgid "View panes" +msgstr "" + diff --git a/sites/all/modules/ctools/translations/general.hu.po b/sites/all/modules/ctools/translations/general.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..435ed0531fa89bbe1be09d6c743a4031cd9511d1 --- /dev/null +++ b/sites/all/modules/ctools/translations/general.hu.po @@ -0,0 +1,268 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 12:50+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 "Delete" +msgstr "Törlés" +msgid "Operations" +msgstr "Műveletek" +msgid "Type" +msgstr "Típus" +msgid "Cancel" +msgstr "Mégsem" +msgid "Language" +msgstr "Nyelv" +msgid "Enable" +msgstr "Engedélyezés" +msgid "Disable" +msgstr "Letilt" +msgid "Disabled" +msgstr "Tiltott" +msgid "Enabled" +msgstr "Engedélyezett" +msgid "Edit" +msgstr "Szerkesztés" +msgid "Search" +msgstr "Keresés" +msgid "Weight" +msgstr "Súly" +msgid "Settings" +msgstr "Beállítások" +msgid "Export" +msgstr "Export" +msgid "Taxonomy term" +msgstr "Taxonómia kifejezés" +msgid "Save" +msgstr "Mentés" +msgid "Default" +msgstr "Alapértelmezés" +msgid "Update" +msgstr "Frissítés" +msgid "Views" +msgstr "Nézetek" +msgid "Access" +msgstr "Hozzáférés" +msgid "View" +msgstr "Megtekintés" +msgid "Path" +msgstr "Útvonal" +msgid "Node type" +msgstr "Tartalomtípus" +msgid "Menu" +msgstr "Menü" +msgid "Keywords" +msgstr "Kulcsszavak" +msgid "User" +msgstr "Felhasználó" +msgid "Configure" +msgstr "Beállítás" +msgid "Error" +msgstr "Hiba" +msgid "Node" +msgstr "Tartalom" +msgid "Date format" +msgstr "Dátumformátum" +msgid "Pager ID" +msgstr "Lapozó azonosító" +msgid "Breadcrumb" +msgstr "Menümorzsa" +msgid "Custom" +msgstr "Egyedi" +msgid "Input format" +msgstr "Beviteli forma" +msgid "Vocabulary" +msgstr "Szótár" +msgid "Term" +msgstr "Kifejezés" +msgid "Term ID" +msgstr "Kifejezés azonosító" +msgid "Term name" +msgstr "Kifejezés neve" +msgid "Overridden" +msgstr "Felülírva" +msgid "Normal" +msgstr "Normál" +msgid "System" +msgstr "Rendszer" +msgid "Basic" +msgstr "Alap" +msgid "Role" +msgstr "Csoport" +msgid "String" +msgstr "Karaktersorozat" +msgid "Anonymous" +msgstr "Anonymous" +msgid "Clone" +msgstr "Klónozás" +msgid "Arguments" +msgstr "Argumentumok" +msgid "Operation" +msgstr "Művelet" +msgid "Node title" +msgstr "Tartalom címe" +msgid "Revert" +msgstr "Visszaállítás" +msgid "Open in new window" +msgstr "Megnyitás új ablakban" +msgid "Loading..." +msgstr "Betöltés..." +msgid "Storage" +msgstr "Tárolás" +msgid "You must select a node." +msgstr "Ki kell választani egy tartalmat." +msgid "Relationship type" +msgstr "Kapcsolattípus" +msgid "Form" +msgstr "Űrlap" +msgid "Node author" +msgstr "Tartalom szerzője" +msgid "Node title." +msgstr "Tartalom címe." +msgid "Edit node" +msgstr "Tartalom szerkesztése" +msgid "Edit this node" +msgstr "Ennek a tartalomnak a szerkesztése" +msgid "Link title to node" +msgstr "A cím hivatkozzon a tartalomra" +msgid "Check here to make the title link to the node." +msgstr "Bejelölve a cím a tartalomra fog hivatkozni." +msgid "Identifier" +msgstr "Azonosító" +msgid "Publishing options on the Node form." +msgstr "Közzétételi beállítások a tartalom űrlapon." +msgid "Term description goes here." +msgstr "Ide jön a kifejezés leírása." +msgid "Currently set to !link" +msgstr "Jelenlegi beállítás: !link" +msgid "Invalid node selected." +msgstr "Érvénytelen tartalom lett kiválasztva." +msgid "Select the vocabulary for this form." +msgstr "Szótár kiválasztása ehhez az űrlaphoz." +msgid "Keyword" +msgstr "Kulcsszó" +msgid "No context" +msgstr "Nincs környezet." +msgid "Local" +msgstr "Helyi" +msgid "Leave node title" +msgstr "Tartalom címének meghagyása" +msgid "" +"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." +msgstr "" +"Haladó: ha be van jelölve, nem nyúl a tartalom címéhez; a cím " +"kétszer jelenhet meg, kivéve ha a smink gondoskodik erről." +msgid "Use pager" +msgstr "Lapozó használata" +msgid "Offset" +msgstr "Eltolás" +msgid "Display feed icons" +msgstr "Hírolvasó ikon megjelenítése" +msgid "Deleted/missing view @view" +msgstr "Törölt/hiányzó @view nézet" +msgid "Immediate parent" +msgstr "Közvetlen szülő" +msgid "Widgets" +msgstr "Felületi elemek" +msgid "Relcontext" +msgstr "Relcontext" +msgid "Simplecontext" +msgstr "Simplecontext" +msgid "Page elements" +msgstr "Oldalelemek" +msgid "Search type" +msgstr "Keresés típusa" +msgid "Chaos tool suite" +msgstr "Chaos tool suite" +msgid "Default site language" +msgstr "A webhely alapértelmezett nyelve" +msgid "No menu entry" +msgstr "Nincs menübejegyzés" +msgid "Configure settings for this item." +msgstr "Az elem beállításainak szerkesztése." +msgid "Remove this item." +msgstr "Elem eltávolítása." +msgid "Invalid object name." +msgstr "Érvénytelen objektumnév." +msgid "In code" +msgstr "Kódban" +msgid "Administrative title" +msgstr "Adminisztratív cím" +msgid "Administrative description" +msgstr "Adminisztratív leírás" +msgid "Edit name, path and other basic settings for the page." +msgstr "" +"Az oldal nevének, elérési útjának és egyéb " +"alapbeállításainak szerkesztése." +msgid "page-summary-label" +msgstr "page-summary-label" +msgid "page-summary-data" +msgstr "page-summary-data" +msgid "page-summary-operation" +msgstr "page-summary-operation" +msgid "This page is publicly accessible." +msgstr "Ez az oldal nyivánosan elérhető." +msgid "Inject hierarchy of first term into breadcrumb trail" +msgstr "Az első kifejezés hierarchiájának beillesztése a morzsasávba" +msgid "If checked, taxonomy term parents will appear in the breadcrumb trail." +msgstr "" +"Ha be van jelölve, akkor a taxonómia kifejezés szülői megjelennek " +"a morzsasávban." +msgid "User being viewed" +msgstr "Megtekintett felhasználó" +msgid "Control access by role." +msgstr "Hozzáférés szabályozása csoport alapján." +msgid "Only the checked roles will be granted access." +msgstr "Csak a bejelölt csoportok kapnak hozzáférési jogot." +msgid "@identifier can have any role" +msgstr "@identifier bármelyik csoportban lehet" +msgid "Enter the node ID of a node for this argument" +msgstr "Egy tartalom azonosítójának megadása ehhez az argumentumhoz" +msgid "node_form" +msgstr "node_form" +msgid "'%title' [node id %nid]" +msgstr "'%title' [tartalomazonosító %nid]" +msgid "Reset identifier to node title" +msgstr "Azonosító visszaállítása a tartalom címére" +msgid "" +"If checked, the identifier will be reset to the node title of the " +"selected node." +msgstr "" +"Ha be van jelölve, akkor az azonosító a kiválasztott tartalom " +"címére lesz visszaállítva." +msgid "Broken/missing/deleted view." +msgstr "Hibás/hiányzó/törölt nézet." +msgid "View panes" +msgstr "Nézettáblák" +msgid "CTools Examples" +msgstr "CTools példák" +msgid "Enter the title or NID of a node" +msgstr "Egy tartalom címének vagy tartalomazonosítójának megadása" +msgid "Show only node teaser" +msgstr "Csak a tartalom bevezetőjének mutatása" +msgid "Include node links for \"add comment\", \"read more\" etc." +msgstr "" +"„Új hozzászólás”, „Tovább”, stb., tartalomhivatkozások " +"hozzáadása." +msgid "Template identifier" +msgstr "Sablonazonosító" +msgid "" +"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." +msgstr "" +"Ez az azonosító a tartalmat megjelenítő sablonjavaslataként lesz " +"hozzáadva: node-panel-IDENTIFIER.tpl.php. A sablonjavaslatokról " +"részletesen a Drupal smink kézikönyvben lehet olvasni." diff --git a/sites/all/modules/ctools/translations/general.pot b/sites/all/modules/ctools/translations/general.pot new file mode 100644 index 0000000000000000000000000000000000000000..37f603e2155bf057f0f290bdb4e7803ce472eb4b --- /dev/null +++ b/sites/all/modules/ctools/translations/general.pot @@ -0,0 +1,3829 @@ +# $Id$ +# +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# ctools.install,v 1.14 2009/10/17 22:58:24 sdboyer +# ctools.info,v 1.6 2009/10/17 22:58:24 sdboyer +# bulk_export.info,v 1.3 2009/10/08 11:03:24 sun +# ctools_plugin_example.info,v 1.2 2009/10/08 11:03:24 sun +# page_manager.info,v 1.4 2009/10/17 22:58:26 sdboyer +# views_content.info,v 1.4 2009/10/17 22:58:24 sdboyer +# bulk_export.module,v 1.4 2009/10/17 22:58:24 sdboyer +# page_manager.admin.inc,v 1.34 2009/10/15 18:38:14 merlinofchaos +# page.inc,v 1.20 2009/10/17 22:58:24 sdboyer +# ctools_plugin_example.module,v 1.2 2009/10/17 22:58:24 sdboyer +# arg_length.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# simplecontext_content_type.inc,v 1.2 2009/10/13 20:55:50 merlinofchaos +# simplecontext.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# relcontext_from_simplecontext.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# example_role.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# role.inc,v 1.8 2009/10/12 12:42:53 sdboyer +# node_access.inc,v 1.8 2009/10/12 12:42:53 sdboyer +# perm.inc,v 1.7 2009/10/12 12:42:53 sdboyer +# user_contact.inc,v 1.2 2009/10/12 23:18:29 merlinofchaos +# profile_fields.inc,v 1.6 2009/10/08 11:18:57 sun +# user_picture.inc,v 1.4 2009/09/27 03:41:03 merlinofchaos +# user_profile.inc,v 1.8 2009/09/27 03:41:03 merlinofchaos +# user.inc,v 1.6 2009/10/12 12:42:54 sdboyer +# simplecontext_arg.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# no_context_content_type.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# relcontext_content_type.inc,v 1.2 2009/10/13 20:55:50 merlinofchaos +# relcontext.inc,v 1.1 2009/08/17 22:02:26 merlinofchaos +# ajax.inc,v 1.17 2009/10/12 12:42:53 sdboyer +# content.inc,v 1.16 2009/10/21 21:25:35 merlinofchaos +# content.menu.inc,v 1.4 2009/10/17 22:58:25 sdboyer +# node_author.inc,v 1.1 2009/07/18 22:10:48 merlinofchaos +# context-access-admin.inc,v 1.10 2009/10/17 22:58:25 sdboyer +# context-admin.inc,v 1.12 2009/10/12 12:42:53 sdboyer +# page.admin.inc,v 1.23 2009/10/17 22:58:24 sdboyer +# custom.inc,v 1.10 2009/10/12 12:42:53 sdboyer +# search_result.inc,v 1.2 2009/10/12 23:16:11 merlinofchaos +# views.inc,v 1.14 2009/10/21 20:18:05 merlinofchaos +# node_links.inc,v 1.3 2009/09/27 03:41:02 merlinofchaos +# export.inc,v 1.22 2009/10/17 22:58:25 sdboyer +# page_manager.module,v 1.23 2009/10/18 01:22:28 sdboyer +# search_form.inc,v 1.2 2009/10/12 23:16:11 merlinofchaos +# context-task-handler.inc,v 1.26 2009/10/17 22:58:25 sdboyer +# context.inc,v 1.36 2009/10/12 12:42:53 sdboyer +# context.theme.inc,v 1.10 2009/10/17 22:58:25 sdboyer +# page_manager.theme.inc,v 1.7 2009/10/18 01:22:28 sdboyer +# views_content_plugin_display_panel_pane.inc,v 1.3 2009/09/09 18:25:03 merlinofchaos +# css.inc,v 1.13 2009/10/17 22:58:25 sdboyer +# form.inc,v 1.11 2009/08/13 22:24:02 merlinofchaos +# menu.inc,v 1.5 2009/10/17 22:58:25 sdboyer +# modal.inc,v 1.9 2009/10/13 20:06:56 merlinofchaos +# modal.js,v 1.20 2009/10/13 20:06:56 merlinofchaos +# wizard.inc,v 1.14 2009/10/08 11:09:56 sun +# term_view.inc,v 1.6 2009/10/08 11:09:57 sun +# search.inc,v 1.2 2009/10/12 23:16:11 merlinofchaos +# blog.inc,v 1.2 2009/10/13 18:11:15 merlinofchaos +# blog_user.inc,v 1.3 2009/10/13 18:12:09 merlinofchaos +# contact_user.inc,v 1.3 2009/10/13 18:11:15 merlinofchaos +# user_view.inc,v 1.4 2009/10/18 01:22:28 sdboyer +# contact_site.inc,v 1.2 2009/10/12 23:18:29 merlinofchaos +# node_edit.inc,v 1.4 2009/09/27 03:41:02 merlinofchaos +# node_view.inc,v 1.4 2009/08/04 21:43:06 merlinofchaos +# node.inc,v 1.8 2009/10/17 22:58:26 sdboyer +# poll.inc,v 1.1 2009/10/13 18:27:39 merlinofchaos +# terms.inc,v 1.4 2009/10/12 12:42:53 sdboyer +# term.inc,v 1.8 2009/10/12 12:42:53 sdboyer +# page_breadcrumb.inc,v 1.2 2009/10/17 22:58:26 sdboyer +# compare_users.inc,v 1.4 2009/10/12 12:42:53 sdboyer +# node_language.inc,v 1.8 2009/10/12 12:42:53 sdboyer +# node_type.inc,v 1.10 2009/10/18 01:22:28 sdboyer +# node_attachments.inc,v 1.2 2009/09/27 03:41:02 merlinofchaos +# node_body.inc,v 1.3 2009/09/27 03:41:02 merlinofchaos +# node_book_nav.inc,v 1.2 2009/09/27 03:41:02 merlinofchaos +# node_comment_form.inc,v 1.2 2009/09/27 03:41:02 merlinofchaos +# node_comments.inc,v 1.4 2009/10/17 22:58:26 sdboyer +# node_content.inc,v 1.5 2009/09/27 03:41:02 merlinofchaos +# node_created.inc,v 1.2 2009/09/27 03:41:02 merlinofchaos +# node_title.inc,v 1.3 2009/09/27 03:41:02 merlinofchaos +# node_type_desc.inc,v 1.2 2009/09/27 03:41:02 merlinofchaos +# node_updated.inc,v 1.2 2009/09/27 03:41:02 merlinofchaos +# node.inc,v 1.14 2009/10/17 22:58:25 sdboyer +# book_parent.inc,v 1.4 2009/10/17 22:58:26 sdboyer +# term_from_node.inc,v 1.4 2009/10/21 21:25:35 merlinofchaos +# user_from_node.inc,v 1.6 2009/10/18 01:22:28 sdboyer +# site_language.inc,v 1.7 2009/10/12 12:42:53 sdboyer +# node_add_form.inc,v 1.11 2009/10/12 12:42:54 sdboyer +# php.inc,v 1.4 2009/10/18 01:22:28 sdboyer +# term.inc,v 1.3 2009/10/18 01:22:28 sdboyer +# term_vocabulary.inc,v 1.5 2009/10/12 12:42:53 sdboyer +# term_description.inc,v 1.2 2009/09/27 03:41:02 merlinofchaos +# term_list.inc,v 1.5 2009/10/17 22:58:24 sdboyer +# term_parent.inc,v 1.5 2009/10/17 22:58:26 sdboyer +# vocabulary_terms.inc,v 1.5 2009/10/17 22:58:25 sdboyer +# term.inc,v 1.8 2009/10/17 22:58:25 sdboyer +# vocabulary.inc,v 1.4 2009/10/12 12:42:54 sdboyer +# nid.inc,v 1.9 2009/10/12 12:42:53 sdboyer +# node_edit.inc,v 1.6 2009/10/12 12:42:53 sdboyer +# node_add.inc,v 1.4 2009/10/12 12:42:53 sdboyer +# string.inc,v 1.5 2009/10/12 12:42:53 sdboyer +# string.inc,v 1.7 2009/10/12 12:42:54 sdboyer +# uid.inc,v 1.11 2009/10/12 12:42:53 sdboyer +# user_name.inc,v 1.2 2009/10/12 12:42:53 sdboyer +# vid.inc,v 1.5 2009/10/12 12:42:53 sdboyer +# block.inc,v 1.11 2009/10/18 01:22:28 sdboyer +# contact.inc,v 1.2 2009/10/12 23:18:29 merlinofchaos +# views_content.module,v 1.5 2009/10/17 22:58:24 sdboyer +# form.inc,v 1.1 2009/04/18 02:00:34 merlinofchaos +# node_form_attachments.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_author.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_book.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_buttons.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_comment.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_input_format.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_log.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_menu.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_path.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_publishing.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_form_taxonomy.inc,v 1.1 2009/04/18 02:00:35 merlinofchaos +# node_edit_form.inc,v 1.13 2009/10/17 22:58:25 sdboyer +# page_footer_message.inc,v 1.2 2009/10/17 22:58:26 sdboyer +# page_help.inc,v 1.2 2009/10/17 22:58:26 sdboyer +# page_messages.inc,v 1.2 2009/10/17 22:58:26 sdboyer +# page_mission.inc,v 1.2 2009/10/17 22:58:26 sdboyer +# page_slogan.inc,v 1.2 2009/10/17 22:58:26 sdboyer +# page_tabs.inc,v 1.2 2009/10/17 22:58:26 sdboyer +# page_title.inc,v 1.2 2009/10/17 22:58:26 sdboyer +# terms.inc,v 1.7 2009/10/17 22:58:25 sdboyer +# views_panes.inc,v 1.18 2009/10/21 19:52:00 merlinofchaos +# views_content.views.inc,v 1.3 2009/10/17 22:58:26 sdboyer +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-11-20 23:20+0100\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" + +#: ctools.install:17 +msgid "CTools CSS Cache" +msgstr "" + +#: ctools.install:19 +msgid "Exists" +msgstr "" + +#: ctools.install:24 +msgid "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." +msgstr "" + +#: ctools.install:26 +msgid "Unable to create" +msgstr "" + +#: ctools.install:92 +msgid "A special cache used to store objects that are being edited; it serves to save state in an ordinarily stateless environment." +msgstr "" + +#: ctools.info:0 +msgid "Chaos tools" +msgstr "" + +#: ctools.info:0 +msgid "A library of helpful tools by Merlin of Chaos." +msgstr "" + +#: ctools.info:0 bulk_export/bulk_export.info:0 ctools_plugin_example/ctools_plugin_example.info:0 page_manager/page_manager.info:0 views_content/views_content.info:0 +msgid "Chaos tool suite" +msgstr "" + +#: bulk_export/bulk_export.module:15 +msgid "Access Bulk Exporter" +msgstr "" + +#: bulk_export/bulk_export.module:16 +msgid "Export various system objects into code." +msgstr "" + +#: bulk_export/bulk_export.module:73 +msgid "Bulk export results" +msgstr "" + +#: bulk_export/bulk_export.module:97;121;132 +msgid "Place this in @file" +msgstr "" + +#: bulk_export/bulk_export.module:138 +msgid "There are no objects to be exported at this time." +msgstr "" + +#: bulk_export/bulk_export.module:163 +msgid "Module name" +msgstr "" + +#: bulk_export/bulk_export.module:164 +msgid "Enter the module name to export code to." +msgstr "" + +#: bulk_export/bulk_export.module:169 page_manager/page_manager.admin.inc:682 page_manager/plugins/tasks/page.inc:183 +msgid "Export" +msgstr "" + +#: bulk_export/bulk_export.module:204 +msgid "There are no objects in your system that may be exported at this time." +msgstr "" + +#: bulk_export/bulk_export.module:37 +msgid "Bulk Exporter" +msgstr "" + +#: bulk_export/bulk_export.module:38 +msgid "Bulk-export multiple CTools-handled data objects to code." +msgstr "" + +#: bulk_export/bulk_export.info:0 +msgid "Bulk Export" +msgstr "" + +#: bulk_export/bulk_export.info:0 +msgid "Performs bulk exporting of data objects known about by Chaos tools." +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.module:36 +msgid "Demonstration code, advanced help, and a demo panel to show how to build ctools plugins." +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.module:79 +msgid "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." +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.module:81 +msgid "There is a demo panel demonstrating much of the functionality provided at\n <a href=\"@demo_url\">CTools demo panel</a>, and you can find documentation on the examples at\n !ctools_plugin_example_help.\n CTools itself provides documentation at !ctools_help. Mostly, though, the code itself is intended to be the teacher.\n You can find it in %path." +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.module:35 +msgid "CTools plugin example" +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.info:0 +msgid "Chaos Tools (CTools) Plugin Example" +msgstr "" + +#: ctools_plugin_example/ctools_plugin_example.info:0 +msgid "Shows how an external module can provide ctools plugins (for Panels, etc.)." +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:15 +msgid "Arg length" +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:16 +msgid "Control access by length of simplecontext argument." +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:20 ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:33;42 ctools_plugin_example/plugins/contexts/simplecontext.inc:16 ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc:22 +msgid "Simplecontext" +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:30 +msgid "Grant access if simplecontext argument length is" +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:31 +msgid "Greater than" +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:31 +msgid "Less than or equal to" +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:36 +msgid "Length of simplecontext argument" +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:39 +msgid "Access/visibility will be granted based on arg length." +msgstr "" + +#: ctools_plugin_example/plugins/access/arg_length.inc:63 +msgid "Simpletext argument must be !comp @length characters" +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:16 +msgid "CTools example: role" +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:17 plugins/access/role.inc:15 +msgid "Control access by role." +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:22 plugins/access/node_access.inc:22 plugins/access/perm.inc:20 plugins/access/role.inc:21 plugins/content_types/contact/user_contact.inc:17;18 plugins/content_types/user_context/profile_fields.inc:15;16 plugins/content_types/user_context/user_picture.inc:13;14 plugins/content_types/user_context/user_profile.inc:13;14 plugins/contexts/user.inc:15 +msgid "User" +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:32 plugins/access/role.inc:31 +msgid "Role" +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:35 plugins/access/role.inc:34 +msgid "Only the checked roles will be granted access." +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:74 plugins/access/role.inc:75 +msgid "@identifier can have any role" +msgstr "" + +#: ctools_plugin_example/plugins/access/example_role.inc:76 +msgid "@identifier must have role \"@roles\"" +msgid_plural "@identifier can be one of \"@roles\"" +msgstr[0] "" +msgstr[1] "" + +#: ctools_plugin_example/plugins/arguments/simplecontext_arg.inc:26 +msgid "Simplecontext arg" +msgstr "" + +#: ctools_plugin_example/plugins/arguments/simplecontext_arg.inc:29 +msgid "Creates a \"simplecontext\" from the arg." +msgstr "" + +#: ctools_plugin_example/plugins/arguments/simplecontext_arg.inc:37 +msgid "Enter the simplecontext arg" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:19 +msgid "CTools example no context content type" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:20 +msgid "No context content type - requires and uses no context." +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:37 ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:30 ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:37 +msgid "CTools Examples" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:94 +msgid "Item1" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:96 +msgid "The setting for item 1." +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:103 +msgid "Item2" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/no_context_content_type.inc:105 +msgid "The setting for item 2" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:21 +msgid "CTools example relcontext content type" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:28 +msgid "Relcontext content type - works with relcontext context." +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:29 ctools_plugin_example/plugins/contexts/relcontext.inc:16 +msgid "Relcontext" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:55 +msgid "\n This is a block of data created by the Relcontent content type.\n Data in the block may be assembled from static text (like this) or from the\n content type settings form ($conf) for the content type, or from the context\n that is passed in. <br />\n In our case, the configuration form ($conf) has just one field, 'config_item_1;\n and it's configured with:\n " +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:87 +msgid "Config Item 1 (relcontext)" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/relcontext_content_type.inc:89 +msgid "Setting for relcontext." +msgstr "" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:23 +msgid "Simplecontext content type" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:32 +msgid "Simplecontext content type - works with a simplecontext context." +msgstr "" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:82 +msgid "\n This is a block of data created by the Simplecontext content type.\n Data in the block may be assembled from static text (like this) or from the\n content type settings form ($conf) for the content type, or from the context\n that is passed in. <br />\n In our case, the configuration form ($conf) has just one field, 'config_item_1;\n and it's configured with:\n " +msgstr "" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:111 +msgid "Config Item 1 for simplecontext content type" +msgstr "" + +#: ctools_plugin_example/plugins/content_types/simplecontext_content_type.inc:113 +msgid "The stuff for item 1." +msgstr "" + +#: ctools_plugin_example/plugins/contexts/relcontext.inc:17 +msgid "A relcontext object." +msgstr "" + +#: ctools_plugin_example/plugins/contexts/relcontext.inc:53 +msgid "Relcontext context from simplecontext" +msgstr "" + +#: ctools_plugin_example/plugins/contexts/relcontext.inc:77 +msgid "Relcontext setting" +msgstr "" + +#: ctools_plugin_example/plugins/contexts/relcontext.inc:79 +msgid "Just an example setting." +msgstr "" + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:17 +msgid "A single \"simplecontext\" context, or data element." +msgstr "" + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:25 +msgid "Enter some data to represent this \"simplecontext\"." +msgstr "" + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:58 +msgid "Simplecontext context from config" +msgstr "" + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:87 +msgid "Setting for simplecontext" +msgstr "" + +#: ctools_plugin_example/plugins/contexts/simplecontext.inc:89 +msgid "An example setting that could be used to configure a context" +msgstr "" + +#: ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc:19 +msgid "Relcontext from simplecontext" +msgstr "" + +#: ctools_plugin_example/plugins/relationships/relcontext_from_simplecontext.inc:21 +msgid "Adds a relcontext from existing simplecontext." +msgstr "" + +#: includes/ajax.inc:137 page_manager/page_manager.admin.inc:927 +msgid "Error" +msgstr "" + +#: includes/ajax.inc:138 +msgid "Server reports invalid input error." +msgstr "" + +#: includes/content.inc:337 +msgid "@type:@subtype will not display due to missing context" +msgstr "" + +#: includes/content.inc:422 +msgid "No info" +msgstr "" + +#: includes/content.inc:423 +msgid "No info available." +msgstr "" + +#: includes/content.inc:454 +msgid "Override title" +msgstr "" + +#: includes/content.inc:473 +msgid "You may use %keywords from contexts, as well as %title to contain the original title." +msgstr "" + +#: includes/content.inc:544 page_manager/page_manager.admin.inc:578 +msgid "Configure" +msgstr "" + +#: includes/content.inc:547 +msgid "Configure new !subtype_title" +msgstr "" + +#: includes/content.inc:550 +msgid "Configure !subtype_title" +msgstr "" + +#: includes/content.menu.inc:45 plugins/content_types/node_context/node_author.inc:36 plugins/contexts/user.inc:49 +msgid "Anonymous" +msgstr "" + +#: includes/content.menu.inc:46 +msgid "by @user" +msgstr "" + +#: includes/context-access-admin.inc:159 +msgid "Add" +msgstr "" + +#: includes/context-access-admin.inc:165 +msgid "All criteria must pass." +msgstr "" + +#: includes/context-access-admin.inc:166 +msgid "Only one criteria must pass." +msgstr "" + +#: includes/context-access-admin.inc:174;405 includes/context-admin.inc:622;701;772;883 page_manager/page_manager.admin.inc:1177 +msgid "Save" +msgstr "" + +#: includes/context-access-admin.inc:198 +msgid "Broken/missing access plugin %plugin" +msgstr "" + +#: includes/context-access-admin.inc:205 includes/context-admin.inc:342 +msgid "Configure settings for this item." +msgstr "" + +#: includes/context-access-admin.inc:206 includes/context-admin.inc:338 +msgid "Remove this item." +msgstr "" + +#: includes/context-access-admin.inc:214 includes/context-admin.inc:850 page_manager/page_manager.admin.inc:90;267;1316 page_manager/plugins/tasks/page.admin.inc:654 plugins/content_types/custom/custom.inc:113 plugins/content_types/search/search_result.inc:113;151 +msgid "Title" +msgstr "" + +#: includes/context-access-admin.inc:215 +msgid "Description" +msgstr "" + +#: includes/context-access-admin.inc:220 +msgid "No criteria selected, this test will pass." +msgstr "" + +#: includes/context-access-admin.inc:278;346;457 +msgid "Missing callback hooks." +msgstr "" + +#: includes/context-access-admin.inc:303 +msgid "Add criteria" +msgstr "" + +#: includes/context-access-admin.inc:367 +msgid "Edit criteria" +msgstr "" + +#: includes/context-admin.inc:26 page_manager/plugins/tasks/page.inc:158 views_content/plugins/content_types/views.inc:360 +msgid "Arguments" +msgstr "" + +#: includes/context-admin.inc:27;858 +msgid "argument" +msgstr "" + +#: includes/context-admin.inc:29 +msgid "Add argument" +msgstr "" + +#: includes/context-admin.inc:37 +msgid "Relationships" +msgstr "" + +#: includes/context-admin.inc:38;748 +msgid "relationship" +msgstr "" + +#: includes/context-admin.inc:40 +msgid "Add relationship" +msgstr "" + +#: includes/context-admin.inc:48 +msgid "Contexts" +msgstr "" + +#: includes/context-admin.inc:49;598 +msgid "context" +msgstr "" + +#: includes/context-admin.inc:51 +msgid "Add context" +msgstr "" + +#: includes/context-admin.inc:59 +msgid "Required contexts" +msgstr "" + +#: includes/context-admin.inc:60;686 +msgid "required context" +msgstr "" + +#: includes/context-admin.inc:62 +msgid "Add required context" +msgstr "" + +#: includes/context-admin.inc:365;493;931 page_manager/plugins/tasks/page.admin.inc:952 +msgid "Invalid object name." +msgstr "" + +#: includes/context-admin.inc:412 +msgid "Add @type \"@context\"" +msgstr "" + +#: includes/context-admin.inc:511 +msgid "Invalid context type" +msgstr "" + +#: includes/context-admin.inc:530 +msgid "Edit @type \"@context\"" +msgstr "" + +#: includes/context-admin.inc:597;685;747;857 plugins/content_types/node_context/node_links.inc:93 +msgid "Identifier" +msgstr "" + +#: includes/context-admin.inc:598;686;748;858 +msgid "Enter a name to identify this !type on administrative screens." +msgstr "" + +#: includes/context-admin.inc:604;692;754;864 plugins/content_types/custom/custom.inc:147 +msgid "Keyword" +msgstr "" + +#: includes/context-admin.inc:605;693;755;865 +msgid "Enter a keyword to use for substitution in titles." +msgstr "" + +#: includes/context-admin.inc:839 includes/export.inc:184;268 page_manager/page_manager.module:500;515 page_manager/plugins/tasks/page.inc:217 plugins/content_types/search/search_form.inc:117 views_content/plugins/content_types/views.inc:432 +msgid "Default" +msgstr "" + +#: includes/context-admin.inc:841 +msgid "Ignore it; content that requires this context will not be available." +msgstr "" + +#: includes/context-admin.inc:842 +msgid "Display page not found or display nothing at all." +msgstr "" + +#: includes/context-admin.inc:845 +msgid "If the argument is missing or is not valid, select how this should behave." +msgstr "" + +#: includes/context-admin.inc:852 +msgid "Enter a title to use when this argument is present. You may use %KEYWORD substitution, where the keyword is specified below." +msgstr "" + +#: includes/context-admin.inc:942 +msgid "Unable to delete missing item!" +msgstr "" + +#: includes/context-task-handler.inc:118 +msgid "Edit @type" +msgstr "" + +#: includes/context-task-handler.inc:308 +msgid "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." +msgstr "" + +#: includes/context-task-handler.inc:356 +msgid "Summary of contexts" +msgstr "" + +#: includes/context.inc:49 +msgid "Unknown context" +msgstr "" + +#: includes/context.inc:195;196;400 page_manager/plugins/tasks/page.admin.inc:1120;1140 +msgid "No context" +msgstr "" + +#: includes/context.inc:311;418 +msgid "Context %count" +msgstr "" + +#: includes/context.inc:311;418 +msgid "Context" +msgstr "" + +#: includes/context.inc:425 +msgid "Please choose which context and how you would like it converted." +msgstr "" + +#: includes/context.inc:1233 +msgid "@identifier (@keyword)" +msgstr "" + +#: includes/context.inc:1297 +msgid "Logged in user" +msgstr "" + +#: includes/context.inc:1335 +msgid ", and " +msgstr "" + +#: includes/context.inc:1335 +msgid ", or " +msgstr "" + +#: includes/context.theme.inc:80 page_manager/plugins/tasks/page.admin.inc:696 page_manager/theme/page_manager.theme.inc:103 views_content/plugins/views/views_content_plugin_display_panel_pane.inc:196 +msgid "Weight" +msgstr "" + +#: includes/context.theme.inc:82 plugins/access/node_access.inc:33 +msgid "Operation" +msgstr "" + +#: includes/context.theme.inc:131;237 +msgid "Built in context" +msgstr "" + +#: includes/context.theme.inc:134;158;181;201;240;259;275;290 +msgid "Keyword: %@keyword" +msgstr "" + +#: includes/context.theme.inc:136;161;183;203 +msgid "@keyword --> @title" +msgstr "" + +#: includes/context.theme.inc:155;256 +msgid "Argument @count" +msgstr "" + +#: includes/context.theme.inc:178;272 +msgid "Context @count" +msgstr "" + +#: includes/context.theme.inc:198;287 +msgid "From \"@title\"" +msgstr "" + +#: includes/css.inc:166 +msgid "Unable to create CTools CSS cache directory. Check the permissions on your files directory." +msgstr "" + +#: includes/export.inc:139 page_manager/page_manager.module:366 page_manager/plugins/tasks/page.admin.inc:1456 +msgid "Normal" +msgstr "" + +#: includes/export.inc:177 page_manager/page_manager.admin.inc:1473 page_manager/page_manager.module:509 page_manager/plugins/tasks/page.admin.inc:1485;1499;1510 +msgid "Overridden" +msgstr "" + +#: includes/export.inc:601 page_manager/page_manager.module:642 +msgid "Local" +msgstr "" + +#: includes/form.inc:303 +msgid "Validation error, please try again. If this error persists, please contact the site administrator." +msgstr "" + +#: includes/menu.inc:58 +msgid "Home" +msgstr "" + +#: includes/modal.inc:52 +msgid "Close Window" +msgstr "" + +#: includes/modal.inc:53;53 +msgid "Close window" +msgstr "" + +#: includes/modal.inc:54 js/modal.js:0;0 +msgid "Loading..." +msgstr "" + +#: includes/modal.inc:54 +msgid "Loading" +msgstr "" + +#: includes/wizard.inc:373 +msgid "Continue" +msgstr "" + +#: includes/wizard.inc:374 +msgid "Back" +msgstr "" + +#: includes/wizard.inc:375 +msgid "Update and return" +msgstr "" + +#: includes/wizard.inc:376 +msgid "Finish" +msgstr "" + +#: includes/wizard.inc:377 page_manager/page_manager.admin.inc:1183 +msgid "Cancel" +msgstr "" + +#: page_manager/page_manager.admin.inc:25 +msgid "See the getting started guide for more information." +msgstr "" + +#: page_manager/page_manager.admin.inc:40 +msgid "This page is currently locked for editing by you. Nobody else may edit this page until these changes are saved or canceled." +msgstr "" + +#: page_manager/page_manager.admin.inc:44 +msgid "This page is currently locked for editing by another user. You may not edit this page without breaking the lock." +msgstr "" + +#: page_manager/page_manager.admin.inc:52;297 +msgid "Reset" +msgstr "" + +#: page_manager/page_manager.admin.inc:88;238;270 page_manager/plugins/tasks/page.admin.inc:642 +msgid "Type" +msgstr "" + +#: page_manager/page_manager.admin.inc:89;268 +msgid "Name" +msgstr "" + +#: page_manager/page_manager.admin.inc:91;269 page_manager/plugins/tasks/page.admin.inc:399;1244;1370 page_manager/plugins/tasks/page.inc:649 page_manager/plugins/tasks/term_view.inc:258 plugins/content_types/search/search_form.inc:115 +msgid "Path" +msgstr "" + +#: page_manager/page_manager.admin.inc:92;245;271 page_manager/plugins/tasks/page.inc:46;594 +msgid "Storage" +msgstr "" + +#: page_manager/page_manager.admin.inc:95 page_manager/plugins/tasks/page.admin.inc:909 +msgid "Operations" +msgstr "" + +#: page_manager/page_manager.admin.inc:163 page_manager/plugins/tasks/search.inc:213 +msgid "System" +msgstr "" + +#: page_manager/page_manager.admin.inc:171 page_manager/plugins/tasks/page.inc:217 page_manager/plugins/tasks/search.inc:215 +msgid "In code" +msgstr "" + +#: page_manager/page_manager.admin.inc:189 page_manager/page_manager.module:79 page_manager/plugins/tasks/page.inc:625;667;703 views_content/plugins/views/views_content_plugin_display_panel_pane.inc:120 +msgid "Edit" +msgstr "" + +#: page_manager/page_manager.admin.inc:197;523;529;708;713 page_manager/plugins/tasks/page.inc:600 +msgid "Enable" +msgstr "" + +#: page_manager/page_manager.admin.inc:203;536;542;719;724 page_manager/plugins/tasks/page.inc:604 +msgid "Disable" +msgstr "" + +#: page_manager/page_manager.admin.inc:234 +msgid "<All>" +msgstr "" + +#: page_manager/page_manager.admin.inc:252;253 page_manager/plugins/tasks/page.inc:605 +msgid "Enabled" +msgstr "" + +#: page_manager/page_manager.admin.inc:253 page_manager/plugins/tasks/page.inc:601 +msgid "Disabled" +msgstr "" + +#: page_manager/page_manager.admin.inc:259 page_manager/plugins/tasks/search.inc:25 +msgid "Search" +msgstr "" + +#: page_manager/page_manager.admin.inc:264 +msgid "Sort by" +msgstr "" + +#: page_manager/page_manager.admin.inc:266 +msgid "Enabled, title" +msgstr "" + +#: page_manager/page_manager.admin.inc:278 +msgid "Order" +msgstr "" + +#: page_manager/page_manager.admin.inc:280 +msgid "Up" +msgstr "" + +#: page_manager/page_manager.admin.inc:281 +msgid "Down" +msgstr "" + +#: page_manager/page_manager.admin.inc:290 +msgid "Apply" +msgstr "" + +#: page_manager/page_manager.admin.inc:470;662 +msgid "Summary" +msgstr "" + +#: page_manager/page_manager.admin.inc:471 +msgid "Get a summary of the information about this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:524 +msgid "Activate this page so that it will be in use in your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:537 +msgid "De-activate this page. The data will remain but the page will not be in use on your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:548 +msgid "Add variant" +msgstr "" + +#: page_manager/page_manager.admin.inc:549 +msgid "Add a new variant to this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:554;587 +msgid "Create variant" +msgstr "" + +#: page_manager/page_manager.admin.inc:559 +msgid "Import variant" +msgstr "" + +#: page_manager/page_manager.admin.inc:560 +msgid "Add a new variant to this page from code exported from another page." +msgstr "" + +#: page_manager/page_manager.admin.inc:566 +msgid "Reorder variants" +msgstr "" + +#: page_manager/page_manager.admin.inc:568 +msgid "Change the priority of the variants to ensure that the right one gets selected." +msgstr "" + +#: page_manager/page_manager.admin.inc:579 +msgid "Configure a newly created variant prior to actually adding it to the page." +msgstr "" + +#: page_manager/page_manager.admin.inc:606;611 +msgid "Break lock" +msgstr "" + +#: page_manager/page_manager.admin.inc:607 +msgid "Break the lock on this page so that you can edit it." +msgstr "" + +#: page_manager/page_manager.admin.inc:630 +msgid "Variants" +msgstr "" + +#: page_manager/page_manager.admin.inc:655 +msgid "Variant operations" +msgstr "" + +#: page_manager/page_manager.admin.inc:663 +msgid "Get a summary of the information about this variant." +msgstr "" + +#: page_manager/page_manager.admin.inc:677 page_manager/plugins/tasks/page.admin.inc:1384 page_manager/plugins/tasks/page.inc:178 +msgid "Clone" +msgstr "" + +#: page_manager/page_manager.admin.inc:678 +msgid "Make an exact copy of this variant." +msgstr "" + +#: page_manager/page_manager.admin.inc:683 +msgid "Export this variant into code to import into another page." +msgstr "" + +#: page_manager/page_manager.admin.inc:688;692 page_manager/plugins/tasks/page.admin.inc:1499 page_manager/plugins/tasks/page.inc:189 +msgid "Revert" +msgstr "" + +#: page_manager/page_manager.admin.inc:689 +msgid "Remove all changes to this variant and revert to the version in code." +msgstr "" + +#: page_manager/page_manager.admin.inc:698;702 page_manager/plugins/tasks/page.admin.inc:1499 page_manager/plugins/tasks/page.inc:196 plugins/access/node_access.inc:38 +msgid "Delete" +msgstr "" + +#: page_manager/page_manager.admin.inc:699 +msgid "Remove this variant from the page completely." +msgstr "" + +#: page_manager/page_manager.admin.inc:709 +msgid "Activate this variant so that it will be in use in your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:720 +msgid "De-activate this variant. The data will remain but the variant will not be in use on your system." +msgstr "" + +#: page_manager/page_manager.admin.inc:732 +msgid "No variants" +msgstr "" + +#: page_manager/page_manager.admin.inc:814 plugins/access/node_access.inc:37 +msgid "Update" +msgstr "" + +#: page_manager/page_manager.admin.inc:928 +msgid "This operation trail does not exist." +msgstr "" + +#: page_manager/page_manager.admin.inc:945 +msgid "The page has been updated. Changes will not be permanent until you save." +msgstr "" + +#: page_manager/page_manager.admin.inc:962 +msgid "Unable to update changes due to lock." +msgstr "" + +#: page_manager/page_manager.admin.inc:1112 +msgid "This setting contains unsaved changes." +msgstr "" + +#: page_manager/page_manager.admin.inc:1170 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1201 +msgid "All pending changes have been discarded, and the page is now unlocked." +msgstr "" + +#: page_manager/page_manager.admin.inc:1252 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1317 +msgid "Administrative title of this variant. If you leave blank it will be automatically assigned." +msgstr "" + +#: page_manager/page_manager.admin.inc:1322 +msgid "Variant type" +msgstr "" + +#: page_manager/page_manager.admin.inc:1331 +msgid "Optional features" +msgstr "" + +#: page_manager/page_manager.admin.inc:1333 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1361;1516 +msgid "Variant name" +msgstr "" + +#: page_manager/page_manager.admin.inc:1362;1517 +msgid "Enter the name of the new variant." +msgstr "" + +#: page_manager/page_manager.admin.inc:1367 +msgid "Paste variant code here" +msgstr "" + +#: page_manager/page_manager.admin.inc:1383 +msgid "No variant found." +msgstr "" + +#: page_manager/page_manager.admin.inc:1386 +msgid "Unable to get a variant from the import. Errors reported: @errors" +msgstr "" + +#: page_manager/page_manager.admin.inc:1474 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1477 +msgid "Are you sure you want to delete this variant? This deletion will not be made permanent until you click Save." +msgstr "" + +#: page_manager/page_manager.admin.inc:1543 +msgid "This variant is currently disabled. Enabling it will make it available in your system. This will not take effect until you save this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:1562 +msgid "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." +msgstr "" + +#: page_manager/page_manager.admin.inc:1594 +msgid "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?" +msgstr "" + +#: page_manager/page_manager.admin.inc:1606 +msgid "The lock has been cleared and all changes discarded. You may now make changes to this page." +msgstr "" + +#: page_manager/page_manager.admin.inc:1614 +msgid "Enabling this page will immediately make it available in your system (there is no need to wait for a save.)" +msgstr "" + +#: page_manager/page_manager.admin.inc:1641 +msgid "Disabling this page will immediately make it unavailable in your system (there is no need to wait for a save.)" +msgstr "" + +#: page_manager/page_manager.admin.inc:1699 +msgid "This page has no variants and thus no output of its own." +msgstr "" + +#: page_manager/page_manager.admin.inc:1704 +msgid "Add a new variant" +msgstr "" + +#: page_manager/page_manager.admin.inc:1722 +msgid "Unable to disable due to lock." +msgstr "" + +#: page_manager/page_manager.admin.inc:1725 +msgid "Unable to enable due to lock." +msgstr "" + +#: page_manager/page_manager.module:66 +msgid "Pages" +msgstr "" + +#: page_manager/page_manager.module:67 +msgid "Add, edit and remove overridden system pages and user defined pages from the system." +msgstr "" + +#: page_manager/page_manager.module:72 +msgid "List" +msgstr "" + +#: page_manager/page_manager.info:0 +msgid "Page manager" +msgstr "" + +#: page_manager/page_manager.info:0 +msgid "Provides a UI and API to manage pages within the site." +msgstr "" + +#: page_manager/plugins/tasks/blog.inc:17;18 +msgid "All blogs" +msgstr "" + +#: page_manager/plugins/tasks/blog.inc:19 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/blog.inc:56 +msgid "Page manager module is unable to enable blog because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/blog_user.inc:16;17 +msgid "User blog" +msgstr "" + +#: page_manager/plugins/tasks/blog_user.inc:18 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/blog_user.inc:59 +msgid "Page manager module is unable to enable blog/%user because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/blog_user.inc:109 page_manager/plugins/tasks/contact_user.inc:105 page_manager/plugins/tasks/user_view.inc:100 +msgid "User being viewed" +msgstr "" + +#: page_manager/plugins/tasks/contact_site.inc:17;18 +msgid "Site contact page" +msgstr "" + +#: page_manager/plugins/tasks/contact_site.inc:19 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/contact_site.inc:56 +msgid "Page manager module is unable to enable contact because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/contact_user.inc:12;13 +msgid "User contact" +msgstr "" + +#: page_manager/plugins/tasks/contact_user.inc:14 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/contact_user.inc:55 +msgid "Page manager module is unable to enable user/%user/contact because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:13;14 +msgid "Node add/edit form" +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:15 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:55 +msgid "Page manager module is unable to enable node/%node/edit because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:65 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:129 +msgid "Create @name" +msgstr "" + +#: page_manager/plugins/tasks/node_edit.inc:143 +msgid "Node being edited" +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:22;24 +msgid "Node template" +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:25 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:66 +msgid "Page manager module is unable to enable node/%node because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/node_view.inc:118 +msgid "Node being viewed" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:201;279 +msgid "Basic settings" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:202;974;982 +msgid "Argument settings" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:203;439 +msgid "Access control" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:204 +msgid "Menu settings" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:280 +msgid "A meaningless second page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:372;1362 plugins/content_types/custom/custom.inc:106 views_content/plugins/views/views_content_plugin_display_panel_pane.inc:166 +msgid "Administrative title" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:373;1363 +msgid "The name of this page. This will appear in the administrative interface to easily identify it." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:379 +msgid "Machine name" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:380 +msgid "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!" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:391 views_content/plugins/views/views_content_plugin_display_panel_pane.inc:176;186 +msgid "Administrative description" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:392 +msgid "A description of what this page is, does or is for, for administrative use." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:400 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:422 +msgid "Make this your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:423 +msgid "To set this panel as your home page you must create a unique path name with no % placeholders in the path. The current site home page is set to %homepage." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:428 +msgid "This page is currently set to be your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:440 +msgid "Visible menu item" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:461 +msgid "Name is required." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:468 +msgid "That name is used by another page: @page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:473 +msgid "Page name must be alphanumeric or underscores only." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:480 +msgid "That path is used by another page: @page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:488 +msgid "Path is required." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:501 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:506 +msgid "You cannot have a dynamic path element after an optional path element." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:515 +msgid "You cannot have a static path element after an optional path element." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:526 +msgid "That path is already in used. This system cannot override existing paths." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:534 +msgid "That path is currently assigned to be an alias for @alias. This system cannot override existing aliases." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:539 +msgid "You cannot make this page your site home page if it uses % placeholders." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:547 +msgid "Duplicated argument %arg" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:552 +msgid "Invalid arg <em>%</em>. All arguments must be named with keywords." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:645 page_manager/plugins/tasks/page.inc:700 page_manager/plugins/tasks/term_view.inc:269 +msgid "No menu entry" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:646 +msgid "Normal menu entry" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:647;709 +msgid "Menu tab" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:648 +msgid "Default menu tab" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:657 +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:667 +msgid "Warning: Changing this item's menu will not work reliably in Drupal 6.4 or earlier. Please upgrade your copy of Drupal at !url." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:677 page_manager/plugins/tasks/page.inc:172;705 page_manager/plugins/tasks/term_view.inc:272 +msgid "Menu" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:681;731 +msgid "Insert item into an available menu." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:692 +msgid "Menu selection requires the activation of menu module." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:699 +msgid "The lower the weight the higher/further left it will appear." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:707 +msgid "Parent menu item" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:709 +msgid "Already exists" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:709 +msgid "Normal menu item" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:711 +msgid "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>." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:716 +msgid "Parent item title" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:719 +msgid "If creating a parent menu item, enter the title of the item." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:727 +msgid "Parent item menu" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:744 +msgid "Tab weight" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:748 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:783 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:852 +msgid "No context assigned" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:876 +msgid "Change" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:893 page_manager/plugins/tasks/page.inc:143 page_manager/plugins/tasks/term_view.inc:50;65 +msgid "Settings" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:906 +msgid "Argument" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:907 +msgid "Position in path" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:908 +msgid "Context assigned" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:927 +msgid "The path %path has no arguments to configure." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:961 +msgid "Invalid keyword." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:973 +msgid "Change context type" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:978 +msgid "Change argument" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1084 +msgid "No context selected" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1167 +msgid "Error: missing argument." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1180 +msgid "Context identifier" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1181 +msgid "This is the title of the context used to identify it later in the administrative process. This will never be shown to a user." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1187 +msgid "Error: missing or invalid argument plugin %argument." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1235 +msgid "Import page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1238;1356 +msgid "Page name" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1239 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1245 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1250 +msgid "Allow overwrite of an existing page" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1251 +msgid "If the name you selected already exists in the database, this page will be allowed to overwrite the existing page." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1256 +msgid "Paste page code here" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1262 +msgid "Import" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1278 +msgid "No handler found." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1280 +msgid "Unable to get a page from the import. Errors reported: @errors" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1291 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1357 +msgid "Enter the name to the new page It must be unique and contain only alphanumeric characters and underscores." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1371 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1377 +msgid "Clone variants" +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1378 +msgid "If checked all variants associated with the page will be cloned as well. If not checked the page will be cloned without variants." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1486 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1489 +msgid "Are you sure you want to delete this page? Deleting a page cannot be undone." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1512 +msgid "The page has been deleted." +msgstr "" + +#: page_manager/plugins/tasks/page.admin.inc:1516 +msgid "The page has been reverted." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:22 +msgid "Custom pages" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:23 +msgid "Administrator created pages that have a URL path, access control and entries in the Drupal menu system." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:39 +msgid "Create a new page" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:150 page_manager/plugins/tasks/term_view.inc:68 +msgid "Basic" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:151 page_manager/plugins/tasks/term_view.inc:69 +msgid "Edit name, path and other basic settings for the page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:159 +msgid "Set up contexts for the arguments on this page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:165;670 page_manager/plugins/tasks/term_view.inc:264 +msgid "Access" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:166 +msgid "Control what users can access this page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:167 +msgid "Access rules are used to test if the page is accessible and any menu items associated with it are visible." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:173 +msgid "Provide this page a visible menu or a menu tab." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:179 +msgid "Make a copy of this page" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:184 +msgid "Export this page as code that can be imported or embedded into a module." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:190 +msgid "Remove all changes to this page and revert to the version in code." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:197 +msgid "Remove this page from your system completely." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:208 plugins/content_types/custom/custom.inc:26;58 plugins/content_types/node/node.inc:27 plugins/content_types/search/search_form.inc:119 +msgid "Custom" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:322 page_manager/plugins/tasks/term_view.inc:133 plugins/access/node_access.inc:36 +msgid "View" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:609 +msgid "Status" +msgstr "" + +#: page_manager/plugins/tasks/page.inc:628 +msgid "This is your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:631 +msgid "This page is set to become your site home page." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:661 +msgid "Accessible only if @conditions." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:664 page_manager/plugins/tasks/term_view.inc:265 +msgid "This page is publicly accessible." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:676 +msgid "No menu entry." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:677 +msgid "Normal menu entry." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:678 +msgid "Menu tab." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:679 +msgid "Default menu tab." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:685 +msgid "Title: %title." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:688 +msgid "Parent title: %title." +msgstr "" + +#: page_manager/plugins/tasks/page.inc:693 +msgid "Menu block: %title." +msgstr "" + +#: page_manager/plugins/tasks/poll.inc:17;18 +msgid "All polls" +msgstr "" + +#: page_manager/plugins/tasks/poll.inc:19 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/poll.inc:56 +msgid "Page manager module is unable to enable poll because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/search.inc:91 +msgid "Page manager module is unable to enable search/@name/%menu_tail because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/search.inc:155 plugins/content_types/search/search_form.inc:17 plugins/content_types/search/search_result.inc:13 +msgid "Keywords" +msgstr "" + +#: page_manager/plugins/tasks/search.inc:212 +msgid "Search @type" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:23;24 +msgid "Taxonomy term template" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:25 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:51 +msgid "Update settings specific to the taxonomy term view." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:101 +msgid "Page manager module is unable to enable taxonomy/term/%term because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:161 +msgid "Term(s) being viewed" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:161 +msgid "Term being viewed" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:169 +msgid "Depth" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:224 +msgid "Allow multiple terms on taxonomy/term/%term" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:225 +msgid "Single term" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:225 +msgid "Multiple terms" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:226 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:230 plugins/arguments/terms.inc:54 +msgid "Inject hierarchy of first term into breadcrumb trail" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:233 plugins/arguments/term.inc:93 plugins/arguments/terms.inc:57 +msgid "If checked, taxonomy term parents will appear in the breadcrumb trail." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:278 +msgid "Multiple terms may be used, separated by , or +." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:281 +msgid "Only a single term may be used." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:285 +msgid "%term" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:291 +msgid "Breadcrumb trail will contain taxonomy term hierarchy" +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:294 +msgid "Breadcrumb trail will not contain taxonomy term hiearchy." +msgstr "" + +#: page_manager/plugins/tasks/term_view.inc:298 plugins/content_types/page/page_breadcrumb.inc:15 +msgid "Breadcrumb" +msgstr "" + +#: page_manager/plugins/tasks/user_view.inc:15;16 +msgid "User profile template" +msgstr "" + +#: page_manager/plugins/tasks/user_view.inc:17 +msgid "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." +msgstr "" + +#: page_manager/plugins/tasks/user_view.inc:59 +msgid "Page manager module is unable to enable user/%user because some other module already has overridden with %callback." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:42 +msgid "Locked" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:42 +msgid "This page is being edited by another user and you cannot make changes to it." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:45 +msgid "New" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:45 +msgid "This page is newly created and has not yet been saved to the database. It will not be available until you save it." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:48 +msgid "Changed" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:48 +msgid "This page has been modified, but these modifications are not yet live. While modifying this page, it is locked from modification by other users." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:98 +msgid "No task handlers are defined for this task." +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:102 +msgid "Variant" +msgstr "" + +#: page_manager/theme/page_manager.theme.inc:124 +msgid "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>." +msgstr "" + +#: plugins/access/compare_users.inc:14 +msgid "User: compare" +msgstr "" + +#: plugins/access/compare_users.inc:15 +msgid "Compare two users (logged-in user and user being viewed, for example)" +msgstr "" + +#: plugins/access/compare_users.inc:23 +msgid "First User" +msgstr "" + +#: plugins/access/compare_users.inc:24 +msgid "Second User" +msgstr "" + +#: plugins/access/compare_users.inc:36 +msgid "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." +msgstr "" + +#: plugins/access/compare_users.inc:41 +msgid "Grant access if user contexts are" +msgstr "" + +#: plugins/access/compare_users.inc:42 +msgid "Equal" +msgstr "" + +#: plugins/access/compare_users.inc:42 +msgid "Not equal" +msgstr "" + +#: plugins/access/compare_users.inc:70 +msgid "@id1 @comp @id2" +msgstr "" + +#: plugins/access/node_access.inc:14 +msgid "Node: accessible" +msgstr "" + +#: plugins/access/node_access.inc:15 +msgid "Control access with built in Drupal node access test." +msgstr "" + +#: plugins/access/node_access.inc:23 plugins/access/node_language.inc:22 plugins/access/node_type.inc:21 plugins/content_types/node/node.inc:15 plugins/content_types/node_context/node_attachments.inc:13;14 plugins/content_types/node_context/node_author.inc:13;14 plugins/content_types/node_context/node_body.inc:13;14 plugins/content_types/node_context/node_book_nav.inc:14;15 plugins/content_types/node_context/node_comment_form.inc:14;15 plugins/content_types/node_context/node_comments.inc:15;16 plugins/content_types/node_context/node_content.inc:13;14 plugins/content_types/node_context/node_created.inc:13;14 plugins/content_types/node_context/node_links.inc:14;15 plugins/content_types/node_context/node_title.inc:13;14 plugins/content_types/node_context/node_type_desc.inc:13;14 plugins/content_types/node_context/node_updated.inc:13;14 plugins/contexts/node.inc:16 plugins/relationships/book_parent.inc:17 plugins/relationships/term_from_node.inc:17 plugins/relationships/user_from_node.inc:17 +msgid "Node" +msgstr "" + +#: plugins/access/node_access.inc:39 +msgid "Create nodes of the same type" +msgstr "" + +#: plugins/access/node_access.inc:41 +msgid "Using built in Drupal node access rules, determine if the user can perform the selected operation on the node." +msgstr "" + +#: plugins/access/node_access.inc:78 +msgid "@user can view @node." +msgstr "" + +#: plugins/access/node_access.inc:81 +msgid "@user can edit @node." +msgstr "" + +#: plugins/access/node_access.inc:84 +msgid "@user can delete @node." +msgstr "" + +#: plugins/access/node_access.inc:87 +msgid "@user can create nodes of the same type as @node." +msgstr "" + +#: plugins/access/node_language.inc:15 +msgid "Node: language" +msgstr "" + +#: plugins/access/node_language.inc:16 +msgid "Control access by node language." +msgstr "" + +#: plugins/access/node_language.inc:32;94 +msgid "Current site language" +msgstr "" + +#: plugins/access/node_language.inc:33;95 plugins/access/site_language.inc:31;69 +msgid "Default site language" +msgstr "" + +#: plugins/access/node_language.inc:34;96 +msgid "No language" +msgstr "" + +#: plugins/access/node_language.inc:38 plugins/access/site_language.inc:35 +msgid "Language" +msgstr "" + +#: plugins/access/node_language.inc:41 +msgid "Pass only if the node is in one of the selected languages." +msgstr "" + +#: plugins/access/node_language.inc:110 +msgid "@identifier is in any language" +msgstr "" + +#: plugins/access/node_language.inc:113 +msgid "@identifier language is \"@languages\"" +msgid_plural "@identifier language is one of \"@languages\"" +msgstr[0] "" +msgstr[1] "" + +#: plugins/access/node_type.inc:14 +msgid "Node: type" +msgstr "" + +#: plugins/access/node_type.inc:15 +msgid "Control access by node_type." +msgstr "" + +#: plugins/access/node_type.inc:36 plugins/contexts/node.inc:171 plugins/contexts/node_add_form.inc:21;100 +msgid "Node type" +msgstr "" + +#: plugins/access/node_type.inc:39 +msgid "Only the checked node types will be valid." +msgstr "" + +#: plugins/access/node_type.inc:96 +msgid "@identifier is any node type" +msgstr "" + +#: plugins/access/node_type.inc:99 +msgid "@identifier is type \"@types\"" +msgid_plural "@identifier type is one of \"@types\"" +msgstr[0] "" +msgstr[1] "" + +#: plugins/access/perm.inc:14 +msgid "User: permission" +msgstr "" + +#: plugins/access/perm.inc:15 +msgid "Control access by permission string." +msgstr "" + +#: plugins/access/perm.inc:41 +msgid "Permission" +msgstr "" + +#: plugins/access/perm.inc:43 +msgid "Only users with the selected permission flag will be able to access this." +msgstr "" + +#: plugins/access/perm.inc:65 +msgid "Error, unset permission" +msgstr "" + +#: plugins/access/perm.inc:68 +msgid "@identifier has \"@perm\"" +msgstr "" + +#: plugins/access/php.inc:14;41 +msgid "PHP Code" +msgstr "" + +#: plugins/access/php.inc:15 +msgid "Control access through arbitrary PHP code." +msgstr "" + +#: plugins/access/php.inc:35 +msgid "Administrative desc" +msgstr "" + +#: plugins/access/php.inc:37 +msgid "A description for this test for administrative purposes." +msgstr "" + +#: plugins/access/php.inc:43 +msgid "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." +msgstr "" + +#: plugins/access/php.inc:48 +msgid "You do not have sufficient permissions to edit PHP code." +msgstr "" + +#: plugins/access/role.inc:14 +msgid "User: role" +msgstr "" + +#: plugins/access/role.inc:78 +msgid "@identifier has role \"@roles\"" +msgid_plural "@identifier has one of \"@roles\"" +msgstr[0] "" +msgstr[1] "" + +#: plugins/access/site_language.inc:15 +msgid "User: language" +msgstr "" + +#: plugins/access/site_language.inc:16 +msgid "Control access by the language the user or site currently uses." +msgstr "" + +#: plugins/access/site_language.inc:38 +msgid "Pass only if the current site language is one of the selected languages." +msgstr "" + +#: plugins/access/site_language.inc:83 +msgid "Site language is any language" +msgstr "" + +#: plugins/access/site_language.inc:86 +msgid "Site language is \"@languages\"" +msgid_plural "Site language is one of \"@languages\"" +msgstr[0] "" +msgstr[1] "" + +#: plugins/access/term.inc:14 +msgid "Taxonomy: term" +msgstr "" + +#: plugins/access/term.inc:15 +msgid "Control access by a specific term." +msgstr "" + +#: plugins/access/term.inc:22 plugins/access/term_vocabulary.inc:21 plugins/content_types/term_context/term_description.inc:13 plugins/content_types/term_context/term_list.inc:13 plugins/relationships/term_parent.inc:17 +msgid "Term" +msgstr "" + +#: plugins/access/term.inc:41 plugins/content_types/vocabulary_context/vocabulary_terms.inc:14;15 plugins/contexts/term.inc:67 plugins/contexts/vocabulary.inc:57 plugins/relationships/term_from_node.inc:53 +msgid "Vocabulary" +msgstr "" + +#: plugins/access/term.inc:44 plugins/contexts/term.inc:70 plugins/contexts/vocabulary.inc:63 +msgid "Select the vocabulary for this form." +msgstr "" + +#: plugins/access/term.inc:63 +msgid "Terms" +msgstr "" + +#: plugins/access/term.inc:64 +msgid "Select a term or terms from @vocabulary." +msgstr "" + +#: plugins/access/term.inc:148 +msgid "@term can be the term \"@terms\"" +msgid_plural "@term can be one of these terms: @terms" +msgstr[0] "" +msgstr[1] "" + +#: plugins/access/term_vocabulary.inc:14 +msgid "Taxonomy: vocabulary" +msgstr "" + +#: plugins/access/term_vocabulary.inc:15 +msgid "Control access by term vocabulary." +msgstr "" + +#: plugins/access/term_vocabulary.inc:37 +msgid "Vocabularies" +msgstr "" + +#: plugins/access/term_vocabulary.inc:39 +msgid "Only terms in the checked vocabularies will be valid." +msgstr "" + +#: plugins/access/term_vocabulary.inc:83 +msgid "@identifier is any vocabulary" +msgstr "" + +#: plugins/access/term_vocabulary.inc:86 +msgid "@identifier vocabulary is \"@vids\"" +msgid_plural "@identifier vocabulary is one of \"@vids\"" +msgstr[0] "" +msgstr[1] "" + +#: plugins/arguments/nid.inc:15 +msgid "Node: ID" +msgstr "" + +#: plugins/arguments/nid.inc:17 +msgid "Creates a node context from a node ID argument." +msgstr "" + +#: plugins/arguments/nid.inc:21 plugins/arguments/node_edit.inc:22 +msgid "Enter the node ID of a node for this argument" +msgstr "" + +#: plugins/arguments/node_add.inc:15 +msgid "Node add form: node type" +msgstr "" + +#: plugins/arguments/node_add.inc:18 +msgid "Creates a node add form context from a node type argument." +msgstr "" + +#: plugins/arguments/node_edit.inc:15 +msgid "Node edit form: node ID" +msgstr "" + +#: plugins/arguments/node_edit.inc:18 +msgid "Creates a node edit form context from a node ID argument." +msgstr "" + +#: plugins/arguments/string.inc:15 plugins/contexts/string.inc:15 +msgid "String" +msgstr "" + +#: plugins/arguments/string.inc:18 +msgid "A string is a minimal context that simply holds a string that can be used for some other purpose." +msgstr "" + +#: plugins/arguments/string.inc:23 +msgid "Enter a value for this argument" +msgstr "" + +#: plugins/arguments/string.inc:49 +msgid "Get all arguments after this one" +msgstr "" + +#: plugins/arguments/string.inc:52 +msgid "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\"." +msgstr "" + +#: plugins/arguments/term.inc:15 +msgid "Taxonomy term: ID" +msgstr "" + +#: plugins/arguments/term.inc:18 +msgid "Creates a single taxonomy term from a taxonomy ID or taxonomy term name." +msgstr "" + +#: plugins/arguments/term.inc:81 +msgid "Argument type" +msgstr "" + +#: plugins/arguments/term.inc:83 plugins/contexts/term.inc:24 +msgid "Term ID" +msgstr "" + +#: plugins/arguments/term.inc:83 plugins/contexts/term.inc:25 +msgid "Term name" +msgstr "" + +#: plugins/arguments/term.inc:90 +msgid "Inject hierarchy into breadcrumb trail" +msgstr "" + +#: plugins/arguments/term.inc:106 +msgid "Enter a taxonomy term ID." +msgstr "" + +#: plugins/arguments/term.inc:111 +msgid "Enter a taxonomy term name." +msgstr "" + +#: plugins/arguments/terms.inc:15 +msgid "Taxonomy term (multiple): ID" +msgstr "" + +#: plugins/arguments/terms.inc:18 +msgid "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." +msgstr "" + +#: plugins/arguments/terms.inc:24 +msgid "Enter a term ID or a list of term IDs separated by a + or a ," +msgstr "" + +#: plugins/arguments/uid.inc:15 +msgid "User: ID" +msgstr "" + +#: plugins/arguments/uid.inc:18 +msgid "Creates a user context from a user ID argument." +msgstr "" + +#: plugins/arguments/uid.inc:22 +msgid "Enter the user ID of a user for this argument" +msgstr "" + +#: plugins/arguments/user_name.inc:15 +msgid "User: name" +msgstr "" + +#: plugins/arguments/user_name.inc:18 +msgid "Creates a user context from a user name." +msgstr "" + +#: plugins/arguments/user_name.inc:22 +msgid "Enter the username of a user for this argument" +msgstr "" + +#: plugins/arguments/vid.inc:15 +msgid "Vocabulary: ID" +msgstr "" + +#: plugins/arguments/vid.inc:18 +msgid "Creates a vocabulary context from a vocabulary ID argument." +msgstr "" + +#: plugins/arguments/vid.inc:22 +msgid "Enter the vocabulary ID for this argument" +msgstr "" + +#: plugins/content_types/block/block.inc:21 +msgid "Block" +msgstr "" + +#: plugins/content_types/block/block.inc:91 +msgid "Configure block" +msgstr "" + +#: plugins/content_types/block/block.inc:92 +msgid "Configure this block's 'block settings' in administer >> site building >> blocks" +msgstr "" + +#: plugins/content_types/block/block.inc:227 +msgid "Deleted/missing block @module-@delta" +msgstr "" + +#: plugins/content_types/block/block.inc:265;269;344 +msgid "Miscellaneous" +msgstr "" + +#: plugins/content_types/block/block.inc:277;357 +msgid "Menus" +msgstr "" + +#: plugins/content_types/block/block.inc:284;314;319;324;348;381 +msgid "Activity" +msgstr "" + +#: plugins/content_types/block/block.inc:329;334;352;376;386 plugins/content_types/contact/contact.inc:17 plugins/content_types/search/search_form.inc:18 plugins/content_types/search/search_result.inc:14 views_content/views_content.module:56 +msgid "Widgets" +msgstr "" + +#: plugins/content_types/block/block.inc:339 +msgid "Feeds" +msgstr "" + +#: plugins/content_types/contact/contact.inc:14;62 +msgid "Contact form" +msgstr "" + +#: plugins/content_types/contact/contact.inc:16 +msgid "The site contact form that allows users to send a message to site administrators." +msgstr "" + +#: plugins/content_types/contact/contact.inc:32 +msgid "Contact" +msgstr "" + +#: plugins/content_types/contact/user_contact.inc:14;68 +msgid "User contact form" +msgstr "" + +#: plugins/content_types/contact/user_contact.inc:16 +msgid "The site contact form that allows users to contact other users." +msgstr "" + +#: plugins/content_types/contact/user_contact.inc:38 +msgid "Contact @name" +msgstr "" + +#: plugins/content_types/custom/custom.inc:20 +msgid "New custom content" +msgstr "" + +#: plugins/content_types/custom/custom.inc:22 +msgid "Create a completely custom piece of HTML content." +msgstr "" + +#: plugins/content_types/custom/custom.inc:61 +msgid "Custom: @title" +msgstr "" + +#: plugins/content_types/custom/custom.inc:107 +msgid "This title will be used administratively to identify this pane. If blank, the regular title will be used." +msgstr "" + +#: plugins/content_types/custom/custom.inc:117 +msgid "Body" +msgstr "" + +#: plugins/content_types/custom/custom.inc:127 +msgid "Use context keywords" +msgstr "" + +#: plugins/content_types/custom/custom.inc:128 +msgid "If checked, context keywords will be substituted in this content." +msgstr "" + +#: plugins/content_types/custom/custom.inc:132 +msgid "Substitutions" +msgstr "" + +#: plugins/content_types/custom/custom.inc:143 +msgid "@identifier: @title" +msgstr "" + +#: plugins/content_types/custom/custom.inc:147 +msgid "Value" +msgstr "" + +#: plugins/content_types/form/form.inc:13 +msgid "General form" +msgstr "" + +#: plugins/content_types/form/form.inc:15 +msgid "Everything in the form that is not displayed by other content." +msgstr "" + +#: plugins/content_types/form/form.inc:16;17;43 plugins/content_types/node_form/node_form_attachments.inc:14;15 plugins/content_types/node_form/node_form_author.inc:13;14 plugins/content_types/node_form/node_form_book.inc:14;15 plugins/content_types/node_form/node_form_buttons.inc:13;14 plugins/content_types/node_form/node_form_comment.inc:14;15 plugins/content_types/node_form/node_form_input_format.inc:13;14 plugins/content_types/node_form/node_form_log.inc:13;14 plugins/content_types/node_form/node_form_menu.inc:14;15 plugins/content_types/node_form/node_form_path.inc:14;15 plugins/content_types/node_form/node_form_publishing.inc:19;20 plugins/content_types/node_form/node_form_taxonomy.inc:14;15 +msgid "Form" +msgstr "" + +#: plugins/content_types/form/form.inc:44 +msgid "Form goes here." +msgstr "" + +#: plugins/content_types/form/form.inc:52 +msgid "\"@s\" base form" +msgstr "" + +#: plugins/content_types/node/node.inc:24 +msgid "Existing node" +msgstr "" + +#: plugins/content_types/node/node.inc:26 +msgid "Add a node from your site as content." +msgstr "" + +#: plugins/content_types/node/node.inc:70 plugins/content_types/node_context/node_content.inc:61 +msgid "Edit node" +msgstr "" + +#: plugins/content_types/node/node.inc:71 plugins/content_types/node_context/node_content.inc:62 +msgid "Edit this node" +msgstr "" + +#: plugins/content_types/node/node.inc:108 plugins/content_types/node_context/node_content.inc:130 +msgid "Leave node title" +msgstr "" + +#: plugins/content_types/node/node.inc:109 plugins/content_types/node_context/node_content.inc:131 +msgid "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." +msgstr "" + +#: plugins/content_types/node/node.inc:115 plugins/contexts/node.inc:82 plugins/contexts/node_edit_form.inc:99 +msgid "Enter the title or NID of a node" +msgstr "" + +#: plugins/content_types/node/node.inc:116 +msgid "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." +msgstr "" + +#: plugins/content_types/node/node.inc:132 plugins/content_types/node_context/node_content.inc:141 +msgid "Show only node teaser" +msgstr "" + +#: plugins/content_types/node/node.inc:140 plugins/content_types/node_context/node_content.inc:154 +msgid "Include node links for \"add comment\", \"read more\" etc." +msgstr "" + +#: plugins/content_types/node/node.inc:146 plugins/content_types/node_context/node_content.inc:167 +msgid "Template identifier" +msgstr "" + +#: plugins/content_types/node/node.inc:147 plugins/content_types/node_context/node_content.inc:168 +msgid "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." +msgstr "" + +#: plugins/content_types/node/node.inc:181 +msgid "Invalid node" +msgstr "" + +#: plugins/content_types/node/node.inc:199 +msgid "Node loaded from @var" +msgstr "" + +#: plugins/content_types/node/node.inc:207 +msgid "Deleted/missing node @nid" +msgstr "" + +#: plugins/content_types/node_context/node_attachments.inc:10;23 +msgid "Attached files" +msgstr "" + +#: plugins/content_types/node_context/node_attachments.inc:12 +msgid "A list of files attached to the node." +msgstr "" + +#: plugins/content_types/node_context/node_attachments.inc:31 +msgid "Attached files go here." +msgstr "" + +#: plugins/content_types/node_context/node_attachments.inc:39 +msgid "\"@s\" attachments" +msgstr "" + +#: plugins/content_types/node_context/node_author.inc:10 plugins/relationships/user_from_node.inc:14 +msgid "Node author" +msgstr "" + +#: plugins/content_types/node_context/node_author.inc:12 +msgid "The author of the referenced node." +msgstr "" + +#: plugins/content_types/node_context/node_author.inc:35 +msgid "Author" +msgstr "" + +#: plugins/content_types/node_context/node_author.inc:49 +msgid "Link to author profile" +msgstr "" + +#: plugins/content_types/node_context/node_author.inc:52 +msgid "Check here to link to the node author profile." +msgstr "" + +#: plugins/content_types/node_context/node_author.inc:70 +msgid "\"@s\" author" +msgstr "" + +#: plugins/content_types/node_context/node_body.inc:10 +msgid "Node body" +msgstr "" + +#: plugins/content_types/node_context/node_body.inc:12 +msgid "The body of the referenced node." +msgstr "" + +#: plugins/content_types/node_context/node_body.inc:58 +msgid "\"@s\" body" +msgstr "" + +#: plugins/content_types/node_context/node_book_nav.inc:11;25 +msgid "Book navigation" +msgstr "" + +#: plugins/content_types/node_context/node_book_nav.inc:13 +msgid "The navigation menu the book the node belongs to." +msgstr "" + +#: plugins/content_types/node_context/node_book_nav.inc:31 +msgid "Book navigation goes here." +msgstr "" + +#: plugins/content_types/node_context/node_book_nav.inc:39 +msgid "\"@s\" book navigation" +msgstr "" + +#: plugins/content_types/node_context/node_comment_form.inc:11 +msgid "Comment form" +msgstr "" + +#: plugins/content_types/node_context/node_comment_form.inc:13 +msgid "A form to add a new comment." +msgstr "" + +#: plugins/content_types/node_context/node_comment_form.inc:26 +msgid "Add comment" +msgstr "" + +#: plugins/content_types/node_context/node_comment_form.inc:29 +msgid "Comment form here." +msgstr "" + +#: plugins/content_types/node_context/node_comment_form.inc:47 +msgid "\"@s\" comment form" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:12 +msgid "Node comments" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:14 +msgid "The comments of the referenced node." +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:32 +msgid "Comments" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:34 +msgid "Node comments go here." +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:49 +msgid "Mode" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:56 +msgid "Sort" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:62 +msgid "!a comments per page" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:65 +msgid "Pager" +msgstr "" + +#: plugins/content_types/node_context/node_comments.inc:80 +msgid "\"@s\" comments" +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:10 +msgid "Node content" +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:12 +msgid "The content of the referenced node." +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:44 plugins/content_types/node_context/node_links.inc:41 +msgid "Node title." +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:45 +msgid "Node content goes here." +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:135 plugins/content_types/node_context/node_links.inc:78 +msgid "Link title to node" +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:138 plugins/content_types/node_context/node_links.inc:81 plugins/content_types/node_context/node_title.inc:55 +msgid "Check here to make the title link to the node." +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:148 +msgid "Treat this as the primary node page" +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:149 +msgid "This can affect title rendering and breadcrumbs from some node types." +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:160 +msgid "No extras" +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:161 +msgid "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." +msgstr "" + +#: plugins/content_types/node_context/node_content.inc:182 +msgid "\"@s\" content" +msgstr "" + +#: plugins/content_types/node_context/node_created.inc:10 +msgid "Node created date" +msgstr "" + +#: plugins/content_types/node_context/node_created.inc:12 +msgid "The date the referenced node was created." +msgstr "" + +#: plugins/content_types/node_context/node_created.inc:35 +msgid "Created date" +msgstr "" + +#: plugins/content_types/node_context/node_created.inc:49 plugins/content_types/node_context/node_updated.inc:49 +msgid "Date format" +msgstr "" + +#: plugins/content_types/node_context/node_created.inc:74 +msgid "\"@s\" created date" +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:11 +msgid "Node links" +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:13 +msgid "Node links of the referenced node." +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:42 +msgid "Node links go here." +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:84 +msgid "Teaser mode" +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:87 +msgid "Check here to show links in teaser mode." +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:94 +msgid "Whatever is placed here will appear in $node->panel_identifier to help theme node links displayed on the panel" +msgstr "" + +#: plugins/content_types/node_context/node_links.inc:108 +msgid "\"@s\" links" +msgstr "" + +#: plugins/content_types/node_context/node_title.inc:10 plugins/contexts/node.inc:169 +msgid "Node title" +msgstr "" + +#: plugins/content_types/node_context/node_title.inc:12 +msgid "The title of the referenced node." +msgstr "" + +#: plugins/content_types/node_context/node_title.inc:52 +msgid "Link to node" +msgstr "" + +#: plugins/content_types/node_context/node_title.inc:73 +msgid "\"@s\" title" +msgstr "" + +#: plugins/content_types/node_context/node_type_desc.inc:10;34 +msgid "Node type description" +msgstr "" + +#: plugins/content_types/node_context/node_type_desc.inc:12 +msgid "Node type description." +msgstr "" + +#: plugins/content_types/node_context/node_type_desc.inc:35 +msgid "Node type description goes here." +msgstr "" + +#: plugins/content_types/node_context/node_type_desc.inc:43 +msgid "\"@s\" type description" +msgstr "" + +#: plugins/content_types/node_context/node_updated.inc:10 +msgid "Node last updated date" +msgstr "" + +#: plugins/content_types/node_context/node_updated.inc:12 +msgid "The date the referenced node was last updated." +msgstr "" + +#: plugins/content_types/node_context/node_updated.inc:35 +msgid "Last updated date" +msgstr "" + +#: plugins/content_types/node_context/node_updated.inc:74 +msgid "\"@s\" last updated date" +msgstr "" + +#: plugins/content_types/node_form/node_form_attachments.inc:12 +msgid "Node form file attachments" +msgstr "" + +#: plugins/content_types/node_form/node_form_attachments.inc:13 +msgid "File attachments on the Node form." +msgstr "" + +#: plugins/content_types/node_form/node_form_attachments.inc:22 plugins/content_types/node_form/node_form_author.inc:20 plugins/content_types/node_form/node_form_book.inc:22 plugins/content_types/node_form/node_form_buttons.inc:20 plugins/content_types/node_form/node_form_comment.inc:22 plugins/content_types/node_form/node_form_input_format.inc:20 plugins/content_types/node_form/node_form_log.inc:20 plugins/content_types/node_form/node_form_menu.inc:22 plugins/content_types/node_form/node_form_path.inc:22 plugins/content_types/node_form/node_form_publishing.inc:28 plugins/content_types/node_form/node_form_taxonomy.inc:22 +msgid "node_form" +msgstr "" + +#: plugins/content_types/node_form/node_form_attachments.inc:24 +msgid "Attach files" +msgstr "" + +#: plugins/content_types/node_form/node_form_attachments.inc:35 +msgid "Attach files." +msgstr "" + +#: plugins/content_types/node_form/node_form_attachments.inc:41 +msgid "\"@s\" node form attach files" +msgstr "" + +#: plugins/content_types/node_form/node_form_author.inc:11 +msgid "Node form author information" +msgstr "" + +#: plugins/content_types/node_form/node_form_author.inc:12 +msgid "Author information on the Node form." +msgstr "" + +#: plugins/content_types/node_form/node_form_author.inc:22 +msgid "Authoring information" +msgstr "" + +#: plugins/content_types/node_form/node_form_author.inc:35 +msgid "Authoring information." +msgstr "" + +#: plugins/content_types/node_form/node_form_author.inc:41 +msgid "\"@s\" node form publishing options" +msgstr "" + +#: plugins/content_types/node_form/node_form_book.inc:12 +msgid "Node form book options" +msgstr "" + +#: plugins/content_types/node_form/node_form_book.inc:13 +msgid "Book options for the node." +msgstr "" + +#: plugins/content_types/node_form/node_form_book.inc:24 +msgid "Book options" +msgstr "" + +#: plugins/content_types/node_form/node_form_book.inc:39 +msgid "Book options." +msgstr "" + +#: plugins/content_types/node_form/node_form_book.inc:45 +msgid "\"@s\" node form book options" +msgstr "" + +#: plugins/content_types/node_form/node_form_buttons.inc:11 +msgid "Node form submit buttons" +msgstr "" + +#: plugins/content_types/node_form/node_form_buttons.inc:12 +msgid "Submit buttons for the node form." +msgstr "" + +#: plugins/content_types/node_form/node_form_buttons.inc:29 +msgid "Node form buttons." +msgstr "" + +#: plugins/content_types/node_form/node_form_buttons.inc:35 +msgid "\"@s\" node form submit buttons" +msgstr "" + +#: plugins/content_types/node_form/node_form_comment.inc:12 +msgid "Node form comment settings" +msgstr "" + +#: plugins/content_types/node_form/node_form_comment.inc:13 +msgid "Comment settings on the Node form." +msgstr "" + +#: plugins/content_types/node_form/node_form_comment.inc:24 +msgid "Comment options" +msgstr "" + +#: plugins/content_types/node_form/node_form_comment.inc:35 +msgid "Comment options." +msgstr "" + +#: plugins/content_types/node_form/node_form_comment.inc:41 +msgid "\"@s\" node form comment settings" +msgstr "" + +#: plugins/content_types/node_form/node_form_input_format.inc:11 +msgid "Node form input format" +msgstr "" + +#: plugins/content_types/node_form/node_form_input_format.inc:12 +msgid "Input format for the body field on a node." +msgstr "" + +#: plugins/content_types/node_form/node_form_input_format.inc:22 plugins/content_types/search/search_result.inc:131;169 +msgid "Input format" +msgstr "" + +#: plugins/content_types/node_form/node_form_input_format.inc:33 +msgid "Input format." +msgstr "" + +#: plugins/content_types/node_form/node_form_input_format.inc:39 +msgid "\"@s\" node form input format" +msgstr "" + +#: plugins/content_types/node_form/node_form_log.inc:11 +msgid "Node form revision log message" +msgstr "" + +#: plugins/content_types/node_form/node_form_log.inc:12 +msgid "Revision log message for the node." +msgstr "" + +#: plugins/content_types/node_form/node_form_log.inc:28 +msgid "\"@s\" node form revision log" +msgstr "" + +#: plugins/content_types/node_form/node_form_menu.inc:12 +msgid "Node form menu settings" +msgstr "" + +#: plugins/content_types/node_form/node_form_menu.inc:13 +msgid "Menu settings on the Node form." +msgstr "" + +#: plugins/content_types/node_form/node_form_menu.inc:24 +msgid "Menu options" +msgstr "" + +#: plugins/content_types/node_form/node_form_menu.inc:36 +msgid "Menu options." +msgstr "" + +#: plugins/content_types/node_form/node_form_menu.inc:42 +msgid "\"@s\" node form menu settings" +msgstr "" + +#: plugins/content_types/node_form/node_form_path.inc:12 +msgid "Node form url path settings" +msgstr "" + +#: plugins/content_types/node_form/node_form_path.inc:13 plugins/content_types/node_form/node_form_publishing.inc:18 +msgid "Publishing options on the Node form." +msgstr "" + +#: plugins/content_types/node_form/node_form_path.inc:24 +msgid "URL path options" +msgstr "" + +#: plugins/content_types/node_form/node_form_path.inc:36 +msgid "URL Path options." +msgstr "" + +#: plugins/content_types/node_form/node_form_path.inc:42 +msgid "\"@s\" node form path options" +msgstr "" + +#: plugins/content_types/node_form/node_form_publishing.inc:16 +msgid "Node form publishing options" +msgstr "" + +#: plugins/content_types/node_form/node_form_publishing.inc:27 +msgid "Publishing options" +msgstr "" + +#: plugins/content_types/node_form/node_form_publishing.inc:39 +msgid "Publishing options." +msgstr "" + +#: plugins/content_types/node_form/node_form_publishing.inc:45 +msgid "\"@s\" node form author information" +msgstr "" + +#: plugins/content_types/node_form/node_form_taxonomy.inc:12 +msgid "Node form categories" +msgstr "" + +#: plugins/content_types/node_form/node_form_taxonomy.inc:13 +msgid "Taxonomy categories for the node." +msgstr "" + +#: plugins/content_types/node_form/node_form_taxonomy.inc:24 +msgid "Categories" +msgstr "" + +#: plugins/content_types/node_form/node_form_taxonomy.inc:35 +msgid "Categories." +msgstr "" + +#: plugins/content_types/node_form/node_form_taxonomy.inc:41 +msgid "\"@s\" node form select taxonomy" +msgstr "" + +#: plugins/content_types/page/page_breadcrumb.inc:18 +msgid "Add the breadcrumb trail as content." +msgstr "" + +#: plugins/content_types/page/page_breadcrumb.inc:19 plugins/content_types/page/page_footer_message.inc:19 plugins/content_types/page/page_help.inc:19 plugins/content_types/page/page_messages.inc:19 plugins/content_types/page/page_mission.inc:19 plugins/content_types/page/page_slogan.inc:19 plugins/content_types/page/page_tabs.inc:19 plugins/content_types/page/page_title.inc:19 +msgid "Page elements" +msgstr "" + +#: plugins/content_types/page/page_footer_message.inc:16 +msgid "Page footer message" +msgstr "" + +#: plugins/content_types/page/page_footer_message.inc:18 +msgid "Add the page footer message as content." +msgstr "" + +#: plugins/content_types/page/page_help.inc:15 +msgid "Help" +msgstr "" + +#: plugins/content_types/page/page_help.inc:18 +msgid "Add the help text of the current page as content." +msgstr "" + +#: plugins/content_types/page/page_messages.inc:15 +msgid "Status messages" +msgstr "" + +#: plugins/content_types/page/page_messages.inc:18 +msgid "Add the status messages of the current page as content." +msgstr "" + +#: plugins/content_types/page/page_mission.inc:15 +msgid "Mission" +msgstr "" + +#: plugins/content_types/page/page_mission.inc:18 +msgid "Add the site mission statement as content." +msgstr "" + +#: plugins/content_types/page/page_slogan.inc:15 +msgid "Site Slogan" +msgstr "" + +#: plugins/content_types/page/page_slogan.inc:18 +msgid "Add the slogan trail as content." +msgstr "" + +#: plugins/content_types/page/page_tabs.inc:15 +msgid "Tabs" +msgstr "" + +#: plugins/content_types/page/page_tabs.inc:18 +msgid "Add the tabs (local tasks) as content." +msgstr "" + +#: plugins/content_types/page/page_title.inc:16 +msgid "Page title" +msgstr "" + +#: plugins/content_types/page/page_title.inc:18 +msgid "Add the page title as content." +msgstr "" + +#: plugins/content_types/search/search_form.inc:14 +msgid "Advanced search form" +msgstr "" + +#: plugins/content_types/search/search_form.inc:16 +msgid "A search form with advanced options." +msgstr "" + +#: plugins/content_types/search/search_form.inc:96 plugins/content_types/search/search_result.inc:95 +msgid "Search type" +msgstr "" + +#: plugins/content_types/search/search_form.inc:103 +msgid "Search form" +msgstr "" + +#: plugins/content_types/search/search_form.inc:105 +msgid "Simple" +msgstr "" + +#: plugins/content_types/search/search_form.inc:106 +msgid "Advanced" +msgstr "" + +#: plugins/content_types/search/search_form.inc:109 +msgid "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." +msgstr "" + +#: plugins/content_types/search/search_form.inc:118 +msgid "Same page" +msgstr "" + +#: plugins/content_types/search/search_form.inc:136 +msgid "Override default prompt" +msgstr "" + +#: plugins/content_types/search/search_form.inc:163 +msgid "@type search form" +msgstr "" + +#: plugins/content_types/search/search_result.inc:10;65 +msgid "Search results" +msgstr "" + +#: plugins/content_types/search/search_result.inc:12 +msgid "The results of a search using keywords." +msgstr "" + +#: plugins/content_types/search/search_result.inc:58 +msgid "results" +msgstr "" + +#: plugins/content_types/search/search_result.inc:70 +msgid "Your search yielded no results" +msgstr "" + +#: plugins/content_types/search/search_result.inc:103 +msgid "Record a watchdog log entry when searches are made" +msgstr "" + +#: plugins/content_types/search/search_result.inc:109 +msgid "Override \"no result\" text" +msgstr "" + +#: plugins/content_types/search/search_result.inc:121 +msgid "No result text" +msgstr "" + +#: plugins/content_types/search/search_result.inc:147 +msgid "Display text if no search keywords were submitted" +msgstr "" + +#: plugins/content_types/search/search_result.inc:159 +msgid "No keywords text" +msgstr "" + +#: plugins/content_types/search/search_result.inc:198 +msgid "@type search result" +msgstr "" + +#: plugins/content_types/search/search_result.inc:58 +msgid "search" +msgstr "" + +#: plugins/content_types/search/search_result.inc:58 +msgid "%keys (@type)." +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:10 +msgid "Term description" +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:12 +msgid "Term description." +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:14 plugins/content_types/term_context/term_list.inc:14 plugins/contexts/term.inc:15 +msgid "Taxonomy term" +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:30 +msgid "Edit term" +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:31 +msgid "Edit this term" +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:38 plugins/content_types/term_context/term_list.inc:63 +msgid "Term description goes here." +msgstr "" + +#: plugins/content_types/term_context/term_description.inc:46 +msgid "\"@s\" term description" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:10 +msgid "List of related terms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:12 +msgid "Terms related to an existing term; may be child, siblings or top level." +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:72 +msgid "Child terms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:73 +msgid "Related terms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:74 +msgid "Sibling terms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:75 +msgid "Top level terms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:76 +msgid "Term synonyms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:88 +msgid "Which terms" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:97 +msgid "List type" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:98 +msgid "Unordered" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:98 +msgid "Ordered" +msgstr "" + +#: plugins/content_types/term_context/term_list.inc:105 +msgid "\"@s\" @type" +msgstr "" + +#: plugins/content_types/user_context/profile_fields.inc:12 +msgid "Profile category" +msgstr "" + +#: plugins/content_types/user_context/profile_fields.inc:14 +msgid "Contents of a single profile category." +msgstr "" + +#: plugins/content_types/user_context/profile_fields.inc:65 +msgid "Profile content goes here." +msgstr "" + +#: plugins/content_types/user_context/profile_fields.inc:92 +msgid "Which category" +msgstr "" + +#: plugins/content_types/user_context/profile_fields.inc:102 +msgid "Text to display if category has no data. Note that title will not display unless overridden." +msgstr "" + +#: plugins/content_types/user_context/profile_fields.inc:123 +msgid "\"@s\" profile fields" +msgstr "" + +#: plugins/content_types/user_context/user_picture.inc:10 +msgid "User picture" +msgstr "" + +#: plugins/content_types/user_context/user_picture.inc:12 +msgid "The picture of a user." +msgstr "" + +#: plugins/content_types/user_context/user_picture.inc:37 +msgid "\"@s\" user picture" +msgstr "" + +#: plugins/content_types/user_context/user_profile.inc:10 +msgid "User profile" +msgstr "" + +#: plugins/content_types/user_context/user_profile.inc:12 +msgid "The profile of a user." +msgstr "" + +#: plugins/content_types/user_context/user_profile.inc:42 +msgid "\"@s\" user profile" +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:11 +msgid "Vocabulary terms" +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:13 +msgid "All the terms in a vocabulary." +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:66 +msgid "\"@s\" terms" +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:73 +msgid "Maximum depth" +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:74 +msgid "unlimited" +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:76 +msgid "Define the maximum depth of terms being displayed." +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:81 +msgid "Display as tree" +msgstr "" + +#: plugins/content_types/vocabulary_context/vocabulary_terms.inc:83 +msgid "If checked, the terms are displayed in a tree, otherwise in a flat list." +msgstr "" + +#: plugins/contexts/node.inc:17 +msgid "A node object." +msgstr "" + +#: plugins/contexts/node.inc:29 +msgid "Enter the node ID of a node for this context." +msgstr "" + +#: plugins/contexts/node.inc:92 plugins/contexts/node_edit_form.inc:109 +msgid "'%title' [node id %nid]" +msgstr "" + +#: plugins/contexts/node.inc:92 plugins/contexts/node_edit_form.inc:109 +msgid "Open in new window" +msgstr "" + +#: plugins/contexts/node.inc:93 plugins/contexts/node_edit_form.inc:110 +msgid "Currently set to !link" +msgstr "" + +#: plugins/contexts/node.inc:105 plugins/contexts/node_edit_form.inc:122 +msgid "Reset identifier to node title" +msgstr "" + +#: plugins/contexts/node.inc:106 plugins/contexts/node_edit_form.inc:123 +msgid "If checked, the identifier will be reset to the node title of the selected node." +msgstr "" + +#: plugins/contexts/node.inc:118 plugins/contexts/node_edit_form.inc:135 +msgid "You must select a node." +msgstr "" + +#: plugins/contexts/node.inc:144 plugins/contexts/node_edit_form.inc:164 +msgid "Invalid node selected." +msgstr "" + +#: plugins/contexts/node.inc:167 +msgid "Node ID" +msgstr "" + +#: plugins/contexts/node.inc:168 +msgid "Node revision ID" +msgstr "" + +#: plugins/contexts/node.inc:170 +msgid "Author UID" +msgstr "" + +#: plugins/contexts/node_add_form.inc:15 +msgid "Node add form" +msgstr "" + +#: plugins/contexts/node_add_form.inc:16 +msgid "A node add form." +msgstr "" + +#: plugins/contexts/node_add_form.inc:25 +msgid "Enter the node type this context." +msgstr "" + +#: plugins/contexts/node_add_form.inc:78 +msgid "Submit @name" +msgstr "" + +#: plugins/contexts/node_add_form.inc:104 +msgid "Select the node type for this form." +msgstr "" + +#: plugins/contexts/node_edit_form.inc:15 +msgid "Node edit form" +msgstr "" + +#: plugins/contexts/node_edit_form.inc:16 +msgid "A node edit form." +msgstr "" + +#: plugins/contexts/node_edit_form.inc:27 +msgid "Enter the node ID of a node for this argument:" +msgstr "" + +#: plugins/contexts/string.inc:16 +msgid "A context that is just a string." +msgstr "" + +#: plugins/contexts/string.inc:22 +msgid "Raw string" +msgstr "" + +#: plugins/contexts/string.inc:23 +msgid "HTML-safe string" +msgstr "" + +#: plugins/contexts/string.inc:28 +msgid "Enter the string for this context." +msgstr "" + +#: plugins/contexts/term.inc:16 +msgid "A single taxonomy term object." +msgstr "" + +#: plugins/contexts/term.inc:26 +msgid "Vocabulary ID" +msgstr "" + +#: plugins/contexts/term.inc:79 +msgid "Currently set to @term. Enter another term if you wish to change the term." +msgstr "" + +#: plugins/contexts/term.inc:96 +msgid "Select a term from @vocabulary." +msgstr "" + +#: plugins/contexts/term.inc:114 +msgid "Reset identifier to term title" +msgstr "" + +#: plugins/contexts/term.inc:115 +msgid "If checked, the identifier will be reset to the term name of the selected term." +msgstr "" + +#: plugins/contexts/term.inc:128 +msgid "You must select a term." +msgstr "" + +#: plugins/contexts/term.inc:139 +msgid "Invalid term selected." +msgstr "" + +#: plugins/contexts/terms.inc:16 +msgid "Taxonomy terms" +msgstr "" + +#: plugins/contexts/terms.inc:17 +msgid "Multiple taxonomy terms, as a group." +msgstr "" + +#: plugins/contexts/terms.inc:25 +msgid "Term ID of first term" +msgstr "" + +#: plugins/contexts/terms.inc:26 +msgid "Term ID of all term, separated by + or ," +msgstr "" + +#: plugins/contexts/terms.inc:27 +msgid "Term name of first term" +msgstr "" + +#: plugins/contexts/terms.inc:28 +msgid "Term name of all terms, separated by + or ," +msgstr "" + +#: plugins/contexts/terms.inc:29 +msgid "Vocabulary ID of first term" +msgstr "" + +#: plugins/contexts/user.inc:16 +msgid "A single user object." +msgstr "" + +#: plugins/contexts/user.inc:24 +msgid "User ID" +msgstr "" + +#: plugins/contexts/user.inc:25 +msgid "User name" +msgstr "" + +#: plugins/contexts/vocabulary.inc:15 +msgid "Taxonomy vocabulary" +msgstr "" + +#: plugins/contexts/vocabulary.inc:16 +msgid "A single taxonomy vocabulary object." +msgstr "" + +#: plugins/relationships/book_parent.inc:14 +msgid "Book parent" +msgstr "" + +#: plugins/relationships/book_parent.inc:16 +msgid "Adds a book parent from a node context." +msgstr "" + +#: plugins/relationships/book_parent.inc:63 plugins/relationships/term_parent.inc:63 +msgid "Relationship type" +msgstr "" + +#: plugins/relationships/book_parent.inc:64 plugins/relationships/term_parent.inc:64 +msgid "Immediate parent" +msgstr "" + +#: plugins/relationships/book_parent.inc:64 +msgid "Top level book" +msgstr "" + +#: plugins/relationships/term_from_node.inc:14 +msgid "Term from node" +msgstr "" + +#: plugins/relationships/term_from_node.inc:16 +msgid "Adds a taxonomy term from a node context; if multiple terms are selected, this will get the \"first\" term only." +msgstr "" + +#: plugins/relationships/term_parent.inc:14 +msgid "Term parent" +msgstr "" + +#: plugins/relationships/term_parent.inc:16 +msgid "Adds a taxonomy term parent from a term context." +msgstr "" + +#: plugins/relationships/term_parent.inc:64 +msgid "Top level term" +msgstr "" + +#: plugins/relationships/user_from_node.inc:16 +msgid "Creates the author of a node as a user context." +msgstr "" + +#: views_content/views_content.module:61 views_content/plugins/content_types/views.inc:99 +msgid "Views" +msgstr "" + +#: views_content/views_content.module:92 +msgid "Make all views available as panes" +msgstr "" + +#: views_content/views_content.module:93 +msgid "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." +msgstr "" + +#: views_content/views_content.module:20 +msgid "Views panes" +msgstr "" + +#: views_content/views_content.module:24 +msgid "Configure Views to be used as CTools content." +msgstr "" + +#: views_content/views_content.info:0 +msgid "Views content panes" +msgstr "" + +#: views_content/views_content.info:0 +msgid "Allows Views content to be used in Panels, Dashboard and other modules which use the CTools Content API." +msgstr "" + +#: views_content/plugins/content_types/views.inc:18 +msgid "All views" +msgstr "" + +#: views_content/plugins/content_types/views.inc:33 +msgid "Select display" +msgstr "" + +#: views_content/plugins/content_types/views.inc:36 +msgid "Configure view" +msgstr "" + +#: views_content/plugins/content_types/views.inc:226 +msgid "Display" +msgstr "" + +#: views_content/plugins/content_types/views.inc:228 +msgid "Choose which display of this view you wish to use." +msgstr "" + +#: views_content/plugins/content_types/views.inc:249 views_content/plugins/content_types/views_panes.inc:282 +msgid "Broken/missing/deleted view." +msgstr "" + +#: views_content/plugins/content_types/views.inc:253 +msgid "Configure view @view (@display)" +msgstr "" + +#: views_content/plugins/content_types/views.inc:275 +msgid "Link title to view" +msgstr "" + +#: views_content/plugins/content_types/views.inc:281 +msgid "Provide a \"more\" link that links to the view" +msgstr "" + +#: views_content/plugins/content_types/views.inc:282 +msgid "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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:288 views_content/plugins/content_types/views_panes.inc:335 +msgid "Display feed icons" +msgstr "" + +#: views_content/plugins/content_types/views.inc:294 +msgid "Custom pager settings" +msgstr "" + +#: views_content/plugins/content_types/views.inc:299 +msgid "Use different pager settings from view settings" +msgstr "" + +#: views_content/plugins/content_types/views.inc:306 +msgid "<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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:313 views_content/plugins/content_types/views_panes.inc:343 views_content/plugins/views/views_content_plugin_display_panel_pane.inc:148 +msgid "Use pager" +msgstr "" + +#: views_content/plugins/content_types/views.inc:322 views_content/plugins/content_types/views_panes.inc:351 +msgid "Pager ID" +msgstr "" + +#: views_content/plugins/content_types/views.inc:335 +msgid "Num posts" +msgstr "" + +#: views_content/plugins/content_types/views.inc:343 views_content/plugins/content_types/views_panes.inc:372 +msgid "Offset" +msgstr "" + +#: views_content/plugins/content_types/views.inc:345 +msgid "The number of items to skip and not display." +msgstr "" + +#: views_content/plugins/content_types/views.inc:352 +msgid "Send arguments" +msgstr "" + +#: views_content/plugins/content_types/views.inc:354 +msgid "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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:362 +msgid "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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:368 +msgid "Override URL" +msgstr "" + +#: views_content/plugins/content_types/views.inc:370 +msgid "If this is set, override the View URL; this can sometimes be useful to set to the panel URL" +msgstr "" + +#: views_content/plugins/content_types/views.inc:394;406 views_content/plugins/content_types/views_panes.inc:411;414 +msgid "Deleted/missing view @view" +msgstr "" + +#: views_content/plugins/content_types/views.inc:396 +msgid "View: @name" +msgstr "" + +#: views_content/plugins/content_types/views.inc:409 +msgid "View information" +msgstr "" + +#: views_content/plugins/content_types/views.inc:412 +msgid "Using display @display." +msgstr "" + +#: views_content/plugins/content_types/views.inc:433 +msgid "Argument @arg using context @context converted into @converter" +msgstr "" + +#: views_content/plugins/content_types/views.inc:441 +msgid "@count items displayed." +msgstr "" + +#: views_content/plugins/content_types/views.inc:443 +msgid "With pager." +msgstr "" + +#: views_content/plugins/content_types/views.inc:446 +msgid "Without pager." +msgstr "" + +#: views_content/plugins/content_types/views.inc:450 +msgid "Skipping first @count results" +msgstr "" + +#: views_content/plugins/content_types/views.inc:453 +msgid "With more link." +msgstr "" + +#: views_content/plugins/content_types/views.inc:456 +msgid "With feed icon." +msgstr "" + +#: views_content/plugins/content_types/views.inc:459 +msgid "Sending arguments." +msgstr "" + +#: views_content/plugins/content_types/views.inc:462 +msgid "Using arguments: @args" +msgstr "" + +#: views_content/plugins/content_types/views.inc:465 +msgid "Using url: @url" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:15;94 views_content/plugins/views/views_content_plugin_display_panel_pane.inc:92 +msgid "View panes" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:319 +msgid "Link title to page" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:326 +msgid "Provide a \"more\" link." +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:363 +msgid "Num items" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:365 +msgid "Select the number of items to display, or 0 to display all results." +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:374 +msgid "Enter the number of items to skip; enter 0 to skip no items." +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:381 +msgid "Override path" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:383 +msgid "If this is set, override the View URL path; this can sometimes be useful to set to the panel URL." +msgstr "" + +#: views_content/plugins/views/views_content.views.inc:16 +msgid "Content pane" +msgstr "" + +#: views_content/plugins/views/views_content.views.inc:17 +msgid "Is available as content for a panel or dashboard display." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:56 +msgid "Pane settings" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:61 +msgid "Use view name" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:70 +msgid "Admin title" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:76 +msgid "Use view description" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:85 +msgid "Admin desc" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:101 +msgid "Category" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:107;151 +msgid "Link to view" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:108;114;208;218 +msgid "Yes" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:108;114;208;218 +msgid "No" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:113 +msgid "Use Panel path" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:119 +msgid "Argument input" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:128;142 +msgid "Allow settings" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "None" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "All" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "Some" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:144 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:149 +msgid "Items per page" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:150 +msgid "Pager offset" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:152 +msgid "More link" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:153 +msgid "Path override" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:154 +msgid "Title override" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:171 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:181 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:193 +msgid "This is category the pane will appear in on the add content dialog." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:199 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:204 +msgid "Link pane title to view" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:214 +msgid "Inherit path from panel display" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:220 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:225 +msgid "Choose the data source for view arguments" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:242 +msgid "No argument" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:243 +msgid "Argument wildcard" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:244 +msgid "From context" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:245 +msgid "From panel argument" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:246 +msgid "Fixed" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:247 +msgid "Input on pane config" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:250 +msgid "@arg source" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:256 +msgid "Required context" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:257 +msgid "If \"From context\" is selected, which type of context to use." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:266 +msgid "Context is optional" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:267 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:275 +msgid "Panel argument" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:276 +msgid "If \"From panel argument\" is selected, which panel argument to use." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +msgid "First" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +msgid "Second" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +msgid "Third" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +msgid "Fourth" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +msgid "Fifth" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:278 +msgid "Sixth" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:285 +msgid "Fixed argument" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:286 +msgid "If \"Fixed\" is selected, what to use as an argument." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:294 +msgid "Label" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:295 +msgid "If this argument is presented to the panels user, what label to apply to it." +msgstr "" + diff --git a/sites/all/modules/ctools/views_content/plugins/content_types/icon_views_block_legacy.png b/sites/all/modules/ctools/views_content/plugins/content_types/icon_views_block_legacy.png new file mode 100644 index 0000000000000000000000000000000000000000..f2e07474a358847696d4525c1e94696fd1907559 Binary files /dev/null and b/sites/all/modules/ctools/views_content/plugins/content_types/icon_views_block_legacy.png differ diff --git a/sites/all/modules/ctools/views_content/plugins/content_types/icon_views_page.png b/sites/all/modules/ctools/views_content/plugins/content_types/icon_views_page.png new file mode 100644 index 0000000000000000000000000000000000000000..27efe7c13a4ba5eb9c8c98d1610c71408a77abae Binary files /dev/null and b/sites/all/modules/ctools/views_content/plugins/content_types/icon_views_page.png differ diff --git a/sites/all/modules/ctools/views_content/plugins/content_types/icon_views_page_legacy.png b/sites/all/modules/ctools/views_content/plugins/content_types/icon_views_page_legacy.png new file mode 100644 index 0000000000000000000000000000000000000000..31173353471a442a55937d9ca37db8861c953777 Binary files /dev/null and b/sites/all/modules/ctools/views_content/plugins/content_types/icon_views_page_legacy.png differ diff --git a/sites/all/modules/ctools/views_content/plugins/content_types/translations/views_content-plugins-content_types.hu.po b/sites/all/modules/ctools/views_content/plugins/content_types/translations/views_content-plugins-content_types.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..d0905b1f6ff51b60e472f9694b5dd7e1bcf9651d --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/content_types/translations/views_content-plugins-content_types.hu.po @@ -0,0 +1,150 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 12:48+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 "Display" +msgstr "Képernyő" +msgid "Override URL" +msgstr "URL felülbírálása" +msgid "" +"If this is set, override the View URL; this can sometimes be useful to " +"set to the panel URL" +msgstr "" +"Ha ez be van kapocsolva, akkor felülírja a nézet webcímét. Néha " +"hasznos lehet a panel webcímére állítani." +msgid "All views" +msgstr "Összes nézet" +msgid "Override path" +msgstr "Elérési út felülbírálása" +msgid "Link title to view" +msgstr "A cím hivatkozzon a nézetre" +msgid "Provide a \"more\" link that links to the view" +msgstr "Egy, a nézetre hivatkozó „tovább” hivatkozást biztosít" +msgid "" +"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." +msgstr "" +"Ez független bármilyen, a nézet által biztosított tovább " +"hivatkozástól; ha két tovább hivatkozás jelenik meg, ezt ki kell " +"kapcsolni. A nézetek csak a „blokk” típus használatakor " +"biztosítanak tovább hivatkozást, azonban ha be van ágyazva, akkor " +"ezt kell használni." +msgid "Num posts" +msgstr "Beküldések száma" +msgid "Send arguments" +msgstr "Argumentumok küldése" +msgid "Select display" +msgstr "Képernyő kiválasztása" +msgid "Configure view" +msgstr "Nézet beállítása" +msgid "Choose which display of this view you wish to use." +msgstr "A nézet használni kívánt képernyőjének kiválasztása." +msgid "Configure view @view (@display)" +msgstr "@view (@display) nézet beállítása" +msgid "View: @name" +msgstr "Nézet: @name" +msgid "View information" +msgstr "Nézet adatai" +msgid "Using display @display." +msgstr "@display képernyő használata." +msgid "Argument @arg using context @context converted into @converter" +msgstr "" +"@context környezet által használt @arg argumentum konvertálva lett " +"ebbe: @converter" +msgid "@count items displayed." +msgstr "@count elem lett megjelenítve." +msgid "With pager." +msgstr "Lapozóval." +msgid "Without pager." +msgstr "Lapozó nélkül." +msgid "Skipping first @count results" +msgstr "Első @count eredmény átugrása" +msgid "With more link." +msgstr "Tovább hivatkozással." +msgid "With feed icon." +msgstr "Hírforrás ikonnal." +msgid "Sending arguments." +msgstr "Argumentumok küldése." +msgid "Using arguments: @args" +msgstr "Használt argumentumok: @args" +msgid "Using url: @url" +msgstr "Használt url: @url" +msgid "Link title to page" +msgstr "A cím hivatkozzon az oldalra" +msgid "Provide a \"more\" link." +msgstr "Egy „tovább” hivatkozás biztosítása." +msgid "Num items" +msgstr "Elemek száma" +msgid "Select the number of items to display, or 0 to display all results." +msgstr "" +"A megjelenített elemek száma, vagy 0 az összes eredmény " +"megjelenítéséhez." +msgid "Enter the number of items to skip; enter 0 to skip no items." +msgstr "Az átugrott elemek száma; a 0 nem ugrik át elemet." +msgid "" +"If this is set, override the View URL path; this can sometimes be " +"useful to set to the panel URL." +msgstr "" +"Ha be van állítva, felülírja a nézet URL elérési útját; néha " +"hasznos lehet a panel URL címére beállítani." +msgid "Custom pager settings" +msgstr "Egyéni lapozó beállításai" +msgid "Use different pager settings from view settings" +msgstr "" +"A lapozó eltérő beállításainak használata a nézet " +"beállításai alapján" +msgid "" +"<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." +msgstr "" +"<strong>Figyelmeztetés</strong>: ez a nézet AJAX-ot használ. A " +"lapozó beállítások felülírása kezdetben működni fog, de ahogy " +"a nézet frissítve lesz AJAX-on keresztül, az eredeti beállítások " +"lesznek használva. Nem kell felülírni a lapozó beállításokat " +"azokban a nézetekben, ahol az AJAX beállítások engedélyezve " +"vannak." +msgid "The number of items to skip and not display." +msgstr "Az átugrott és nem mutatott elemek száma." +msgid "" +"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." +msgstr "" +"Kiválasztva a panel összes argumentuma át lesz küldve " +"közvetlenül a nézetnek. Ha be van jelölve, a panel argumentumok a " +"környezet argumentumok után következnek és megelőznek bármilyen " +"további, a lenti Argumentumok mezőn keresztül átadott " +"argumentumot. Meg kell jegyezni, hogy az argumentumok nem " +"tartalmazzák az alap URL-t; csak az URL utáni vagy a " +"helykitöltőkkel beállított értékek lesznek argumentumként " +"figyelembe véve." +msgid "" +"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." +msgstr "" +"További, az URL részeként arg1/arg2/arg3 formában a nézetnek " +"küldött argumentumok. %0, %1, ..., %N használható az argumentumok " +"kinyerésére az URL-ből. Vagy @0, @1, @2, ..., @N használható a " +"panelben átadott argumentunokhoz. Megjegyzés: csak a legutolsó " +"megoldásként használható. A Panels következő verzióiban ezek " +"már nem lesznek benne." diff --git a/sites/all/modules/ctools/views_content/plugins/content_types/views.inc b/sites/all/modules/ctools/views_content/plugins/content_types/views.inc new file mode 100644 index 0000000000000000000000000000000000000000..f825c809c497a74175555054d28ef5fb36e65c84 --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/content_types/views.inc @@ -0,0 +1,567 @@ +<?php +// $Id: views.inc,v 1.17 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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.') + ); + + return $form; +} + +/** + * 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->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/sites/all/modules/ctools/views_content/plugins/content_types/views_attachments.inc b/sites/all/modules/ctools/views_content/plugins/content_types/views_attachments.inc new file mode 100644 index 0000000000000000000000000000000000000000..b5aa4222caa555e8e9bcd07394fd0796ecfdbba5 --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/content_types/views_attachments.inc @@ -0,0 +1,76 @@ +<?php +// $Id: views_attachments.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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'], + ); + + return $form; +} + +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/sites/all/modules/ctools/views_content/plugins/content_types/views_empty.inc b/sites/all/modules/ctools/views_content/plugins/content_types/views_empty.inc new file mode 100644 index 0000000000000000000000000000000000000000..7bcc86c92813399d8500d17861e5fcd006a3e23a --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/content_types/views_empty.inc @@ -0,0 +1,53 @@ +<?php +// $Id: views_empty.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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); + $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/sites/all/modules/ctools/views_content/plugins/content_types/views_exposed.inc b/sites/all/modules/ctools/views_content/plugins/content_types/views_exposed.inc new file mode 100644 index 0000000000000000000000000000000000000000..8dd90f08010f9533e5016dd6e2c28eda779c73fd --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/content_types/views_exposed.inc @@ -0,0 +1,53 @@ +<?php +// $Id: views_exposed.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/views_content/plugins/content_types/views_feed.inc b/sites/all/modules/ctools/views_content/plugins/content_types/views_feed.inc new file mode 100644 index 0000000000000000000000000000000000000000..53b325927b7fb3dceef1fa908d36d630ae7730c2 --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/content_types/views_feed.inc @@ -0,0 +1,53 @@ +<?php +// $Id: views_feed.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/views_content/plugins/content_types/views_footer.inc b/sites/all/modules/ctools/views_content/plugins/content_types/views_footer.inc new file mode 100644 index 0000000000000000000000000000000000000000..595c164f8175d44dcc7754d9671b11702206c42a --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/content_types/views_footer.inc @@ -0,0 +1,53 @@ +<?php +// $Id: views_footer.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/views_content/plugins/content_types/views_header.inc b/sites/all/modules/ctools/views_content/plugins/content_types/views_header.inc new file mode 100644 index 0000000000000000000000000000000000000000..3a446556ee3d5ab2eafda911d2ff94ecc7f6a665 --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/content_types/views_header.inc @@ -0,0 +1,53 @@ +<?php +// $Id: views_header.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/views_content/plugins/content_types/views_pager.inc b/sites/all/modules/ctools/views_content/plugins/content_types/views_pager.inc new file mode 100644 index 0000000000000000000000000000000000000000..24ae47b223dde32ec73b10f7577a9c0df3f09069 --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/content_types/views_pager.inc @@ -0,0 +1,53 @@ +<?php +// $Id: views_pager.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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/sites/all/modules/ctools/views_content/plugins/content_types/views_panes.inc b/sites/all/modules/ctools/views_content/plugins/content_types/views_panes.inc new file mode 100644 index 0000000000000000000000000000000000000000..630e12a5925777dc88c596700bc65b712e8c7be5 --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/content_types/views_panes.inc @@ -0,0 +1,615 @@ +<?php +// $Id: views_panes.inc,v 1.24 2011/01/05 19:53:36 merlinofchaos Exp $ + +/** + * @file + * Content type plugin to allow Views to be exposed as a display type, + * leaving most of the configuration on the view. + */ + +/** + * Implements 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 = t('@view: @display', array('@view' => $view->name, '@display' => $display->display_title)); + } + + $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[] = $panel_args[$argument['panel']]; + 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 ($conf['fields_override'] 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']] : ''; + } + } + + return $form; +} + +/** + * 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/sites/all/modules/ctools/views_content/plugins/content_types/views_row.inc b/sites/all/modules/ctools/views_content/plugins/content_types/views_row.inc new file mode 100644 index 0000000000000000000000000000000000000000..8233480188d62bc1536156ed1b2ced7dfbb3597f --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/content_types/views_row.inc @@ -0,0 +1,190 @@ +<?php +// $Id: views_row.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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; + } + + // Support Views 2 and Views 3. + if (method_exists($view, 'get_items_per_page')) { + $view->init_pager(); + $rows = $view->get_items_per_page(); + } + else { + $rows = $view->display_handler->get_option('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/sites/all/modules/ctools/views_content/plugins/contexts/view.inc b/sites/all/modules/ctools/views_content/plugins/contexts/view.inc new file mode 100644 index 0000000000000000000000000000000000000000..fed1f8f9f92d456818099e1f8be459f27647fda8 --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/contexts/view.inc @@ -0,0 +1,135 @@ +<?php +// $Id: view.inc,v 1.2 2010/10/11 22:18:24 sdboyer Exp $ + +/** + * @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($form, &$form_state) { + $conf = $form_state['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_state) { + if (empty($form_state['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/sites/all/modules/ctools/views_content/plugins/relationships/node_from_view.inc b/sites/all/modules/ctools/views_content/plugins/relationships/node_from_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..de8f3e9c4d5789c455ee5bd75995e1e8f6a814c2 --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/relationships/node_from_view.inc @@ -0,0 +1,65 @@ +<?php +// $Id: node_from_view.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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($form, &$form_state) { + $conf = $form_state['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_state) { + if (intval($form_state['values']['row']) <= 0) { + form_error($form['row'], t('Row number must be a positive integer value.')); + } +} diff --git a/sites/all/modules/ctools/views_content/plugins/relationships/term_from_view.inc b/sites/all/modules/ctools/views_content/plugins/relationships/term_from_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..e99dcf8f755251c42da1bd80f0cb26ee0512ab10 --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/relationships/term_from_view.inc @@ -0,0 +1,65 @@ +<?php +// $Id: term_from_view.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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($form, &$form_state) { + $conf = $form_state['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_state) { + if (intval($form_state['values']['row']) <= 0) { + form_error($form['row'], t('Row number must be a positive integer value.')); + } +} diff --git a/sites/all/modules/ctools/views_content/plugins/relationships/user_from_view.inc b/sites/all/modules/ctools/views_content/plugins/relationships/user_from_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..62e907ffcc8d5a45fc3420a8c9ecb013355cfe8d --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/relationships/user_from_view.inc @@ -0,0 +1,65 @@ +<?php +// $Id: user_from_view.inc,v 1.2 2010/10/11 22:18:22 sdboyer Exp $ + +/** + * @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($form, &$form_state) { + $conf = $form_state['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_state) { + if (intval($form_state['values']['row']) <= 0) { + form_error($form['row'], t('Row number must be a positive integer value.')); + } +} diff --git a/sites/all/modules/ctools/views_content/plugins/views/translations/views_content-plugins-views.hu.po b/sites/all/modules/ctools/views_content/plugins/views/translations/views_content-plugins-views.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..e3567c0b41d6311a5139a64486b38a1c74b6fb89 --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/views/translations/views_content-plugins-views.hu.po @@ -0,0 +1,176 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-12 02:42+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 "Yes" +msgstr "Igen" +msgid "No" +msgstr "Nem" +msgid "None" +msgstr "Nincs" +msgid "Admin title" +msgstr "Adminisztratív cím" +msgid "Category" +msgstr "Kategória" +msgid "Label" +msgstr "Címke" +msgid "All" +msgstr "Minden" +msgid "Some" +msgstr "Néhány" +msgid "First" +msgstr "Első" +msgid "Second" +msgstr "Másodperc" +msgid "Fixed" +msgstr "Rögzített" +msgid "Third" +msgstr "Harmadik" +msgid "Fourth" +msgstr "Negyedik" +msgid "Fifth" +msgstr "Ötödik" +msgid "Argument wildcard" +msgstr "Argumentumot helyettesítő karakter" +msgid "No argument" +msgstr "Nincs argumentum" +msgid "From context" +msgstr "Környezetből" +msgid "From panel argument" +msgstr "Panel argumentumból" +msgid "Input on pane config" +msgstr "Bemenet a táblabeállításon" +msgid "Required context" +msgstr "Szükséges környezet" +msgid "Panel argument" +msgstr "Panel argumentum" +msgid "If \"From panel argument\" is selected, which panel argument to use." +msgstr "" +"Ha a „Panel argumentumból” van kiválasztva, akkor melyik panel " +"argumentum legyen felhasználva." +msgid "Sixth" +msgstr "Hatodik" +msgid "Fixed argument" +msgstr "Rögzített argumentum" +msgid "If \"Fixed\" is selected, what to use as an argument." +msgstr "" +"Ha a „Rögzített” van kiválasztva, akkor mi legyen " +"argumentumként felhasználva." +msgid "" +"If this argument is presented to the panels user, what label to apply " +"to it." +msgstr "" +"Ha ez az argumentum a panels felhasználónak szól, akkor milyen " +"címke legyen alkalmazva hozzá." +msgid "Link to view" +msgstr "Hivatkozás a nézetre" +msgid "More link" +msgstr "Tovább hivatkozás" +msgid "Items per page" +msgstr "Elemek oldalanként" +msgid "Content pane" +msgstr "Tartalomtábla" +msgid "Is available as content for a panel or dashboard display." +msgstr "" +"Tartalomként elérhető egy panel, vagy egy irányítópult " +"képernyő számára." +msgid "Pane settings" +msgstr "Tábla beállítások" +msgid "Use view name" +msgstr "Nézetnév használata" +msgid "Use view description" +msgstr "Nézetleírás használata" +msgid "Admin desc" +msgstr "Adminisztratív leírás" +msgid "Use Panel path" +msgstr "Panel elérési út használata" +msgid "Argument input" +msgstr "Argumentum bemenet" +msgid "Allow settings" +msgstr "Beállítások engedélyezése" +msgid "" +"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." +msgstr "" +"A bejelölt beállítások elérhetőek lesznek a panel " +"táblabeállítás párbeszédablakában, ahol a panels felhasználó " +"módosítani tudja azokat. A be nem jelölt beállítások nem lesznek " +"elérhetőek, továbbá a beállítások csak ebben a képernyőben " +"lesznek használva." +msgid "Pager offset" +msgstr "Lapozó eltolása" +msgid "Path override" +msgstr "Elérési út felülbírálása" +msgid "Title override" +msgstr "Cím felülírása" +msgid "" +"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." +msgstr "" +"Ez az a cím, ami ebben a nézettáblában a tartalom hozzáadása " +"párbeszédablakban fog megjelenni. Üresen hagyva a nézet neve lesz " +"használva." +msgid "" +"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." +msgstr "" +"Ez a szöveg akkor fog megjelenni, amikor a felhasználó az egeret a " +"tartalom hozzáadása párbeszédablakban a tábla fölé viszi. " +"Üresen hagyva a nézet leírása lesz használva." +msgid "This is category the pane will appear in on the add content dialog." +msgstr "" +"Ez az a kategória, amiben a tábla megjelenik a tartalom hozzáadása " +"párbeszédablakban." +msgid "" +"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." +msgstr "" +"A kategória alapértelmezett súlya. Meg kell jegyezni, hogy ha a " +"kategória súlya több helyen is be van állítva, akkor csak az " +"első panelek fogják megkapni ezt a beállítást, vagyis ha a súly " +"nem tűnik működőnek, le kell ellenőrizni azokat a helyeket ahol a " +"súly be lett állítva." +msgid "Link pane title to view" +msgstr "A tábla címe hivatkozzon a nézetre" +msgid "Inherit path from panel display" +msgstr "Panel képernyőről örökölt elérési út" +msgid "" +"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." +msgstr "" +"Ha igen, minden a Views által létrehozott tovább, összefoglaló " +"és felfedett bemenet hivatkozás a panelek elérési útjába kerül " +"és nem a nézetébe, amennyiben a megjelenítésnek van elérési " +"útja." +msgid "Choose the data source for view arguments" +msgstr "Nézetargumentumok adatforrásának kiválasztása" +msgid "@arg source" +msgstr "@arg forrás" +msgid "If \"From context\" is selected, which type of context to use." +msgstr "" +"A „Környezetből” kiválasztása esetén melyik környezettípus " +"legyen használva." +msgid "Context is optional" +msgstr "A környezet nem kötelező" +msgid "" +"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." +msgstr "" +"Ennek a környezetnek jelen kell lennie a tábla működéséhez. Ha " +"szükség van a használatára, meg kell győződni róla, hogy az " +"argumentumkezelő tudja elegánsan kezelni az üres értékeket." diff --git a/sites/all/modules/ctools/views_content/plugins/views/views_content.views.inc b/sites/all/modules/ctools/views_content/plugins/views/views_content.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..6e35bce27b169c469f8620dfa811b63786bbec1d --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/views/views_content.views.inc @@ -0,0 +1,59 @@ +<?php +// $Id: views_content.views.inc,v 1.4 2010/09/07 09:02:51 sdboyer Exp $ + +/** + * @file + * Contains Views plugin definitions for the panel pane display. + */ + +/** + * Implements 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', + ), + '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', + ), + ), + '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/sites/all/modules/ctools/views_content/plugins/views/views_content_plugin_display_ctools_context.inc b/sites/all/modules/ctools/views_content/plugins/views/views_content_plugin_display_ctools_context.inc new file mode 100644 index 0000000000000000000000000000000000000000..6a5759fd4e01471ccc96b6d2fb85752b39b0cdf3 --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/views/views_content_plugin_display_ctools_context.inc @@ -0,0 +1,156 @@ +<?php +// $Id: views_content_plugin_display_ctools_context.inc,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ +/** + * @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/sites/all/modules/ctools/views_content/plugins/views/views_content_plugin_display_panel_pane.inc b/sites/all/modules/ctools/views_content/plugins/views/views_content_plugin_display_panel_pane.inc new file mode 100644 index 0000000000000000000000000000000000000000..f8108a9bec2af81fa383009ecc2766d12081ae76 --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/views/views_content_plugin_display_panel_pane.inc @@ -0,0 +1,404 @@ +<?php +// $Id: views_content_plugin_display_panel_pane.inc,v 1.7 2011/01/01 01:27:38 merlinofchaos Exp $ + +/** + * 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'); + ctools_include('dependent'); + $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('form_process_select', 'ctools_dependent_process'), + '#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('form_process_checkbox', 'ctools_dependent_process'), + '#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('form_process_select', 'ctools_dependent_process'), + '#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('ctools_dependent_process'), + '#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('ctools_dependent_process'), + '#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/sites/all/modules/ctools/views_content/plugins/views/views_content_plugin_style_ctools_context.inc b/sites/all/modules/ctools/views_content/plugins/views/views_content_plugin_style_ctools_context.inc new file mode 100644 index 0000000000000000000000000000000000000000..ce79b583105632937400386e2949d833cbc65a2c --- /dev/null +++ b/sites/all/modules/ctools/views_content/plugins/views/views_content_plugin_style_ctools_context.inc @@ -0,0 +1,58 @@ +<?php +// $Id: views_content_plugin_style_ctools_context.inc,v 1.2 2010/10/11 22:18:23 sdboyer Exp $ +/** + * @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(); + + /** + * Set default options + */ + function options(&$options) { + parent::options($options); + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + } + + /** + * 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/sites/all/modules/ctools/views_content/translations/views_content.de.po b/sites/all/modules/ctools/views_content/translations/views_content.de.po new file mode 100644 index 0000000000000000000000000000000000000000..d21d8788e702ccf653a61fb10f919bf7ce4fb522 --- /dev/null +++ b/sites/all/modules/ctools/views_content/translations/views_content.de.po @@ -0,0 +1,457 @@ +# $Id: views_content.de.po,v 1.1 2009/08/16 21:28:45 hass Exp $ +# +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# panels.module,v 1.10.2.9 2007/03/15 23:13:41 merlinofchaos +# fourcol_25_25_25_25.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# threecol_33_33_33.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_25_75.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_33_66.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_38_62.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_50_50.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_62_38.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_66_33.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# twocol_75_25.inc,v 1.0 2006/09/02 11:47:00 alexander.hass +# threecol_25_50_25_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# threecol_33_34_33.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# threecol_33_34_33_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# twocol.inc,v 1.6 2006/08/22 23:54:20 merlinofchaos +# twocol_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos +# +msgid "" +msgstr "" +"Project-Id-Version: panels 5.x\n" +"POT-Creation-Date: 2009-08-16 20:47+0200\n" +"PO-Revision-Date: 2009-08-16 23:27+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: Alexander Hass\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" + +#: views_content/plugins/content_types/views.inc:18 +msgid "All views" +msgstr "Alle Ansichten" + +#: views_content/plugins/content_types/views.inc:32 +msgid "Select display" +msgstr "Anzeige auswählen" + +#: views_content/plugins/content_types/views.inc:35 +msgid "Configure view" +msgstr "Ansicht konfigurieren" + +#: views_content/plugins/content_types/views.inc:234 +msgid "Display" +msgstr "Anzeige" + +#: views_content/plugins/content_types/views.inc:236 +msgid "Choose which display of this view you wish to use." +msgstr "" + +#: views_content/plugins/content_types/views.inc:266 +#: views_content/plugins/content_types/views_panes.inc:277 +msgid "Broken/missing/deleted view." +msgstr "Beschädigte/Fehlende/Gelöschte Ansicht." + +#: views_content/plugins/content_types/views.inc:272 +msgid "Configure view @view (@display)" +msgstr "Ansicht @view (@display) konfigurieren" + +#: views_content/plugins/content_types/views.inc:294 +msgid "Link title to view" +msgstr "Titel mit Ansicht verlinken" + +#: views_content/plugins/content_types/views.inc:295 +msgid "If checked, the title will be a link to the view." +msgstr "Falls aktiviert, verlinkt Titel zur Ansicht." + +#: views_content/plugins/content_types/views.inc:301 +msgid "Provide a \"more\" link that links to the view" +msgstr "Stellt einen „Mehr“-Link bereit, der zur Ansicht verlinkt" + +#: views_content/plugins/content_types/views.inc:302 +msgid "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." +msgstr "Dies ist unabhängig von jeglichem Mehr-Link, welcher von der Ansicht selbst bereitgestellt wird; falls zwei Mehr-Links angezeigt werden, diesen hier deaktivieren. Ansichten stellen nur in der Block-Ausgabe einen Mehr-Link bereit. Für eingebettete Ansichten diesen verwenden." + +#: views_content/plugins/content_types/views.inc:308 +#: views_content/plugins/content_types/views_panes.inc:330 +msgid "Display feed icons" +msgstr "Newsfeed-Symbole anzeigen" + +#: views_content/plugins/content_types/views.inc:309 +msgid "If checked, any feed icons provided by this view will be displayed." +msgstr "Falls aktiviert, werden alle von der Ansicht bereitgestellten Feed-Symbole angezeigt." + +#: views_content/plugins/content_types/views.inc:324 +#: views_content/plugins/content_types/views_panes.inc:348 +msgid "Pager ID" +msgstr "Pager-ID" + +#: views_content/plugins/content_types/views.inc:337 +msgid "Num posts" +msgstr "Beitragsanzahl" + +#: views_content/plugins/content_types/views.inc:339 +msgid "Select the number of posts to display, or 0 to display all results." +msgstr "Die Anzahl der anzuzeigenden Beiträge auswählen, oder 0 um alle Ergebnisse anzuzeigen." + +#: views_content/plugins/content_types/views.inc:345 +#: views_content/plugins/content_types/views_panes.inc:371 +msgid "Offset" +msgstr "Offset" + +#: views_content/plugins/content_types/views.inc:347 +msgid "Offset in the node list or 0 to start at 1st item." +msgstr "Offset in der Beitragsliste oder 0, um beim erstem Eintrag zu beginnen." + +#: views_content/plugins/content_types/views.inc:352 +msgid "Send arguments" +msgstr "Argumente übergeben" + +#: views_content/plugins/content_types/views.inc:354 +msgid "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." +msgstr "Aktivieren, um alle Argumente des Panels direkt zur Ansicht zu übergeben. Falls aktiviert, kommen die Panel-Argumente nach jeglichen Kontext-Argumenten oben und vor jeglichen, zusätzlichen Argumenten, welche durch das Argument-Feld unten hinzugefügt wurden." + +#: views_content/plugins/content_types/views.inc:362 +msgid "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." +msgstr "Zusätzliche Argumente, die der Ansicht übergeben werden, als ob diese Bestandteil der URL wären; in der Form arg1/arg2/arg3. %0, %1, ..., %N kann verwendet werden, um Argumente aus der URL zu übergeben. Oder @0, @1, @2, ..., @N verwenden, um Panel-Argumente zu übergeben." + +#: views_content/plugins/content_types/views.inc:368 +msgid "Override URL" +msgstr "URL überschreiben" + +#: views_content/plugins/content_types/views.inc:370 +msgid "If this is set, override the View URL; this can sometimes be useful to set to the panel URL" +msgstr "Falls aktiviert, wird die URL der Ansicht überschrieben; manchmal kann es sinnvoll sein, die Panel-URL einzusetzen." + +#: views_content/plugins/content_types/views.inc:402;422 +#: views_content/plugins/content_types/views_panes.inc:410;413 +msgid "Deleted/missing view @view" +msgstr "Entfernte/fehlende Ansicht @view" + +#: views_content/plugins/content_types/views.inc:404 +msgid "View: @name" +msgstr "Ansicht: @name" + +#: views_content/plugins/content_types/views.inc:426 +msgid "View information" +msgstr "Ansichtsinformation" + +#: views_content/plugins/content_types/views.inc:429 +msgid "Using display @display." +msgstr "Anzeige @display wurd verwendet." + +#: views_content/plugins/content_types/views.inc:450 +msgid "Argument @arg using context @context converted into @converter" +msgstr "" + +#: views_content/plugins/content_types/views.inc:458 +msgid "@count items displayed." +msgstr "@count Einträge wurden angezeigt." + +#: views_content/plugins/content_types/views.inc:460 +msgid "With pager." +msgstr "Mit Seitennavigation." + +#: views_content/plugins/content_types/views.inc:463 +msgid "Without pager." +msgstr "Ohne Seitennavigation." + +#: views_content/plugins/content_types/views.inc:467 +#, fuzzy +msgid "Skipping first @count results" +msgstr "Überspringe die ersten @count Ergebnisse" + +#: views_content/plugins/content_types/views.inc:470 +msgid "With more link." +msgstr "Mit „Mehr“-Link" + +#: views_content/plugins/content_types/views.inc:473 +msgid "With feed icon." +msgstr "Mit Feed-Symbole." + +#: views_content/plugins/content_types/views.inc:476 +msgid "Sending arguments." +msgstr "Argumente übergeben." + +#: views_content/plugins/content_types/views.inc:479 +#, fuzzy +msgid "Using arguments: @args" +msgstr "Argumente verwenden: @arg" + +#: views_content/plugins/content_types/views.inc:482 +msgid "Using url: @url" +msgstr "Verwende URL: @url" + +#: views_content/plugins/content_types/views_panes.inc:314 +msgid "Link title to page" +msgstr "Titel mit Seite verlinken" + +#: views_content/plugins/content_types/views_panes.inc:321 +msgid "Provide a \"more\" link." +msgstr "Stellt einen „Mehr“-Link bereit." + +#: views_content/plugins/content_types/views_panes.inc:362 +msgid "Num items" +msgstr "Anzahl Einträge" + +#: views_content/plugins/content_types/views_panes.inc:364 +msgid "Select the number of items to display, or 0 to display all results." +msgstr "Die Anzahl der anzuzeigenden Einträge auswählen, oder 0 um alle Ergebnisse anzuzeigen." + +#: views_content/plugins/content_types/views_panes.inc:373 +msgid "Enter the number of items to skip; enter 0 to skip no items." +msgstr "Die Anzahl der zu überspringenden Einträge eingeben, oder 0 um alle Einträge zu überspringen." + +#: views_content/plugins/content_types/views_panes.inc:380 +msgid "Override path" +msgstr "Pfad überschreiben" + +#: views_content/plugins/content_types/views_panes.inc:382 +msgid "If this is set, override the View URL path; this can sometimes be useful to set to the panel URL." +msgstr "Sobald aktiviert, wird die Ansichten-URL übersteuert; manchmal kann es sinnvoll sein, die Panel-URL einzusetzen." + +#: views_content/plugins/views/views_content.views.inc:16 +msgid "Content pane" +msgstr "Inhaltsausschnitt" + +#: views_content/plugins/views/views_content.views.inc:17 +msgid "Is available as content for a panel or dashboard display." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:56 +msgid "Pane settings" +msgstr "Ausschnitt-Einstellungen" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:61 +msgid "Use view name" +msgstr "Ansichtsname verwenden" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:70 +msgid "Admin title" +msgstr "Admin Titel" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:76 +msgid "Use view description" +msgstr "Ansichtsbeschreibung verwenden" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:85 +msgid "Admin desc" +msgstr "Admin-Beschreibung" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:101 +msgid "Category" +msgstr "Kategorie" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:107;151 +msgid "Link to view" +msgstr "Zur Ansicht verlinken" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:108;114;208;218 +msgid "Yes" +msgstr "Ja" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:108;114;208;218 +msgid "No" +msgstr "Nein" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:113 +msgid "Use Panel path" +msgstr "Panel-Pfad verwenden" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:119 +msgid "Argument input" +msgstr "Argumenteingabe" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:128;142 +msgid "Allow settings" +msgstr "Einstellungen zulassen" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "None" +msgstr "Nichts" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "All" +msgstr "Alle" + +# context senstive issue? +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +#, fuzzy +msgid "Some" +msgstr "Einige" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:144 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:149 +msgid "Items per page" +msgstr "Beträge pro Seite" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:150 +msgid "Pager offset" +msgstr "Offset der Seitennavigation" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:152 +msgid "More link" +msgstr "„Mehr“-Link" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:153 +msgid "Path override" +msgstr "Pfad-Übersteuerung" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:154 +msgid "Title override" +msgstr "Titel-Übersteuerung" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:171 +msgid "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." +msgstr "Dies ist der Titel, der für diesen Ansichten-Ausschnitt im „Inhalt hinzufügen“-Dialog erscheint. Falls nicht gesetzt, wird der Ansichten-Name verwendet." + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:181 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:193 +msgid "This is category the pane will appear in on the add content dialog." +msgstr "Die ist die Kategorie, in welcher der Ausschnitt im „Inhalt hinzufügen“-Dialog erscheint." + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:199 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:204 +msgid "Link pane title to view" +msgstr "Ausschnitt-Titel mit Ansicht verlinken" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:214 +msgid "Inherit path from panel display" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:220 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:225 +msgid "Choose the data source for view arguments" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:242 +msgid "No argument" +msgstr "Kein Argument" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:243 +msgid "Argument wildcard" +msgstr "Argument-Platzhalter" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:244 +msgid "From context" +msgstr "Aus Kontext" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:245 +msgid "From panel argument" +msgstr "Aus Panel-Argument" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:246 +msgid "Fixed" +msgstr "Statisch" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:247 +msgid "Input on pane config" +msgstr "Eingabe in Panel-Inhalt-Einstellungen" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:250 +msgid "@arg source" +msgstr "@arg-Quelle" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:256 +msgid "Required context" +msgstr "Erfoderlicher Kontext" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:257 +msgid "If \"From context\" is selected, which context to require." +msgstr "Der erforderliche Kontext, falls „Aus Kontext“ ausgewählt wurde." + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:266 +msgid "Panel argument" +msgstr "Panel-Argument" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:267 +msgid "If \"From panel argument\" is selected, which panel argument to use." +msgstr "Das zu verwendende Panel-Argument, falls „Aus Panel-Argument“ ausgewählt wurde." + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "First" +msgstr "Erstes" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Second" +msgstr "Zweites" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Third" +msgstr "Drittes" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Fourth" +msgstr "Viertes" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Fifth" +msgstr "Fünftes" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Sixth" +msgstr "Sechstes" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:276 +msgid "Fixed argument" +msgstr "Statisches Argument" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:277 +msgid "If \"Fixed\" is selected, what to use as an argument." +msgstr "Das Argument, falls „Statisch“ ausgewählt wurde." + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:285 +msgid "Label" +msgstr "Bezeichnung" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:286 +msgid "If this argument is presented to the panels user, what label to apply to it." +msgstr "Die verwendete Bezeichnung, falls dieses Argument für den Benutzer erscheint." + +#: views_content/views_content.module:92 +msgid "Make all views available as panes" +msgstr "Alle Ansichten als Ausschnitte zu Verfügung stellen" + +#: views_content/views_content.module:93 +msgid "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." +msgstr "" + +#: views_content/views_content.module:20 +msgid "Views panes" +msgstr "Panel-Ansichten" + +#: views_content/views_content.module:24 +msgid "Configure Views to be used as CTools content." +msgstr "Ansichten konfigurieren, die als CTools-Inhalt verwendet werden." + +#: views_content/views_content.module:0 +msgid "views_content" +msgstr "views_content" + +#: views_content/views_content.info:0 +msgid "Views content panes" +msgstr "" + +#: views_content/views_content.info:0 +msgid "Allows Views content to be used in Panels, Dashboard and other modules which use the CTools Content API." +msgstr "" + diff --git a/sites/all/modules/ctools/views_content/translations/views_content.fr.po b/sites/all/modules/ctools/views_content/translations/views_content.fr.po new file mode 100644 index 0000000000000000000000000000000000000000..59e1ee6b9fa84ea7ca08f68ad547e7164dacd9e8 --- /dev/null +++ b/sites/all/modules/ctools/views_content/translations/views_content.fr.po @@ -0,0 +1,490 @@ +# $Id: views_content.fr.po,v 1.1 2009/08/16 20:10:09 hass Exp $ +# +# French translation of Drupal (general) +# Copyright 2009 Jérémy Chatard <jchatard@breek.fr> +# Generated from files: +# views_content.module,v 1.4 2009/08/07 19:58:33 merlinofchaos +# views.inc,v 1.11 2009/05/12 00:17:27 merlinofchaos +# views_content.info,v 1.2 2009/07/12 18:11:59 merlinofchaos +# views_panes.inc,v 1.13 2009/07/20 17:45:21 merlinofchaos +# views_content_plugin_display_panel_pane.inc,v 1.2 2009/04/20 21:35:25 merlinofchaos +# views_content.views.inc,v 1.2 2009/04/30 22:37:52 merlinofchaos +# +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-08-15 12:16+0200\n" +"PO-Revision-Date: 2009-08-16 11:19+0100\n" +"Last-Translator: Jérémy Chatard <jchatard@breek.fr>\n" +"Language-Team: French <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" + +#: views_content.module:56 +msgid "Widgets" +msgstr "Widgtes" + +#: views_content.module:61 +#: plugins/content_types/views.inc:99 +msgid "Views" +msgstr "Vues" + +#: views_content.module:92 +msgid "Make all views available as panes" +msgstr "Rend toutes les vues disponibles en panneaux" + +#: views_content.module:93 +msgid "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." +msgstr "Si sélectionné, toutes les vues seront disponibles sous forme de content pane pour être ajoutées aux types de contenu. Si non sélectionné, seules les vues qui disposent d'un affichage Content pane seront disponible en tant que content panes. Désélectionnez ceci si vous souhaitez contrôler plus finement quelles vues sont diponibles l'interface des panels pour les utilisateurs." + +#: views_content.module:20 +msgid "Views panes" +msgstr "" + +#: views_content.module:24 +msgid "Configure Views to be used as CTools content." +msgstr "Configurer des vues pour être utilisées comme contenu avec CTools." + +#: views_content.info:0 +msgid "Views content panes" +msgstr "" + +#: views_content.info:0 +msgid "Allows Views content to be used in Panels, Dashboard and other modules which use the CTools Content API." +msgstr "Permet au contenu des vues d'être utilisé dans les panels, le Dashboard et d'autres modules qui utilisent l'API de contenu de CTools." + +#: views_content.info:0 +msgid "Chaos tool suite" +msgstr "Chaos tool suite" + +#: plugins/content_types/views.inc:18 +msgid "All views" +msgstr "Toutes les vues" + +#: plugins/content_types/views.inc:32 +msgid "Select display" +msgstr "Sélectionnez un affichage" + +#: plugins/content_types/views.inc:35 +msgid "Configure view" +msgstr "Configurer la vue" + +#: plugins/content_types/views.inc:234 +msgid "Display" +msgstr "Affichage" + +#: plugins/content_types/views.inc:236 +msgid "Choose which display of this view you wish to use." +msgstr "Choisissez quel affichage de la vue vous souhaitez utiliser." + +#: plugins/content_types/views.inc:266 +#: plugins/content_types/views_panes.inc:277 +msgid "Broken/missing/deleted view." +msgstr "Vue cassée/manquante/supprimée." + +#: plugins/content_types/views.inc:272 +msgid "Configure view @view (@display)" +msgstr "Configurer la vue @view (@display)" + +#: plugins/content_types/views.inc:294 +msgid "Link title to view" +msgstr "Lier le titre à la vue" + +#: plugins/content_types/views.inc:295 +msgid "If checked, the title will be a link to the view." +msgstr "Si cette option est sélectionnée, le titre sera un lien vers la vue." + +#: plugins/content_types/views.inc:301 +msgid "Provide a \"more\" link that links to the view" +msgstr "Fournit un lien \"plus\" qui renvoit vers la vue" + +#: plugins/content_types/views.inc:302 +msgid "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." +msgstr "Ceci est indépendant de tout lien fournit par la vue elle-même ; si vous voyez deux lien \"plus\", désactivez celui-ci. Views ne fournira un lien plus que si vous utilisez l'affichage \"block\", donc si vous en disposez pas utilisez celui-ci." + +#: plugins/content_types/views.inc:308 +#: plugins/content_types/views_panes.inc:330 +msgid "Display feed icons" +msgstr "Afficher les icônes des flux" + +#: plugins/content_types/views.inc:309 +msgid "If checked, any feed icons provided by this view will be displayed." +msgstr "Si cette option est sélectionnée, tous les icônes des flux fournis par cette vue seront affichés." + +#: plugins/content_types/views.inc:317 +#: plugins/content_types/views_panes.inc:341 +#: plugins/views/views_content_plugin_display_panel_pane.inc:148 +msgid "Use pager" +msgstr "Utiliser la pagination" + +#: plugins/content_types/views.inc:324 +#: plugins/content_types/views_panes.inc:348 +msgid "Pager ID" +msgstr "ID de la pagination" + +#: plugins/content_types/views.inc:337 +msgid "Num posts" +msgstr "Nombre de posts" + +#: plugins/content_types/views.inc:339 +msgid "Select the number of posts to display, or 0 to display all results." +msgstr "Sélectionnez le nombre d'éléments à afficher, ou 0 pour afficher tous les résultats." + +#: plugins/content_types/views.inc:345 +#: plugins/content_types/views_panes.inc:371 +msgid "Offset" +msgstr "Décalage" + +#: plugins/content_types/views.inc:347 +msgid "Offset in the node list or 0 to start at 1st item." +msgstr "Décalage dans la liste de noeuds ou 0 pour commencer avec le 1er élément." + +#: plugins/content_types/views.inc:352 +msgid "Send arguments" +msgstr "Envoyer l'argument" + +#: plugins/content_types/views.inc:354 +msgid "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." +msgstr "Sélectionnez ceci pour envoyer tous les arguments du panel directement à la vue. Si sélectionné, les arguments du panel arriveront après les contextes ci-dessous et précèderont n'importe quel argument supplémentaire défini dans le champ argument ci-dessous." + +#: plugins/content_types/views.inc:360 +msgid "Arguments" +msgstr "Arguments" + +#: plugins/content_types/views.inc:362 +msgid "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." +msgstr "Arguments supplémentaires à envoyer à la vue comme si ceux-ci faisaient partie de l'URL, sous la forme arg1/arg2/arg3. Vous pouvez utiliser %0, %1, ..., %N pour récupérer les arguments depuis l'URL. Ou utiliser @0, @1, @2, ..., @N pour utiliser les arguments passés dans le panel." + +#: plugins/content_types/views.inc:368 +msgid "Override URL" +msgstr "Surcharger l'URL" + +#: plugins/content_types/views.inc:370 +msgid "If this is set, override the View URL; this can sometimes be useful to set to the panel URL" +msgstr "Si ceci est défini, surcharge l'URL de la vue ; ce qui peut être pratique pour la définir à l'URL de la vue" + +#: plugins/content_types/views.inc:402;422 +#: plugins/content_types/views_panes.inc:410;413 +msgid "Deleted/missing view @view" +msgstr "Vue @view supprimée/manquante" + +#: plugins/content_types/views.inc:404 +msgid "View: @name" +msgstr "Vue : @name" + +#: plugins/content_types/views.inc:426 +msgid "View information" +msgstr "Information de la vue" + +#: plugins/content_types/views.inc:429 +msgid "Using display @display." +msgstr "Utilise l'affichage @display." + +#: plugins/content_types/views.inc:449 +msgid "Default" +msgstr "Par défaut" + +#: plugins/content_types/views.inc:450 +msgid "Argument @arg using context @context converted into @converter" +msgstr "L'argument @arg utilisant le contexte @context a été converti en @converter" + +#: plugins/content_types/views.inc:458 +msgid "@count items displayed." +msgstr "@count éléments affichés." + +#: plugins/content_types/views.inc:460 +msgid "With pager." +msgstr "Avec pagination." + +#: plugins/content_types/views.inc:463 +msgid "Without pager." +msgstr "Sans pagination." + +#: plugins/content_types/views.inc:467 +msgid "Skipping first @count results" +msgstr "Sauter les @count premiers résultats" + +#: plugins/content_types/views.inc:470 +msgid "With more link." +msgstr "Avec un lien plus." + +#: plugins/content_types/views.inc:473 +msgid "With feed icon." +msgstr "Avec une icône de flux." + +#: plugins/content_types/views.inc:476 +msgid "Sending arguments." +msgstr "Envoi des arguments" + +#: plugins/content_types/views.inc:479 +msgid "Using arguments: @args" +msgstr "Avec les arguments : @args" + +#: plugins/content_types/views.inc:482 +msgid "Using url: @url" +msgstr "Avec l'URL : @url" + +#: plugins/content_types/views_panes.inc:15;94 +#: plugins/views/views_content_plugin_display_panel_pane.inc:92 +msgid "View panes" +msgstr "" + +#: plugins/content_types/views_panes.inc:314 +msgid "Link title to page" +msgstr "Lier le titre à la page" + +#: plugins/content_types/views_panes.inc:321 +msgid "Provide a \"more\" link." +msgstr "Fournir un lien \"plus\"." + +#: plugins/content_types/views_panes.inc:362 +msgid "Num items" +msgstr "Nombre d'éléments" + +#: plugins/content_types/views_panes.inc:364 +msgid "Select the number of items to display, or 0 to display all results." +msgstr "Sélectionnez le nombre d'éléments à afficher, ou 0 pour afficher tous les résultats." + +#: plugins/content_types/views_panes.inc:373 +msgid "Enter the number of items to skip; enter 0 to skip no items." +msgstr "Saisissez le nombre d'éléments à sauter ; entrez 0 pour ne sauter aucun élément." + +#: plugins/content_types/views_panes.inc:380 +msgid "Override path" +msgstr "Surcharger le chemin" + +#: plugins/content_types/views_panes.inc:382 +msgid "If this is set, override the View URL path; this can sometimes be useful to set to the panel URL." +msgstr "Si ceci est défini, surcharge le chemin de la Vue ; ceci peut être pratique pour la définir à l'URL du panel." + +#: plugins/views/views_content.views.inc:16 +msgid "Content pane" +msgstr "" + +#: plugins/views/views_content.views.inc:17 +msgid "Is available as content for a panel or dashboard display." +msgstr "Est disponible comme contenu pour un panel ou affichage de type dashboard." + +#: plugins/views/views_content_plugin_display_panel_pane.inc:56 +msgid "Pane settings" +msgstr "Paramètres du pane" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:61 +msgid "Use view name" +msgstr "Utiliser le nom de la vue" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:70 +msgid "Admin title" +msgstr "Titre d'administratif" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:76 +msgid "Use view description" +msgstr "Utiliser la description de la vue" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:85 +msgid "Admin desc" +msgstr "Description administrative" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:101 +msgid "Category" +msgstr "Catégorie" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:107;151 +msgid "Link to view" +msgstr "Lier à la vue" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:108;114;208;218 +msgid "Yes" +msgstr "Oui" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:108;114;208;218 +msgid "No" +msgstr "Non" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:113 +msgid "Use Panel path" +msgstr "Utiliser le chemin du Panel" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:119 +msgid "Argument input" +msgstr "" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:120 +msgid "Edit" +msgstr "Modifier" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:128;142 +#, fuzzy +msgid "Allow settings" +msgstr "Permettre les paramètres" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "None" +msgstr "Aucun" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "All" +msgstr "Tous / Toutes" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "Some" +msgstr "Plusieurs" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:144 +msgid "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." +msgstr "Les paramètres sélectionnés seront disponibles dans la fenêtre de configuration du pane pour être modifié par l'utilisateur. Les paramètres non sélectionnés ne seront pas disponibles et n'utiliseront que les paramètres de cet affichage." + +#: plugins/views/views_content_plugin_display_panel_pane.inc:149 +msgid "Items per page" +msgstr "Éléments par page" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:150 +msgid "Pager offset" +msgstr "Décalage de la pagination" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:152 +msgid "More link" +msgstr "Lien \"plus\"" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:153 +msgid "Path override" +msgstr "Surchargement du chemin" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:154 +msgid "Title override" +msgstr "Surchargement du titre" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:166 +msgid "Administrative title" +msgstr "Titre pour l'administration" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:171 +msgid "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." +msgstr "Ceci est le titre qui va apparaître pour le pane de cette vue dans la fenêtre d'ajout de contenu. Si vide, le nom de la vue sera utilisé." + +#: plugins/views/views_content_plugin_display_panel_pane.inc:176;186 +msgid "Administrative description" +msgstr "Description pour l'administration" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:181 +msgid "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." +msgstr "Ceci est le texte qui va apparaître quand l'utilisateur va placer sa souris au-dessus du pane dans la fenêtre d'ajout de contenu. Si vide, la description de la vue sera utilisée." + +#: plugins/views/views_content_plugin_display_panel_pane.inc:193 +msgid "This is category the pane will appear in on the add content dialog." +msgstr "Ceci est la catégorie dans laquelle apparaîtra le pane dans la fenêtre d'ajout de contenu." + +#: plugins/views/views_content_plugin_display_panel_pane.inc:196 +msgid "Weight" +msgstr "Poids" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:199 +#, fuzzy +msgid "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." +msgstr "Ceci est le poids par défaut de la catégorie. Notez que si le poids de la catégorie est défini à plusieurs endroits, seul le premier est visible par Panels, donc si le poids ne semble pas fonctionner, vérifiez dans les autres endroits où le poids pourrait avoir été défini." + +#: plugins/views/views_content_plugin_display_panel_pane.inc:204 +msgid "Link pane title to view" +msgstr "Lier le titre du pane à la vue" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:214 +msgid "Inherit path from panel display" +msgstr "Hérite le chemin de l'affichage du panel" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:220 +#, fuzzy +msgid "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." +msgstr "Si oui, tous les liens générés par Views, tel que les liens plus, les liens de résumé, et les liens de saisies exposés vont aller dans l'affichage des chemins des panels, pas la vue, si l'affichage a un chemin." + +#: plugins/views/views_content_plugin_display_panel_pane.inc:225 +msgid "Choose the data source for view arguments" +msgstr "Choisissez la source de données des arguments de la vue" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:242 +msgid "No argument" +msgstr "Aucun argument" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:243 +msgid "Argument wildcard" +msgstr "Caractères de remplacement de l'arguement" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:244 +msgid "From context" +msgstr "Depuis le contexte" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:245 +msgid "From panel argument" +msgstr "Depuis l'argument du panel" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:246 +msgid "Fixed" +msgstr "Fixe" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:247 +#, fuzzy +msgid "Input on pane config" +msgstr "Saisie sur la configuration du pane" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:250 +msgid "@arg source" +msgstr "source de @arg" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:256 +msgid "Required context" +msgstr "Conexte requis" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:257 +msgid "If \"From context\" is selected, which context to require." +msgstr "Si \"Depuis le contexte\" est sélectionné, quel contexte nécessiter." + +#: plugins/views/views_content_plugin_display_panel_pane.inc:266 +msgid "Panel argument" +msgstr "Argument du panel" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:267 +msgid "If \"From panel argument\" is selected, which panel argument to use." +msgstr "Si \"Depuis l'argument du panel\" est sélectionné, quel argument du panel utiliser." + +#: plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "First" +msgstr "Premier" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Second" +msgstr "Seconde" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Third" +msgstr "Troisième" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Fourth" +msgstr "Quatrième" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Fifth" +msgstr "Cinquième" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Sixth" +msgstr "Sixième" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:276 +msgid "Fixed argument" +msgstr "Argument fixe" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:277 +msgid "If \"Fixed\" is selected, what to use as an argument." +msgstr "Si \"Fixe\" est sélectionné, quoi utiliser comme argument." + +#: plugins/views/views_content_plugin_display_panel_pane.inc:285 +msgid "Label" +msgstr "Étiquette" + +#: plugins/views/views_content_plugin_display_panel_pane.inc:286 +#, fuzzy +msgid "If this argument is presented to the panels user, what label to apply to it." +msgstr "Si cet argument est présenté aux panels des utilisateurs, quel intitulé doit y être appliqué." + diff --git a/sites/all/modules/ctools/views_content/translations/views_content.hu.po b/sites/all/modules/ctools/views_content/translations/views_content.hu.po new file mode 100644 index 0000000000000000000000000000000000000000..a7c44e2a0b5f0d69bd54f25979c50d5637d2aa37 --- /dev/null +++ b/sites/all/modules/ctools/views_content/translations/views_content.hu.po @@ -0,0 +1,41 @@ +# Hungarian translation of Chaos tool suite (6.x-1.2) +# Copyright (c) 2009 by the Hungarian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Chaos tool suite (6.x-1.2)\n" +"POT-Creation-Date: 2009-12-13 13:41+0000\n" +"PO-Revision-Date: 2009-12-13 12:48+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 "Views panes" +msgstr "Views táblák" +msgid "Make all views available as panes" +msgstr "Legyen minden nézet elérhető táblaként" +msgid "" +"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." +msgstr "" +"Ha be van jelölve, minden nézet elérhető lesz tartalomtípusokhoz " +"hozzáadható tartalomtáblaként. Ha nincs bejelölve, csak a " +"„Tartalomtábla” megjelenítéssel rendelkező nézetek lesznek " +"elérhetőek tartalomtáblaként. Kikapcsolva gondosabban " +"szabályozható, hogy mely nézet tartalma lesz elérhető a panelek " +"elrendezési felületét használók számára." +msgid "Configure Views to be used as CTools content." +msgstr "Nézetek beállítása Ctools tartalomként történő használatra." +msgid "Views content panes" +msgstr "Views tartalomtáblák" +msgid "" +"Allows Views content to be used in Panels, Dashboard and other modules " +"which use the CTools Content API." +msgstr "" +"Engedélyezi a Views tartalmak használatát a Panels, a Dashboard és " +"egyéb, a CTools Content API-t használó modulokban." diff --git a/sites/all/modules/ctools/views_content/translations/views_content.pot b/sites/all/modules/ctools/views_content/translations/views_content.pot new file mode 100644 index 0000000000000000000000000000000000000000..6e1b4ef9fd6705bc4aaba3e5b7fb4d3656a7770e --- /dev/null +++ b/sites/all/modules/ctools/views_content/translations/views_content.pot @@ -0,0 +1,437 @@ +# $Id: views_content.pot,v 1.1 2009/08/16 19:13:58 hass Exp $ +# +# LANGUAGE translation of Drupal (views_content-plugins-content_types) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# views.inc,v 1.11 2009/05/12 00:17:27 merlinofchaos +# views_panes.inc,v 1.13 2009/07/20 17:45:21 merlinofchaos +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-08-16 20:47+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" + +#: views_content/plugins/content_types/views.inc:18 +msgid "All views" +msgstr "" + +#: views_content/plugins/content_types/views.inc:32 +msgid "Select display" +msgstr "" + +#: views_content/plugins/content_types/views.inc:35 +msgid "Configure view" +msgstr "" + +#: views_content/plugins/content_types/views.inc:234 +msgid "Display" +msgstr "" + +#: views_content/plugins/content_types/views.inc:236 +msgid "Choose which display of this view you wish to use." +msgstr "" + +#: views_content/plugins/content_types/views.inc:266 +#: views_content/plugins/content_types/views_panes.inc:277 +msgid "Broken/missing/deleted view." +msgstr "" + +#: views_content/plugins/content_types/views.inc:272 +msgid "Configure view @view (@display)" +msgstr "" + +#: views_content/plugins/content_types/views.inc:294 +msgid "Link title to view" +msgstr "" + +#: views_content/plugins/content_types/views.inc:295 +msgid "If checked, the title will be a link to the view." +msgstr "" + +#: views_content/plugins/content_types/views.inc:301 +msgid "Provide a \"more\" link that links to the view" +msgstr "" + +#: views_content/plugins/content_types/views.inc:302 +msgid "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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:308 +#: views_content/plugins/content_types/views_panes.inc:330 +msgid "Display feed icons" +msgstr "" + +#: views_content/plugins/content_types/views.inc:309 +msgid "If checked, any feed icons provided by this view will be displayed." +msgstr "" + +#: views_content/plugins/content_types/views.inc:324 +#: views_content/plugins/content_types/views_panes.inc:348 +msgid "Pager ID" +msgstr "" + +#: views_content/plugins/content_types/views.inc:337 +msgid "Num posts" +msgstr "" + +#: views_content/plugins/content_types/views.inc:339 +msgid "Select the number of posts to display, or 0 to display all results." +msgstr "" + +#: views_content/plugins/content_types/views.inc:345 +#: views_content/plugins/content_types/views_panes.inc:371 +msgid "Offset" +msgstr "" + +#: views_content/plugins/content_types/views.inc:347 +msgid "Offset in the node list or 0 to start at 1st item." +msgstr "" + +#: views_content/plugins/content_types/views.inc:352 +msgid "Send arguments" +msgstr "" + +#: views_content/plugins/content_types/views.inc:354 +msgid "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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:362 +msgid "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." +msgstr "" + +#: views_content/plugins/content_types/views.inc:368 +msgid "Override URL" +msgstr "" + +#: views_content/plugins/content_types/views.inc:370 +msgid "If this is set, override the View URL; this can sometimes be useful to set to the panel URL" +msgstr "" + +#: views_content/plugins/content_types/views.inc:402;422 +#: views_content/plugins/content_types/views_panes.inc:410;413 +msgid "Deleted/missing view @view" +msgstr "" + +#: views_content/plugins/content_types/views.inc:404 +msgid "View: @name" +msgstr "" + +#: views_content/plugins/content_types/views.inc:426 +msgid "View information" +msgstr "" + +#: views_content/plugins/content_types/views.inc:429 +msgid "Using display @display." +msgstr "" + +#: views_content/plugins/content_types/views.inc:450 +msgid "Argument @arg using context @context converted into @converter" +msgstr "" + +#: views_content/plugins/content_types/views.inc:458 +msgid "@count items displayed." +msgstr "" + +#: views_content/plugins/content_types/views.inc:460 +msgid "With pager." +msgstr "" + +#: views_content/plugins/content_types/views.inc:463 +msgid "Without pager." +msgstr "" + +#: views_content/plugins/content_types/views.inc:467 +msgid "Skipping first @count results" +msgstr "" + +#: views_content/plugins/content_types/views.inc:470 +msgid "With more link." +msgstr "" + +#: views_content/plugins/content_types/views.inc:473 +msgid "With feed icon." +msgstr "" + +#: views_content/plugins/content_types/views.inc:476 +msgid "Sending arguments." +msgstr "" + +#: views_content/plugins/content_types/views.inc:479 +msgid "Using arguments: @args" +msgstr "" + +#: views_content/plugins/content_types/views.inc:482 +msgid "Using url: @url" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:314 +msgid "Link title to page" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:321 +msgid "Provide a \"more\" link." +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:362 +msgid "Num items" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:364 +msgid "Select the number of items to display, or 0 to display all results." +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:373 +msgid "Enter the number of items to skip; enter 0 to skip no items." +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:380 +msgid "Override path" +msgstr "" + +#: views_content/plugins/content_types/views_panes.inc:382 +msgid "If this is set, override the View URL path; this can sometimes be useful to set to the panel URL." +msgstr "" + +#: views_content/plugins/views/views_content.views.inc:16 +msgid "Content pane" +msgstr "" + +#: views_content/plugins/views/views_content.views.inc:17 +msgid "Is available as content for a panel or dashboard display." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:56 +msgid "Pane settings" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:61 +msgid "Use view name" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:70 +msgid "Admin title" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:76 +msgid "Use view description" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:85 +msgid "Admin desc" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:101 +msgid "Category" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:107;151 +msgid "Link to view" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:108;114;208;218 +msgid "Yes" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:108;114;208;218 +msgid "No" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:113 +msgid "Use Panel path" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:119 +msgid "Argument input" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:128;142 +msgid "Allow settings" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "None" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "All" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:129 +msgid "Some" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:144 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:149 +msgid "Items per page" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:150 +msgid "Pager offset" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:152 +msgid "More link" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:153 +msgid "Path override" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:154 +msgid "Title override" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:171 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:181 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:193 +msgid "This is category the pane will appear in on the add content dialog." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:199 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:204 +msgid "Link pane title to view" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:214 +msgid "Inherit path from panel display" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:220 +msgid "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." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:225 +msgid "Choose the data source for view arguments" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:242 +msgid "No argument" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:243 +msgid "Argument wildcard" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:244 +msgid "From context" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:245 +msgid "From panel argument" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:246 +msgid "Fixed" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:247 +msgid "Input on pane config" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:250 +msgid "@arg source" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:256 +msgid "Required context" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:257 +msgid "If \"From context\" is selected, which context to require." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:266 +msgid "Panel argument" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:267 +msgid "If \"From panel argument\" is selected, which panel argument to use." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "First" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Second" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Third" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Fourth" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Fifth" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:269 +msgid "Sixth" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:276 +msgid "Fixed argument" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:277 +msgid "If \"Fixed\" is selected, what to use as an argument." +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:285 +msgid "Label" +msgstr "" + +#: views_content/plugins/views/views_content_plugin_display_panel_pane.inc:286 +msgid "If this argument is presented to the panels user, what label to apply to it." +msgstr "" + +#: views_content/views_content.module:92 +msgid "Make all views available as panes" +msgstr "" + +#: views_content/views_content.module:93 +msgid "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." +msgstr "" + +#: views_content/views_content.module:20 +msgid "Views panes" +msgstr "" + +#: views_content/views_content.module:24 +msgid "Configure Views to be used as CTools content." +msgstr "" + +#: views_content/views_content.module:0 +msgid "views_content" +msgstr "" + +#: views_content/views_content.info:0 +msgid "Views content panes" +msgstr "" + +#: views_content/views_content.info:0 +msgid "Allows Views content to be used in Panels, Dashboard and other modules which use the CTools Content API." +msgstr "" diff --git a/sites/all/modules/ctools/views_content/views_content.admin.inc b/sites/all/modules/ctools/views_content/views_content.admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/sites/all/modules/ctools/views_content/views_content.info b/sites/all/modules/ctools/views_content/views_content.info new file mode 100644 index 0000000000000000000000000000000000000000..f7132f3c4aee6cf577e30709c06111722e5e4c0a --- /dev/null +++ b/sites/all/modules/ctools/views_content/views_content.info @@ -0,0 +1,18 @@ +; $Id: views_content.info,v 1.6 2011/01/01 00:01:46 merlinofchaos Exp $ +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 = 7.x +package = Chaos tool suite +files[] = plugins/views/views_content_plugin_display_ctools_context.inc +files[] = plugins/views/views_content_plugin_display_panel_pane.inc +files[] = plugins/views/views_content_plugin_style_ctools_context.inc + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-1.0-alpha2" +core = "7.x" +project = "ctools" +datestamp = "1294276864" + diff --git a/sites/all/modules/ctools/views_content/views_content.module b/sites/all/modules/ctools/views_content/views_content.module new file mode 100644 index 0000000000000000000000000000000000000000..aee8ad1d3f8d7b5c7938026b3be4b97976a24131 --- /dev/null +++ b/sites/all/modules/ctools/views_content/views_content.module @@ -0,0 +1,185 @@ +<?php +// $Id: views_content.module,v 1.8 2010/11/01 18:51:22 merlinofchaos Exp $ + +/** + * @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. + */ + +/** + * Implements hook_menu(). + */ +function views_content_menu() { + $items = array(); + + if (!module_exists('panels')) { + $items['admin/config/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']), + ); + + return $form; +} + +/** + * 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(); + } +} + +/** + * Implements 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/sites/all/modules/views/CHANGELOG.txt b/sites/all/modules/views/CHANGELOG.txt new file mode 100644 index 0000000000000000000000000000000000000000..7a71a76c494a2a052597ecbc641c11d2049c9d72 --- /dev/null +++ b/sites/all/modules/views/CHANGELOG.txt @@ -0,0 +1,268 @@ +CHANGELOG for Views 3 for Drupal 7 + +Views 3.x-7.x-alpha1 (05-Jan-2011) +================================== + +#914102 by torelad: Correct placeholder in views_date_sql_format. +#931582 by bec: Provide integration of {file_usage} table. +by dereine: Fix in_operator test. +by dereine: Fix more testcases by adding $this->resetAll(). +#931886 by bojanz: Remove views_handler_filter_float because numeric handler + dbtng does everything. +#932792 by bec: Extras for formatting {file_managed} fields. +by dereine: Move file_* handlers to extra files. +#934086 by dereine: Attach the contextual links library only once. +#917402 by yhahn: Update taxonomy handlers for d7 changes. +#930582 by berdir, Damz, dereine: Fix query substitutions for subqueries. +#711860 by dereine: 00 entered in pager total fails. +#889770 by tim.plunkett: Empty fields not always hidden based on row settings. +#762484 by master-of-magic: Link to node status could be lost between rows. +#908272 by jaydub: Fix incorrect length of view description form field. +#772782 by mstrelan: Menu normal item menu should default to system default menu rather than "navigation". +#571234 by dereine: Better handling of invalid exposed filters or other methods that cause a view to abort during the build process. +#685554 by MyXelf: Illegal characters in View tag translated improperly when used in theming templates. +#508832 by nick_vh: Documentation improvement on templates. +#887220 by dereine: Fix fatal error when using GROUP BY. +#930714 by brad.bulger: Add aggregator GUID field. +#936828 by xjm: Empty field replacement not quite always working. +#872000 by NaX: Comment edit field needs option to set destination so it can work like comment edit field. +#799580 by dereine: api version of views exports should use views_api_version() not hardcoded number. +#884440 by Amitaibu: Improve token encoding to eliminate double html entity encoding. +#847930 by dereine: Reduce duplicates option not staying set. +#865482 by dereine: RSS options form does not include override. +#813422 by dereine and killes: Improved time-based caching expiration. +#829550 by hefox: Better testing of batch form use by exposed filters. +#570618 by dereine: Enforce denying access to disabled views more strongly. +#667014 by dereine: Prevent notice with relationships and node row style if relationship has no endpoint node. +#835934 by dereine: Provide relationship from files to users. +#738172 by dereine: Fields rewritten to be links with just a fragment did not work. +#694094 by Ian Ward: Allow more static caches to be resettable. (port by aspilicious) +#811226 by dereine: Fix another notice in area text handler. (port by aspilicious) +#917916 by MyXelf: break delimiter not removed from formatted output. (port by aspilicious) +#918654 by Will White: numeric GROUP BY fields missing numeric format options. +by dereine: Test for views_handler_filter_date. +#785236 by e_log: Add aggregator field item id as a field. +#366886 by Scott Reynolds: For "last comment time" if "count zero is empty" is set, use empty text for nodes with no comments. +#611086 by dereine: add -url token to files that can fetch proper URLs with private filesystems. +#635336 by dereine: Remove unused fields from views. +#795270 by dereine: Remove unnecessary links to sections that will have no settings. +#882800 by dereine: Move "Distinct" option to query settings. +#755342 by jcmarco: Improve SQL date field handling. +#338893 by dereine: Aggregator argument not always properly converted to title. +#787184 introduce the long awaited "Update and Override" button. +#718832 by dereine: Add file extension as a field available within the File group. +#941974 by dereine: Use contextual links in the views ui when possible. +#761102 by dereine: test: user default argument. +by dereine: Fix notice in views_ui_add_page. +#667950 by damZ, dereine: Port #dependency form elements to #states. +Added missing file: modules/taxonomy/views_handler_filter_vocabulary_machine_name.inc +#882800 by rszrama: Fix notice for options['distinct']. +#950246 by ZoeN: Fix dbtng in views_handler_argument_aggregator_fid. +#884730 by yched, bojanz, karenS, wundo: Add new UI for formatter settings options to the field settings config. +by dereine: Add the dependeny ctools. +#952576 by yhahn: Use JS_LIBRARY group for adding core library js files. +#563020 by dereine: Replace views object cache with ctools object cache. +#952636 by yhahn: Support string format identifiers in field_markup handler. +#954030 by alweb: Fix title query in views_handler_argument_term_node_tid. +#954784 by tekante: views_join class produces a SQL error when an array is in definition['extra']['value']. +#962756 by bojanz: Field delta shows the placeholder instead of the field name. +#667950 by merlinofchaos, bojanz and dereine: Revert the states patch and use ctools dependency instead. +#960528 by dereine: Clicksort doesn't work for field names that contain special characters. +by dereine: Document add_where for formula. +by dereine: Fix notice in ajax.inc. +#963382 by aidanlis: Fix typo in mathematical expression field help text. +#807614 by dereine: Test filter_numeric. +#928000 by mfer, dereine: form.js dependency missing. +by dereine: Fix some notices. +by dereine: Fix views_exposed_form test. +by dereine: Move test files around. +by dereine: Fix notice in group_by_numeric. +by eporama: Add a test for views_plugin_argument_validate_user. +#788950 by merlinofchaos, bojanz, dereine: Fixed ui when clicking override. +#965432 by bojanz: Display column for single column fields, if that column is not "value". +#965188 by Scott Reynolds: Remove comment.comment column, it does not exist in the database anymore. +#969124 by brenk28: Fix notices in rss feeds related to readmore. +#968286 by bojanz: Let field::render_as_link support entity url options. +#967188 by Island Usurper: Fix exposed data submitted data. +#954916 by becw: taxonomy term id from URL expects taxonomy objects in term fields, none present. +#968372 by becw: "Taxonomy: Term" filter autocomplete broken. +#971326 by dereine: Join fieldapi fields additional on deleted = 0. +#713078 by achaux: Aggregator not properly using allowed tags from core. +#428196 by dereine, funkmasterjones and tic2000: Allow specification of default sort order (asc or desc) per field in table style. +#944680 by rvilar: Properly t() untranslated string. +#881680 by brianV and longwave: Avoid unnecessary invoking of view objects for argument validation when no argument validation is necessary. +#767244 by Magnus: Fix some untranslatable strings due to less than and greater than characters. +#855280 by dereine: Exposed forms set "Input required" lose exposed sorts. +#935388 by infojunkie: Add post_build and post_execute hooks similar to post_render. +#973496 by das-peter: Don't use call-time-reference for comment_view. +#938806 by jenlampton: Node: title field should link to node by default. +#956654 by mdupont: Translation for "offset" field in dates needed work. +#931390 by dww: Optimize boolean logic by using "= 1" rather than "<> 0" for faster queries. +#567918 by iamjon: Improve documentation for token replacement. +#881468 by longwave: Improve performance by static caching results of argument validation because menu likes to double validate things. +#964266 by dereine: cache_expire() missing $type. +#477984 by demeritcowboy, fatstar415, mike dodd, dagmar: Properly handle value for "empty" and "not empty" special operators. +#768060 by EmmanueleQuinto, xjm, others: Make sure that render alter options do not accidentally get blown up for empty fields. +#847724 by dereine: Allow jump menu "Summary" style to customize choose text, just like the regular summary style. +#669636 by dereine and bojanz: Convert the rest of the field handlers that have link options to use the advanced render. +#871578 by dereine: Comment "new" might not work right without a comment count field. +#910864 by Bevan, dereine: exposed filter blocks should not be cached by core block caching. +Remove unused/lost view::render_exposed_form. +#776830: Fix pager settings on attachments and feeds. +#835544 by iamjon: export broke if key contained an apostrophe. +#941990 by master-of-magic: Link to node when using relationships could occasionally lose track and create bad links. +#833790: Click sort could break on fields that were actually formulas. +#963454 by dereine: Remove related terms data definitions. +#976098 by dereine: Fix notice in field field handler render function. +#626732 by dereine: Fix analyze ok-button and added a test for it. +#338584 by superbaloo: Allow displays to be re-ordered in the UI. +#502348: Move advanced rendering up the chain a little bit to allow for non-standard uses of fields, such as grouping, to use advanced rendering features. +#943984 by Kars-T: Remove extraneous line of code. +#751970 by dereine: View list form auto submit on change. +#502348 followup. +#977846 by dereine: Use ctools_process_dependency for table plugin. (follow up of #502348). +#942106 by andypost: Fix converting from vid to vocabulary in taxonomy handlers. +#870792 by bojanz: Options form needs to be re-rendered if it failed validation. +#980628 by bojanz: Fix options-query in field::render_as_link. +#979264 by pwolanin: Account for flipped comment status values in Drupal 7. +#972864 by bec: Provide term relationship via taxonomy term reference fields. +#979634 by linclark: Fix field grouping. +#972934 by dereine: Fix Node: User posted or commented. +by dereine: Preview shouldn't expect to have the sql plugin, always. +#960596 by dereine: Argument in preview aren't escaped. +#983166 by dereine: Rename $class to $classes in the table template file and write some updating documentation. +#963372 by dereine: Add 'form_process_checkbox' to every checkbox which uses process 'ctools_dependent_process'. +#979082 by dereine: Add 'form_process_select' to every select which uses process 'ctools_dependent_process'. +#936196 by jmiccolis, yhahn, adrian, bojanz, dereine: Don't use entity_load for the fieldapi-field handler, but use real sql fields. +by dereine: Fix notice in views_ui_preview(). +#965496 by ayalon: Update and Override broke validation of most views admin forms. +#868990: Fix undefined call to $view->set_use_pager() +#669636 followup by bojanz: Fix improper use of field_alias by row styles. +#979046 by travist: Fix PHP 5.3 problem in views_access with no arguments. +#978864 by linclark: Fix title bug with area handlers. +#983460 by dereine: "Default sort" radio is in wrong column on table style settings. +#783798 by dereine: GROUP BY can cause sort criteria to get incorrectly added to view. +#357529 by nedjo, dddave, dagmar, dereine, yhahn, others: Implement plugin to handle translations of views configuration data. +#983606 by jonathan1055: Breadcrumb disappears on bulk export results. +#945034 by das-peter: Allow any kind of build_mode for node row style. +#936196 by rszrama, das-peter, bojanz, dereine: Fix some bugs with the fieldapi field handler. +#983272 by bojanz: Support click sorting for Field API fields. +by dereine: Fix error in plugin_default_taxonomy_tid. +#974542 by dereine: Use the same signature for pre_render in every handler. +#988490 by dereine: Fix global view result counter. +#740686 by dereine, dagmar: Integrate the functionality of Semantic Views (though it takes a significantly diffrent form). +#988726 by yhahn: Use taxonomy_term_data 'format' column for description field. +#988520 by dereine: Fix sql of date handler for offset. +#952636 by yhahn, jmiccolis, dagmar, dereine: Support string format identifiers. +#960810: Fixed merge error of semantic views patch. +#769458 by anrikun: Fix double encoding of alt/title text on link rewriting. +#318944 by dereine: Prevent warning in table view when user has no permission to view any fields. +#416178 by dereine: Profile field checkboxes did not properly filter false values. +#949526 by dereine: External database not used. +#913688 by dereine: Fix feed icon path. +#768802 by dereine: Allow sort by node language. +#600742 by dagmar: Allow displays to be disabled. +reported by swentel: Remove left over debugging dsm. +#468484 by dereine: Filter by unread not relationship safe. +#833790 redux by dereine: Make sure field actually exists. +#607942 by dashton: Support "rel" attribute in link rewriting. +#994014 by idflood: Add missing semicolon to node translation link handler. +#909886: -Any- option shows up on boolean exposed filters even when not optional. +#972934 by dereine: Fix sql of subquery of comment_user_uid argument handler. +Follow up #607942, use ctools_dependent_process. +#817360 by John Morahan: Have Analyze button warn if view has no access control. +#898990 by dereine: Fix bad SQL generated on related terms relationship if no vocabularies selected. +#833220 by dereine: Properly validate value on date filter. +#910256 by dagmar: Add an - All - option to exposed items per page. +#779668 by esteewhy: Fix not technically valid use of break statements. +#909332 by dereine: Add col-first and col-last classes to grid style. +#989092 by dereine: Semantic views integration broke grid view a little. +#868972 by dereine: Add a "summary" attribute for accessibility on table and grid styles. +#992174 by dereine: Add missing field handler aggregator_xss in the views.info file. +by dereine: Fix fatal error in the field term_node_tid handler. +#994856 by dereine: Replace views dependecy with ctools... again. +by dereine: Replace _fake_instance in field field handler with a ctools helper function. +#996634 by das-peter: Add missing rel to option_definition of the field handler. +#610418 by joachim: Add handler descriptions to handler edit forms. +#368687 by dereine: Allow a relationship from node revision to master node. +#759082 by dereine: Prevent invalid argument warning with no relationships. +#946368 by dereine: User argument default ignoring node author checkbox in some cases. +#867636 by chromix: Give jump menu an option to set default value to current path. +#997772 by dereine: Fix node_view_analyze by using dbtng and d7 role_permission database schema. +#998278 by dereine: Update field.views.inc based on #986992. +#998400 by das-peter: Use vocabulary in "term name converted to term id". +#785036 by dereine and bojanz: Properly validate display IDs. +#958312 by tim.plunkett: Exports could have extraneous whitespace when exported from other modules like features. +#927270 by Cyberwolf: Allow the "options callback" for the in_operator filter handler to also have an "options argument" in the definition. +#497936: Profile fields with dashes in their names cause bad queries. +#608926 by Longwave: Remove unused theme("nodate") functionality. +#993002 by alex_b, dereine: Fix notice in views_plugin_display_page.inc. +#1000044 by pivica: Fix notice for element_type in some field handlers. +#984390 by yhahn: Fix full pager variables. +#972620 by dereine: Add an administrative title field for all handlers to make it more possible to distinguish similar fields from each other in the UI. +#627378: Allow specifying that your module provides specialized views templates via hook_views_api. +#627378 follow up: Remove debug calls. +#1001442 by dboulet: Add classes/title text to contextual links. +#999042 by bojanz: Remove the option to use the site mission for the RSS feed description, because drupal doesn't have this field anymore. +#985602 by bblake, bojanz, dereine: Support slave server. +by dereine: Fix views.info file. +#987478 by bojanz: Let field field handler properly handle field language. +#1002060 by troky: COMMENT_NODE_* constants have new names +#996306 by alex_b: Respect 'edit terms in ' settings +#987478 by bojanz: Fix some more edge cases in field field handler. +#1003034 by das-peter: Use preg_slit instead of split. +#905712 by dagmar: Add Published/Not published as text options to published field. +#816354 by dereine: Provide a field to create administrative comments on displays. +#1004596 by pillarsdotnet: Wrong usage of theme('image'...) in contact field handler. +#1006088 by aspilicious: Remove unneeded files from .info file. +#1005662 by troky: Change original hook to base hook in views hook_theme. +#808016 by dereine: Clarify short/medium/long date formats. +#829928 by gordon: Allow strip tags to get a list of tags to keep. +#1004538 by ngmaloney, bojanz: Support timestamps before 1970 in views date sql. +#522318 by dereine: Provide a "human readable" name for all Views. +#1003112 by ralf: Add configure line to views_ui.info +#118672: Allow an OR in filters by adding groups in the filter UI. +by dereine: Add a test for field math, and fix the field math :) +#1007036 by bojanz: Fix Node: Has new content filter. +by dereine: Add a test for filter equality. +by dereine: Add a test for field counter. +#1007036 by dereine: Fix join condition for Node: Has new content filter. +by dereine: Fix tests for detecting module template files. +#1007730 by bojanz, merlinofchaos, dereine: Fix views_handler_filter_string, add tests and add a general placeholder method. +#1006644 by bojanz, dereine: Allow field field handler to work with users. +#759082 by dereine: Fix whitescreen due to incorrect relationship loop code. +by dereine: Remove old comment about select::countQuery. +#863478 by damz, dereine: Allow basic distinct support. +#667950 by bec : Remove workaround for filter_numeric dependency. +#1011266 by sime: Fix whitescreen due to changes in #759082. +#1011220 by aspilicious: Auto-Generate View's Machine-Readable Name. +#1001542 by mikeytown2: view::set_display() has wrong return code when it fails. +#1011220 follow-up: Add missing point on machine_name. +#722330 by dereine: Views should include core version for updates. +#1008706 by dereine: Convert placeholders to new api. +#807616 by damz, dereine: Remove views_handler_sort_formula and add a short entry in api-upgrading.html +#873238 follow up by dereine: Remove adding cookie.js all the time. Ajax loading works now. +#591302 by yhahn: Update ajax_view.js for ajax framework. +#972638 by bojanz: Mini pager hasn't been ported. +#1011334 by dereine: Exposed filters without input broke sql. +#990088 by yhahn: Fix taxonomy integration by changing vid to nid for taxonomy_index. +#1007466 by aspilicious, dereine: Provide a api function for adding complex queries: add_where_expression, add_having_condition. +#1008170 by dereine: Fix views_handler_filter_groupby_numeric by using add_having_expression. +#1013170 by das-peter: Fix broken view::preview which was broken on #1001542. +#644008 by Cyberwolf and dereine: Allow access plugins access to arguments. +#997424 by dereine: Use drupal_add_library instead of drupal_add_js where it's possible. +#992704 by solotandem, bojanz, dereine: support to groupby entity_id. +#970514 by moshe, dereine: Provide basic drush integration for views. +#1015306 by dereine: Fix index in field_field. +by solotandem: Make a better description for the group_type field in groupby form. +#1015856 by solotandem: Eliminate PHP notices related to recent groupby changes. +#1016058 by dereine: Fix string contain all words. +#940316 by merlinofchaos: Allow to rescan template files from non-current themes. +by mikejoconnor, dereine: Fix notice for exporting view->core. +#1002744 by bojanz: Use entity_load for fieldapi field handlers. +#957206 by dereine: Add missing views.info entry for aggregator iid argument handler. +#1002744 by bojanz: Refactor views_field_field by renaming some variables/comments. +by dereine: Bring vpr and views_debug back. +#955464 by dereine: Fix glossary and many to one mode handler. +#1016430 by bojanz: fix two small bugs in field_field handler. +by dereine: Add $view->version to all default views. +#1006176 by das-peter, bojanz: Add support for field based translation. diff --git a/sites/all/modules/views/D7UPGRADE.txt b/sites/all/modules/views/D7UPGRADE.txt new file mode 100644 index 0000000000000000000000000000000000000000..08d3a3b4f29fdf02c7df017b9b69dab303be292b --- /dev/null +++ b/sites/all/modules/views/D7UPGRADE.txt @@ -0,0 +1,2 @@ +Information about upgrading existing views from Drupal 6 to Drupal 7 is located +in the module's advanced help under api upgrading. diff --git a/sites/all/modules/views/LICENSE.txt b/sites/all/modules/views/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..2c095c8d3f42488e8168f9710a4ffbfc4125a159 --- /dev/null +++ b/sites/all/modules/views/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/sites/all/modules/views/README.txt b/sites/all/modules/views/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..f6217bba1a08c2f6ad4fe08901a270797b23825a --- /dev/null +++ b/sites/all/modules/views/README.txt @@ -0,0 +1,28 @@ +// $Id: README.txt,v 1.26.6.1 2009/11/02 22:01:25 merlinofchaos Exp $ + +Welcome to Views 2. Please see the advanced help for more information. + +If you're having trouble installing this module, please ensure that your +tar program is not flattening the directory tree, truncating filenames +or losing files. + +Installing Views: + +Place the entirety of this directory in sites/all/modules/views + +Navigate to administer >> build >> modules. Enable Views and Views UI. + +If upgrading from Drupal 5 and Views 1, your views need to be +converted manually. See administer >> build >> modules >> views >> tools >> convert. + +If you're new to Views, try the Simple Views module which can create some +often used Views for you, this might save you some time. + +Recommended modules for use with Views: + CCK + Voting API + Views Bonus Pack + Views Bulk Operations + +Experimental modules: + Views OR \ No newline at end of file diff --git a/sites/all/modules/views/css/views-admin.css b/sites/all/modules/views/css/views-admin.css new file mode 100644 index 0000000000000000000000000000000000000000..8e29f2f1d66bfb6d0fc2e6e3934f6da48c22b341 --- /dev/null +++ b/sites/all/modules/views/css/views-admin.css @@ -0,0 +1,724 @@ +/* $Id: views-admin.css,v 1.14.4.12 2010/12/24 13:42:00 dereine Exp $ */ + +/* + * Summary pad + */ +/* set up some defaults so weird themes don't override us too badly. */ +.views-tabset { + color: #494949; + background-color: white; +} + +.views-tabset a:visited, +.views-tabset a:hover, +.views-tabset a { + color: #027AC6; +} + +.views-tabset .views-tab fieldset { + margin-top: 0; +} + +/* + * First column: display drawers + */ +.views-tabset .views-tabs { + background: #F6F6F6; + border-top: #D6DBDE 1px solid; + border-bottom: #D6DBDE 1px solid; + border-left: #D6DBDE 1px solid; + float: left; + width: 117px; + margin-right: 0; +} + +* html .views-tabset .views-tabs { + width: 114px; + position: relative; + left: 4px; +} + +.views-tabset .views-tabs ul { + list-style-type: none !important; + list-style-image: none !important; + padding: 0; + margin: 0; + position: relative; +} + +.views-tabset .views-tabs ul li { + background: #efefef; + list-style-type: none; + list-style-image: none; + line-height: 100%; + border-bottom: #D6DBDE 1px solid; + margin: 0; + padding: 0; + position: relative; +} + +.views-tabset .views-tabs ul li.active { + background: #fff url(../images/arrow-active.png) no-repeat right; + position: relative; + width: 118px; + margin-right: -1px; +} + +.views-tabset .views-tabs ul li a { + display: block; + font-size: 90%; + color: #777; + font-weight: normal; + padding: 0.5em; +} + +.views-tabset .views-tabs ul li a:hover { + background-color: #f6f6f6; + text-decoration: none; +} + +.views-tabset .views-tabs ul li.active a { + color: #000; + font-weight: bold; +} + +.views-tabset .views-tabs ul li.active a:hover { + color: #000; + background: #fff url(../images/arrow-active.png) no-repeat right; +} + +.views-tabset .extra { + text-align: center; + margin-right: 0; +} + +.views-tabset .extra input { + margin-top: 0; + margin-right: 0; + font-size: 10px; + white-space: normal; +} + +/* + * Three columns with setting-summaries + */ +.views-tabset .views-display { + border: #D6DBDE 1px solid; + margin-left: 118px; /* 118 -1 causes borders to overlap */ + min-height: 302px; + _height: 300px; /*stupid IE hack */ +} + +* html .views-tabset .views-display { + margin-left: 114px; +} + +div.views-display-deleted, +div.views-display-deleted div.top, +div.views-display-deleted div.tab-section { + background-color: #eee; +} + +.views-display { + background: #fff; +} + +.views-display div { + font-size: 8pt; + line-height: 12pt; +} + +.views-display .top { + padding: 0.5em 0em 0em 1em; + background: #fff; +} + +.views-display .top .display-title { + font-weight: bold; +} +.views-display .top .display-description { + margin-left: 1em; + font-style: italic; + overflow: hide; + white-space: nowrap; + font-size: 90%; +} + +.views-display .tab-section { + width: 32.5%; + padding: 0; + margin: 0; + float: left; + min-height: 273px; + _height: 274px; +} + +.views-display .tab-section .inside { + margin: 0.5em 0.5em 0.5em 1em; +} + +.views-display .tab-section .inside .views-category { + margin-bottom: 1em; + background: #f6f6f6; + border: 1px #efefef solid; +} + +.views-display .tab-section .inside .views-category-content { + padding: 0em 0em 0.5em 1em; +} + +.views-display .tab-section .inside .views-category-title { + padding: .1em .1em .1em .3em; + margin: 0 0 .1em 0; + font-size: 9pt; + font-weight: bold; + background-color: #efefef; + border-bottom: 1px #efefef solid; +} + +.views-display .tab-section .links { + float: right; + font-size: 6pt; + position: relative; + display: inline; +} + +.views-display .tab-section .links a { + font-size: 6pt; + font-style: italic; +} + +.views-display .form-submit, +#views-ajax-pad .form-submit { + margin: 0; +} + +.views-display .middle { + width: 34%; +} + +.views-basic-info { + margin: 0.5em 0em 0 0; + padding: 0.5em; +} + +/* + * AJAX pad, the bottom part where settings are edited. + */ +#views-ajax-pad { + background: transparent; + margin-top: 0px; +} + +#views-ajax-pad > div.ajax-progress { + display: none; +} + +#views-ajax-title { + background: #f6f6f6; + color: #000; + border-left: #D6DBDE 1px solid; + border-right: #D6DBDE 1px solid; + margin: 0 0 0 118px; + padding: 1em 1em 0em 1em; + font-weight: bold; +} + +#views-ajax-pad .message { + background: #f6f6f6; + color: #000; + margin-left: 118px; + border: #D6DBDE 1px solid; + border-top: 0; + /* padding: 3em 0em; */ + text-align: center; + font-style: italic; +} + +#views-ajax-pad form { + background: #fff; + color: #000; + margin-left: 118px; + border: #D6DBDE 1px solid; + padding-top: 3px; + border-top: 0; + float: none; +} + +#views-ajax-pad .views-messages { + background: transparent; + margin-left: 118px; + padding: 5px; + border: #D6DBDE 1px solid; + border-top: 0; +} + +#views-ajax-pad .form-buttons { + margin: 0; + padding: 0.5em 1em; + background: #f6f6f6; + clear: left; +} + +#views-ajax-pad .clear { + clear: left; +} + +#views-ajax-pad .form-buttons .form-submit { + font-size: 10px; +} + +#views-ajax-pad .form-item { + margin: 0.5em; + padding: 0em 0.5em; +} + +/* These put checkboxes closer together */ +#views-ajax-pad .form-checkboxes .form-item, +#views-ajax-pad .form-checkboxes .description, +#views-ajax-pad .form-checkboxes input, +#views-ajax-pad .form-radios .form-item, +#views-ajax-pad .form-radios label, +#views-ajax-pad .form-radios input { + margin-top: 0; + margin-bottom: 0; +} + +#views-ajax-pad .form-item .form-checkboxes, +#views-ajax-pad .form-checkboxes input, +#views-ajax-pad .form-checkboxes label, +#views-ajax-pad .form-item .form-checkboxes .form-item, +#views-ajax-pad .form-item .form-radios, +#views-ajax-pad .form-radios input, +#views-ajax-pad .form-radios label, +#views-ajax-pad .form-item .form-radios .form-item { + padding-left: 0; + margin-left: 0; +} + +#views-ajax-pad .form-checkboxes .description, +#views-ajax-pad .form-radios .description { + margin-left: 2em; +} + +#views-ajax-pad { + display: none; +} + +html.js #views-ajax-pad { + display: block; +} + +.views-override, +.views-expose { + padding: 0.5em 1em 0em 1em; +} + +#views-ajax-pad .views-override .form-submit, +#views-ajax-pad .views-expose .form-submit { + float: right; + margin: 0 .5em 0 1em; +} + +#views-ajax-pad .views-expose .description, +#views-ajax-pad .views-override .description { + margin-bottom: .25em; +} + +/* + * Some column widths for use within the ajax pad + */ +#views-ajax-pad .views-left-10 { + float: left; + width: 10%; +} + +#views-ajax-pad .views-left-20 { + float: left; + width: 20%; +} + +#views-ajax-pad .views-left-25 { + float: left; + width: 25%; +} + +#views-ajax-pad .views-left-30 { + float: left; + width: 30%; +} + +#views-ajax-pad .views-left-40 { + float: left; + width: 40%; +} + +#views-ajax-pad .views-left-50 { + float: left; + width: 49.5%; +} + +#views-ajax-pad .views-right-50 { + float: right; + width: 50%; +} + +#views-ajax-pad .views-right-60 { + float: right; + width: 60%; +} + +#views-ajax-pad .views-right-70 { + float: right; + width: 70%; +} + +#views-ajax-pad .views-left-75 { + float: left; + width: 75%; +} + +#views-ajax-pad .views-radio-box { + overflow: auto; + height: 22em; +} + +#views-ajax-pad fieldset { + margin: 0 .5em; +} + +#views-ajax-pad table td .form-item, +#views-ajax-pad table td .form-item input, +#views-ajax-pad table td .form-item select { + padding: 0; + margin: 0; +} + +#views-ajax-pad label.hidden-options { + background: transparent url(../images/arrow-active.png) no-repeat right; + height: 12px; + padding-right: 12px; +} + +#views-ajax-pad label.expanded-options { + background: transparent url(../images/expanded-options.png) no-repeat right; + height: 12px; + padding-right: 16px; +} + +#views-ajax-pad .dependent-options { + padding-left: 30px; +} + +/* + * Add, Rearrange and Configure buttons using sprites + */ +a.views-button-configure, +a.views-button-add, +a.views-button-rearrange, +a.views-button-remove { + background:transparent url(../images/sprites.png); + display: inline-block; + float: right; + height: 12px; + width: 16px; + margin: 2px 0px 1px 0px; + border-bottom: #C2C9CE 1px solid; + border-right: #C2C9CE 1px solid; + padding: 0px; +} + +a.views-button-remove { + background-position: 0px -72px; + position: relative; +} +a.views-button-remove:hover { + background-position: 0px -84px; +} + +a.views-button-configure { + background-position: 0px -48px; + margin: 0; +} +a.views-button-configure:hover { + background-position: 0px -60px; +} + +a.views-button-add { + background-position: 0px -24px; +} +a.views-button-add:hover { + background-position: 0px -36px; +} + +a.views-button-rearrange { + background-position: 0px 0px; +} +a.views-button-rearrange:hover { + background-position: 0px -12px; +} + +a.views-button-remove span, +a.views-button-rearrange span, +a.views-button-configure span, +a.views-button-add span { + display: none; +} + +html.js #arrange thead { + display: none; +} + +html.js #ungroupable_arrange .views-hide-label { + color: #D4E7F3; +} + +#ungroupable_arrange thead tr { + /* this CSS mirrors what is found in core for blocks admin. */ + background-color: #D4E7F3; + border-bottom: 1px solid #B4D7F0; + border-top: 1.5em solid #FFFFFF; + color: #455067; + padding-top: 0; + padding-bottom: 0; +} + +html.js .views-remove-checkbox { + display: none; +} + +a.views-button-remove { + display: none; +} + +html.js a.views-button-remove { + display: inline; +} + +.arrange tr.even, +.arrange tr.odd, +.arrange td { + padding-top: 0; + padding-bottom: 0; +} + +.arrange .form-item { + padding: 0; +} + +div.changed { + background-color: #ffe; + font-weight: bold; +} + +div.view-changed { + display: none; + float: right; + font-style: italic; + color: #f93; + padding-left: 1em; +} + +div.views-tab div.changed a { + +} + +div.changed div.view-changed { + display: block; +} + +.views-display .tab-section .inside .overridden { + /* all this so we don't mess up background-color */ +/* background-image: url(../images/overridden.gif); + background-repeat: no-repeat; + background-position: left; + padding-left: 10px; */ +} + +.views-display .tab-section .views-category-content.overridden { + background-image: none; +} + +.views-display .tab-section .inside .defaulted { + color: #aaa; + font-style: italic; +} + +.views-display .tab-section .inside .defaulted a { + font-style: italic; +} + +.hilited { + color: #000; + font-weight: bold; + background-color: #ffd; + padding-left: 10px; +} + +#views-ajax-pad fieldset { + background: transparent; + padding-left: 10px; +} + +#views-ajax-pad pre { + overflow: auto; + border: 1px solid #333; + background-color: #f0f0f0; + padding: .5em; +} + +form#views-ui-reorder-displays-button { + margin-bottom: 0em; + border-bottom: 1px solid #ccc; +} +form#views-ui-reorder-displays-button input.form-submit{ + margin-bottom: 2em; +} + +form#views-add-display-form { + margin-bottom: 0em; + border-bottom: 1px solid #ccc; +} + +form#views-add-display-form select { + width: 8.5em; +} + +#views-ui-edit-view-form { + margin: 10px 0 0; + padding: 0; + clear: both; +} + +#views-live-preview { + padding-top: .5em; +} + +#views-live-preview form, +#center #views-live-preview form { + border: 1px solid #D6DBDE; + margin: 0 0 .5em 0; + padding: .5em; +} + +#views-live-preview form div.form-item { + float: left; + margin: 0; + padding: 0 1em 0 0; +} + +#views-live-preview form input#preview-submit { + margin: 1em 0 0 0; +} + +.view-locked { + color: red; + border: 1px solid red; + padding: 1em; +} + +/* Hide by default only with js */ +html.js .views-hidden { + display: none; +} + +.views-query-info { +/* overflow: auto; */ +} + +.views-query-info pre { + white-space: pre; /* CSS2 */ + white-space: -moz-pre-wrap; /* Mozilla */ + white-space: -hp-pre-wrap; /* HP printers */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: pre-wrap; /* CSS 2.1 */ + white-space: pre-line; /* CSS 3 (and 2.1 as well, actually) */ + word-wrap: break-word; /* IE */ + max-height: 200px; + overflow: scroll; +} + +.views-quick-links { + float: right; +} + +.views-quick-links ul.links li { + padding-left: 1em; +} + +.views-quick-links li.last { +} + +.views-edit-view .advanced-help-link { + padding-right: 3px; +} + +#views-ajax-title .advanced-help-link { + position: relative; + top: 2px; + padding-right: 3px; +} + +#views-ajax-pad input, +#views-ajax-pad textarea { + max-width: 95%; +} + +.clone-display, +.remove-display { + float: right; + margin: 0; + padding: .2em 1em 0 0; + position: relative; + top: .1em; +} + +.views-display .remove-display form, +.remove-display input, +.views-display .clone-display form, +.clone-display input { + margin: 0 !important; +} + +.views-validator-options { + padding: 0 1em; + margin: 0 1em; + border: 1px solid; +} + +div.views-category #page-title { + background: none; + padding-top: 0px; +} + +.group-populated { + display: none; +} + +td.group { + /* this CSS mirrors what is found in core for blocks admin. */ + background-color: #D4E7F3; + border-bottom: 1px solid #B4D7F0; + border-top: 1.5em solid #FFFFFF; + color: #455067; +} + +td.group-title { + font-weight: bold; +} + +tr.group-message { + font-style: italic; + color:#999999; +} + +.group-message .form-submit, +#views-add-group { + float: right; + clear: both; +} + +html.js .views-group-select { + display: none; +} diff --git a/sites/all/modules/views/css/views-list-rtl.css b/sites/all/modules/views/css/views-list-rtl.css new file mode 100644 index 0000000000000000000000000000000000000000..132462138357ffe50446a2c3095505d9b28b30e5 --- /dev/null +++ b/sites/all/modules/views/css/views-list-rtl.css @@ -0,0 +1,28 @@ +/* $Id: views-list-rtl.css,v 1.1 2009/03/25 00:08:45 merlinofchaos Exp $ */ + +table.views-entry { + clear: right; /* RTL */ +} + +table.views-entry td.view-ops { + text-align: left; /* RTL */ +} + +#views-ui-list-views-form .form-item { + padding-left: 1em; /* RTL */ + float: right; /* RTL */ +} + +#edit-order-wrapper { + clear: right; /* RTL */ +} + +#edit-views-apply, +#edit-views-reset { + float: right; /* RTL */ +} + +.views-entry .advanced-help-link { + padding-left: 3px; /* RTL */ +} + diff --git a/sites/all/modules/views/css/views-list.css b/sites/all/modules/views/css/views-list.css new file mode 100644 index 0000000000000000000000000000000000000000..29e4c60bf8d5ddae4f7b76fc1cc835b412d2b98b --- /dev/null +++ b/sites/all/modules/views/css/views-list.css @@ -0,0 +1,80 @@ +/* $Id: views-list.css,v 1.12.6.2 2009/11/18 20:04:07 merlinofchaos Exp $ */ + +table.views-entry { + margin: 3px 0; + border: 1px solid #ddd; + background-color: white; + color: #494949; /* matches garland */ + clear: left; /* LTR */ + width: 100%; +} + +table.views-entry tbody { + border: none; +} + +table.views-entry td.view-ops { + width: 45%; + text-align: right; /* LTR */ + background-color: #eee; +} + +table.views-entry td.view-name { + background-color: #eee; +} + +table.views-entry .description { + vertical-align: top; +} + +body form#views-ui-list-views-form { + margin: 0 0 1.5em 0; +} + +#views-ui-list-views-form .form-item { + padding-right: 1em; /* LTR */ + float: left; /* LTR */ + margin-top: 0; + margin-bottom: 0; +} + +#edit-order-wrapper { + clear: left; /* LTR */ +} + +#edit-views-apply, +#edit-views-reset { + margin-top: 1.65em; + float: left; /* LTR */ +} + +.views-entry .advanced-help-link { + position: relative; + top: 2px; + padding-right: 3px; /* LTR */ +} + +table.view-disabled { + color: #999; +} + +table.views-entry td { + line-height: 1.4; + padding-bottom: 10px; +} +table.view-disabled td { + line-height: 1.4; + padding-bottom: 10px; + background: none; +} +table.view-enabled td.view-name, +table.view-enabled td.view-ops, +table.view-disabled td.view-name, +table.view-disabled td.view-ops { + line-height: 1.6; + padding-bottom: 0.3em; +} +table.view-enabled td.view-name, +table.view-enabled td.view-ops { + background: #E4F0F8; +} diff --git a/sites/all/modules/views/css/views-rtl.css b/sites/all/modules/views/css/views-rtl.css new file mode 100644 index 0000000000000000000000000000000000000000..fef2bd9f823cfbade4258a3b9582e554fefa60dc --- /dev/null +++ b/sites/all/modules/views/css/views-rtl.css @@ -0,0 +1,6 @@ + +.views-exposed-form .views-exposed-widget { + float: right; /* RTL */ + padding: .5em 1em 0 0; /* RTL */ +} + diff --git a/sites/all/modules/views/css/views-tabs.css b/sites/all/modules/views/css/views-tabs.css new file mode 100644 index 0000000000000000000000000000000000000000..34ed6feed733dc646c8dd75e55f1efee33c87bcd --- /dev/null +++ b/sites/all/modules/views/css/views-tabs.css @@ -0,0 +1,5 @@ +/* $Id */ + +.ui-tabs-hide { + display: none; +} diff --git a/sites/all/modules/views/css/views.css b/sites/all/modules/views/css/views.css new file mode 100644 index 0000000000000000000000000000000000000000..b909f0b2476697076d8a7982a7883c74225734d0 --- /dev/null +++ b/sites/all/modules/views/css/views.css @@ -0,0 +1,57 @@ +/* $Id: views.css,v 1.11.6.5 2010/07/04 10:04:50 dereine Exp $ */ +.views-exposed-form .views-exposed-widget { + float: left; /* LTR */ + padding: .5em 1em 0 0; /* LTR */ +} + +.views-exposed-form .views-exposed-widget .form-submit { + margin-top: 1.6em; +} + +.views-exposed-form .form-item, +.views-exposed-form .form-submit { + margin-top: 0; + margin-bottom: 0; +} + +.views-exposed-form label { + font-weight: bold; +} + +.views-exposed-widgets { + margin-bottom: .5em; +} + +/* table style column align */ +.views-align-left { + text-align: left; +} +.views-align-right { + text-align: right; +} +.views-align-center { + text-align: center; +} + +div.view div.views-hide { + display: none; +} + +/** For IE we add the class via js; for other browsers we rely on :hover **/ +div.view div.views-hide-hover, +div.view:hover div.views-hide { + display: block; + position: absolute; + z-index: 200; +} + +/* don't do this one in IE */ +div.view:hover div.views-hide { + margin-top: -1.5em; +} + +/* Remove the border on tbody that system puts in */ +.views-view-grid tbody { + border-top: none; +} + diff --git a/sites/all/modules/views/docs/docs.php b/sites/all/modules/views/docs/docs.php new file mode 100644 index 0000000000000000000000000000000000000000..141368b53a08c17298c6400e3844b0b783133ca4 --- /dev/null +++ b/sites/all/modules/views/docs/docs.php @@ -0,0 +1,713 @@ +<?php +// $Id: docs.php,v 1.16.4.10 2010/12/18 08:02:37 dereine Exp $ +/** + * @file + * This file contains no working PHP code; it exists to provide additional documentation + * for doxygen as well as to document hooks in the standard Drupal manner. + */ + +/** + * @mainpage Views 2 API Manual + * + * Much of this information is actually stored in the advanced help; please + * check the API topic. This help will primarily be aimed at documenting + * classes and function calls. + * + * An online version of the advanced help API documentation is available from: + * @link http://views-help.doc.logrus.com/help/views/api @endlink + * + * Topics: + * - @ref view_lifetime + * - @ref views_hooks + * - @ref views_handlers + * - @ref views_plugins + * - @ref views_templates + */ + +/** + * @page view_lifetime The life of a view + * + * This page explains the basic cycle of a view and what processes happen. + */ + +/** + * @page views_handlers About Views' handlers + * + * This page explains what views handlers are, how they're written, and what + * the basic conventions are. + * + * - @ref views_field_handlers + * - @ref views_sort_handlers + * - @ref views_filter_handlers + * - @ref views_argument_handlers + * - @ref views_relationship_handlers + */ + +/** + * @page views_plugins About Views' plugins + * + * This page explains what views plugins are, how they're written, and what + * the basic conventions are. + * + * - @ref views_display_plugins + * - @ref views_style_plugins + * - @ref views_row_plugins + */ + +/** + * @defgroup views_hooks Views' hooks + * @{ + * Hooks that can be implemented by other modules in order to implement the + * Views API. + */ + +/** + * Describe table structure to Views. + * + * This hook should be placed in MODULENAME.views.inc and it will be auto-loaded. + * This must either be in the same directory as the .module file or in a subdirectory + * named 'includes'. + * + * The full documentation for this hook is in the advanced help. + * @link http://views-help.doc.logrus.com/help/views/api-tables @endlink + */ +function hook_views_data() { + // This example describes how to write hook_views_data() for the following + // table: + // + // CREATE TABLE example_table ( + // nid INT(11) NOT NULL COMMENT 'Primary key; refers to {node}.nid.', + // plain_text_field VARCHAR(32) COMMENT 'Just a plain text field.', + // numeric_field INT(11) COMMENT 'Just a numeric field.', + // boolean_field INT(1) COMMENT 'Just an on/off field.', + // timestamp_field INT(8) COMMENT 'Just a timestamp field.', + // PRIMARY KEY(nid) + // ); + + // The 'group' index will be used as a prefix in the UI for any of this + // table's fields, sort criteria, etc. so it's easy to tell where they came + // from. + $data['example_table']['table']['group'] = t('Example table'); + + // Define this as a base table. In reality this is not very useful for + // this table, as it isn't really a distinct object of its own, but + // it makes a good example. + $data['example_table']['table']['base'] = array( + 'field' => 'nid', + 'title' => t('Example table'), + 'help' => t("Example table contains example content and can be related to nodes."), + 'weight' => -10, + ); + + // This table references the {node} table. + // This creates an 'implicit' relationship to the node table, so that when 'Node' + // is the base table, the fields are automatically available. + $data['example_table']['table']['join'] = array( + // Index this array by the table name to which this table refers. + // 'left_field' is the primary key in the referenced table. + // 'field' is the foreign key in this table. + 'node' => array( + 'left_field' => 'nid', + 'field' => 'nid', + ), + ); + + // Next, describe each of the individual fields in this table to Views. For + // each field, you may define what field, sort, argument, and/or filter + // handlers it supports. This will determine where in the Views interface you + // may use the field. + + // Node ID field. + $data['example_table']['nid'] = array( + 'title' => t('Example content'), + 'help' => t('Some example content that references a node.'), + // Because this is a foreign key to the {node} table. This allows us to + // have, when the view is configured with this relationship, all the fields + // for the related node available. + 'relationship' => array( + 'base' => 'node', + 'field' => 'nid', + 'handler' => 'views_handler_relationship', + 'label' => t('Example node'), + ), + ); + + // Example plain text field. + $data['example_table']['plain_text_field'] = array( + 'title' => t('Plain text field'), + 'help' => t('Just a plain text field.'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // Example numeric text field. + $data['example_table']['numeric_field'] = array( + 'title' => t('Numeric field'), + 'help' => t('Just a numeric field.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // Example boolean field. + $data['example_table']['boolean_field'] = array( + 'title' => t('Boolean field'), + 'help' => t('Just an on/off field.'), + 'field' => array( + 'handler' => 'views_handler_field_boolean', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_boolean_operator', + 'label' => t('Published'), + 'type' => 'yes-no', + // use boolean_field = 1 instead of boolean_field <> 0 in WHERE statment + 'use equal' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // Example timestamp field. + $data['example_table']['timestamp_field'] = array( + 'title' => t('Timestamp field'), + 'help' => t('Just a timestamp field.'), + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + ); + + return $data; +} + +/** + * Alter table structure. + * + * You can add/edit/remove to existing tables defined by hook_views_data(). + * + * This hook should be placed in MODULENAME.views.inc and it will be auto-loaded. + * This must either be in the same directory as the .module file or in a subdirectory + * named 'includes'. + * + * The full documentation for this hook is in the advanced help. + * @link http://views-help.doc.logrus.com/help/views/api-tables @endlink + */ +function hook_views_data_alter(&$data) { + // This example alters the title of the node: nid field for the admin. + $data['node']['nid']['title'] = t('Node-Nid'); + + // This example adds a example field to the users table + $data['users']['example_field'] = array( + 'title' => t('Example field'), + 'help' => t('Some examüple content that references a user'), + 'handler' => 'hook_handlers_field_example_field', + ); + + // This example changes the handler of the node title field. + // In this handler you could do stuff, like preview of the node, when clicking the node title. + + $data['node']['title']['handler'] = 'modulename_handlers_field_node_title'; +} + + +/** + * The full documentation for this hook is now in the advanced help. + * + * This hook should be placed in MODULENAME.views.inc and it will be auto-loaded. + * This must either be in the same directory as the .module file or in a subdirectory + * named 'includes'. + * + * This is a stub list as a reminder that this needs to be doc'd and is not used + * in views anywhere so might not be remembered when this is formally documented: + * - style: 'even empty' + */ +function hook_views_plugins() { + // example code here +} + +/** + * Alter existing plugins data, defined by modules. + */ +function hook_views_plugins_alter(&$plugins) { + // Add apachesolr to the base of the node row plugin. + $plugins['row']['node']['base'][] = 'apachesolr'; +} + +/** + * Register View API information. This is required for your module to have + * its include files loaded; for example, when implementing + * hook_views_default_views(). + * + * @return + * An array with the following possible keys: + * - api: (required) The version of the Views API the module implements. + * - path: (optional) If includes are stored somewhere other than within + * the root module directory or a subdirectory called includes, specify + * its path here. + * - template path: (optional) A path where the module has stored it's views template files. + * When you have specificed this key views automatically uses the template files for the views. + * You can use the same naming conventions like for normal views template files. + */ +function hook_views_api() { + return array( + 'api' => 2, + 'path' => drupal_get_path('module', 'example') . '/includes/views', + ); +} + +/** + * This hook allows modules to provide their own views which can either be used + * as-is or as a "starter" for users to build from. + * + * This hook should be placed in MODULENAME.views_default.inc and it will be + * auto-loaded. This must either be in the same directory as the .module file + * or in a subdirectory named 'includes'. + * + * The $view->disabled boolean flag indicates whether the View should be + * enabled or disabled by default. + * + * @return + * An associative array containing the structures of views, as generated from + * the Export tab, keyed by the view name. A best practice is to go through + * and add t() to all title and label strings, with the exception of menu + * strings. + */ +function hook_views_default_views() { + // Begin copy and paste of output from the Export tab of a view. + $view = new view; + $view->name = 'frontpage'; + $view->description = t('Emulates the default Drupal front page; you may set the default home page path to this view to make it your front page.'); + $view->tag = t('default'); + $view->base_table = 'node'; + $view->api_version = 2; + $view->disabled = FALSE; // Edit this to true to make a default view disabled initially + $view->display = array(); + $display = new views_display; + $display->id = 'default'; + $display->display_title = t('Defaults'); + $display->display_plugin = 'default'; + $display->position = '1'; + $display->display_options = array ( + 'style_plugin' => 'default', + 'style_options' => + array ( + ), + 'row_plugin' => 'node', + 'row_options' => + array ( + 'teaser' => 1, + 'links' => 1, + ), + 'relationships' => + array ( + ), + 'fields' => + array ( + ), + 'sorts' => + array ( + 'sticky' => + array ( + 'id' => 'sticky', + 'table' => 'node', + 'field' => 'sticky', + 'order' => 'ASC', + ), + 'created' => + array ( + 'id' => 'created', + 'table' => 'node', + 'field' => 'created', + 'order' => 'ASC', + 'relationship' => 'none', + 'granularity' => 'second', + ), + ), + 'arguments' => + array ( + ), + 'filters' => + array ( + 'promote' => + array ( + 'id' => 'promote', + 'table' => 'node', + 'field' => 'promote', + 'operator' => '=', + 'value' => '1', + 'group' => 0, + 'exposed' => false, + 'expose' => + array ( + 'operator' => false, + 'label' => '', + ), + ), + 'status' => + array ( + 'id' => 'status', + 'table' => 'node', + 'field' => 'status', + 'operator' => '=', + 'value' => '1', + 'group' => 0, + 'exposed' => false, + 'expose' => + array ( + 'operator' => false, + 'label' => '', + ), + ), + ), + 'items_per_page' => 10, + 'use_pager' => '1', + 'pager_element' => 0, + 'title' => '', + 'header' => '', + 'header_format' => '1', + 'footer' => '', + 'footer_format' => '1', + 'empty' => '', + 'empty_format' => '1', + ); + $view->display['default'] = $display; + $display = new views_display; + $display->id = 'page'; + $display->display_title = t('Page'); + $display->display_plugin = 'page'; + $display->position = '2'; + $display->display_options = array ( + 'defaults' => + array ( + 'access' => true, + 'title' => true, + 'header' => true, + 'header_format' => true, + 'header_empty' => true, + 'footer' => true, + 'footer_format' => true, + 'footer_empty' => true, + 'empty' => true, + 'empty_format' => true, + 'items_per_page' => true, + 'offset' => true, + 'use_pager' => true, + 'pager_element' => true, + 'link_display' => true, + 'php_arg_code' => true, + 'exposed_options' => true, + 'style_plugin' => true, + 'style_options' => true, + 'row_plugin' => true, + 'row_options' => true, + 'relationships' => true, + 'fields' => true, + 'sorts' => true, + 'arguments' => true, + 'filters' => true, + 'use_ajax' => true, + 'distinct' => true, + ), + 'relationships' => + array ( + ), + 'fields' => + array ( + ), + 'sorts' => + array ( + ), + 'arguments' => + array ( + ), + 'filters' => + array ( + ), + 'path' => 'frontpage', + ); + $view->display['page'] = $display; + $display = new views_display; + $display->id = 'feed'; + $display->display_title = t('Feed'); + $display->display_plugin = 'feed'; + $display->position = '3'; + $display->display_options = array ( + 'defaults' => + array ( + 'access' => true, + 'title' => false, + 'header' => true, + 'header_format' => true, + 'header_empty' => true, + 'footer' => true, + 'footer_format' => true, + 'footer_empty' => true, + 'empty' => true, + 'empty_format' => true, + 'use_ajax' => true, + 'items_per_page' => true, + 'offset' => true, + 'use_pager' => true, + 'pager_element' => true, + 'use_more' => true, + 'distinct' => true, + 'link_display' => true, + 'php_arg_code' => true, + 'exposed_options' => true, + 'style_plugin' => false, + 'style_options' => false, + 'row_plugin' => false, + 'row_options' => false, + 'relationships' => true, + 'fields' => true, + 'sorts' => true, + 'arguments' => true, + 'filters' => true, + ), + 'relationships' => + array ( + ), + 'fields' => + array ( + ), + 'sorts' => + array ( + ), + 'arguments' => + array ( + ), + 'filters' => + array ( + ), + 'displays' => + array ( + 'default' => 'default', + 'page' => 'page', + ), + 'style_plugin' => 'rss', + 'style_options' => + array ( + 'description' => '', + ), + 'row_plugin' => 'node_rss', + 'row_options' => + array ( + 'item_length' => 'default', + ), + 'path' => 'rss.xml', + 'title' => t('Front page feed'), + ); + $view->display['feed'] = $display; + // End copy and paste of Export tab output. + + // Add view to list of views to provide. + $views[$view->name] = $view; + + // ...Repeat all of the above for each view the module should provide. + + // At the end, return array of default views. + return $views; +} + +/** + * This hook is called right before all default views are cached to the + * database. It takes a keyed array of views by reference. + */ +function hook_views_default_views_alter(&$views) { + if (isset($views['taxonomy_term'])) { + $views['taxonomy_term']->set_display('default'); + $views['taxonomy_term']->display_handler->set_option('title', 'Categories'); + } +} + +/** + * Stub hook documentation + * + * This hook should be placed in MODULENAME.views_convert.inc and it will be auto-loaded. + * This must either be in the same directory as the .module file or in a subdirectory + * named 'includes'. + */ +function hook_views_convert() { + // example code here +} + +/** + * Stub hook documentation + */ +function hook_views_query_substitutions() { + // example code here +} + +/** + * This hook is called at the very beginning of views processing, + * before anything is done. + * + * Adding output to the view can be accomplished by placing text on + * $view->attachment_before and $view->attachment_after. + */ +function hook_views_pre_view(&$view, &$display_id, &$args) { + // example code here +} + +/** + * This hook is called right before the build process, but after displays + * are attached and the display performs its pre_execute phase. + * + * Adding output to the view can be accomplished by placing text on + * $view->attachment_before and $view->attachment_after. + */ +function hook_views_pre_build(&$view) { + // example code here +} + +/** + * This hook is called right after the build process. The query is + * now fully built, but it has not yet been run through db_rewrite_sql. + * + * Adding output to the view can be accomplished by placing text on + * $view->attachment_before and $view->attachment_after. + */ +function hook_views_post_build(&$view) { + // example code here +} + +/** + * This hook is called right before the execute process. The query is + * now fully built, but it has not yet been run through db_rewrite_sql. + * + * Adding output to the view can be accomplished by placing text on + * $view->attachment_before and $view->attachment_after. + */ +function hook_views_pre_execute(&$view) { + // example code here +} + +/** + * This hook is called right after the execute process. The query has + * been executed, but the pre_render() phase has not yet happened for + * handlers. + * + * Adding output to the view can be accomplished by placing text on + * $view->attachment_before and $view->attachment_after. Altering the + * content can be achieved by editing the items of $view->result. + */ +function hook_views_post_execute(&$view) { + // example code here +} + +/** + * This hook is called right before the render process. The query has + * been executed, and the pre_render() phase has already happened for + * handlers, so all data should be available. + * + * Adding output to the view can be accomplished by placing text on + * $view->attachment_before and $view->attachment_after. Altering the + * content can be achieved by editing the items of $view->result. + * + * This hook can be utilized by themes. + */ +function hook_views_pre_render(&$view) { + // example code here +} + +/** + * Post process any rendered data. + * + * This can be valuable to be able to cache a view and still have some level of + * dynamic output. In an ideal world, the actual output will include HTML + * comment based tokens, and then the post process can replace those tokens. + * + * Example usage. If it is known that the view is a node view and that the + * primary field will be a nid, you can do something like this: + * + * <!--post-FIELD-NID--> + * + * And then in the post render, create an array with the text that should + * go there: + * + * strtr($output, array('<!--post-FIELD-1-->', 'output for FIELD of nid 1'); + * + * All of the cached result data will be available in $view->result, as well, + * so all ids used in the query should be discoverable. + * + * This hook can be utilized by themes. + */ +function hook_views_post_render(&$view, &$output, &$cache) { + +} + +/** + * Stub hook documentation + * + * This hook should be placed in MODULENAME.views.inc and it will be auto-loaded. + * This must either be in the same directory as the .module file or in a subdirectory + * named 'includes'. + * + */ +function hook_views_query_alter(&$view, &$query) { + // example code here +} + +/** + * This hook should be placed in MODULENAME.views.inc and it will be auto-loaded. + * This must either be in the same directory as the .module file or in a subdirectory + * named 'includes'. + * + * Alter the links that appear over a view. They are in a format suitable for + * theme('links'). + * + * Warning: $view is not a reference in PHP4 and cannot be modified here. But it IS + * a reference in PHP5, and can be modified. Please be careful with it. + * + * @see theme_links + */ +function hook_views_admin_links_alter(&$links, $view) { + // example code here +} + +/** + * This hook should be placed in MODULENAME.views.inc and it will be auto-loaded. + * This must either be in the same directory as the .module file or in a subdirectory + * named 'includes'. + * + * Alter the rows that appear with a view, which includes path and query information. + * The rows are suitable for theme('table'). + * + * Warning: $view is not a reference in PHP4 and cannot be modified here. But it IS + * a reference in PHP5, and can be modified. Please be careful with it. + * + * @see theme_table + */ +function hook_views_preview_info_alter(&$rows, $view) { + // example code here +} + +/** + * @} + */ diff --git a/sites/all/modules/views/documentation-standards.txt b/sites/all/modules/views/documentation-standards.txt new file mode 100644 index 0000000000000000000000000000000000000000..ea6113571ee8692e4af9688bf8603b005191e673 --- /dev/null +++ b/sites/all/modules/views/documentation-standards.txt @@ -0,0 +1,6 @@ +- If the interface text is *bolded*, it got strong tags. +- If it's a button they need to click, that's *bold* too. +- If the text is not bolded (ex: links to click, options to check), it +got /italicized/. +- If it's user-entered text it got 'single quotes'. + diff --git a/sites/all/modules/views/handlers/views_handler_area.inc b/sites/all/modules/views/handlers/views_handler_area.inc new file mode 100644 index 0000000000000000000000000000000000000000..85254605ad72a84b476e6a0ba0935bb68bfc83f4 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_area.inc @@ -0,0 +1,106 @@ +<?php +// $Id: views_handler_area.inc,v 1.1.4.3 2010/12/17 21:42:19 merlinofchaos Exp $ +/** + * @file + * Views area handlers. + */ + +/** + * @defgroup views_area_handlers Views' relationship handlers + * @{ + * Handlers to tell Views what can display in header, footer + * and empty text in a view. + */ + +class views_handler_area extends views_handler { + /** + * Get this field's label. + */ + function label() { + if (!isset($this->options['label'])) { + return $this->ui_name(); + } + return $this->options['label']; + } + + function option_definition() { + $options = parent::option_definition(); + + $this->definition['field'] = !empty($this->definition['field']) ? $this->definition['field'] : ''; + $label = !empty($this->definition['label']) ? $this->definition['label'] : $this->definition['field']; + $options['label'] = array('default' => $label, 'translatable' => TRUE); + $options['empty'] = array('default' => 0, 'bool' => TRUE); + + return $options; + } + + /** + * Provide extra data to the administration form + */ + function admin_summary() { + return $this->label(); + } + + /** + * Default options form that provides the label widget that all fields + * should have. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['label'] = array( + '#type' => 'textfield', + '#title' => t('Label'), + '#default_value' => isset($this->options['label']) ? $this->options['label'] : '', + '#description' => t('The label for this area that will be displayed only administratively.'), + ); + + if ($form_state['type'] != 'empty') { + $form['empty'] = array( + '#type' => 'checkbox', + '#title' => t('Display even if view has no result'), + '#default_value' => isset($this->options['empty']) ? $this->options['empty'] : 0, + '#description' => t('If checked this area will be rended, even if the views has no results.'), + ); + } + } + + /** + * Don't run a query + */ + function query() { } + + /** + * Render the area + */ + function render($empty = FALSE) { + return ''; + } +} + +/** + * A special handler to take the place of missing or broken handlers. + */ +class views_handler_area_broken extends views_handler_area { + function ui_name($short = FALSE) { + return t('Broken/missing handler'); + } + + function ensure_my_table() { /* No table to ensure! */ } + function query() { /* No query to run */ } + function render($empty = FALSE) { return ''; } + function options_form(&$form, &$form_state) { + $form['markup'] = array( + '#prefix' => '<div class="form-item description">', + '#value' => t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.'), + ); + } + + /** + * Determine if the handler is considered 'broken' + */ + function broken() { return TRUE; } +} + +/** + * @} + */ diff --git a/sites/all/modules/views/handlers/views_handler_area_text.inc b/sites/all/modules/views/handlers/views_handler_area_text.inc new file mode 100644 index 0000000000000000000000000000000000000000..537de4a789c27d0a93818c51502270da677f0a46 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_area_text.inc @@ -0,0 +1,59 @@ +<?php +// $Id: views_handler_area_text.inc,v 1.1.4.7 2010/12/06 17:13:49 dereine Exp $ + +class views_handler_area_text extends views_handler_area { + + function option_definition() { + $options = parent::option_definition(); + $options['content'] = array('default' => '', 'translatable' => TRUE); + $options['format'] = array('default' => filter_default_format()); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $form['content'] = array( + '#type' => 'text_format', + '#default_value' => $this->options['content'], + '#rows' => 6, + '#format' => $this->options['format'], + ); + } + + function options_submit(&$form, &$form_state) { + $form_state['values']['options']['format'] = $form_state['values']['options']['content']['format']; + $form_state['values']['options']['content'] = $form_state['values']['options']['content']['value']; + parent::options_submit($form, $form_state); + } + + function render($empty = FALSE) { + if (!$empty || !empty($this->options['empty'])) { + return $this->render_textarea($this->options['content'], $this->options['format']); + } + return ''; + } + + /** + * Render a text area, using the proper format. + */ + function render_textarea($value, $format) { + static $formats = array(); + + if (!array_key_exists($format, $formats)) { + if ($filter = filter_format_load($format)) { + $formats[$format] = $filter->name; + } + } + + if (!isset($formats[$format])) { + return; + } + + if ($value) { + return check_markup($value, $format, '', FALSE); + } + } + +} + diff --git a/sites/all/modules/views/handlers/views_handler_argument.inc b/sites/all/modules/views/handlers/views_handler_argument.inc new file mode 100644 index 0000000000000000000000000000000000000000..1438c57be43e5f9425619b926336e86a39476dff --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_argument.inc @@ -0,0 +1,938 @@ +<?php +// $Id: views_handler_argument.inc,v 1.9.4.12 2010/12/17 21:42:19 merlinofchaos Exp $ + +/** + * @defgroup views_argument_handlers Handlers for arguments + * @{ + */ + +/** + * Base class for arguments. + * + * The basic argument works for very simple arguments such as nid and uid + * + * Definition terms for this handler: + * - name field: The field to use for the name to use in the summary, which is + * the displayed output. For example, for the node: nid argument, + * the argument itself is the nid, but node.title is displayed. + * - name table: The table to use for the name, should it not be in the same + * table as the argument. + * - empty field name: For arguments that can have no value, such as taxonomy + * which can have "no term", this is the string which + * will be displayed for this lack of value. Be sure to use + * t(). + * - validate type: A little used string to allow an argument to restrict + * which validator is available to just one. Use the + * validator ID. This probably should not be used at all, + * and may disappear or change. + * - numeric: If set to TRUE this field is numeric and will use %d instead of + * %s in queries. + * + * @ingroup views_argument_handlers + */ +class views_handler_argument extends views_handler { + var $name_field = NULL; + /** + * Constructor + */ + function construct() { + parent::construct(); + + if (!empty($this->definition['name field'])) { + $this->name_field = $this->definition['name field']; + } + if (!empty($this->definition['name table'])) { + $this->name_table = $this->definition['name table']; + } + } + + function init(&$view, &$options) { + parent::init($view, $options); + } + + /** + * Give an argument the opportunity to modify the breadcrumb, if it wants. + * This only gets called on displays where a breadcrumb is actually used. + * + * The breadcrumb will be in the form of an array, with the keys being + * the path and the value being the already sanitized title of the path. + */ + function set_breadcrumb(&$breadcrumb) { } + + /** + * Determine if the argument can generate a breadcrumb + * + * @return TRUE/FALSE + */ + function uses_breadcrumb() { + $info = $this->default_actions($this->options['default_action']); + return !empty($info['breadcrumb']); + } + + function is_wildcard($arg = NULL) { + if (!isset($arg)) { + $arg = $this->argument; + } + + return !empty($this->options['wildcard']) && $this->options['wildcard'] === $arg; + } + + function wildcard_title() { + return $this->options['wildcard_substitution']; + } + + /** + * Determine if the argument needs a style plugin. + * + * @return TRUE/FALSE + */ + function needs_style_plugin() { + $info = $this->default_actions($this->options['default_action']); + $validate_info = $this->default_actions($this->options['validate_fail']); + return !empty($info['style plugin']) || !empty($validate_info['style plugin']); + } + + function option_definition() { + $options = parent::option_definition(); + + $options['default_action'] = array('default' => 'ignore'); + $options['style_plugin'] = array('default' => 'default_summary', 'export' => 'export_style'); + $options['style_options'] = array('default' => array(), 'export' => FALSE); + $options['wildcard'] = array('default' => 'all'); + $options['wildcard_substitution'] = array('default' => t('All'), 'translatable' => TRUE); + $options['title'] = array('default' => '', 'translatable' => TRUE); + $options['breadcrumb'] = array('default' => '', 'translatable' => TRUE); + $options['default_argument_type'] = array('default' => 'fixed', 'export' => 'export_plugin'); + $options['default_argument_options'] = array('default' => array(), 'export' => FALSE); + $options['validate_type'] = array('default' => 'none', 'export' => 'export_plugin'); + $options['validate_options'] = array('default' => array(), 'export' => FALSE); + $options['validate_fail'] = array('default' => 'not found'); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $defaults = $this->default_actions(); + + $form['title'] = array( + '#prefix' => '<div class="clearfix">', + '#suffix' => '</div>', + '#type' => 'textfield', + '#title' => t('Title'), + '#default_value' => $this->options['title'], + '#description' => t('The title to use when this argument is present. It will override the title of the view and titles from previous arguments. You can use percent substitution here to replace with argument titles. Use "%1" for the first argument, "%2" for the second, etc.'), + ); + + $form['breadcrumb'] = array( + '#prefix' => '<div class="clearfix">', + '#suffix' => '</div>', + '#type' => 'textfield', + '#title' => t('Breadcrumb'), + '#default_value' => $this->options['breadcrumb'], + '#description' => t('The Breadcrumb title to use when this argument is present. If no breadcrumb is set here, default Title values will be used, see "Title" for percent substitutions.'), + ); + + $form['clear_start'] = array( + '#markup' => '<div class="clearfix">', + ); + + $form['defaults_start'] = array( + '#markup' => '<div class="views-left-50">', + ); + + $form['default_action'] = array( + '#type' => 'radios', + '#title' => t('Action to take if argument is not present'), + '#default_value' => $this->options['default_action'], + ); + + $form['defaults_stop'] = array( + '#markup' => '</div>', + ); + + $form['wildcard'] = array( + '#prefix' => '<div class="views-right-50">', + // prefix and no suffix means these two items will be grouped together. + '#type' => 'textfield', + '#title' => t('Wildcard'), + '#size' => 20, + '#default_value' => $this->options['wildcard'], + '#description' => t('If this value is received as an argument, the argument will be ignored; i.e, "all values"'), + ); + + $form['wildcard_substitution'] = array( + '#suffix' => '</div>', + '#type' => 'textfield', + '#title' => t('Wildcard title'), + '#size' => 20, + '#default_value' => $this->options['wildcard_substitution'], + '#description' => t('The title to use for the wildcard in substitutions elsewhere.'), + ); + + $form['clear_stop'] = array( + '#markup' => '</div>', + ); + + $options = array(); + $validate_options = array(); + foreach ($defaults as $id => $info) { + $options[$id] = $info['title']; + if (empty($info['default only'])) { + $validate_options[$id] = $info['title']; + } + if (!empty($info['form method'])) { + $this->{$info['form method']}($form, $form_state); + } + } + + $form['default_action']['#options'] = $options; + + $form['validate_options_div_prefix'] = array( + '#id' => 'views-validator-options', + '#markup' => '<fieldset id="views-validator-options"><legend>' . t('Validator options') . '</legend>', + ); + + $form['validate_type'] = array( + '#type' => 'select', + '#title' => t('Validator'), + '#default_value' => $this->options['validate_type'], + ); + + $validate_types = array('none' => t('- Basic validation -')); + $plugins = views_fetch_plugin_data('argument validator'); + foreach ($plugins as $id => $info) { + if (!empty($info['no ui'])) { + continue; + } + + $valid = TRUE; + if (!empty($info['type'])) { + $valid = FALSE; + if (empty($this->definition['validate type'])) { + continue; + } + foreach ((array) $info['type'] as $type) { + if ($type == $this->definition['validate type']) { + $valid = TRUE; + break; + } + } + } + + // If we decide this validator is ok, add it to the list. + if ($valid) { + $plugin = $this->get_plugin('argument validator', $id); + if ($plugin) { + if ($plugin->access() || $this->options['validate_type'] == $id) { + $form['argument_validate'][$id] = array( + '#prefix' => '<div id="edit-options-validate-options-' . $id . '-wrapper">', + '#suffix' => '</div>', + '#type' => 'item', + '#input' => TRUE, // trick it into checking input to make #process run + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-options-validate-type' => array($id) + ), + '#id' => 'edit-options-validate-options-' . $id, + ); + $plugin->options_form($form['argument_validate'][$id], $form_state); + $validate_types[$id] = $info['title']; + } + } + } + } + + asort($validate_types); + $form['validate_type']['#options'] = $validate_types; + + $form['validate_fail'] = array( + '#type' => 'select', + '#title' => t('Action to take if argument does not validate'), + '#default_value' => $this->options['validate_fail'], + '#options' => $validate_options, + ); + + $form['validate_options_div_suffix'] = array( + '#markup' => '</fieldset>', + ); + } + + function options_validate(&$form, &$form_state) { + if (empty($form_state['values']['options'])) { + return; + } + + // Let the plugins do validation. + $default_id = $form_state['values']['options']['default_argument_type']; + $plugin = $this->get_plugin('argument default', $default_id); + if ($plugin) { + $plugin->options_validate($form['argument_default'][$default_id], $form_state, $form_state['values']['options']['argument_default'][$default_id]); + } + + $validate_id = $form_state['values']['options']['validate_type']; + $plugin = $this->get_plugin('argument validator', $validate_id); + if ($plugin) { + $plugin->options_validate($form['argument_validate'][$default_id], $form_state, $form_state['values']['options']['argument_validate'][$validate_id]); + } + + } + + function options_submit(&$form, &$form_state) { + if (empty($form_state['values']['options'])) { + return; + } + + // Let the plugins make submit modifications if necessary. + $default_id = $form_state['values']['options']['default_argument_type']; + $plugin = $this->get_plugin('argument default', $default_id); + if ($plugin) { + $options = &$form_state['values']['options']['argument_default'][$default_id]; + $plugin->options_submit($form['argument_default'][$default_id], $form_state, $options); + // Copy the now submitted options to their final resting place so they get saved. + $form_state['values']['options']['default_argument_options'] = $options; + } + + $validate_id = $form_state['values']['options']['validate_type']; + $plugin = $this->get_plugin('argument validator', $validate_id); + if ($plugin) { + $options = &$form_state['values']['options']['argument_validate'][$validate_id]; + $plugin->options_submit($form['argument_validate'][$validate_id], $form_state, $options); + // Copy the now submitted options to their final resting place so they get saved. + $form_state['values']['options']['validate_options'] = $options; + } + } + + /** + * Provide a list of default behaviors for this argument if the argument + * is not present. + * + * Override this method to provide additional (or fewer) default behaviors. + */ + function default_actions($which = NULL) { + $defaults = array( + 'ignore' => array( + 'title' => t('Display all values'), + 'method' => 'default_ignore', + 'breadcrumb' => TRUE, // generate a breadcrumb to here + ), + 'not found' => array( + 'title' => t('Hide view / Page not found (404)'), + 'method' => 'default_not_found', + 'hard fail' => TRUE, // This is a hard fail condition + ), + 'empty' => array( + 'title' => t('Display empty text'), + 'method' => 'default_empty', + 'breadcrumb' => TRUE, // generate a breadcrumb to here + ), + 'summary asc' => array( + 'title' => t('Summary, sorted ascending'), + 'method' => 'default_summary', + 'method args' => array('asc'), + 'style plugin' => TRUE, + 'breadcrumb' => TRUE, // generate a breadcrumb to here + ), + 'summary desc' => array( + 'title' => t('Summary, sorted descending'), + 'method' => 'default_summary', + 'method args' => array('desc'), + 'style plugin' => TRUE, + 'breadcrumb' => TRUE, // generate a breadcrumb to here + ), + 'summary asc by count' => array( + 'title' => t('Summary, sorted by number of records ascending'), + 'method' => 'default_summary', + 'method args' => array('asc', 'num_records'), + 'style plugin' => TRUE, + 'breadcrumb' => TRUE, // generate a breadcrumb to here + ), + 'summary desc by count' => array( + 'title' => t('Summary, sorted by number of records descending'), + 'method' => 'default_summary', + 'method args' => array('desc', 'num_records'), + 'style plugin' => TRUE, + 'breadcrumb' => TRUE, // generate a breadcrumb to here + ), + 'default' => array( + 'title' => t('Provide default argument'), + 'method' => 'default_default', + 'form method' => 'default_argument_form', + 'has default argument' => TRUE, + 'default only' => TRUE, // this can only be used for missing argument, not validation failure + ), + ); + + if ($which) { + if (!empty($defaults[$which])) { + return $defaults[$which]; + } + } + else { + return $defaults; + } + } + + /** + * Provide a form for selecting the default argument when the + * default action is set to provide default argument. + */ + function default_argument_form(&$form, &$form_state) { + $plugins = views_fetch_plugin_data('argument default'); + $options = array(); + + // This construct uses 'hidden' and not markup because process doesn't + // run. It also has an extra div because the dependency wants to hide + // the parent in situations like this, so we need a second div to + // make this work. + $form['default_options_div_prefix'] = array( + '#type' => 'hidden', + '#id' => 'views-default-options', + '#prefix' => '<div id="views-default-options-wrapper"><fieldset id="views-default-options"><legend>' . t('Provide default argument options') . '</legend>', + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:options[default_action]' => array('default')), + ); + + $form['default_argument_type'] = array( + '#prefix' => '<div id="edit-options-default-argument-type-wrapper">', + '#suffix' => '</div>', + '#type' => 'radios', + '#id' => 'edit-options-default-argument-type', + '#title' => t('Default argument type'), + '#default_value' => $this->options['default_argument_type'], + ); + + foreach ($plugins as $id => $info) { + if (!empty($info['no ui'])) { + continue; + } + $plugin = $this->get_plugin('argument default', $id); + if ($plugin) { + if ($plugin->access() || $this->options['default_argument_type'] == $id) { + $form['argument_default'][$id] = array( + '#prefix' => '<div id="edit-options-argument-default-options-' . $id . '-wrapper">', + '#suffix' => '</div>', + '#id' => 'edit-options-argument-default-options-' . $id, + '#type' => 'item', + '#input' => TRUE, // trick it into checking input to make #process run + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'radio:options[default_action]' => array('default'), + 'radio:options[default_argument_type]' => array($id) + ), + '#dependency_count' => 2, + ); + $options[$id] = $info['title']; + $plugin->options_form($form['argument_default'][$id], $form_state); + } + } + } + + $form['default_options_div_suffix'] = array( + '#markup' => '</fieldset></div>', + ); + + asort($options); + $form['default_argument_type']['#options'] = $options; + } + + /** + * Handle the default action, which means our argument wasn't present. + * + * Override this method only with extreme care. + * + * @return + * A boolean value; if TRUE, continue building this view. If FALSE, + * building the view will be aborted here. + */ + function default_action($info = NULL) { + if (!isset($info)) { + $info = $this->default_actions($this->options['default_action']); + } + + if (!$info) { + return FALSE; + } + + if (!empty($info['method args'])) { + return call_user_func_array(array(&$this, $info['method']), $info['method args']); + } + else { + return $this->{$info['method']}(); + } + } + + /** + * How to act if validation failes + */ + function validate_fail() { + $info = $this->default_actions($this->options['validate_fail']); + return $this->default_action($info); + } + /** + * Default action: ignore. + * + * If an argument was expected and was not given, in this case, simply + * ignore the argument entirely. + */ + function default_ignore() { + return TRUE; + } + + /** + * Default action: not found. + * + * If an argument was expected and was not given, in this case, report + * the view as 'not found' or hide it. + */ + function default_not_found() { + // Set a failure condition and let the display manager handle it. + $this->view->build_info['fail'] = TRUE; + return FALSE; + } + + /** + * Default action: empty + * + * If an argument was expected and was not given, in this case, display + * the view's empty text + */ + function default_empty() { + // We return with no query; this will force the empty text. + $this->view->built = TRUE; + $this->view->executed = TRUE; + $this->view->result = array(); + return FALSE; + } + + /** + * This just returns true. The view argument builder will know where + * to find the argument from. + */ + function default_default() { + return TRUE; + } + + /** + * Determine if the argument is set to provide a default argument. + */ + function has_default_argument() { + $info = $this->default_actions($this->options['default_action']); + return !empty($info['has default argument']); + } + + /** + * Get a default argument, if available. + */ + function get_default_argument() { + $plugin = $this->get_plugin('argument default'); + if ($plugin) { + return $plugin->get_argument(); + } + } + + /** + * Default action: summary. + * + * If an argument was expected and was not given, in this case, display + * a summary query. + */ + function default_summary($order, $by = NULL) { + $this->view->build_info['summary'] = TRUE; + $this->view->build_info['summary_level'] = $this->options['id']; + + // Change the display style to the summary style for this + // argument. + $this->view->plugin_name = $this->options['style_plugin']; + $this->view->style_options = $this->options['style_options']; + + // Clear out the normal primary field and whatever else may have + // been added and let the summary do the work. + $this->query->clear_fields(); + $this->summary_query(); + + $this->summary_sort($order, $by); + + // Summaries have their own sorting and fields, so tell the View not + // to build these. + $this->view->build_sort = $this->view->build_fields = FALSE; + return TRUE; + } + + /** + * Build the info for the summary query. + * + * This must: + * - add_groupby: group on this field in order to create summaries. + * - add_field: add a 'num_nodes' field for the count. Usually it will + * be a count on $view->base_field + * - set_count_field: Reset the count field so we get the right paging. + * + * @return + * The alias used to get the number of records (count) for this entry. + */ + function summary_query() { + $this->ensure_my_table(); + // Add the field. + $this->base_alias = $this->query->add_field($this->table_alias, $this->real_field); + + $this->summary_name_field(); + return $this->summary_basics(); + } + + /** + * Add the name field, which is the field displayed in summary queries. + * This is often used when the argument is numeric. + */ + function summary_name_field() { + // Add the 'name' field. For example, if this is a uid argument, the + // name field would be 'name' (i.e, the username). + + if (isset($this->name_table)) { + // if the alias is different then we're probably added, not ensured, + // so look up the join and add it instead. + if ($this->table_alias != $this->table) { + $j = views_get_table_join($this->name_table, $this->table); + if ($j) { + $join = clone $j; + $join->left_table = $this->table_alias; + $this->name_table_alias = $this->query->add_table($this->name_table, $this->relationship, $join); + } + } + else { + $this->name_table_alias = $this->query->ensure_table($this->name_table, $this->relationship); + } + } + else { + $this->name_table_alias = $this->table_alias; + } + + if (isset($this->name_field)) { + $this->name_alias = $this->query->add_field($this->name_table_alias, $this->name_field); + } + else { + $this->name_alias = $this->base_alias; + } + } + + /** + * Some basic summary behavior that doesn't need to be repeated as much as + * code that goes into summary_query() + */ + function summary_basics($count_field = TRUE) { + // Add the number of nodes counter + $distinct = ($this->view->display_handler->get_option('distinct') && empty($this->query->no_distinct)); + + $count_alias = $this->query->add_field($this->query->base_table, $this->query->base_field, 'num_records', + array('count' => TRUE, 'distinct' => $distinct)); + $this->query->add_groupby($this->name_alias); + + if ($count_field) { + $this->query->set_count_field($this->table_alias, $this->real_field); + } + + $this->count_alias = $count_alias; + } + + /** + * Sorts the summary based upon the user's selection. The base variant of + * this is usually adequte. + * + * @param $order + * The order selected in the UI. + */ + function summary_sort($order, $by = NULL) { + $this->query->add_orderby(NULL, NULL, $order, (!empty($by) ? $by : $this->name_alias)); + } + + /** + * Provide the argument to use to link from the summary to the next level; + * this will be called once per row of a summary, and used as part of + * $view->get_url(). + * + * @param $data + * The query results for the row. + */ + function summary_argument($data) { + return $data->{$this->base_alias}; + } + + /** + * Provides the name to use for the summary. By default this is just + * the name field. + * + * @param $data + * The query results for the row. + */ + function summary_name($data) { + $value = $data->{$this->name_alias}; + if (empty($value) && !empty($this->definition['empty field name'])) { + $value = $this->definition['empty field name']; + } + return check_plain($value); + } + + /** + * Set up the query for this argument. + * + * The argument sent may be found at $this->argument. + */ + function query() { + $this->ensure_my_table(); + $this->query->add_where(0, "$this->table_alias.$this->real_field", $this->argument); + } + + /** + * Get the title this argument will assign the view, given the argument. + * + * This usually needs to be overridden to provide a proper title. + */ + function title() { + return check_plain($this->argument); + } + + /** + * Called by the view object to get the title. This may be set by a + * validator so we don't necessarily call through to title(). + */ + function get_title() { + if (isset($this->validated_title)) { + return $this->validated_title; + } + else { + return $this->title(); + } + } + + /** + * Validate that this argument works. By default, all arguments are valid. + */ + function validate_arg($arg) { + // By using % in URLs, arguments could be validated twice; this eases + // that pain. + if (isset($this->argument_validated)) { + return $this->argument_validated; + } + + if ($this->is_wildcard($arg)) { + return $this->argument_validated = TRUE; + } + + if ($this->options['validate_type'] == 'none') { + return $this->argument_validated = $this->validate_argument_basic($arg); + } + + $plugin = $this->get_plugin('argument validator'); + if ($plugin) { + return $this->argument_validated = $plugin->validate_argument($arg); + } + + // If the plugin isn't found, fall back to the basic validation path: + return $this->argument_validated = $this->validate_argument_basic($arg); + } + + /** + * Called by the menu system to validate an argument. + * + * This checks to see if this is a 'soft fail', which means that if the + * argument fails to validate, but there is an action to take anyway, + * then validation cannot actually fail. + */ + function validate_argument($arg) { + $validate_info = $this->default_actions($this->options['validate_fail']); + if (empty($validate_info['hard fail'])) { + return TRUE; + } + + $rc = $this->validate_arg($arg); + + // If the validator has changed the validate fail condition to a + // soft fail, deal with that: + $validate_info = $this->default_actions($this->options['validate_fail']); + if (empty($validate_info['hard fail'])) { + return TRUE; + } + + return $rc; + } + + /** + * Provide a basic argument validation. + * + * This can be overridden for more complex types; the basic + * validator only checks to see if the argument is not NULL + * or is numeric if the definition says it's numeric. + */ + function validate_argument_basic($arg) { + if (!isset($arg) || $arg === '') { + return FALSE; + } + + if (!empty($this->definition['numeric']) && !isset($this->options['break_phrase']) && !is_numeric($arg)) { + return FALSE; + } + + return TRUE; + } + + /** + * Set the input for this argument + * + * @return TRUE if it successfully validates; FALSE if it does not. + */ + function set_argument($arg) { + $this->argument = $arg; + return $this->validate_arg($arg); + } + + /** + * Get the value of this argument. + */ + function get_value() { + // If we already processed this argument, we're done. + if (isset($this->argument)) { + return $this->argument; + } + + // Otherwise, we have to pretend to process ourself to find the value. + $value = NULL; + // Find the position of this argument within the view. + $position = 0; + foreach ($this->view->argument as $id => $argument) { + if ($id == $this->options['id']) { + break; + } + $position++; + } + + $arg = isset($this->view->args[$position]) ? $this->view->args[$position] : NULL; + $this->position = $position; + + // Clone ourselves so that we don't break things when we're really + // processing the arguments. + $argument = clone $this; + if (!isset($arg) && $argument->has_default_argument()) { + $arg = $argument->get_default_argument(); + } + // Set the argument, which will also validate that the argument can be set. + if ($argument->set_argument($arg)) { + $value = $argument->argument; + } + unset($argument); + return $value; + } + + /** + * Special handling for the style export. + * + * Arguments can have styles for the summary view. This special export + * handler makes sure this works properly. + */ + function export_style($indent, $prefix, $storage, $option, $definition, $parents) { + $output = ''; + $name = $storage[$option]; + $options = $storage['style_options']; + + $plugin = views_get_plugin('style', $name); + if ($plugin) { + $plugin->init($this->view, $this->display, $options); + // Write which plugin to use. + $output .= $indent . $prefix . "['$option'] = '$name';\n"; + + // Pass off to the plugin to export itself. + $output .= $plugin->export_options($indent, $prefix . "['style_options']"); + } + + return $output; + } + + /** + * Special handling for the style export. + * + * Arguments can have styles for the summary view. This special export + * handler makes sure this works properly. + */ + function export_plugin($indent, $prefix, $storage, $option, $definition, $parents) { + $output = ''; + if ($option == 'default_argument_type') { + $type = 'argument default'; + $option_name = 'default_argument_options'; + } + else { + $type = 'argument validator'; + $option_name = 'validate_options'; + } + $plugin = $this->get_plugin($type); + $name = $this->options[$option]; + + if ($plugin) { + // Write which plugin to use. + $output .= $indent . $prefix . "['$option'] = '$name';\n"; + + // Pass off to the plugin to export itself. + $output .= $plugin->export_options($indent, $prefix . "['$option_name']"); + } + + return $output; + } + + /** + * Get the display or row plugin, if it exists. + */ + function get_plugin($type = 'argument default', $name = NULL) { + $options = array(); + switch ($type) { + case 'argument default': + $plugin_name = 'default_argument_type'; + $options_name = 'default_argument_options'; + break; + case 'argument validator': + $plugin_name = 'validate_type'; + $options_name = 'validate_options'; + } + + if (!$name) { + $name = $this->options[$plugin_name]; + } + + // we only fetch the options if we're fetching the plugin actually + // in use. + if ($name == $this->options[$plugin_name]) { + $options = $this->options[$options_name]; + } + + $plugin = views_get_plugin($type, $name); + if ($plugin) { + $plugin->init($this->view, $this, $options); + return $plugin; + } + } +} + +/** + * A special handler to take the place of missing or broken handlers. + * + * @ingroup views_argument_handlers + */ +class views_handler_argument_broken extends views_handler_argument { + function ui_name($short = FALSE) { + return t('Broken/missing handler'); + } + + function ensure_my_table() { /* No table to ensure! */ } + function query() { /* No query to run */ } + function options_form(&$form, &$form_state) { + $form['markup'] = array( + '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>', + ); + } + + /** + * Determine if the handler is considered 'broken' + */ + function broken() { return TRUE; } +} + +/** + * @} + */ diff --git a/sites/all/modules/views/handlers/views_handler_argument_date.inc b/sites/all/modules/views/handlers/views_handler_argument_date.inc new file mode 100644 index 0000000000000000000000000000000000000000..d987c65e8af3ec1b39e6e6107287e9fe512657fe --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_argument_date.inc @@ -0,0 +1,67 @@ +<?php +// $Id: views_handler_argument_date.inc,v 1.3.6.3 2010/03/11 08:30:24 dereine Exp $ +/** + * Abstract argument handler for dates. + * + * Adds an option to set a default argument based on the current date. + * + * @param $arg_format + * The format string to use on the current time when + * creating a default date argument. + * + * Definitions terms: + * - many to one: If true, the "many to one" helper will be used. + * - invalid input: A string to give to the user for obviously invalid input. + * This is deprecated in favor of argument validators. + * @see views_many_to_one_helper + * + * @ingroup views_argument_handlers + */ +class views_handler_argument_date extends views_handler_argument_formula { + var $option_name = 'default_argument_date'; + var $arg_format = 'Y-m-d'; + + /** + * Add an option to set the default value to the current date. + */ + function default_argument_form(&$form, &$form_state) { + parent::default_argument_form($form, $form_state); + $form['default_argument_type']['#options'] += array('date' => t('Current date')); + $form['default_argument_type']['#options'] += array('node_created' => t("Current node's creation time")); + $form['default_argument_type']['#options'] += array('node_changed' => t("Current node's update time")); } + + /** + * Set the empty argument value to the current date, + * formatted appropriately for this argument. + */ + function get_default_argument($raw = FALSE) { + if (!$raw && $this->options['default_argument_type'] == 'date') { + return date($this->arg_format, REQUEST_TIME); + } + else if (!$raw && in_array($this->options['default_argument_type'], array('node_created', 'node_changed'))) { + foreach (range(1, 3) as $i) { + $node = menu_get_object('node', $i); + if (!empty($node)) { + continue; + } + } + + if (arg(0) == 'node' && is_numeric(arg(1))) { + $node = node_load(arg(1)); + } + + if (empty($node)) { + return parent::get_default_argument(); + } + elseif ($this->options['default_argument_type'] == 'node_created') { + return date($this->arg_format, $node->created); + } + elseif ($this->options['default_argument_type'] == 'node_changed') { + return date($this->arg_format, $node->changed); + } + } + + return parent::get_default_argument($raw); + + } +} diff --git a/sites/all/modules/views/handlers/views_handler_argument_formula.inc b/sites/all/modules/views/handlers/views_handler_argument_formula.inc new file mode 100644 index 0000000000000000000000000000000000000000..18960f90adf44c2abdf08fb022be85e7d276caba --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_argument_formula.inc @@ -0,0 +1,58 @@ +<?php +// $Id: views_handler_argument_formula.inc,v 1.1.6.3 2011/01/03 17:46:33 dereine Exp $ +/** + * Abstract argument handler for simple formulae. + * + * Child classes of this object should implement summary_argument, at least. + * + * Definition terms: + * - formula: The formula to use for this handler. + * + * @ingroup views_argument_handlers + */ +class views_handler_argument_formula extends views_handler_argument { + var $formula = NULL; + /** + * Constructor + */ + function construct() { + parent::construct(); + + if (!empty($this->definition['formula'])) { + $this->formula = $this->definition['formula']; + } + } + + function get_formula() { + return str_replace('***table***', $this->table_alias, $this->formula); + } + + /** + * Build the summary query based on a formula + */ + function summary_query() { + $this->ensure_my_table(); + // Now that our table is secure, get our formula. + $formula = $this->get_formula(); + + // Add the field. + $this->base_alias = $this->name_alias = $this->query->add_field(NULL, $formula, $this->field); + $this->query->set_count_field(NULL, $formula, $this->field); + + return $this->summary_basics(FALSE); + } + + /** + * Build the query based upon the formula + */ + function query() { + $this->ensure_my_table(); + // Now that our table is secure, get our formula. + $placeholder = $this->placeholder(); + $formula = $this->get_formula() .' = ' . $placeholder; + $placeholders = array( + $placeholder => $this->argument, + ); + $this->query->add_where(0, $formula, $placeholders, 'formula'); + } +} diff --git a/sites/all/modules/views/handlers/views_handler_argument_group_by_numeric.inc b/sites/all/modules/views/handlers/views_handler_argument_group_by_numeric.inc new file mode 100644 index 0000000000000000000000000000000000000000..c5a7da6c5cc1fe33913c37063bd9dbc5c09c5bf8 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_argument_group_by_numeric.inc @@ -0,0 +1,18 @@ +<?php +// $Id: views_handler_argument_group_by_numeric.inc,v 1.1.4.2 2010/01/24 22:37:52 dereine Exp $ + +/** + * Simple handler for arguments using group by. + */ +class views_handler_argument_group_by_numeric extends views_handler_argument { + function query($group_by = FALSE) { + $this->ensure_my_table(); + $field = $this->get_field(); + + $this->query->add_having(0, $field, $this->argument); + } + + function ui_name() { + return $this->get_field(parent::ui_name()); + } +} diff --git a/sites/all/modules/views/handlers/views_handler_argument_many_to_one.inc b/sites/all/modules/views/handlers/views_handler_argument_many_to_one.inc new file mode 100644 index 0000000000000000000000000000000000000000..e2346c4f378deb8fadd0c5f45124f1aa7ebe1c6f --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_argument_many_to_one.inc @@ -0,0 +1,171 @@ +<?php +// $Id: views_handler_argument_many_to_one.inc,v 1.1.6.3 2010/03/22 20:40:31 merlinofchaos Exp $ +/** + * An argument handler for use in fields that have a many to one relationship + * with the table(s) to the left. This adds a bunch of options that are + * reasonably common with this type of relationship. + * Definition terms: + * - numeric: If true, the field will be considered numeric. Probably should + * always be set TRUE as views_handler_argument_string has many to one + * capabilities. + * - zero is null: If true, a 0 will be handled as empty, so for example + * a default argument can be provided or a summary can be shown. + * + * @ingroup views_argument_handlers + */ +class views_handler_argument_many_to_one extends views_handler_argument { + function init(&$view, &$options) { + parent::init($view, $options); + $this->helper = new views_many_to_one_helper($this); + + // Ensure defaults for these, during summaries and stuff: + $this->operator = 'or'; + $this->value = array(); + } + + function option_definition() { + $options = parent::option_definition(); + + if (!empty($this->definition['numeric'])) { + $options['break_phrase'] = array('default' => FALSE); + } + + $options['add_table'] = array('default' => FALSE); + $options['require_value'] = array('default' => FALSE); + + views_many_to_one_helper::option_definition($options); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + // allow + for or, , for and + if (!empty($this->definition['numeric'])) { + $form['break_phrase'] = array( + '#type' => 'checkbox', + '#title' => t('Allow multiple terms per argument.'), + '#description' => t('If selected, users can enter multiple arguments in the form of 1+2+3 (for OR) or 1,2,3 (for AND).'), + '#default_value' => !empty($this->options['break_phrase']), + ); + } + + $form['add_table'] = array( + '#type' => 'checkbox', + '#title' => t('Allow multiple arguments to work together.'), + '#description' => t('If selected, multiple instances of this argument can work together, as though multiple terms were supplied to the same argument. This setting is not compatible with the "Reduce duplicates" setting.'), + '#default_value' => !empty($this->options['add_table']), + ); + + $form['require_value'] = array( + '#type' => 'checkbox', + '#title' => t('Do not display items with no value in summary'), + '#default_value' => !empty($this->options['require_value']), + ); + + $this->helper->options_form($form, $form_state); + } + + /** + * Override ensure_my_table so we can control how this joins in. + * The operator actually has influence over joining. + */ + function ensure_my_table() { + $this->helper->ensure_my_table(); + } + + function query() { + $empty = FALSE; + if (isset($this->definition['zero is null']) && $this->definition['zero is null']) { + if (empty($this->argument)) { + $empty = TRUE; + } + } + else { + if (!isset($this->argument)) { + $empty = TRUE; + } + } + if ($empty) { + parent::ensure_my_table(); + $this->query->add_where(0, "$this->table_alias.$this->real_field", NULL, 'IS NULL'); + return; + } + + if (!empty($this->options['break_phrase'])) { + views_break_phrase($this->argument, $this); + } + else { + $this->value = array($this->argument); + $this->operator = 'or'; + } + + $this->helper->add_filter(); + } + + function title() { + if (!$this->argument) { + return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : t('Uncategorized'); + } + + if (!empty($this->options['break_phrase'])) { + views_break_phrase($this->argument, $this); + } + else { + $this->value = array($this->argument); + $this->operator = 'or'; + } + + // @todo -- both of these should check definition for alternate keywords. + + if (empty($this->value)) { + return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : t('Uncategorized'); + } + + if ($this->value === array(-1)) { + return !empty($this->definition['invalid input']) ? $this->definition['invalid input'] : t('Invalid input'); + } + + return implode($this->operator == 'or' ? ' + ' : ', ', $this->title_query()); + } + + function summary_query() { + $field = $this->table . '.' . $this->field; + $join = $this->get_join(); + + if (!empty($this->options['require_value'])) { + $join->type = 'INNER'; + } + + if (empty($this->options['add_table']) || empty($this->view->many_to_one_tables[$field])) { + $this->table_alias = $this->query->ensure_table($this->table, $this->relationship, $join); + } + else { + $this->table_alias = $this->helper->summary_join(); + } + + // Add the field. + $this->base_alias = $this->query->add_field($this->table_alias, $this->real_field); + + $this->summary_name_field(); + + return $this->summary_basics(); + } + + function summary_argument($data) { + $value = $data->{$this->base_alias}; + if (empty($value)) { + $value = 0; + } + + return $value; + } + + /** + * Override for specific title lookups. + */ + function title_query() { + return $this->value; + } +} + diff --git a/sites/all/modules/views/handlers/views_handler_argument_null.inc b/sites/all/modules/views/handlers/views_handler_argument_null.inc new file mode 100644 index 0000000000000000000000000000000000000000..884e5578cabccd39ede4903707f6f27ba9893c7c --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_argument_null.inc @@ -0,0 +1,60 @@ +<?php +// $Id: views_handler_argument_null.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos Exp $ +/** + * Argument handler that ignores the argument. + */ +class views_handler_argument_null extends views_handler_argument { + function option_definition() { + $options = parent::option_definition(); + $options['must_not_be'] = array('default' => FALSE); + return $options; + } + + /** + * Override options_form() so that only the relevant options + * are displayed to the user. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['must_not_be'] = array( + '#type' => 'checkbox', + '#title' => t('Fail basic validation if any argument is given'), + '#default_value' => !empty($this->options['must_not_be']), + '#description' => t('By checking this field, you can use this to make sure views with more arguments than necessary fail validation.'), + ); + + unset($form['wildcard']); + unset($form['wildcard_substitution']); + } + + /** + * Override default_actions() to remove actions that don't + * make sense for a null argument. + */ + function default_actions($which = NULL) { + if ($which) { + if (in_array($which, array('ignore', 'not found', 'empty', 'default'))) { + return parent::default_actions($which); + } + return; + } + $actions = parent::default_actions(); + unset($actions['summary asc']); + unset($actions['summary desc']); + return $actions; + } + + function validate_argument_basic($arg) { + if (!empty($this->options['must_not_be'])) { + return !isset($arg); + } + + return parent::validate_argument_basic($arg); + } + + /** + * Override the behavior of query() to prevent the query + * from being changed in any way. + */ + function query() {} +} diff --git a/sites/all/modules/views/handlers/views_handler_argument_numeric.inc b/sites/all/modules/views/handlers/views_handler_argument_numeric.inc new file mode 100644 index 0000000000000000000000000000000000000000..6d5d7851c5007379598d85eafd520ea65b11e778 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_argument_numeric.inc @@ -0,0 +1,94 @@ +<?php +// $Id: views_handler_argument_numeric.inc,v 1.1.6.1 2009/11/02 22:01:25 merlinofchaos Exp $ +/** + * @file + * Contains the numeric argument handler. + */ + +/** + * Basic argument handler for arguments that are numeric. Incorporates + * break_phrase. + * + * @ingroup views_argument_handlers + */ +class views_handler_argument_numeric extends views_handler_argument { + function option_definition() { + $options = parent::option_definition(); + + $options['break_phrase'] = array('default' => FALSE); + $options['not'] = array('default' => FALSE); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + // allow + for or, , for and + $form['break_phrase'] = array( + '#type' => 'checkbox', + '#title' => t('Allow multiple terms per argument.'), + '#description' => t('If selected, users can enter multiple arguments in the form of 1+2+3 or 1,2,3.'), + '#default_value' => !empty($this->options['break_phrase']), + ); + + $form['not'] = array( + '#type' => 'checkbox', + '#title' => t('Exclude the argument'), + '#description' => t('If selected, the numbers entered in the argument will be excluded rather than limiting the view.'), + '#default_value' => !empty($this->options['not']), + ); + } + + function title() { + if (!$this->argument) { + return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : t('Uncategorized'); + } + + if (!empty($this->options['break_phrase'])) { + views_break_phrase($this->argument, $this); + } + else { + $this->value = array($this->argument); + $this->operator = 'or'; + } + + if (empty($this->value)) { + return !empty($this->definition['empty field name']) ? $this->definition['empty field name'] : t('Uncategorized'); + } + + if ($this->value === array(-1)) { + return !empty($this->definition['invalid input']) ? $this->definition['invalid input'] : t('Invalid input'); + } + + return implode($this->operator == 'or' ? ' + ' : ', ', $this->title_query()); + } + + /** + * Override for specific title lookups. + */ + function title_query() { + return $this->value; + } + + function query() { + $this->ensure_my_table(); + + if (!empty($this->options['break_phrase'])) { + views_break_phrase($this->argument, $this); + } + else { + $this->value = array($this->argument); + } + + if (count($this->value) > 1) { + $operator = empty($this->options['not']) ? 'IN' : 'NOT IN'; + $placeholders = implode(', ', array_fill(0, sizeof($this->value), '%d')); + $this->query->add_where(0, "$this->table_alias.$this->real_field", $this->value, $operator); + } + else { + $operator = empty($this->options['not']) ? '=' : '!='; + $this->query->add_where(0, "$this->table_alias.$this->real_field", $this->argument, $operator); + } + } +} diff --git a/sites/all/modules/views/handlers/views_handler_argument_string.inc b/sites/all/modules/views/handlers/views_handler_argument_string.inc new file mode 100644 index 0000000000000000000000000000000000000000..ce95473ca35d767de822d55d60006ab49c314a02 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_argument_string.inc @@ -0,0 +1,240 @@ +<?php +// $Id: views_handler_argument_string.inc,v 1.5.4.7 2011/01/05 22:40:08 dereine Exp $ + +/** + * Basic argument handler to implement string arguments that may have length + * limits. + * + * @ingroup views_argument_handlers + */ +class views_handler_argument_string extends views_handler_argument { + function init(&$view, &$options) { + parent::init($view, $options); + if (!empty($this->definition['many to one'])) { + $this->helper = new views_many_to_one_helper($this); + + // Ensure defaults for these, during summaries and stuff: + $this->operator = 'or'; + $this->value = array(); + } + } + + function option_definition() { + $options = parent::option_definition(); + + $options['glossary'] = array('default' => FALSE); + $options['limit'] = array('default' => 0); + $options['case'] = array('default' => 'none'); + $options['path_case'] = array('default' => 'none'); + $options['transform_dash'] = array('default' => FALSE); + + if (!empty($this->definition['many to one'])) { + $options['add_table'] = array('default' => FALSE); + $options['require_value'] = array('default' => FALSE); + } + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $form['glossary'] = array( + '#type' => 'checkbox', + '#title' => t('Glossary mode'), + '#description' => t('Glossary mode applies a limit to the number of characters used in the argument, which allows the summary view to act as a glossary.'), + '#default_value' => $this->options['glossary'], + ); + + $form['limit'] = array( + '#type' => 'textfield', + '#title' => t('Character limit'), + '#description' => t('How many characters of the argument to filter against. If set to 1, all fields starting with the letter in the argument would be matched.'), + '#default_value' => $this->options['limit'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-options-glossary' => array(TRUE)), + ); + + $form['case'] = array( + '#type' => 'select', + '#title' => t('Case'), + '#description' => t('When printing the argument result, how to transform the case.'), + '#options' => array( + 'none' => t('No transform'), + 'upper' => t('Upper case'), + 'lower' => t('Lower case'), + 'ucfirst' => t('Capitalize first letter'), + 'ucwords' => t('Capitalize each word'), + ), + '#default_value' => $this->options['case'], + ); + + $form['path_case'] = array( + '#type' => 'select', + '#title' => t('Case in path'), + '#description' => t('When printing url paths, how to transform the case of the argument. Do not use this unless with Postgres as it uses case sensitive comparisons.'), + '#options' => array( + 'none' => t('No transform'), + 'upper' => t('Upper case'), + 'lower' => t('Lower case'), + 'ucfirst' => t('Capitalize first letter'), + 'ucwords' => t('Capitalize each word'), + ), + '#default_value' => $this->options['path_case'], + ); + + $form['transform_dash'] = array( + '#type' => 'checkbox', + '#title' => t('Transform spaces to dashes in URL'), + '#default_value' => $this->options['transform_dash'], + ); + + if (!empty($this->definition['many to one'])) { + $form['add_table'] = array( + '#type' => 'checkbox', + '#title' => t('Allow multiple arguments to work together.'), + '#description' => t('If selected, multiple instances of this argument can work together, as though multiple terms were supplied to the same argument. This setting is not compatible with the "Reduce duplicates" setting.'), + '#default_value' => !empty($this->options['add_table']), + ); + + $form['require_value'] = array( + '#type' => 'checkbox', + '#title' => t('Do not display items with no value in summary'), + '#default_value' => !empty($this->options['require_value']), + ); + } + } + + /** + * Build the summary query based on a string + */ + function summary_query() { + if (empty($this->definition['many to one'])) { + $this->ensure_my_table(); + } + else { + $this->table_alias = $this->helper->summary_join(); + } + + if (empty($this->options['glossary'])) { + // Add the field. + $this->base_alias = $this->name_alias = $this->query->add_field($this->table_alias, $this->real_field); + $this->query->set_count_field($this->table_alias, $this->real_field); + } + else { + // Add the field. + $formula = $this->get_formula(); + $placeholder_length = $this->placeholder_length; + $params = array( + 'placeholders' => array( + $placeholder_length => intval($this->options['limit']), + ), + ); + + $this->base_alias = $this->name_alias = $this->query->add_field(NULL, $formula, $this->field . '_truncated', $params); + $this->query->set_count_field(NULL, $formula, $this->field, $this->field . '_truncated'); + } + + return $this->summary_basics(FALSE); + } + + /** + * Get the formula for this argument. + * + * $this->ensure_my_table() MUST have been called prior to this. + */ + function get_formula() { + return "SUBSTRING($this->table_alias.$this->real_field, 1, $this->placeholder_length)"; + } + + /** + * Build the query based upon the formula + */ + function query() { + $argument = $this->argument; + if (!empty($this->options['transform_dash'])) { + $argument = strtr($argument, '-', ' '); + } + $this->placeholder_length = $this->placeholder(); + + if (!empty($this->definition['many to one'])) { + if (!empty($this->options['glossary'])) { + $this->helper->formula = TRUE; + } + $this->value = array($argument); + $this->helper->ensure_my_table(); + + $this->helper->placeholders = array($this->placeholder_length => intval($this->options['limit'])); + $this->helper->add_filter(); + return; + } + + $this->ensure_my_table(); + $formula = FALSE; + if (empty($this->options['glossary'])) { + $field = "$this->table_alias.$this->real_field"; + } + else { + $formula = TRUE; + $field = $this->get_formula(); + } + + if ($formula) { + $placeholder = $this->placeholder(); + $placeholder_length = $this->placeholder_length; + $field .= ' = ' . $placeholder; + $placeholders = array( + $placeholder_length => intval($this->options['limit']), + $placeholder => $argument, + ); + $this->query->add_where_expression(0, $field, $placeholders); + } + else { + $this->query->add_where(0, $field, $argument); + } + } + + function summary_argument($data) { + $value = $this->case_transform($data->{$this->base_alias}, 'path_case'); + if (!empty($this->options['transform_dash'])) { + $value = strtr($value, ' ', '-'); + } + return $value; + } + + function case_transform($string, $option) { + global $multibyte; + + switch ($this->options[$option]) { + default: + return $string; + case 'upper': + return drupal_strtoupper($string); + case 'lower': + return drupal_strtolower($string); + case 'ucfirst': + return drupal_strtoupper(drupal_substr($string, 0, 1)) . drupal_substr($string, 1); + case 'ucwords': + if ($multibyte == UNICODE_MULTIBYTE) { + return mb_convert_case($string, MB_CASE_TITLE); + } else { + return ucwords($string); + } + } + } + + function title() { + $title = $this->case_transform($this->argument, 'case'); + if (!empty($this->options['transform_dash'])) { + $title = strtr($title, '-', ' '); + } + + return check_plain($title); + } + + function summary_name($data) { + return $this->case_transform(parent::summary_name($data), 'case'); + } + +} + diff --git a/sites/all/modules/views/handlers/views_handler_field.inc b/sites/all/modules/views/handlers/views_handler_field.inc new file mode 100644 index 0000000000000000000000000000000000000000..f514d94dbc74780b5bb4db7072e6cad538b5d85c --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_field.inc @@ -0,0 +1,1112 @@ +<?php +// $Id: views_handler_field.inc,v 1.33.4.44 2010/12/23 22:38:54 dereine Exp $ +/** + * @defgroup views_field_handlers Views' field handlers + * @{ + * Handlers to tell Views how to build and display fields. + * + */ + +/** + * Base field handler that has no options and renders an unformatted field. + * + * Definition terms: + * - additional fields: An array of fields that should be added to the query + * for some purpose. The array is in the form of: + * array('identifier' => array('table' => tablename, + * 'field' => fieldname); as many fields as are necessary + * may be in this array. + * - click sortable: If TRUE, this field may be click sorted. + */ +class views_handler_field extends views_handler { + var $field_alias = 'unknown'; + var $aliases = array(); + + /** + * Construct a new field handler. + */ + function construct() { + parent::construct(); + + $this->additional_fields = array(); + if (!empty($this->definition['additional fields'])) { + $this->additional_fields = $this->definition['additional fields']; + } + + if (!isset($this->options['exclude'])) { + $this->options['exclude'] = ''; + } + } + + /** + * Determine if this field can allow advanced rendering. + * + * Fields can set this to FALSE if they do not wish to allow + * token based rewriting or link-making. + */ + function allow_advanced_render() { + return TRUE; + } + + function init(&$view, &$options) { + parent::init($view, $options); + + $this->options += array( + 'exclude' => FALSE, + ); + } + + /** + * Called to add the field to a query. + */ + function query() { + $this->ensure_my_table(); + // Add the field. + $this->field_alias = $this->query->add_field($this->table_alias, $this->real_field); + + $this->add_additional_fields(); + } + + /** + * Add 'additional' fields to the query. + * + * @param $fields + * An array of fields. The key is an identifier used to later find the + * field alias used. The value is either a string in which case it's + * assumed to be a field on this handler's table; or it's an array in the + * form of + * @code array('table' => $tablename, 'field' => $fieldname) @endcode + */ + function add_additional_fields($fields = NULL) { + if (!isset($fields)) { + // notice check + if (empty($this->additional_fields)) { + return; + } + $fields = $this->additional_fields; + } + if (!empty($fields) && is_array($fields)) { + foreach ($fields as $identifier => $info) { + if (is_array($info)) { + if (isset($info['table'])) { + $table_alias = $this->query->ensure_table($info['table'], $this->relationship); + } + else { + $table_alias = $this->table_alias; + } + + if (empty($table_alias)) { + debug(t('Handler @handler tried to add additional_field @identifier but @table could not be added!', array('@handler' => $this->definition['handler'], '@identifier' => $identifier, '@table' => $info['table']))); + $this->aliases[$identifier] = 'broken'; + continue; + } + + $params = array(); + if (!empty($info['params'])) { + $params = $info['params']; + } + + $this->aliases[$identifier] = $this->query->add_field($table_alias, $info['field'], NULL, $params); + } + else { + $this->aliases[$info] = $this->query->add_field($this->table_alias, $info); + } + } + } + } + + /** + * Called to determine what to tell the clicksorter. + */ + function click_sort($order) { + if (isset($this->field_alias)) { + // Since fields should always have themselves already added, just + // add a sort on the field. + $this->query->add_orderby(NULL, NULL, $order, $this->field_alias); + } + } + + /** + * Determine if this field is click sortable. + */ + function click_sortable() { + return !empty($this->definition['click sortable']); + } + + /** + * Get this field's label. + */ + function label() { + if (!isset($this->options['label'])) { + return ''; + } + return $this->options['label']; + } + + /** + * Return an HTML element based upon the field's element type. + */ + function element_type($none_supported = FALSE, $default_empty = FALSE) { + if ($none_supported) { + if ($this->options['element_type'] === '0') { + return ''; + } + } + if ($this->options['element_type']) { + return check_plain($this->options['element_type']); + } + + if ($default_empty) { + return ''; + } + + if (isset($this->definition['element type'])) { + return $this->definition['element type']; + } + + return 'span'; + } + + /** + * Return an HTML element for the label based upon the field's element type. + */ + function element_label_type($none_supported = FALSE, $default_empty = FALSE) { + if ($none_supported) { + if ($this->options['element_label_type'] === '0') { + return ''; + } + } + if ($this->options['element_label_type']) { + return check_plain($this->options['element_label_type']); + } + + if ($default_empty) { + return ''; + } + + return 'span'; + } + + /** + * Return an HTML element for the wrapper based upon the field's element type. + */ + function element_wrapper_type($none_supported = FALSE, $default_empty = FALSE) { + if ($none_supported) { + if ($this->options['element_wrapper_type'] === '0') { + return 0; + } + } + if ($this->options['element_wrapper_type']) { + return check_plain($this->options['element_wrapper_type']); + } + + if ($default_empty) { + return ''; + } + + return 'div'; + } + + /** + * Provide a list of elements valid for field HTML. + * + * This function can be overridden by fields that want more or fewer + * elements available, though this seems like it would be an incredibly + * rare occurence. + */ + function get_elements() { + return array( + '' => t('- Use default -'), + '0' => t('- None -'), + 'div' => t('DIV'), + 'span' => t('SPAN'), + 'h1' => t('H1'), + 'h2' => t('H2'), + 'h3' => t('H3'), + 'h4' => t('H4'), + 'h5' => t('H5'), + 'h6' => t('H6'), + 'p' => t('P'), + 'strong' => t('STRONG'), + 'em' => t('EM'), + ); + } + + /** + * Return the class of the field. + */ + function element_classes() { + $classes = $this->tokenize_value($this->options['element_class']); + return drupal_clean_css_identifier($classes); + } + + /** + * Replace a value with tokens from the last field. + * + * This function actually figures out which field was last and uses its + * tokens so they will all be available. + */ + function tokenize_value($value) { + if (strpos($value, '[') !== FALSE || strpos($value, '!') !== FALSE || strpos($value, '%') !== FALSE) { + $fake_item = array( + 'alter_text' => TRUE, + 'text' => $value, + ); + + // Get tokens from the last field. + $last_field = end($this->view->field); + if (isset($last_field->last_tokens)) { + $tokens = $last_field->last_tokens; + } + else { + $tokens = $last_field->get_render_tokens($fake_item); + } + + $value = strip_tags($this->render_altered($fake_item, $tokens)); + } + + return $value; + } + + /** + * Return the class of the field's label. + */ + function element_label_classes() { + return drupal_clean_css_identifier($this->options['element_label_class']); + } + + /** + * Return the class of the field's wrapper. + */ + function element_wrapper_classes() { + return drupal_clean_css_identifier($this->options['element_wrapper_class']); + } + + function option_definition() { + $options = parent::option_definition(); + + $options['label'] = array('default' => $this->definition['title'], 'translatable' => TRUE); + $options['exclude'] = array('default' => FALSE, 'bool' => TRUE); + $options['alter'] = array( + 'contains' => array( + 'alter_text' => array('default' => FALSE), + 'text' => array('default' => '', 'translatable' => TRUE), + 'make_link' => array('default' => FALSE), + 'path' => array('default' => '', 'translatable' => TRUE), + 'absolute' => array('default' => '', 'translatable' => FALSE), + 'alt' => array('default' => '', 'translatable' => TRUE), + 'rel' => array('default' => ''), + 'link_class' => array('default' => ''), + 'prefix' => array('default' => '', 'translatable' => TRUE), + 'suffix' => array('default' => '', 'translatable' => TRUE), + 'target' => array('default' => '', 'translatable' => TRUE), + 'trim' => array('default' => FALSE), + 'max_length' => array('default' => ''), + 'word_boundary' => array('default' => TRUE), + 'ellipsis' => array('default' => TRUE), + 'strip_tags' => array('default' => FALSE), + 'preserve_tags' => array('default' => ''), + 'html' => array('default' => FALSE), + ), + ); + $options['element_type'] = array('default' => ''); + $options['element_class'] = array('default' => ''); + + $options['element_label_type'] = array('default' => ''); + $options['element_label_class'] = array('default' => ''); + $options['element_label_colon'] = array('default' => TRUE); + + $options['element_wrapper_type'] = array('default' => ''); + $options['element_wrapper_class'] = array('default' => ''); + + $options['element_default_classes'] = array('default' => TRUE); + + $options['empty'] = array('default' => '', 'translatable' => TRUE); + $options['hide_empty'] = array('default' => FALSE); + $options['empty_zero'] = array('default' => FALSE); + + return $options; + } + + /** + * Default options form that provides the label widget that all fields + * should have. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + // Use prefix and suffix to fake a fieldset because we use #tree. + $form['style_prefix'] = array( + '#value' => '<fieldset id="views-validator-options"><legend>' . t('Style settings') . '</legend>', + ); + + $form['exclude'] = array( + '#type' => 'checkbox', + '#title' => t('Exclude from display'), + '#default_value' => $this->options['exclude'], + '#description' => t('Check this box to not display this field, but still load it in the view. Use this option to not show a grouping field in each record, or when doing advanced theming, or when you want to use this field as a token in other fields.'), + ); + + $form['element_type'] = array( + '#title' => t('HTML element'), + '#options' => $this->get_elements(), + '#type' => 'select', + '#default_value' => $this->options['element_type'], + '#description' => t('Most styles provide wrappers for fields. If the chosen style supports wrappers, wrap the field in this HTML element. The default will usually be either DIV or SPAN.'), + ); + + $form['element_class'] = array( + '#title' => t('Element class'), + '#description' => t('The class to provide on the wrapper element. You may enter data from this view as per the "Replacement patterns" used in "Rewrite the output of this field".'), + '#type' => 'textfield', + '#default_value' => $this->options['element_class'], + ); + + $form['label'] = array( + '#type' => 'textfield', + '#title' => t('Label'), + '#default_value' => isset($this->options['label']) ? $this->options['label'] : '', + '#description' => t('The label for this field that will be displayed to end users if the style requires it.'), + ); + + $form['element_label_type'] = array( + '#title' => t('Label HTML element'), + '#options' => $this->get_elements(FALSE), + '#type' => 'select', + '#default_value' => $this->options['element_label_type'], + '#description' => t('What HTML Element type to use to wrap the label.'), + ); + + $form['element_label_class'] = array( + '#title' => t('Label class'), + '#description' => t('The class to provide on the label wrapper element.'), + '#type' => 'textfield', + '#default_value' => $this->options['element_label_class'], + ); + + $form['element_label_colon'] = array( + '#type' => 'checkbox', + '#title' => t('Place a colon after the label'), + '#default_value' => $this->options['element_label_colon'], + '#description' => t('If the label is to be inline with the value, place a colon between them. Not valid for styles such as table where the label is not placed with the value.'), + ); + + $form['element_wrapper_type'] = array( + '#title' => t('Wrapper HTML element'), + '#options' => $this->get_elements(FALSE), + '#type' => 'select', + '#default_value' => $this->options['element_wrapper_type'], + '#description' => t('What HTML Element type to use to wrap the field (and the label). This is not supported by some styles such as tables.'), + ); + + $form['element_wrapper_class'] = array( + '#title' => t('Wrapper class'), + '#description' => t('The class to provide on the wrapper element.'), + '#type' => 'textfield', + '#default_value' => $this->options['element_wrapper_class'], + ); + + $form['element_default_classes'] = array( + '#type' => 'checkbox', + '#title' => t('Add default classes'), + '#default_value' => $this->options['element_default_classes'], + '#description' => t('Use default Views classes to identify the field, field label and field content.'), + ); + + $form['style_suffix'] = array( + '#value' => '</fieldset>', + ); + + $form['alter'] = array( + '#title' => t('Rewriting'), + '#type' => 'fieldset', + ); + + if ($this->allow_advanced_render()) { + $form['alter']['#tree'] = TRUE; + $form['alter']['alter_text'] = array( + '#type' => 'checkbox', + '#title' => t('Rewrite the output of this field'), + '#description' => t('If checked, you can alter the output of this field by specifying a string of text with replacement tokens that can use any existing field output.'), + '#default_value' => $this->options['alter']['alter_text'], + ); + + $form['alter']['text'] = array( + '#title' => t('Text'), + '#type' => 'textarea', + '#default_value' => $this->options['alter']['text'], + '#description' => t('The text to display for this field. You may include HTML. You may enter data from this view as per the "Replacement patterns" below.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-alter-text' => array(1) + ), + ); + + $form['alter']['make_link'] = array( + '#type' => 'checkbox', + '#title' => t('Output this field as a link'), + '#description' => t('If checked, this field will be made into a link. The destination must be given below.'), + '#default_value' => $this->options['alter']['make_link'], + ); + $form['alter']['path'] = array( + '#title' => t('Link path'), + '#type' => 'textfield', + '#default_value' => $this->options['alter']['path'], + '#description' => t('The Drupal path or absolute URL for this link. You may enter data from this view as per the "Replacement patterns" below.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-make-link' => array(1) + ), + '#maxlength' => 255, + ); + $form['alter']['absolute'] = array( + '#type' => 'checkbox', + '#title' => t('Use absolute path'), + '#default_value' => $this->options['alter']['absolute'], + '#process' => array('form_process_checkbox', 'ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-make-link' => array(1) + ), + ); + + $form['alter']['link_class'] = array( + '#title' => t('Link class'), + '#type' => 'textfield', + '#default_value' => $this->options['alter']['link_class'], + '#description' => t('The CSS class to apply to the link.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-make-link' => array(1) + ), + ); + $form['alter']['alt'] = array( + '#title' => t('Alt text'), + '#type' => 'textfield', + '#default_value' => $this->options['alter']['alt'], + '#description' => t('Text to place as "alt" text which most browsers display as a tooltip when hovering over the link.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-make-link' => array(1) + ), + ); + $form['alter']['rel'] = array( + '#title' => t('Rel Text'), + '#type' => 'textfield', + '#default_value' => $this->options['alter']['rel'], + '#description' => t('Include Rel attribute for use in lightbox2 or other javascript utility.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-make-link' => array(1) + ), + ); + $form['alter']['prefix'] = array( + '#title' => t('Prefix text'), + '#type' => 'textfield', + '#default_value' => $this->options['alter']['prefix'], + '#description' => t('Any text to display before this link. You may include HTML.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-make-link' => array(1) + ), + ); + $form['alter']['suffix'] = array( + '#title' => t('Suffix text'), + '#type' => 'textfield', + '#default_value' => $this->options['alter']['suffix'], + '#description' => t('Any text to display after this link. You may include HTML.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-make-link' => array(1) + ), + ); + $form['alter']['target'] = array( + '#title' => t('Target'), + '#type' => 'textfield', + '#default_value' => $this->options['alter']['target'], + '#description' => t("Target of the link, such as _blank, _parent or an iframe's name. This field is rarely used."), + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-make-link' => array(1) + ), + ); + + + // Get a list of the available fields and arguments for token replacement. + $options = array(); + foreach ($this->view->display_handler->get_handlers('field') as $field => $handler) { + $options[t('Fields')]["[$field]"] = $handler->ui_name(); + // We only use fields up to (and including) this one. + if ($field == $this->options['id']) { + break; + } + } + $count = 0; // This lets us prepare the key as we want it printed. + foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) { + $options[t('Arguments')]['%' . ++$count] = t('@argument title', array('@argument' => $handler->ui_name())); + $options[t('Arguments')]['!' . $count] = t('@argument input', array('@argument' => $handler->ui_name())); + } + + $this->document_self_tokens($options[t('Fields')]); + + // Default text. + $output = t('<p>You must add some additional fields to this display before using this field. These fields may be marked as <em>Exclude from display</em> if you prefer. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.</p>'); + // We have some options, so make a list. + if (!empty($options)) { + $output = t('<p>The following tokens are available for this field. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields. +If you would like to have the characters %5B and %5D please use the html entity codes \'%5B\' or \'%5D\' or they will get replaced with empty space.</p>'); + foreach (array_keys($options) as $type) { + if (!empty($options[$type])) { + $items = array(); + foreach ($options[$type] as $key => $value) { + $items[] = $key . ' == ' . $value; + } + $output .= theme('item_list', + array( + 'items' => $items, + 'type' => $type + )); + } + } + } + // This construct uses 'hidden' and not markup because process doesn't + // run. It also has an extra div because the dependency wants to hide + // the parent in situations like this, so we need a second div to + // make this work. + $form['alter']['help'] = array( + '#type' => 'hidden', + '#id' => 'views-tokens-help', + '#prefix' => '<div><fieldset id="views-tokens-help"><legend>' . t('Replacement patterns') . '</legend>' . $output . '</fieldset></div>', + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-make-link' => array(1), + 'edit-options-alter-alter-text' => array(1), + ), + ); + + $form['alter']['trim'] = array( + '#type' => 'checkbox', + '#title' => t('Trim this field to a maximum length'), + '#description' => t('If checked, this field be trimmed to a maximum length in characters.'), + '#default_value' => $this->options['alter']['trim'], + ); + + $form['alter']['max_length'] = array( + '#title' => t('Maximum length'), + '#type' => 'textfield', + '#default_value' => $this->options['alter']['max_length'], + '#description' => t('The maximum number of characters this field can be.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-trim' => array(1) + ), + ); + + $form['alter']['word_boundary'] = array( + '#type' => 'checkbox', + '#title' => t('Trim only on a word boundary'), + '#description' => t('If checked, this field be trimmed only on a word boundary. This is guaranteed to be the maximum characters stated or less. If there are no word boundaries this could trim a field to nothing.'), + '#default_value' => $this->options['alter']['word_boundary'], + '#process' => array('form_process_checkbox', 'ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-trim' => array(1) + ), + ); + + $form['alter']['ellipsis'] = array( + '#type' => 'checkbox', + '#title' => t('Add an ellipsis'), + '#description' => t('If checked, a "..." will be added if a field was trimmed.'), + '#default_value' => $this->options['alter']['ellipsis'], + '#process' => array('form_process_checkbox', 'ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-trim' => array(1) + ), + ); + + $form['alter']['html'] = array( + '#type' => 'checkbox', + '#title' => t('Field can contain HTML'), + '#description' => t('If checked, HTML corrector will be run to ensure tags are properly closed after trimming.'), + '#default_value' => $this->options['alter']['html'], + '#process' => array('form_process_checkbox', 'ctools_dependent_process'), + '#dependency' => array( + 'edit-options-alter-trim' => array(1) + ), + ); + + $form['alter']['strip_tags'] = array( + '#type' => 'checkbox', + '#title' => t('Strip HTML tags'), + '#description' => t('If checked, all HTML tags will be stripped.'), + '#default_value' => $this->options['alter']['strip_tags'], + '#process' => array('form_process_checkbox', 'ctools_dependent_process'), + ); + $form['alter']['preserve_tags'] = array( + '#type' => 'textfield', + '#title' => t('Preserve certain tags'), + '#description' => t('List the tags that need to be preserved during the stripping process. example "<p> <br>" which will preserve all p and br elements'), + '#default_value' => $this->options['alter']['preserve_tags'], + '#dependency' => array( + 'edit-options-alter-strip-tags' => array(1), + ), + '#process' => array('ctools_dependent_process'), + ); + } + + // Use prefix and suffix to fake a fieldset because we use #tree. + $form['empty_prefix'] = array( + '#value' => '<fieldset id="views-validator-options"><legend>' . t('Empty field behavior') . '</legend>', + ); + + $form['empty'] = array( + '#type' => 'textfield', + '#title' => t('Empty text'), + '#default_value' => $this->options['empty'], + '#description' => t('If the field is empty, display this text instead.'), + ); + + $form['empty_zero'] = array( + '#type' => 'checkbox', + '#title' => t('Count the number 0 as empty'), + '#default_value' => $this->options['empty_zero'], + '#description' => t('If the field contains the number zero, display the empty text instead'), + ); + + $form['hide_empty'] = array( + '#type' => 'checkbox', + '#title' => t('Hide if empty'), + '#default_value' => $this->options['hide_empty'], + '#description' => t('Do not display anything for this field if it is empty. Note that the field label may still be displayed. Check style or row style settings to hide labels for empty fields.'), + ); + + $form['empty_suffix'] = array( + '#value' => '</fieldset>', + ); + + } + + /** + * Provide extra data to the administration form + */ + function admin_summary() { + return $this->label(); + } + + /** + * Run before any fields are rendered. + * + * This gives the handlers some time to set up before any handler has + * been rendered. + * + * @param $values + * An array of all objects returned from the query. + */ + function pre_render(&$values) { } + + /** + * Render the field. + * + * @param $values + * The values retrieved from the database. + */ + function render($values) { + $value = $values->{$this->field_alias}; + return check_plain($value); + } + + /** + * Render a field using advanced settings. + * + * This renders a field normally, then decides if render-as-link and + * text-replacement rendering is necessary. + */ + function advanced_render($values) { + if ($this->allow_advanced_render() && method_exists($this, 'render_item')) { + $raw_items = $this->get_items($values); + } + else { + $this->last_render = $value = $this->render($values); + $this->original_value = $value; + } + + if ($this->allow_advanced_render()) { + $tokens = NULL; + if (method_exists($this, 'render_item')) { + $items = array(); + foreach ($raw_items as $count => $item) { + $this->last_render = $this->render_item($count, $item); + $this->original_value = $this->last_render; + + $alter = $item + $this->options['alter']; + $items[] = $this->render_text($alter); + } + + $value = $this->render_items($items); + } + else { + $value = $this->render_text($this->options['alter']); + } + + // This happens here so that render_as_link can get the unaltered value of + // this field as a token rather than the altered value. + $this->last_render = $value; + } + + if (empty($this->last_render)) { + if (($this->last_render !== 0 && $this->last_render !== '0') || !empty($this->options['empty_zero'])) { + $alter = $this->options['alter']; + $alter['alter_text'] = 1; + $alter['text'] = $this->options['empty']; + $this->last_render = $this->render_text($alter); + } + } + + return $this->last_render; + } + + /** + * Perform an advanced text render for the item. + * + * This is separated out as some fields may render lists, and this allows + * each item to be handled individually. + */ + function render_text($alter) { + $value = trim($this->last_render); + + if (!empty($alter['alter_text']) && $alter['text'] !== '') { + $tokens = $this->get_render_tokens($alter); + $value = $this->render_altered($alter, $tokens); + } + + if ($this->options['hide_empty'] && empty($value) && ($value !== 0 || $this->options['empty_zero'])) { + return ''; + } + + if (!empty($alter['strip_tags'])) { + $value = strip_tags($value, $alter['preserve_tags']); + } + + if (!empty($alter['trim']) && !empty($alter['max_length'])) { + $value = $this->render_trim_text($alter, $value); + } + + if (!empty($alter['make_link']) && !empty($alter['path'])) { + if (!isset($tokens)) { + $tokens = $this->get_render_tokens($alter); + } + $value = $this->render_as_link($alter, $value, $tokens); + } + + return $value; + } + + /** + * Render this field as altered text, from a fieldset set by the user. + */ + function render_altered($alter, $tokens) { + // Filter this right away as our substitutions are already sanitized. + $value = filter_xss_admin($alter['text']); + $value = strtr($value, $tokens); + + return $value; + } + + /** + * Trim the field down to the specified length. + */ + function render_trim_text($alter, $value) { + if (!empty($alter['strip_tags'])) { + // NOTE: It's possible that some external fields might override the + // element type so if someone from, say, CCK runs into a bug here, + // this may be why =) + $this->definition['element type'] = 'span'; + } + return views_trim_text($alter, $value); + } + + /** + * Render this field as a link, with the info from a fieldset set by + * the user. + */ + function render_as_link($alter, $text, $tokens) { + $value = ''; + + if (!empty($alter['prefix'])) { + $value .= filter_xss_admin(strtr($alter['prefix'], $tokens)); + } + + $options = array( + 'html' => TRUE, + 'absolute' => !empty($alter['absolute']) ? TRUE : FALSE, + ); + + // $path will be run through check_url() by l() so we do not need to + // sanitize it ourselves. + $path = $alter['path']; + + // html_entity_decode removes <front>, so check whether its different to front. + if ($path != '<front>') { + // Use strip tags as there should never be HTML in the path. + // However, we need to preserve special characters like " that + // were removed by check_plain(). + $path = strip_tags(html_entity_decode(strtr($path, $tokens))); + } + + // If the path is empty do not build a link around the given text and return + // it as is. + if (empty($path)) { + return $text; + } + + // Parse the URL and move any query and fragment parameters out of the path. + $url = parse_url($path); + if (isset($url['query'])) { + $path = strtr($path, array('?' . $url['query'] => '')); + $options['query'] = drupal_get_query_array($url['query']); + } + if (isset($url['fragment'])) { + $path = strtr($path, array('#' . $url['fragment'] => '')); + // If the path is empty we want to have a fragment for the current site. + if ($path == '') { + $options['external'] = TRUE; + } + $options['fragment'] = $url['fragment']; + } + + $alt = strtr($alter['alt'], $tokens); + // Set the title attribute of the link only if it improves accessibility + if ($alt && $alt != $text) { + $options['attributes']['title'] = html_entity_decode($alt, ENT_QUOTES); + } + + $class = strtr($alter['link_class'], $tokens); + if ($class) { + $options['attributes']['class'] = array($class); + } + + if (!empty($alter['rel']) && $rel = strtr($alter['rel'], $tokens)) { + $options['attributes']['rel'] = $rel; + } + + $target = check_plain(trim(strtr($alter['target'],$tokens))); + if (!empty($target)) { + $options['attributes']['target'] = $target; + } + + // If the query and fragment were programatically assigned overwrite any + // parsed values. + if (isset($alter['query'])) { + // Convert the query to a string, perform token replacement, and then + // convert back to an array form for l(). + $options['query'] = drupal_http_build_query($alter['query']); + $options['query'] = strtr($options['query'], $tokens); + $options['query'] = drupal_get_query_array($options['query']); + } + if (isset($alter['alias'])) { + // Alias is a boolean field, so no token. + $options['alias'] = $alter['alias']; + } + if (isset($alter['fragment'])) { + $options['fragment'] = strtr($alter['fragment'], $tokens); + } + if (isset($alter['language'])) { + $options['language'] = $alter['language']; + } + + // If the url came from entity_uri(), pass along the required options. + if (isset($alter['entity'])) { + $options['entity'] = $alter['entity']; + } + if (isset($alter['entity_type'])) { + $options['entity_type'] = $alter['entity_type']; + } + + $value .= l($text, $path, $options); + + if (!empty($alter['suffix'])) { + $value .= filter_xss_admin(strtr($alter['suffix'], $tokens)); + } + + return $value; + } + + /** + * Get the 'render' tokens to use for advanced rendering. + * + * This runs through all of the fields and arguments that + * are available and gets their values. This will then be + * used in one giant str_replace(). + */ + function get_render_tokens($item) { + $tokens = array(); + if (!empty($this->view->build_info['substitutions'])) { + $tokens = $this->view->build_info['substitutions']; + } + $count = 0; + foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) { + $token = '%' . ++$count; + if (!isset($tokens[$token])) { + $tokens[$token] = ''; + } + + // Use strip tags as there should never be HTML in the path. + // However, we need to preserve special characters like " that + // were removed by check_plain(). + $tokens['!' . $count] = isset($this->view->args[$count - 1]) ? strip_tags(html_entity_decode($this->view->args[$count - 1])) : ''; + } + + // Now add replacements for our fields. + foreach ($this->view->display_handler->get_handlers('field') as $field => $handler) { + if (isset($handler->last_render)) { + $tokens["[$field]"] = $handler->last_render; + } + else { + $tokens["[$field]"] = ''; + } + $this->add_self_tokens($tokens, $item); + + // We only use fields up to (and including) this one. + if ($field == $this->options['id']) { + break; + } + } + + $this->last_tokens = $tokens; + return $tokens; + } + + /** + * Add any special tokens this field might use for itself. + * + * This method is intended to be overridden by items that generate + * fields as a list. For example, the field that displays all terms + * on a node might have tokens for the tid and the term. + * + * By convention, tokens should follow the format of [token-subtoken] + * where token is the field ID and subtoken is the field. If the + * field ID is terms, then the tokens might be [terms-tid] and [terms-name]. + */ + function add_self_tokens(&$tokens, $item) { } + + /** + * Document any special tokens this field might use for itself. + * + * @see add_self_tokens() for details. + */ + function document_self_tokens(&$tokens) { } + + /** + * Call out to the theme() function, which probably just calls render() but + * allows sites to override output fairly easily. + */ + function theme($values) { + return theme($this->theme_functions(), + array( + 'view' => $this->view, + 'field' => $this, + 'row' => $values + )); + } + + function theme_functions() { + $themes = array(); + $hook = 'views_view_field'; + + $display = $this->view->display[$this->view->current_display]; + + if (!empty($display)) { + $themes[] = $hook . '__' . $this->view->name . '__' . $display->id . '__' . $this->options['id']; + $themes[] = $hook . '__' . $this->view->name . '__' . $display->id; + $themes[] = $hook . '__' . $display->id . '__' . $this->options['id']; + $themes[] = $hook . '__' . $display->id; + if ($display->id != $display->display_plugin) { + $themes[] = $hook . '__' . $this->view->name . '__' . $display->display_plugin . '__' . $this->options['id']; + $themes[] = $hook . '__' . $this->view->name . '__' . $display->display_plugin; + $themes[] = $hook . '__' . $display->display_plugin . '__' . $this->options['id']; + $themes[] = $hook . '__' . $display->display_plugin; + } + } + $themes[] = $hook . '__' . $this->view->name . '__' . $this->options['id']; + $themes[] = $hook . '__' . $this->view->name; + $themes[] = $hook . '__' . $this->options['id']; + $themes[] = $hook; + + return $themes; + } +} + +/** + * A special handler to take the place of missing or broken handlers. + */ +class views_handler_field_broken extends views_handler_field { + function ui_name($short = FALSE) { + return t('Broken/missing handler'); + } + + function ensure_my_table() { /* No table to ensure! */ } + function query() { /* No query to run */ } + function options_form(&$form, &$form_state) { + $form['markup'] = array( + '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>', + ); + } + + /** + * Determine if the handler is considered 'broken' + */ + function broken() { return TRUE; } +} + +/** + * Render a numeric value as a size. + */ +class views_handler_field_file_size extends views_handler_field { + function option_definition() { + $options = parent::option_definition(); + + $options['file_size_display'] = array('default' => 'formatted'); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['file_size_display'] = array( + '#title' => t('File size display'), + '#type' => 'select', + '#options' => array( + 'formatted' => t('Formatted (in KB or MB)'), + 'bytes' => t('Raw bytes'), + ), + ); + } + + function render($values) { + if ($values->{$this->field_alias}) { + switch ($this->options['file_size_display']) { + case 'bytes': + return $values->{$this->field_alias}; + case 'formatted': + default: + return format_size($values->{$this->field_alias}); + } + } + else { + return ''; + } + } +} + +/** + * A handler to run a field through simple XSS filtering + */ +class views_handler_field_xss extends views_handler_field { + function render($values) { + $value = $values->{$this->field_alias}; + return filter_xss($value); + } +} + +/** + * @} + */ diff --git a/sites/all/modules/views/handlers/views_handler_field_boolean.inc b/sites/all/modules/views/handlers/views_handler_field_boolean.inc new file mode 100644 index 0000000000000000000000000000000000000000..ad2ee71045e236225cb63704dd7a0b70f03be85c --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_field_boolean.inc @@ -0,0 +1,74 @@ +<?php +// $Id: views_handler_field_boolean.inc,v 1.3.4.3 2010/08/26 09:41:55 dereine Exp $ + +/** + * A handler to provide proper displays for booleans. + * + * Allows for display of true/false, yes/no, on/off. + * + * Definition terms: + * - output formats: An array where the first entry is displayed on boolean false + * and the second is displayed on boolean true. An example for sticky is: + * @code + * 'output formats' => array( + * 'sticky' => array('', t('Sticky')), + * ), + * @endcode + * + * @ingroup views_field_handlers + */ +class views_handler_field_boolean extends views_handler_field { + function option_definition() { + $options = parent::option_definition(); + $options['type'] = array('default' => 'yes-no'); + $options['not'] = array('definition bool' => 'reverse'); + + return $options; + } + + function init(&$view, &$options) { + parent::init($view, $options); + + $default_formats = array( + 'yes-no' => array(t('Yes'), t('No')), + 'true-false' => array(t('True'), t('False')), + 'on-off' => array(t('On'), t('Off')), + ); + $output_formats = isset($this->definition['output formats']) ? $this->definition['output formats'] : array(); + $this->formats = array_merge($default_formats, $output_formats); + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + foreach ($this->formats as $key => $item) { + $options[$key] = implode('/', $item); + } + + $form['type'] = array( + '#type' => 'select', + '#title' => t('Output format'), + '#options' => $options, + '#default_value' => $this->options['type'], + ); + $form['not'] = array( + '#type' => 'checkbox', + '#title' => t('Reverse'), + '#description' => t('If checked, true will be displayed as false.'), + '#default_value' => $this->options['not'], + ); + } + + function render($values) { + $value = $values->{$this->field_alias}; + if (!empty($this->options['not'])) { + $value = !$value; + } + + if (isset($this->formats[$this->options['type']])) { + return $value ? $this->formats[$this->options['type']][0] : $this->formats[$this->options['type']][1]; + } + else { + return $value ? $this->formats['yes-no'][0] : $this->formats['yes-no'][1]; + } + } +} diff --git a/sites/all/modules/views/handlers/views_handler_field_counter.inc b/sites/all/modules/views/handlers/views_handler_field_counter.inc new file mode 100644 index 0000000000000000000000000000000000000000..4bf4c2ad149db48c2d08e6c7ebe325088977d7e7 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_field_counter.inc @@ -0,0 +1,42 @@ +<?php +// $Id: views_handler_field_counter.inc,v 1.3.4.4 2010/11/05 07:20:54 dereine Exp $ + +class views_handler_field_counter extends views_handler_field { + function option_definition() { + $options = parent::option_definition(); + $options['counter_start'] = array('default' => 1); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $form['counter_start'] = array( + '#type' => 'textfield', + '#title' => t('Starting value'), + '#default_value' => $this->options['counter_start'], + '#description' => t('Specify the number the counter should start at.'), + //'#process' => array('ctools_dependent_process'), + '#size' => 2, + ); + } + + function query() { + // do nothing -- to override the parent query. + } + + function render($values) { + // Note: 1 is subtracted from the counter start value below because the + // counter value is incremented by 1 at the end of this function. + $count = is_numeric($this->options['counter_start']) ? $this->options['counter_start'] - 1 : 0; + $pager = $this->view->query->pager; + // Get the base count of the pager. + if ($pager->use_pager()) { + $count += ($pager->get_items_per_page() * $pager->get_current_page() + $pager->get_offset()); + } + // Add the counter for the current site. + $count += $this->view->row_index + 1; + + return $count; + } +} diff --git a/sites/all/modules/views/handlers/views_handler_field_custom.inc b/sites/all/modules/views/handlers/views_handler_field_custom.inc new file mode 100644 index 0000000000000000000000000000000000000000..8b3a6419136f3a4f7ecdcdca990b99faeab98674 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_field_custom.inc @@ -0,0 +1,35 @@ +<?php +// $Id: views_handler_field_custom.inc,v 1.1.6.2 2010/11/05 07:20:54 dereine Exp $ + +/** + * A handler to provide a field that is completely custom by the administrator. + * + * @ingroup views_field_handlers + */ +class views_handler_field_custom extends views_handler_field { + function query() { + // do nothing -- to override the parent query. + } + + function option_definition() { + $options = parent::option_definition(); + + // Override the alter text option to always alter the text. + $options['alter']['contains']['alter_text'] = array('default' => TRUE); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + // Remove the checkbox + unset($form['alter']['alter_text']); + unset($form['alter']['text']['#dependency']); + unset($form['alter']['text']['#process']); + } + + function render($values) { + // Nothing to render. + return ''; + } +} diff --git a/sites/all/modules/views/handlers/views_handler_field_date.inc b/sites/all/modules/views/handlers/views_handler_field_date.inc new file mode 100644 index 0000000000000000000000000000000000000000..c69289a1e999f39bf62199a6a83ef1f7630c5f86 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_field_date.inc @@ -0,0 +1,74 @@ +<?php +// $Id: views_handler_field_date.inc,v 1.3.4.6 2010/12/23 22:34:37 dereine Exp $ +/** + * A handler to provide proper displays for dates. + * + * @ingroup views_field_handlers + */ +class views_handler_field_date extends views_handler_field { + function option_definition() { + $options = parent::option_definition(); + + $options['date_format'] = array('default' => 'small'); + $options['custom_date_format'] = array('default' => ''); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $form['date_format'] = array( + '#type' => 'select', + '#title' => t('Date format'), + '#options' => array( + 'small' => t('Short date format') . ' ' . format_date(REQUEST_TIME, 'small'), + 'medium' => t('Medium date format') . ' ' . format_date(REQUEST_TIME, 'medium'), + 'large' => t('Long date format') . ' ' . format_date(REQUEST_TIME, 'large'), + 'custom' => t('Custom'), + 'raw time ago' => t('Time ago'), + 'time ago' => t('Time ago (with "ago" appended)'), + 'raw time span' => t('Time span (future dates start with - )'), + 'time span' => t('Time span (with "ago/hence" appended)'), + ), + '#default_value' => isset($this->options['date_format']) ? $this->options['date_format'] : 'small', + ); + $form['custom_date_format'] = array( + '#type' => 'textfield', + '#title' => t('Custom date format'), + '#description' => t('If "Custom", see <a href="http://us.php.net/manual/en/function.date.php" target="_blank">the PHP docs</a> for date formats. If "Time ago" this is the the number of different units to display, which defaults to two.'), + '#default_value' => isset($this->options['custom_date_format']) ? $this->options['custom_date_format'] : '', + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-options-date-format' => array('custom', 'raw time ago', 'time ago', 'raw time span', 'time span')), + ); + } + + function render($values) { + $value = $values->{$this->field_alias}; + $format = $this->options['date_format']; + if (in_array($format, array('custom', 'raw time ago', 'time ago', 'raw time span', 'time span'))) { + $custom_format = $this->options['custom_date_format']; + } + + if ($value) { + $time_diff = REQUEST_TIME - $value; // will be positive for a datetime in the past (ago), and negative for a datetime in the future (hence) + switch ($format) { + case 'raw time ago': + return format_interval($time_diff, is_numeric($custom_format) ? $custom_format : 2); + case 'time ago': + return t('%time ago', array('%time' => format_interval($time_diff, is_numeric($custom_format) ? $custom_format : 2))); + case 'raw time span': + return ($time_diff < 0 ? '-' : '') . format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2); + case 'time span': + return t(($time_diff < 0 ? '%time hence' : '%time ago'), array('%time' => format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2))); + case 'custom': + if ($custom_format == 'r') { + return format_date($value, $format, $custom_format, null, 'en'); + } + return format_date($value, $format, $custom_format); + default: + return format_date($value, $format); + } + } + } +} diff --git a/sites/all/modules/views/handlers/views_handler_field_group_by_numeric.inc b/sites/all/modules/views/handlers/views_handler_field_group_by_numeric.inc new file mode 100644 index 0000000000000000000000000000000000000000..3e2c211fac7723a0fcbc05e0f1b00d1b7d233a56 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_field_group_by_numeric.inc @@ -0,0 +1,44 @@ +<?php +// $Id: views_handler_field_group_by_numeric.inc,v 1.1.4.6 2010/11/07 11:36:59 dereine Exp $ + +/** + * Handler for GROUP BY on simple numeric fields. + */ +class views_handler_field_group_by_numeric extends views_handler_field_numeric { + function init(&$view, &$options) { + parent::init($view, $options); + + // Initialize the original handler. + $this->handler = views_get_handler($options['table'], $options['field'], 'field'); + $this->handler->init($view, $options); + } + + /** + * Called to add the field to a query. + */ + function query() { + $this->ensure_my_table(); + // Add the field, taking care of any aggregation that may affect it. + $params = array( + 'function' => $this->options['group_type'], + ); + + $this->field_alias = $this->query->add_field($this->table_alias, $this->real_field, NULL, $params); + $this->add_additional_fields(); + } + + /** + * Called to determine what to tell the clicksorter. + */ + function click_sort($order) { + $params = array( + 'function' => $this->options['group_type'], + ); + + $this->query->add_orderby($this->table, $this->field, $order, $this->field_alias, $params); + } + + function ui_name($short = FALSE) { + return $this->get_field(parent::ui_name($short)); + } +} diff --git a/sites/all/modules/views/handlers/views_handler_field_markup.inc b/sites/all/modules/views/handlers/views_handler_field_markup.inc new file mode 100644 index 0000000000000000000000000000000000000000..09ad254425fff6f78e6ad9787c0784f62a30ec18 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_field_markup.inc @@ -0,0 +1,46 @@ +<?php +// $Id: views_handler_field_markup.inc,v 1.3.6.5 2010/12/16 18:23:42 dereine Exp $ + +/** + * A handler to run a field through check_markup, using a companion + * format field. + * + * - format: (REQUIRED) Either a string format id to use for this field or an + * array('field' => {$field}) where $field is the field in this table + * used to control the format such as the 'format' field in the node, + * which goes with the 'body' field. + * + * @ingroup views_field_handlers + */ +class views_handler_field_markup extends views_handler_field { + /** + * Constructor; calls to base object constructor. + */ + function construct() { + parent::construct(); + + $this->format = $this->definition['format']; + + $this->additional_fields = array(); + if (is_array($this->format)) { + $this->additional_fields['format'] = $this->format; + } + } + + function render($values) { + $value = $values->{$this->field_alias}; + $format = is_array($this->format) ? $values->{$this->aliases['format']} : $this->format; + if ($value) { + $value = str_replace('<!--break-->', '', $value); + return check_markup($value, $format, ''); + } + } + + function element_type($none_supported = FALSE, $default_empty = FALSE) { + if (isset($this->definition['element type'])) { + return $this->definition['element type']; + } + + return 'div'; + } +} diff --git a/sites/all/modules/views/handlers/views_handler_field_math.inc b/sites/all/modules/views/handlers/views_handler_field_math.inc new file mode 100644 index 0000000000000000000000000000000000000000..d5200c3d8d7c44ff2d60ca912aba9f2d0b1de631 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_field_math.inc @@ -0,0 +1,74 @@ +<?php +// $Id: views_handler_field_math.inc,v 1.1.2.3 2010/11/05 07:20:54 dereine Exp $ +/** + * Render a mathematical expression as a numeric value + * + * Definition terms: + * - float: If true this field contains a decimal value. If unset this field + * will be assumed to be integer. + * + * @ingroup views_field_handlers + */ +class views_handler_field_math extends views_handler_field_numeric { + function option_definition() { + $options = parent::option_definition(); + $options['expression'] = array('default' => ''); + + return $options; + } + + function options_form(&$form, &$form_state) { + $form['expression'] = array( + '#type' => 'textarea', + '#title' => t('Expression'), + '#description' => t('Enter mathematical expressions such as 2 + 2 or sqrt(5). You my assign variables and create mathematical functions and evaluate them. Use the ; to separate these. For example: f(x) = x + 2; f(2).'), + '#default_value' => $this->options['expression'], + ); + + // Create a place for the help + $form['expression_help'] = array(); + parent::options_form($form, $form_state); + + // Then move the existing help: + $form['expression_help'] = $form['alter']['help']; + unset($form['expression_help']['#dependency']); + unset($form['expression_help']['#process']); + unset($form['alter']['help']); + } + + function render($values) { + ctools_include('math-expr'); + $value = strtr($this->options['expression'], $this->get_render_tokens(array())); + $expressions = explode(';', $value); + $math = new ctools_math_expr; + foreach ($expressions as $expression) { + if ($expression !== '') { + $value = $math->evaluate($expression); + } + } + + // The rest is directly from views_handler_field_numeric but because it + // does not allow the value to be passed in, it is copied. + if (!empty($this->options['set_precision'])) { + $value = number_format($value, $this->options['precision'], $this->options['decimal'], $this->options['separator']); + } + else { + $remainder = abs($value) - intval(abs($value)); + $value = $value > 0 ? floor($value) : ceil($value); + $value = number_format($value, 0, '', $this->options['separator']); + if ($remainder) { + // The substr may not be locale safe. + $value .= $this->options['decimal'] . substr($remainder, 2); + } + } + + // Check to see if hiding should happen before adding prefix and suffix. + if ($this->options['hide_empty'] && empty($value) && ($value !== 0 || $this->options['empty_zero'])) { + return ''; + } + + return check_plain($this->options['prefix'] . $value . $this->options['suffix']); + } + + function query() { } +} diff --git a/sites/all/modules/views/handlers/views_handler_field_numeric.inc b/sites/all/modules/views/handlers/views_handler_field_numeric.inc new file mode 100644 index 0000000000000000000000000000000000000000..a9ccb61f7f6e3629afe5db7ac39cbd8ef3de4737 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_field_numeric.inc @@ -0,0 +1,126 @@ +<?php +// $Id: views_handler_field_numeric.inc,v 1.6.4.4 2010/11/05 07:20:54 dereine Exp $ +/** + * Render a field as a numeric value + * + * Definition terms: + * - float: If true this field contains a decimal value. If unset this field + * will be assumed to be integer. + * + * @ingroup views_field_handlers + */ +class views_handler_field_numeric extends views_handler_field { + function option_definition() { + $options = parent::option_definition(); + + $options['set_precision'] = array('default' => FALSE); + $options['precision'] = array('default' => 0); + $options['decimal'] = array('default' => '.', 'translatable' => TRUE); + $options['separator'] = array('default' => ',', 'translatable' => TRUE); + $options['format_plural'] = array('default' => FALSE); + $options['format_plural_singular'] = array('default' => '1'); + $options['format_plural_plural'] = array('default' => '@count'); + $options['prefix'] = array('default' => '', 'translatable' => TRUE); + $options['suffix'] = array('default' => '', 'translatable' => TRUE); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + if (!empty($this->definition['float'])) { + $form['set_precision'] = array( + '#type' => 'checkbox', + '#title' => t('Round'), + '#description' => t('If checked, the number will be rounded.'), + '#default_value' => $this->options['set_precision'], + ); + $form['precision'] = array( + '#type' => 'textfield', + '#title' => t('Precision'), + '#default_value' => $this->options['precision'], + '#description' => t('Specify how many digits to print after the decimal point.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-options-set-precision' => array(TRUE)), + '#size' => 2, + ); + $form['decimal'] = array( + '#type' => 'textfield', + '#title' => t('Decimal point'), + '#default_value' => $this->options['decimal'], + '#description' => t('What single character to use as a decimal point.'), + '#size' => 2, + ); + } + $form['separator'] = array( + '#type' => 'textfield', + '#title' => t('Thousands separator'), + '#default_value' => $this->options['separator'], + '#description' => t('What single character to use as the thousands separator.'), + '#size' => 2, + ); + $form['format_plural'] = array( + '#type' => 'checkbox', + '#title' => t('Format plural'), + '#description' => t('If checked, special handling will be used for plurality.'), + '#default_value' => $this->options['format_plural'], + ); + $form['format_plural_singular'] = array( + '#type' => 'textfield', + '#title' => t('Singular form'), + '#default_value' => $this->options['format_plural_singular'], + '#description' => t('Text to use for the singular form.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-options-format-plural' => array(TRUE)), + ); + $form['format_plural_plural'] = array( + '#type' => 'textfield', + '#title' => t('Plural form'), + '#default_value' => $this->options['format_plural_plural'], + '#description' => t('Text to use for the plural form, @count will be replaced with the value.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-options-format-plural' => array(TRUE)), + ); + $form['prefix'] = array( + '#type' => 'textfield', + '#title' => t('Prefix'), + '#default_value' => $this->options['prefix'], + '#description' => t('Text to put before the number, such as currency symbol.'), + ); + $form['suffix'] = array( + '#type' => 'textfield', + '#title' => t('Suffix'), + '#default_value' => $this->options['suffix'], + '#description' => t('Text to put after the number, such as currency symbol.'), + ); + } + + function render($values) { + $value = $values->{$this->field_alias}; + if (!empty($this->options['set_precision'])) { + $value = number_format($value, $this->options['precision'], $this->options['decimal'], $this->options['separator']); + } + else { + $remainder = abs($value) - intval(abs($value)); + $value = $value > 0 ? floor($value) : ceil($value); + $value = number_format($value, 0, '', $this->options['separator']); + if ($remainder) { + // The substr may not be locale safe. + $value .= $this->options['decimal'] . substr($remainder, 2); + } + } + + // Check to see if hiding should happen before adding prefix and suffix. + if ($this->options['hide_empty'] && empty($value) && ($value !== 0 || $this->options['empty_zero'])) { + return ''; + } + + // Should we format as a plural. + if (!empty($this->options['format_plural'])) { + $value = format_plural($value, $this->options['format_plural_singular'], $this->options['format_plural_plural']); + } + + return check_plain($this->options['prefix'] . $value . $this->options['suffix']); + } +} diff --git a/sites/all/modules/views/handlers/views_handler_field_prerender_list.inc b/sites/all/modules/views/handlers/views_handler_field_prerender_list.inc new file mode 100644 index 0000000000000000000000000000000000000000..a8869ad51b2922460132096935fea783b03aec91 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_field_prerender_list.inc @@ -0,0 +1,122 @@ +<?php +// $Id: views_handler_field_prerender_list.inc,v 1.3.4.4 2010/11/05 07:20:54 dereine Exp $ + +/** + * Field handler to provide a list of items. + * + * The items are expected to be loaded by a child object during pre_render, + * and 'my field' is expected to be the pointer to the items in the list. + * + * Items to render should be in a list in $this->items + * + * @ingroup views_field_handlers + */ +class views_handler_field_prerender_list extends views_handler_field { + function option_definition() { + $options = parent::option_definition(); + + $options['type'] = array('default' => 'separator'); + $options['separator'] = array('default' => ', '); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['type'] = array( + '#type' => 'radios', + '#title' => t('Display type'), + '#options' => array( + 'ul' => t('Unordered list'), + 'ol' => t('Ordered list'), + 'separator' => t('Simple separator'), + ), + '#default_value' => $this->options['type'], + ); + + $form['separator'] = array( + '#type' => 'textfield', + '#title' => t('Separator'), + '#default_value' => $this->options['separator'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:options[type]' => array('separator')), + ); + } + + /** + * Render the field. + * + * This function is deprecated, but left in for older systems that have not + * yet or won't update their prerender list fields. If a render_item method + * exists, this will not get used by advanced_render. + */ + function render($values) { + $field = $values->{$this->field_alias}; + if (!empty($this->items[$field])) { + if ($this->options['type'] == 'separator') { + return implode(check_plain($this->options['separator']), $this->items[$field]); + } + else { + return theme('item_list', + array( + 'items' => $this->items[$field], + 'title' => NULL, + 'type' => $this->options['type'] + )); + } + } + } + + /** + * Render all items in this field together. + * + * When using advanced render, each possible item in the list is rendered + * individually. Then the items are all pasted together. + */ + function render_items($items) { + if (!empty($items)) { + if ($this->options['type'] == 'separator') { + return implode(check_plain($this->options['separator']), $items); + } + else { + return theme('item_list', + array( + 'items' => $items, + 'title' => NULL, + 'type' => $this->options['type'] + )); + } + } + } + + /** + * Return an array of items for the field. + * + * Items should be stored in the result array, if possible, as an array + * with 'value' as the actual displayable value of the item, plus + * any items that might be found in the 'alter' options array for + * creating links, such as 'path', 'fragment', 'query' etc, such a thing + * is to be made. Additionally, items that might be turned into tokens + * should also be in this array. + */ + function get_items($values) { + $field = $values->{$this->field_alias}; + if (!empty($this->items[$field])) { + return $this->items[$field]; + } + + return array(); + } + + /** + * Determine if advanced rendering is allowed. + * + * By default, advanced rendering will NOT be allowed if the class + * inheriting from this does not implement a 'render_items' method. + */ + function allow_advanced_render() { + // Note that the advanced render bits also use the presence of + // this method to determine if it needs to render items as a list. + return method_exists($this, 'render_item'); + } +} diff --git a/sites/all/modules/views/handlers/views_handler_field_url.inc b/sites/all/modules/views/handlers/views_handler_field_url.inc new file mode 100644 index 0000000000000000000000000000000000000000..dc3cd363cac8d6f4df672d4689b2130d0e9751a5 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_field_url.inc @@ -0,0 +1,39 @@ +<?php +// $Id: views_handler_field_url.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos Exp $ + +/** + * Field handler to provide simple renderer that turns a URL into a clickable link. + * + * @ingroup views_field_handlers + */ +class views_handler_field_url extends views_handler_field { + function option_definition() { + $options = parent::option_definition(); + + $options['display_as_link'] = array('default' => TRUE); + + return $options; + } + + /** + * Provide link to the page being visited. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['display_as_link'] = array( + '#title' => t('Display as link'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['display_as_link']), + ); + } + + function render($values) { + $value = $values->{$this->field_alias}; + if (!empty($this->options['display_as_link'])) { + return l(check_plain($value), $value, array('html' => TRUE)); + } + else { + return $value; + } + } +} diff --git a/sites/all/modules/views/handlers/views_handler_filter.inc b/sites/all/modules/views/handlers/views_handler_filter.inc new file mode 100644 index 0000000000000000000000000000000000000000..a67ac94fa202b94e3049134275b160e168fda497 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_filter.inc @@ -0,0 +1,551 @@ +<?php +// $Id: views_handler_filter.inc,v 1.10.4.15 2010/12/24 13:42:00 dereine Exp $ +/** + * @defgroup views_filter_handlers Views' filter handlers + * @{ + * Handlers to tell Views how to filter queries. + * + * Definition items: + * - allow empty: If true, the 'IS NULL' and 'IS NOT NULL' operators become + * available as standard operators. + * - + */ + +/** + * Base class for filters. + */ +class views_handler_filter extends views_handler { + /** + * Provide some extra help to get the operator/value easier to use. + * + * This likely has to be overridden by filters which are more complex + * than simple operator/value. + */ + function init(&$view, &$options) { + parent::init($view, $options); + + $this->operator = $this->options['operator']; + $this->value = $this->options['value']; + + // Compatibility: Set use_operator to true if the old way of using + // the operator is set and use_operator is NULL (was never set). + if (!empty($options['exposed']) && !empty($options['expose']['operator']) && !isset($options['expose']['use_operator'])) { + $this->options['expose']['use_operator'] = TRUE; + } + + // If there are relationships in the view, allow empty should be true + // so that we can do IS NULL checks on items. Not all filters respect + // allow empty, but string and numeric do and that covers enough. + if ($this->view->display_handler->get_option('relationships')) { + $this->definition['allow empty'] = TRUE; + } + } + + function option_definition() { + $options = parent::option_definition(); + + $options['operator'] = array('default' => '='); + $options['value'] = array('default' => ''); + $options['group'] = array('default' => '0'); + $options['exposed'] = array('default' => FALSE); + $options['expose'] = array( + 'contains' => array( + 'operator' => array('default' => FALSE), + 'label' => array('default' => '', 'translatable' => TRUE), + 'use_operator' => array('default' => 0), + 'operator' => array('default' => ''), + 'identifier' => array('default' => ''), + 'optional' => array('default' => 1), + 'remember' => array('default' => 0), + 'single' => array('default' => 1), + ), + ); + + return $options; + } + + /** + * Display the filter on the administrative summary + */ + function admin_summary() { + return check_plain((string) $this->operator) . ' ' . check_plain((string) $this->value); + } + + /** + * Determine if a filter can be exposed. + */ + function can_expose() { return TRUE; } + + /** + * Provide the basic form which calls through to subforms. + * If overridden, it is best to call through to the parent, + * or to at least make sure all of the functions in this form + * are called. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + if ($this->can_expose()) { + $this->show_expose_button($form, $form_state); + } + $form['op_val_start'] = array('#markup' => '<div class="clearfix">'); + $this->show_operator_form($form, $form_state); + $this->show_value_form($form, $form_state); + $form['op_val_end'] = array('#markup' => '</div>'); + if ($this->can_expose()) { + $this->show_expose_form($form, $form_state); + } + } + + /** + * Simple validate handler + */ + function options_validate(&$form, &$form_state) { + $this->operator_validate($form, $form_state); + $this->value_validate($form, $form_state); + if (!empty($this->options['exposed'])) { + $this->expose_validate($form, $form_state); + } + + } + + /** + * Simple submit handler + */ + function options_submit(&$form, &$form_state) { + unset($form_state['values']['expose_button']); // don't store this. + $this->operator_submit($form, $form_state); + $this->value_submit($form, $form_state); + if (!empty($this->options['exposed'])) { + $this->expose_submit($form, $form_state); + } + } + + /** + * Shortcut to display the operator form. + */ + function show_operator_form(&$form, &$form_state) { + $this->operator_form($form, $form_state); + $form['operator']['#prefix'] = '<div class="views-left-30">'; + $form['operator']['#suffix'] = '</div>'; + } + + /** + * Provide a form for setting the operator. + * + * This may be overridden by child classes, and it must + * define $form['operator']; + */ + function operator_form(&$form, &$form_state) { + $options = $this->operator_options(); + if (!empty($options)) { + $form['operator'] = array( + '#type' => count($options) < 10 ? 'radios' : 'select', + '#title' => t('Operator'), + '#default_value' => $this->operator, + '#options' => $options, + ); + } + } + + /** + * Provide a list of options for the default operator form. + * Should be overridden by classes that don't override operator_form + */ + function operator_options() { return array(); } + + /** + * Validate the operator form. + */ + function operator_validate($form, &$form_state) { } + + /** + * Perform any necessary changes to the form values prior to storage. + * There is no need for this function to actually store the data. + */ + function operator_submit($form, &$form_state) { } + + /** + * Shortcut to display the value form. + */ + function show_value_form(&$form, &$form_state) { + $this->value_form($form, $form_state); + if (empty($this->no_operator)) { + $form['value']['#prefix'] = '<div class="views-right-70">' . (isset($form['value']['#prefix']) ? $form['value']['#prefix'] : ''); + $form['value']['#suffix'] = (isset($form['value']['#suffix']) ? $form['value']['#suffix'] : '') . '</div>'; + } + } + + /** + * Provide a form for setting options. + * + * This should be overridden by all child classes and it must + * define $form['value'] + */ + function value_form(&$form, &$form_state) { $form['value'] = array(); } + + /** + * Validate the options form. + */ + function value_validate($form, &$form_state) { } + + /** + * Perform any necessary changes to the form values prior to storage. + * There is no need for this function to actually store the data. + */ + function value_submit($form, &$form_state) { } + + /** + * Handle the 'left' side fo the exposed options form. + */ + function expose_form_left(&$form, &$form_state) { + if (!empty($form['operator']['#type'])) { + $form['expose']['use_operator'] = array( + '#type' => 'checkbox', + '#title' => t('Unlock operator'), + '#description' => t('When checked, the operator will be exposed to the user'), + '#default_value' => !empty($this->options['expose']['use_operator']), + ); + $form['expose']['operator'] = array( + '#type' => 'textfield', + '#default_value' => $this->options['expose']['operator'], + '#title' => t('Operator identifier'), + '#size' => 40, + '#description' => t('This will appear in the URL after the ? to identify this operator.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-options-expose-use-operator' => array(1) + ), + ); + } + else { + $form['expose']['operator'] = array( + '#type' => 'value', + '#value' => '', + ); + } + + $form['expose']['identifier'] = array( + '#type' => 'textfield', + '#default_value' => $this->options['expose']['identifier'], + '#title' => t('Filter identifier'), + '#size' => 40, + '#description' => t('This will appear in the URL after the ? to identify this filter. Cannot be blank.'), + ); + $form['expose']['label'] = array( + '#type' => 'textfield', + '#default_value' => $this->options['expose']['label'], + '#title' => t('Label'), + '#size' => 40, + ); + } + + /** + * Handle the 'right' side fo the exposed options form. + */ + function expose_form_right(&$form, &$form_state) { + $form['expose']['optional'] = array( + '#type' => 'checkbox', + '#title' => t('Optional'), + '#description' => t('This exposed filter is optional and will have added options to allow it not to be set.'), + '#default_value' => $this->options['expose']['optional'], + ); + if (empty($this->no_single)) { + $form['expose']['single'] = array( + '#type' => 'checkbox', + '#title' => t('Force single'), + '#description' => t('Force this exposed filter to accept only one option.'), + '#default_value' => $this->options['expose']['single'], + ); + } + $form['expose']['remember'] = array( + '#type' => 'checkbox', + '#title' => t('Remember'), + '#description' => t('Remember the last setting the user gave this filter.'), + '#default_value' => $this->options['expose']['remember'], + ); + } + + /** + * Validate the options form. + */ + function expose_validate($form, &$form_state) { + if (empty($form_state['values']['options']['expose']['identifier'])) { + form_error($form['expose']['identifier'], t('The identifier is required if the filter is exposed.')); + } + + if (!empty($form_state['values']['options']['expose']['identifier']) && $form_state['values']['options']['expose']['identifier'] == 'value') { + form_error($form['expose']['identifier'], t('This identifier is not allowed.')); + } + + if (!$this->view->display_handler->is_identifier_unique($form_state['id'], $form_state['values']['options']['expose']['identifier'])) { + form_error($form['expose']['identifier'], t('This identifier is used by another handler.')); + } + } + + /** + * Provide default options for exposed filters. + */ + function expose_options() { + $this->options['expose'] = array( + 'use_operator' => FALSE, + 'operator' => $this->options['id'] . '_op', + 'identifier' => $this->options['id'], + 'label' => $this->ui_name(), + 'remember' => FALSE, + 'single' => TRUE, + 'optional' => TRUE, + ); + } + + /** + * Render our chunk of the exposed filter form when selecting + * + * You can override this if it doesn't do what you expect. + */ + function exposed_form(&$form, &$form_state) { + if (empty($this->options['exposed'])) { + return; + } + + // Build the exposed form, when its based on an operator. + if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator'])) { + $operator = $this->options['expose']['operator']; + $this->operator_form($form, $form_state); + $form[$operator] = $form['operator']; + + if (isset($form[$operator]['#title'])) { + unset($form[$operator]['#title']); + } + + $this->exposed_translate($form[$operator], 'operator'); + + unset($form['operator']); + } + + // Build the form and set the value based on the identifier. + if (!empty($this->options['expose']['identifier'])) { + $value = $this->options['expose']['identifier']; + $this->value_form($form, $form_state); + $form[$value] = $form['value']; + + if (isset($form[$value]['#title']) && !empty($form[$value]['#type']) && $form[$value]['#type'] != 'checkbox') { + unset($form[$value]['#title']); + } + + $this->exposed_translate($form[$value], 'value'); + + if (!empty($form['#type']) && ($form['#type'] == 'checkboxes' || ($form['#type'] == 'select' && !empty($form['#multiple'])))) { + unset($form[$value]['#default_value']); + } + + if (!empty($form['#type']) && $form['#type'] == 'select' && empty($form['#multiple'])) { + $form[$value]['#default_value'] = 'All'; + } + + if ($value != 'value') { + unset($form['value']); + } + } + } + + /** + * Make some translations to a form item to make it more suitable to + * exposing. + */ + function exposed_translate(&$form, $type) { + if (!isset($form['#type'])) { + return; + } + + if ($form['#type'] == 'radios') { + $form['#type'] = 'select'; + } + // Checkboxes don't work so well in exposed forms due to GET conversions. + if ($form['#type'] == 'checkboxes') { + if (empty($form['#no_convert']) || !empty($this->options['expose']['single'])) { + $form['#type'] = 'select'; + } + if (empty($this->options['expose']['single'])) { + $form['#multiple'] = TRUE; + } + } + if (!empty($this->options['expose']['single']) && isset($form['#multiple'])) { + unset($form['#multiple']); + $form['#size'] = NULL; + } + + if ($type == 'value' && !empty($this->options['expose']['optional']) && $form['#type'] == 'select' && empty($form['#multiple'])) { + $any_label = variable_get('views_exposed_filter_any_label', 'old_any') == 'old_any' ? t('<Any>') : t('- Any -'); + $form['#options'] = array('All' => $any_label) + $form['#options']; + $form['#default_value'] = 'All'; + } + } + + /** + * Tell the renderer about our exposed form. This only needs to be + * overridden for particularly complex forms. And maybe not even then. + * + * @return + * An array with the following keys: + * - operator: The $form key of the operator. Set to NULL if no operator. + * - value: The $form key of the value. Set to NULL if no value. + * - label: The label to use for this piece. + */ + function exposed_info() { + if (empty($this->options['exposed'])) { + return; + } + + return array( + 'operator' => $this->options['expose']['operator'], + 'value' => $this->options['expose']['identifier'], + 'label' => $this->options['expose']['label'], + ); + } + + /** + * Check to see if input from the exposed filters should change + * the behavior of this filter. + */ + function accept_exposed_input($input) { + if (empty($this->options['exposed'])) { + return TRUE; + } + + + if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator']) && isset($input[$this->options['expose']['operator']])) { + $this->operator = $input[$this->options['expose']['operator']]; + } + + if (!empty($this->options['expose']['identifier'])) { + $value = $input[$this->options['expose']['identifier']]; + + // Various ways to check for the absence of optional input. + if (!empty($this->options['expose']['optional'])) { + + if (($this->operator == 'empty' || $this->operator == 'not empty') && $value === '') { + $value = ' '; + } + + if ($this->operator != 'empty' && $this->operator != 'not empty') { + if ($value == 'All' || $value === array()) { + return FALSE; + } + } + + if (!empty($this->no_single) && $value === '') { + return FALSE; + } + } + + + if (isset($value)) { + $this->value = $value; + if (empty($this->no_single) && !empty($this->options['expose']['single'])) { + $this->value = array($value); + } + } + else { + return FALSE; + } + } + + return TRUE; + } + + function store_exposed_input($input, $status) { + if (empty($this->options['exposed']) || empty($this->options['expose']['identifier'])) { + return TRUE; + } + + if (empty($this->options['expose']['remember'])) { + return; + } + + // Figure out which display id is responsible for the filters, so we + // know where to look for session stored values. + $display_id = ($this->view->display_handler->is_defaulted('filters')) ? 'default' : $this->view->current_display; + + // shortcut test. + $operator = !empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator']); + + // false means that we got a setting that means to recuse ourselves, + // so we should erase whatever happened to be there. + if (!$status && isset($_SESSION['views'][$this->view->name][$display_id])) { + $session = &$_SESSION['views'][$this->view->name][$display_id]; + if ($operator && isset($session[$this->options['expose']['operator']])) { + unset($session[$this->options['expose']['operator']]); + } + + if (isset($session[$this->options['expose']['identifier']])) { + unset($session[$this->options['expose']['identifier']]); + } + } + + if ($status) { + if (!isset($_SESSION['views'][$this->view->name][$display_id])) { + $_SESSION['views'][$this->view->name][$display_id] = array(); + } + + $session = &$_SESSION['views'][$this->view->name][$display_id]; + + if ($operator && isset($input[$this->options['expose']['operator']])) { + $session[$this->options['expose']['operator']] = $input[$this->options['expose']['operator']]; + } + + $session[$this->options['expose']['identifier']] = $input[$this->options['expose']['identifier']]; + } + } + + /** + * Add this filter to the query. + * + * Due to the nature of fapi, the value and the operator have an unintended + * level of indirection. You will find them in $this->operator + * and $this->value respectively. + */ + function query() { + $this->ensure_my_table(); + $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field", $this->value, $this->operator); + } + + /** + * Can this filter be used in OR groups? + * + * Some filters have complicated where clauses that cannot be easily used + * with OR groups. Some filters must also use HAVING which also makes + * them not groupable. These filters will end up in a special group + * if OR grouping is in use. + */ + function can_group() { + return TRUE; + } +} + + +/** + * A special handler to take the place of missing or broken handlers. + */ +class views_handler_filter_broken extends views_handler_filter { + function ui_name($short = FALSE) { + return t('Broken/missing handler'); + } + + function ensure_my_table() { /* No table to ensure! */ } + function query() { /* No query to run */ } + function options_form(&$form, &$form_state) { + $form['markup'] = array( + '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>', + ); + } + + /** + * Determine if the handler is considered 'broken' + */ + function broken() { return TRUE; } +} + + +/** + * @} + */ diff --git a/sites/all/modules/views/handlers/views_handler_filter_boolean_operator.inc b/sites/all/modules/views/handlers/views_handler_filter_boolean_operator.inc new file mode 100644 index 0000000000000000000000000000000000000000..601b6169a2d483af30e560695eeca03bd512a66a --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_filter_boolean_operator.inc @@ -0,0 +1,163 @@ +<?php +// $Id: views_handler_filter_boolean_operator.inc,v 1.6.4.8 2010/12/09 23:52:48 merlinofchaos Exp $ +/** + * Simple filter to handle matching of boolean values + * + * Definition items: + * - label: (REQUIRED) The label for the checkbox. + * - type: For basic 'true false' types, an item can specify the following: + * - true-false: True/false (this is the default) + * - yes-no: Yes/No + * - on-off: On/Off + * - accept null: Treat a NULL value as false. + */ +class views_handler_filter_boolean_operator extends views_handler_filter { + // exposed filter options + var $no_single = TRUE; + // Don't display empty space where the operator would be. + var $no_operator = TRUE; + // Whether to accept NULL as a false value or not + var $accept_null = FALSE; + + function construct() { + $this->value_value = t('True'); + if (isset($this->definition['label'])) { + $this->value_value = $this->definition['label']; + } + if (isset($this->definition['accept null'])) { + $this->accept_null = (bool) $this->definition['accept null']; + } + else if (isset($this->definition['accept_null'])) { + $this->accept_null = (bool) $this->definition['accept_null']; + } + $this->value_options = NULL; + parent::construct(); + } + + /** + * Return the possible options for this filter. + * + * Child classes should override this function to set the possible values + * for the filter. Since this is a boolean filter, the array should have + * two possible keys: 1 for "True" and 0 for "False", although the labels + * can be whatever makes sense for the filter. These values are used for + * configuring the filter, when the filter is exposed, and in the admin + * summary of the filter. Normally, this should be static data, but if it's + * dynamic for some reason, child classes should use a guard to reduce + * database hits as much as possible. + */ + function get_value_options() { + if (isset($this->definition['type'])) { + if ($this->definition['type'] == 'yes-no') { + $this->value_options = array(1 => t('Yes'), 0 => t('No')); + } + if ($this->definition['type'] == 'on-off') { + $this->value_options = array(1 => t('On'), 0 => t('Off')); + } + } + + // Provide a fallback if the above didn't set anything. + if (!isset($this->value_options)) { + $this->value_options = array(1 => t('True'), 0 => t('False')); + } + } + + function option_definition() { + $options = parent::option_definition(); + + $options['value']['default'] = FALSE; + + return $options; + } + + function operator_form(&$form, &$form_state) { + $form['operator'] = array(); + } + + function value_form(&$form, &$form_state) { + if (empty($this->value_options)) { + // Initialize the array of possible values for this filter. + $this->get_value_options(); + } + if (!empty($form_state['exposed'])) { + // Exposed filter: use a select box to save space. + $filter_form_type = 'select'; + } + else { + // Configuring a filter: use radios for clarity. + $filter_form_type = 'radios'; + } + $form['value'] = array( + '#type' => $filter_form_type, + '#title' => $this->value_value, + '#options' => $this->value_options, + '#default_value' => $this->value, + ); + if (!empty($this->options['exposed'])) { + $identifier = $this->options['expose']['identifier']; + if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) { + $form_state['input'][$identifier] = $this->value; + } + // If we're configuring an exposed filter, add an <Any> option. + if (empty($form_state['exposed']) || !empty($this->options['optional'])) { + $any_label = variable_get('views_exposed_filter_any_label', 'old_any') == 'old_any' ? '<Any>' : t('- Any -'); + if ($form['value']['#type'] != 'select') { + $any_label = check_plain($any_label); + } + $form['value']['#options'] = array('All' => $any_label) + $form['value']['#options']; + } + } + } + + function value_validate($form, &$form_state) { + if ($form_state['values']['options']['value'] == 'All' && empty($form_state['values']['options']['expose']['optional'])) { + form_set_error('value', t('You must select a value unless this is an optional exposed filter.')); + } + } + + function admin_summary() { + if (!empty($this->options['exposed'])) { + return t('exposed'); + } + if (empty($this->value_options)) { + $this->get_value_options(); + } + // Now that we have the valid options for this filter, just return the + // human-readable label based on the current value. The value_options + // array is keyed with either 0 or 1, so if the current value is not + // empty, use the label for 1, and if it's empty, use the label for 0. + return $this->value_options[!empty($this->value)]; + } + + function expose_options() { + parent::expose_options(); + $this->options['expose']['operator'] = ''; + $this->options['expose']['label'] = $this->value_value; + $this->options['expose']['optional'] = FALSE; + } + + function query() { + $this->ensure_my_table(); + $field = "$this->table_alias.$this->real_field"; + + if (empty($this->value)) { + if ($this->accept_null) { + $or = db_or() + ->condition($field, 0, '=') + ->condition($field, NULL, 'IS NULL'); + $this->query->add_where($this->options['group'], $or); + } + else { + $this->query->add_where($this->options['group'], $field, 0, '='); + } + } + else { + if (!empty($this->definition['use equal'])) { + $this->query->add_where($this->options['group'], $field, 1, '='); + } + else { + $this->query->add_where($this->options['group'], $field, 0, '<>'); + } + } + } +} diff --git a/sites/all/modules/views/handlers/views_handler_filter_boolean_operator_string.inc b/sites/all/modules/views/handlers/views_handler_filter_boolean_operator_string.inc new file mode 100644 index 0000000000000000000000000000000000000000..f5b5cb17ecd27ac10e8c7a16921ae3ffb7bf1069 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_filter_boolean_operator_string.inc @@ -0,0 +1,28 @@ +<?php +// $Id: views_handler_filter_boolean_operator_string.inc,v 1.2.4.1 2009/11/02 22:01:25 merlinofchaos Exp $ +/** + * Simple filter to handle matching of boolean values. + * + * This handler checks to see if a string field is empty (equal to '') or not. + * It is otherwise identical to the parent operator. + * + * Definition items: + * - label: (REQUIRED) The label for the checkbox. + */ +class views_handler_filter_boolean_operator_string extends views_handler_filter_boolean_operator { + function query() { + $this->ensure_my_table(); + $where = "$this->table_alias.$this->real_field "; + + if (empty($this->value)) { + $where .= "= ''"; + if ($this->accept_null) { + $where = '(' . $where . " OR $this->table_alias.$this->real_field IS NULL)"; + } + } + else { + $where .= "<> ''"; + } + $this->query->add_where($this->options['group'], $where); + } +} diff --git a/sites/all/modules/views/handlers/views_handler_filter_date.inc b/sites/all/modules/views/handlers/views_handler_filter_date.inc new file mode 100644 index 0000000000000000000000000000000000000000..8493169242c397f932dff415af3d4728e25dfa1e --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_filter_date.inc @@ -0,0 +1,155 @@ +<?php +// $Id: views_handler_filter_date.inc,v 1.3.6.7 2011/01/03 17:46:33 dereine Exp $ + +/** + * Filter to handle dates stored as a timestamp. + */ +class views_handler_filter_date extends views_handler_filter_numeric { + function option_definition() { + $options = parent::option_definition(); + + // value is already set up properly, we're just adding our new field to it. + $options['value']['contains']['type']['default'] = 'date'; + + return $options; + } + + /** + * Add a type selector to the value form + */ + function value_form(&$form, &$form_state) { + if (empty($form_state['exposed'])) { + $form['value']['type'] = array( + '#type' => 'radios', + '#title' => t('Value type'), + '#options' => array( + 'date' => t('A date in any machine readable format. CCYY-MM-DD HH:MM:SS is preferred.'), + 'offset' => t('An offset from the current time such as "!example1" or "!example2"', array('!example1' => '+1 day', '!example2' => '-2 hours -30 minutes')), + ), + '#default_value' => !empty($this->value['type']) ? $this->value['type'] : 'date', + ); + } + parent::value_form($form, $form_state); + } + + function options_validate(&$form, &$form_state) { + parent::options_validate($form, $form_state); + + if (!empty($form_state['values']['options']['expose']['optional'])) { + // Who cares what the value is if it's exposed and optional. + return; + } + + $this->validate_valid_time($form['value'], $form_state['values']['options']['operator'], $form_state['values']['options']['value']); + } + + function exposed_validate(&$form, &$form_state) { + if (empty($this->options['exposed'])) { + return; + } + + if (!empty($this->options['expose']['optional'])) { + // Who cares what the value is if it's exposed and optional. + return; + } + + $value = &$form_state['values'][$this->options['expose']['identifier']]; + if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator'])) { + $operator = $form_state['values'][$this->options['expose']['operator']]; + } + else { + $operator = $this->operator; + } + + $this->validate_valid_time($this->options['expose']['identifier'], $operator, $value); + + } + + /** + * Validate that the time values convert to something usable. + */ + function validate_valid_time(&$form, $operator, $value) { + $operators = $this->operators(); + + if ($operators[$operator]['values'] == 1) { + $convert = strtotime($value['value']); + if (!empty($form['value']) && ($convert == -1 || $convert === FALSE)) { + form_error($form['value'], t('Invalid date format.')); + } + } + elseif ($operators[$operator]['values'] == 2) { + $min = strtotime($value['min']); + if ($min == -1 || $min === FALSE) { + form_error($form['min'], t('Invalid date format.')); + } + $max = strtotime($value['max']); + if ($max == -1 || $max === FALSE) { + form_error($form['max'], t('Invalid date format.')); + } + } + } + + function accept_exposed_input($input) { + if (empty($this->options['exposed'])) { + return TRUE; + } + + // Store this because it will get overwritten. + $type = $this->value['type']; + $rc = parent::accept_exposed_input($input); + + // Don't filter if value(s) are empty. + $operators = $this->operators(); + if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator'])) { + $operator = $input[$this->options['expose']['operator']]; + } + else { + $operator = $this->operator; + } + + if ($operators[$operator]['values'] == 1) { + if ($this->value['value'] == '') { + return FALSE; + } + } + else { + if ($this->value['min'] == '' || $this->value['max'] == '') { + return FALSE; + } + } + + // restore what got overwritten by the parent. + $this->value['type'] = $type; + return $rc; + } + + function op_between($field) { + if ($this->operator == 'between') { + $a = intval(strtotime($this->value['min'], 0)); + $b = intval(strtotime($this->value['max'], 0)); + } + else { + $a = intval(strtotime($this->value['max'], 0)); + $b = intval(strtotime($this->value['min'], 0)); + } + + if ($this->value['type'] == 'offset') { + $a = '***CURRENT_TIME***' . sprintf('%+d', $a); // keep sign + $b = '***CURRENT_TIME***' . sprintf('%+d', $b); // keep sign + } + // %s is safe here because strtotime scrubbed the input and we might + // have a string if using offset. + $placeholder1 = $this->placeholder(); + $placeholder2 = $this->placeholder(); + $this->query->add_where($this->options['group'], "$field BETWEEN $placeholder1 AND $placeholder2", array($placeholder1 => $a, $placeholder2 => $b), 'formula'); + } + + function op_simple($field) { + $value = intval(strtotime($this->value['value'], 0)); + if (!empty($this->value['type']) && $this->value['type'] == 'offset') { + $value = '***CURRENT_TIME***' . sprintf('%+d', $value); // keep sign + } + $placeholder = $this->placeholder(); + $this->query->add_where($this->options['group'], "$field $this->operator $placeholder", array($placeholder => $value), 'formula'); + } +} diff --git a/sites/all/modules/views/handlers/views_handler_filter_equality.inc b/sites/all/modules/views/handlers/views_handler_filter_equality.inc new file mode 100644 index 0000000000000000000000000000000000000000..cd5a6182b24f2bf96f8722d387ae50bc1eb3faeb --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_filter_equality.inc @@ -0,0 +1,39 @@ +<?php +// $Id: views_handler_filter_equality.inc,v 1.2 2008/09/10 01:08:06 merlinofchaos Exp $ +/** + * Simple filter to handle equal to / not equal to filters + */ +class views_handler_filter_equality extends views_handler_filter { + // exposed filter options + var $no_single = TRUE; + + /** + * Provide simple equality operator + */ + function operator_options() { + return array( + '=' => t('Is equal to'), + '!=' => t('Is not equal to'), + ); + } + + /** + * Provide a simple textfield for equality + */ + function value_form(&$form, &$form_state) { + $form['value'] = array( + '#type' => 'textfield', + '#title' => t('Value'), + '#size' => 30, + '#default_value' => $this->value, + ); + + if (!empty($form_state['exposed'])) { + $identifier = $this->options['expose']['identifier']; + if (!isset($form_state['input'][$identifier])) { + $form_state['input'][$identifier] = $this->value; + } + } + } +} + diff --git a/sites/all/modules/views/handlers/views_handler_filter_group_by_numeric.inc b/sites/all/modules/views/handlers/views_handler_filter_group_by_numeric.inc new file mode 100644 index 0000000000000000000000000000000000000000..b65773f83fd0950d2fd60e7cf5465ffa51efe26c --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_filter_group_by_numeric.inc @@ -0,0 +1,52 @@ +<?php +// $Id: views_handler_filter_group_by_numeric.inc,v 1.1.4.7 2011/01/04 00:55:39 dereine Exp $ + +/** + * Simple filter to handle greater than/less than filters + */ +class views_handler_filter_group_by_numeric extends views_handler_filter_numeric { + function query() { + $this->ensure_my_table(); + $field = $this->get_field(); + + $info = $this->operators(); + if (!empty($info[$this->operator]['method'])) { + $this->{$info[$this->operator]['method']}($field); + } + } + function op_between($field) { + $placeholder = $this->placeholder(); + if ($this->operator == 'between') { + $this->query->add_having_expression($this->options['group'], "$field >= $placeholder", array($placeholder => $this->value['min'])); + $this->query->add_having_expression($this->options['group'], "$field <= $placeholder", array($placeholder => $this->value['max'])); + } + else { + $placeholder_min = $placeholder; + $placeholder_max = $this->placeholder(); + $this->query->add_having_expression($this->options['group'], "$field <= $placeholder_min OR $field >= $placeholder_max", array($placeholder_min => $this->value['min'], $placeholder_max => $this->value['max'])); + } + } + + function op_simple($field) { + $placeholder = $this->placeholder(); + $this->query->add_having_expression($this->options['group'], "$field $this->operator $placeholder", array($placeholder => $this->value['value'])); + } + + function op_empty($field) { + if ($this->operator == 'empty') { + $operator = "IS NULL"; + } + else { + $operator = "IS NOT NULL"; + } + + $this->query->add_having_expression($this->options['group'], "$field $operator"); + } + + function ui_name($short = FALSE) { + return $this->get_field(parent::ui_name($short)); + } + + function can_group() { return FALSE; } +} + diff --git a/sites/all/modules/views/handlers/views_handler_filter_in_operator.inc b/sites/all/modules/views/handlers/views_handler_filter_in_operator.inc new file mode 100644 index 0000000000000000000000000000000000000000..9c000120873573df0c2a2bedaa5d0b79a967781c --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_filter_in_operator.inc @@ -0,0 +1,366 @@ +<?php +// $Id: views_handler_filter_in_operator.inc,v 1.12.4.11 2010/12/16 01:06:06 merlinofchaos Exp $ +/** + * Simple filter to handle matching of multiple options selectable via checkboxes + * + * Definition items: + * - numeric: If set to true, this item will use numeric operators instead of string. + * - options callback: The function to call in order to generate the value options. If omitted, the options 'Yes' and 'No' will be used. + * - options arguments: An array of arguments to pass to the options callback. + * + */ +class views_handler_filter_in_operator extends views_handler_filter { + var $value_form_type = 'checkboxes'; + + function construct() { + parent::construct(); + $this->value_title = t('Options'); + $this->value_options = NULL; + } + + /** + * Child classes should be used to override this function and set the + * 'value options', unless 'options callback' is defined as a valid function + * or static public method to generate these values. + * + * This can use a guard to be used to reduce database hits as much as + * possible. + */ + function get_value_options() { + if (isset($this->value_options)) { + return; + } + + if (isset($this->definition['options callback']) && is_callable($this->definition['options callback'])) { + if (isset($this->definition['options arguments']) && is_array($this->definition['options arguments'])) { + $this->value_options = call_user_func_array($this->definition['options callback'], $this->definition['options arguments']); + } + else { + $this->value_options = call_user_func($this->definition['options callback']); + } + } + else { + $this->value_options = array(t('Yes'), t('No')); + } + } + + function expose_options() { + parent::expose_options(); + $this->options['expose']['reduce'] = FALSE; + } + + function expose_form_right(&$form, &$form_state) { + parent::expose_form_right($form, $form_state); + $form['expose']['reduce'] = array( + '#type' => 'checkbox', + '#title' => t('Limit list to selected items'), + '#description' => t('If checked, the only items presented to the user will be the ones selected here.'), + '#default_value' => !empty($this->options['expose']['reduce']), // safety + ); + } + + function option_definition() { + $options = parent::option_definition(); + + $options['operator']['default'] = 'in'; + $options['value']['default'] = array(); + $options['expose']['contains']['reduce'] = array('default' => FALSE); + + return $options; + } + + /** + * This kind of construct makes it relatively easy for a child class + * to add or remove functionality by overriding this function and + * adding/removing items from this array. + */ + function operators() { + $operators = array( + 'in' => array( + 'title' => t('Is one of'), + 'short' => t('in'), + 'short_single' => t('='), + 'method' => 'op_simple', + 'values' => 1, + ), + 'not in' => array( + 'title' => t('Is not one of'), + 'short' => t('not in'), + 'short_single' => t('<>'), + 'method' => 'op_simple', + 'values' => 1, + ), + ); + // if the definition allows for the empty operator, add it. + if (!empty($this->definition['allow empty'])) { + $operators += array( + 'empty' => array( + 'title' => t('Is empty (NULL)'), + 'method' => 'op_empty', + 'short' => t('empty'), + 'values' => 0, + ), + 'not empty' => array( + 'title' => t('Is not empty (NOT NULL)'), + 'method' => 'op_empty', + 'short' => t('not empty'), + 'values' => 0, + ), + ); + } + + return $operators; + } + + /** + * Build strings from the operators() for 'select' options + */ + function operator_options($which = 'title') { + $options = array(); + foreach ($this->operators() as $id => $info) { + $options[$id] = $info[$which]; + } + + return $options; + } + + function operator_values($values = 1) { + $options = array(); + foreach ($this->operators() as $id => $info) { + if (isset($info['values']) && $info['values'] == $values) { + $options[] = $id; + } + } + + return $options; + } + + function value_form(&$form, &$form_state) { + $form['value'] = array(); + + $this->get_value_options(); + $options = $this->value_options; + $default_value = (array) $this->value; + + $which = 'all'; + if (!empty($form['operator'])) { + $source = ($form['operator']['#type'] == 'radios') ? 'radio:options[operator]' : 'edit-options-operator'; + } + if (!empty($form_state['exposed'])) { + $identifier = $this->options['expose']['identifier']; + + if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator'])) { + // exposed and locked. + $which = in_array($this->operator, $this->operator_values(1)) ? 'value' : 'none'; + } + else { + $source = 'edit-' . drupal_html_id($this->options['expose']['operator']); + } + + if (!empty($this->options['expose']['reduce'])) { + $options = $this->reduce_value_options(); + + if (empty($this->options['expose']['single']) && !empty($this->options['expose']['optional'])) { + $default_value = array(); + } + } + + if (!empty($this->options['expose']['single'])) { + if (!empty($this->options['expose']['optional']) && (empty($default_value) || !empty($this->options['expose']['reduce']))) { + $default_value = 'All'; + } + elseif (empty($default_value)) { + $keys = array_keys($options); + $default_value = array_shift($keys); + } + else { + $copy = $default_value; + $default_value = array_shift($copy); + } + } + } + + if ($which == 'all' || $which == 'value') { + $form['value'] = array( + '#type' => $this->value_form_type, + '#title' => $this->value_title, + '#options' => $options, + '#default_value' => $default_value, + // These are only valid for 'select' type, but do no harm to checkboxes. + '#multiple' => TRUE, + '#size' => count($options) > 8 ? 8 : count($options), + ); + if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) { + $form_state['input'][$identifier] = $default_value; + } + + $process = array(); + if ($this->value_form_type == 'checkboxes') { + // If this form element will use checkboxes in the UI, we need to + // check_plain() all the options ourselves since FAPI is inconsistent + // about this. However, instead of directly doing that to the #options + // right now, we define a #process callback since we might change our + // mind later and convert this into a 'select' form element, which + // would lead to double-escaping the options. + $process[] = 'views_process_check_options'; + } + if ($which == 'all') { + if (empty($form_state['exposed']) && (in_array($this->value_form_type, array('checkbox', 'checkboxes', 'radios', 'select')))) { + $process[] = "form_process_$this->value_form_type"; + $form['value']['#prefix'] = '<div id="edit-options-value-wrapper">'; + $form['value']['#suffix'] = '</div>'; + } + $process[] = 'ctools_dependent_process'; + $form['value']['#dependency'] = array($source => $this->operator_values(1)); + } + if (!empty($process)) { + $form['value']['#process'] = $process; + } + } + } + + /** + * When using exposed filters, we may be required to reduce the set. + */ + function reduce_value_options($input = NULL) { + if (!isset($input)) { + $input = $this->value_options; + } + + // Because options may be an array of strings, or an array of mixed arrays + // and strings (optgroups) or an array of objects, we have to + // step through and handle each one individually. + $options = array(); + foreach ($input as $id => $option) { + if (is_array($option)) { + $options[$id] = $this->reduce_value_options($option); + continue; + } + elseif (is_object($option)) { + $keys = array_keys($option->option); + $key = array_shift($keys); + if (isset($this->options['value'][$key])) { + $options[$id] = $option; + } + } + elseif (isset($this->options['value'][$id])) { + $options[$id] = $option; + } + } + return $options; + } + + function accept_exposed_input($input) { + // A very special override because the All state for this type of + // filter could have a default: + if (empty($this->options['exposed'])) { + return TRUE; + } + + // If this is single and optional, this says that yes this filter will + // participate, but using the default settings, *if* 'limit is true. + if (!empty($this->options['expose']['single']) && !empty($this->options['expose']['optional']) && !empty($this->options['expose']['limit'])) { + $identifier = $this->options['expose']['identifier']; + if ($input[$identifier] == 'All') { + return TRUE; + } + } + + return parent::accept_exposed_input($input); + } + + function value_submit($form, &$form_state) { + // Drupal's FAPI system automatically puts '0' in for any checkbox that + // was not set, and the key to the checkbox if it is set. + // Unfortunately, this means that if the key to that checkbox is 0, + // we are unable to tell if that checkbox was set or not. + + // Luckily, the '#value' on the checkboxes form actually contains + // *only* a list of checkboxes that were set, and we can use that + // instead. + + $form_state['values']['options']['value'] = $form['value']['#value']; + } + + function admin_summary() { + if (!empty($this->options['exposed'])) { + return t('exposed'); + } + $info = $this->operators(); + + $this->get_value_options(); + + if (!is_array($this->value)) { + return; + } + + $operator = check_plain($info[$this->operator]['short']); + $values = ''; + if (in_array($this->operator, $this->operator_values(1))) { + // Remove every element which is not known. + foreach ($this->value as $value) { + if (!isset($this->value_options[$value])) { + unset($this->value[$value]); + } + } + // Choose different kind of ouput for 0, a single and multiple values. + if (count($this->value) == 0) { + $values = t('Unknown'); + } + else if (count($this->value) == 1) { + // If any, use the 'single' short name of the operator instead. + if (isset($info[$this->operator]['short_single'])) { + $operator = check_plain($info[$this->operator]['short_single']); + } + + $keys = $this->value; + $value = array_shift($keys); + $values = check_plain($this->value_options[$value]); + } + else { + foreach ($this->value as $value) { + if ($values !== '') { + $values .= ', '; + } + if (strlen($values) > 8) { + $values .= '...'; + break; + } + $values .= check_plain($this->value_options[$value]); + } + } + } + + return $operator . (($values !== '') ? ' ' . $values : ''); + } + + function query() { + $info = $this->operators(); + if (!empty($info[$this->operator]['method'])) { + $this->{$info[$this->operator]['method']}(); + } + } + + function op_simple() { + if (empty($this->value)) { + return; + } + $this->ensure_my_table(); + + // We use array_values() because the checkboxes keep keys and that can cause + // array addition problems. + $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field", array_values($this->value), $this->operator); + } + + function op_empty() { + $this->ensure_my_table(); + if ($this->operator == 'empty') { + $operator = "IS NULL"; + } + else { + $operator = "IS NOT NULL"; + } + + $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field", NULL, $operator); + } +} diff --git a/sites/all/modules/views/handlers/views_handler_filter_many_to_one.inc b/sites/all/modules/views/handlers/views_handler_filter_many_to_one.inc new file mode 100644 index 0000000000000000000000000000000000000000..68716543f3fcfaa37331cbaadbc19774b7aaa11c --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_filter_many_to_one.inc @@ -0,0 +1,106 @@ +<?php +// $Id: views_handler_filter_many_to_one.inc,v 1.2.4.5 2010/10/12 22:14:55 merlinofchaos Exp $ + +/** + * Complex filter to handle filtering for many to one relationships, + * such as terms (many terms per node) or roles (many roles per user). + * + * The construct method needs to be overridden to provide a list of options; + * alternately, the value_form and admin_summary methods need to be overriden + * to provide something that isn't just a select list. + */ +class views_handler_filter_many_to_one extends views_handler_filter_in_operator { + function init(&$view, &$options) { + parent::init($view, $options); + $this->helper = new views_many_to_one_helper($this); + } + + function option_definition() { + $options = parent::option_definition(); + + $options['operator']['default'] = 'or'; + $options['value']['default'] = array(); + + views_many_to_one_helper::option_definition($options); + + return $options; + } + + function operators() { + $operators = array( + 'or' => array( + 'title' => t('Is one of'), + 'short' => t('or'), + 'short_single' => t('='), + 'method' => 'op_helper', + 'values' => 1, + 'ensure_my_table' => 'helper', + ), + 'and' => array( + 'title' => t('Is all of'), + 'short' => t('and'), + 'short_single' => t('='), + 'method' => 'op_helper', + 'values' => 1, + 'ensure_my_table' => 'helper', + ), + 'not' => array( + 'title' => t('Is none of'), + 'short' => t('not'), + 'short_single' => t('<>'), + 'method' => 'op_helper', + 'values' => 1, + 'ensure_my_table' => 'helper', + ), + ); + // if the definition allows for the empty operator, add it. + if (!empty($this->definition['allow empty'])) { + $operators += array( + 'empty' => array( + 'title' => t('Is empty (NULL)'), + 'method' => 'op_empty', + 'short' => t('empty'), + 'values' => 0, + ), + 'not empty' => array( + 'title' => t('Is not empty (NOT NULL)'), + 'method' => 'op_empty', + 'short' => t('not empty'), + 'values' => 0, + ), + ); + } + + return $operators; + } + + var $value_form_type = 'select'; + function value_form(&$form, &$form_state) { + parent::value_form($form, $form_state); + + if (empty($form_state['exposed'])) { + $this->helper->options_form($form, $form_state); + } + } + + /** + * Override ensure_my_table so we can control how this joins in. + * The operator actually has influence over joining. + */ + function ensure_my_table() { + // Defer to helper if the operator specifies it. + $info = $this->operators(); + if (isset($info[$this->operator]['ensure_my_table']) && $info[$this->operator]['ensure_my_table'] == 'helper') { + return $this->helper->ensure_my_table(); + } + + return parent::ensure_my_table(); + } + + function op_helper() { + if (empty($this->value)) { + return; + } + $this->helper->add_filter(); + } +} diff --git a/sites/all/modules/views/handlers/views_handler_filter_numeric.inc b/sites/all/modules/views/handlers/views_handler_filter_numeric.inc new file mode 100644 index 0000000000000000000000000000000000000000..0c5ce5756658b238204084edb56b842a70a4e391 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_filter_numeric.inc @@ -0,0 +1,302 @@ +<?php +// $Id: views_handler_filter_numeric.inc,v 1.7.6.7 2011/01/01 10:59:37 dereine Exp $ + +/** + * Simple filter to handle greater than/less than filters + */ +class views_handler_filter_numeric extends views_handler_filter { + var $no_single = TRUE; + function option_definition() { + $options = parent::option_definition(); + + $options['value'] = array( + 'contains' => array( + 'min' => array('default' => ''), + 'max' => array('default' => ''), + 'value' => array('default' => ''), + ), + ); + + return $options; + } + + function operators() { + $operators = array( + '<' => array( + 'title' => t('Is less than'), + 'method' => 'op_simple', + 'short' => t('<'), + 'values' => 1, + ), + '<=' => array( + 'title' => t('Is less than or equal to'), + 'method' => 'op_simple', + 'short' => t('<='), + 'values' => 1, + ), + '=' => array( + 'title' => t('Is equal to'), + 'method' => 'op_simple', + 'short' => t('='), + 'values' => 1, + ), + '!=' => array( + 'title' => t('Is not equal to'), + 'method' => 'op_simple', + 'short' => t('!='), + 'values' => 1, + ), + '>=' => array( + 'title' => t('Is greater than or equal to'), + 'method' => 'op_simple', + 'short' => t('>='), + 'values' => 1, + ), + '>' => array( + 'title' => t('Is greater than'), + 'method' => 'op_simple', + 'short' => t('>'), + 'values' => 1, + ), + 'between' => array( + 'title' => t('Is between'), + 'method' => 'op_between', + 'short' => t('between'), + 'values' => 2, + ), + 'not between' => array( + 'title' => t('Is not between'), + 'method' => 'op_between', + 'short' => t('not between'), + 'values' => 2, + ), + ); + + // if the definition allows for the empty operator, add it. + if (!empty($this->definition['allow empty'])) { + $operators += array( + 'empty' => array( + 'title' => t('Is empty (NULL)'), + 'method' => 'op_empty', + 'short' => t('empty'), + 'values' => 0, + ), + 'not empty' => array( + 'title' => t('Is not empty (NOT NULL)'), + 'method' => 'op_empty', + 'short' => t('not empty'), + 'values' => 0, + ), + ); + } + + return $operators; + } + + /** + * Provide a list of all the numeric operators + */ + function operator_options($which = 'title') { + $options = array(); + foreach ($this->operators() as $id => $info) { + $options[$id] = $info[$which]; + } + + return $options; + } + + function operator_values($values = 1) { + $options = array(); + foreach ($this->operators() as $id => $info) { + if ($info['values'] == $values) { + $options[] = $id; + } + } + + return $options; + } + /** + * Provide a simple textfield for equality + */ + function value_form(&$form, &$form_state) { + $form['value']['#tree'] = TRUE; + + // We have to make some choices when creating this as an exposed + // filter form. For example, if the operator is locked and thus + // not rendered, we can't render dependencies; instead we only + // render the form items we need. + $which = 'all'; + if (!empty($form['operator'])) { + $source = ($form['operator']['#type'] == 'radios') ? 'radio:options[operator]' : 'edit-options-operator'; + } + + if (!empty($form_state['exposed'])) { + $identifier = $this->options['expose']['identifier']; + + if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator'])) { + // exposed and locked. + $which = in_array($this->operator, $this->operator_values(2)) ? 'minmax' : 'value'; + } + else { + $source = 'edit-' . drupal_html_id($this->options['expose']['operator']); + } + } + + if ($which == 'all') { + $form['value']['value'] = array( + '#type' => 'textfield', + '#title' => empty($form_state['exposed']) ? t('Value') : '', + '#size' => 30, + '#default_value' => $this->value['value'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array($source => $this->operator_values(1)), + ); + if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['value'])) { + $form_state['input'][$identifier]['value'] = $this->value['value']; + } + } + elseif ($which == 'value') { + // When exposed we drop the value-value and just do value if + // the operator is locked. + $form['value'] = array( + '#type' => 'textfield', + '#title' => empty($form_state['exposed']) ? t('Value') : '', + '#size' => 30, + '#default_value' => $this->value['value'], + ); + if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) { + $form_state['input'][$identifier] = $this->value['value']; + } + } + + if ($which == 'all' || $which == 'minmax') { + $form['value']['min'] = array( + '#type' => 'textfield', + '#title' => empty($form_state['exposed']) ? t('Min') : '', + '#size' => 30, + '#default_value' => $this->value['min'], + ); + $form['value']['max'] = array( + '#type' => 'textfield', + '#title' => empty($form_state['exposed']) ? t('And max') : t('And'), + '#size' => 30, + '#default_value' => $this->value['max'], + ); + if ($which == 'all') { + $dependency = array( + '#process' => array('ctools_dependent_process'), + '#dependency' => array($source => $this->operator_values(2)), + ); + $form['value']['min'] += $dependency; + $form['value']['max'] += $dependency; + } + if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['min'])) { + $form_state['input'][$identifier]['min'] = $this->value['min']; + } + if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier]['max'])) { + $form_state['input'][$identifier]['max'] = $this->value['max']; + } + + if (!isset($form['value'])) { + // Ensure there is something in the 'value'. + $form['value'] = array( + '#type' => 'value', + '#value' => NULL + ); + } + } + } + + function query() { + $this->ensure_my_table(); + $field = "$this->table_alias.$this->real_field"; + + $info = $this->operators(); + if (!empty($info[$this->operator]['method'])) { + $this->{$info[$this->operator]['method']}($field); + } + } + + function op_between($field) { + if ($this->operator == 'between') { + $this->query->add_where($this->options['group'], $field, array($this->value['min'], $this->value['max']), 'BETWEEN'); + } + else { + $this->query->add_where($this->options['group'], db_or()->condition($field, $this->value['min'], '<=')->condition($field, $this->value['max'], '>=')); + } + } + + function op_simple($field) { + $this->query->add_where($this->options['group'], $field, $this->value['value'], $this->operator); + } + + function op_empty($field) { + if ($this->operator == 'empty') { + $operator = "IS NULL"; + } + else { + $operator = "IS NOT NULL"; + } + + $this->query->add_where($this->options['group'], $field, NULL, $operator); + } + + function admin_summary() { + if (!empty($this->options['exposed'])) { + return t('exposed'); + } + + $options = $this->operator_options('short'); + $output = check_plain($options[$this->operator]); + if (in_array($this->operator, $this->operator_values(2))) { + $output .= ' ' . t('@min and @max', array('@min' => $this->value['min'], '@max' => $this->value['max'])); + } + elseif (in_array($this->operator, $this->operator_values(1))) { + $output .= ' ' . check_plain($this->value['value']); + } + return $output; + } + + /** + * Do some minor translation of the exposed input + */ + function accept_exposed_input($input) { + if (empty($this->options['exposed'])) { + return TRUE; + } + + // rewrite the input value so that it's in the correct format so that + // the parent gets the right data. + if (!empty($this->options['expose']['identifier'])) { + $value = &$input[$this->options['expose']['identifier']]; + if (!is_array($value)) { + $value = array( + 'value' => $value, + ); + } + } + + $rc = parent::accept_exposed_input($input); + + if (!empty($this->options['expose']['optional'])) { + // We have to do some of our own optional checking. + $info = $this->operators(); + if (!empty($info[$this->operator]['values'])) { + switch ($info[$this->operator]['values']) { + case 1: + if ($value['value'] === '') { + return FALSE; + } + break; + case 2: + if ($value['min'] === '' && $value['max'] === '') { + return FALSE; + } + break; + } + } + } + + return $rc; + } +} diff --git a/sites/all/modules/views/handlers/views_handler_filter_string.inc b/sites/all/modules/views/handlers/views_handler_filter_string.inc new file mode 100644 index 0000000000000000000000000000000000000000..9c4408054f8452a13b0f37f8c3c34cb618dc6b95 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_filter_string.inc @@ -0,0 +1,305 @@ +<?php +// $Id: views_handler_filter_string.inc,v 1.8.4.6 2011/01/05 18:18:40 dereine Exp $ + +/** + * Basic textfield filter to handle string filtering commands + * including equality, like, not like, etc. + */ +class views_handler_filter_string extends views_handler_filter { + // exposed filter options + var $no_single = TRUE; + + /** + * This kind of construct makes it relatively easy for a child class + * to add or remove functionality by overriding this function and + * adding/removing items from this array. + */ + function operators() { + $operators = array( + '=' => array( + 'title' => t('Is equal to'), + 'short' => t('='), + 'method' => 'op_equal', + 'values' => 1, + ), + '!=' => array( + 'title' => t('Is not equal to'), + 'short' => t('!='), + 'method' => 'op_equal', + 'values' => 1, + ), + 'contains' => array( + 'title' => t('Contains'), + 'short' => t('contains'), + 'method' => 'op_contains', + 'values' => 1, + ), + 'word' => array( + 'title' => t('Contains any word'), + 'short' => t('has word'), + 'method' => 'op_word', + 'values' => 1, + ), + 'allwords' => array( + 'title' => t('Contains all words'), + 'short' => t('has all'), + 'method' => 'op_word', + 'values' => 1, + ), + 'starts' => array( + 'title' => t('Starts with'), + 'short' => t('begins'), + 'method' => 'op_starts', + 'values' => 1, + ), + 'not_starts' => array( + 'title' => t('Does not start with'), + 'short' => t('not_begins'), + 'method' => 'op_not_starts', + 'values' => 1, + ), + 'ends' => array( + 'title' => t('Ends with'), + 'short' => t('ends'), + 'method' => 'op_ends', + 'values' => 1, + ), + 'not_ends' => array( + 'title' => t('Does not end with'), + 'short' => t('not_ends'), + 'method' => 'op_not_ends', + 'values' => 1, + ), + 'not' => array( + 'title' => t('Does not contain'), + 'short' => t('!has'), + 'method' => 'op_not', + 'values' => 1, + ), + 'shorterthan' => array( + 'title' => t('Length is shorter than'), + 'short' => t('shorter than'), + 'method' => 'op_shorter', + 'values' => 1, + ), + 'longerthan' => array( + 'title' => t('Length is longer than'), + 'short' => t('longer than'), + 'method' => 'op_longer', + 'values' => 1, + ), + ); + // if the definition allows for the empty operator, add it. + if (!empty($this->definition['allow empty'])) { + $operators += array( + 'empty' => array( + 'title' => t('Is empty (NULL)'), + 'method' => 'op_empty', + 'short' => t('empty'), + 'values' => 0, + ), + 'not empty' => array( + 'title' => t('Is not empty (NOT NULL)'), + 'method' => 'op_empty', + 'short' => t('not empty'), + 'values' => 0, + ), + ); + } + + return $operators; + } + + /** + * Build strings from the operators() for 'select' options + */ + function operator_options($which = 'title') { + $options = array(); + foreach ($this->operators() as $id => $info) { + $options[$id] = $info[$which]; + } + + return $options; + } + + function admin_summary() { + if (!empty($this->options['exposed'])) { + return t('exposed'); + } + + $options = $this->operator_options('short'); + $output = check_plain($options[$this->operator]); + if (in_array($this->operator, $this->operator_values(1))) { + $output .= ' ' . check_plain($this->value); + } + return $output; + } + + function operator_values($values = 1) { + $options = array(); + foreach ($this->operators() as $id => $info) { + if (isset($info['values']) && $info['values'] == $values) { + $options[] = $id; + } + } + + return $options; + } + + /** + * Provide a simple textfield for equality + */ + function value_form(&$form, &$form_state) { + // We have to make some choices when creating this as an exposed + // filter form. For example, if the operator is locked and thus + // not rendered, we can't render dependencies; instead we only + // render the form items we need. + $which = 'all'; + if (!empty($form['operator'])) { + $source = ($form['operator']['#type'] == 'radios') ? 'radio:options[operator]' : 'edit-options-operator'; + } + if (!empty($form_state['exposed'])) { + $identifier = $this->options['expose']['identifier']; + + if (empty($this->options['expose']['use_operator']) || empty($this->options['expose']['operator'])) { + // exposed and locked. + $which = in_array($this->operator, $this->operator_values(1)) ? 'value' : 'none'; + } + else { + $source = 'edit-' . drupal_html_id($this->options['expose']['operator']); + } + } + + if ($which == 'all' || $which == 'value') { + $form['value'] = array( + '#type' => 'textfield', + '#title' => t('Value'), + '#size' => 30, + '#default_value' => $this->value, + ); + if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) { + $form_state['input'][$identifier] = $this->value; + } + + if ($which == 'all') { + $form['value'] += array( + '#process' => array('ctools_dependent_process'), + '#dependency' => array($source => $this->operator_values(1)), + ); + } + } + + if (!isset($form['value'])) { + // Ensure there is something in the 'value'. + $form['value'] = array( + '#type' => 'value', + '#value' => NULL + ); + } + } + + function operator() { + return $this->operator == '=' ? 'LIKE' : 'NOT LIKE'; + } + + /** + * Add this filter to the query. + * + * Due to the nature of fapi, the value and the operator have an unintended + * level of indirection. You will find them in $this->operator + * and $this->value respectively. + */ + function query() { + $this->ensure_my_table(); + $field = "$this->table_alias.$this->real_field"; + + $info = $this->operators(); + if (!empty($info[$this->operator]['method'])) { + $this->{$info[$this->operator]['method']}($field); + } + } + + function op_equal($field) { + $this->query->add_where($this->options['group'], $field, $this->value, $this->operator()); + } + + function op_contains($field) { + $placeholder = $this->placeholder(); + $this->query->add_where($this->options['group'], "$field LIKE $placeholder", array($placeholder => '%' . db_like($this->value) . '%'), 'formula'); + } + + function op_word($field) { + $where = $this->operator == 'word' ? db_or() : db_and(); + + preg_match_all('/ (-?)("[^"]+"|[^" ]+)/i', ' ' . $this->value, $matches, PREG_SET_ORDER); + foreach ($matches as $match) { + $phrase = false; + // Strip off phrase quotes + if ($match[2]{0} == '"') { + $match[2] = substr($match[2], 1, -1); + $phrase = true; + } + $words = trim($match[2], ',?!();:-'); + $words = $phrase ? array($words) : preg_split('/ /', $words, -1, PREG_SPLIT_NO_EMPTY); + foreach ($words as $word) { + $placeholder = $this->placeholder(); + $where->where("$field LIKE $placeholder", array($placeholder => '%' . db_like(trim($word, " ,!?")) . '%')); + } + } + + if (!$where) { + return; + } + + // previously this was a call_user_func_array but that's unnecessary + // as views will unpack an array that is a single arg. + $this->query->add_where($this->options['group'], $where); + } + + function op_starts($field) { + $placeholder = $this->placeholder(); + $this->query->add_where($this->options['group'], "$field LIKE $placeholder", array($placeholder => db_like($this->value) . '%'), 'formula'); + } + + function op_not_starts($field) { + $placeholder = $this->placeholder(); + $this->query->add_where($this->options['group'], "$field NOT LIKE $placeholder", array($placeholder => db_like($this->value) . '%'), 'formula'); + } + + function op_ends($field) { + $placeholder = $this->placeholder(); + $this->query->add_where($this->options['group'], "$field LIKE $placeholder", array($placeholder => '%' . db_like($this->value)), 'formula'); + } + + function op_not_ends($field) { + $placeholder = $this->placeholder(); + $this->query->add_where($this->options['group'], "$field NOT LIKE $placeholder", array($placeholder => '%' . db_like($this->value)), 'formula'); + } + + function op_not($field) { + $placeholder = $this->placeholder(); + $this->query->add_where($this->options['group'], "$field NOT LIKE $placeholder", array($placeholder => '%' . db_like($this->value) . '%'), 'formula'); + } + + function op_shorter($field) { + $placeholder = $this->placeholder(); + $this->query->add_where($this->options['group'], "LENGTH($field) < $placeholder", array($placeholder => $this->value), 'formula'); + } + + function op_longer($field) { + $placeholder = $this->placeholder(); + $this->query->add_where($this->options['group'], "LENGTH($field) > $placeholder", array($placeholder => $this->value), 'formula'); + } + + function op_empty($field) { + if ($this->operator == 'empty') { + $operator = "IS NULL"; + } + else { + $operator = "IS NOT NULL"; + } + + $this->query->add_where($this->options['group'], $field, NULL, $operator); + } + +} diff --git a/sites/all/modules/views/handlers/views_handler_relationship.inc b/sites/all/modules/views/handlers/views_handler_relationship.inc new file mode 100644 index 0000000000000000000000000000000000000000..9b34c3403b404095b8cea9dbbb03a405c14e1368 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_relationship.inc @@ -0,0 +1,153 @@ +<?php +// $Id: views_handler_relationship.inc,v 1.4.4.4 2010/12/17 21:42:19 merlinofchaos Exp $ +/** + * @file + * Views' relationship handlers. + */ + +/** + * @defgroup views_relationship_handlers Views' relationship handlers + * @{ + * Handlers to tell Views how to create alternate relationships. + */ + +/** + * Simple relationship handler that allows a new version of the primary table + * to be linked in. + * + * The base relationship handler can only handle a single join. Some relationships + * are more complex and might require chains of joins; for those, you must + * utilize a custom relationship handler. + * + * Definition items: + * - base: The new base table this relationship will be adding. This does not + * have to be a declared base table, but if there are no tables that + * utilize this base table, it won't be very effective. + * - base field: The field to use in the relationship; if left out this will be + * assumed to be the primary field. + * - relationship table: The actual table this relationship operates against. + * This is analogous to using a 'table' override. + * - relationship field: The actual field this relationship operates against. + * This is analogous to using a 'real field' override. + * - label: The default label to provide for this relationship, which is + * shown in parentheses next to any field/sort/filter/argument that uses + * the relationship. + */ +class views_handler_relationship extends views_handler { + /** + * Init handler to let relationships live on tables other than + * the table they operate on. + */ + function init(&$view, &$options) { + parent::init($view, $options); + if (isset($this->definition['relationship table'])) { + $this->table = $this->definition['relationship table']; + } + if (isset($this->definition['relationship field'])) { + $this->field = $this->definition['relationship field']; + } + } + + /** + * Get this field's label. + */ + function label() { + if (!isset($this->options['label'])) { + return $this->ui_name(); + } + return $this->options['label']; + } + + function option_definition() { + $options = parent::option_definition(); + + $label = !empty($this->definition['label']) ? $this->definition['label'] : $this->definition['field']; + $options['label'] = array('default' => $label, 'translatable' => TRUE); + $options['required'] = array('default' => FALSE); + + return $options; + } + + /** + * Default options form that provides the label widget that all fields + * should have. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['label'] = array( + '#type' => 'textfield', + '#title' => t('Label'), + '#default_value' => isset($this->options['label']) ? $this->options['label'] : '', + '#description' => t('The label for this relationship that will be displayed only administratively.'), + ); + + $form['required'] = array( + '#type' => 'checkbox', + '#title' => t('Require this relationship'), + '#description' => t('If required, items that do not contain this relationship will not appear.'), + '#default_value' => !empty($this->options['required']), + ); + } + + /** + * Called to implement a relationship in a query. + */ + function query() { + // Figure out what base table this relationship brings to the party. + $table_data = views_fetch_data($this->definition['base']); + $base_field = empty($this->definition['base field']) ? $table_data['table']['base']['field'] : $this->definition['base field']; + + $this->ensure_my_table(); + + $def = $this->definition; + $def['table'] = $this->definition['base']; + $def['field'] = $base_field; + $def['left_table'] = $this->table_alias; + $def['left_field'] = $this->field; + if (!empty($this->options['required'])) { + $def['type'] = 'INNER'; + } + + if (!empty($def['join_handler']) && class_exists($def['join_handler'])) { + $join = new $def['join_handler']; + } + else { + $join = new views_join(); + } + + $join->definition = $def; + $join->construct(); + $join->adjusted = TRUE; + + // use a short alias for this: + $alias = $def['table'] . '_' . $this->table; + + $this->alias = $this->query->add_relationship($alias, $join, $this->definition['base'], $this->relationship); + } +} + +/** + * A special handler to take the place of missing or broken handlers. + */ +class views_handler_relationship_broken extends views_handler_relationship { + function ui_name($short = FALSE) { + return t('Broken/missing handler'); + } + + function ensure_my_table() { /* No table to ensure! */ } + function query() { /* No query to run */ } + function options_form(&$form, &$form_state) { + $form['markup'] = array( + '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>', + ); + } + + /** + * Determine if the handler is considered 'broken' + */ + function broken() { return TRUE; } +} + +/** + * @} + */ diff --git a/sites/all/modules/views/handlers/views_handler_sort.inc b/sites/all/modules/views/handlers/views_handler_sort.inc new file mode 100644 index 0000000000000000000000000000000000000000..9e4662c65c2100f73b1e1a9bbaf05845915ad711 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_sort.inc @@ -0,0 +1,193 @@ +<?php +// $Id: views_handler_sort.inc,v 1.2.4.4 2010/12/17 21:42:19 merlinofchaos Exp $ +/** + * @defgroup views_sort_handlers Views' sort handlers + * @{ + * Handlers to tell Views how to sort queries + */ + +/** + * Base sort handler that has no options and performs a simple sort + */ +class views_handler_sort extends views_handler { + + /** + * Determine if a sort can be exposed. + */ + function can_expose() { return TRUE; } + + /** + * Called to add the sort to a query. + */ + function query() { + $this->ensure_my_table(); + // Add the field. + $this->query->add_orderby($this->table_alias, $this->real_field, $this->options['order']); + } + + function option_definition() { + $options = parent::option_definition(); + + $options['order'] = array('default' => 'ASC'); + $options['exposed'] = array('default' => FALSE); + $options['expose'] = array( + 'contains' => array( + 'label' => array('default' => '', 'translatable' => TRUE), + ), + ); + return $options; + } + + /** + * Display whether or not the sort order is ascending or descending + */ + function admin_summary() { + if (!empty($this->options['exposed'])) { + return t('Exposed'); + } + switch ($this->options['order']) { + case 'ASC': + case 'asc': + default: + return t('asc'); + break; + case 'DESC'; + case 'desc'; + return t('desc'); + break; + } + } + + /** + * Basic options for all sort criteria + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + if ($this->can_expose()) { + $this->show_expose_button($form, $form_state); + } + $form['op_val_start'] = array('#value' => '<div class="clearfix">'); + $this->show_sort_form($form, $form_state); + $form['op_val_end'] = array('#value' => '</div>'); + if ($this->can_expose()) { + $this->show_expose_form($form, $form_state); + } + } + + /** + * Simple validate handler + */ + function options_validate(&$form, &$form_state) { + $this->sort_validate($form, $form_state); + if (!empty($this->options['exposed'])) { + $this->expose_validate($form, $form_state); + } + + } + + /** + * Simple submit handler + */ + function options_submit(&$form, &$form_state) { + unset($form_state['values']['expose_button']); // don't store this. + $this->sort_submit($form, $form_state); + if (!empty($this->options['exposed'])) { + $this->expose_submit($form, $form_state); + } + } + + /** + * Shortcut to display the value form. + */ + function show_sort_form(&$form, &$form_state) { + $options = $this->sort_options(); + if (!empty($options)) { + $form['order'] = array( + '#type' => 'radios', + '#options' => $options, + '#default_value' => $this->options['order'], + ); + } + } + + function sort_validate(&$form, &$form_state) { } + + function sort_submit(&$form, &$form_state) { } + + /** + * Provide a list of options for the default sort form. + * Should be overridden by classes that don't override sort_form + */ + function sort_options() { + return array( + 'ASC' => t('Sort ascending'), + 'DESC' => t('Sort descending'), + ); + } + + /** + * Since all exposed sorts are grouped into one select box. + * We don't return nothing when views call to exposed_form() + */ + function exposed_form(&$form, &$form_state) { } + + /** + * Handle the 'left' side fo the exposed options form. + */ + function expose_form_left(&$form, &$form_state) { + $form['expose']['label'] = array( + '#type' => 'textfield', + '#default_value' => $this->options['expose']['label'], + '#title' => t('Label'), + '#required' => TRUE, + '#size' => 40, + ); + } + + /** + * Handle the 'right' side fo the exposed options form. + */ + function expose_form_right(&$form, &$form_state) { + $form['expose']['order'] = array( + '#type' => 'value', + '#value' => 'ASC', + ); + } + + /** + * Provide default options for exposed sorts. + */ + function expose_options() { + $this->options['expose'] = array( + 'order' => $this->options['order'], + 'label' => $this->ui_name(), + ); + } +} + +/** + * A special handler to take the place of missing or broken handlers. + */ +class views_handler_sort_broken extends views_handler_sort { + function ui_name($short = FALSE) { + return t('Broken/missing handler'); + } + + function ensure_my_table() { /* No table to ensure! */ } + function query() { /* No query to run */ } + function options_form(&$form, &$form_state) { + $form['markup'] = array( + '#markup' => '<div class="form-item description">' . t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.') . '</div>', + ); + } + + /** + * Determine if the handler is considered 'broken' + */ + function broken() { return TRUE; } +} + + +/** + * @} + */ diff --git a/sites/all/modules/views/handlers/views_handler_sort_date.inc b/sites/all/modules/views/handlers/views_handler_sort_date.inc new file mode 100644 index 0000000000000000000000000000000000000000..9f0c76bf8ccff9d1cf3a1ca59b4510d5cd725e69 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_sort_date.inc @@ -0,0 +1,70 @@ +<?php +// $Id: views_handler_sort_date.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos Exp $ + +/** + * Basic sort handler for dates. + * + * This handler enables granularity, which is the ability to make dates + * equivalent based upon nearness. + * + * @ingroup views_sort_handlers + */ +class views_handler_sort_date extends views_handler_sort { + function option_definition() { + $options = parent::option_definition(); + + $options['granularity'] = array('default' => 'second'); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $form['granularity'] = array( + '#type' => 'radios', + '#title' => t('Granularity'), + '#options' => array( + 'second' => t('Second'), + 'minute' => t('Minute'), + 'hour' => t('Hour'), + 'day' => t('Day'), + 'month' => t('Month'), + 'year' => t('Year'), + ), + '#description' => t('The granularity is the smallest unit to use when determining whether two dates are the same; for example, if the granularity is "Year" then all dates in 1999, regardless of when they fall in 1999, will be considered the same date.'), + '#default_value' => $this->options['granularity'], + ); + } + + /** + * Called to add the sort to a query. + */ + function query() { + $this->ensure_my_table(); + switch ($this->options['granularity']) { + case 'second': + default: + $this->query->add_orderby($this->table_alias, $this->real_field, $this->options['order']); + return; + case 'minute': + $formula = views_date_sql_format('YmdHi', "$this->table_alias.$this->real_field"); + break; + case 'hour': + $formula = views_date_sql_format('YmdH', "$this->table_alias.$this->real_field"); + break; + case 'day': + $formula = views_date_sql_format('Ymd', "$this->table_alias.$this->real_field"); + break; + case 'month': + $formula = views_date_sql_format('Ym', "$this->table_alias.$this->real_field"); + break; + case 'year': + $formula = views_date_sql_format('Y', "$this->table_alias.$this->real_field"); + break; + } + + // Add the field. + $this->query->add_orderby(NULL, $formula, $this->options['order'], $this->table_alias . '_' . $this->field . '_' . $this->options['granularity']); + } +} diff --git a/sites/all/modules/views/handlers/views_handler_sort_group_by_numeric.inc b/sites/all/modules/views/handlers/views_handler_sort_group_by_numeric.inc new file mode 100644 index 0000000000000000000000000000000000000000..ddc04c6ed54c3a6b75d15ae28dbb1810206a44c2 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_sort_group_by_numeric.inc @@ -0,0 +1,31 @@ +<?php +// $Id: views_handler_sort_group_by_numeric.inc,v 1.1.4.4 2010/11/30 21:14:22 merlinofchaos Exp $ +/** + * Handler for GROUP BY on simple numeric fields. + */ +class views_handler_sort_group_by_numeric extends views_handler_sort { + function init(&$view, &$options) { + parent::init($view, $options); + + // Initialize the original handler. + $this->handler = views_get_handler($options['table'], $options['field'], 'sort'); + $this->handler->init($view, $options); + } + + /** + * Called to add the field to a query. + */ + function query() { + $this->ensure_my_table(); + + $params = array( + 'function' => $this->options['group_type'], + ); + + $this->query->add_orderby($this->table_alias, $this->real_field, $this->options['order'], NULL, $params); + } + + function ui_name() { + return $this->get_field(parent::ui_name()); + } +} diff --git a/sites/all/modules/views/handlers/views_handler_sort_menu_hierarchy.inc b/sites/all/modules/views/handlers/views_handler_sort_menu_hierarchy.inc new file mode 100644 index 0000000000000000000000000000000000000000..43a2b92e2fdeed52fe313278d5eb2ce2897e07c6 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_sort_menu_hierarchy.inc @@ -0,0 +1,20 @@ +<?php +// $Id: views_handler_sort_menu_hierarchy.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos Exp $ + +/** + * Sort in menu hierarchy order. + * + * Given a field name of 'p' this produces an ORDER BY on p1, p2, ..., p9. + * This is only really useful for the {menu_links} table. + * + * @ingroup views_sort_handlers + */ +class views_handler_sort_menu_hierarchy extends views_handler_sort { + function query() { + $this->ensure_my_table(); + $max_depth = isset($this->definition['max depth']) ? $this->definition['max depth'] : MENU_MAX_DEPTH; + for ($i = 1; $i <= $max_depth; ++$i) { + $this->query->add_orderby($this->table_alias, $this->field . $i, $this->options['order']); + } + } +} diff --git a/sites/all/modules/views/handlers/views_handler_sort_random.inc b/sites/all/modules/views/handlers/views_handler_sort_random.inc new file mode 100644 index 0000000000000000000000000000000000000000..0a1c0a5b45af15e6abb02c54beecf7689f241eb8 --- /dev/null +++ b/sites/all/modules/views/handlers/views_handler_sort_random.inc @@ -0,0 +1,27 @@ +<?php +// $Id: views_handler_sort_random.inc,v 1.1.6.1 2009/11/02 22:01:25 merlinofchaos Exp $ + +/** + * Handle a random sort. + */ +class views_handler_sort_random extends views_handler_sort { + function query() { + switch (db_driver()) { + case 'mysql': + case 'mysqli': + $formula = 'RAND()'; + break; + case 'pgsql': + $formula = 'RANDOM()'; + break; + } + if (!empty($formula)) { + $this->query->add_orderby(NULL, $formula, $this->options['order'], '_' . $this->field); + } + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['order']['#access'] = FALSE; + } +} diff --git a/sites/all/modules/views/help/about.html b/sites/all/modules/views/help/about.html new file mode 100644 index 0000000000000000000000000000000000000000..3f91b997267986c921b3ba06da4b4d7364487f09 --- /dev/null +++ b/sites/all/modules/views/help/about.html @@ -0,0 +1,18 @@ +<!-- $Id: about.html,v 1.5.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ --> +The views module allows administrators and site designers to create, manage, and display lists of content. Each list managed by the views module is known as a "view", and the output of a view is known as a "display". Displays are provided in either block or page form, and a single view may have multiple displays. Optional navigation aids, including a system path and menu item, can be set for each page-based display of a view. By default, views may be created that list content (a <em>Node</em> view type), content revisions (a <em>Node revisions</em> view type) or users (a <em>User</em> view type). A view may be restricted to members of specific user roles, and may be added, edited or deleted at the <a href="base_url:admin/structure/views">views administration page</a> + +The "building block" design of the views system provides power and flexibility, allowing parameters to be specified only when needed. While an advanced view may use all of available parameters to create complex and highly interactive applications, a simple content listing may specify only a few options. All views rely on a conceptual framework that includes: + +<ul> + <li><a href="topic:views/field">Fields</a>, or the individual pieces of data being displayed. Adding the fields <em>Node: Title</em>, <em>Node: Type</em>, and <em>Node: Post date</em> to a node view, for example, includes the title, content type and creation date in the displayed results </li> + + <li><a href="topic:views/relationship">Relationships</a>, or information about how data elements relate to one another. If relationship data is available, like that provided by a CCK <em>nodereference</em> field, items from a related node may be included in the view </li> + + <li><a href="topic:views/argument">Arguments</a>, or additional parameters that dynamically refine the view results, passed as part of the path. Adding an argument of <em>Node: Type</em> to a node view with a path of "content", for example, dynamically filters the displayed items by content type. In this example (shown with Clean URLs enabled), accessing the view through the path "<em>http://www.example.com/content/page</em>" displays all posts of the type "page", the path "<em>http://www.example.com/content/story</em>" displays all posts of the type "story", and "<em>http://www.example.com/content</em>" displays all posts regardless of type) </li> + + <li><a href="topic:views/sort">Sort criteria</a>, which determine the order of items displayed in the view results. Adding the sort criteria <em>Node: Post date</em> (in descending order) to a node <em>view</em>, for example, sorts the displayed posts in descending order by creation date </li> + + <li><a href="topic:views/filter">Filters</a>, which limit items displayed in the results. Adding the filter <em>Node: Published</em> (and setting it equal to "Published") to a node view, for example, prevents unpublished items from being displayed</li> + + <li><a href="topic:views/display">Displays</a>, which control where the output will be seen. Every view has a default display, which doesn't actually display the view anywhere, but is used to hold the default settings for the view, and is used when the view is called programmatically if another display is not specified. Much more useful to users are the <a href="topic:views/display-page">page</a> display, which gives a view a path and allows it to be the primary content of a page, or the <a href="topic:views/display-block">block</a> display which allows it to appear as secondary content on other pages.</li> +</ul> diff --git a/sites/all/modules/views/help/analyze-theme.html b/sites/all/modules/views/help/analyze-theme.html new file mode 100644 index 0000000000000000000000000000000000000000..6605a30de6f603e558fc0431125948ea74f3dd0b --- /dev/null +++ b/sites/all/modules/views/help/analyze-theme.html @@ -0,0 +1,24 @@ +<!-- $Id: analyze-theme.html,v 1.5.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ --> +<p>You may use any of the following possible theme files to modify individual parts of your view. In total, there are four parts to theming a view.</p> +<ul> + <li> The <strong>display</strong> theme is usually views-view.tpl.php and it largely controls the decorations around a view; where the header, footer, pager, more link, feed icon, etc, will be placed. </li> + + <li> The <strong>style</strong> will control how all of the results of the display are put together. It may be as simple as just displaying all of the rows, or it may be a complex table generator or something in between. </li> + + <li> The <strong>row</strong> style controls each individual row; not all styles utilize the row style (notably the table), but most others do. + + <li> Finally, <strong>field</strong> themes allow you to override the look and even the data of each individual field, if the style uses fields. The actual template the system will use should be hilighted in <strong>bold</strong>.</li> +</ul> + +<div class="help-box" style="text-align:center"> +<a href="path:images/style-breakdown-large.png"><img src="path:images/style-breakdown.png" /></a> +<em>A breakdown of View output</em> +</div> + +<p>The link to the left of each type will give you information about the default template used for that type. You may cut and paste this and place it in your theme with the appropriate template, or you may copy the base file from the views/theme directory (or, if provided by a module, from the module's directory). <strong>It is important that you clear the theme registry cache every time you add a new template, or the new template will not be picked up.</strong></p> + +<p><strong>Important note:</strong> You place your custom template files in your theme directory, <strong>not views/theme</strong>. This is always true of theming with Drupal. + +<p>In addition to this tool, the very useful <a href="http://drupal.org/project/devel">devel</a> module contains a tool called the "Theme developer" which does a good job of visually showing you which areas of your site use which themes. Be careful with it, though, as the theme developer causes the Views edit page to break.</p> + +<p>Also, this feature will only work properly with Drupal 6.3 and later; prior to Drupal 6.3 <a href="http://drupal.org/node/241570">this patch</a> will be required.</p> diff --git a/sites/all/modules/views/help/api-default-views.html b/sites/all/modules/views/help/api-default-views.html new file mode 100644 index 0000000000000000000000000000000000000000..2a2837ca91e17dee736292493d988d127ae4ca47 --- /dev/null +++ b/sites/all/modules/views/help/api-default-views.html @@ -0,0 +1,106 @@ +<!-- $Id: api-default-views.html,v 1.3.6.4 2010/12/23 22:11:34 dereine Exp $ --> +Views can be stored in the database, which is typical of smaller sites and hobby sites. However, Views may also be stored directly in the code as "default" views, (which simply means they're available by default). Modules often come with views that are specific to the module data, but it's also possible -- and <b>highly</b> recommended -- that sites which have separate "development" and "production" sites export their views into default views in a site-specific module. This makes it very easy to transfer views from dev to production without making database changes. + +<h3>Creating a module</h3> +First, create a directory in <em>sites/all/modules</em> for your new module. Call it whatever you like, but for this example we will call it <em>mymodule</em>. + +In this directory, create a <em>mymodule.module</em> file. It can be empty for now, but it should at least contain an opening PHP tag: +<pre><?php +// $Id $ +</pre> + +It should not contain a closing ?> tag, as the closing ?> tag is not required and anything AFTER the closing tag, such as a space or a linefeed, will be displayed directly to the browser and can potentially cause problems. + +The .module file will contain functions and drupal hooks. Hooks are specially named functions that Drupal will call in order to get your module's response at certain times while generating pages. The only function you will need for this exercise is the 'views_api' hook that tells Views that this module supports the Views API and what version: + +<pre>function mymodule_views_api() { + return array('api' => 2.0); +} +</pre> + +For other uses you may well add additional functions. + +Second, you need to create a <em>mymodule.info</em> file: + +<pre>; $Id $ +name = My module +description = My site specific module. +core = 6.x +</pre> + +Once you have these two files set up, you should be able to activate your new module at the <em>Administer >> Modules</em> page. +<h3>Exporting your views</h3> + +The easiest way to do this is to activate the 'views_export' module, and navigate to <em>Administer >> Structure >> Views >> Tools >> Bulk export</em> Place a check next to each view that you want in your module, type the module name into the text field, and click export. This will create the entire <em>hook_views_default_views()</em> function for you. + +You can also export individual views. If you do this, keep in mind that this export does not include the line that adds the exported $view into the larger $views array: + +<pre>$views[$view->name] = $view</pre> + +To place this into your <em>hook_views_default_views()</em> you will need to place that after the view, and make sure the function returns $views at the end. + +<h3>Placing your exported views into your module</h3> +Cut and paste the entire output of the bulk export tool into mymodule.views_default.inc -- and be sure to put a <?php at the top of the file so that the webserver knows that it's PHP code! Then visit the Views tools page and clear the Views cache. Your views should now be listed as <b>Overridden</b> on the view list page. If you <b>revert</b> these views, they will be removed from the database, but will remain in code. + +<h3>Theming your views in your module</h3> +You can theme these views in the module and not need to rely on the theme to do this at all; and in fact, the theme can continue to override these just like it ordinarily would, even if your module provides a theme. This is very useful for distributing a module where the view needs to look "just so." + +To do this, you need to implement <em>hook_theme()</em> in your module: +<pre>function mymodule_theme($existing) { + return array( + 'views_view__viewname__displayid' => array ( + 'arguments' => array('view' => NULL), + 'template' => 'views-view--viewname--displayid', + 'base hook' => 'views_view', + 'path' => drupal_get_path('module', 'mymodule'), + ), + ); +} +</pre> + +There are a small number of gotchas in doing this that you must be aware of. + +<ol> +<li>When referring to a template filename, you always use dashes in the name. i.e, <em>views-view--viewname--displayid.tpl.php</em>. However, when referring to the hook or function names, you use underscores instead of dashes. i.e, <em>views_view</em> and <em>views_view__viewname__displayid</em></li> + +<li>The 'arguments' change based upon which of the 3 types you're overriding. There's the 'display', the 'style' and the 'row' style. The above code is assuming the display, which is usually just <em>views_view</em>. Here are the possibilities: + +<pre>display: array('view' => NULL), +style: array('view' => NULL, 'options' => NULL, 'rows' => NULL, 'title' => NULL), +row style: array('view' => NULL, 'options' => NULL, 'row' => NULL), +</pre> + +Be sure to use the right arguments line or the theme system will not properly translate. +</li> +<li>The 'template' line should never include the extension, so drop the .tpl.php from it.</li> + +<li>You need to make sure that the Views preprocess functions get registered. The 'base hook' line in the definition does that, but it can only do it if it comes after the Views registration, which actually happens very late in theme building. 99% of the time, your module will come before Views. You have two choices to deal with this: +<ol> + <li>Set your module's weight to 11 or higher in the database. Views' weight is 10. You can make this happen automatically when the module is first installed by creating a mymodule.install file and using this code: + <pre>function mymodule_install() { + db_query("UPDATE {system} SET weight = 11 WHERE name = 'mymodule'"); +} +</pre> + If you use this method, the <em>base hook</em> should be set to the name of the original template being used. i.e, if this is a variate of views-view-list.tpl.php, this should be 'views_view_list'. + </li> + <li>You can also just force it to list the preprocessors without actually having to detect them. This doesn't require modifying your module's weight, which is not always possible, you can insert this code into the array: + <pre> 'preprocess functions' => array( + 'template_preprocess', + 'template_preprocess_views_view', + 'mymodule_preprocess_views_view__viewname_displayid', + ), +</pre> + + The first one is the global 'template_preprocess' function which all templates utilize. It does some basic things such as setting up $zebra and a few other items. See <a href="http://api.drupal.org/api/function/template_preprocess/6">api.drupal.org</a> for specifics. + + The second one is the plugin specific preprocess. Like 'base hook' it should conform to the name used by the original template. i.e, if the original template was <em>views-view-list.tpl.php</em> then that preprocess function would be named <em>template_preprocess_views_view_list</em>. + + The third one is your module's preprocess function, if it needs one. In general, you probably will not need one, and you should only attempt to use one if you are reasonably familiar with the concept of preprocess functions and Drupal's theme system in general. See Drupal's theme documentation for more information. + </li> +</ol> +</li> +<li> + If you leave the path blank the template file will be searched for in "./" which is the Drupal install base path. +</li> +</ol> + diff --git a/sites/all/modules/views/help/api-example.html b/sites/all/modules/views/help/api-example.html new file mode 100644 index 0000000000000000000000000000000000000000..9e1710046faf2a549a076d3d3a47378dd7f0e93b --- /dev/null +++ b/sites/all/modules/views/help/api-example.html @@ -0,0 +1,181 @@ +<!-- $Id: api-example.html,v 1.2.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ --> + +For the new table defined by the Node example module to be understood by the views module you need to create a node_example.views.inc file that describes the table and its relationships to the rest of the database. In order for views to know that this file is to be loaded you need to implement hook_views_api. This is done by adding the following function into your node_example.module file + +<pre> +<?php +/** + * Implements hook_views_api(). + * + * This tells drupal that there is Views integration file named + * module-name.views.inc + */ +function node_example_views_api() { + // Note that you can include 'path' in this array so that your views.inc + // file can be stored in a different location. + return array( + 'api' => 2.0 + ); +} +?> +</pre> + +Below is the contents of a simple node_example.views.inc file that allows you to create views that include the new color and quantity information. + +<pre> +<?php +// $Id: api-example.html,v 1.2.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * This file is used to tell the views module about the new node_example table. + * + * Database definition: + * @code + * CREATE TABLE node_example ( + * vid int(10) unsigned NOT NULL default '0', + * nid int(10) unsigned NOT NULL default '0', + * color varchar(255) NOT NULL default '', + * quantity int(10) unsigned NOT NULL default '0', + * PRIMARY KEY (vid, nid), + * KEY `node_example_nid` (nid) + * ) + * @endcode + */ + +function node_example_views_data() { + // Basic table information. + + // ---------------------------------------------------------------- + // node_example table + // New group within Views called 'Example' + // The group will appear in the UI in the dropdown tha allows you + // to narrow down which fields and filters are available. + + $data = array(); + $data['node_example']['table']['group'] = t('Example'); + + // Let Views know that our example table joins to the 'node' + // base table. This means it will be available when listing + // nodes and automatically make its fields appear. + // + // We also show up for node revisions. + $data['node_example']['table']['join'] = array( + 'node_revisions' => array( + 'left_field' => 'vid', + 'field' => 'vid', + ), + 'node' => array( + 'left_field' => 'vid', + 'field' => 'vid', + ), + ); + + // quantity + $data['node_example']['quantity'] = array( + 'title' => t('Quantity'), + 'help' => t('Quantity of items.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // Color + $data['node_example']['color'] = array( + 'title' => t('Color'), + 'help' => t('Color of item.'), + + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + return $data; +} + +?> +</pre> + +Some notes on usage: + +Within Views, click on the Add tab. You have a number of type options here. Normally you would select either 'Node' (if you only want to display information on current nodes) or 'Node revision' (if you want to display information on all revisions of the nodes) + +With this configuration you always pull out of the database, data for every single node, whether or not it has color and quantity information. To display information on just those nodes that have color and quantity information you can use a filter so that only nodes which don't have a NULL color or a NULL quantity are displayed. + +<h3>Type/relationship extension</h3> + +When your tables have first class data, you will often need to have own View types and View relationships defined. With the current node_example table this isn't required although I try to justify it below on an efficiency basis. See [[http://groups.drupal.org/node/17236#comment-58980|this discussion]] as to why it isn't justified. + +Pulling data out of the database for every node when you only want data for the new Example node type is inefficient. To reduce the initial data extraction to just that relating to the new Example nodes requires that you make the node_example table the base table. This can be done by adding the following code into the node_example.views.inc file just before the 'return $data;' + +<pre> +<?php + +// **** Begin optional extra for type and relationships **** + + // Use node_example as a new base table + // by creating a new views type called 'Node example' + // This allows it to be selected as the 'view type' + // when you initially add a new view. + $data['node_example']['table']['base'] = array( + 'field' => 'vid', + 'title' => t('Node example'), + 'help' => t("Node example type with color and quantity information."), + 'weight' => -9, + ); + + // When using the new 'Node example' type you need to use relationships + // to access fields in other tables. + + // Relationship to the 'Node revision' table + $data['node_example']['vid'] = array( + 'title' => t('Node revision'), + 'help' => t('The particular node revision the color and quantity is attached to'), + 'relationship' => array( + 'label' => t('Node revision'), + 'base' => 'node_revisions', + 'base field' => 'vid', + // This allows us to not show this relationship if the base is already + // node_revisions so users won't create circular relationships. + 'skip base' => array('node', 'node_revisions'), + ), + ); + + // Relationship to the 'Node' table + $data['node_example']['nid'] = array( + 'title' => t('Node'), + 'help' => t('The particular node the color and quantity is attached to'), + 'relationship' => array( + 'label' => t('Node'), + 'base' => 'node', + 'base field' => 'nid', + // This allows us to not show this relationship if the base is already + // node so users won't create circular relationships. + 'skip base' => array('node', 'node_revisions'), + ), + ); + +// **** End optional extra for type and relationships **** + +?> +</pre> + +The above code adds a new 'Node example' to the view types that can be selected within the Add tab window of views. Selecting this sets the node_example table to be the base table. + +If you select 'Node example' as view type, when you initially go into the edit window of views you will find the only fields available are the color and quantity fields. To get fields from other tables you need to add a relationship. Relationships may be found at the top in the same column as the fields. diff --git a/sites/all/modules/views/help/api-handlers.html b/sites/all/modules/views/help/api-handlers.html new file mode 100644 index 0000000000000000000000000000000000000000..b222618acd41f34b3317f9ddaf824c17bafcab4a --- /dev/null +++ b/sites/all/modules/views/help/api-handlers.html @@ -0,0 +1,70 @@ +<!-- $Id: api-handlers.html,v 1.4.6.2 2010/07/19 09:18:42 dereine Exp $ --> +In Views, a handler is an object that is part of the view and is part of the query building flow. + +Handlers are objects; much of the time, the base handlers will work, but often you'll need to override the handler for something. One typical handler override will be views_handler_filter_operator_in which allows you to have a filter select from a list of options; you'll need to override this to provide your list. + +Handlers have two distint code flows; the UI flow and the view building flow. + +For the query flow: + +<dl> +<dt>handler->construct()</dt> +<dd>Create the initial handler; at this time it is not yet attached to a view. It is here that you can set basic defaults if needed, but there will be no knowledge of the environment yet.</dd> +<dt>handler->set_definition()</dt> +<dd>Set the data from hook_views_data() relevant to the handler.</dd> +<dt>handler->init()</dt> +<dd>Attach the handler to a view, and usually provides the options from the display.</dd> +<dt>handler->pre_query()</dt> +<dd>Run prior to the query() stage to do early processing.</dd> +<dt>handler->query()</dt> +<dd>Do the bulk of the work this handler needs to do to add itself to the query.</dd> +</dl> + +Fields, being the only handlers concerned with output, also have an extended piece of the flow: +<dl> +<dt>handler->pre_render()</dt> +<dd>Called prior to the actual rendering, this allows handlers to query for extra data; the entire resultset is available here, and this is where items that have "multiple values" per record can do their extra query for all of the records available. There are several examples of this at work in the code.</dd> +<dt>handler->render()</dt> +<dd>This does the actual work of rendering the field.</dd> +</dl> + +Most handlers are just extensions of existing classes with a few tweaks that are specific to the field in question. For example: + +<pre> +/** + * Filter by node type + */ +class views_handler_filter_node_type extends views_handler_filter_in_operator { + function get_value_options() { + if (!isset($this->value_options)) { + $this->value_title = t('Node type'); + $types = node_get_types(); + foreach ($types as $type => $info) { + $options[$type] = $info->name; + } + $this->value_options = $options; + } + } +} +</pre> + +<i>views_handler_filter_in_operator</i> provides a simple mechanism to set the list used and the rest of the handler is perfectly fine for this. + +Handlers are stored in their own files and loaded on demand. +Like all other module files, they must first be registered through the module's info file. For example: +<pre> +name = Example module +description = "Gives an example of a module." +core = 7.x +files[] = example.module +files[] = example.install + +; Views handlers +files[] = includes/views/handlers/example_handler_argument_string.inc +</pre> + +The best place to learn more about handlers and how they work is to explore <a href="http://views.doc.logrus.com">the views API site</a> and use existing handlers as a guide and a model. Understanding how views_handler and its child classes work is handy but you can do a lot just following these models. You can also explore the views module directory, particularly node.views.inc. + +Please note that while all handler names in views are prefixed with views_, you should use your own module's name to prefix your handler names in order to ensure namespace safety. Note that the basic pattern for handler naming goes like this: + +[module]_handler_[type]_[tablename]_[fieldname]. Sometimes table and fieldname are not appropriate, but something that resembles what the table/field would be can be used. diff --git a/sites/all/modules/views/help/api-plugins.html b/sites/all/modules/views/help/api-plugins.html new file mode 100644 index 0000000000000000000000000000000000000000..139003836978e643b25c09345cf7072f78fbacc3 --- /dev/null +++ b/sites/all/modules/views/help/api-plugins.html @@ -0,0 +1,79 @@ +<!-- $Id: api-plugins.html,v 1.7.6.2 2010/07/28 06:58:25 dereine Exp $ --> +In Views, a plugin is a bit like a handler, but plugins are not directly responsible for building the query. Instead, they are objects that are used to display the view or make other modifications. + +There are 6 types of plugins in Views: +<dl> +<dt>Display</dt> +<dd>Display plugins are responsible for controlling <strong>where</strong> a view lives. Page and block are the most common displays, as well as the ubiquitous 'default' display which is likely what will be embedded.</dd> +<dt>Style</dt> +<dd>Style plugins control how a view is displayed. For the most part they are object wrappers around theme templates. +<dt>Row style</dt> +<dd>Row styles handle each individual record from a node.</dd> +<dt>Argument default</dt> +<dd>Argument default plugins allow pluggable ways of providing arguments for blocks. Views includes plugins to extract node and user IDs from the URL; additional plugins could be used for a wide variety of tasks.</dd> +<dt>Argument validator</dt> +<dd>Validator plugins can ensure arguments are valid, and even do transformations on the arguments.</dd> +<dt>Access</dt> +<dd>Access plugins are responsible for controlling access to the view.</dd> +</dl> + +Plugins are registered by implementing <strong>hook_views_plugins()</strong> in your modulename.views.inc file and returning an array of data. + +The array will look something like this: +<pre> + return array( + 'display' => array( + // ... list of display plugins, + ), + 'style' => array( + // ... list of style plugins, + ), + 'row' => array( + // ... list of row style plugins, + ), + 'argument default' => array( + // ... list of argument default plugins, + ), + 'argument validator' => array( + // ... list of argument validator plugins, + ), + 'access' => array( + // ... list of access plugins, + ), + ); +</pre> + +Each plugin will be registered with an identifier for the plugin, plus a fairly lengthy list of items that can define how and where the plugin is used. Here is an example from Views core: + +<pre> + 'node' => array( + 'title' => t('Node'), + 'help' => t('Display the node with standard node view.'), + 'handler' => 'views_plugin_row_node_view', + 'path' => drupal_get_path('module', 'views') . '/modules/node', // not necessary for most modules + 'theme' => 'views_view_row_node', + 'base' => array('node'), // only works with 'node' as base. + 'uses options' => TRUE, + 'type' => 'normal', + ), +</pre> + +Of particular interest is the <em>path</em> directive, which works a little differently from handler registration; each plugin must define its own path, rather than relying on a global info for the paths. For example: + +<pre> + 'feed' => array( + 'title' => t('Feed'), + 'help' => t('Display the view as a feed, such as an RSS feed.'), + 'handler' => 'views_plugin_display_feed', + 'uses hook menu' => TRUE, + 'use ajax' => FALSE, + 'use pager' => FALSE, + 'accept attachments' => FALSE, + 'admin' => t('Feed'), + 'help topic' => 'display-feed', + ), +</pre> + +Please be sure to prefix your plugin identifiers with your module name to ensure namespace safety; after all, two different modules could try to implement the 'grid2' plugin, and that would cause one plugin to completely fail. + +...TODO: Finish this document.... diff --git a/sites/all/modules/views/help/api-tables.html b/sites/all/modules/views/help/api-tables.html new file mode 100644 index 0000000000000000000000000000000000000000..288c4ddb96cb5ac809a0a479e547e99f50847727 --- /dev/null +++ b/sites/all/modules/views/help/api-tables.html @@ -0,0 +1,235 @@ +<!-- $Id: api-tables.html,v 1.8.4.3 2010/10/12 21:21:02 merlinofchaos Exp $ --> +Tables are described to Views via hook_views_data(), which returns an array of table information, keyed by the name of the table. For example, if your module is describing three tables, 'foo', 'bar' and 'baz', your array will look like this: +<pre>$data = array( + 'foo' => array( + // ...info here... + ), + 'bar' => array( + // ...info here... + ), + 'baz' => array( + // ...info here... + ), +); +</pre> + +The key should be the actual database name of the table (not including prefix), but it can be an alias as long as the join information (explained later) contains the real name of the table. + +Each item in the array should be a field in the table, with the exception of a special information section called 'table'. Example: + +<pre>$data['foo'] = array( + 'table' => array( + // ... info about the table, described later ... + ), + 'bar' => array( + // ... info about the field named 'bar', i.e, foo.bar, + ), + 'baz' => array( + // ... info about the field named 'baz', i.e, foo.baz, + ), +); +</pre> + +Once you get down to an array that contains actual data, that piece of the array will often be referred to as the definition. + +<h2>The 'table' section</h2> +Each table should have a 'table' section in it, which is used to set default information for the table, such as the group, as well as the very important joins and whether or not this is a base table. + +First, there are several items that are actually for fields but can be placed here so that all fields within the table inherit them: +<dl> +<dt>group</dt> +<dd>The name of the group this item will be with. In the UI, this is displayed as Group: Title. For example, "Node: Node ID", "Taxonomy: Term description", etc. It is important to be consistent with groups, because the UI sorts by group, and allows filtering by group to find fields as well.</dd> +<dt>title</dt> +<dd>The actual name of the field; it should be concise and descriptive.</dd> +<dt>help</dt> +<dd>A longer description to help describe what the field is or does. It should try to be only a line or two so as not to clutter the UI.</dd> +</dl> + +In general, having 'title' and 'help' at the table level doesn't make a lot of sense, but usually every item in a table is in the same group. Thus it is very common to define the 'group': + +<pre> + $data['foo']['table']['group'] = t('Foo'); +</pre> + +<h3>Base table</h3> +If your table is a base table -- meaning it can be the primary, central table for a View to use, you can declare it to be a base table. This primarily provides UI information so that it can be selected. +For example: +<pre> + // Advertise this table as a possible base table + $data['node']['table']['base'] = array( + 'field' => 'nid', + 'title' => t('Node'), + 'help' => t("Nodes are a Drupal site's primary content."), + 'weight' => -10, + ); +</pre> + +The following tags are available in the +<dl> +<dt>field</dt> +<dd>The primary key field for this table. For Views to treat any table as a base table, it <b>must</b> have a primary field. For node this is the 'nid', for users this is the 'uid', etc. <strong>Without a single primary key field (i.e. not a composite key), Views will not be able to utilize the table as a base table.</strong> If your table does not have a primary key field, it is not too difficult to just add a serial field to it, usually.</dd> +<dt>title</dt> +<dd>The title of this table in the UI. It should be singular and describe the object that this table contains from the perspective of the user.</dd> +<dt>help</dt> +<dd>A short piece of text to describe what object this table contains.</dd> +<dt>database</dt> +<dd>If this table is held in a different database from your Drupal database, specify it as a string in the exact same format as the settings.php file. This is a special purpose variable that will probably be only used in site specific code, and <b>it must be the same database type as your Drupal database</b>. Also, don't try to join it to any table that isn't in the same database. That'll just create all kinds of silly errors. For example: +<pre> + // In settings.php for your site + // Your drupal (site) database needs to be called 'default' + $db_url['default'] = 'mysqli://user:pass@host/drupal_db'; + $db_url['budget'] = 'mysqli://user:pass@host/other_db'; +</pre> +Then when you are describing the external database in your base table you would write something like this: +<pre> + $data[$table]['table']['base'] = array( + 'field' => 'Primary key', + 'title' => t('Field name'), + 'help' => t('Field description'), + 'database' => 'budget', + 'weight' => -10, + ); +</pre> +</dd> +</dl> + +<h3>Linking your table to existing base tables</h3> +For Views to use your table, it has to either be a base table, or know how to link to an existing base table. Or sometimes both. Views uses this information to create a path to the base table; when the table is added to the query, Views will walk along this path, adding all tables required into the query. + +<div class="help-box" style="text-align:center"> +<a href="path:images/node-term_node-term_data-large.png"><img src="path:images/node-term_node-term_data.png" /></a> +<em>How taxonomy_term_data joins to node</em> +</div> + +In the above example, to use these with 'node' as the base table, both 'taxonomy_term_data' and 'term_node' need to be defined, and they each need a join handler for node: + +<pre> +$data['taxonomy_term_data']['table']['join']['node'] = array( + 'left_table' => 'term_node', + 'left_field' => 'tid', + 'field' => 'tid', +); +</pre> + +The above can be read as "In order to join to the node table, the taxonomy_term_data table must first link to the term_node table, and they join on the 'tid' field.". When adding this table to the query for a node view, Views will look at this and then look for the term_node table. + +<pre> +$data['term_node']['table']['join']['node'] = array( + 'left_field' => 'nid', + 'field' => 'nid', +); +</pre> + +Above, the fact that 'left_table' is left out lets us know that term_node links directly to the node table, using the 'nid' field on both sides of the join. + +Quite a few more fields are available in this definition: +<dl> + <dt>handler</dt> + <dd>The name of the handler object to use. Defaults to 'views_join'. You may create custom join handlers that may or may not use any of the data below, as they see fit.</dd> + <dt>table</dt> + <dd>Table to join. This is optional, and should only be used if the table being referenced is an alias.</dd> + <dt>field</dt> + <dd>Field to join on. This is required.</dd> + <dt>left_table</dt> + <dd>The next step toward the final destination. If this is the final destination it may be omitted.</dd> + <dt>left_field</dt> + <dd>The field to join to on the left side. This is required.</dd> + <dt>type</dt> + <dd>Either LEFT (default) or INNER.</dd> + <dt>extra</dt> + <dd>Either a string that's directly added, or an array of items. Each item is, itself, an array: + <dl> + <dt>field</dt> + <dd>Field or formula</dd> + <dt>operator</dt> + <dd>Similar to filters, this is the operator, such as >, <, =, etc. Defaults to = or IN.</dd> + <dt>value</dt> + <dd>Must be set. If an array, operator will be defaulted to IN.</dd> + <dt>numeric</dt> + <dd>If true, the value will not be surrounded in quotes, and %d will be used for its placeholder.</dd> + </dl> + </dd> + <dt>extra type</dt> + <dd> How all the extras will be combined. Either AND or OR. Defaults to AND.</dd> +</dl> + +<h2>Describing fields on tables</h2> +Aside from the special table tag, each table can also have an unlimited number of field designations; these correspond roughly to fields on the table, though it is very common to use non-fields to display data that isn't directly in a field, such as data arrived from formulae, or special links related to the object the table is part of. + +Each field is described in the view data with an array, keyed to the database name of the field. This array may contain some information fields, plus an entry in each of the five types of items Views has per field: argument, field, filter, relationship, sort. For example: + +<pre> +$data['node']['nid'] = array( + 'title' => t('Nid'), + 'help' => t('The node ID of the node.'), // The help that appears on the UI, + // Information for displaying the nid + 'field' => array( + 'handler' => 'views_handler_field_node', + 'click sortable' => TRUE, + ), + // Information for accepting a nid as an argument + 'argument' => array( + 'handler' => 'views_handler_argument_node_nid', + 'name field' => 'title', // the field to display in the summary. + 'numeric' => TRUE, + 'validate type' => 'nid', + ), + // Information for accepting a nid as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + // Information for sorting on a nid. + 'sort' => array( + 'handler' => 'views_handler_sort', + ), +); +</pre> + +The above example describes the 'nid' field on the 'node' table, providing 4 of the 5 handlers. Note that while field is normally expected to be the database name of the field, it doesn't have to be; you can use an alias (which is how you get multiple handlers per field) or something completely made up for items that aren't tied to the database. For example: + +<pre> +$data['node']['edit_node'] = array( + 'field' => array( + 'title' => t('Edit link'), + 'help' => t('Provide a simple link to edit the node.'), + 'handler' => 'views_handler_field_node_link_edit', + ), +); +</pre> + +The above handler definition an edit link to a node, but this isn't a field in and of itself. For aliased fields, here is another example: + +<pre> +$data['users']['uid_current'] = array( + 'real field' => 'uid', + 'title' => t('Current'), + 'help' => t('Filter the view to the currently logged in user.'), + 'filter' => array( + 'handler' => 'views_handler_filter_user_current', + ), +); +</pre> + +The above definition provides an alternate filter handler on the uid field for the current user. + +The following items are allowed in the field definition: + +<dl> +<dt>group, title, help</dt> +<dd>As above, these fields are for the UI. If placed here, any of these fields will override a setting on the base table.</dd> +<dt>real field</dt> +<dd>If this field is an alias, the "real field" may be placed here, and the handler will never know the difference.</dd> + +<dt>field</dt> +<dd>A handler definition for the "Field" section, which is a field that may be displayed in a view. The definition is an array; the contents of the array are completely up to the handler, other than the 'handler' definition. If omitted, handler will default to 'views_handler_field'.</dd> +<dt>filter</dt> +<dd>A handler definition for the "Filters" section, which will be used to apply WHERE clauses to the view. The definition is an array; the contents of the array are completely up to the handler, other than the 'handler' definition. If omitted, handler will default to 'views_handler_filter'.</dd> +<dt>sort</dt> +<dd>A handler definition for the "Sort criteria" section, which will be used to add an ORDER BY clause to the view. The definition is an array; the contents of the array are completely up to the handler, other than the 'handler' definition. If omitted, handler will default to 'views_handler_sort'.</dd> +<dt>relationship</dt> +<dd>A handler definition for the "Field" section, which is a way to bring in new or alternative base tables in the view. The definition is an array; the contents of the array are completely up to the handler, other than the 'handler' definition. If omitted, handler will default to 'views_handler_relationship'. The basic relationship handler requires 'base' and 'base field' to be set; 'base' and 'base field' represent the "right" half of the join that will use this field as the left side.</dd> +<dt>argument</dt> +<dd>A handler definition for the "Field" section, which is method of accepting user input from the URL or some other source. The definition is an array; the contents of the array are completely up to the handler, other than the 'handler' definition. If omitted, handler will default to 'views_handler_argument'.</dd> +</dl> + +For more information about what handlers need/use what data, visit <a href="http://views.doc.logrus.com">the Views API site</a> and check out the available handlers. diff --git a/sites/all/modules/views/help/api-upgrading.html b/sites/all/modules/views/help/api-upgrading.html new file mode 100644 index 0000000000000000000000000000000000000000..58b0325fcf8221197ad2c294b3b134747ded0b2f --- /dev/null +++ b/sites/all/modules/views/help/api-upgrading.html @@ -0,0 +1,64 @@ +<!-- $Id: api-upgrading.html,v 1.1.2.5 2011/01/04 00:37:55 dereine Exp $ --> +In order to take advantage of the changes in Drupal 7, Views has gone through several API changes. +Here's what you should know. + +<h3>Handler registry</h3> + +Views now uses Drupal's dynamic-loading code registry. +You can safely remove your implementations of hook_views_handlers(), since they are no longer used. + +Please remember to specify the handlers in your module's .info file. For example: +<pre> +name = Example module +description = "Gives an example of a module." +core = 7.x +files[] = example.module +files[] = example.install + +; Views handlers +files[] = includes/views/handlers/example_handler_argument_string.inc +</pre> + +<h3>Removed handlers</h3> + +Note that views_handler_filter_float has been removed. +This functionality is now handled by views_handler_filter_numeric. +There's no need for having a special handler any more, thanks to the new DB layer in Drupal 7. + +views_handler_sort_formula has been removed. +Everyone who used it can extend from views_handler_sort, too. + +<h3>Ctools dependency</h3> +Views requires ctools now, so it can use the dependency system of ctools. +The only thing you have to do is to replace +<pre> +'#process' => array('views_process_dependeny') +</pre> +with +<pre> +'#process' => array('ctools_dependent_process'), +</pre> + +<h3>Changed add_where api</h3> +If your field is a plain sql field: +<code> + $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field " . $this->operator . " '%s'", $this->value); +</code> +has to be converted to +<code> + $this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field", $this->value, $this->operator); +</code> +If your field is a complex where condition: +<code> + $this->query->add_where($this->options['group'], "$upper($field) NOT LIKE $upper('%%%s')", $this->value); +</code> +has to be converted to +<code> + $placeholder = $this->placeholder(); + $this->query->add_where_expression($this->options['group'], "$field LIKE $placeholder", array($placeholder => '%' . db_like($this->value))); +</code> +placeholder() generates a automatic unique placeholder for you. + +add_where with operator 'formula' can be converted to add_where_expression. +add_having with operator 'formula' can be converted to add_having_expression. + diff --git a/sites/all/modules/views/help/api.html b/sites/all/modules/views/help/api.html new file mode 100644 index 0000000000000000000000000000000000000000..6294e262080ffb3663ca8ca35b0ee69539ecb3ed --- /dev/null +++ b/sites/all/modules/views/help/api.html @@ -0,0 +1,25 @@ +<!-- $Id: api.html,v 1.5.6.2 2010/12/17 21:13:16 merlinofchaos Exp $ --> +Views allows modules to describe their tables relationships to each other, as well as fields, filters, sort criteria and arguments via <strong>hook_views_data()</strong>. Whenever Views deems it necessary, this hook is called, the data aggregated together and cached. <strong>hook_views_data_alter()</strong> may also be used to modify existing data, changing other module's handlers or adding handlers to other module's tables. + +Views also allows modules to create new display types, style types, row styles, argument default handlers and argument validators via <strong>hook_views_handlers()</strong> and <strong>hook_views_plugins()</strong>. + +These hooks are kept in a file named MODULENAME.views.inc. This file is automatically included upon need, so there is no need to try and include this in hook_init or any other method of including .inc files. This file should store hook_views_data, hook_views_data_alter(), hook_views_plugins(), hook_views_handlers(), as well as any other hooks and subsidiary data that will only be used by your module when Views is active. All handlers and plugins provided by your module should be in separate .inc files. + +There are two similar files, MODULENAME.views_default.inc and MODULENAME.views_convert.inc which contain default views and views 1 to views 2 convert helpers, respectively. + +<h3>hook_views_api()</h3> +<strong>In order for your files to be included, your module must first implement hook_views_api()</strong> in the main .module file. This module should return array of information. The following items may be returned: + +<dl> +<dt><strong>api</strong></dt> +<dd>This must appear; it should be the oldest API version that your module can work with. If Views is currently running an older version of the API, it will ignore your module's views integration. This is a good thing, as it will prevent code crashes, at the expense of your module's functionality disappearing. +<br /> +You may find the current Views API version by calling <strong>views_api_version()</strong> which is implemented at the top of views.module. This version numbering starts at 2.0. Every time changes are made to the Views handlers and plugins or other aspects of the Views API, the number will tick up (by either .001, .01 .1 or 1 depending upon how major the changes are). Note that <strong>views_api_version()</strong> was introduced in Views 2.0-rc2 and may not exist prior to that version. You may use drupal_function_exists() to test to see if this function is there. +<br /> +Often these versions are basically compatible with each other and Views won't care if your module implements 2.000, 2.001, 2.002, etc. Your module can request that it won't work with any version older than a given version, however. Views will determine, itself, if a newer version will work. +</dd> +<dt><strong>path</strong></dt> +<dd>If your *.views*.inc files are not in the same directory as the .module file, then return the full path here. You should probably use something like drupal_get_path('module', 'yourmodulename') . '/includepath'.</dd> +<dt><strong>template path</strong></dt> +<dd>A path where the module has stored it's views template files. When you have specificed this key views automatically uses the template files for the views. You can use the same naming conventions like for normal views template files.</dd> +</dl> diff --git a/sites/all/modules/views/help/argument.html b/sites/all/modules/views/help/argument.html new file mode 100644 index 0000000000000000000000000000000000000000..992f62d8eefab018236ec44d6e2d81412dc9e872 --- /dev/null +++ b/sites/all/modules/views/help/argument.html @@ -0,0 +1,58 @@ +<!-- $Id: argument.html,v 1.8.6.1 2010/03/19 23:03:13 merlinofchaos Exp $ --> +Arguments are input. While they often come from the URL, <strong>they don't always</strong> so please don't be shocked when they don't. Each display type may have its own source for arguments. Block displays have no source of arguments at all; they cannot pull arguments from the URL, and often require use of the default argument PHP code in order to get arguments. The argument default plugins can be used to get arguments into a block view. See "Provide default", below. + +In general, arguments are used to filter the view, and in that sense they have a very close relationship to filters, but that isn't necessarily true for every argument. Arguments can be used for any purpose, really; the extent of what the argument does is up to the developer of the argument, but the arguments that come with Views are almost entirely filters. + +A typical use of an argument might be to reduce a view to a single node, a single user, or nodes with a given taxonomy term. + +<h3>Action to take if argument is not present</h3> +<dl> +<dt>Ignore</dt> +<dd>The argument is removed from the view as though it weren't there and all results will be displayed.</dd> + +<dt>Hide view / Page not found</dt> +<dd>The view will remove itself entirely if the argument is not present; for a block this means it simply won't appear. For page views the View will return a 404 and present a "Page not found" error. </dd> + +<dt>Display empty text</dt> +<dd>The value of the <a href=topic:views/empty-text>empty text</a> will be displayed.</dd> + +<dt>Summary</dt> +<dd>The view will attempt to display a summary of arguments available, based upon the view, and provide links to the view with those arguments. Summaries have their own style handlers as well as options. The default summary style simply displays a list of arguments with a count of entries found per argument. This special mode is a very powerful part of Views.</dd> + +<dt>Provide default</dt> +<dd>If no argument is given, a default argument can be selected. The method of choosing the default argument is selectable and pluggable.</dd> +</dl> + +<h3>Wildcards</h3> +All arguments have a 'wildcard', which is an argument that means to use all values. In practice, it is the same as 'Ignore' above, where the argument is simply removed and the view is created without the argument. The wildcard title is used in titles and breadcrumb trails. +<h3>Default arguments</h3> +Default argument selection is available <strong>only if the action to take is "Provide default"</strong>. When that is selected, a new fieldset will appear letting you choose what the default argument will be. Views provides the following default selectors by default (but other modules may add more): +<dl> +<dt>Fixed entry </dt> +<dd>You may directly enter what the argument will be. This is not a variable, it will always be the same argument. </dd> +<dt>Node ID from URL</dt> +<dd>This will attempt to find a Node ID from the URL, and is primarily useful for the Node: ID argument (though other arguments that use Node IDs, such as the CCK Node Reference argument, will find it useful too). For example, when visiting the path 'node/1' or 'node/1/edit' it will know that the '1' in that path is a node ID and use it.</dd> +<dt>User ID from URL</dt> +<dd>Like Node ID from URL, this will attempt to find a user ID from the path. It also includes an option to look for a node and use the node author as the user ID.</dd> +<dt>User ID from logged in user</dt> +<dd>You can use this to easily default a menu item to the logged in user. For example, if you created the path 'blogs' and gave it a User: ID argument with this default, 'blogs' would go to the user's own blogs, and blogs/1 would go to User ID 1's blogs.</dd> +</dl> + +Please bear in mind that the selection of default argument happens only if an argument is not provided. If using a display that has no argument source, such as a block, this will always be used. However, if using a display that reads arguments from the URL, this will happen only if the URL did not contain an argument. +<h3>Argument validation</h3> +Arguments can also have validators, which are pluggable systems used to ensure that arguments fit within certain parameters. When a validator is chosen, it may provide some settings for the validator, including the action to take if an argument is presented, but it fails to validate. These actions are generally the same as the default actions above, excluding the ability to provide another default. + +If a view provides a menu option, such as a tab, if the argument does not validate the tab will not appear. + +This sytem can have other validators plugged in; by default, Views provides: +<dl> +<dt>Basic validation</dt> +<dd>Ensures that the argument is present. A PHP NULL value (from eg. PHP default argument code) will invalidate.</dd> +<dt>Node</dt> +<dd>Ensure that the argument is a valid Node ID. You may select which types of node the validator will accept.</dd> +<dt>Taxonomy term</dt> +<dd>Ensure that the argument is a valid taxonomy term. This includes options to limit to specific vocabularies and can transform the argument to the right type depending upon the actual argument. Set the Argument Type option to the actual type of data that the argument being used is expecting.</dd> +<dt>PHP Code</dt> +<dd>You may enter arbitrary PHP code, similar to the php block visibility code, to determine if the argument is valid or not.</dd> + +</dl> diff --git a/sites/all/modules/views/help/display-attachment.html b/sites/all/modules/views/help/display-attachment.html new file mode 100644 index 0000000000000000000000000000000000000000..3a682eddee9277c2af502447c917930dcb187413 --- /dev/null +++ b/sites/all/modules/views/help/display-attachment.html @@ -0,0 +1,2 @@ +<!-- $Id: display-attachment.html,v 1.2 2008/04/29 00:35:07 merlinofchaos Exp $ --> +Attachment displays are 'attached' to another display in the same view. When the display is visited, the attached display will also be rendered and may be placed before, after or both before and after the original display. Attachment displays are often useful for displaying an argument summary view along with a page display that accepts arguments. This can be used to provide a kind of glossary. \ No newline at end of file diff --git a/sites/all/modules/views/help/display-block.html b/sites/all/modules/views/help/display-block.html new file mode 100644 index 0000000000000000000000000000000000000000..713c6ef88e88fcfc1a54857d89fb3ee52abcf557 --- /dev/null +++ b/sites/all/modules/views/help/display-block.html @@ -0,0 +1,11 @@ +<!-- $Id: display-block.html,v 1.5 2008/10/14 17:06:02 merlinofchaos Exp $ --> +Block displays will show up on your blocks administration page. Once a block display is created and saved, it can be enabled and positioned in your theme by visiting <strong>administer >> site building >> blocks</strong> and selecting it from the list. + +Blocks <strong>do not</strong> accept arguments from any source; the only way to get arguments to a block is to provide defaults to it, possibly via the PHP Code default setting. + +<ul> +<li>Edit the argument in question; you may want to override this argument if you have multiple displays using it.</li> +<li>Change the "Action to take if argument is not present" to "Provide default argument". This will bring up a new box called "Provide default argument options".</li> +<li>The most common default argument type used for blocks is Node from URL, where it attempts to determine if the URL refers to a node, for example if visiting 'node/1' or 'node/1/edit'. User ID from URL is also very common.</li> +<li>If you change the default argument type to 'PHP Code' (note: You must have permission to use PHP code on your site) you can enter PHP to define the argument needed. Simply return the argument.</li> +</ul> diff --git a/sites/all/modules/views/help/display-default.html b/sites/all/modules/views/help/display-default.html new file mode 100644 index 0000000000000000000000000000000000000000..c50b50328866d41dbcd943a44863c5003b6c0b71 --- /dev/null +++ b/sites/all/modules/views/help/display-default.html @@ -0,0 +1,5 @@ +<!-- $Id: display-default.html,v 1.2 2008/04/29 00:35:07 merlinofchaos Exp $ --> +The default display is primarily a display to store settings, and isn't actually used anywhere within the Views system. It is possible for external programs to use the default display, but if they do they will (hopefully) tell you which display they will be working with. The default display is also a convenient display to use to embed into your site using PHP snippets; this is useful, for example, in node content, but this is something that should generally only be done by administrators. + +In general, you probably want to add either a <a href="topic:views/display-page">page display</a> or a <a href="topic:views/display-block">block display</a>. + diff --git a/sites/all/modules/views/help/display-feed.html b/sites/all/modules/views/help/display-feed.html new file mode 100644 index 0000000000000000000000000000000000000000..690d640323b79badfd5a60f9afe37e09a5ce95f0 --- /dev/null +++ b/sites/all/modules/views/help/display-feed.html @@ -0,0 +1,2 @@ +<!-- $Id: display-feed.html,v 1.2 2008/05/05 05:09:36 merlinofchaos Exp $ --> +A feed display allows you to attach an RSS feed to a view. \ No newline at end of file diff --git a/sites/all/modules/views/help/display-page.html b/sites/all/modules/views/help/display-page.html new file mode 100644 index 0000000000000000000000000000000000000000..1ea3338a2a5372d88a1bbda269b2085865e1eff9 --- /dev/null +++ b/sites/all/modules/views/help/display-page.html @@ -0,0 +1,6 @@ +<!-- $Id: display-page.html,v 1.3.6.1 2010/03/25 20:31:11 merlinofchaos Exp $ --> +Page displays have a <a href="topic:views/path">path</a> and an optional <a href="topic:views/menu">menu</a> component. Page displays will be the primary content for the page, meaning they will be displayed in the main content area when you visit the URL that corresponds to the path. + +Page displays take their arguments from the URL. You can embed arguments into the URL using %; in previous versions of Views, this was '$arg'. For example, 'node/%/foo' will accept URLs such as 'node/1/foo'. + +Please remember that using a % placeholder makes the argument required. If you wish to have an optional argument, simply omit the % from the path. I.e. using "page/%" as the path requires an argument and visiting 'http://www.example.com/page' will not trigger the view. \ No newline at end of file diff --git a/sites/all/modules/views/help/display.html b/sites/all/modules/views/help/display.html new file mode 100644 index 0000000000000000000000000000000000000000..df1e36660db92f68e0b11adb5c3a437a993538ce --- /dev/null +++ b/sites/all/modules/views/help/display.html @@ -0,0 +1,12 @@ +<!-- $Id: display.html,v 1.2.6.2 2010/12/09 01:06:33 merlinofchaos Exp $ --> +Displays tell Views where the output should go. By adding a display to a View, you can have your view appear as a page, or as a block, or even as an attachment to a different display on the view. + +Each display can have its own settings, but when created, a display will take all of its <em>basic settings</em> from the <strong>default display</strong> which all Views must have. For most settings, there is an <a href="topic:views/overrides">override</a> button that will override that single setting for the current display. Overridden settings will have a mark in the summary for that display. All 'default display settings' are shown in the other displays in '<i>italic</i>'. When you override a setting, then it is shown 'normal'. + +Please keep in mind that when you are editing a setting on a display that is not overridden, then by default you are editing that for all displays. + +Overriding <strong>fields</strong>, <strong>arguments</strong>, <strong>sorts</strong>, <strong>filters</strong> and <strong>relationships</strong>, can only be done by overriding the entire group or none of them. To do this, click on the header for the filters or the rearrange button. Once you override, the display will then have its own copies of the fields/filters/etc and changes to the defaults will not be reflected on your display. + +With the <strong>Reorder</strong> button you can organize the order of your displays. +With the <strong>Analysis</strong> button the system checks the view and may give you suggestions if something is wrong. +You can <strong>clone a display</strong> by using the link in the header of the display. \ No newline at end of file diff --git a/sites/all/modules/views/help/embed.html b/sites/all/modules/views/help/embed.html new file mode 100644 index 0000000000000000000000000000000000000000..f66ecc4c82afaeffc301e7fe918eee43f2c26bc4 --- /dev/null +++ b/sites/all/modules/views/help/embed.html @@ -0,0 +1,25 @@ +<!-- $Id: embed.html,v 1.1 2008/06/13 00:56:19 merlinofchaos Exp $ --> +You can easily embed the results of a view into other parts of your site; +either with code as a module, or in nodes or blocks as snippets. The +easiest way is to use the function <strong>views_embed_view()</strong>: + +<code>/** + * Embed a view using a PHP snippet. + * + * This function is meant to be called from PHP snippets, should one wish to + * embed a view in a node or something. It's meant to provide the simplest + * solution and doesn't really offer a lot of options, but breaking the function + * apart is pretty easy, and this provides a worthwhile guide to doing so. + * + * @param $name + * The name of the view to embed. + * @param $display_id + * The display id to embed. If unsure, use 'default', as it will always be + * valid. But things like 'page' or 'block' should work here. + * @param ... + * Any additional parameters will be passed as arguments. + */ +function views_embed_view($name, $display_id = 'default') { +</code> + +To figure out the id of a display, hover your mouse over the tab to select that display. Everything after the '#views-tab-' is the id of that display. This ID is guaranteed never to change unless you delete the display and create a new one. diff --git a/sites/all/modules/views/help/example-author-block.html b/sites/all/modules/views/help/example-author-block.html new file mode 100644 index 0000000000000000000000000000000000000000..e8c11e13eb124eddd473cbd7be5dc12ce50d8d5a --- /dev/null +++ b/sites/all/modules/views/help/example-author-block.html @@ -0,0 +1,78 @@ +<!-- $Id: example-author-block.html,v 1.1.6.2 2010/08/13 22:22:28 merlinofchaos Exp $ --> +<p>In this example you will create a context-sensitive block that shows the titles of recent blog entries by an author when viewing one of their posts. This will demonstrate using Views <em>arguments</em> to dynamically filter a view's contents at display time.</p> + +<p>Before working through this example, enable the <strong>Blog</strong> module and populate some entries from a few different users.</p> + +<h3>Creating the View</h3> +<p>The first step is creating a view for our recent blog entries block. Because the block will show the titles of blog entries, this view is considered a "Node" type. Go to <a target="_blank" href="/admin/structure/views/add">add new view</a>, enter the following properties, and click <strong>Next</strong>:</p> + +<dl> + <dt>View name</dt> + <dd>recent_blog_entries</dd> + <dt>View description</dt> + <dd>List of recent blog entries for a given author.</dd> + <dt>View tag</dt> + <dd>blog</dd> + <dt>View type</dt> + <dd>Node</dd> +</dl> + +<h3>Generating a list of blog entries</h3> +<p>It will be much easier to see the view progress if we can see it doing something. In this section, we will create a basic view displaying blog entry titles.</p> + +<ol> +<li>In the third column, locate the <strong>Fields</strong> area. Generally speaking, fields are the pieces of information that you want to display in the view (in this case, node title). Click the <strong>+</strong> icon to add a field.</li> +<li>Scroll down to <strong>Defaults: Add fields</strong>, below the settings table. A large selection of fields will be available.</li> +<li>In the <strong>Groups</strong> drop-down menu, select <em>Node</em>. This will limit the list to only the default fields exposed by Node module.</li> +<li>Scroll down the list, select the <em>Node: Title</em> field, and click <strong>Add</strong>.</li> +<li>You will now be presented with settings for the <em>Node: Title</em> field. Delete the label from the <strong>Label</strong> field, so that each individual node title is not prefixed with the word "Title." Additionally, check the <em>Link this field to its node</em> box so that visitors who see an interesting title can click directly on it to read the blog entry to which it belongs.</li> +<li>When finished, click <strong>Update</strong>. If you scroll down to the <strong>Live Preview</strong> section, you should now see a list of several node titles; however both blog entries and other node types will be in the list. Let's fix that.</li> +<li>In the fourth column, locate the <strong>Filters</strong> area. Filters limit the results displayed in the view, and we can use this to our advantage here by showing node titles only from blog entries and not every type of node. Click the <strong>+</strong> icon to add a filter.</li> +<li>As before, scroll down to the <strong>Defaults: Add filters</strong> section, select <em>Node</em> from the <strong>Groups</strong> select box to limit the list of options to only those exposed by Node module.</li> +<li>Scroll down and select the <em>Node: Type</em> field and click <strong>Add</strong>. In the settings page that appears, leave <strong>Operator</strong> as <em>Is one of</em> and select <em>Blog entry</em> under <strong>Node type</strong>. Click <strong>Update</strong> when finished.</li> +<li>Now, by scrolling down to <strong>Live preview</strong>, you'll see that the list only shows blog entries.</li> +</ol> + +<h3>Adding context with arguments</h3> +<p>While filters are very useful for limiting the results of a view when the condition is always consistent (for example, a view of blog entry nodes should <em>always</em> be filtered by the blog entry type), something filters can't do is smart decision-making based on the page context. In our case, we want the view to display a different list of blog entries when looking at a post by user 'admin' than we do when looking at a post by user 'member', and filters won't be able to help.</p> + +<p>Luckily, there's another way to filter a view's content: <em>arguments</em>. Through arguments, Views are able to obtain additional context (typically via dynamic URLs with IDs in them) and can take this context into consideration when displaying the view.</p> + +<p>Let's walk through adding and configuring an argument to our view so that we can change its contents based on post author.</p> + +<ol> +<li>In the third column, locate the <strong>Arguments</strong> area. Click the <strong>+</strong> icon to add an argument.</li> +<li>Because we are basing the view around content <em>authors</em>, this time under <strong>Groups</strong> select <em>User</em>. Check <em>User: Uid</em> and click <strong>Add</strong>.</li> +<li>The <strong>Defaults: Configure Argument User: Uid</strong> settings page has a lot going on, but only a few things that need our attention.</li> +<li>The <strong>Title</strong> field here, unlike the Title field under <em>Basic Settings</em>, can be based upon the context that the view is being displayed in. Change the title to 'Recent entries by %1.' %1 will later be expanded to the user's name (based on the User: Uid argument) when the view is displayed.</li> +<li>Under <strong>Action to take if argument is not present</strong>, there are a variety of options, ranging from displaying a 404 or a 403 page to simply displaying all values in the view. In our case, if an argument isn't specified (which it won't be, since this view will be displayed in a sidebar block, not as a page with its own URL), we want to give it a default one to act on. Select <em>Provide default argument</em>.</li> +<li>Assuming JavaScript is enabled in your browser, you should now get another selection for <strong>Default argument type</strong>. Select <em>User ID from URL</em>. This will cause Views to first see if it can figure out a user ID from the current URL (for example, user/1). If it can't, it will instead check to see if the current page is a node page (such as node/42) and, if so, take the user ID from the node's author field instead.</li> +<li><strong>Validator options</strong> provide a useful way to control what kind of arguments your view will accept. Select <em>User</em> as the <strong>Validator</strong>. By default, changing this setting will check the incoming argument and ensure it's a valid user ID; if not, the view will be hidden from the page.</li> +<li>Once you have changed the argument's title, default argument, and validator options, click <strong>Update</strong> to save your changes.</li> +<li>You'll notice that now the Live preview no longer shows anything. Did we just break the view? Fortunately, no. It's merely abiding by our wishes to hide itself if there is no valid user ID given to it. Try entering a '1' in the <strong>Arguments</strong> box and clicking <strong>Preview</strong>. You should now see a list of only user 1's blog entries.</li> +</ol> + +<h3>Creating the block</h3> +<p>So the live preview is now showing basically what we want. There's just one problem: we have no way to stick what we've done so far into a sidebar block! Let's fix that by adding a new <strong>Display</strong>.</p> + +<ol> +<li>In the first column, under <strong>Defaults</strong>, there is a select box containing entries such as <em>Page</em>, <em>Feed</em>, and, yes, <em>Block</em>! Select <em>Block</em> and click <strong>Add display</strong>.</li> +<li>There's not much else to do here as far as Views is concerned. Under <strong>Block settings</strong>, click the <em>None</em> link next to <strong>Admin</strong> and fill in a description for the block in the administrative interface, such as: 'Recent blog entries by author.' and click <strong>Update</strong>.</li> +<li>Save your work by clicking the <strong>Save</strong> button at the bottom of the Views interface. You should receive a message that the view has been saved.</li> +<li>Next, navigate to the <a target="_blank" href="/admin/build/block">blocks interface</a> and drag the 'Recent blog entries by author' block to the right sidebar region (or similar) and click <strong>Save blocks</strong>.</li> +<li>You'll notice this appeared to do nothing. No block shows in the sidebar. But remember, we are looking at an adminitrative page; we are not looking at a page that would provide a user ID context. Navigate to the <a target="_blank" href="/blog">main blog listing</a> and click on an entry there. You should now see a sidebar block, titled something like "Recent entries by admin," with a list of blog entries beneath it.</li> +</ol> + +<h3>Finishing touches</h3> +<p>There are still a few remaining things to do before our view is complete. For example, we said that the block was to show <em>recent</em> blog entries, but instead it's showing them in the order they were entered, with oldest on top. Additionally, even unpublished entries are showing in the list currently.</p> + +<ol> +<li>Return to the <a target="_blank" href="/admin/structure/views/edit/recent_blog_entries">recent_blog_entries view edit page</a>.</li> +<li>Add an additional filter by clicking the <strong>+</strong> icon in the <strong>Filters</strong> section in the fourth column.</li> +<li>Change <strong>Groups</strong> to <em>Node</em> and select <em>Node: Published</em>. Click <strong>Add</strong>.</li> +<li>Under the <strong>Published</strong> selection, choose <em>Yes</em> and click <strong>Update</strong>.</li> +<li>To handle sorting, locate the <strong>Sort criteria</strong> area, just above filters, and click the <strong>+</strong> icon there.</li> +<li>Under <strong>Groups</strong>, again select <em>Node</em>. From the list of options, check <em>Node: Post date</em> and click <strong>Add</strong>.</li> +<li>In the settings page, change <strong>Sort order</strong> to <em>Descending</em>. This will place the newer posts on top of the older ones. Click <strong>Update</strong> when finished.</li> +<li>Finally, <strong>Save</strong> the view for your new settings to take effect.</li> +</ol> diff --git a/sites/all/modules/views/help/example-recent-stories.html b/sites/all/modules/views/help/example-recent-stories.html new file mode 100644 index 0000000000000000000000000000000000000000..57f373a0ecba9f99cbff989b8e9c42c35f1a6041 --- /dev/null +++ b/sites/all/modules/views/help/example-recent-stories.html @@ -0,0 +1,58 @@ +<!-- $Id: example-recent-stories.html,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ --> +In this example you will create a list of nodes of the content type "story", to be shown in a block. Through this step-by-step process, you will become familiar with some basic steps in creating a view, and familiarize yourself with the Views User Interface. + +<ol> +<li><h3>Creating a new view</h3> +<p>Go to <a target="_blank" href="base_url:admin/structure/views/add">add new view</a>. Give your new view the name 'recent_stories', description 'Recent Stories', tag 'story', type 'Node' and click <strong>Next</strong>.</p></li> +<li><h3>About the interface</h3> +<p>You have been brought to Views User Interface. As you start, you are editing the "Default" options for the view. In the 1st column on the left you can see the drop-down menu offers 'block', for example, to select settings specific only to block views. In the remaining columns, you will be able to add or change options by clicking on links or icons. These options will then appear below this main area. Most likely, you will need to scroll a bit to see the options appear.</p></li> +<li><h3>Selecting the fields to display</h3> + <ol> + <li>In 3rd column locate the <strong>Fields</strong> options. Click the <strong>+</strong> icon to add fields.</li> + <li>Scroll down to <strong>Defaults: Add fields</strong>. In the <strong>Groups</strong> drop-down menu select 'Node', then check the following two fields: <em>Node: Post date</em>, <em>Node: Title</em>. Then click <strong>Add</strong>.</li> + <li>You will be taken through the fields you added one at a time. Make the changes specified below. + <ul> + <li>For the <em>Post date</em> field: Delete the 'Post date' label. Change the <strong>Date format</strong> to <em>Custom</em>, and the <strong>Custom date format</strong> to 'F j, Y, g:i a' (do not type the single quotes; for the meaning of these letter codes, click on <em>the PHP docs</em> link under that box to arrive at the explanation). Click <strong>Update</strong>.</li> + <li>For the <em>Title</em> field: Delete the 'Title' label. Select <em>Link this field to its node.</em> Click <strong>Update</strong>.</li> + </ul> + </li> + <li>Scroll back up to <strong>Fields</strong> and click the <strong>↑↓</strong> icon to rearrange fields.</li> + <li>Drag the four-sided arrow next to <em>Node: Title</em> so that it appears above <em>Node: Post date</em>. Click <strong>Update</strong> to save the new field order.</li> + </ol> +</li> +<li><h3>Filtering to <em>story</em> nodes only</h3> + <ol> + <li>Click the <strong>+</strong> icon next to <strong>Filters</strong>.</li> + <li>In the <strong>Groups</strong> drop-down menu select 'Node', then check the <em>Node: Published</em> and <em>Node: Type</em> filters, and click <strong>Add</strong>.</li> + <li>Select the <em>Published</em> checkbox. Click <strong>Update</strong></li> + <li>Select <em>Is one of</em> and check <em>Story</em> in the <em>Node Type</em> field. Click <strong>Update</strong>.</li> + </ol> +</li> +<li><h3>Sorting to show most recent first</h3> + <ol> + <li>Scroll up to <strong>Sort criteria</strong> and click the <strong>+</strong> icon.</li> + <li>In the <strong>Groups</strong> drop-down menu below, select 'Node', then check <em>Node: Post date</em>, and click <strong>Add</strong>. Alternatively, you may instead check <em>Node: Last comment time</em>, or <em>Node: Updated/commented date</em>, or <em>Node: Updated date</em>.</li> + <li>Select <em>Descending</em> <strong>Sort order</strong>. Click <strong>Update</strong>.</li> + </ol> +</li> +<li><h3>Refining the basic settings</h3> + <ul> + <li>In 1st column under <strong>Basic settings</strong> locate these options: + <ul> + <li><em>Items to Display</em> setting, click <em>10</em>. Change the '10' to '4'. Click <strong>Update</strong></li> + <li><em>Style</em> setting, click <em>Unformatted</em>. Change to <em>List</em>. Click <strong>Update</strong>.</li> + </ul> + </li> + </ul> +</li> +<li><h3>Adding a block display for custom options</h3> + <ol> + <li>In the dropdown on the left, ensure that <em>Block</em> is selected, and click <strong>Add Display</strong>.</li> + <li>Under <strong>Block settings</strong>, click the <em>None</em> link next to the <em>Admin</em> setting. Change <strong>Block: Block admin description</strong> to 'Recent Stories'.</li> + </ol> +</li> +<li><h3>Saving the view</h3> +<p>Click <strong>Save</strong> to save your work.</p></li> +<li><h3>Instructing Drupal to show the block</h3> +<p>Finally, you should tell Drupal to show this block. Configure your block by going to <a target="_blank" href="base_url:admin/build/block">admin/build/block</a>. Locate the block in the list: it is labeled <em>Recent Stories</em>. Place this block in a region and click <strong>Save</strong>. You may click <em>Configure</em> to set a different title, to determine which roles can view the block, and on which pages it appears; If you want your block on the front page only, enter '<front>'.</p></li> +</ol> diff --git a/sites/all/modules/views/help/example-user-feed.html b/sites/all/modules/views/help/example-user-feed.html new file mode 100644 index 0000000000000000000000000000000000000000..58e8ab352df3bb89a0f5abb032aaa8d84a022502 --- /dev/null +++ b/sites/all/modules/views/help/example-user-feed.html @@ -0,0 +1,74 @@ +<!-- $Id: example-user-feed.html,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ --> +<p>In this example you will create a <em>Feed display</em> to show nodes by individual users, dynamically selected through the URL. You will become familiar with the Views 2 interface, as well as learn how to use an argument to pull in a user name and use it in a dynamically created path.</p> +<p>A <em>feed</em> is a data format that places your site's content into a file that can be read and displayed by news reader programs. When visiting a site, you may notice a small <a href="http://drupal.org/misc/feed.png">RSS transmission icon</a>, whereby clicking on it, you can subscribe to the site's most recent content. This makes it easier for your visitors to keep up to date with your website. You can also use this format to aggregate information into other sites. For more information, please watch a video from Common Craft about <a href="http://www.commoncraft.com/rss_plain_english">RSS in plain English</a>.</p> +<p>Note, Drupal automatically creates a feed for your website, but you may want to create feeds with specific information. In this case, a list per user. </p> +<ol> + <li> + <h3>Creating a new view </h3> + <ol> + <li>Go to <a target="_blank" href="/admin/structure/views/add">add new view</a>. Give it the name 'user_feed', description 'A feed of user nodes.', tag 'users', type 'Node' and click Next.</li> + </ol> + </li> + <li><strong>About the Interface.</strong> You have been brought to the Views User Interface. As you start, you are editing the "Default" options for the view. In the 1st column on the left- you can see the pull-down menu offers 'Feed', for example, to select settings specific only to RSS views. In the remaining columns, you will be able to add or change options by clicking on links or icons. These options appear below this main area. Most likely, you will need to scroll to see the options appear. As you make changes, these options will appear in bold until you save your view.</li> + <li> + <h3>Change default display</h3> + <ol> + <li>Under <strong>Basic Settings</strong> in the 2nd column, click <em>Row style: Fields</em></li> + <li>A menu loads below, <em>Defaults: How should each row in this view be styled</em>, check the <em>Node</em> option, and click <strong>Update</strong>.</li> + <li>This loads another options menu, <em>Defaults: Row style options</em> click <strong>Update</strong>.</li> + </ol> + </li> + <li> + <h3>Create the RSS view </h3> + <ol> + <li>In the 1st column, select 'Feed' in the drop-down menu, and click <strong>Add Display</strong>.</li> + <li>Under <strong>Basic Settings </strong>in the 2nd column, click<em> Row style:Missing style plugin</em></li> + <li>Note, options appear below the Views Interface, you may need to scroll to see <em>Feed: How should each row in this view be styled</em><br /> + tick <strong>Node</strong>, then <strong>Update</strong></li> + <li>This loads the next options menu- <em>Display type: </em>select "Use default RSS settings", click <strong>Update</strong>.</li> + </ol> + </li> + <li> + <h3>Set the path for accessing your feed</h3> + <ol> + <li> In the 2nd column under <strong>Feed settings</strong>, click <em>Path: None </em></li> + <li>In options below <em>Feed: The menu path or URL of this view</em> enter in the path with an argument feeds/%/rss.xml</li> + <li>Click <strong>Update</strong></li> + </ol> + </li> + <li> + <h3>Set up your arguments to say which user's nodes to display</h3> + <ol> + <li>To the right of <strong>Arguments</strong>, click the + sign to add and argument</li> + <li>In the Feed: Add arguments menu that loads below, select User in the pull-down menu</li> + <li>Check the box <em>User: Name</em>, click <strong>Add</strong></li> + <li>Scroll down to options to find <strong>Case in path:</strong> select <em>Lower case</em></li> + <li>Check the box <em>Transform spaces to dashes in URL</em></li> + <li>Click <strong>Update default display</strong></li> + </ol> + </li> + <li> + <h3>Sort to show most recent at top of feed</h3> + <ol> + <li>Scroll up to <strong>Sort criteria</strong> in the right most column and click the + icon.</li> + <li>In the <strong>Groups</strong> drop-down menu below, select 'Node', then check <em>Node: Post date</em>, and click <strong>Add</strong>. </li> + <li>Select <em>Descending</em> <strong>Sort order</strong>. Click <strong>Update</strong>.</li> + </ol> + </li> + <li> + <h3>Set filters to hide unpublished entries</h3> + <ol> + <li>Click the + icon next to <strong>Filters</strong>. In the options below, select <em>Node</em> under <strong>Groups</strong> drop-down menu, choose the <em>Node: Published</em> filter, and click <strong>Add</strong>.</li> + <li>Check the box <em>Published</em>. Click <strong>Update default display</strong></li> + </ol> + </li> + <li> + <h3>Test</h3> + <ol> + <li>Click <strong>Save</strong></li> + <li>Under <strong>Live preview</strong> type in the name of a user, in lowercase, replacing spaces with dashes, click <strong>Preview</strong>.</li> + <li>You should test and find your feeds at URLs like http://yoursite.com/feeds/user-name/rss.xml</li> + <li>You can use this path for aggregating on another site. You can also attach the RSS feed to another display of view to make the feed link appear on that display.</li> + </ol> + </li> +</ol> \ No newline at end of file diff --git a/sites/all/modules/views/help/example-users-by-role.html b/sites/all/modules/views/help/example-users-by-role.html new file mode 100644 index 0000000000000000000000000000000000000000..1d8033eb4d00b0bf2d0e480b10451719a5c75d09 --- /dev/null +++ b/sites/all/modules/views/help/example-users-by-role.html @@ -0,0 +1,48 @@ +<!-- $Id: example-users-by-role.html,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ --> +In this example you will create a page view listing users on your site. Through this step-by-step process, you will become familiar with some basic steps in creating a view, and familiarize yourself with the Views User Interface. + +<ol> +<li><h3>Creating a new view</h3> +<p>Go to <a target="_blank" href="base_url:admin/structure/views/add">add new view</a>. Give your new view the name 'user_list', description 'A simple user listing.', tag 'users', type 'User' and click <strong>Next</strong>.</p></li> +<li><h3>About the Interface</h3> +<p>You have been brought to the Views User Interface. As you start, you are editing the "Default" options for the view. In the 1st column on the left you can see the drop-down menu offers 'block', for example, to select settings specific only to block views. In the remaining columns, you will be able to add or change options by clicking on links or icons. These options will then appear below this main area. Most likely, you will need to scroll to see the options appear. As you make changes, these options will appear in bold until you save your view.</p></li> +<li><h3>Creating a page display; choosing a URL and creating a menu link</h3> + <ol> + <li>In the 1st column, ensure that 'Page' is selected in the drop-down menu, and click <strong>Add Display</strong>.</li> + <li>Next we'll define the path for this page. A page must have a path, and we define it early so that Views doesn't warn us "Display Page uses path but path is undefined." Locate the <strong>Page settings</strong> in the 2nd column, and click the <em>None</em> link next to the <em>Path</em> setting. In the options editing area that appears below, set the path to 'user_list' (or something Implement you prefer) and click <strong>Update</strong>.</li> + <li>Next to <em>Menu</em> setting, Click the <em>No menu</em> link. In the options which appear below, select <em>Normal menu entry</em>, and set the title to 'User list' and click <strong>Update</strong>.</li> + <li>Scroll up to <strong>Basic settings</strong>, in that same 2nd column, and click the <em>No</em> link next to <em>Use pager</em>. Below, in the options, select <em>Full pager</em> and click <strong>Update default display</strong>.</li> + </ol> +</li> +<li><h3>Selecting the fields to display</h3> + <ol> + <li>In 3rd column locate the <strong>Fields</strong> options. Click the <strong>+</strong> icon to add fields.</li> + <li>Scroll down to <strong>Defaults: Add fields</strong>. In the <strong>Groups</strong> drop-down menu select 'User', then check the following fields: <em>User: Created date</em>, <em>User: Delete link</em>, <em>User: Edit link</em>, <em>User: Last access</em>, <em>User: Name</em> and <em>User: Picture</em>. Then click <strong>Add</strong>.</li> + <li>You will be taken through the fields you added one at a time. Click <strong>Update default display</strong> to go to each next field. Leave the default options on all fields except <em>Delete link</em>; change that field's label to 'Operations'.</li> + <li>Scroll back up to <strong>Fields</strong> and click the <strong>↑↓</strong> icon to rearrange fields. Down below, drag the <em>Name</em> field, by dragging its four-sided arrow, to the top. Drag the <em>Delete link (Operations)</em> field to the bottom, and the <em>Edit link</em> field just above it. Then click <strong>Update</strong>.</li> + </ol> +</li> +<li><h3>Seeing what we've done so far</h3> +<p>At this point, you have done enough to create a valid view. If you scroll down, you will see a preview of your view. If it doesn't show already, click the <strong>Preview</strong> button; but generally this display updates automatically whenever you finish working in one of the mini forms.</p></li> +<li><h3>Styling the view as a table; combining related fields into columns</h3> + <ol> + <li>Under <strong>Basic settings</strong>, in the 1st column, click the <em>Unformatted</em> link next to the <em>Style</em> setting. In the options below, under <strong>Page: How should this view be styled</strong>, choose <em>Table</em> and click <strong>Update default display</strong>.</li> + <li>You will be taken to a <strong>Page: Style options</strong> form to edit the table settings. Locate our <em>Edit link</em> field in this mini form, and notice the <strong>Column</strong> drop-down. Change this drop-down to show <em>Operations</em>. In the <strong>Separator</strong> column next to the <em>Operations</em> field, type ' | ' (note the spaces around the <strong>|</strong> symbol). Check all of the <strong>Sortable</strong> checkboxes, and set <strong>Default sort</strong> to <em>Name</em>. When finished, click <strong>Update default display</strong>.</li> + </ol> +</li> +<li><h3>Filtering the user list to exclude unwanted entries</h3> + <ol> + <li>Click the <strong>+</strong> icon next to <strong>Filters</strong>.</li> + <li>In the <strong>Groups</strong> drop-down menu select 'User', then check the <em>User: Name</em> filter, and click <strong>Add</strong>.</li> + <li>Select <em>Is not one of</em> and enter 'Anonymous' in the <strong>Usernames</strong> box. Click <strong>Update default display</strong>.</li> + </ol> +</li> +<li><h3>Adding an argument to list users by role dynamically</h3> + <ol> + <li>Scroll up to <strong>Arguments</strong>, and click its <strong>+</strong> icon.</li> + <li>Check the <em>User: Roles</em> argument, and click <strong>Add</strong>. Set the title to '%1' (don't type the quotes), and under <strong>Action to take if argument is not present</strong> select <em>Summary, sorted ascending</em>. Leave the other settings as they are. Click <strong>Update default display</strong>, and click <strong>Update</strong> through the prompts that follow to accept their default values.</li> + </ol> +</li> +<li><h3>Saving the view</h3> +<p>Finally, click the <strong>Save</strong> button to save your work. At the very top, click <strong>View "Page"</strong> to go to your new view!</p></li> +</ol> diff --git a/sites/all/modules/views/help/field.html b/sites/all/modules/views/help/field.html new file mode 100644 index 0000000000000000000000000000000000000000..83e42aee5d28f44a2015da8883659d8f5c56aaba --- /dev/null +++ b/sites/all/modules/views/help/field.html @@ -0,0 +1,6 @@ +<!-- $Id: field.html,v 1.2 2008/05/15 19:17:11 merlinofchaos Exp $ --> +Fields are the individual pieces of data being displayed. Adding the fields <em>Node: Title</em>, <em>Node: Type</em>, and <em>Node: Post date</em> to a node view, for example, includes the title, content type and creation date in the displayed results). + +Fields may not appear on every display, because not all style plugins actually use fields. For example, the 'node' row plugin simply displays the node through Drupal's normal mechanisms, and fields are not involved. + +For the most part, the field settings should be self explanatory. Fields will appear in the order that they are arranged in, and they will usually appear with the label they are given. \ No newline at end of file diff --git a/sites/all/modules/views/help/filter.html b/sites/all/modules/views/help/filter.html new file mode 100644 index 0000000000000000000000000000000000000000..447862e361e00cbb336ad8cfd6f5569cdec5d802 --- /dev/null +++ b/sites/all/modules/views/help/filter.html @@ -0,0 +1,13 @@ +<!-- $Id: filter.html,v 1.3 2009/02/20 20:46:48 merlinofchaos Exp $ --> +Filters are used to reduce the data set that Views provides. That is to say, without any filters applied, Views will return all of your content. You don't want that, so at least some filters must be used. + +Some very commonly used filters: +<ul> +<li> The 'Node: Published' filter is used to restrict a node View to only nodes that are are have the 'published' box checked. This can be very important to prevent users from viewing content they should not have access to.</li> +<li> The 'Node: Promoted to front page' filter can be used to show only nodes that have the 'promote to front page' turned on. </li> +<li> The 'Node: Type' filter is useful for showing only certain types of nodes. Let's say you wanted users to see only nodes that were 'book' nodes, or a combination of 'book' nodes and 'staff-blog' nodes. This filter allows you to select exactly that.</li> +<li> The 'User: Current' filter will show only nodes that the logged in user has authored.</li> +<li> The 'Node: Post date' filter can be used to show only nodes posted before, after, or between a range of dates.</li> +</ul> + +The above list is only a tiny fraction of the filters available in Views, referenced here to give an idea of the kinds of tasks filters can accomplish. diff --git a/sites/all/modules/views/help/getting-started.html b/sites/all/modules/views/help/getting-started.html new file mode 100644 index 0000000000000000000000000000000000000000..a29a2c6ab7c82094ffbece35ee5821aac1193e79 --- /dev/null +++ b/sites/all/modules/views/help/getting-started.html @@ -0,0 +1,23 @@ +<!-- $Id: getting-started.html,v 1.8 2008/10/14 18:20:25 merlinofchaos Exp $ --> +For those new to Views, it can be a complex system that appears totally overwhelming. The good news is that the UI is designed to compartmentalize everything; this means that for the most part, you can ignore the parts you're not interested in. Start small and build your way up. + +Because of this, the edit UI can seem overwhelming at first, but there are really just a few things you <strong>have</strong> to know. The rest you can find through exploration. The Views Edit UI image, below, gives an overview of what you'll find on the edit UI. + +<div class="help-box" style="text-align:center"> +<a href="path:images/overview-ui-large.png"><img src="path:images/overview-ui-small.png" /></a> +<em>The Views Edit UI</em> +</div> + +Notes: +1) Every view has a number of <a href="topic:views/display">displays</a> which represent where output will be placed. If you're familiar with the original Views 1, you could set a view to be a 'page', with a URL (path), or a block that could show up in a sidebar. With Views 2, you can add as many displays as you like. In addition, you have the <em>default</em> display which contains the basic settings, but doesn't actually show up anywhere. + +2) When you click on the link for an item, a form will open up. For browsers with smaller resolutions, you may have to scroll down a little to see this form. If a form is open, the item its attached to will be highlighted. + +3) <a href="topic:views/overrides">Overrides</a> mean that a particular display is <strong>not</strong> using default settings. When you create a new display, many of its settings will start off using default values. This will be indicated by italics and a lighter color. <strong>If you change these values without first overriding them, you will change the default value for all displays that use them.</strong> + +4) Some items, particularly styles, have additional settings. Ordinarily when you <em>update</em> a style, if it has additional settings you will automatically see that form next. Often, you will need to go directly to those settings. + +5) You can safely leave a view page to go and do other things. If you come back, the view will still be there, stored in a cache. Keep in mind, however, that while you do this, that view is <em>locked</em>, meaning another user cannot edit this view without breaking the lock. Breaking the lock will discard your changes. + +It helps to have something particular in mind that you want to accomplish when using Views. Here are a couple of ideas and a brief sketch of how to accomplish what you want. + diff --git a/sites/all/modules/views/help/images/node-term_node-term_data-large.png b/sites/all/modules/views/help/images/node-term_node-term_data-large.png new file mode 100644 index 0000000000000000000000000000000000000000..4fcd19146f92075a6fac35bc9f3eb3e429fe7b99 Binary files /dev/null and b/sites/all/modules/views/help/images/node-term_node-term_data-large.png differ diff --git a/sites/all/modules/views/help/images/node-term_node-term_data.png b/sites/all/modules/views/help/images/node-term_node-term_data.png new file mode 100644 index 0000000000000000000000000000000000000000..de1273c98a099a182ff8a05783ec22599220d64b Binary files /dev/null and b/sites/all/modules/views/help/images/node-term_node-term_data.png differ diff --git a/sites/all/modules/views/help/images/overview-ui-large.png b/sites/all/modules/views/help/images/overview-ui-large.png new file mode 100644 index 0000000000000000000000000000000000000000..04fbe90d1485ab7b9121237dcb80559099108425 Binary files /dev/null and b/sites/all/modules/views/help/images/overview-ui-large.png differ diff --git a/sites/all/modules/views/help/images/overview-ui-small.png b/sites/all/modules/views/help/images/overview-ui-small.png new file mode 100644 index 0000000000000000000000000000000000000000..ed7595f26b81039f74adc44e2ac70ac5c0c887b0 Binary files /dev/null and b/sites/all/modules/views/help/images/overview-ui-small.png differ diff --git a/sites/all/modules/views/help/images/style-breakdown-large.png b/sites/all/modules/views/help/images/style-breakdown-large.png new file mode 100644 index 0000000000000000000000000000000000000000..698b8cc32ad649054ad42a7c1dafb2eb57392f27 Binary files /dev/null and b/sites/all/modules/views/help/images/style-breakdown-large.png differ diff --git a/sites/all/modules/views/help/images/style-breakdown.png b/sites/all/modules/views/help/images/style-breakdown.png new file mode 100644 index 0000000000000000000000000000000000000000..d7513a89bad1e7e40606a35dd160f82cf8c75d50 Binary files /dev/null and b/sites/all/modules/views/help/images/style-breakdown.png differ diff --git a/sites/all/modules/views/help/images/views1-admin-large.png b/sites/all/modules/views/help/images/views1-admin-large.png new file mode 100644 index 0000000000000000000000000000000000000000..06744bddc5ded58cee4c2ec2d6bc9be194b55fc5 Binary files /dev/null and b/sites/all/modules/views/help/images/views1-admin-large.png differ diff --git a/sites/all/modules/views/help/images/views1-admin.png b/sites/all/modules/views/help/images/views1-admin.png new file mode 100644 index 0000000000000000000000000000000000000000..398c145b90e440c3a3b63dfde8278e40e75a9225 Binary files /dev/null and b/sites/all/modules/views/help/images/views1-admin.png differ diff --git a/sites/all/modules/views/help/images/views1-changeviewtype-large.png b/sites/all/modules/views/help/images/views1-changeviewtype-large.png new file mode 100644 index 0000000000000000000000000000000000000000..5c58d81377074cac4b1cd35c8e5fb4a2b2c18e69 Binary files /dev/null and b/sites/all/modules/views/help/images/views1-changeviewtype-large.png differ diff --git a/sites/all/modules/views/help/images/views1-changeviewtype.png b/sites/all/modules/views/help/images/views1-changeviewtype.png new file mode 100644 index 0000000000000000000000000000000000000000..6b1798a33b3f2cf05bdda51cbfc3adaafca04e8f Binary files /dev/null and b/sites/all/modules/views/help/images/views1-changeviewtype.png differ diff --git a/sites/all/modules/views/help/images/views2-addaview-large.png b/sites/all/modules/views/help/images/views2-addaview-large.png new file mode 100644 index 0000000000000000000000000000000000000000..bbad1b18fefef095764c98b71bc5a915fca90478 Binary files /dev/null and b/sites/all/modules/views/help/images/views2-addaview-large.png differ diff --git a/sites/all/modules/views/help/images/views2-addaview.png b/sites/all/modules/views/help/images/views2-addaview.png new file mode 100644 index 0000000000000000000000000000000000000000..546ea169c95f9dd0116217962555a52bbedee065 Binary files /dev/null and b/sites/all/modules/views/help/images/views2-addaview.png differ diff --git a/sites/all/modules/views/help/images/views2-adddisplay-large.png b/sites/all/modules/views/help/images/views2-adddisplay-large.png new file mode 100644 index 0000000000000000000000000000000000000000..51c367551a19d7fe693205a5eacd957145d8c8cd Binary files /dev/null and b/sites/all/modules/views/help/images/views2-adddisplay-large.png differ diff --git a/sites/all/modules/views/help/images/views2-adddisplay.png b/sites/all/modules/views/help/images/views2-adddisplay.png new file mode 100644 index 0000000000000000000000000000000000000000..dff143e56ea5b275e042cdee13fc3bac31b6ec7c Binary files /dev/null and b/sites/all/modules/views/help/images/views2-adddisplay.png differ diff --git a/sites/all/modules/views/help/images/views2-addfields-large.png b/sites/all/modules/views/help/images/views2-addfields-large.png new file mode 100644 index 0000000000000000000000000000000000000000..b7c1ba58c2339a28772927f64cff85353dc088bb Binary files /dev/null and b/sites/all/modules/views/help/images/views2-addfields-large.png differ diff --git a/sites/all/modules/views/help/images/views2-addfields.png b/sites/all/modules/views/help/images/views2-addfields.png new file mode 100644 index 0000000000000000000000000000000000000000..e70c75817b355440f91e4d79d13d9c60322fa671 Binary files /dev/null and b/sites/all/modules/views/help/images/views2-addfields.png differ diff --git a/sites/all/modules/views/help/images/views2-addfieldsajax-large.png b/sites/all/modules/views/help/images/views2-addfieldsajax-large.png new file mode 100644 index 0000000000000000000000000000000000000000..a9308a0317004ed6d6c12a519d8d29a60990b89a Binary files /dev/null and b/sites/all/modules/views/help/images/views2-addfieldsajax-large.png differ diff --git a/sites/all/modules/views/help/images/views2-addfieldsajax.png b/sites/all/modules/views/help/images/views2-addfieldsajax.png new file mode 100644 index 0000000000000000000000000000000000000000..3043d04a500361f250cd5007989ff62b0301b61f Binary files /dev/null and b/sites/all/modules/views/help/images/views2-addfieldsajax.png differ diff --git a/sites/all/modules/views/help/images/views2-admin-large.png b/sites/all/modules/views/help/images/views2-admin-large.png new file mode 100644 index 0000000000000000000000000000000000000000..d262bc55e7a4e0a131c99221571a32f8653cb941 Binary files /dev/null and b/sites/all/modules/views/help/images/views2-admin-large.png differ diff --git a/sites/all/modules/views/help/images/views2-admin.png b/sites/all/modules/views/help/images/views2-admin.png new file mode 100644 index 0000000000000000000000000000000000000000..c2733638179d986ed12262aa85596acbe91964ff Binary files /dev/null and b/sites/all/modules/views/help/images/views2-admin.png differ diff --git a/sites/all/modules/views/help/images/views2-changedisplaystyle-large.png b/sites/all/modules/views/help/images/views2-changedisplaystyle-large.png new file mode 100644 index 0000000000000000000000000000000000000000..09925df87fb64afbdfc3b2d44b31c70fc19015ad Binary files /dev/null and b/sites/all/modules/views/help/images/views2-changedisplaystyle-large.png differ diff --git a/sites/all/modules/views/help/images/views2-changedisplaystyle.png b/sites/all/modules/views/help/images/views2-changedisplaystyle.png new file mode 100644 index 0000000000000000000000000000000000000000..5a82ea5610d32d23af16e6f284a31176b7e88c76 Binary files /dev/null and b/sites/all/modules/views/help/images/views2-changedisplaystyle.png differ diff --git a/sites/all/modules/views/help/images/views2-fieldspreview-large.png b/sites/all/modules/views/help/images/views2-fieldspreview-large.png new file mode 100644 index 0000000000000000000000000000000000000000..e2730b414b4c26872e21de02484528ae210ac289 Binary files /dev/null and b/sites/all/modules/views/help/images/views2-fieldspreview-large.png differ diff --git a/sites/all/modules/views/help/images/views2-fieldspreview.png b/sites/all/modules/views/help/images/views2-fieldspreview.png new file mode 100644 index 0000000000000000000000000000000000000000..5a41ab29de02367587a31eaaeee95bcae0da281b Binary files /dev/null and b/sites/all/modules/views/help/images/views2-fieldspreview.png differ diff --git a/sites/all/modules/views/help/images/views2-newview-large.png b/sites/all/modules/views/help/images/views2-newview-large.png new file mode 100644 index 0000000000000000000000000000000000000000..498627a90940b9fd7958ceab239aada9d6b1298b Binary files /dev/null and b/sites/all/modules/views/help/images/views2-newview-large.png differ diff --git a/sites/all/modules/views/help/images/views2-newview.png b/sites/all/modules/views/help/images/views2-newview.png new file mode 100644 index 0000000000000000000000000000000000000000..b522d2ce36bf1eed232940bbacf051f1a3f99856 Binary files /dev/null and b/sites/all/modules/views/help/images/views2-newview.png differ diff --git a/sites/all/modules/views/help/images/views2-rearrangefields-large.png b/sites/all/modules/views/help/images/views2-rearrangefields-large.png new file mode 100644 index 0000000000000000000000000000000000000000..acfed4cdf86a00dada0adcfbaf0326679b31c667 Binary files /dev/null and b/sites/all/modules/views/help/images/views2-rearrangefields-large.png differ diff --git a/sites/all/modules/views/help/images/views2-rearrangefields.png b/sites/all/modules/views/help/images/views2-rearrangefields.png new file mode 100644 index 0000000000000000000000000000000000000000..562df08d6858b4d33b99debf0df480ab0dd70c3d Binary files /dev/null and b/sites/all/modules/views/help/images/views2-rearrangefields.png differ diff --git a/sites/all/modules/views/help/images/views2-tablestyle-large.png b/sites/all/modules/views/help/images/views2-tablestyle-large.png new file mode 100644 index 0000000000000000000000000000000000000000..67e9e6b9cc0b8a4bb92d0c2aedede6d91e071571 Binary files /dev/null and b/sites/all/modules/views/help/images/views2-tablestyle-large.png differ diff --git a/sites/all/modules/views/help/images/views2-tablestyle.png b/sites/all/modules/views/help/images/views2-tablestyle.png new file mode 100644 index 0000000000000000000000000000000000000000..f8997403ac2d266e1898c1b760b218b81a78ff4b Binary files /dev/null and b/sites/all/modules/views/help/images/views2-tablestyle.png differ diff --git a/sites/all/modules/views/help/menu.html b/sites/all/modules/views/help/menu.html new file mode 100644 index 0000000000000000000000000000000000000000..208d52d1f0eeacc9f97f085a19317e87339c3c84 --- /dev/null +++ b/sites/all/modules/views/help/menu.html @@ -0,0 +1,22 @@ +<!-- $Id: menu.html,v 1.2.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ --> +Page displays can hook into the Drupal menu system and provide <strong>menu links</strong> that will appear in the Navigation system as well as <strong>tabs</strong> that can be used to keep Views next to each other. + +For simple <strong>menu links</strong>, there is very little you need to do; simply select 'Normal menu entry' and fill in the text for the title. This will appear in the Navigation menu by default; you will need to visit the menu administration page to move this to another menu. + +Tabs are not quite so simple; there are some complex rules for using tabs in Drupal. +<ol> +<li> All tabs must have a parent, which is the next level up in the path hierarchy. For example, if the view path is 'example/taba' then the parent must be 'example'. +<li> All tabs must have one and only one default tab; this is usually the same content as the parent. +<li> If a parent does not exist, when creating the 'default' tab, Views will allow you to also create a parent item. It will automatically set up the URL for you when it does this. +<li> Tab weight is used to control what order the tabs are displayed in. Lower numbers will display more to the left. For tabs whose numbers are the same, they will be displayed alphabetically. +<li> Drupal only supports 2 levels of tabs, so be careful about trying to put tabs within tabs within tabs. That won't work. +</ol> + +For example, if you have two views that you want to be tabs, you could set it up like this: +<ul> +<li> In the first view, set the path to 'tabs/tab1'. Set it to be the 'default tab', set the title to 'Tab 1' and the weight to 0. +<li> Click update and you will be taken to a form that lets you define the parent. Since 'tabs' doesn't already exist in the system, select 'Normal menu item', and set the title to 'Tabs'. +<li> On the second view, set the path to 'tabs/tab2'; set it to be a 'Menu tab', and set the title to 'Tab 2'. +</ul> + +With this done, you will now have a Navigation link named 'Tabs' and when you click on it, you will go to the tabs, with 'Tab 1' being the default tab that appears. You can then click between Tab 1 and Tab 2. diff --git a/sites/all/modules/views/help/new.html b/sites/all/modules/views/help/new.html new file mode 100644 index 0000000000000000000000000000000000000000..606f6a614b45015d5fb1d6572dfc997d28d95b9b --- /dev/null +++ b/sites/all/modules/views/help/new.html @@ -0,0 +1,114 @@ +<!-- $Id: new.html,v 1.5.6.1 2010/10/12 21:35:03 merlinofchaos Exp $ --> +Views 2 is the newest major release of Views and it is specifically coded for Drupal 6. Views 2 retains all of the core functionality of Views 1, together with a completely revamped user interface and a large set of new features which greatly expand upon the original feature-set of Views 1. This document is a side-by-side comparison of Views 1 versus Views 2 from a user's perspective, detailing the UI changes, some new ways to perform old tasks, the cool new features of Views 2 and how these features can be used to address some of the shortcomings of Views 1. + +<h2>Admin interface</h2> +The first thing that pops out after you install Views 2 is the radically different admin interface: +<div class="help-box" style="text-align:center"> +<a href="path:images/views2-admin-large.png"><img src="path:images/views2-admin.png" /></a> +<em>Views 2 admin interface</em> +</div> + +compared to the old comfy Views 1 interface: + +<div class="help-box" style="text-align:center"> +<a href="path:images/views1-admin-large.png"><img src="path:images/views1-admin.png" /></a> +<em>Views 1 admin interface</em> +</div> + +The new admin interface performs the same functions as the old -- listing all the views in the system, providing links to add or import views and a link to Views Tools -- but has been compacted, with each view displayed as a paragraph style-row compared to the table of Views 1 and set of filters on top to ease locating views among a large list. + +Context-help is available by clicking the small blue question-mark icon. Context-help in Views 2 is provided by the <a href="http://drupal.org/project/advanced_help">Advanced Help</a> module, so make sure to install that together with installing Views 2. The small blue help icons will be available in various parts of the Views UI. In particular, look for them as part of the description of a <strong>display</strong>, when setting <strong>style</strong> options, and in various editing sections such as <strong>path</strong>, <strong>menu</strong> and the like. + +Several new attributes of each view are visible in the filter header: +<ol> +<li><strong>Tag</strong> - This is just another label for organizing and sorting views. Tags can be any text. Views that are provided by modules will often be tagged together to make it easy to find them. Tags are also added to your template suggestions, so take care what you set here. For example setting the tag <i>Page</i> will give all your views the Page template.</li> +<li><strong>Display</strong> - In Views 1 each view query was tied to its display; in other words your fields, sorts, filters, and arguments could only be displayed in the single page or block display provided in the view definition. In Views 2, view displays have been decoupled from view queries - it is now possible to have multiple page, block, and feed displays from a single view. More on view displays later. </li> +<li><strong>Type</strong> - Views 2 view types are radically different from Views 1 types. Views 1 types basically defined how the node list displays were <i>styled</i> - you had Full Nodes, Teaser List, Table View, and so on. In Views 2 view display styles have been broken out into the separate <i>Style</i> attribute. View types now refer to the primary table on which information for the query will be retrieved which controls what arguments, fields, sort criteria and filters are available. Views 2 view types are discussed later. +</li> +</ol> + +<h2>Adding a view</h2> +So let's jump in and add a view. For this example, we're going to create a <strong>user</strong> view, which will display a list of users. +<div class="help-box" style="text-align:center"> +<a href="path:images/views2-addaview-large.png"><img src="path:images/views2-addaview.png" /></a> +<em>Adding a view</em> +</div> + +The first step in adding a view is simply entering a name (only alphanumeric characters, no spaces) a description, tag, and the view type. To get the user view, we selected the <strong>User</strong> radio button. + +<div class="help-box" style="text-align:center"> +<a href="path:images/views2-newview-large.png"><img src="path:images/views2-newview.png" /></a> +<em>Configuring the new view</em> +</div> + +This might be the 2nd whoa moment as the interface here is also completely revamped from Views 1.x. The best way to summarize is to say all the pieces from the Views 1.x interface are still there...just in different places. Fields, arguments, sort critera and filters are all still there there, just in new AJAXY-flavours. + +Let's start by adding some fields: + +<div class="help-box" style="text-align:center"> +<a href="path:images/views2-addfields-large.png"><img src="path:images/views2-addfields.png" /></a> +<em>Adding fields</em> +</div> + +Clicking on the [+] icon next to the word Fields unfurls a section beneath the view information with all the available fields grouped by Comment, File, Node, Node revision, Taxonomy and User, and probably a few others. This is a general paradigm for the Views 2 interface -- clicking on a widget or link unfurls a section beneath the view information with the relevant interface. Usually, what is being edited will be hilited in yellow, as well. + +When adding items, you can use the Groups drop-down box to show only a subset of the fields available according to the above groups, or select All to see all fields available, which is what was selected when the section unfurled. For our example, we're selecting the 'User' group and adding the <strong>User: E-mail</strong>, <strong>User: Name</strong> and <strong>User: Picture</strong> fields. + +<div class="help-box" style="text-align:center"> +<a href="path:images/views2-addfieldsajax-large.png"><img src="path:images/views2-addfieldsajax.png" /></a> +<em>Adding fields</em> +</div> + +Once we add our fields they show up in the Fields section of the interface. We will be walked through each field we added, so keep clicking <strong>update</strong>, even if you don't make changes to the field and you will see the next one. + +The fields we added can be rearranged by clicking the up/down icon, right next to the add icon we used earlier. We can also remove a field using the same interface. + +<div class="help-box" style="text-align:center"> +<a href="path:images/views2-rearrangefields-large.png"><img src="path:images/views2-rearrangefields.png" /></a> +<em>Rearranging fields</em> +</div> + +From here, the fields can be dragged up and down by grabbing the little drag handle on the left and moving them where you like. Making a change to any part of the view by clicking update usually triggers a refresh of the view preview which is conveniently located right below the main interface. + +<div class="help-box" style="text-align:center"> +<a href="path:images/views2-fieldspreview-large.png"><img src="path:images/views2-fieldspreview.png" /></a> +<em>Views preview</em> +</div> + +Now that we have some fields set up we can turn our attention to Basic Settings for the view. + +It's important to note that all the interface elements pertain to the current <i>Display</i> selected for the view. As mentioned before a view can have multiple displays. The first time you create a view you'll be manipulating the <i>Default</i> display. You can add displays using the Add Display button, whose Basic Settings are completely different from each other; this lets you have as many displays of a view as you would like all sharing items such as Sort Criteria, Filters and Arguments but different display settings like Title, Style, Fields, and Pager settings. Also, any display you add automatically inherits display settings from the default display initially, so you can keep a core of common settings in your default display and add additional settings for every other display. + +<div class="help-box" style="text-align:center"> +<a href="path:images/views2-adddisplay-large.png"><img src="path:images/views2-adddisplay.png" /></a> +<em>Adding a <strong>Page</strong> display </em> +</div> +Let's stick with the Default display and twiddle some settings. We can set the <i>Title</i> to "User View 1" and the <i>Style</i> to Table. As mentioned earlier, view styles in Views 2 correspond more to view types in Views 1 (remember, List, Table, Teasers, Full nodes). + +<div class="help-box" style="text-align:center"> +<a href="path:images/views1-changeviewtype-large.png"><img src="path:images/views1-changeviewtype.png" /></a> +<em>Selecting a Views 1 View Type</em> +</div> + +In Views 2, view <i>styles</i> control how a view display looks. These styles are significantly different from the Types in Views 1; in particular, types have been 'broken up'; there is now the <em>style</em> as well as the <em>row style</em> which focus on different parts of the output. + +<div class="help-box" style="text-align:center"> +<a href="path:images/style-breakdown-large.png"><img src="path:images/style-breakdown.png" /></a> +<em>A breakdown of View output</em> +</div> + +We change the style by clicking on the current style on the left hand side of the View information area. + +<div class="help-box" style="text-align:center"> +<a href="path:images/views2-changedisplaystyle-large.png"><img src="path:images/views2-changedisplaystyle.png" /></a> +<em>Selecting a Views 2 Display Style</em> +</div> + +We're given the style options of <strong>Grid</strong>, <strong>List</strong>, <strong>Table</strong> and <strong>Unformatted</strong>. Additional display styles can be added by modules which have Views <i>style plugins</i>. Choosing a style reveals a "settings" button which you can click to configure the style you've chosen. In the shot below we've selected and are configuring the Table style, which we're using to produce a more compact output than we had earlier. + +<div class="help-box" style="text-align:center"> +<a href="path:images/views2-tablestyle-large.png"><img src="path:images/views2-tablestyle.png" /></a> +<em>Selecting and configuring the table style</em> +</div> + +... TODO: Finish this document ... diff --git a/sites/all/modules/views/help/overrides.html b/sites/all/modules/views/help/overrides.html new file mode 100644 index 0000000000000000000000000000000000000000..59b68a9ba4e8eae02d1e9b6efbe3c53fb36c8cc1 --- /dev/null +++ b/sites/all/modules/views/help/overrides.html @@ -0,0 +1,7 @@ +<!-- $Id: overrides.html,v 1.2.6.1 2010/03/10 20:00:30 merlinofchaos Exp $ --> + +If an item is <strong>using defaults</strong> then it is using values from the <strong>default display</strong>. <em>IMPORTANT NOTE:</em> If you modify this value, you are modifying the <strong>default display</strong> and thus modifying for all displays that are using default values. + +If that is not what you intend, you must click the <strong>override</strong> button. Once overridden, that display now has its own version of the value; modifying it will not modify it for other displays. + +For <strong>Relationships</strong>, <strong>arguments</strong>, <strong>fields</strong>, <strong>sort criteria</strong>, and <strong>filters</strong>, each of these must be overridden as a group! In other words, you cannot override a single filter, but instead must override all filters. A message will appear on the item to let you know what its status is, but you can only change the status by clicking on the header or the rearrange button for that item. diff --git a/sites/all/modules/views/help/path.html b/sites/all/modules/views/help/path.html new file mode 100644 index 0000000000000000000000000000000000000000..2c4404e0e10cf36c0edc213b532bcdff087f3ea8 --- /dev/null +++ b/sites/all/modules/views/help/path.html @@ -0,0 +1,8 @@ +<!-- $Id: path.html,v 1.3 2008/06/25 19:26:01 merlinofchaos Exp $ --> +If a display has a path that means that it can be retrieved directly by calling a URL as a first class page on your Drupal site. Any items after the path will be passed into the view as arguments. For example, if the path is <strong>foo/bar</strong> and a user visits <strong>http://www.example.com/foo/bar/baz/beta</strong>, 'baz' and 'beta' will be given as arguments to the view. These can be handled by adding items to the <a href="topic:views/arguments">arguments</a> section. + +You may also use placeholders in your path to represent arguments that come in the middle. For example, the path <strong>node/%/someview</strong> would expect the first argument to be the second part of the path. For example, <strong>node/21/someview</strong> would have an argument of '21'. + +<em>Note:</em> Views 1 used <strong>$arg</strong> for this kind of thing. $arg is no longer allowed as part of the path. You must use % instead. + +If multiple displays <strong>within the same view</strong> have the same path, the user will get the first display they have access to. This means you can create successfuly less restricted displays in order to give administrators and privileged users different content at the same path. \ No newline at end of file diff --git a/sites/all/modules/views/help/relationship.html b/sites/all/modules/views/help/relationship.html new file mode 100644 index 0000000000000000000000000000000000000000..b37ce143060038ffcc212f506bb1182e02310476 --- /dev/null +++ b/sites/all/modules/views/help/relationship.html @@ -0,0 +1,14 @@ +<!-- $Id: relationship.html,v 1.6 2009/02/20 20:46:48 merlinofchaos Exp $ --> +Relationships allow you to expand the query to include objects other than the base query. This is actually made more difficult to understand by the fact that Views actually includes a few relationships by default, and doesn't tell you they're there. For historical reasons, it would be inconvenient to remove these default relationships. When relationships are present, all fields (including relationships) will gain a new form item to let you select which relationship they will use. They will default to using no relationship at all. + +The main example of the relationship that is there by default is the node --> user relationship; every node has an author, and if a node is in the query, the user who wrote that node is automatically made available. [Note: the author considers it an error that this relationship is automatic, but by the time it was realized this was in error, it was too late to change it.] + +A similar relationship that is <b>not</b> automatically made available is for node revisions. Each revision has its own author, which is the user who made the revision. By adding the "Node revision: User" relationship, all of the 'user' fields, sorts, filters and arguments available to a user will now be available for the revision author. + +When a relationship is added to the view, all applicable items will gain a "Relationship" select box, where you can choose which version of that particular item you wish to use. This can be illustrated with an example: + +A 'comment' view contains the relationships 'Comment: node' and 'Comment: user'. This means that all the fields for the node that a comment is attached to are available, and all the user fields for that node author also become available. The other relationship makes fields for the author of the comment available -- very often not the author of the node! + +When you add the "User: name" field, you will be presented with a select box. Either the node relationship or the user relationship must be selected, because there are two possible user names in the view to choose from. + +Another example of relationships involves the <strong>Files</strong> table. In Drupal, files are related to users, but files are not necessarily related to nodes. However, the upload.module allows some files to be attached to nodes. The only way for Views to deal with this discrepancy is with relationships. When creating a 'node' view, it's possible to add an uploaded files relationship to get file data for nodes that were attached with the upload module. It is also possible to go the other way; from a files view you may add a relationship via the Upload table to view information about the node. diff --git a/sites/all/modules/views/help/sort.html b/sites/all/modules/views/help/sort.html new file mode 100644 index 0000000000000000000000000000000000000000..645f2dd84fd7f4119afc70fdcf7078f6b03f801f --- /dev/null +++ b/sites/all/modules/views/help/sort.html @@ -0,0 +1,25 @@ +<!-- $Id: sort.html,v 1.2 2008/06/13 00:56:19 merlinofchaos Exp $ --> +Sort criteria determine what order the records are retrieved from the database and displayed in; generally, all you need to do is pick a field and choose ascending (1, 2, 3, 4) or descending (4, 3, 2, 1) and it will be done. If you have multiple sort criteria, the second (and later) items only come into play if the first item is the same. + +Different data types sort just a little bit differently from others: +<dl> +<dt>Number fields</dt> +<dd>Number fields sort like you would expect. 1 comes before 2 which comes before 10 which comes before 100 which comes before 200, etc.</dd> +<dt>Text fields</dt> +<dd>Text fields always sort alphabetically, even if the text contains numbers. This can have some odd effects if you have numbers stored in text, because the values 1, 3, 7, 10, 12, 20, 100, 120 will sort like this: +<ul> +<li> 1 </li> +<li> 10 </li> +<li> 100 </li> +<li> 12 </li> +<li> 120 </li> +<li> 200 </li> +<li> 3 </li> +<li> 7 </li> +</ul> + +This is because these fields sort purely by characters, and not numeric value. i.e, comparing 200 and 3, the '2' comes before the '3', therefore, '200' is "smaller" than '3'. +</dd> +<dt>Date fields</dt> +<dd>Date fields often can have a 'granularity', which is a way of making similar dates actually be the same date. Take two dates that are close to each other: <strong>May 1, 2007 5:30 am</strong> and <strong>May 1, 2007 9:45am</strong>. Without granularity, the two dates are compared and the first date comes before the second date. However, if the granularity is set to 'day' it only looks at the parts of the date up to the day: <strong>May 1, 2007</strong> and <strong>May 1, 2007</strong>. At that point, they are the same, and the sort would move on to the next sort criterion.</dd> +</dl> diff --git a/sites/all/modules/views/help/style-comment-rss.html b/sites/all/modules/views/help/style-comment-rss.html new file mode 100644 index 0000000000000000000000000000000000000000..774359ce5de5b4cc2c4f5a5eab9d6c200ee76dfd --- /dev/null +++ b/sites/all/modules/views/help/style-comment-rss.html @@ -0,0 +1,2 @@ +<!-- $Id: style-comment-rss.html,v 1.1 2008/06/13 00:56:19 merlinofchaos Exp $ --> +This row style is only available to RSS styles. It produces XML necessary for an RSS feed for the comment. \ No newline at end of file diff --git a/sites/all/modules/views/help/style-fields.html b/sites/all/modules/views/help/style-fields.html new file mode 100644 index 0000000000000000000000000000000000000000..05a173b075db52a151411267cc497ced8b10be27 --- /dev/null +++ b/sites/all/modules/views/help/style-fields.html @@ -0,0 +1,6 @@ +<!-- $Id: style-fields.html,v 1.3 2008/06/17 20:07:03 merlinofchaos Exp $ --> +The <strong>fields</strong> row style displays each field defined in the view, one after another. Each field defines its own output. + +By default, each field is put in a <div> unless it is selected to be <em>inline</em>. If it is inline, it is put in a <span>. Two items in <div>s will be displayed one after another, with the second one below the first. Two items in <span>s will be displayed on the same line. One item in a <span> next to <div>s is the same as two items in <div>s. This means that for the <em>inline</em> setting to do anything, at least two consecutive items must be set inline. + +You may define a separator which will be placed between each item. This separator may be html. You can use &nbsp; to print blank space. \ No newline at end of file diff --git a/sites/all/modules/views/help/style-grid.html b/sites/all/modules/views/help/style-grid.html new file mode 100644 index 0000000000000000000000000000000000000000..d9b24fc9109c266c84c3cab6c2bf524bbf8df100 --- /dev/null +++ b/sites/all/modules/views/help/style-grid.html @@ -0,0 +1,21 @@ +<!-- $Id: style-grid.html,v 1.3.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ --> +The <strong>grid</strong> style will display each row of your view within a grid. You may customize the number of columns, though it defaults to 4. A grid looks like this: + +<table width="100%"> +<tr><td>row 1</td><td>row 2</td><td>row 3</td><td>row 4</td></tr> +<tr><td>row 5</td><td>row 6</td><td>row 7</td><td>row 8</td></tr> +<tr><td>row 9</td><td>row 10</td><td>row 11</td><td>row 12</td></tr> +<tr><td>row 13</td><td>row 14</td><td>row 15</td><td>row 16</td></tr> +</table> + +The above uses the 'horizontal' alignment, where rows are added into the grid from left to right. + +With a vertical alignment, rows will be placed from top to bottom, like this: +<table width="100%"> +<tr><td>row 1</td><td>row 5</td><td>row 9</td><td>row 13</td></tr> +<tr><td>row 2</td><td>row 6</td><td>row 10</td><td>row 14</td></tr> +<tr><td>row 3</td><td>row 7</td><td>row 11</td><td>row 15</td></tr> +<tr><td>row 4</td><td>row 8</td><td>row 12</td><td>row 16</td></tr> +</table> + +This style uses a <a href="topic:views/style-row">row style</a> to determine what each row will look like. \ No newline at end of file diff --git a/sites/all/modules/views/help/style-list.html b/sites/all/modules/views/help/style-list.html new file mode 100644 index 0000000000000000000000000000000000000000..f5e98baad035b7010a5ff1b7402f6a3074f9ca6f --- /dev/null +++ b/sites/all/modules/views/help/style-list.html @@ -0,0 +1,21 @@ +<!-- $Id: style-list.html,v 1.3.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ --> +The <strong>List</strong> view style will display every row of the view as part of an HTML list construct. For example: +<ul> +<li> Row 1 </li> +<li> Row 2 </li> +<li> Row 3 </li> +<li> Row 4 </li> +</ul> + +You may select whether or not the list is <em>ordered</em> which just means whether or not it uses numbers instead of the bullet: + +<ol> +<li> Row 1 </li> +<li> Row 2 </li> +<li> Row 3 </li> +<li> Row 4 </li> +</ol> + +The list style also uses a <em>row style</em> which means that it doesn't care what the actual output for each row of the view is. + +If you need information about using CSS to style list views, you may find this <a href="http://www.alistapart.com/stories/taminglists/">A list apart guide to styling lists</a> useful. \ No newline at end of file diff --git a/sites/all/modules/views/help/style-node-rss.html b/sites/all/modules/views/help/style-node-rss.html new file mode 100644 index 0000000000000000000000000000000000000000..332b2853ccf3114ec5e6bad6bb20244b7882d76c --- /dev/null +++ b/sites/all/modules/views/help/style-node-rss.html @@ -0,0 +1,2 @@ +<!-- $Id: style-node-rss.html,v 1.2 2008/06/13 00:56:19 merlinofchaos Exp $ --> +This row style is only available to RSS styles. It produces XML necessary for an RSS feed for the node record. \ No newline at end of file diff --git a/sites/all/modules/views/help/style-node.html b/sites/all/modules/views/help/style-node.html new file mode 100644 index 0000000000000000000000000000000000000000..360b96f4125b2befc8085409faff254808c638a7 --- /dev/null +++ b/sites/all/modules/views/help/style-node.html @@ -0,0 +1,10 @@ +<!-- $Id: style-node.html,v 1.4.6.1 2010/09/15 09:01:01 dereine Exp $ --> +The <strong>node</strong> row style will display each item of the view through Drupal's standard <em>node_view()</em> function. Views has very little control over this output, except for the options you see. Instead, the output is run through the standard node template mechanism (typically <strong>node.tpl.php</strong> or a variant thereof) and any decisions about what is output may be done there. + +Views does add an extra 'suggestion' to the list of possible node templates: <strong>node--view--VIEWNAME.tpl.php</strong> -- you may use this to theme a node specifically for the view. This can be handy for creating very small teasers and the like. + +You may opt to display the full node body or the node teaser, and you may add the node links (such as he 'comment' links that appear after a node) or not. + +Because of this behavior, <strong>the node row style does not utilize fields</strong> and the Fields section will not be displayed. + +<strong>Please note that this row style performs a node_load() for every row, and as such can produce a lot of extra queries.</strong> Sometimes this is necessary, but it can have a negative impact on your site's performance! diff --git a/sites/all/modules/views/help/style-row.html b/sites/all/modules/views/help/style-row.html new file mode 100644 index 0000000000000000000000000000000000000000..2d983035e75382b0f9e4f60506f25667291c4c1a --- /dev/null +++ b/sites/all/modules/views/help/style-row.html @@ -0,0 +1,4 @@ +<!-- $Id: style-row.html,v 1.1 2008/06/13 00:56:19 merlinofchaos Exp $ --> +A row style is an individual style to display only an individual record within a view. For example, a <strong>node</strong> type view would display one node per row; a <strong>user</strong> type view would display one user per row. + +Some row styles use <em>fields</em> which means you select from the available fields to display; others do not; they are able to use the base type and create a display. Usually, row styles that do not use fields <em>produce less efficient (slower) views</em>, so bear this in mind when contemplating the performance of your site. \ No newline at end of file diff --git a/sites/all/modules/views/help/style-rss.html b/sites/all/modules/views/help/style-rss.html new file mode 100644 index 0000000000000000000000000000000000000000..d661fd7a51bc2faa8743e5315cab3889cf7d07ce --- /dev/null +++ b/sites/all/modules/views/help/style-rss.html @@ -0,0 +1,4 @@ +<!-- $Id: style-rss.html,v 1.2 2008/06/13 00:56:19 merlinofchaos Exp $ --> +The <strong>RSS</strong> output style is only available for <em>Feed</em> display types. It will display the view as an RSS feed, which is a specialized XML output. This output is not user visible, but can be parsed by feed readers for aggregation. + +You may supply a description for the RSS feed; most feed readers will display this description along with the contents of the feed. You may also select to use the site's mission statement for the description. \ No newline at end of file diff --git a/sites/all/modules/views/help/style-summary-unformatted.html b/sites/all/modules/views/help/style-summary-unformatted.html new file mode 100644 index 0000000000000000000000000000000000000000..2350a15fbef709a1599c92f3b664d160defea736 --- /dev/null +++ b/sites/all/modules/views/help/style-summary-unformatted.html @@ -0,0 +1,4 @@ +<!-- $Id: style-summary-unformatted.html,v 1.1 2008/06/13 00:56:19 merlinofchaos Exp $ --> +The <strong>unformatted summary</strong> style is only available for <em>summary</em> styles, which are when an argument has been set to provide a summary if it was not provided with a value. This summary provides the possible candidates for the argument one after another with no special formatting. If <em>inline</em> is selected, the summary items will be enclosed within <span> tags. Otherwise the items will be in <div> tags. + +You can also elect to display the number of matching records for the argument, plus change the number of items per page for the summary. This is often useful because summary views are often quite small, but other views quite space intensive. It is very common to have far more records available in the summary view than in the more normal view. \ No newline at end of file diff --git a/sites/all/modules/views/help/style-summary.html b/sites/all/modules/views/help/style-summary.html new file mode 100644 index 0000000000000000000000000000000000000000..f6012a4f495c4d48dd97655edb1bc6ec5272bc26 --- /dev/null +++ b/sites/all/modules/views/help/style-summary.html @@ -0,0 +1,4 @@ +<!-- $Id: style-summary.html,v 1.2 2008/06/13 00:56:19 merlinofchaos Exp $ --> +The <strong>list summary</strong> style is only available for <em>summary</em> styles, which are when an argument has been set to provide a summary if it was not provided with a value. This summary provides a list of possible candidates for the argument in a standard HTML list. Like the normal list style, you may set this list to be ordered or not. + +You can also elect to display the number of matching records for the argument, plus change the number of items per page for the summary. This is often useful because summary views are often quite small, but other views quite space intensive. It is very common to have far more records available in the summary view than in the more normal view. \ No newline at end of file diff --git a/sites/all/modules/views/help/style-table.html b/sites/all/modules/views/help/style-table.html new file mode 100644 index 0000000000000000000000000000000000000000..e7fb89bec4659503e17d42fc86eeeeaf74d69274 --- /dev/null +++ b/sites/all/modules/views/help/style-table.html @@ -0,0 +1,14 @@ +<!-- $Id: style-table.html,v 1.2 2008/06/13 00:56:19 merlinofchaos Exp $ --> +The <strong>table</strong> style will display the View results as a table; each row of the table will correspond to a row from the view result. + +When setting the table options, each field in the view will be presented with some information next to each field: +<dl> +<dt> <strong>Column</strong> </dt> +<dd> By default, each field is its own column. However, you can place multiple fields in the same column. To do this, pick which field you want to represent the column, then pick another field and set the 'column' value to that field. You can place as many fields as you like in a single column, but only the main field in a column can be click-sorted.</dd> +<dt> <strong>Separator</strong> </dt> +<dd> If you have multiple fields in the same column, the separator will be placed between each one. At the very least, &nbsp; should be used, as without the separator the fields will be placed very close to each other. Common separators are a bullet, the | symbol, and a comma. If there are no other fields in the column, the separator will have no effect.</dd> +<dt> <strong>Sortable</strong> </dt> +<dd> If checked, the header for the column will be clickable, and the user may re-sort the table by clicking on this to sort by that field. At this time Views does not support click-sorting to sort by multiple columns at the same time.</dd> +<dt> <strong>Default sort</strong> </dt> +<dd> You may select a column which will be sorted by default when the table is first viewed. This column will be highlighted to the user. You may also select whether the default sort is ascending or descending.</dd> +</dl> \ No newline at end of file diff --git a/sites/all/modules/views/help/style-unformatted.html b/sites/all/modules/views/help/style-unformatted.html new file mode 100644 index 0000000000000000000000000000000000000000..777d2ed1d567578e4e69a4d8a573b1a1635a9488 --- /dev/null +++ b/sites/all/modules/views/help/style-unformatted.html @@ -0,0 +1,2 @@ +<!-- $Id: style-unformatted.html,v 1.2 2008/06/13 00:56:19 merlinofchaos Exp $ --> +The unformatted output style simply places each row of the view, one after another, with no additional formatting. diff --git a/sites/all/modules/views/help/style.html b/sites/all/modules/views/help/style.html new file mode 100644 index 0000000000000000000000000000000000000000..3eb6fdfee76cb8a42ceba071f01eaf6704ce84de --- /dev/null +++ b/sites/all/modules/views/help/style.html @@ -0,0 +1,15 @@ +<!-- $Id: style.html,v 1.4.6.1 2010/03/16 22:27:29 merlinofchaos Exp $ --> +The Views' <strong>style</strong> system is how you customize the output produced by your view. A view style is basically a smart theme template that processes the view data and then outputs it. All styles in Views can be <a href="topic:views/using-theme">overridden</a> by placing copies of the templates in your theme directory and then modifying them. See the <a href="topic:views/analyze-theme">theme: information</a> link available on all views to get hints for which templates a given view is using. + +<div class="help-box" style="text-align:center"> +<a href="path:images/style-breakdown-large.png"><img src="path:images/style-breakdown.png" /></a> +<em>A breakdown of View output</em> +</div> +By default, the style is <em>unformatted</em>, which means that there is very little style actually used; the records are simply displayed one after another, enclosed in a <div> tag so that you can use <a href="topic:views/theme-css">CSS to manipulate the view</a>. + +Some styles use a separate <a href="topic:views/style-row">row style</a> to determine how each row of the View looks. This is useful for mixing and matching styles to more readily produce exactly the kind of output you need. + +Many styles can be <strong>grouped</strong>. For styles that can, there will be a 'grouping field' option; pick one of the fields to group by. This grouping field will be displayed as a header, and all rows will be displayed beneath it. +With the Theme Developer module enabled, the field grouping in Views does not work. Disable the Theme Developer module before grouping by fields. + +Each style is its own entity. diff --git a/sites/all/modules/views/help/theme-css.html b/sites/all/modules/views/help/theme-css.html new file mode 100644 index 0000000000000000000000000000000000000000..bfa3593a6d8dc1a086112573bc1220b8a89539b4 --- /dev/null +++ b/sites/all/modules/views/help/theme-css.html @@ -0,0 +1,76 @@ +<!-- $Id: theme-css.html,v 1.3.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ --> +Views uses a wide array of CSS classes on all of its content to ensure that you can easily and accurately select exactly the content you need in order to manipulate it with CSS. + +Typically, every view is wrapped in a div with the name of the view as part of its class (for all these examples, we will assume the name of the view is <strong>myview</strong>), as well as the generic class 'view': + +<pre> +<div class="view view-myview"> +... +</div> +</pre> + +In your CSS, you can modify all views: + +<pre> +div.view { + border: 1px solid black; +} +</pre> + +Or just your view: + +<pre> +div.view-myview { + background: yellow; +} +</pre> + +By default, the general view template also provides the following classes to easily style other areas of the view: +<ul> +<li> .view-header </li> +<li> .view-filters </li> +<li> .view-content </li> +<li> .view-empty (if an "empty" text is used when the view has no results) </li> +<li> .view-footer </li> +<li> .feed-icon </li> +<li> .attachment-before (if using an "attachment" display)</li> +<li> .attachment-after (if using an "attachment" display)</li> +</ul> + +So for example: +<pre> +div.view-myview div.view-header { + /* make the header stand out */ + font-size: 120%; + font-weight: bold; +} + +div.view-myview div.view-footer { + /* Make the footer less important */ + font-size: 80%; + font-style: italic; + color: #CCC; +} +</pre> + +In the above example, we whimsically made the header bold and in a bigger font, and the footer smaller, italicized, and greyish. + +<h3>Views with fields</h3> +If your view has fields, each field is uniquely tagged with its ID. A field's ID may be gleaned from the Theme: Information page. Note that due to CSS rules, any _ in the id will be converted to - automatically, so if you have a field whose id is 'edit_node' (this is the field used to provide an "edit" link to a node), it will be 'edit-node'. Additionally, to make sure that the view IDs don't conflict with other css classes in the system, they will be pretended with 'views-field-'; thus, the final CSS class for the field with the id 'edit_node' will be <strong>views-field-edit-node</strong>. + +Exactly how this appears is going to depend upon the style you're using. For example, the 'unformatted' style uses <strong>div.views-field-edit-node</strong> and <strong>div.views-label-edit-node</strong> to access that particular field, but a table would use <strong>td.views-field-edit-node</strong> and <strong>th.views-field-edit-node</strong> to access the table header; or just <strong>.views-field-edit-node</strong> to affect both. + +<pre> +.view-myview th { + color: red; /* make all headers red */ +} + +.view-myview .views-field-title { + font-weight: bold; /* Make the 'title' field bold */ +} + +.view-myview td.views-field-body { + font-size: 60%; /* Make the text in the body field small */ +} +</pre> + diff --git a/sites/all/modules/views/help/updating.html b/sites/all/modules/views/help/updating.html new file mode 100644 index 0000000000000000000000000000000000000000..67f246a821ed7c2d32f5f228e04f5650853e5859 --- /dev/null +++ b/sites/all/modules/views/help/updating.html @@ -0,0 +1,3 @@ +<!-- $Id: updating.html,v 1.3 2008/07/03 05:05:12 merlinofchaos Exp $ --> +TODO: This document needs to be fleshed out. + diff --git a/sites/all/modules/views/help/upgrading.html b/sites/all/modules/views/help/upgrading.html new file mode 100644 index 0000000000000000000000000000000000000000..c6527b5452cc744f986e011117f28ce2c4832869 --- /dev/null +++ b/sites/all/modules/views/help/upgrading.html @@ -0,0 +1,9 @@ +;<!-- $Id: upgrading.html,v 1.1.2.2 2010/11/27 20:12:58 dereine Exp $ --> + +<h3>Updating templates</h3> +If you have theme files for node-view-$viewname of comment-view-$viewname you have +to convert them to node--view--$viewname or comment--view--$viewname. + +<h4>Updating table templates</h4> +The class variable was renamed to $classes. Additional if you want to add +classes, you should add it to $classes_array and drupal will automatically convert it to the $classes string. \ No newline at end of file diff --git a/sites/all/modules/views/help/using-theme.html b/sites/all/modules/views/help/using-theme.html new file mode 100644 index 0000000000000000000000000000000000000000..c94bbd58a4e047da2166bb817db76a319223e50a --- /dev/null +++ b/sites/all/modules/views/help/using-theme.html @@ -0,0 +1,51 @@ +<!-- $Id: using-theme.html,v 1.6.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ --> +Views theme templates are straightforward to use with the Drupal theming system. If you are unfamiliar with the theming system at all, you should probably at least read <a href="http://drupal.org/node/173880">drupal.org theming documentation</a>. That said, these are the important things you need to know: + +<ol> +<li> Copy a base Views template to one of the names provided from the Theme: Information section of the View. Copy this template right into your theme directory. </li> +<li> Clear the theme registry. See the <a href="http://drupal.org/node/173880#theme-registry">instructions</a> for how to do this. </li> +<li> Your new template should now operate; assuming you picked a nicely named template that includes the view name, that template should now be active for your view. A good example is <strong>views-view-list--foobar.tpl.php</strong> which would work for a view named 'foobar'.</li> +<li> You can now modify this template all you like.</li> +</ol> + +For any template that uses fields, the fields will be in array. In order to use this effectively, you will need to understand enough PHP to fetch data from an array. This is a place where the <a href="http://drupal.org/project/devel">devel module</a> can really help you, because you can use its dsm() function right in your template to see what variables it uses. There is an alternative to dsm() that works without devel module, but it's a bit longer to use. + +For example, I placed the following code inside a loop in views-view-table.php.php: +<code> <?php drupal_set_message('<pre>' . var_export($row, true) . '</pre>'); ?> +</code> + +And it produced this output: +<code> array ( + 'nid' => '97', + 'title' => 'Scisco Ideo Vicis Feugiat Qui', + 'name' => 'luwrepuslan', + ) +</code> + +My view had three fields: +<code>Node: Nid +Node: Title +User: Name +</code> + +The contents of the $row variable included these fields, in precisely the order that I had arranged them to using the Views rearrange link. Also worth noting, though, is that each field also has an identifier so it can easily be pulled out of the row should I want to display it differently. Using +<code><?php print $row['title']; ?> +</code> + +Would print just the title for that row. Please remember that I'm doing this inside the loop, so this will get repeated for every row of the view. + +The IDs used to fetch items from the array, id <strong>$row['title']</strong> can be quickly and easily looked up on the Theme: Information page. Once a field has been added to the view, its ID will not change, but note that if there are two "title" fields in a view, one will be 'title' and the other will be 'title1', in order to prevent namespace collisions. + +The important thing here is that Views does provide IDs. Views doesn't tell you what these IDs are, but it's easy to get them by dumping the row data and doing a simple visual inspection. Views does guarantee that these IDs will not change, unless you actually add a new field and remove the existing one (in which case 'title', above, would become 'title1'). + +<h2>The basic fields template</h2> + +The most common template people will need to rewrite is the "simple" views-view-fields.tpl.php, which is the template used by the <i>Fields</i> row style and all it does is display a simple list of fields. However, it is not that simple to the user. Because the template can't inherently know what the fields are, it has to go through an array in a loop. + +This loop isn't very handy when you really want to have fine control over the template by placing your fields precisely where and how you want. Relax, though; if you know what your fields are, you can rewrite this. If you end up writing your own HTML, the only part that is really important is the content for each field. We know from above that you can get the ID for each field on the Theme: Information page from the view. In the header for the template, we can see that the fields are all in the $fields array, and each field is an object. That leads us to this: + +<code><?php print $fields['some_id']->content; ?></code> + +Assuming you replace some_id with an id found on the theme: information page, this code will print the content for that field. You can also get the label and some other data about the field, as well as the raw information. Complete details for what is available are documented directly in views-view-fields.tpl.php. + +Keep in mind that if you rewrite your templates using this, you'll need to maintain this template whenever changes are made to the fields of the view; while this isn't generally recommend, sometimes it's necessary to get the kind of control you might ultimately need. diff --git a/sites/all/modules/views/help/view-type.html b/sites/all/modules/views/help/view-type.html new file mode 100644 index 0000000000000000000000000000000000000000..3285a857107768c9a70060e9070c6d62e86c2ede --- /dev/null +++ b/sites/all/modules/views/help/view-type.html @@ -0,0 +1,22 @@ +<!-- $Id: view-type.html,v 1.5 2009/02/20 20:46:48 merlinofchaos Exp $ --> +<p>The <strong>view type</strong> describes how this view is stored; Views is capable of having Views entirely in code that are not in the database. This allows modules to easily ship with Views built in, and it allows you to create a module to store your views for easy deployment between development and production servers.</p> + +<dl> +<dt><strong>Normal</strong></dt> +<dd>Normal views are stored in your database and are completely local to your system.</dd> + +<dt><strong>Default</strong></dt> +<dd>Default views are stored only in code and are not anywhere in your database. They may be <strong>enabled</strong> or <strong>disabled</strong> but you may not completely remove them from your system. You can <strong>override</strong> the view which will create a local copy of your view. If you do this, future updates to the version in code will not affect your view.</dd> + +<dt><strong>Overridden</strong></dt> +<dd>Overridden views are stored both in code and in the database; while overridden, the version that is in code is completely dormant. If you <strong>revert</strong> the view, the version in the database will be deleted, and the version that is in code will once again be used.</dd> +</dl> + +You may store your views in code with the following procedure: +<ol> +<li> Create a module to store the views. </li> +<li> Add the function <em>MODULENAME_views_default_views()</em> to this module. </li> +<li> Export the view you wish to store in your module in code. Cut and paste that into the abovenamed function. Make sure the last line of the view is: <em>$views[$view->name] = $view;</em></li> +<li> Make sure the last line of the function is <em>return $views;</em></li> +<li> After you make any changes, be sure to <strong>clear the Views' cache</strong>. You may do this from the <strong>Tools</strong> menu.</li> +</ol> diff --git a/sites/all/modules/views/help/views.help.ini b/sites/all/modules/views/help/views.help.ini new file mode 100644 index 0000000000000000000000000000000000000000..0895d5a7746106e41241c6aaef23897d3483231e --- /dev/null +++ b/sites/all/modules/views/help/views.help.ini @@ -0,0 +1,204 @@ +; $Id: views.help.ini,v 1.18.4.5 2010/08/26 19:00:51 dereine Exp $ +[advanced help settings] +line break = TRUE + +[about] +title = "What is Views?" +weight = -40 + +[getting-started] +title = "Getting started" +weight = -45 + +[example-users-by-role] +title = "Create a page to list users by role" +parent = getting-started +weight = -10 + +[example-recent-stories] +title = "Create a block of recent stories" +parent = getting-started +weight = 0 + +[example-user-feed] +title = "Create an RSS feed of user posts" +parent = getting-started +weight = 30 + +[example-author-block] +title = "Create a block of author's recent blog posts" +parent = getting-started +weight = 40 + +[view-type] +title = "View types" + +[display] +title = "Displays" +weight = -30 + +[display-default] +title = "Default display" +parent = display +weight = -20 + +[display-page] +title = "Page display" +parent = display +weight = -15 + +[display-block] +title = "Block display" +parent = display +weight = -10 + +[display-attachment] +title = "Attachment display" +parent = display + +[display-feed] +title = "Feed display" +parent = display + +[argument] +title = "Arguments" +parent = about + +[field] +title = "Fields" +parent = about + +[sort] +title = "Sorts" +parent = about + +[filter] +title = "Filters" +parent = about + +[relationship] +title = "Relationships" +parent = about + +[style] +title = "Output styles (View styles)" +weight = -20 + +[style-row] +title = "View row styles" +parent = style +weight = 10 + +[style-list] +title = "List output style" +parent = style + +[style-unformatted] +title = "Unformatted output style" +parent = style +weight = -6 + +[style-table] +title = "Table output style" +parent = style +weight = -5 + +[style-grid] +title = "Grid output style" +parent = style +weight = -5 + +[style-rss] +title = "RSS output style" +parent = style +weight = -5 + +[style-fields] +title = "Fields row style" +parent = style-row + +[style-node] +title = "Node row style" +parent = style-row + +[style-node-rss] +title = "Node RSS item row style" +parent = style-row + +[style-comment-rss] +title = "Comment RSS item row style" +parent = style-row + +[style-summary-unformatted] +title = "Unformatted summary style" +parent = "style" +weight = 10 + +[style-summary] +title = "List summary style" +parent = "style" +weight = 10 + +[menu] +title = "Menu options (page display)" + +[path] +title = "Path options (page display)" + +[analyze-theme] +title = "Theme information" + +[using-theme] +title = "Using Views templates" +parent = analyze-theme + +[theme-css] +title = "Using CSS with Views" +parent = analyze-theme + +[overrides] +title = "What are overrides?" + +[embed] +title = "Embedding a view into other parts of your site" + +[new] +title = "What's new in Views 2" +weight = -42 + +[upgrading] +title = "Upgrading your Views from Drupal 6 to Drupal 7" + +; API related +[api] +title = "Views' API" +weight = 100 + +[api-tables] +title = "Describing tables to Views" +weight = -100 +parent = api + +[api-default-views] +title = "Using default views in your module" +weight = -90 +parent = api + +[api-handlers] +title = "How Views handlers work" +weight = -50 +parent = api + +[api-plugins] +title = "How Views plugins work" +weight = -40 +parent = api + +[api-upgrading] +title = "Upgrading to Drupal 7 (API)" +parent = api + +[api-example] +title = "Integrating the Node Example module" +parent = api +weight = 100 diff --git a/sites/all/modules/views/images/arrow-active.png b/sites/all/modules/views/images/arrow-active.png new file mode 100644 index 0000000000000000000000000000000000000000..3bbd3c27f29f9a1781276a2ae8faa7afd5d2d36e Binary files /dev/null and b/sites/all/modules/views/images/arrow-active.png differ diff --git a/sites/all/modules/views/images/expanded-options.png b/sites/all/modules/views/images/expanded-options.png new file mode 100644 index 0000000000000000000000000000000000000000..b7b755c0a44f7ebae4972e9489f7d004c0ab82c7 Binary files /dev/null and b/sites/all/modules/views/images/expanded-options.png differ diff --git a/sites/all/modules/views/images/overridden.gif b/sites/all/modules/views/images/overridden.gif new file mode 100644 index 0000000000000000000000000000000000000000..b7811910ef8bc56ffd61757641c3a062353ef8ed Binary files /dev/null and b/sites/all/modules/views/images/overridden.gif differ diff --git a/sites/all/modules/views/images/sprites.png b/sites/all/modules/views/images/sprites.png new file mode 100644 index 0000000000000000000000000000000000000000..908362229800862620d45fafead8476df6f66c2d Binary files /dev/null and b/sites/all/modules/views/images/sprites.png differ diff --git a/sites/all/modules/views/images/status-active.gif b/sites/all/modules/views/images/status-active.gif new file mode 100644 index 0000000000000000000000000000000000000000..207e95c3fa8cc31a89af150ad74059b1667922b6 Binary files /dev/null and b/sites/all/modules/views/images/status-active.gif differ diff --git a/sites/all/modules/views/includes/admin.inc b/sites/all/modules/views/includes/admin.inc new file mode 100644 index 0000000000000000000000000000000000000000..cd0d64a1afc24cc3c77866c6686e66076f0c4d75 --- /dev/null +++ b/sites/all/modules/views/includes/admin.inc @@ -0,0 +1,4167 @@ +<?php +// $Id: admin.inc,v 1.161.4.86 2011/01/04 23:54:35 dereine Exp $ +/** + * @file admin.inc + * Provides the Views' administrative interface. + */ + +/** + * Page callback to list views in the system. + */ +function views_ui_list_views($arg = NULL) { + if ($arg != NULL) { + return drupal_not_found(); + } + + $output = theme('views_ui_list_views'); + views_ui_check_advanced_help(); + return $output; +} + +/** + * Check to see if the advanced help module is installed, and if not put up + * a message. + * + * Only call this function if the user is already in a position for this to + * be useful. + */ +function views_ui_check_advanced_help() { + if (variable_get('views_hide_help_message', FALSE)) { + return; + } + + if (!module_exists('advanced_help')) { + $filename = db_query_range("SELECT filename FROM {system} WHERE type = 'module' AND name = 'advanced_help'", 0, 1) + ->fetchField(); + if ($filename && file_exists($filename)) { + drupal_set_message(t('If you <a href="@modules">enable the advanced help module</a>, Views will provide more and better help. <a href="@hide">Hide this message.</a>', array('@modules' => url('admin/modules'),'@hide' => url('admin/structure/views/tools')))); + } + else { + drupal_set_message(t('If you install the advanced help module from !href, Views will provide more and better help. <a href="@hide">Hide this message.</a>', array('!href' => l('http://drupal.org/project/advanced_help', 'http://drupal.org/project/advanced_help'), '@hide' => url('admin/structure/views/tools')))); + } + } +} + +/** + * Preprocess the list views theme + */ +function template_preprocess_views_ui_list_views(&$vars) { + $items = array(); + $sorts = array(); + + $views = views_get_all_views(); + + // Respond to a reset command by clearing session and doing a drupal goto + // back to the base URL. + if (isset($_GET['op']) && $_GET['op'] == t('Reset')) { + unset($_SESSION['views']['#admin']); + drupal_goto('admin/structure/views'); + } + if (count($_GET) <= 1) { + if (isset($_SESSION['views']['#admin']) && is_array($_SESSION['views']['#admin'])) { + $_GET += $_SESSION['views']['#admin']; + } + } + else { + $_SESSION['views']['#admin'] = $_GET; + unset($_SESSION['views']['#admin']['q']); + } + + $form_state = array( + 'views' => $views, + 'method' => 'get', + 'rerender' => TRUE, + 'no_redirect' => TRUE, + 'always_process' => TRUE, + 'build_info' => array( + 'args' => array(), + ), + ); + + $vars['widgets'] = drupal_build_form('views_ui_list_views_form', $form_state); + unset($vars['widgets']['form_id']); + unset($vars['widgets']['form_build_id']); + $vars['widgets'] = drupal_render($vars['widgets']); + + $vars['help_type_icon'] = ''; + if (module_exists('advanced_help')) { + $vars['help_type_icon'] = theme('advanced_help_topic', array('module' => 'views', 'topic' => 'view-type')); + } + + $base_tables = views_fetch_base_tables(); + + foreach ($views as $view) { + if ($form_state['values']['tag'] != 'all') { + if ($form_state['values']['tag'] == 'none') { + if (!empty($view->tag)) { + continue; + } + } + elseif ($form_state['values']['tag'] != $view->tag) { + continue; + } + } + if ($form_state['values']['type'] != 'all' && $form_state['values']['type'] != $view->type) { + continue; + } + + if ($form_state['values']['base'] != 'all' && $form_state['values']['base'] != $view->base_table) { + continue; + } + + if ($form_state['values']['display'] != 'all' && empty($view->display[$form_state['values']['display']])) { + continue; + } + + if ($form_state['values']['status'] != 'all' && (!empty($view->disabled) == $form_state['values']['status'])) { + continue; + } + + $item = new stdClass(); + $item->ops = array(); + + if (empty($view->disabled)) { + $item->ops[] = l(t('Edit'), "admin/structure/views/edit/$view->name"); + $item->ops[] = l(t('Export'), "admin/structure/views/export/$view->name"); + $item->ops[] = l(t('Clone'), "admin/structure/views/clone/$view->name"); + } + if ($view->type != t('Default')) { + $text = $view->type == t('Overridden') ? t('Revert') : t('Delete'); + $item->ops[] = l($text, "admin/structure/views/delete/$view->name"); + } + else { + if (empty($view->disabled)) { + $item->ops[] = l(t('Disable'), "admin/structure/views/disable/$view->name", array('query' => drupal_get_destination())); + } + else { + $item->ops[] = l(t('Enable'), "admin/structure/views/enable/$view->name", array('query' => drupal_get_destination())); + } + } + + $item->ops = implode(' | ', $item->ops); + if (empty($view->display)) { + $item->path = t('Warning! Broken view!'); + } + else { + $view->init_display(); // Make sure all the handlers are set up + $all_paths = array(); + foreach ($view->display as $display) { + if (!empty($display->handler) && $display->handler->has_path()) { + $one_path = $display->handler->get_option('path'); + if (empty($path_sort)) { + $path_sort = strtolower($one_path); + } + if (empty($view->disabled) && strpos($one_path, '%') === FALSE) { + $all_paths[] = l($one_path, $one_path); + } + else { + $all_paths[] = check_plain($one_path); + } + } + } + if (!empty($all_paths)) { + $item->path = implode(', ', array_unique($all_paths)); + } + } + + $item->type = $view->type; + $item->name = $view->name; + + if (!empty($view->tag)) { + $item->tag = $view->tag; + } + + $item->title = $view->get_title(); + $item->base = !empty($base_tables[$view->base_table]['title']) ? $base_tables[$view->base_table]['title'] : t('Broken'); + + $item->displays = array(); + foreach ($view->display as $display) { + if (!empty($display->handler->definition['admin'])) { + $item->displays[$display->handler->definition['admin']] = TRUE; + } + } + + if ($item->displays) { + ksort($item->displays); + $item->displays = implode(', ', array_keys($item->displays)); + } + + $item->description = check_plain($view->description); + $item->classes = empty($view->disabled) ? 'view-enabled' : 'view-disabled'; + $items[] = $item; + + $sort = intval(empty($view->disabled) xor $form_state['values']['sort'] == 'asc'); + + switch ($form_state['values']['order']) { + case 'name': + default: + $sort .= strtolower($view->name); + break; + case 'title': + $sort .= strtolower($item->title); + break; + case 'path': + $sort .= strtolower($raw_path); // $path; + break; + case 'type': + $sort .= $view->type . $view->name; + break; + case 'tag': + $sort .= strtolower($view->tag); + break; + case 'desc': + $sort .= strtolower($view->description); + break; + } + + $sorts[] = $sort; + } + + if ($form_state['values']['sort'] == 'desc') { + arsort($sorts); + } + else { + asort($sorts); + } + + $i = array(); + foreach ($sorts as $id => $title) { + $i[] = $items[$id]; + } + + views_add_css('views-list'); + $vars['views'] = $i; + + $getting_started = ''; + if (module_exists('advanced_help')) { + $getting_started = theme('advanced_help_topic', array('module' => 'views', 'topic' => 'getting-started', 'type' => 'title')); + } + if (!$getting_started) { + $getting_started = t('Install the advanced help module for the getting started'); + } + + $vars['help'] = t('Not sure what to do? Try the "!getting-started" page.', array('!getting-started' => $getting_started)); +} + +/** + * Provide a form for sorting and filtering the list of views. + */ +function views_ui_list_views_form($form, &$form_state) { + if (!variable_get('clean_url', FALSE)) { + $form['q'] = array( + '#type' => 'hidden', + '#value' => $_GET['q'], + ); + } + + $all = array('all' => t('- All -')); + $none = array('none' => t('- None -')); + + $form['type'] = array( + '#type' => 'select', + '#title' => t('Storage'), + '#options' => array( + 'all' => t('- All -'), + t('Normal') => t('Normal'), + t('Default') => t('Default'), + t('Overridden') => t('Overridden'), + ), + '#default_value' => 'all', + ); + + $status = array( + '0' => t('Disabled'), + '1' => t('Enabled'), + ); + $form['status'] = array( + '#type' => 'select', + '#title' => t('Status'), + '#options' => array_merge($all, $status), + '#default_value' => 'all', + ); + + $bases = array(); + foreach (views_fetch_base_tables() as $table => $info) { + $bases[$table] = $info['title']; + } + + $form['base'] = array( + '#type' => 'select', + '#title' => t('Type'), + '#options' => array_merge($all, $bases), + '#default_value' => 'all', + ); + + $tags = array(); + + $extras = array(); + if (isset($form_state['views'])) { + foreach ($form_state['views'] as $name => $view) { + if (!empty($view->tag)) { + $tags[$view->tag] = $view->tag; + } + } + } + + asort($tags); + + $form['tag'] = array( + '#type' => 'select', + '#title' => t('Tag'), + '#options' => array_merge($all, $none, $tags), + '#default_value' => 'all', + ); + + $displays = array(); + foreach (views_fetch_plugin_data('display') as $id => $info) { + if (!empty($info['admin'])) { + $displays[$id] = $info['admin']; + } + } + + asort($displays); + + $form['display'] = array( + '#type' => 'select', + '#title' => t('Displays'), + '#options' => array_merge($all, $displays), + '#default_value' => 'all', + ); + + $form['order'] = array( + '#type' => 'select', + '#title' => t('Sort by'), + '#options' => array( + 'name' => t('Name'), + 'title' => t('Title'), + 'tag' => t('Tag'), + 'path' => t('Path'), + 'type' => t('Type'), + 'desc' => t('Description'), + ), + '#default_value' => 'name', + ); + + $form['sort'] = array( + '#type' => 'select', + '#title' => t('Order'), + '#options' => array( + 'asc' => t('Up'), + 'desc' => t('Down'), + ), + '#default_value' => 'asc', + ); + + // Autosubmit all form elements. + ctools_add_js('auto-submit'); + $form['#attributes']['class'][] = 'ctools-auto-submit-full-form'; + + $form['submit'] = array( + '#name' => '', // so it won't in the $_GET args + '#type' => 'submit', + '#id' => 'edit-views-apply', + '#value' => t('Apply'), + '#attributes' => array('class' => array('ctools-use-ajax', 'ctools-auto-submit-click')), + ); + + if (!empty($_SESSION['views']['#admin'])) { + $form['reset'] = array( + '#type' => 'submit', + '#id' => 'edit-views-reset', + '#value' => t('Reset'), + ); + } + $form['#token'] = FALSE; + + return $form; +} + +/** + * Page callback for the live preview. + * + * @todo make this use a template + */ +function views_ui_preview($js, $view) { + // Take off the items we know so that we can have just the args passed + // in for later use. + $func_args = func_get_args(); + array_shift($func_args); // $js + array_shift($func_args); // $view + $display_id = (count($func_args)) ? array_shift($func_args) : 'default'; + + $form_state = array( + 'display_id' => $display_id, + 'view_args' => $func_args ? implode('/', $func_args) : '', + 'rerender' => TRUE, + 'no_redirect' => TRUE, + 'view' => &$view, + 'ajax' => $js, + 'build_info' => array( + 'args' => array(), + ), + ); + + $form = drupal_build_form('views_ui_preview_form', $form_state); + $output = drupal_render($form); + $args = array(); + if (isset($form_state['view_args']) && $form_state['view_args'] !== '') { + $args = explode('/', $form_state['view_args']); + } + + $errors = $view->validate(); + if ($errors === TRUE) { + $view->ajax = $js; + $view->live_preview = TRUE; + $view->set_exposed_input($_POST); + + // Store the current view URL for later use: + $view->set_display($form_state['display_id']); + $view->set_arguments($args); + + if ($view->display_handler->get_option('path')) { + $path = $view->get_url(); + } + + // Make view links come back to preview. + $view->override_path = 'admin/structure/views/nojs/preview/' . $view->name . '/' . $form_state['display_id']; + + // also override $_GET['q'] so we get the pager + $_GET['q'] = $view->override_path; + if ($form_state['view_args']) { + $_GET['q'] .= '/' . $form_state['view_args']; + } + + $preview = $view->preview($form_state['display_id'], $args); + + // Get information from the preview for display. + if (!empty($view->build_info['query'])) { + $rows = array(); + $query = $view->build_info['query']; + // Only the sql default class has a method getArguments. + $quoted = array(); + + if (get_class($view->query) == 'views_plugin_query_default') { + $arguments = $query->getArguments(); + $connection = Database::getConnection(); + foreach ((array)$query->arguments() as $key => $val) { + $quoted[$key] = $connection->quote($val); + } + } + $rows[] = array('<strong>' . t('Query') . '</strong>', '<pre>' . check_plain(strtr($query, $quoted)) . '</pre>'); + if (!empty($view->additional_queries)) { + $queries = '<strong>' . t('These queries were run during view rendering:') . '</strong>'; + foreach ($view->additional_queries as $query) { + if ($queries) { + $queries .= "\n"; + } + $queries .= t('[@time ms]', array('@time' => intval($query[1] * 100000) / 100)) . ' ' . $query[0]; + } + + $rows[] = array('<strong>' . t('Other queries') . '</strong>', '<pre>' . $queries . '</pre>'); + } + + $rows[] = array('<strong>' . t('Title') . '</strong>', filter_xss_admin($view->get_title())); + if (isset($path)) { + $path = l($path, $path); + } + else { + $path = t('This display has no path.'); + } + + $rows[] = array('<strong>' . t('Path') . '</strong>', $path); + + $rows[] = array('<strong>' . t('Query build time') . '</strong>', t('@time ms', array('@time' => intval($view->build_time * 100000) / 100))); + $rows[] = array('<strong>' . t('Query execute time') . '</strong>', t('@time ms', array('@time' => intval($view->execute_time * 100000) / 100))); + $rows[] = array('<strong>' . t('View render time') . '</strong>', t('@time ms', array('@time' => intval($view->render_time * 100000) / 100))); + drupal_alter('views_preview_info', $rows, $view); + + $info = theme('table', array('rows' => $rows)); + } + else { + $info = theme('table', array('rows' => array(array('<strong>' . t('Query') . '</strong>', t('No query was run'))))); + } + } + else { + foreach ($errors as $error) { + drupal_set_message($error, 'error'); + } + $preview = t('Unable to preview due to validation errors.'); + $info = ''; + } + + $info = '<div class="views-query-info">' . $info . '</div>'; + + if (variable_get('views_ui_query_on_top', FALSE)) { + $output .= $info . $preview; + } + else { + $output .= $preview . $info; + } + + if (!$js) { + views_add_css('views-admin'); + drupal_set_title($view->get_title()); + return $output; + } + else { + $commands = array(); + if (!empty($view->js_settings)) { + $commands[] = ajax_command_settings($view->js_settings); + } + $display = ''; + if ($messages = theme('status_messages')) { + $display = '<div class="views-messages">' . $messages . '</div>'; + } + $display .= $output; + if ($display) { + $commands[] = ajax_command_html('div#views-live-preview', $display); + } + return $js ? array('#type' => 'ajax', '#commands' => $commands) : $commands; + } +} + +/** + * Form for generating argument information for the live preview. + */ +function views_ui_preview_form($form, &$form_state) { + $view = &$form_state['view']; + $view->init_display(); + $options = array(); + foreach ($view->display as $id => $display) { + $options[$id] = $display->display_title; + } + + $form['#attributes'] = array( + 'class' => array('clearfix'), + ); + + $form['display_id'] = array( + '#type' => 'select', + '#title' => t('Display'), + '#options' => $options, + '#default_value' => $form_state['display_id'], + '#id' => 'preview-display-id', + ); + + $form['args'] = array( + '#type' => 'textfield', + '#title' => t('Arguments'), + '#default_value' => $form_state['view_args'], + '#description' => t('Separate arguments with a / as though they were a URL path.'), + '#id' => 'preview-args', + ); + + $form['preview'] = array( + '#type' => 'submit', + '#value' => t('Preview'), + '#id' => 'preview-submit', + ); + + $form['live_preview'] = array( + '#type' => 'checkbox', + '#title' => t('Automatic live preview'), + '#default_value' => !variable_get('views_ui_disable_live_preview', 0), + ); + + $form['#action'] = url("admin/structure/views/nojs/preview/$view->name"); + return $form; +} + +/** + * Submit the preview form. + * + * This just takes the data and stores it on the form state in a + * known location. The caller will be responsible for using it. + */ +function views_ui_preview_form_submit(&$form, &$form_state) { + $form_state['display_id'] = $form_state['values']['display_id']; + $form_state['view_args'] = $form_state['values']['args']; +} + +/** + * Page callback to add a new view. + */ +function views_ui_add_page() { + $form_state = array( + 'view' => NULL, + 'build_info' => array( + 'args' => array(), + ), + ); + + $form = drupal_build_form('views_ui_add_form', $form_state); + return drupal_render($form); +} + +/** + * Page callback to add a new view. + */ +function views_ui_clone_page($view) { + $form_state = array( + 'view' => $view->copy(), + 'build_info' => array( + 'args' => array(), + ), + ); + + drupal_set_title(t('Clone view %view', array('%view' => $view->name)), PASS_THROUGH); + return drupal_render(drupal_build_form('views_ui_add_form', $form_state)); +} + +/** + * Form constructor callback to create the views Add Form, phase 1. + */ +function views_ui_add_form($form, &$form_state) { + $view = $form_state['view']; + $form = array(); + + $form['human_name'] = array( + '#type' => 'textfield', + '#title' => t('View name'), + '#description' => t('A descriptive name for this view. Spaces are allowed.'), + '#default_value' => $view ? $view->human_name : '', + '#required' => TRUE, + '#size' => 32, + '#maxlength' => 255, + ); + + $form['name'] = array( + '#type' => 'machine_name', + '#maxlength' => 32, + '#machine_name' => array( + 'exists' => 'views_get_view', + 'source' => array('human_name'), + ), + '#description' => t('A unique machine-readable name for this View. It must only contain lowercase letters, numbers, and underscores.'), + ); + + $form['description'] = array( + '#type' => 'textfield', + '#title' => t('View description'), + '#description' => t('This description will appear on the Views administrative UI to tell you what the view is about.'), + '#default_value' => $view ? $view->description : '', + '#maxlength' => 255, + ); + + $form['tag'] = array( + '#type' => 'textfield', + '#title' => t('View tag'), + '#description' => t('Enter an optional tag for this view; it is used only to help sort views on the administrative page.'), + '#default_value' => $view ? $view->tag : '', + '#autocomplete_path' => 'admin/views/ajax/autocomplete/tag', + ); + + $base_tables = array(); + foreach (views_fetch_base_tables() as $table => $info) { + $base_tables[$table] = $info['title'] . '<div class="description">' . $info['description'] . '</div>'; + } + + $form['base_table'] = array( + '#type' => 'radios', + '#title' => t('View type'), + '#description' => t('The view type is the primary table for which information is being retrieved. The view type controls what arguments, fields, sort criteria and filters are available, so once this is set it <strong>cannot be changed</strong>.'), + '#default_value' => $view ? $view->base_table : 'node', + '#options' => $base_tables, + ); + + if ($view) { + $form['base_table']['#disabled'] = TRUE; + } + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Next'), + '#validate' => array('views_ui_add_form_validate'), + '#submit' => array('views_ui_add_form_submit'), + ); + + return $form; +} + +/** + * Validate the add view form. + */ +function views_ui_add_form_validate($form, &$form_state) { + $name = $form_state['values']['name']; + + // View name must be alphanumeric or underscores, no other punctuation. + if (preg_match('/[^a-zA-Z0-9_]/', $name) || is_numeric($name)) { + form_error($form['name'], t('View name must be alphanumeric or underscores only, but cannot be numeric.')); + } + + // View name must already exist. + $view = views_get_view($form_state['values']['name']); + if ($view && $view->type != t('Default')) { + form_error($form['name'], t('You must use a unique name for this view.')); + } +} + +/** + * Process the add view form + */ +function views_ui_add_form_submit($form, &$form_state) { + $view = $form_state['view'] ? $form_state['view'] : views_new_view(); + $view->name = $form_state['values']['name']; + $view->human_name = $form_state['values']['human_name']; + $view->description = $form_state['values']['description']; + $view->tag = $form_state['values']['tag']; + $view->core = VERSION; + if (empty($form['base_table']['#disabled'])) { + $view->base_table = $form_state['values']['base_table']; + } + + views_ui_cache_set($view); + $form_state['redirect'] ='admin/structure/views/edit/' . $view->name; +} + +/** + * Page to delete a view. + */ +function views_ui_delete_confirm($form, &$form_state, $view) { + $form_state['view'] = &$view; + $form = array(); + + $cancel = 'admin/structure/views'; + if (!empty($_REQUEST['cancel'])) { + $cancel = $_REQUEST['cancel']; + } + + if ($view->type == t('Overridden')) { + $title = t('Are you sure you want to revert the view %name?', array('%name' => $view->name)); + $desc = t('Reverting the view will delete the view that is in the database, reverting it to the original default view. Any changes you have made will be lost and cannot be recovered.'); + $button = t('Revert'); + } + else { + $title = t('Are you sure you want to delete the view %name?', array('%name' => $view->name)); + $desc = t('Deleting a view cannot be undone.'); + $button = t('Delete'); + } + + return confirm_form($form, + $title, + $cancel, + $desc, + $button, + t('Cancel')); +} + +/** + * Submit handler to delete a view. + */ +function views_ui_delete_confirm_submit(&$form, &$form_state) { + $form_state['view']->delete(); + ctools_object_cache_clear('view', $form_state['view']->name); + drupal_set_message(t('The view has been deleted.')); + $form_state['redirect'] = 'admin/structure/views'; +} + +/** + * Page to delete a view. + */ +function views_ui_break_lock_confirm($form, &$form_state, $view) { + $form_state['view'] = &$view; + $form = array(); + + if (empty($view->locked)) { + return t('There is no lock on view %view to break.', array('%name' => $view->name)); + } + + $cancel = 'admin/structure/views/edit/' . $view->name; + if (!empty($_REQUEST['cancel'])) { + $cancel = $_REQUEST['cancel']; + } + + $account = user_load($view->locked->uid); + return confirm_form($form, + t('Are you sure you want to break the lock on view %name?', + array('%name' => $view->name)), + $cancel, + t('By breaking this lock, any unsaved changes made by !user will be lost!', array('!user' => theme('username', array('account' => $account)))), + t('Break lock'), + t('Cancel')); +} + +/** + * Submit handler to break_lock a view. + */ +function views_ui_break_lock_confirm_submit(&$form, &$form_state) { + ctools_object_cache_clear_all('view', $form_state['view']->name); + $form_state['redirect'] = 'admin/structure/views/edit/' . $form_state['view']->name; + drupal_set_message(t('The lock has been broken and you may now edit this view.')); +} + +/** + * The main view edit page + */ +function views_ui_edit_page($view) { + drupal_set_title(t('Edit view %view', array('%view' => $view->name)), PASS_THROUGH); + $output = theme('views_ui_edit_view', array('view' => $view)); + views_ui_check_advanced_help(); + return $output; +} + +/** + * Export a view for cut & paste. + */ +function views_ui_export_page($form, &$form_state, $view) { + $code = $view->export(); + $lines = substr_count($code, "\n"); + $form['code'] = array( + '#type' => 'textarea', + '#title' => $view->name, + '#default_value' => $code, + '#rows' => $lines, + ); + return $form; +} + +/** + * Import a view from cut & paste + */ +function views_ui_import_page($form, &$form_state) { + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('View name'), + '#description' => t('Enter the name to use for this view if it is different from the source view. Leave blank to use the name of the view.'), + ); + + $form['view'] = array( + '#type' => 'textarea', + '#title' => t('Paste view code here'), + '#required' => TRUE, + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Import'), + '#submit' => array('views_ui_import_submit'), + '#validate' => array('views_ui_import_validate'), + ); + return $form; +} + +/** + * Validate handler to import a view + */ +function views_ui_import_validate($form, &$form_state) { + $view = ''; + views_include('view'); + ob_start(); + eval($form_state['values']['view']); + ob_end_clean(); + + if (!is_object($view)) { + return form_error($form['view'], t('Unable to interpret view code.')); + } + + if (empty($view->api_version) || $view->api_version < 2) { + // Check for some value that would only exist on a Views 1 view. + if (isset($view->url) || isset($view->page) || isset($view->block)) { + views_include('convert'); + $view = views1_import($view); + drupal_set_message(t('You are importing a view created in Views version 1. You may need to adjust some parameters to work correctly in version 2.'), 'warning'); + } + else { + form_error($form['view'], t('That view is not compatible with this version of Views.')); + } + } + elseif ($view->api_version > views_api_version()) { + form_error($form['view'], t('That view is created for the version @import_version of views, but you only have @api_version', array( + '@import_version' => $view->api_version, + '@api_version' => views_api_version()))); + } + + // View name must be alphanumeric or underscores, no other punctuation. + if (!empty($form_state['values']['name']) && preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['name'])) { + form_error($form['name'], t('View name must be alphanumeric or underscores only.')); + } + + if ($form_state['values']['name']) { + $view->name = $form_state['values']['name']; + } + + $test = views_get_view($view->name); + if ($test && $test->type != t('Default')) { + form_set_error('', t('A view by that name already exists; please choose a different name')); + } + + $view->init_display(); + + $broken = FALSE; + // Make sure that all plugins and handlers needed by this view actually exist. + foreach ($view->display as $id => $display) { + if (empty($display->handler) || !empty($display->handler->broken)) { + drupal_set_message(t('Display plugin @plugin is not available.', array('@plugin' => $display->display_plugin)), 'error'); + $broken = TRUE; + continue; + } + + $plugin = views_get_plugin('style', $display->handler->get_option('style_plugin')); + if (!$plugin) { + drupal_set_message(t('Style plugin @plugin is not available.', array('@plugin' => $display->handler->get_option('style_plugin'))), 'error'); + $broken = TRUE; + } + elseif ($plugin->uses_row_plugin()) { + $plugin = views_get_plugin('row', $display->handler->get_option('row_plugin')); + if (!$plugin) { + drupal_set_message(t('Row plugin @plugin is not available.', array('@plugin' => $display->handler->get_option('row_plugin'))), 'error'); + $broken = TRUE; + } + } + + foreach (views_object_types() as $type => $info) { + $handlers = $display->handler->get_handlers($type); + if ($handlers) { + foreach ($handlers as $id => $handler) { + if ($handler->broken()) { + drupal_set_message(t('@type handler @table.@field is not available.', array( + '@type' => $info['stitle'], + '@table' => $handler->table, + '@field' => $handler->field, + )), 'error'); + $broken = TRUE; + } + } + } + } + } + + if ($broken) { + form_set_error('', t('Unable to import view.')); + } + + $form_state['view'] = &$view; +} + +/** + * Submit handler for view import + */ +function views_ui_import_submit($form, &$form_state) { + // Store in cache and then go to edit. + views_ui_cache_set($form_state['view']); + $form_state['redirect'] = 'admin/structure/views/edit/' . $form_state['view']->name; +} + +/** + * The main edit view form, which is really just a save/cancel/delete button. + */ +function views_ui_edit_view_form($form, &$form_state, $view) { + $form['buttons']['save'] = array( + '#type' => 'submit', + '#value' => t('Save'), + '#validate' => array('views_ui_edit_view_form_validate'), + '#submit' => array('views_ui_edit_view_form_submit'), + ); + + $form['buttons']['cancel'] = array( + '#type' => 'submit', + '#value' => t('Cancel'), + '#submit' => array('views_ui_edit_view_form_cancel'), + ); + + if (is_numeric($view->vid)) { + $form['buttons']['delete'] = array( + '#type' => 'submit', + '#value' => $view->type == t('Overridden') ? t('Revert') : t('Delete'), + '#submit' => array('views_ui_edit_view_form_delete'), + ); + } + + $form_state['view'] = &$view; + return $form; +} + +/** + * Validate that a view is complete and whole. + */ +function views_ui_edit_view_form_validate($form, &$form_state) { + // Do not validate cancel or delete or revert. + if (empty($form_state['clicked_button']['#value']) || $form_state['clicked_button']['#value'] != t('Save')) { + return; + } + + $errors = $form_state['view']->validate(); + if ($errors !== TRUE) { + foreach ($errors as $error) { + form_set_error('', $error); + } + } +} + +/** + * Submit handler for the edit view form. + */ +function views_ui_edit_view_form_submit($form, &$form_state) { + // Go through and remove displayed scheduled for removal. + foreach ($form_state['view']->display as $id => $display) { + if (!empty($display->deleted)) { + unset($form_state['view']->display[$id]); + } + } + // Rename display ids if needed. + foreach ($form_state['view']->display as $id => $display) { + if (!empty($display->new_id)) { + $form_state['view']->display[$id]->id = $display->new_id; + } + } + + $form_state['view']->save(); + drupal_set_message(t('The view %name has been saved.', array('%name' => $form_state['view']->name))); + + // Make sure menu items get rebuilt as neces + menu_rebuild(); + + // Clear the views cache. + cache_clear_all('*', 'cache_views'); + + // Clear the page cache. + cache_clear_all(); + + // Remove this view from cache so we can edit it properly. + ctools_object_cache_clear('view', $form_state['view']->name); +} + +/** + * Submit handler for the edit view form. + */ +function views_ui_edit_view_form_cancel($form, &$form_state) { + // Remove this view from cache so edits will be lost. + ctools_object_cache_clear('view', $form_state['view']->name); + if (empty($form['view']->vid)) { + // I seem to have to drupal_goto here because I can't get fapi to + // honor the redirect target. Not sure what I screwed up here. + drupal_goto('admin/structure/views'); + } +} + +function views_ui_edit_view_form_delete($form, &$form_state) { + unset($_REQUEST['destination']); + // Redirect to the delete confirm page + $form_state['redirect'] = array('admin/structure/views/delete/' . $form_state['view']->name, array('query' => drupal_get_destination() + array('cancel' => 'admin/structure/views/edit/' . $form_state['view']->name))); +} + +/** + * Preprocess the view edit page. + */ +function template_preprocess_views_ui_edit_view(&$vars) { + $view = &$vars['view']; + ctools_include('dependent'); + + // The form has to be saved as variable because of strict warnings. + $form = drupal_get_form('views_ui_edit_view_form', $view); + $vars['save_button'] = drupal_render($form); + + $table = views_fetch_data($view->base_table); + $vars['base_table'] = !empty($table['table']['base']['title']) ? + $table['table']['base']['title'] : t('Unknown or missing table name'); + + views_include('tabs'); + $tabs = new views_tabset; + + $vars['message'] = '<div class="message">' . t("Click on an item to edit that item's details.") . '</div>'; + + if (!$view->set_display('default')) { + drupal_set_message(t('This view has a broken default display and cannot be used.'), 'error'); + } + + foreach ($view->display as $display) { + list($title, $body) = views_ui_display_tab($view, $display); + // The first display is the default. + $tabs->set($display->id, $title, $body); + } + + // This is the area that will render beneath the links + $form_state = array( + 'view' => &$view, + 'ajax' => FALSE, + 'build_info' => array( + 'args' => array(), + ), + 'no_cache' => TRUE, + ); + + $form = drupal_build_form('views_ui_add_display_form', $form_state); + $display_button = drupal_render($form); + $form = drupal_get_form('views_ui_analyze_view_button', $view); + $analyze_button = drupal_render($form); + $form = drupal_get_form('views_ui_reorder_displays_button', $view); + $reorder_button = drupal_render($form); + $tabs->add_extra($display_button . $reorder_button . $analyze_button); + + $vars['tabs'] = $tabs->render(); + + $form_state = array( + 'display_id' => 'default', + 'view_args' => '', + 'rerender' => FALSE, + 'no_redirect' => TRUE, + 'view' => &$view, + 'input' => array(), + 'build_info' => array( + 'args' => array(), + ), + ); + $preview_form = drupal_build_form('views_ui_preview_form', $form_state); + $vars['preview'] = drupal_render($preview_form); + + $vars['locked'] = NULL; + if (isset($view->locked) && is_object($view->locked)) { + $account = array(); + $account['account'] = user_load($view->locked->uid); + $account['name'] = $account['account']->name; + $vars['locked'] = theme('username', array('account' => $account['account'])); + $vars['lock_age'] = format_interval(REQUEST_TIME - $view->locked->updated); + $vars['break'] = url('admin/structure/views/break-lock/' . $view->name); + } + + $vars['quick_links_raw'] = array( + 'views-export' => array( + 'title' => t('Export'), + 'attributes' => array('title' => t("Export this view")), + 'href' => "admin/structure/views/export/$view->name", + ), + 'views-clone' => array( + 'title' => t('Clone'), + 'attributes' => array('title' => t("Create a copy of this view")), + 'href' => "admin/structure/views/clone/$view->name", + ), + ); + + $paths = array(); + foreach ($view->display as $id => $display) { + if (!empty($display->handler) && $display->handler->has_path()) { + $path = $display->handler->get_path(); + if (strpos($path, '%') === FALSE && !isset($paths[$path])) { + $vars['quick_links_raw']['views-view-' . $display->id] = array( + 'title' => t('View "@display"', array('@display' => $display->display_title)), + 'attributes' => array('title' => t("Go to the real page for this display")), + 'href' => $path, + ); + // Displays can have the same path; no point in showing more than one link. + $paths[$path] = TRUE; + } + } + } + + if (module_exists('contextual')) { + $build = array( + '#prefix' => '<div class="contextual-links-wrapper">', + '#suffix' => '</div>', + '#theme' => 'links__contextual', + '#links' => $vars['quick_links_raw'], + '#attributes' => array('class' => array('contextual-links')), + '#attached' => array( + 'library' => array(array('contextual', 'contextual-links')), + ), + ); + $vars['quick_links'] = drupal_render($build); + } + else { + $vars['quick_links'] = theme('links__views_quick_links', array('links' => $vars['quick_links_raw'])); + } + views_add_css('views-admin'); + views_add_js('ajax'); + drupal_add_library('system', 'jquery.form'); + + // Also add any js files required by plugins: + $plugins = views_fetch_plugin_data(); + foreach ($plugins as $type => $type_plugins) { + foreach ($type_plugins as $name => $plugin) { + if (!empty($plugin['js'])) { + foreach ($plugin['js'] as $file) { + drupal_add_js($file); + } + } + } + } + + $settings = array('views' => array('ajax' => array( + 'id' => '#views-ajax-pad', + 'title' => '#views-ajax-title', + 'defaultForm' => $vars['message'], + ))); + + drupal_add_js($settings, 'setting'); +} + +function template_preprocess_views_ui_edit_tab(&$vars) { + $view = $vars['view']; + $display = $vars['display']; + $plugin = $display->handler->definition; + + $top = $left = $middle = $right = ''; + + // If this form was submitted it was already handled, so force it not to + // submit again. + + $vars['remove'] = ''; + $vars['clone'] = ''; + if (empty($plugin['no remove'])) { + if (!empty($_POST['form_id']) && in_array($_POST['form_id'], array('views_ui_remove_display_form', 'views_ui_clone_display_form'))) { + unset($_POST['form_id']); + } + $form_state = array('view' => &$view, 'display_id' => $display->id, 'ajax' => FALSE, 'build_info' => array('args' => array())); + $remove_form = drupal_build_form('views_ui_remove_display_form', $form_state); + $clone_form = drupal_build_form('views_ui_clone_display_form', $form_state); + $vars['remove'] = drupal_render($remove_form); + $vars['clone'] = drupal_render($clone_form); + } + + // basic fields + $vars['title'] = check_plain($display->display_title); + $vars['description'] = check_plain($plugin['help']); + + // Special fields if this is the default display. + $vars['default'] = ($display->id == 'default'); + $vars['details_class'] = drupal_clean_css_identifier('details'); + if (!empty($view->changed_sections['details'])) { + $vars['details_changed'] = TRUE; + } + + foreach (array('human_name', 'tag', 'description') as $property) { + if (!empty($view->changed_sections[$property])) { + $vars['details_changed'][$property] = TRUE; + } + switch ($property) { + case 'human_name': + $title = t('Human name'); + break; + case 'tag': + $title = t('Tag'); + break; + case 'description': + $title = t('Description'); + break; + } + $value = empty($view->{$property}) ? t('None') : check_plain($view->{$property}); + $vars['details'][$property] = $title . ': ' . l($value, "admin/structure/views/nojs/$property/$view->name", array('attributes' => array('class' => 'views-ajax-link'))); + } + + // Calculate options from display plugin. + $options = $categories = array(); + $display->handler->options_summary($categories, $options); + + // Build all of the options we were returned and put them into the + // category data fields. + foreach ($options as $id => $option) { + if (empty($categories[$option['category']]['data'])) { + $categories[$option['category']]['data'] = array(); + } + $categories[$option['category']]['data'][$id] = array(); + $data = &$categories[$option['category']]['data'][$id]; + $data['content'] = ''; + $data['links'] = ''; + $data['overridden'] = FALSE; + $data['defaulted'] = FALSE; + + // If there are optional links, build them first so they float properly. + if (!empty($option['links'])) { + foreach ($option['links'] as $link_id => $link_value) { + $data['links'] .= $display->handler->option_link($link_value, $link_id, 'views-button-configure'); + } + } + if (!empty($option['title'])) { + $data['content'] .= $option['title'] . ': '; + } + + $data['content'] .= $display->handler->option_link($option['value'], $id, '', empty($option['desc']) ? '' : $option['desc']); + if (!empty($display->handler->options['defaults'][$id])) { + $display_id = 'default'; + $data['defaulted'] = TRUE; + } + else { + $display_id = $display->id; + if (!$display->handler->is_default_display()) { + if ($display->handler->defaultable_sections($id)) { + $data['overridden'] = TRUE; + } + } + } + $data['class'][] = drupal_clean_css_identifier($display_id . '-' . $id); + if (!empty($view->changed_sections[$display_id . '-' . $id])) { + $data['changed'] = TRUE; + } + } + + $vars['categories'] = $categories; + + // Add a help icon + if (isset($plugin['help topic']) && module_exists('advanced_help')) { + $vars['display_help_icon'] = theme('advanced_help_topic', array('module' => $plugin['module'], 'topic' => $plugin['help topic'])); + } + else { + $vars['display_help_icon'] = ''; + } + + // Fetch style plugin info because it has some effect on how/what we render. + $style_plugin = $display->handler->get_plugin(); + + $vars['fields'] = ''; + $vars['areas'] = array(); + foreach (array('header', 'footer', 'empty') as $area) { + $vars['areas'][$area] = theme('views_ui_edit_item', array( + 'type' => $area, 'view' => $view, 'display' => $display, + )); + } + $vars['fields'] = theme('views_ui_edit_item', array('type' => 'field', 'view' => $view, 'display' => $display, 'no_fields' => !($style_plugin && $style_plugin->uses_fields()))); + $vars['relationships'] = theme('views_ui_edit_item', array('type' => 'relationship', 'view' => $view, 'display' => $display)); + $vars['arguments'] = theme('views_ui_edit_item', array('type' => 'argument', 'view' => $view, 'display' => $display)); + $vars['filters'] = theme('views_ui_edit_item', array('type' => 'filter', 'view' => $view, 'display' => $display)); + $vars['sorts'] = theme('views_ui_edit_item', array('type' => 'sort', 'view' => $view, 'display' => $display)); +} + +/** + * Generate the summary output for a single display to render in a tab. + */ +function views_ui_display_tab($view, $display) { + if (isset($display->handler)) { + $plugin = $display->handler->definition; + } + if (empty($plugin)) { + $title = isset($display->display_title) ? $display->display_title : t('Invalid'); + return array($title, t("Error: Display @display refers to a plugin named '@plugin', but that plugin doesn't exist!", array('@display' => $display->id, '@plugin' => $display->display_plugin))); + + // @todo We can do a better 'plugin does not exist' tab. + } + + // The display should always be initialized prior to this call. + if (empty($display->handler)) { + return FALSE; + } + + $body = theme('views_ui_edit_tab', array('view' => $view, 'display' => $display)); + return array($display->display_title, $body); +} + +/** + * Add information about a section to a display. + */ +function template_preprocess_views_ui_edit_item(&$vars) { + $type = $vars['type']; + $view = $vars['view']; + $display = $vars['display']; + + $types = views_object_types(); + + $vars['overridden'] = FALSE; + $vars['defaulted'] = FALSE; + $vars['item_help_icon'] = module_exists('advanced_help') ? theme('advanced_help_topic', array('module' => 'views', 'topic' => $type)) : ''; + + if ($vars['no_fields']) { + $vars['title'] = $types[$type]['title']; + $vars['rearrange'] = NULL; + $vars['add'] = NULL; + return; + } + + // Different types now have different rearrange forms, so we use this switch + // to get the right one. + switch ($type) { + case 'filter': + $rearrange_url = "admin/structure/views/nojs/rearrange-$type/$view->name/$display->id/$type"; + break; + default: + $rearrange_url = "admin/structure/views/nojs/rearrange/$view->name/$display->id/$type"; + } + + $vars['rearrange'] = l('<span>' . t('Rearrange') . '</span>', $rearrange_url, array('attributes' => array('class' => array('views-button-rearrange', 'views-ajax-link'), 'title' => t('Rearrange')), 'html' => TRUE)); + + $vars['add'] = l('<span>' . t('Add') . '</span>', "admin/structure/views/nojs/add-item/$view->name/$display->id/$type", array('attributes' => array('class' => array('views-button-add', 'views-ajax-link'), 'title' => t('Add'), 'id' => 'views-add-' . $type), 'html' => true)); + + if (!$display->handler->is_default_display()) { + if (!$display->handler->is_defaulted($types[$type]['plural'])) { + $vars['overridden'] = TRUE; + } + else { + $vars['defaulted'] = TRUE; + } + } + + if ($display->display_plugin != 'default') { + $vars['title'] = l($types[$type]['title'], "admin/structure/views/nojs/config-type/$view->name/$display->id/$type", array('attributes' => array('class' => array('views-ajax-link'), 'id' => 'views-title-' . $type))); + } + else { + $vars['title'] = $types[$type]['title']; + } + + $fields = array(); + + static $relationships = NULL; + if (!isset($relationships)) { + // Get relationship labels + $relationships = array(); + // @todo: get_handlers() + $handlers = $display->handler->get_option('relationships'); + if ($handlers) { + foreach ($handlers as $id => $info) { + $handler = $display->handler->get_handler('relationship', $id); + $relationships[$id] = $handler->label(); + } + } + } + + // Filters can now be grouped so we do a little bit extra: + $groups = array(); + $grouping = FALSE; + if ($type == 'filter') { + $group_info = $view->display_handler->get_option('filter_groups'); + if (!empty($group_info['groups']) && count($group_info['groups']) > 1) { + $grouping = TRUE; + $groups = array(0 => array()); + } + } + + foreach ($display->handler->get_option($types[$type]['plural']) as $id => $field) { + $fields[$id] = array(); + + $handler = $display->handler->get_handler($type, $id); + if (empty($handler)) { + $fields[$id]['class'][] = 'broken'; + $field_name = t('Broken/missing handler: @table > @field', array('@table' => $field['table'], '@field' => $field['field'])); + $fields[$id]['title'] = l($field_name, "admin/structure/views/nojs/config-item/$view->name/$display->id/$type/$id", array('attributes' => array('class' => array('views-ajax-link')), 'html' => TRUE)); + $fields[$id]['info'] = ''; + continue; + } + + $field_name = $handler->ui_name(TRUE); + if (!empty($field['relationship']) && !empty($relationships[$field['relationship']])) { + $field_name = '(' . $relationships[$field['relationship']] . ') ' . $field_name; + } + + $fields[$id]['title'] = l($field_name, "admin/structure/views/nojs/config-item/$view->name/$display->id/$type/$id", array('attributes' => array('class' => array('views-ajax-link')), 'html' => TRUE)); + $fields[$id]['class'][] = drupal_clean_css_identifier($display->id . '-' . $type . '-' . $id); + if (!empty($view->changed_sections[$display->id . '-' . $type . '-' . $id])) { + $fields[$id]['changed'] = TRUE; + } + $fields[$id]['info'] = $handler->admin_summary(); + + if ($display->handler->use_group_by()) { + $fields[$id]['links'] = l('<span>' . t('Group settings') . '</span>', "admin/structure/views/nojs/config-item-group/$view->name/$display->id/$type/$id", array('attributes' => array('class' => 'views-button-configure views-ajax-link', 'title' => t('Group settings')), 'html' => true)); + } + + if ($handler->has_extra_options()) { + $fields[$id]['links'] = l('<span>' . t('Settings') . '</span>', "admin/structure/views/nojs/config-item-extra/$view->name/$display->id/$type/$id", array('attributes' => array('class' => array('views-button-configure', 'views-ajax-link'), 'title' => t('Settings')), 'html' => true)); + } + + if ($handler->needs_style_plugin()) { + $style_plugin = views_fetch_plugin_data('style', $handler->options['style_plugin']); + $style_title = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin['title']; + $pid = $id . '-style-plugin'; + + if (!empty($style_plugin['uses options'])) { + $fields[$pid]['links'] = l('<span>' . t('Change settings for this style') . '</span>', "admin/structure/views/nojs/config-style/$view->name/$display->id/$type/$id", array('attributes' => array('class' => array('views-button-configure', 'views-ajax-link'), 'title' => t('Settings')), 'html' => true)); + } + + $fields[$pid]['title'] = ' ' . t(' Style: !style', array('!style' => l($style_title, "admin/structure/views/nojs/change-style/$view->name/$display->id/$type/$id", array('attributes' => array('class' => array('views-ajax-link')))))); + $fields[$pid]['class'][] = drupal_clean_css_identifier($display->id . '-' . $type . '-' . $pid); + if (!empty($view->changed_sections[$display->id . '-' . $type . '-' . $pid])) { + $fields[$pid]['changed'] = TRUE; + } + $fields[$pid]['info'] = ''; + } + + if ($grouping) { + $gid = $handler->options['group']; + + // Show in default group if the group does not exist. + if (empty($group_info['groups'][$gid])) { + $gid = 0; + } + $groups[$gid][] = $id; + } + } + + // If using grouping, re-order fields so that they show up properly in the list. + if ($type == 'filter' && $grouping) { + $store = $fields; + $fields = array(); + foreach ($groups as $gid => $contents) { + if (!empty($fields)) { + $operator = ') ' . ($group_info['operator'] == 'OR' ? t('OR') : t('AND')) . ' ('; + } + else { + $operator = '('; + } + $fields[] = array( + 'class' => 'views-group-text', + 'title' => $operator, + 'info' => '', + ); + $started = FALSE; + foreach ($contents as $pid) { + $operator = ' '; + if ($started) { + $operator .= ($group_info['groups'][$gid] == 'OR' ? t('OR') : t('AND')) . ' '; + } + $store[$pid]['title'] = $operator . $store[$pid]['title']; + $started = TRUE; + $fields[$pid] = $store[$pid]; + } + } + $fields[] = array( + 'class' => 'views-group-text', + 'title' => ')', + 'info' => '', + ); + } + + $vars['fields'] = $fields; +} + +/** + * Regenerate the tabs for AJAX updates. + */ +function views_ui_regenerate_tabs(&$view, &$output, $display_id = NULL) { + if (empty($display_id)) { + $displays = array_keys($view->display); + } + elseif (!is_array($display_id)) { + $displays = array($display_id); + if ($display_id != 'default') { + $displays[] = 'default'; + } + } + else { + $displays = $display_id; + } + + if (!$view->set_display('default')) { + return; + } + + foreach ($displays as $id) { + list($title, $body) = views_ui_display_tab($view, $view->display[$id]); + $output[] = ajax_command_html('#views-tab-' . $id, $body); + $output[] = ajax_command_html('#views-tab-title-' . $id, check_plain($title)); + } +} + +/** + * Provide standard buttons for the forms to make it easy. Also provide + * a hidden op operator because the forms plugin doesn't seem to properly + * provide which button was clicked. + */ +function views_ui_standard_form_buttons(&$form, &$form_state, $form_id, $name = NULL, $third = NULL, $submit = NULL) { + $form['buttons'] = array( + '#prefix' => '<div class="clearfix"><div class="form-buttons">', + '#suffix' => '</div></div>', + ); + + if (empty($name)) { + $name = t('Update'); + } + + // Add the override and update button + if ($name == t('Update default display')) { + $form['buttons']['override_update'] = array( + '#type' => 'submit', + '#value' => t('Update and override'), + '#submit' => array( + 'views_ui_edit_display_form_override_update_section', + 'views_ui_standard_submit', + 'views_ui_edit_display_form_override_update', + ), + ); + } + + if (empty($form_state['ok_button'])) { + // but be sure submit button validates! + $form['buttons']['submit'] = array( + '#type' => 'submit', + '#value' => $name, + '#submit' => array('views_ui_standard_submit', $form_id . '_submit'), + ); + // Take sure that the validation handler exists. + if (function_exists($form_id . '_validate')) { + $form['buttons']['submit']['#validate'][] = $form_id . '_validate'; + } + + } + + $cancel_submit = function_exists($form_id . '_cancel') ? $form_id . '_cancel' : 'views_ui_standard_cancel'; + $form['buttons']['cancel'] = array( + '#type' => 'submit', + '#value' => empty($form_state['ok_button']) ? t('Cancel') : t('Ok'), + '#submit' => array($cancel_submit), + '#validate' => array(), + ); + + if ($third) { + if (empty($submit)) { + $submit = 'third'; + } + $third_submit = function_exists($form_id . '_' . $submit) ? $form_id . '_' . $submit : 'views_ui_standard_cancel'; + + $form['buttons'][$submit] = array( + '#type' => 'submit', + '#value' => $third, + '#validate' => array(), + '#submit' => array($third_submit), + ); + } + + // Compatibility, to be removed later: + // We used to set these items on the form, but now we want them on the $form_state: + if (isset($form['#title'])) { + $form_state['title'] = $form['#title']; + } + if (isset($form['#help_topic'])) { + $form_state['help_topic'] = $form['#help_topic']; + } + if (isset($form['#help_module'])) { + $form_state['help_module'] = $form['#help_module']; + } + if (isset($form['#url'])) { + $form_state['url'] = $form['#url']; + } + if (isset($form['#js'])) { + if (!empty($form_state['js settings']) && is_array($form_state['js settings'])) { + $form_state['js settings'] = array_merge($form_state['js settings'], $form['#js']); + } + else { + $form_state['js settings'] = $form['#js']; + } + } + if (isset($form['#section'])) { + $form_state['#section'] = $form['#section']; + } + // Finally, we never want these cached -- our object cache does that for us. + $form['#no_cache'] = TRUE; + + // If this isn't an ajaxy form, then we want to set the title. + if (!empty($form['#title'])) { + drupal_set_title($form['#title']); + } + $form['#attached']['css'] = array( + drupal_get_path('module', 'views') . "/css/views-admin.css", + ); +} + +/** + * Basic submit handler applicable to all 'standard' forms + */ +function views_ui_standard_submit($form, &$form_state) { + if (!empty($form['#section'])) { + $form_state['view']->changed_sections[$form['#section']] = TRUE; + } +} + +/** + * Submit handler for cancel button + */ +function views_ui_standard_cancel($form, &$form_state) { + if (!empty($form_state['view']->changed) && isset($form_state['view']->form_cache)) { + unset($form_state['view']->form_cache); + views_ui_cache_set($form_state['view']); + } + + $form_state['redirect'] = 'admin/structure/views/edit/' . $form_state['view']->name; +} + +// -------------------------------------------------------------------------- +// Various subforms for editing the pieces of a view. + +function views_ui_ajax_forms($key = NULL) { + $forms = array( + 'display' => array( + 'form_id' => 'views_ui_edit_display_form', + 'args' => array('section'), + ), + 'remove-display' => array( + 'form_id' => 'views_ui_remove_display_form', + 'args' => array(), + ), + 'config-type' => array( + 'form_id' => 'views_ui_config_type_form', + 'args' => array('type'), + ), + 'rearrange' => array( + 'form_id' => 'views_ui_rearrange_form', + 'args' => array('type'), + ), + 'rearrange-filter' => array( + 'form_id' => 'views_ui_rearrange_filter_form', + 'args' => array('type'), + ), + 'add-item' => array( + 'form_id' => 'views_ui_add_item_form', + 'args' => array('type'), + ), + 'config-item' => array( + 'form_id' => 'views_ui_config_item_form', + 'args' => array('type', 'id'), + ), + 'config-item-extra' => array( + 'form_id' => 'views_ui_config_item_extra_form', + 'args' => array('type', 'id'), + ), + 'config-item-group' => array( + 'form_id' => 'views_ui_config_item_group_form', + 'args' => array('type', 'id'), + ), + 'change-style' => array( + 'form_id' => 'views_ui_change_style_form', + 'args' => array('type', 'id'), + ), + 'config-style' => array( + 'form_id' => 'views_ui_config_style_form', + 'args' => array('type', 'id'), + ), + ); + + if ($key) { + return !empty($forms[$key]) ? $forms[$key] : NULL; + } + + return $forms; +} + +/** + * Build a form identifier that we can use to see if one form + * is the same as another. Since the arguments differ slightly + * we do a lot of spiffy concenation here. + */ +function views_ui_build_identifier($key, $view, $display_id, $args) { + $form = views_ui_ajax_forms($key); + // Automatically remove the single-form cache if it exists and + // does not match the key. + $identifier = implode('-', array($key, $view->name, $display_id)); + + foreach ($form['args'] as $id) { + $arg = (!empty($args)) ? array_shift($args) : NULL; + $identifier .= '-' . $arg; + } + return $identifier; +} + +/** + * Build up a $form_state object suitable for use with drupal_build_form + * based on known information about a form. + */ +function views_ui_build_form_state($js, $key, &$view, $display_id, $args) { + $form = views_ui_ajax_forms($key); + // Build up form state + $form_state = array( + 'form_key' => $key, + 'form_id' => $form['form_id'], + 'view' => &$view, + 'ajax' => $js, + 'display_id' => $display_id, + 'no_redirect' => TRUE, + ); + + foreach ($form['args'] as $id) { + $form_state[$id] = (!empty($args)) ? array_shift($args) : NULL; + } + + return $form_state; +} + +/** + * Create the URL for one of our standard AJAX forms based upon known + * information about the form. + */ +function views_ui_build_form_url($form_state) { + $form = views_ui_ajax_forms($form_state['form_key']); + $ajax = empty($form_state['ajax']) ? 'nojs' : 'ajax'; + $name = $form_state['view']->name; + $url = "admin/structure/views/$ajax/$form_state[form_key]/$name/$form_state[display_id]"; + foreach ($form['args'] as $arg) { + $url .= '/' . $form_state[$arg]; + } + return $url; +} + +/** + * Add another form to the stack; clicking 'update' will go to this form + * rather than closing the ajax pad. + */ +function views_ui_add_form_to_stack($key, &$view, $display_id, $args, $top = FALSE) { + if (empty($view->stack)) { + $view->stack = array(); + } + + $stack = array(views_ui_build_identifier($key, $view, $display_id, $args), $key, &$view, $display_id, $args); + if ($top) { + array_unshift($view->stack, $stack); + } + else { + $view->stack[] = $stack; + } +} + +/** + * Generic entry point to handle forms. + * + * We do this for consistency and to make it easy to chain forms + * together. This only works for forms that use both $view + * and $display_id, so we have a couple of ajax forms that we don't + * use with this system. + */ +function views_ui_ajax_form($js, $key, $view, $display_id) { + // Reset the cache of IDs. Drupal rather aggressively prevents id duplication + // but this causes it to remember IDs that are no longer even being used. + if (isset($_POST['ajax_html_ids'])) { + unset($_POST['ajax_html_ids']); + } + + $form = views_ui_ajax_forms($key); + if (empty($form)) { + return drupal_not_found(); + } + + views_include('ajax'); + $args = func_get_args(); + // Remove the known args + array_splice($args, 0, 4); + + $form_state = views_ui_build_form_state($js, $key, $view, $display_id, $args); + // check to see if this is the top form of the stack. If it is, pop + // it off; if it isn't, the user clicked somewhere else and the stack is + // now irrelevant. + if (!empty($view->stack)) { + $identifier = views_ui_build_identifier($key, $view, $display_id, $args); + $top = array_shift($view->stack); + if (array_shift($top) != $identifier) { + $view->stack = array(); + } + } + + // Automatically remove the form cache if it is set and the key does + // not match. This way navigating away from the form without hitting + // update will work. + if (isset($view->form_cache) && $view->form_cache['key'] != $key) { + unset($view->form_cache); + } + + $output = views_ajax_form_wrapper($form_state['form_id'], $form_state); + if ($form_state['submitted'] && empty($form_state['rerender'])) { + // Sometimes we need to re-generate the form for multi-step type operations. + $object = NULL; + if (!empty($view->stack)) { + $stack = $view->stack; + $top = array_shift($stack); + $top[0] = $js; + $form_state = call_user_func_array('views_ui_build_form_state', $top); + $form_state['input'] = array(); + $form_state['url'] = url(views_ui_build_form_url($form_state)); + if (!$js) { + return drupal_goto(views_ui_build_form_url($form_state)); + } + $output = views_ajax_form_wrapper($form_state['form_id'], $form_state); + } + elseif (!$js) { + // if nothing on the stack, non-js forms just go back to the main view editor. + return drupal_goto("admin/structure/views/edit/$view->name"); + } + else { + $output = array(); + $output[] = views_ajax_command_enable_buttons(); + $output[] = views_ajax_command_dismiss_form(); + $output[] = views_ajax_command_trigger_preview(); + } + views_ui_regenerate_tabs($view, $output); + } + elseif ($js) { + $output[] = views_ajax_command_disable_buttons(); + } + + return $js ? array('#type' => 'ajax', '#commands' => $output) : $output; +} + +/** + * AJAX callback to add a display. + */ +function views_ui_add_display($js, $view) { + views_include('ajax'); + $form_state = array( + 'view' => &$view, + 'ajax' => $js, + ); + + $output = views_ajax_form_wrapper('views_ui_add_display_form', $form_state); + + if ($js) { + if ($form_state['submitted']) { + $id = $form_state['id']; + + // Make sure the new display is active + if (!$view->set_display('default')) { + views_ajax_error(t('Unable to initialize default display')); + } + + // Render the new display + list($title, $body) = views_ui_display_tab($view, $view->display[$id]); + + // Instruct the javascript on the browser to render the new tab. + $output = array(); + $output[] = views_ajax_command_add_tab($id, $title, $body); + } + $output = array('#type' => 'ajax', '#commands' => $output); + } + + // But the non-js variant will return output if it didn't redirect us. + return $output; +} + +/** + * Form to add a display to a view. + */ +function views_ui_add_display_form($form, &$form_state) { + $view = &$form_state['view']; + + $form['display']['display'] = array( + '#type' => 'select', + '#options' => views_fetch_plugin_names('display'), + '#default_value' => 'page', + ); + + $form['display']['add_display'] = array( + '#type' => 'submit', + '#value' => t('Add display'), + '#ajax' => array( + 'path' => "admin/structure/views/ajax/add-display/$view->name", + ), + '#submit' => array('views_ui_add_display_form_submit'), + ); + + $form['#id'] = 'views-add-display-form'; + $form['#attributes'] = array('class' => array('views-ajax-form')); + $form['#action'] = url("admin/structure/views/nojs/add-display/$view->name"); + + return $form; +} + +/** + * Submit handler to add a display to a view. + */ +function views_ui_add_display_form_submit($form, &$form_state) { + // Create the new display + $plugin = $form_state['values']['display']; + $form_state['id'] = $form_state['view']->add_display($plugin); + + // Store in cache + views_ui_cache_set($form_state['view']); + + // Send it back + $form_state['redirect'] = array('admin/structure/views/edit/' . $form_state['view']->name, array('fragment' => 'views-tab-' . $form_state['id'])); +} + +/** + * AJAX callback to add a display. + */ +function views_ui_clone_display($js, $view, $id) { + views_include('ajax'); + $form_state = array( + 'view' => &$view, + 'ajax' => $js, + 'display_id' => $id, + ); + + $output = views_ajax_form_wrapper('views_ui_clone_display_form', $form_state); + + if ($js) { + // If we don't have an output object, it was submitted. Set up the submission. + if (empty($output)) { + $id = $form_state['id']; + + // Make sure the new display is active + if (!$view->set_display('default')) { + views_ajax_render(t('Unable to initialize default display')); + } + + // Render the new display + list($title, $body) = views_ui_display_tab($view, $view->display[$id]); + + // Instruct the javascript on the browser to render the new tab. + $output = new stdClass; + $output->tab = array('#views-tab-' . $id => array('title' => $title, 'body' => $body)); + } + // Render the command object. This automatically exits. + views_ajax_render($output); + } + + // But the non-js variant will return output if it didn't redirect us. + return $output; +} + +/** + * From to clone a display from a view. + */ +function views_ui_clone_display_form($form, &$form_state) { + $view = &$form_state['view']; + $display_id = $form_state['display_id']; + + $form['clone_display'] = array( + '#type' => 'submit', + '#value' => t('Clone display'), + '#submit' => array('views_ui_clone_display_form_submit'), + ); + + $form['#id'] = 'views-clone-display-form'; + $form['#action'] = url("admin/build/views/nojs/clone-display/$view->name/$display_id"); + $form['#attributes'] = array('class' => 'views-ajax-form'); + + return $form; +} + +/** + * Submit handler to add a clone to a display from a view. + */ +function views_ui_clone_display_form_submit($form, &$form_state) { + // Create the new display + $id = $form_state['display_id']; + $display = $form_state['view']->display[$id]; + + $new_id = $form_state['view']->add_display($display->display_plugin); + $form_state['id'] = $new_id; + + // Replace the new display by a copy of the old + $form_state['view']->display[$new_id] = clone $display; + $form_state['view']->display[$new_id]->id = $new_id; + + // Store in cache + views_ui_cache_set($form_state['view']); + + // Send it back + $form_state['redirect'] = array('admin/structure/views/edit/' . $form_state['view']->name, array('fragment' => 'views-tab-' . $new_id)); +} + +/** + * Form to remove a display from a view. + */ +function views_ui_remove_display_form($form, &$form_state) { + $view = &$form_state['view']; + $display_id = $form_state['display_id']; + + if (empty($view->display[$display_id]->deleted)) { + $form['display'] = array( + '#prefix' => '<div class="display-button remove-display">', + '#suffix' => '</div>', + ); + $form['remove_display'] = array( + '#type' => 'submit', + '#value' => t('Remove display'), + '#submit' => array('views_ui_remove_display_form_submit'), + ); + } + else { + $form['display'] = array( + '#prefix' => '<div class="display-button restore-display">', + '#suffix' => '</div>', + ); + $form['restore_display'] = array( + '#type' => 'submit', + '#value' => t('Restore display'), + '#submit' => array('views_ui_remove_display_form_restore'), + ); + } + $form['#action'] = url("admin/structure/views/nojs/remove-display/$view->name/$display_id"); + $form['#attributes'] = array('class' => array('views-ajax-form')); + + return $form; +} + +/** + * Submit handler to add a remove to a display from a view. + */ +function views_ui_remove_display_form_submit($form, &$form_state) { + // Create the new display + $plugin = views_fetch_plugin_data('display', $form_state['view']->display[$form_state['display_id']]->display_plugin); + if (empty($plugin['no remove'])) { + $id = $form_state['display_id']; + $form_state['view']->display[$id]->deleted = TRUE; + + // Store in cache + views_ui_cache_set($form_state['view']); + } +} + +/** + * Submit handler to add a restore a removed display to a view. + */ +function views_ui_remove_display_form_restore($form, &$form_state) { + // Create the new display + $id = $form_state['display_id']; + $form_state['view']->display[$id]->deleted = FALSE; + + // Store in cache + views_ui_cache_set($form_state['view']); +} + +/** + * Page callback to display analysis information on a view. + */ +function views_ui_analyze_view($js, $view) { + views_include('ajax'); + $form_state = array( + 'view' => &$view, + 'ajax' => $js, + ); + + $output = views_ajax_form_wrapper('views_ui_analyze_view_form', $form_state); + + if ($js) { + // If we don't have an output object, it was submitted. Set up the submission. + if ($form_state['submitted'] && empty($form_state['rerender'])) { + $output = array(); + $output[] = views_ajax_command_enable_buttons(); + $output[] = views_ajax_command_dismiss_form(); + views_ui_regenerate_tabs($view, $output); + } + $commands = $output; + return $js ? array('#type' => 'ajax', '#commands' => $commands) : $commands; + } + return $output; +} + +/** + * This form doesn't particularly do much; it's really just providing a link + * but a button seems like it would be nicer here. + * + * It has no submit or anything, as we will never actually submit this form + * where the form is placed. + */ +function views_ui_analyze_view_button($form, &$form_state, $view) { + $form['#action'] = url("admin/structure/views/nojs/analyze/$view->name"); + $form['#attributes'] = array('class' => array('views-ajax-form')); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Analyze'), + '#ajax' => array( + 'path' => "admin/structure/views/ajax/analyze/$view->name", + ), + ); + + return $form; +} + +/** + * Form constructor callback to display analysis information on a view + */ +function views_ui_analyze_view_form($form, &$form_state) { + $view = &$form_state['view']; + + $form['#title'] = t('View analysis'); + $form['#section'] = 'analyze'; + + views_include('analyze'); + $messages = views_analyze_view($view); + + $form['analysis'] = array( + '#prefix' => '<div class="form-item">', + '#suffix' => '</div>', + '#markup' => views_analyze_format_result($view, $messages), + ); + + // Inform the standard button function that we want an OK button. + $form_state['ok_button'] = TRUE; + views_ui_standard_form_buttons($form, $form_state, 'views_ui_analyze_view_form'); + return $form; +} + +/** + * Submit handler for views_ui_analyze_view_form + */ +function views_ui_analyze_view_form_submit($form, &$form_state) { + $form_state['redirect'] = 'admin/structure/views/edit/' . $form_state['view']->name; +} + +/** + * Page callback to display analysis information on a view. + */ +function views_ui_reorder_view($js, $view) { + views_include('ajax'); + $form_state = array( + 'view' => &$view, + 'ajax' => $js, + ); + + $output = views_ajax_form_wrapper('views_ui_reorder_displays_form', $form_state); + + if ($js) { + if ($form_state['submitted'] && empty($form_state['rerender'])) { + // I don't want preprocess to modify the views -> no references + $vars = array('view' => $view); + template_preprocess_views_ui_edit_view($vars); + $output = array(); + $output[] = ajax_command_replace('.views-tabset', $vars['tabs']); + // Not the right place to have html i know ! + $output[] = ajax_command_replace('.views-quick-links', '<div class="views-quick-links">'. $vars['quick_links'] .'</div>'); + $output[] = views_ajax_command_enable_buttons(); + $output[] = views_ajax_command_dismiss_form(); + // Doesn't work yet, maybe we should reload the page dunno + views_ui_regenerate_tabs($view, $output); + } + $commands = $output; + return $js ? array('#type' => 'ajax', '#commands' => $commands) : $commands; + } + return $output; +} + +/** + * Form constructor callback to reorder displays on a view + */ +function views_ui_reorder_displays_form($form, &$form_state) { + $view = &$form_state['view']; + + $form['view'] = array('#type' => 'value', '#value' => $view); + + $form['#tree'] = TRUE; + + $last_display = end($view->display); + + foreach ($view->display as $display) { + $form[$display->id] = array( + 'title' => array('#markup' => $display->display_title), + 'weight' => array( + '#type' => 'weight', + '#value' => $display->position, + '#delta' => $last_display->position, + '#title' => t('Weight for @display', array('@display' => $display->display_title)), + '#title_display' => 'invisible', + ), + '#tree' => TRUE, + '#display' => $display, + 'removed' => array( + '#type' => 'checkbox', + '#id' => 'display-removed-' . $display->id, + '#attributes' => array('class' => array('views-remove-checkbox')), + '#default_value' => isset($display->deleted), + ), + ); + + if (isset($display->deleted) && $display->deleted) { + $form[$display->id]['deleted'] = array('#type' => 'value', '#value' => TRUE); + } + if ($display->id === 'default') { + unset($form[$display->id]['weight']); + unset($form[$display->id]['removed']); + } + + } + + $form['#title'] = t('Displays Reorder'); + $form['#section'] = 'reorder'; + + // Add javascript settings that will be added via $.extend for tabledragging + $form['#js']['tableDrag']['reorder-displays']['weight'][0] = array( + 'target' => 'weight', + 'source' => NULL, + 'relationship' => 'sibling', + 'action' => 'order', + 'hidden' => TRUE, + 'limit' => 0, + ); + + $form['#action'] = url('admin/structure/views/nojs/reorder-displays/'. $view->name); + + views_ui_standard_form_buttons($form, $form_state, 'views_ui_reorder_displays_form'); + + return $form; +} + +/** + * Display position sorting function + */ +function _views_position_sort($display1, $display2) { + if ($display1->position != $display2->position) { + return $display1->position < $display2->position ? -1 : 1; + } + + return 0; +} + +/** + * Submit handler for rearranging display form + */ +function views_ui_reorder_displays_form_submit($form, &$form_state) { + foreach($form_state['input'] as $display => $info) { + // add each value that is a field with a weight to our list, but only if + // it has had its 'removed' checkbox checked. + if (is_array($info) && isset($info['weight']) && empty($info['removed'])) { + $order[$display] = $info['weight']; + } + } + + // Sort the order array + asort($order); + + // Fixing up positions + $position = 2; + + foreach(array_keys($order) as $display) { + $order[$display] = $position++; + } + + // Setting up position and removing deleted displays + $displays = $form_state['view']->display; + foreach($displays as $display_id => $display) { + // Don't touch the default !!! + if ($display_id === 'default') { + continue; + } + if (isset($order[$display_id])) { + $form_state['view']->display[$display_id]->position = $order[$display_id]; + } + else { + $form_state['view']->display[$display_id]->deleted = TRUE; + } + } + + // Sorting back the display array as the position is not enough + uasort($form_state['view']->display, '_views_position_sort'); + + // Store in cache + views_ui_cache_set($form_state['view']); + $form_state['redirect'] = array('admin/structure/views/edit/' . $form_state['view']->name, array('fragment' => 'views-tab-default')); +} + +/** + * Turn the reorder form into a proper table + */ +function theme_views_ui_reorder_displays_form($vars) { + $form = $vars['form']; + $rows = array(); + foreach (element_children($form) as $key) { + if (isset($form[$key]['#display'])) { + $display = &$form[$key]; + + $row = array(); + $row[] = drupal_render($display['title']); + $form[$key]['weight']['#attributes']['class'] = array('weight'); + $row[] = drupal_render($form[$key]['weight']); + if (isset($display['removed'])) { + $row[] = drupal_render($form[$key]['removed']) . + l('<span>' . t('Remove') . '</span>', + 'javascript:void()', + array( + 'attributes' => array( + 'id' => 'display-remove-link-' . $key, + 'class' => array('views-button-remove display-remove-link'), + 'alt' => t('Remove this display'), + 'title' => t('Remove this display')), + 'html' => TRUE)); + } + else { + $row[] = ''; + } + $class = array(); + $styles = array(); + if (isset($form[$key]['weight']['#type'])) { + $class[] = 'draggable'; + } + if (isset($form[$key]['deleted']['#value']) && $form[$key]['deleted']['#value']) { + $styles[] = 'display: none;'; + } + $rows[] = array('data' => $row, 'class' => $class, 'id' => 'display-row-' . $key, 'style' => $styles); + } + } + + $header = array(t('Display'), t('Weight'), t('Remove')); + $output = ''; + drupal_add_tabledrag('reorder-displays', 'order', 'sibling', 'weight'); + + $output = drupal_render($form['override']); + $output .= theme('table', + array('header' => $header, + 'rows' => $rows, + 'attributes' => array('id' => 'reorder-displays'), + )); + $output .= drupal_render_children($form); + + return $output; +} + +/** + * This form doesn't particularly do much; it's really just providing a link + * but a button seems like it would be nicer here. + * + * It has no submit or anything, as we will never actually submit this form + * where the form is placed. + */ +function views_ui_reorder_displays_button($form, &$form_state, $view) { + $form['#action'] = url("admin/structure/views/nojs/reorder-displays/$view->name"); + $form['#attributes'] = array('class' => array('views-ajax-form')); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Reorder'), + '#ajax' => array( + 'path' => "admin/structure/views/ajax/reorder-displays/$view->name", + ), + ); + + return $form; +} + +/** + * Page callback to edit details of a view. + */ +function views_ui_edit_details($property, $js, $view) { + views_include('ajax'); + $form_state = array( + 'view' => &$view, + 'ajax' => $js, + 'property' => $property, + ); + + $output = views_ajax_form_wrapper('views_ui_edit_details_form', $form_state); + + if ($js) { + // If we don't have an output object, it was submitted. Set up the submission. + if ($form_state['submitted'] && empty($form_state['rerender'])) { + $output = array(); + $output[] = views_ajax_command_enable_buttons(); + $output[] = views_ajax_command_dismiss_form(); + views_ui_regenerate_tabs($view, $output); + } + $commands = $output; + return $js ? array('#type' => 'ajax', '#commands' => $commands) : $commands; + } + return $output; +} + +/** + * Form constructor callback to edit details of a view + */ +function views_ui_edit_details_form($form, &$form_state) { + $view = &$form_state['view']; + + $form['#title'] = t('View details'); + $form['#section'] = 'details'; + + switch ($form_state['property']) { + case 'human_name': + $form['human_name'] = array( + '#type' => 'textfield', + '#title' => t('Human readable name'), + '#description' => t('You can use a more descriptive name for this view here. Spaces are allowed'), + '#default_value' => $view->human_name, + ); + break; + + case 'tag': + $form['tag'] = array( + '#type' => 'textfield', + '#title' => t('View tag'), + '#description' => t('Enter an optional tag for this view; it is used only to help sort views on the administrative page.'), + '#default_value' => $view->tag, + '#autocomplete_path' => 'admin/views/ajax/autocomplete/tag', + ); + break; + + case 'description': + $form['description'] = array( + '#type' => 'textfield', + '#title' => t('View description'), + '#description' => t('This description will appear on the Views administrative UI to tell you what the view is about.'), + '#default_value' => $view->description, + ); + break; + } + + views_ui_standard_form_buttons($form, $form_state, 'views_ui_edit_details_form'); + return $form; +} + +/** + * Submit handler for views_ui_edit_details_form + */ +function views_ui_edit_details_form_submit($form, &$form_state) { + $form_state['view']->{$form_state['property']} = $form_state['values'][$form_state['property']]; + views_ui_cache_set($form_state['view']); + $form_state['redirect'] = 'admin/structure/views/edit/' . $form_state['view']->name; +} + +/** + * Form constructor callback to edit display of a view + */ +function views_ui_edit_display_form($form, &$form_state) { + $view = &$form_state['view']; + $display_id = $form_state['display_id']; + $section = $form_state['section']; + + if (!$view->set_display($display_id)) { + views_ajax_error(t('Invalid display id @display', array('@display' => $display_id))); + } + $display = &$view->display[$display_id]; + + // Get form from the handler. + $display->handler->options_form($form, $form_state); + $name = NULL; + if (isset($form_state['update_name'])) { + $name = $form_state['update_name']; + } + + views_ui_standard_form_buttons($form, $form_state, 'views_ui_edit_display_form', $name); + return $form; +} + +/** + * Validate handler for views_ui_edit_display_form + */ +function views_ui_edit_display_form_validate($form, &$form_state) { + $display = &$form_state['view']->display[$form_state['display_id']]; + $display->handler->options_validate($form, $form_state); + + if (form_get_errors()) { + $form_state['rerender'] = TRUE; + } +} + +/** + * Submit handler for views_ui_edit_display_form + */ +function views_ui_edit_display_form_submit($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']); +} + +/** + * Override handler for views_ui_edit_display_form + */ +function views_ui_edit_display_form_override($form, &$form_state) { + $display = &$form_state['view']->display[$form_state['display_id']]; + $display->handler->options_override($form, $form_state); + + views_ui_cache_set($form_state['view']); + $form_state['rerender'] = TRUE; + $form_state['rebuild'] = TRUE; +} +/** + * Override handler and submit views_ui_edit_display_form + */ +function views_ui_edit_display_form_override_update(&$form, &$form_state) { + $display = &$form_state['view']->display[$form_state['display_id']]; + $display->handler->options_override($form, $form_state); + $display->handler->options_submit($form, $form_state); + views_ui_cache_set($form_state['view']); +} + +/** + * Override handler and submit views_ui_edit_display_form + */ +function views_ui_edit_display_form_override_update_section(&$form, &$form_state) { + // Update the #section so it knows what to mark changed. + $form['#section'] = str_replace('default-', $form_state['display_id'] . '-', $form['#section']); +} + +/** + * Form to config items in the views UI. + */ +function views_ui_config_type_form($form, &$form_state) { + $view = &$form_state['view']; + $display_id = $form_state['display_id']; + $type = $form_state['type']; + + $types = views_object_types(); + if (!$view->set_display($display_id)) { + views_ajax_error(t('Invalid display id @display', array('@display' => $display_id))); + } + $display = &$view->display[$display_id]; + $form['#title'] = check_plain($display->display_title) . ': '; + $form['#title'] .= t('Configure @type', array('@type' => $types[$type]['ltitle'])); + $form['#section'] = $display_id . 'config-item'; + + if ($display->handler->defaultable_sections($types[$type]['plural'])) { + $form_state['section'] = $types[$type]['plural']; + $display->handler->add_override_button($form, $form_state, $form_state['section']); + } + + if (!empty($types[$type]['options']) && function_exists($types[$type]['options'])) { + $options = $type . '_options'; + $form[$options] = array('#tree' => TRUE); + $types[$type]['options']($form, $form_state); + } + + $name = NULL; + if (isset($form_state['update_name'])) { + $name = $form_state['update_name']; + } + + views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_type_form', $name); + return $form; +} + +/** + * Submit handler for type configuration form + */ +function views_ui_config_type_form_submit($form, &$form_state) { + $types = views_object_types(); + $display = &$form_state['view']->display[$form_state['display_id']]; + + // Store in cache + views_ui_cache_set($form_state['view']); +} + +/** + * Configure settings particular to filters. + */ +function views_ui_config_filters_form(&$form, &$form_state) { + +} + +/** + * Form to rearrange items in the views UI. + */ +function views_ui_rearrange_form($form, &$form_state) { + $view = &$form_state['view']; + $display_id = $form_state['display_id']; + $type = $form_state['type']; + + $types = views_object_types(); + if (!$view->set_display($display_id)) { + views_ajax_error(t('Invalid display id @display', array('@display' => $display_id))); + } + $display = &$view->display[$display_id]; + $form['#title'] = check_plain($display->display_title) . ': '; + $form['#title'] .= t('Rearrange @type', array('@type' => $types[$type]['ltitle'])); + $form['#section'] = $display_id . 'rearrange-item'; + + if ($display->handler->defaultable_sections($types[$type]['plural'])) { + $form_state['section'] = $types[$type]['plural']; + $display->handler->add_override_button($form, $form_state, $form_state['section']); + } + + $count = 0; + + // Get relationship labels + $relationships = array(); + foreach ($display->handler->get_handlers('relationship') as $id => $handler) { + $relationships[$id] = $handler->label(); + } + + foreach ($display->handler->get_option($types[$type]['plural']) as $id => $field) { + $form[$id] = array('#tree' => TRUE); + $form[$id]['weight'] = array( + '#type' => 'textfield', + '#default_value' => ++$count, + ); + $handler = $display->handler->get_handler($type, $id); + if ($handler) { + $name = $handler->ui_name() . ' ' . $handler->admin_summary(); + if (!empty($field['relationship']) && !empty($relationships[$field['relationship']])) { + $name = '(' . $relationships[$field['relationship']] . ') ' . $name; + } + + $form[$id]['name'] = array( + '#markup' => $name, + ); + } + else { + $form[$id]['name'] = array('#value' => t('Broken field @id', array('@id' => $id))); + } + $form[$id]['removed'] = array( + '#type' => 'checkbox', + '#id' => 'views-removed-' . $id, + '#attributes' => array('class' => array('views-remove-checkbox')), + '#default_value' => 0, + ); + } + + // Add javascript settings that will be added via $.extend for tabledragging + $form['#js']['tableDrag']['arrange']['weight'][0] = array( + 'target' => 'weight', + 'source' => NULL, + 'relationship' => 'sibling', + 'action' => 'order', + 'hidden' => TRUE, + 'limit' => 0, + ); + + $name = NULL; + if (isset($form_state['update_name'])) { + $name = $form_state['update_name']; + } + + views_ui_standard_form_buttons($form, $form_state, 'views_ui_rearrange_form'); + return $form; +} + +/** + * Turn the rearrange form into a proper table + */ +function theme_views_ui_rearrange_form($variables) { + $form = $variables['form']; + + $rows = array(); + foreach (element_children($form) as $id) { + if (isset($form[$id]['name'])) { + $row = array(); + $row[] = drupal_render($form[$id]['name']); + $form[$id]['weight']['#attributes']['class'] = array('weight'); + $row[] = drupal_render($form[$id]['weight']); + $row[] = drupal_render($form[$id]['removed']) . l('<span>' . t('Remove') . '</span>', 'javascript:void()', array('attributes' => array('id' => 'views-remove-link-' . $id, 'class' => array('views-hidden', 'views-button-remove', 'views-remove-link'), 'alt' => t('Remove this item'), 'title' => t('Remove this item')), 'html' => TRUE)); + $rows[] = array('data' => $row, 'class' => array('draggable'), 'id' => 'views-row-' . $id); + } + } + if (empty($rows)) { + $rows[] = array(array('data' => t('No fields available.'), 'colspan' => '2')); + } + + $header = array('', t('Weight'), t('Remove')); + $output = drupal_render($form['override']); + $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'arrange'))); + $output .= drupal_render_children($form); + drupal_add_tabledrag('arrange', 'order', 'sibling', 'weight'); + + return $output; +} + +/** + * Submit handler for rearranging form + */ +function views_ui_rearrange_form_submit($form, &$form_state) { + $types = views_object_types(); + $display = &$form_state['view']->display[$form_state['display_id']]; + + $old_fields = $display->handler->get_option($types[$form_state['type']]['plural']); + $new_fields = $order = array(); + + // Make an array with the weights + foreach ($form_state['values'] as $field => $info) { + // add each value that is a field with a weight to our list, but only if + // it has had its 'removed' checkbox checked. + if (is_array($info) && isset($info['weight']) && empty($info['removed'])) { + $order[$field] = $info['weight']; + } + } + + // Sort the array + asort($order); + + // Create a new list of fields in the new order. + foreach (array_keys($order) as $field) { + $new_fields[$field] = $old_fields[$field]; + } + $display->handler->set_option($types[$form_state['type']]['plural'], $new_fields); + + // Store in cache + views_ui_cache_set($form_state['view']); +} + +/** + * Form to rearrange items in the views UI. + */ +function views_ui_rearrange_filter_form($form, &$form_state) { + $view = &$form_state['view']; + $display_id = $form_state['display_id']; + $type = $form_state['type']; + + $types = views_object_types(); + if (!$view->set_display($display_id)) { + views_ajax_render(t('Invalid display id @display', array('@display' => $display_id))); + } + $display = &$view->display[$display_id]; + $form['#title'] = check_plain($display->display_title) . ': '; + $form['#title'] .= t('Rearrange @type', array('@type' => $types[$type]['ltitle'])); + $form['#section'] = $display_id . 'rearrange-item'; + + if ($display->handler->defaultable_sections($types[$type]['plural'])) { + $form_state['section'] = $types[$type]['plural']; + $display->handler->add_override_button($form, $form_state, $form_state['section']); + } + + if (!empty($view->form_cache)) { + $groups = $view->form_cache['groups']; + $handlers = $view->form_cache['handlers']; + } + else { + $groups = $display->handler->get_option('filter_groups'); + $handlers = $display->handler->get_option($types[$type]['plural']); + } + $count = 0; + + // Get relationship labels + $relationships = array(); + foreach ($display->handler->get_handlers('relationship') as $id => $handler) { + $relationships[$id] = $handler->label(); + } + + $group_options = array(); + + /** + * Filter groups is an array that contains: + * array( + * 'operator' => 'and' || 'or', + * 'groups' => array( + * $group_id => 'and' || 'or', + * ), + * ); + */ + + $grouping = count(array_keys($groups['groups'])) > 1; + + $form['filter_groups']['#tree'] = TRUE; + $form['filter_groups']['operator'] = array( + '#type' => 'select', + '#options' => array ( + 'AND' => t('And'), + 'OR' => t('Or'), + ), + '#default_value' => $groups['operator'], + '#attributes' => array( + 'class' => 'warning-on-change', + ), + '#title' => t('Operator to use on all groups'), + '#description' => t('Either "group 0 AND group 1 AND group 2" or "group 0 OR group 1 OR group 2", etc'), + '#access' => $grouping, + ); + + $form['remove_groups']['#tree'] = TRUE; + + foreach ($groups['groups'] as $id => $group) { + $form['filter_groups']['groups'][$id] = array( + '#title' => t('Group operator'), + '#type' => 'select', + '#options' => array( + 'AND' => t('And'), + 'OR' => t('Or'), + ), + '#default_value' => $group, + '#attributes' => array( + 'class' => array('warning-on-change'), + ), + ); + + $form['remove_groups'][$id] = array(); // to prevent a notice + if ($id != 0) { + $form['remove_groups'][$id] = array( + '#type' => 'submit', + '#value' => t('Remove group @group', array('@group' => $id)), + '#group' => $id, + ); + } + $group_options[$id] = $id == 0 ? t('Default group') : t('Group @group', array('@group' => $id)); + $form['#group_renders'][$id] = array(); + } + + $form['#group_options'] = $group_options; + $form['#groups'] = $groups; + // We don't use get_handlers() because we want items without handlers to + // appear and show up as 'broken' so that the user can see them. + $form['filters'] = array('#tree' => TRUE); + foreach ($handlers as $id => $field) { + // If the group does not exist, move the filters to the default group. + if (empty($field['group']) || empty($groups['groups'][$field['group']])) { + $field['group'] = 0; + } + + $handler = $display->handler->get_handler($type, $id); + if ($grouping && $handler && !$handler->can_group()) { + $field['group'] = 'ungroupable'; + } + + // If not grouping and the handler is set ungroupable, move it back to + // the default group to prevent weird errors from having it be in its + // own group: + if (!$grouping && $field['group'] == 'ungroupable') { + $field['group'] = 0; + } + + // Place this item into the proper group for rendering. + $form['#group_renders'][$field['group']][] = $id; + + $form['filters'][$id]['weight'] = array( + '#type' => 'textfield', + '#default_value' => ++$count, + ); + $form['filters'][$id]['group'] = array( + '#type' => 'select', + '#options' => $group_options, + '#default_value' => $field['group'], + '#attributes' => array( + 'class' => array('views-region-select', 'views-region-' . $id), + ), + '#access' => $field['group'] !== 'ungroupable', + ); + + if ($handler) { + $name = $handler->ui_name() . ' ' . $handler->admin_summary(); + if (!empty($field['relationship']) && !empty($relationships[$field['relationship']])) { + $name = '(' . $relationships[$field['relationship']] . ') ' . $name; + } + + $form['filters'][$id]['name'] = array( + '#markup' => $name, + ); + } + else { + $form['filters'][$id]['name'] = array('#markup' => t('Broken field @id', array('@id' => $id))); + } + $form['filters'][$id]['removed'] = array( + '#type' => 'checkbox', + '#id' => 'views-removed-' . $id, + '#attributes' => array('class' => array('views-remove-checkbox')), + '#default_value' => 0, + ); + } + + // Add javascript settings that will be added via $.extend for tabledragging + // Equivalent: drupal_add_tabledrag('arrange', 'order', 'sibling', 'weight'); + $form['#js']['tableDrag']['arrange']['weight'][0] = array( + 'target' => 'weight', + 'source' => NULL, + 'relationship' => 'sibling', + 'action' => 'order', + 'hidden' => TRUE, + 'limit' => 0, + ); + + $form['#js']['tableDrag']['ungroupable_arrange']['weight'][0] = array( + 'target' => 'weight', + 'source' => NULL, + 'relationship' => 'sibling', + 'action' => 'order', + 'hidden' => TRUE, + 'limit' => 0, + ); + + foreach ($form['#group_renders'] as $group_id => $title) { + // Add javascript settings that will be added via $.extend for tabledragging + // Equivalent: drupal_add_tabledrag('arrange', 'match', 'sibling', 'views-group-select', 'views-group-' . $group_id); + $form['#js']['tableDrag']['arrange']['views-group-select'][] = array( + 'target' => 'views-group-' . $group_id, + 'source' => 'views-group-' . $group_id, + 'relationship' => 'sibling', + 'action' => 'match', + 'hidden' => FALSE, + 'limit' => 0, + ); + } + + if (isset($form_state['update_name'])) { + $name = $form_state['update_name']; + } + + views_ui_standard_form_buttons($form, $form_state, 'views_ui_rearrange_filter_form'); + $form['buttons']['add_group'] = array( + '#type' => 'submit', + '#value' => t('Add new group'), + '#id' => 'views-add-group', + '#group' => 'add', + ); + + return $form; +} + +/** + * Turn the rearrange form into a proper table + */ +function theme_views_ui_rearrange_filter_form(&$vars) { + $form = $vars['form']; + $rows = $ungroupable_rows = array(); + // Enable grouping only if > 1 group. + $grouping = count(array_keys($form['#group_options'])) > 1; + + foreach ($form['#group_renders'] as $group_id => $contents) { + // Header row for the group. + if ($grouping && $group_id !== 'ungroupable') { + $row = array(); + $row[] = array('class' => array('group', 'group-title'), 'data' => $form['#group_options'][$group_id]); + $row[] = array('class' => array('group', 'container-inline'), 'data' => drupal_render($form['filter_groups']['groups'][$group_id]), 'colspan' => 3); + $rows[] = array('class' => array('views-group'), 'data' => $row, 'id' => 'views-group-' . $group_id); + // Row which will only appear if the group has nothing in it: + $row = array(); + $class = 'group-' . (count($contents) ? 'populated' : 'empty'); + $row[] = array('colspan' => 4, 'data' => '<span>' . t('This group is empty') . '</span> ' . + drupal_render($form['remove_groups'][$group_id])); + $rows[] = array('class' => array("group-message", "group-$group_id-message", $class), 'data' => $row, 'id' => 'views-group-' . $group_id); + } + + foreach ($contents as $id) { + if (isset($form['filters'][$id]['name'])) { + $row = array(); + $row[] = drupal_render($form['filters'][$id]['name']); + $form['filters'][$id]['weight']['#attributes']['class'] = array('weight'); + $row[] = drupal_render($form['filters'][$id]['weight']); + $form['filters'][$id]['group']['#attributes']['class'] = array('views-group-select views-group-' . $group_id); + $row[] = drupal_render($form['filters'][$id]['group']); + $row[] = drupal_render($form['filters'][$id]['removed']) . l('<span>' . t('Remove') . '</span>', 'javascript:void()', array('attributes' => array('id' => 'views-remove-link-' . $id, 'class' => array('views-hidden', 'views-button-remove', 'views-groups-remove-link'), 'alt' => t('Remove this item'), 'title' => t('Remove this item')), 'html' => true)); + + $row = array('data' => $row, 'class' => array('draggable'), 'id' => 'views-row-' . $id); + if ($group_id !== 'ungroupable') { + $rows[] = $row; + } + else { + $ungroupable_rows[] = $row; + } + } + } + } + if (empty($rows)) { + $rows[] = array(array('data' => t('No fields available.'), 'colspan' => '2')); + } + + $output = drupal_render($form['override']); + if ($grouping) { + $output .= drupal_render($form['filter_groups']['operator']); + } + else { + $form['filter_groups']['groups'][0]['#title'] = t('Operator'); + $output .= drupal_render($form['filter_groups']['groups'][0]); + } + + if (!empty($ungroupable_rows)) { + drupal_add_tabledrag('ungroupable_arrange', 'order', 'sibling', 'weight'); + $header = array(t('Ungroupable filters'), t('Weight'), array('class' => array('views-hide-label'), 'data' => t('Group')), array('class' => array('views-hide-label'), 'data' => t('Remove'))); + $output .= theme('table', array('header' => $header, 'rows' => $ungroupable_rows, 'attributes' => array('id' => 'ungroupable_arrange', 'class' => array('arrange')))); + } + + drupal_add_tabledrag('arrange', 'order', 'sibling', 'weight'); + $header = array('', t('Weight'), t('Group'), t('Remove')); + $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'arrange', 'class' => array('arrange')))); + $output .= drupal_render_children($form); + return $output; + +} + +/** + * Submit handler for rearranging form + */ +function views_ui_rearrange_filter_form_submit($form, &$form_state) { + $types = views_object_types(); + $display = &$form_state['view']->display[$form_state['display_id']]; + $remember_groups = array(); + + if (!empty($form_state['view']->form_cache)) { + $old_fields = $form_state['view']->form_cache['handlers']; + } + else { + $old_fields = $display->handler->get_option($types[$form_state['type']]['plural']); + } + $count = 0; + + $groups = $form_state['values']['filter_groups']; + // Whatever button was clicked, re-calculate field information. + $new_fields = $order = array(); + + // Make an array with the weights + foreach ($form_state['values']['filters'] as $field => $info) { + // add each value that is a field with a weight to our list, but only if + // it has had its 'removed' checkbox checked. + if (is_array($info) && empty($info['removed'])) { + if (isset($info['weight'])) { + $order[$field] = $info['weight']; + } + + if (isset($info['group'])) { + $old_fields[$field]['group'] = $info['group']; + $remember_groups[$info['group']][] = $field; + } + } + } + + // Sort the array + asort($order); + + // Create a new list of fields in the new order. + foreach (array_keys($order) as $field) { + $new_fields[$field] = $old_fields[$field]; + } + + // Save if the actual update button was clicked. + if (!empty($form_state['clicked_button']['#group'])) { + if ($form_state['clicked_button']['#group'] == 'add') { + // Add a new group + $groups['groups'][] = 'AND'; + } + else { + // Renumber groups above the removed one down. + foreach (array_keys($groups['groups']) as $group_id) { + if ($group_id >= $form_state['clicked_button']['#group']) { + $old_group = $group_id + 1; + if (isset($groups['groups'][$old_group])) { + $groups['groups'][$group_id] = $groups['groups'][$old_group]; + if (isset($remember_groups[$old_group])) { + foreach ($remember_groups[$old_group] as $id) { + $new_fields[$id]['group'] = $group_id; + } + } + } + else { + // If this is the last one, just unset it. + unset($groups['groups'][$group_id]); + } + } + } + } + // Update our cache with values so that cancel still works the way + // people expect. + $form_state['view']->form_cache = array( + 'key' => 'rearrange-filter', + 'groups' => $groups, + 'handlers' => $new_fields, + ); + + // Return to this form except on actual Update. + views_ui_add_form_to_stack('rearrange-filter', $form_state['view'], $form_state['display_id'], array($form_state['type'])); + } + else { + // Actually write changed handler values. + $display->handler->set_option($types[$form_state['type']]['plural'], $new_fields); + $display->handler->set_option('filter_groups', $groups); + if (isset($form_state['view']->form_cache)) { + unset($form_state['view']->form_cache); + } + } + + // Store in cache + views_ui_cache_set($form_state['view']); +} + +/** + * Form to add_item items in the views UI. + */ +function views_ui_add_item_form($form, &$form_state) { + $view = &$form_state['view']; + $display_id = $form_state['display_id']; + $type = $form_state['type']; + + ctools_add_js('dependent'); + + if (!$view->set_display($display_id)) { + views_ajax_error(t('Invalid display id @display', array('@display' => $display_id))); + } + $display = &$view->display[$display_id]; + + $types = views_object_types(); + $ltitle = $types[$type]['ltitle']; + + if (!empty($types[$type]['type'])) { + $type = $types[$type]['type']; + } + + $form['#title'] = check_plain($display->display_title) . ': '; + $form['#title'] .= t('Add @type', array('@type' => $ltitle)); + $form['#section'] = $display_id . 'add-item'; + + // Figure out all the base tables allowed based upon what the relationships provide. + $base_tables = $view->get_base_tables(); + $options = views_fetch_fields(array_keys($base_tables), $type, $display->handler->use_group_by()); + + if (!empty($options)) { + $groups = array('all' => t('- All -')); + $form['group'] = array( + '#type' => 'select', + '#title' => t('Groups'), + '#options' => array(), + '#attributes' => array('class' => array('ctools-master-dependent')), + ); + + $form['name'] = array( + '#prefix' => '<div class="views-radio-box form-checkboxes">', + '#suffix' => '</div>', + '#tree' => TRUE, + '#default_value' => 'all', + ); + + // Group options first to simplify the DOM objects that Views + // dependent JS will act upon. + $grouped_options = array(); + foreach ($options as $key => $option) { + $group = preg_replace('/[^a-z0-9]/', '-', strtolower($option['group'])); + $groups[$group] = $option['group']; + $grouped_options[$group][$key] = $option; + } + + foreach ($grouped_options as $group => $group_options) { + $form['name'][$group . '_start']['#markup'] = '<div class="ctools-dependent-all ctools-dependent-' . $group . '">'; + foreach ($group_options as $key => $option) { + $form['name'][$key] = array( + '#type' => 'checkbox', + '#title' => t('!group: !field', array('!group' => $option['group'], '!field' => $option['title'])), + '#description' => $option['help'], + '#return_value' => $key, + ); + } + $form['name'][$group . '_end']['#markup'] = '</div>'; + } + + $form['group']['#options'] = $groups; + } + else { + $form['markup'] = array( + '#markup' => '<div class="form-item">' . t('There are no @types available to add.', array('@types' => $types[$type]['ltitle'])) . '</div>', + ); + } + ctools_include('dependent'); + views_ui_standard_form_buttons($form, $form_state, 'views_ui_add_item_form', t('Add')); + + return $form; +} + +/** + * Submit handler for adding new item(s) to a view. + */ +function views_ui_add_item_form_submit($form, &$form_state) { + $type = $form_state['type']; + $types = views_object_types(); + + if (!empty($form_state['values']['name']) && is_array($form_state['values']['name'])) { + // Loop through each of the items that were checked and add them to the view. + foreach (array_keys(array_filter($form_state['values']['name'])) as $field) { + list($table, $field) = explode('.', $field, 2); + $id = $form_state['view']->add_item($form_state['display_id'], $type, $table, $field); + + // check to see if we have group by settings + if ($form_state['view']->display_handler->use_group_by()) { + views_ui_add_form_to_stack('config-item-group', $form_state['view'], $form_state['display_id'], array($type, $id)); + } + + // check to see if this type has settings, if so add the settings form first + $handler = views_get_handler($table, $field, $type); + if ($handler && $handler->has_extra_options()) { + views_ui_add_form_to_stack('config-item-extra', $form_state['view'], $form_state['display_id'], array($type, $id)); + } + // Then add the form to the stack + views_ui_add_form_to_stack('config-item', $form_state['view'], $form_state['display_id'], array($type, $id)); + } + } + + if (isset($form_state['view']->form_cache)) { + unset($form_state['view']->form_cache); + } + + // Store in cache + views_ui_cache_set($form_state['view']); +} + + +/** + * Form to config_item items in the views UI. + */ +function views_ui_config_item_form($form, &$form_state) { + $view = &$form_state['view']; + $display_id = $form_state['display_id']; + $type = $form_state['type']; + $id = $form_state['id']; + + $form = array('options' => array('#tree' => TRUE)); + if (!$view->set_display($display_id)) { + views_ajax_error(t('Invalid display id @display', array('@display' => $display_id))); + } + $item = $view->get_item($display_id, $type, $id); + + if ($item) { + $handler = $view->display_handler->get_handler($type, $id); + if (empty($handler)) { + $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field']))); + } + else { + $types = views_object_types(); + + if ($view->display_handler->defaultable_sections($types[$type]['plural'])) { + $form_state['section'] = $types[$type]['plural']; + $view->display_handler->add_override_button($form['options'], $form_state, $form_state['section']); + } + + // A whole bunch of code to figure out what relationships are valid for + // this item. + $relationships = $view->display_handler->get_option('relationships'); + $relationship_options = array(); + + foreach ($relationships as $relationship) { + // relationships can't link back to self. But also, due to ordering, + // relationships can only link to prior relationships. + if ($type == 'relationship' && $id == $relationship['id']) { + break; + } + $relationship_handler = views_get_handler($relationship['table'], $relationship['field'], 'relationship'); + // ignore invalid/broken relationships. + if (empty($relationship_handler)) { + continue; + } + + // If this relationship is valid for this type, add it to the list. + $data = views_fetch_data($relationship['table']); + $base = $data[$relationship['field']]['relationship']['base']; + $base_fields = views_fetch_fields($base, $form_state['type'], $view->display_handler->use_group_by()); + if (isset($base_fields[$item['table'] . '.' . $item['field']])) { + $relationship_handler->init($view, $relationship); + $relationship_options[$relationship['id']] = $relationship_handler->label(); + } + } + + if (!empty($relationship_options)) { + // Make sure the existing relationship is even valid. If not, force + // it to none. + $base_fields = views_fetch_fields($view->base_table, $form_state['type'], $view->display_handler->use_group_by()); + if (isset($base_fields[$item['table'] . '.' . $item['field']])) { + $relationship_options = array_merge(array('none' => t('Do not use a relationship')), $relationship_options); + } + $rel = empty($item['relationship']) ? 'none' : $item['relationship']; + if (empty($relationship_options[$rel])) { + // Pick the first relationship. + $rel = key($relationship_options); + // We want this relationship option to get saved even if the user + // skips submitting the form. + $view->set_item_option($display_id, $type, $id, 'relationship', $rel); + $temp_view = $view->clone_view(); + views_ui_cache_set($temp_view); + } + + $form['options']['relationship'] = array( + '#type' => 'select', + '#title' => t('Relationship'), + '#options' => $relationship_options, + '#default_value' => $rel, + ); + } + else { + $form['options']['relationship'] = array( + '#type' => 'value', + '#value' => 'none', + ); + } + + $form['#title'] = check_plain($view->display[$display_id]->display_title) . ': '; + $form['#title'] .= t('Configure @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->ui_name())); + + $form['form_description'] = array( + '#type' => 'markup', + '#weight' => -1000, + '#prefix' => '<div class="form-item description">', + '#suffix' => '</div>', + '#value' => $handler->definition['help'], + ); + + $form['#section'] = $display_id . '-' . $type . '-' . $id; + + // Get form from the handler. + $handler->options_form($form['options'], $form_state); + $form_state['handler'] = &$handler; + } + + $name = NULL; + if (isset($form_state['update_name'])) { + $name = $form_state['update_name']; + } + + views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_item_form', $name, t('Remove'), 'remove'); + } + return $form; +} + +/** + * Submit handler for configing new item(s) to a view. + */ +function views_ui_config_item_form_validate($form, &$form_state) { + $form_state['handler']->options_validate($form['options'], $form_state); + + if (form_get_errors()) { + $form_state['rerender'] = TRUE; + } +} + +/** + * Submit handler for configing new item(s) to a view. + */ +function views_ui_config_item_form_submit($form, &$form_state) { + // Run it through the handler's submit function. + $form_state['handler']->options_submit($form['options'], $form_state); + $item = $form_state['handler']->options; + $types = views_object_types(); + + $type = $form_state['type']; + if (!empty($types[$type]['type'])) { + $type = $types[$type]['type']; + } + + // Create a new handler and unpack the options from the form onto it. We + // can use that for storage. + $handler = views_get_handler($item['table'], $item['field'], $type); + $handler->init($form_state['view'], $item); + + + // Add the incoming options to existing options because items using + // the extra form may not have everything in the form here. + $options = $form_state['values']['options'] + $form_state['handler']->options; + + // This unpacks only options that are in the definition, ensuring random + // extra stuff on the form is not sent through. + $handler->unpack_options($handler->options, $options, NULL, FALSE); + + // Store the item back on the view + $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $handler->options); + if ($form_state['handler'] && $form_state['handler']->needs_style_plugin()) { + views_ui_add_form_to_stack('change-style', $form_state['view'], $form_state['display_id'], array($form_state['type'], $form_state['id']), TRUE); + } + + // Write to cache + views_ui_cache_set($form_state['view']); +} + +/** + * Form to config_item items in the views UI. + */ +function views_ui_config_item_group_form($type, &$form_state) { + $view = &$form_state['view']; + $display_id = $form_state['display_id']; + $type = $form_state['type']; + $id = $form_state['id']; + + $form = array('options' => array('#tree' => TRUE)); + if (!$view->set_display($display_id)) { + views_ajax_render(t('Invalid display id @display', array('@display' => $display_id))); + } + + $view->init_query(); + + $item = $view->get_item($display_id, $type, $id); + + if ($item) { + $handler = $view->display_handler->get_handler($type, $id); + if (empty($handler)) { + $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field']))); + } + else { + $handler->init($view, $item); + $handler->groupby_form($form, $form_state); + $form_state['handler'] = &$handler; + } + + views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_item_group_form'); + } + return $form; +} + +/** + * Submit handler for configing group settings on a view. + */ +function views_ui_config_item_group_form_submit($form, &$form_state) { + $item =& $form_state['handler']->options; + $type = $form_state['type']; + $id = $form_state['id']; + + $handler = views_get_handler($item['table'], $item['field'], $type); + $handler->init($form_state['view'], $item); + + $handler->groupby_form_submit($form, $form_state); + + // Store the item back on the view + $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item); + + // Write to cache + views_ui_cache_set($form_state['view']); +} + +/** + * Submit handler for removing an item from a view + */ +function views_ui_config_item_form_remove($form, &$form_state) { + // Store the item back on the view + $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], NULL); + + // Write to cache + views_ui_cache_set($form_state['view']); +} + +/** + * Override handler for views_ui_edit_display_form + */ +function views_ui_config_item_form_expose($form, &$form_state) { + $item = &$form_state['handler']->options; + // flip + $item['exposed'] = empty($item['exposed']); + + // If necessary, set new defaults: + if ($item['exposed']) { + $form_state['handler']->expose_options(); + } + + $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item); + + views_ui_cache_set($form_state['view']); + $form_state['rerender'] = TRUE; + $form_state['rebuild'] = TRUE; + $form_state['force_expose_options'] = TRUE; +} + +/** + * Form to config_item items in the views UI. + */ +function views_ui_config_item_extra_form($form, &$form_state) { + $view = &$form_state['view']; + $display_id = $form_state['display_id']; + $type = $form_state['type']; + $id = $form_state['id']; + + $form = array('options' => array('#tree' => TRUE)); + if (!$view->set_display($display_id)) { + views_ajax_error(t('Invalid display id @display', array('@display' => $display_id))); + } + $item = $view->get_item($display_id, $type, $id); + + if ($item) { + $handler = views_get_handler($item['table'], $item['field'], $type); + if (empty($handler)) { + $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field']))); + } + else { + $handler->init($view, $item); + $types = views_object_types(); + + $form['#title'] = check_plain($view->display[$display_id]->display_title) . ': '; + $form['#title'] .= t('Configure extra settings for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->ui_name())); + + $form['#section'] = $display_id . '-' . $type . '-' . $id; + + // Get form from the handler. + $handler->extra_options_form($form['options'], $form_state); + $form_state['handler'] = &$handler; + } + + views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_item_extra_form'); + } + return $form; +} + +/** + * Validation handler for configing new item(s) to a view. + */ +function views_ui_config_item_extra_form_validate($form, &$form_state) { + $form_state['handler']->extra_options_validate($form['options'], $form_state); +} + +/** + * Submit handler for configing new item(s) to a view. + */ +function views_ui_config_item_extra_form_submit($form, &$form_state) { + // Run it through the handler's submit function. + $form_state['handler']->extra_options_submit($form['options'], $form_state); + $item = $form_state['handler']->options; + + // Store the data we're given. + foreach ($form_state['values']['options'] as $key => $value) { + $item[$key] = $value; + } + + // Store the item back on the view + $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item); + + // Write to cache + views_ui_cache_set($form_state['view']); +} + +/** + * Form to change_style items in the views UI. + */ +function views_ui_change_style_form($form, &$form_state) { + $view = &$form_state['view']; + $display_id = $form_state['display_id']; + $type = $form_state['type']; + $id = $form_state['id']; + + $form = array('options' => array('#tree' => TRUE)); + if (!$view->set_display($display_id)) { + views_ajax_error(t('Invalid display id @display', array('@display' => $display_id))); + } + $item = $view->get_item($display_id, $type, $id); + + if ($item) { + $handler = views_get_handler($item['table'], $item['field'], $type); + if (empty($handler)) { + $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field']))); + } + else { + $handler->init($view, $item); + $types = views_object_types(); + $form['#title'] = t('Change summary style for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->ui_name())); + + $form['#section'] = $display_id . '-' . $type . '-' . $id . '-style-plugin'; + + $form['style_plugin'] = array( + '#type' => 'radios', + '#options' => views_fetch_plugin_names('style', 'summary'), + '#default_value' => $item['style_plugin'], + ); + + $form_state['handler'] = &$handler; + } + views_ui_standard_form_buttons($form, $form_state, 'views_ui_change_style_form'); + } + return $form; +} + +function views_ui_change_style_form_validate($form, &$form_state) { + // Run it through the handler's submit function. + $form_state['handler']->options_validate($form['options'], $form_state); + + $plugin = views_get_plugin('style', $form_state['values']['style_plugin']); + if (!$plugin) { + form_error($form['style_plugin'], t('Internal error: broken plugin.')); + } +} + +/** + * Submit handler for configing new item(s) to a view. + */ +function views_ui_change_style_form_submit($form, &$form_state) { + // Run it through the handler's submit function. + $form_state['handler']->options_submit($form['options'], $form_state); + $item = $form_state['handler']->options; + + $plugin = views_get_plugin('style', $form_state['values']['style_plugin']); + if (!$plugin) { + drupal_set_message(t('Internal error: broken plugin.'), 'error'); + return; + } + + $plugin->init($form_state['view'], $form_state['view']->display[$form_state['display_id']]); + + // If changing style plugin, reset options to defaults. + if (empty($item['style_plugin']) || $item['style_plugin'] != $form_state['values']['style_plugin']) { + $item['style_options'] = $plugin->options; + } + + // Store the data we're given. + $item['style_plugin'] = $form_state['values']['style_plugin']; + + // Store the item back on the view + $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item); + + if (!empty($plugin->definition['uses options'])) { + views_ui_add_form_to_stack('config-style', $form_state['view'], $form_state['display_id'], array($form_state['type'], $form_state['id']), TRUE); + } + + // Write to cache + views_ui_cache_set($form_state['view']); +} + +/** + * Form to config_style items in the views UI. + */ +function views_ui_config_style_form($form, &$form_state) { + $view = &$form_state['view']; + $display_id = $form_state['display_id']; + $type = $form_state['type']; + $id = $form_state['id']; + + $form = array('options' => array('#tree' => TRUE)); + if (!$view->set_display($display_id)) { + views_ajax_error(t('Invalid display id @display', array('@display' => $display_id))); + } + $item = $view->get_item($display_id, $type, $id); + + if ($item) { + $handler = views_get_handler($item['table'], $item['field'], $type); + if (empty($handler)) { + $form['markup'] = array('#value' => t("Error: handler for @table > @field doesn't exist!", array('@table' => $item['table'], '@field' => $item['field']))); + } + else { + $handler->init($view, $item); + $types = views_object_types(); + + $form['#title'] = check_plain($view->display[$display_id]->display_title) . ': '; + $form['#title'] .= t('Configure summary style for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $handler->ui_name())); + + $form['#section'] = $display_id . '-' . $type . '-style-options'; + + $plugin = views_get_plugin('style', $handler->options['style_plugin']); + if ($plugin) { + $form['style_options'] = array( + '#tree' => TRUE, + ); + $plugin->init($view, $view->display[$display_id], $handler->options['style_options']); + + $plugin->options_form($form['style_options'], $form_state); + } + + $form_state['handler'] = &$handler; + } + + views_ui_standard_form_buttons($form, $form_state, 'views_ui_config_style_form'); + } + return $form; +} + +/** + * Submit handler for configing new item(s) to a view. + */ +function views_ui_config_style_form_submit($form, &$form_state) { + // Run it through the handler's submit function. + $form_state['handler']->options_submit($form['style_options'], $form_state); + $item = $form_state['handler']->options; + + // Store the data we're given. + $item['style_options'] = $form_state['values']['style_options']; + + // Store the item back on the view + $form_state['view']->set_item($form_state['display_id'], $form_state['type'], $form_state['id'], $item); + + // Write to cache + views_ui_cache_set($form_state['view']); +} + +/** + * Get a list of roles in the system. + */ +function views_ui_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"); + foreach ($result as $obj) { + $roles[$obj->rid] = $obj->name; + } + } + + return $roles; +} + +/** + * Page callback for the Views enable page. + */ +function views_ui_enable_page($view) { + $views_status = variable_get('views_defaults', array()); + $views_status[$view->name] = FALSE; // FALSE is enabled + variable_set('views_defaults', $views_status); + views_invalidate_cache(); + menu_rebuild(); + drupal_goto('admin/structure/views'); +} + +/** + * Page callback for the Views enable page + */ +function views_ui_disable_page($view) { + $views_status = variable_get('views_defaults', array()); + $views_status[$view->name] = TRUE; // True is disabled + variable_set('views_defaults', $views_status); + views_invalidate_cache(); + menu_rebuild(); + drupal_goto('admin/structure/views'); +} + +/** + * Page callback for the tools - other page + */ +function views_ui_admin_tools() { + $form['clear_cache'] = array( + '#type' => 'submit', + '#value' => t("Clear Views' cache"), + '#submit' => array('views_ui_tools_clear_cache'), + ); + + $form['views_sql_signature'] = array( + '#type' => 'checkbox', + '#title' => t('Add Views signature to all SQL queries'), + '#description' => t("All Views-generated queries will include a special 'VIEWS' = 'VIEWS' string in the WHERE clause. This makes identifying Views queries in database server logs simpler, but should only be used when troubleshooting."), + '#default_value' => variable_get('views_sql_signature', FALSE), + ); + + $form['views_skip_cache'] = array( + '#type' => 'checkbox', + '#title' => t('Disable views data caching'), + '#description' => t("Views caches data about tables, modules and views available, to increase performance. By checking this box, Views will skip this cache and always rebuild this data when needed. This can have a serious performance impact on your site."), + '#default_value' => variable_get('views_skip_cache', FALSE), + ); + + $form['views_hide_help_message'] = array( + '#type' => 'checkbox', + '#title' => t('Ignore missing advanced help module'), + '#description' => t("Views uses the advanced help module to provide help text; if this module is not present Views will complain, unless this setting is checked."), + '#default_value' => variable_get('views_hide_help_message', FALSE), + ); + + $form['views_ui_query_on_top'] = array( + '#type' => 'checkbox', + '#title' => t('Show query above live preview'), + '#description' => t("The live preview feature will show you the output of the view you're creating, as well as the view. Check here to show the query and other information above the view; leave this unchecked to show that information below the view."), + '#default_value' => variable_get('views_ui_query_on_top', FALSE), + ); + + $form['views_ui_disable_live_preview'] = array( + '#type' => 'checkbox', + '#title' => t('Disable automatic live preview'), + '#description' => t("Don't automatically update the preview. This can speed up the editing of views a bit.'"), + '#default_value' => variable_get('views_ui_disable_live_preview', 0), + ); + + $form['views_show_additional_queries'] = array( + '#type' => 'checkbox', + '#title' => t('Show other queries run during render during live preview'), + '#description' => t("Drupal has the potential to run many queries while a view is being rendered. Checking this box will display every query run during view render as part of the live preview."), + '#default_value' => variable_get('views_show_additional_queries', FALSE), + ); + + $form['views_no_hover_links'] = array( + '#type' => 'checkbox', + '#title' => t('Do not show hover links over views'), + '#description' => t("To make it easier to administrate your views, Views provides 'hover' links to take you to the edit and export screen of a view whenever the view is used. This can be distracting on some themes, though; if it is problematic, you can turn it off here."), + '#default_value' => variable_get('views_no_hover_links', FALSE), + ); + + $form['views_devel_output'] = array( + '#type' => 'checkbox', + '#title' => t('Enable views performance statistics via the Devel module'), + '#description' => t("Check this to enable some Views query and performance statistics <em>if Devel is installed</em>."), + '#default_value' => variable_get('views_devel_output', FALSE), + ); + + $form['views_no_javascript'] = array( + '#type' => 'checkbox', + '#title' => t('Disable javascript with Views'), + '#description' => t("If you are having problems with the javascript, you can disable it here; the Views UI should degrade and still be usable without javascript, it just not as good."), + '#default_value' => variable_get('views_no_javascript', FALSE), + ); + + $form['views_localization_plugin'] = array( + '#type' => 'radios', + '#title' => t('Translation method'), + '#options' => views_fetch_plugin_names('localization', NULL, array(), TRUE), + '#default_value' => variable_get('views_localization_plugin', 'core'), + '#description' => t('Select a translation method to use for Views data like header, footer, and empty text.'), + ); + + $regions = system_region_list(variable_get('theme_default', 'garland')); + $regions['watchdog'] = t('Watchdog'); + + $form['views_devel_region'] = array( + '#type' => 'select', + '#title' => t('Page region to output performance statistics'), + '#default_value' => variable_get('views_devel_region', 'footer'), + '#options' => $regions, + ); + + $form['views_exposed_filter_any_label'] = array( + '#type' => 'select', + '#title' => t('Label for "Any" value on optional single-select exposed filters'), + '#options' => array('old_any' => '<Any>', 'new_any' => t('- Any -')), + '#default_value' => variable_get('views_exposed_filter_any_label', 'old_any'), + ); + + return system_settings_form($form); +} + +/** + * Submit hook to clear the views cache. + */ +function views_ui_tools_clear_cache() { + views_invalidate_cache(); + drupal_set_message(t('The cache has been cleared.')); +} + +/** + * Submit hook to clear Drupal's theme registry (thereby triggering + * a templates rescan). + */ +function views_ui_config_item_form_rescan($form, &$form_state) { + drupal_theme_rebuild(); + + // The 'Theme: Information' page is about to be shown again. That page + // analyzes the output of theme_get_registry(). However, this latter + // function uses an internal cache (which was initialized before we + // called drupal_theme_rebuild()) so it won't reflect the + // current state of our theme registry. The only way to clear that cache + // is to re-initialize the theme system: + unset($GLOBALS['theme']); + drupal_theme_initialize(); + + $form_state['rerender'] = TRUE; + $form_state['rebuild'] = TRUE; +} + +/** + * Override handler for views_ui_edit_display_form + */ +function views_ui_edit_display_form_change_theme($form, &$form_state) { + // This is just a temporary variable. + $form_state['view']->theme = $form_state['values']['theme']; + + views_ui_cache_set($form_state['view']); + $form_state['rerender'] = TRUE; + $form_state['rebuild'] = TRUE; +} + +/** + * Page callback for views tag autocomplete + */ +function views_ui_autocomplete_tag($string = '') { + $matches = array(); + // get matches from default views: + views_include('view'); + $views = views_discover_default_views(); + foreach ($views as $view) { + if (!empty($view->tag) && strpos($view->tag, $string) === 0) { + $matches[$view->tag] = $view->tag; + } + } + + $count = 10 - count($matches); + if ($string) { + $result = db_query_range("SELECT DISTINCT tag FROM {views_view} WHERE LOWER(tag) LIKE LOWER(:tag)", + 0, $count, + array(':tag' => $string . '%')); + foreach ($result as $view) { + $matches[$view->tag] = check_plain($view->tag); + } + } + + drupal_json_output($matches); +} + +// ------------------------------------------------------------------ +// Get information from the Views data + +function _views_weight_sort($a, $b) { + if ($a['weight'] != $b['weight']) { + return $a['weight'] < $b['weight'] ? -1 : 1; + } + if ($a['title'] != $b['title']) { + return $a['title'] < $b['title'] ? -1 : 1; + } + + return 0; +} + +/** + * Fetch a list of all base tables available + * + * @return + * A keyed array of in the form of 'base_table' => 'Description'. + */ +function views_fetch_base_tables() { + static $base_tables = array(); + if (empty($base_tables)) { + $weights = array(); + $tables = array(); + $data = views_fetch_data(); + foreach ($data as $table => $info) { + if (!empty($info['table']['base'])) { + $tables[$table] = array( + 'title' => $info['table']['base']['title'], + 'description' => $info['table']['base']['help'], + 'weight' => !empty($info['table']['base']['weight']) ? $info['table']['base']['weight'] : 0, + ); + } + } + uasort($tables, '_views_weight_sort'); + $base_tables = $tables; + } + + return $base_tables; +} + +function _views_sort_types($a, $b) { + if ($a['group'] != $b['group']) { + return $a['group'] < $b['group'] ? -1 : 1; + } + + if ($a['title'] != $b['title']) { + return $a['title'] < $b['title'] ? -1 : 1; + } + + return 0; +} + +/** + * Fetch a list of all fields available for a given base type. + * + * @return + * A keyed array of in the form of 'base_table' => 'Description'. + */ +function views_fetch_fields($base, $type, $grouping = FALSE) { + static $fields = array(); + if (empty($fields)) { + $data = views_fetch_data(); + $start = microtime(TRUE); + // This constructs this ginormous multi dimensional array to + // collect the important data about fields. In the end, + // the structure looks a bit like this (using nid as an example) + // $strings['nid']['filter']['title'] = 'string'. + // + // This is constructed this way because the above referenced strings + // can appear in different places in the actual data structure so that + // the data doesn't have to be repeated a lot. This essentially lets + // each field have a cheap kind of inheritance. + + foreach ($data as $table => $table_data) { + $bases = array(); + $strings = array(); + $skip_bases = array(); + foreach ($table_data as $field => $info) { + // Collect table data from this table + if ($field == 'table') { + // calculate what tables this table can join to. + if (!empty($info['join'])) { + $bases = array_keys($info['join']); + } + // And it obviously joins to itself. + $bases[] = $table; + continue; + } + foreach (array('field', 'sort', 'filter', 'argument', 'relationship', 'area') as $key) { + if (!empty($info[$key])) { + if ($grouping && !empty($info[$key]['no group by'])) { + continue; + } + if (!empty($info[$key]['skip base'])) { + foreach ((array) $info[$key]['skip base'] as $base_name) { + $skip_bases[$field][$key][$base_name] = TRUE; + } + } + elseif (!empty($info['skip base'])) { + foreach ((array) $info['skip base'] as $base_name) { + $skip_bases[$field][$key][$base_name] = TRUE; + } + } + foreach (array('title', 'group', 'help', 'base') as $string) { + // First, try the lowest possible level + if (!empty($info[$key][$string])) { + $strings[$field][$key][$string] = $info[$key][$string]; + } + // Then try the field level + elseif (!empty($info[$string])) { + $strings[$field][$key][$string] = $info[$string]; + } + // Finally, try the table level + elseif (!empty($table_data['table'][$string])) { + $strings[$field][$key][$string] = $table_data['table'][$string]; + } + else { + if ($string != 'base') { + $strings[$field][$key][$string] = t("Error: missing @component", array('@component' => $string)); + } + } + } + } + } + } + foreach ($bases as $base_name) { + foreach ($strings as $field => $field_strings) { + foreach ($field_strings as $type_name => $type_strings) { + if (empty($skip_bases[$field][$type_name][$base_name])) { + $fields[$base_name][$type_name]["$table.$field"] = $type_strings; + } + } + } + } + } +// vsm('Views UI data build time: ' . (views_microtime() - $start) * 1000 . ' ms'); + } + + // If we have an array of base tables available, go through them + // all and add them together. Duplicate keys will be lost and that's + // Just Fine. + if (is_array($base)) { + $strings = array(); + foreach ($base as $base_table) { + if (isset($fields[$base_table][$type])) { + $strings += $fields[$base_table][$type]; + } + } + uasort($strings, '_views_sort_types'); + return $strings; + } + + if (isset($fields[$base][$type])) { + uasort($fields[$base][$type], '_views_sort_types'); + return $fields[$base][$type]; + } + return array(); +} + +/** + * Fetch a list of all base tables available + * + * @param $type + * Either 'display', 'style' or 'row' + * @param $key + * For style plugins, this is an optional type to restrict to. May be 'normal', + * 'summary', 'feed' or others based on the neds of the display. + * @param $base + * An array of possible base tables. + * + * @return + * A keyed array of in the form of 'base_table' => 'Description'. + */ +function views_fetch_plugin_names($type, $key = NULL, $base = array()) { + $data = views_fetch_plugin_data(); + + $plugins[$type] = array(); + + foreach ($data[$type] as $id => $plugin) { + // Skip plugins that don't conform to our key. + if ($key && (empty($plugin['type']) || $plugin['type'] != $key)) { + continue; + } + if (empty($plugin['no ui']) && (empty($base) || empty($plugin['base']) || array_intersect($base, $plugin['base']))) { + $plugins[$type][$id] = $plugin['title']; + } + } + + if (!empty($plugins[$type])) { + asort($plugins[$type]); + return $plugins[$type]; + } + // fall-through + return array(); +} + + +/** + * Theme the form for the table style plugin + */ +function theme_views_ui_style_plugin_table($variables) { + $form = $variables['form']; + + $output = drupal_render($form['description_markup']); + + $header = array( + t('Field'), + t('Column'), + t('Align'), + t('Separator'), + array( + 'data' => t('Sortable'), + 'align' => 'center', + ), + array( + 'data' => t('Default order'), + 'align' => 'center', + ), + array( + 'data' => t('Default sort'), + 'align' => 'center', + ), + ); + $rows = array(); + foreach (element_children($form['columns']) as $id) { + $row = array(); + $row[] = drupal_render($form['info'][$id]['name']); + $row[] = drupal_render($form['columns'][$id]); + $row[] = drupal_render($form['info'][$id]['align']); + $row[] = drupal_render($form['info'][$id]['separator']); + if (!empty($form['info'][$id]['sortable'])) { + $row[] = array( + 'data' => drupal_render($form['info'][$id]['sortable']), + 'align' => 'center', + ); + $row[] = array( + 'data' => drupal_render($form['info'][$id]['default_sort_order']), + 'align' => 'center', + ); + $row[] = array( + 'data' => drupal_render($form['default'][$id]), + 'align' => 'center', + ); + } + else { + $row[] = ''; + $row[] = ''; + $row[] = ''; + } + $rows[] = $row; + } + + // Add the special 'None' row. + $rows[] = array(t('None'), '', '', '', '', '', array('align' => 'center', 'data' => drupal_render($form['default'][-1]))); + + $output .= theme('table', array('header' => $header, 'rows' => $rows)); + $output .= drupal_render_children($form); + return $output; +} diff --git a/sites/all/modules/views/includes/ajax.inc b/sites/all/modules/views/includes/ajax.inc new file mode 100644 index 0000000000000000000000000000000000000000..ac006f983570c8c03fc81da0979a3b7e67d87d88 --- /dev/null +++ b/sites/all/modules/views/includes/ajax.inc @@ -0,0 +1,345 @@ +<?php +// $Id: ajax.inc,v 1.20.4.17 2011/01/03 22:56:39 merlinofchaos Exp $ + +/** + * @file ajax.inc + * + * Handles the server side AJAX interactions of Views. + * + * @defgroup ajax Views ajax library + * @{ + */ + +/** + * Menu callback to load a view via AJAX. + */ +function views_ajax() { + if (isset($_REQUEST['view_name']) && isset($_REQUEST['view_display_id'])) { + $name = $_REQUEST['view_name']; + $display_id = $_REQUEST['view_display_id']; + $args = isset($_REQUEST['view_args']) && $_REQUEST['view_args'] !== '' ? explode('/', $_REQUEST['view_args']) : array(); + $path = isset($_REQUEST['view_path']) ? $_REQUEST['view_path'] : NULL; + $dom_id = isset($_REQUEST['view_dom_id']) ? intval($_REQUEST['view_dom_id']) : NULL; + $pager_element = isset($_REQUEST['pager_element']) ? intval($_REQUEST['pager_element']) : NULL; + + $commands = array(); + + $arg = explode('/', $_REQUEST['view_path']); + + // Load the view. + $view = views_get_view($name); + if ($view && $view->access($display_id)) { + // Fix 'q' for paging. + if (!empty($path)) { + $_GET['q'] = $path; + } + + // Add all $_POST data, because AJAX is always a post and many things, + // such as tablesorts, exposed filters and paging assume $_GET. + $_GET += $_POST; + + // Override the display's pager_element with the one actually used. + if (isset($pager_element)) { + $view->display[$display_id]->handler->set_option('pager_element', $pager_element); + } + // Reuse the same DOM id so it matches that in Drupal.settings. + $view->dom_id = $dom_id; + + $errors = $view->validate(); + if ($errors === TRUE) { + $commands[] = ajax_command_replace('.view-dom-id-' . $dom_id, $view->preview($display_id, $args)); + } + else { + foreach ($errors as $error) { + drupal_set_message($error, 'error'); + } + } + } + return array('#type' => 'ajax', '#commands' => $commands); + } +} + +/** + * Creates a Drupal AJAX 'viewsSetForm' command. + * + * @param $output + * The form to display in the modal. + * @param $title + * The title. + * @param $url + * An optional URL. + * + * @return + * An array suitable for use with the ajax_render() function. + */ +function views_ajax_command_set_form($output, $title, $url = NULL) { + $command = array( + 'command' => 'viewsSetForm', + 'output' => $output, + 'title' => $title, + ); + if (isset($url)) { + $command['url'] = $url; + } + return $command; +} + +/** + * Creates a Drupal AJAX 'viewsDismissForm' command. + * + * @return + * An array suitable for use with the ajax_render() function. + */ +function views_ajax_command_dismiss_form() { + $command = array( + 'command' => 'viewsDismissForm', + ); + return $command; +} + +/** + * Creates a Drupal AJAX 'viewsHilite' command. + * + * @param $selector + * The selector to highlight + * + * @return + * An array suitable for use with the ajax_render() function. + */ +function views_ajax_command_hilite($selector) { + return array( + 'command' => 'viewsHilite', + 'selector' => $selector, + ); +} + +/** + * Creates a Drupal AJAX 'addTab' command. + * + * @param $id + * The DOM ID. + * @param $title + * The title. + * @param $body + * The body. + * + * @return + * An array suitable for use with the ajax_render() function. + */ +function views_ajax_command_add_tab($id, $title, $body) { + $command = array( + 'command' => 'viewsAddTab', + 'id' => $id, + 'title' => $title, + 'body' => $body, + ); + return $command; +} + +/** + * Disables Save, Cancel, and Delete buttons. + * + * @return + * An array suitable for use with the ajax_render() function. + */ +function views_ajax_command_disable_buttons() { + $command = array( + 'command' => 'viewsDisableButtons', + ); + return $command; +} + +/** + * Enables Save, Cancel, and Delete buttons. + * + * @return + * An array suitable for use with the ajax_render() function. + */ +function views_ajax_command_enable_buttons() { + $command = array( + 'command' => 'viewsEnableButtons', + ); + return $command; +} + +/** + * Trigger the Views live preview. + * + * @return + * An array suitable for use with the ajax_render() function. + */ +function views_ajax_command_trigger_preview() { + $command = array( + 'command' => 'viewsTriggerPreview', + ); + return $command; +} + +/** + * Return an AJAX error. + */ +function views_ajax_error($message) { + $commands = array(); + $commands[] = views_ajax_command_set_form($message, t('Error')); + return $commands; +} + +/** + * Wrapper around drupal_build_form to handle some AJAX stuff automatically. + * This makes some assumptions about the client. + */ +function views_ajax_form_wrapper($form_id, &$form_state) { + ctools_include('dependent'); + + // This won't override settings already in. + $form_state += array( + 'rerender' => FALSE, + 'no_redirect' => !empty($form_state['ajax']), + 'no_cache' => TRUE, + 'build_info' => array( + 'args' => array(), + ), + ); + + $form = drupal_build_form($form_id, $form_state); + $output = drupal_render($form); + + // These forms have the title built in, so set the title here: + if (empty($form_state['ajax']) && !empty($form_state['title'])) { + drupal_set_title($form_state['title']); + } + + if (!empty($form_state['ajax']) && (empty($form_state['executed']) || !empty($form_state['rerender']))) { + // If the form didn't execute and we're using ajax, build up a + // Ajax command list to execute. + $commands = array(); + + $display = ''; + if ($messages = theme('status_messages')) { + $display = '<div class="views-messages">' . $messages . '</div>'; + } + $display .= $output; + + $title = empty($form_state['title']) ? '' : $form_state['title']; + if (!empty($form_state['help_topic'])) { + $module = !empty($form_state['help_module']) ? $form_state['help_module'] : 'views'; + if (module_exists('advanced_help')) { + $title = theme('advanced_help_topic', array('module' => $module, 'topic' => $form_state['help_topic'])) . $title; + } + } + + $url = empty($form_state['url']) ? url($_GET['q'], array('absolute' => TRUE)) : $form_state['url']; + + $commands[] = views_ajax_command_set_form($display, $title, $url); + if (!empty($form_state['js settings'])) { + $commands[] = ajax_command_settings($form_state['js settings']); + } + + if (!empty($form_state['#section'])) { + $commands[] = views_ajax_command_hilite('.' . drupal_clean_css_identifier($form_state['#section'])); + } + + return $commands; + } + + // These forms have the title built in, so set the title here: + if (empty($form_state['ajax']) && !empty($form_state['title'])) { + drupal_set_title($form_state['title']); + } + + return $output; +} + + +/** + * Page callback for views user autocomplete + */ +function views_ajax_autocomplete_user($string = '') { + // The user enters a comma-separated list of tags. We only autocomplete the last tag. + $array = drupal_explode_tags($string); + + // Fetch last tag + $last_string = trim(array_pop($array)); + $matches = array(); + if ($last_string != '') { + $prefix = count($array) ? implode(', ', $array) . ', ' : ''; + + if (strpos('anonymous', strtolower($last_string)) !== FALSE) { + $matches[$prefix . 'Anonymous'] = 'Anonymous'; + } + $result = db_query_range("SELECT name FROM {users} WHERE name = :string", + 0, 1, + array( + ':string' => $last_string + )); + + foreach ($result as $account) { + $n = $account->name; + // Commas and quotes in terms are special cases, so encode 'em. + if (strpos($account->name, ',') !== FALSE || strpos($account->name, '"') !== FALSE) { + $n = '"' . str_replace('"', '""', $account->name) . '"'; + } + $matches[$prefix . $n] = check_plain($account->name); + } + } + + drupal_json_output($matches); +} + +/** + * Page callback for views taxonomy autocomplete. + * + * @param $vid + * The vocabulary id of the tags which should be returned. + * + * @param $tags_typed + * The typed string of the user. + * + * @see taxonomy_autocomplete() + */ +function views_ajax_autocomplete_taxonomy($vid, $tags_typed = '') { + // The user enters a comma-separated list of tags. We only autocomplete the last tag. + $tags_typed = drupal_explode_tags($tags_typed); + $tag_last = drupal_strtolower(array_pop($tags_typed)); + + $matches = array(); + if ($tag_last != '') { + + $query = db_select('taxonomy_term_data', 't'); + $query->addTag('translatable'); + $query->addTag('term_access'); + + // Do not select already entered terms. + if (!empty($tags_typed)) { + $query->condition('t.name', $tags_typed, 'NOT IN'); + } + // Select rows that match by term name. + $tags_return = $query + ->fields('t', array('tid', 'name')) + ->condition('t.vid', $vid) + ->condition('t.name', '%' . db_like($tag_last) . '%', 'LIKE') + ->range(0, 10) + ->execute() + ->fetchAllKeyed(); + + $prefix = count($tags_typed) ? implode(', ', $tags_typed) . ', ' : ''; + + $term_matches = array(); + foreach ($tags_return as $tid => $name) { + $n = $name; + // Term names containing commas or quotes must be wrapped in quotes. + if (strpos($name, ',') !== FALSE || strpos($name, '"') !== FALSE) { + $n = '"' . str_replace('"', '""', $name) . '"'; + } + else { + $term_matches[$prefix . $n] = check_plain($name); + } + } + } + + drupal_json_output($term_matches); +} + +/** + * @} + */ diff --git a/sites/all/modules/views/includes/analyze.inc b/sites/all/modules/views/includes/analyze.inc new file mode 100644 index 0000000000000000000000000000000000000000..4d9256fff64d4b8213b3e63c5e67ffb3a2b8a61c --- /dev/null +++ b/sites/all/modules/views/includes/analyze.inc @@ -0,0 +1,109 @@ +<?php +// $Id: analyze.inc,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * @file + * Contains the view analyze tool code. + * + * This tool is a small plugin manager to perform analysis on a view and + * report results to the user. This tool is meant to let modules that + * provide data to Views also help users properly use that data by + * detecting invalid configurations. Views itself comes with only a + * small amount of analysis tools, but more could easily be added either + * by modules or as patches to Views itself. + */ + +/** + * Analyze a review and return the results. + * + * @return + * An array of analyze results organized into arrays keyed by 'ok', + * 'warning' and 'error'. + */ +function views_analyze_view(&$view) { + $view->init_display(); + $messages = module_invoke_all('views_analyze', $view); + + return $messages; +} + +/** + * Format the analyze result into a message string. + * + * This is based upon the format of drupal_set_message which uses separate + * boxes for "ok", "warning" and "error". + */ +function views_analyze_format_result($view, $messages) { + if (empty($messages)) { + $messages = array(views_ui_analysis(t('View analysis can find nothing to report.'), 'ok')); + } + + $types = array('ok' => array(), 'warning' => array(), 'error' => array()); + foreach ($messages as $message) { + if (empty($types[$message['type']])) { + $types[$message['type']] = array(); + } + $types[$message['type']][] = $message['message']; + } + + $output = ''; + foreach ($types as $type => $messages) { + $message = ''; + if (count($messages) > 1) { + $message = theme('item_list', array('items' => $messages)); + } + elseif ($messages) { + $message = array_shift($messages); + } + + if ($message) { + $output .= "<div class=\"$type\">$message</div>"; + } + } + + return $output; +} + +/** + * Format an analysis message. + * + * This tool should be called by any module responding to the analyze hook + * to properly format the message. It is usually used in the form: + * @code + * $ret[] = views_ui_analysis(t('This is the message'), 'ok'); + * @endcode + * + * The 'ok' status should be used to provide information about things + * that are acceptable. In general analysis isn't interested in 'ok' + * messages, but instead the 'warning', which is a category for items + * that may be broken unless the user knows what he or she is doing, + * and 'error' for items that are definitely broken are much more useful. + * + * @param $messages + * The message to report. + * @param $type + * The type of message. This should be "ok", "warning" or "error". Other + * values can be used but how they are treated by the output routine + * is undefined. + */ +function views_ui_analysis($message, $type = 'error') { + return array('message' => $message, 'type' => $type); +} + +/** + * Implements hook_views_analyze(). + * + * This is the basic views analysis that checks for very minimal problems. + * There are other analysis tools in core specific sections, such as + * node.views.inc as well. + */ +function views_ui_views_analyze($view) { + $ret = array(); + // Check for something other than the default display: + if (count($view->display) < 2) { + $ret[] = views_ui_analysis(t('This view has only a default display and therefore will not be placed anywhere on your site; perhaps you want to add a page or a block display.'), 'warning'); + } + + return $ret; +} + diff --git a/sites/all/modules/views/includes/base.inc b/sites/all/modules/views/includes/base.inc new file mode 100644 index 0000000000000000000000000000000000000000..3388163dadc2c966e2aa4fc8fd07293b7bf4c65a --- /dev/null +++ b/sites/all/modules/views/includes/base.inc @@ -0,0 +1,304 @@ +<?php +// $Id: base.inc,v 1.3.4.6 2010/12/01 20:05:06 dereine Exp $ +/** + * @file + * + * Provides the basic object definitions used by plugins and handlers. + */ + +/** + * Basic definition for many views objects + */ +class views_object { + /** + * Except for displays, options for the object will be held here. + */ + var $options = array(); + /** + * Information about options for all kinds of purposes will be held here. + * @code + * 'option_name' => array( + * - 'default' => default value, + * - 'translatable' => TRUE/FALSE (wrap in t() on export if true), + * - 'contains' => array of items this contains, with its own defaults, etc. + * If contains is set, the default will be ignored and assumed to + * be array() + * + * ), + * @endcode + * Each option may have any of the following functions: + * - export_option_OPTIONNAME -- Special export handling if necessary. + * - translate_option_OPTIONNAME -- Special handling for translating data + * within the option, if necessary. + */ + function option_definition() { return array(); } + + /** + * Views handlers use a special construct function so that we can more + * easily construct them with variable arguments. + */ + function construct() { $this->set_default_options(); } + + /** + * Set default options on this object. Called by the constructor in a + * complex chain to deal with backward compatibility. + */ + function options(&$options) { } + + /** + * Set default options. + * For backward compatibility, it sends the options array; this is a + * feature that will likely disappear at some point. + */ + function set_default_options() { + $this->_set_option_defaults($this->options, $this->option_definition()); + + // Retained for complex defaults plus backward compatibility. + $this->options($this->options); + } + + function _set_option_defaults(&$storage, $options, $level = 0) { + foreach ($options as $option => $definition) { + if (isset($definition['contains']) && is_array($definition['contains'])) { + $storage[$option] = array(); + $this->_set_option_defaults($storage[$option], $definition['contains'], $level++); + } + elseif (!empty($definition['translatable']) && !empty($definition['default'])) { + $storage[$option] = t($definition['default']); + } + else { + $storage[$option] = isset($definition['default']) ? $definition['default'] : NULL; + } + } + } + + /** + * Unpack options over our existing defaults, drilling down into arrays + * so that defaults don't get totally blown away. + */ + function unpack_options(&$storage, $options, $definition = NULL, $all = TRUE, $check = TRUE, $localization_keys = array()) { + if ($check && !is_array($options)) { + return; + } + + if (!isset($definition)) { + $definition = $this->option_definition(); + } + + if (!empty($this->view)) { + // Ensure we have a localization plugin. + $this->view->init_localization(); + } + + foreach ($options as $key => $value) { + if (is_array($value)) { + // Ignore arrays with no definition. + if (!$all && empty($definition[$key])) { + continue; + } + + if (!isset($storage[$key]) || !is_array($storage[$key])) { + $storage[$key] = array(); + } + + // If we're just unpacking our known options, and we're dropping an + // unknown array (as might happen for a dependent plugin fields) go + // ahead and drop that in. + if (!$all && isset($definition[$key]) && !isset($definition[$key]['contains'])) { + $storage[$key] = $value; + continue; + } + + $this->unpack_options($storage[$key], $value, isset($definition[$key]['contains']) ? $definition[$key]['contains'] : array(), $all, FALSE); + } + elseif (!empty($definition[$key]['translatable']) && !empty($value)) { + $storage[$key] = t($value); + $this->unpack_options($storage[$key], array(), isset($definition[$key]['contains']) ? $definition[$key]['contains'] : array(), $all, FALSE, array_merge($localization_keys, array($key))); + } + // Don't localize strings during editing. When editing, we need to work with + // the original data, not the translated version. + else if (empty($this->view->editing) && !empty($definition[$key]['translatable']) && !empty($value) || !empty($definition['contains'][$key]['translatable']) && !empty($value)) { + if (!empty($this->view) && $this->view->is_translatable()) { + // Allow other modules to make changes to the string before it's + // sent for translation. + // The $keys array is built from the view name, any localization keys + // sent in, and the name of the property being processed. + $translation_data = array( + 'value' => $value, + 'format' => isset($options[$key . '_format']) ? $options[$key . '_format'] : NULL, + 'keys' => array_merge(array($this->view->name), $localization_keys, array($key)), + ); + $storage[$key] = $this->view->localization_plugin->translate($translation_data); + } + // Otherwise, this is a code-based string, so we can use t(). + else { + $storage[$key] = t($value); + } + } + else if ($all || !empty($definition[$key])) { + $storage[$key] = $value; + } + } + } + + /** + * Let the handler know what its full definition is. + */ + function set_definition($definition) { + $this->definition = $definition; + if (isset($definition['field'])) { + $this->real_field = $definition['field']; + } + } + + function destroy() { + if (isset($this->view)) { + unset($this->view); + } + + if (isset($this->display)) { + unset($this->display); + } + + if (isset($this->query)) { + unset($this->query); + } + } + + function export_options($indent, $prefix) { + $output = ''; + foreach ($this->option_definition() as $option => $definition) { + $output .= $this->export_option($indent, $prefix, $this->options, $option, $definition, array()); + } + + return $output; + } + + function export_option($indent, $prefix, $storage, $option, $definition, $parents) { + // Do not export options for which we have no settings. + if (!isset($storage[$option])) { + return; + } + + if (isset($definition['export'])) { + if ($definition['export'] === FALSE) { + return; + } + + // Special handling for some items + if (method_exists($this, $definition['export'])) { + return $this->{$definition['export']}($indent, $prefix, $storage, $option, $definition, $parents); + } + } + + // Add the current option to the parents tree. + $parents[] = $option; + $output = ''; + + // If it has child items, export those separately. + if (isset($definition['contains'])) { + foreach ($definition['contains'] as $sub_option => $sub_definition) { + $output .= $this->export_option($indent, $prefix, $storage[$option], $sub_option, $sub_definition, $parents); + } + } + // Otherwise export just this item. + else { + $default = isset($definition['default']) ? $definition['default'] : NULL; + $value = $storage[$option]; + if (isset($definition['bool'])) { + $value = (bool) $value; + } + + if ($value !== $default) { + $output .= $indent . $prefix . "['" . implode("']['", $parents) . "'] = "; + if (isset($definition['bool'])) { + $output .= empty($storage[$option]) ? 'FALSE' : 'TRUE'; + } + else { + $output .= views_var_export($storage[$option], $indent); + } + + $output .= ";\n"; + } + } + return $output; + } + + /** + * Unpacks each handler to store translatable texts. + */ + function unpack_translatables(&$translatable, $parents = array()) { + foreach ($this->option_definition() as $option => $definition) { + $this->unpack_translatable($translatable, $this->options, $option, $definition, $parents, array()); + } + } + + /** + * Unpack a single option definition. + * + * This function run's through all suboptions recursive. + * + * @param $translatable + * Stores all availible translatable items. + * @param $storage + * @param $option + * @param $definition + * @param $parents + * @param $keys + */ + function unpack_translatable(&$translatable, $storage, $option, $definition, $parents, $keys = array()) { + // Do not export options for which we have no settings. + if (!isset($storage[$option])) { + return; + } + + // Special handling for some items + if (isset($definition['unpack_translatable']) && method_exists($this, $definition['unpack_translatable'])) { + return $this->{$definition['unpack_translatable']}($translatable, $storage, $option, $definition, $parents, $keys); + } + + if (isset($definition['translatable'])) { + if ($definition['translatable'] === FALSE) { + return; + } + } + + // Add the current option to the parents tree. + $parents[] = $option; + + // If it has child items, unpack those separately. + if (isset($definition['contains'])) { + foreach ($definition['contains'] as $sub_option => $sub_definition) { + $translation_keys = array_merge($keys, array($sub_option)); + $this->unpack_translatable($translatable, $storage[$option], $sub_option, $sub_definition, $parents, $translation_keys); + } + } + + // @todo Figure out this double definition stuff. + $options = $storage[$option]; + if (is_array($options)) { + foreach ($options as $key => $value) { + $translation_keys = array_merge($keys, array($key)); + if (is_array($value)) { + $this->unpack_translatable($translatable, $storage, $key, $definition, $parents, $translation_keys); + } + else if (!empty($definition[$key]['translatable']) && !empty($value)) { + // Build source data and add to the array + $translatable[] = array( + 'value' => $value, + 'keys' => $translation_keys, + 'format' => isset($options[$key . '_format']) ? $options[$key . '_format'] : NULL, + ); + } + } + } + else if (!empty($definition['translatable']) && !empty($options)) { + $value = $options; + // Build source data and add to the array + $translatable[] = array( + 'value' => $value, + 'keys' => isset($translation_keys) ? $translation_keys : $parents, + ); + } + } +} diff --git a/sites/all/modules/views/includes/cache.inc b/sites/all/modules/views/includes/cache.inc new file mode 100644 index 0000000000000000000000000000000000000000..de438888bd1d11d6c364ba9e1750ba1cffaf11f7 --- /dev/null +++ b/sites/all/modules/views/includes/cache.inc @@ -0,0 +1,201 @@ +<?php +// $Id: cache.inc,v 1.25.4.8 2010/10/26 19:06:26 dereine Exp $ +/** + * @file cache.inc + * + * Functions to load Views' data so that it knows what is available to + * build queries from. + */ + +/** + * Load views files on behalf of modules. + */ +function _views_include_handlers() { + views_module_include('views.inc'); +} + +/** + * Load default views files on behalf of modules. + */ +function _views_include_default_views() { + views_module_include('views_default.inc'); +} + +/** + * Fetch Views' data from the cache + */ +function _views_fetch_data($table = NULL, $reset = FALSE) { + static $cache = NULL; + if (!isset($cache) || $reset) { + $start = microtime(TRUE); + // NOTE: This happens whether we retrieve them from cache or otherwise. + + $data = views_cache_get('views_data', TRUE); + if (!empty($data->data)) { + $cache = $data->data; + } + + if (empty($cache)) { + views_include_handlers(); + $cache = module_invoke_all('views_data'); + foreach (module_implements('views_data_alter') as $module) { + $function = $module . '_views_data_alter'; + $function($cache); + } + + views_cache_set('views_data', $cache, TRUE); + } + } + + if (!$table) { + return $cache; + } + if (isset($cache[$table])) { + return $cache[$table]; + } + + // Return an empty array if there is no match. + return array(); +} + +/** + * Fetch the plugin data from cache. + */ +function _views_fetch_plugin_data($type = NULL, $plugin = NULL, $reset = FALSE) { + static $cache = NULL; + if (!isset($cache) || $reset) { + $start = microtime(TRUE); + views_include('plugins'); + views_include_handlers(); + + $cache = views_discover_plugins(); + + } + + if (!$type && !$plugin) { + return $cache; + } + elseif (!$plugin) { + // Not in the if above so the else below won't run + if (isset($cache[$type])) { + return $cache[$type]; + } + } + elseif (isset($cache[$type][$plugin])) { + return $cache[$type][$plugin]; + } + + // Return an empty array if there is no match. + return array(); +} + +/** + * Scan all modules for default views and rebuild the default views cache. + * + * @return An associative array of all known default views. + */ +function _views_discover_default_views($reset = FALSE) { + static $cache = NULL; + + if (!isset($cache) || $reset) { + $index = views_cache_get('views_default_views_index', TRUE); + + // Retrieve each cached default view + if (!$reset && isset($index->data) && is_array($index->data)) { + $cache = array(); + foreach ($index->data as $view_name) { + $data = views_cache_get('views_default:' . $view_name, TRUE); + if (isset($data->data) && is_object($data->data)) { + $cache[$view_name] = $data->data; + } + } + } + // If missing index, rebuild the cache + else { + views_include_default_views(); + $cache = array(); + + foreach (module_implements('views_default_views') as $module) { + $results = call_user_func($module . "_views_default_views"); + if (!empty($results) && is_array($results)) { + foreach($results as $name => $view) { + // Only views with a sufficiently high api version are eligible. + if (!empty($view->api_version) && $view->api_version >= 2) { + // Do not cache dead handlers. + $view->destroy(); + if (!isset($cache[$name])) { + $cache[$name] = $view; + } + else { + watchdog('view', "View name '@name' is already taken", array('@name' => $name), WATCHDOG_ERROR); + } + } + } + } + } + + // Allow modules to modify default views before they are cached. + drupal_alter('views_default_views', $cache); + + // Cache the index + $index = array_keys($cache); + views_cache_set('views_default_views_index', $index, TRUE); + + // Cache each view + foreach ($cache as $name => $view) { + views_cache_set('views_default:' . $name, $view, TRUE); + } + } + } + + return $cache; +} + +/** + * Set a cached item in the views cache. + * + * This is just a convenience wrapper around cache_set(). + * + * @param $cid + * The cache ID of the data to store. + * @param $data + * The data to store in the cache. Complex data types will be automatically serialized before insertion. + * Strings will be stored as plain text and not serialized. + * @param $use_language + * If TRUE, the data will be cached specific to the currently active language. + */ +function views_cache_set($cid, $data, $use_language = FALSE) { + global $language; + + if (variable_get('views_skip_cache', FALSE)) { + return; + } + if ($use_language) { + $cid .= ':' . $language->language; + } + + cache_set($cid, $data, 'cache_views'); +} + +/** + * Return data from the persistent views cache. + * + * This is just a convenience wrapper around cache_get(). + * + * @param $cid + * The cache ID of the data to retrieve. + * @param $use_language + * If TRUE, the data will be requested specific to the currently active language. + */ +function views_cache_get($cid, $use_language = FALSE) { + global $language; + + if (variable_get('views_skip_cache', FALSE)) { + return 0; + } + if ($use_language) { + $cid .= ':' . $language->language; + } + + return cache_get($cid, 'cache_views'); +} diff --git a/sites/all/modules/views/includes/convert.inc b/sites/all/modules/views/includes/convert.inc new file mode 100644 index 0000000000000000000000000000000000000000..0cc58f39d7ca07c7c2427b53a0d4bb8711341cb5 --- /dev/null +++ b/sites/all/modules/views/includes/convert.inc @@ -0,0 +1,552 @@ +<?php +// $Id: convert.inc,v 1.17.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ +/** + * @file convert.inc + * + * Contains forms and routines to convert older views to newer views. + */ + +/** + * Page callback for the tools - Views 1 convert page + */ +function views_ui_admin_convert() { + if (!db_table_exists('view_view')) { + return t('There are no Views 1 views stored in the database to convert.'); + } + $items = array(); + $sorts = array(); + + $header = array( + array('data' => t('View name'), 'field' => 'name', 'sort' => 'asc'), + array('data' => t('Description')), + array('data' => t('Operations')), + ); + $current_views = views_get_all_views(); + + $result = db_query("SELECT v.* FROM {view_view} v"); + foreach ($result as $view) { + $ops = array(); + if (!isset($current_views[$view->name])) { + $ops[] = l(t('Convert'), "admin/structure/views1/convert/$view->name"); + } + else { + $ops[] = t('Converted'); + } + $ops[] = l(t('Delete'), "admin/structure/views1/delete/$view->name"); + + $item = array(); + $item[] = check_plain($view->name); + $item[] = check_plain($view->description); + $item[] = implode(' | ', $ops); + $items[] = $item; + + $ts = tablesort_init($header); + switch ($ts['sql']) { + case 'name': + default: + $sorts[] = $item[0]; + break; + case 'title': + $sorts[] = $item[1]; + break; + } + } + + if (!empty($ts)) { + if (strtolower($ts['sort']) == 'desc') { + arsort($sorts); + } + else { + asort($sorts); + } + } + + $i = array(); + foreach ($sorts as $id => $title) { + $i[] = $items[$id]; + } + $output = t('The table below lists Views version 1 views that are stored in the database. You can either convert them to work in Views version 2, or delete them. The views are convertible only if there is no Views 2 view with the same name.'); + $output .= theme('table', array('header' => $header, 'rows' => $i)); + + $output .= drupal_get_form('views_ui_convert_cleanup_form'); + return $output; +} + +/** + * Provide form to clean up Views 1 tables. + */ +function views_ui_convert_cleanup_form() { + $form['verify'] = array( + '#type' => 'checkbox', + '#title' => t('Remove all Views 1 tables'), + '#description' => t('Check this box and then click clean up to drop all Views 1 tables. Warning: this operation will not be reversible! Do this only if you are sure you no longer need this data.'), + '#required' => TRUE, + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Clean up'), + ); + + return $form; +} + +function views_ui_convert_cleanup_form_submit($form, $form_state) { + if (empty($form_state['values']['verify'])) { + drupal_set_message('Please check the box to verify you want to destroy your Views 1 table data.'); + return; + } + + $ret = array(); + if (db_table_exists('view_view')) { + db_drop_table($ret, 'view_view'); + } + if (db_table_exists('view_sort')) { + db_drop_table($ret, 'view_sort'); + } + if (db_table_exists('view_argument')) { + db_drop_table($ret, 'view_argument'); + } + if (db_table_exists('view_tablefield')) { + db_drop_table($ret, 'view_tablefield'); + } + if (db_table_exists('view_filter')) { + db_drop_table($ret, 'view_filter'); + } + if (db_table_exists('view_exposed_filter')) { + db_drop_table($ret, 'view_exposed_filter'); + } + + drupal_set_message(t('All Views 1 tables have been removed.')); +} + +/** + * Page callback for the tools - Views 1 convert page + */ +function views_ui_convert1($name) { + $old = views1_load($name); + if (!$old) { + return t('Unable to find view.'); + } + + $view = views1_import($old); + + if ($view) { + views_ui_cache_set($view); + drupal_goto('admin/structure/views/edit/' . $view->name); + } + else { + return t('Unable to convert view.'); + } +} + +/** + * Page to delete a Views 1 view. + */ +function views_ui_delete1_confirm($form, &$form_state, $vid) { + $form_state['vid'] = $vid; + $form = array(); + + $cancel = 'admin/structure/views/tools/convert'; + if (!empty($_REQUEST['cancel'])) { + $cancel = $_REQUEST['cancel']; + } + return confirm_form($form, + t('Are you sure you want to delete the view %name?', array('%name' => $view->name)), + $cancel, + t('This action cannot be undone.'), + t('Delete'), + t('Cancel')); +} + +/** + * Submit handler to delete a view. + */ +function views_ui_delete1_confirm_submit(&$form, &$form_state) { + views1_delete($form_state['vid']); + drupal_set_message(t('The view has been deleted')); + $form_state['redirect'] = 'admin/structure/views/tools/convert'; +} + +/** + * Convert a Views 1 view to a Views 2 view. + */ +function views1_import($imported) { + $view = views_new_view(); + + $view->name = $imported->name; + $view->description = $imported->description; + + if (!empty($imported->page) && !empty($imported->url)) { + $page_display = $view->add_display('page'); + } + if (!empty($imported->block)) { + $block_display = $view->add_display('block'); + } + $view->init_display(); + + $handler = &$view->display['default']->handler; + $handler->set_option('title', $imported->page_title); + $handler->set_option('header', $imported->page_header); + $handler->set_option('header_format', $imported->page_header_format); + $handler->set_option('footer', $imported->page_footer); + $handler->set_option('footer_format', $imported->page_footer_format); + $handler->set_option('empty', $imported->page_empty); + $handler->set_option('empty_format', $imported->page_empty_format); + + $handler->set_option('use_pager', $imported->use_pager); + $handler->set_option('items_per_page', $imported->nodes_per_page); + $handler->set_option('pager_element', 0); + $handler->set_option('offset', 0); + + $access = array('type' => 'none', 'role' => array(), 'perm' => ''); + if ($imported->access) { + $access['type'] = 'role'; + $access['role'] = drupal_map_assoc($imported->access); + } + + $handler->set_option('access', $access); + if (!empty($imported->page) && !empty($imported->url)) { + $handler = &$view->display[$page_display]->handler; + $url = str_replace('$arg', '%', $imported->url); + $handler->set_option('path', $url); + if ($imported->menu) { + $menu = array('type' => 'normal'); + if ($imported->menu_tab) { + $menu['type'] = 'tab'; + } + if ($imported->menu_tab_default) { + $menu['type'] = 'default tab'; + } + $menu['title'] = $imported->menu_title ? $imported->menu_title : $imported->page_title; + $handler->set_option('menu', $menu); + + if ($menu['type'] == 'default tab') { + $tab_options = array('type' => 'none'); + switch ($imported->menu_tab_default_parent_type) { + case 'tab': + case 'normal': + $tab_options['type'] = $imported->menu_tab_default_parent_type; + break; + } + } + $tab_options['title'] = $imported->menu_parent_title; + $tab_options['weight'] = $imported->menu_parent_tab_weight; + $handler->set_option('tab_options', $tab_options); + } + } + + views1_convert_style($view, $handler, $imported->page_type); + + if (!empty($imported->block)) { + $handler = &$view->display[$block_display]->handler; + + if (!empty($imported->block_title)) { + if (!empty($imported->page)) { + $handler->set_override('title'); + } + $handler->set_option('title', $imported->block_title); + } + + if (!empty($imported->page)) { + $handler->set_override('use_pager'); + } + $handler->set_option('use_pager', FALSE); + + if ($imported->nodes_per_block != $imported->nodes_per_page) { + $handler->set_option('items_per_page', $imported->nodes_per_block); + $handler->set_option('offset', 0); + } + + if (empty($imported->block_use_page_header)) { + if (!empty($imported->page)) { + $handler->set_override('header'); + } + if (!empty($imported->block_header)) { + $handler->set_option('header', $imported->block_header); + $handler->set_option('header_format', $imported->block_header_format); + } + } + if (empty($imported->block_use_page_footer)) { + if (!empty($imported->page)) { + $handler->set_override('footer'); + } + if (!empty($imported->block_footer)) { + $handler->set_option('footer', $imported->block_footer); + $handler->set_option('footer_format', $imported->block_footer_format); + } + } + if (empty($imported->block_use_page_empty)) { + if (!empty($imported->page)) { + $handler->set_override('empty'); + } + if (!empty($imported->block_empty)) { + $handler->set_option('empty', $imported->block_empty); + $handler->set_option('empty_format', $imported->block_empty_format); + } + } + + $handler->set_option('use_more', $imported->block_more); + + if (!empty($imported->page)) { + $handler->set_override('style_plugin'); + } + views1_convert_style($view, $handler, $imported->block_type); + } + + // For each of the fields, arguments, filters, and sorts in the old view, + // check if a handler for this item exists in Views 2 and add it, + // then see if any other modules want to adapt it using hook_views_convert(). + + foreach ($imported->field as $field) { + $id = $view->add_item('default', 'field', $field['tablename'], $field['field'], array('label' => $field['label'])); + if ($view->display_handler->get_option('style_plugin') == 'table') { + $options = $view->display_handler->get_option('style_options'); + if (!empty($field['sortable'])) { + $options['info'][$id]['sortable'] = TRUE; + if (!empty($field['defaultsort'])) { + $options['default'] = $id; + } + } + $view->display_handler->set_option('style_options', $options); + } + foreach (module_implements('views_convert') as $module) { + module_invoke($module, 'views_convert', 'default', 'field', $view, $field, $id); + } + } + foreach ($imported->sort as $field) { + $id = $view->add_item('default', 'sort', $field['tablename'], $field['field'], array('order' => $field['sortorder'])); + foreach (module_implements('views_convert') as $module) { + module_invoke($module, 'views_convert', 'default', 'sort', $view, $field, $id); + } + } + $actions = array('ignore', 'not found', 'ignore', 'summary asc', 'summary asc', 'summary desc', 'summary asc', 'empty'); + foreach ($imported->argument as $id => $field) { + if (!empty($imported->view_args_php)) { + $field['argoptions']['default_action'] = 'default'; + $field['argoptions']['default_argument_type'] = 'php'; + $field['argoptions']['default_argument_php'] = '$args = eval(\''. str_replace("'", "\\'", $imported->view_args_php) .'\');'."\n"; + $field['argoptions']['default_argument_php'] .= 'if (isset($args['. $field['position'] .'])) {'."\n"; + $field['argoptions']['default_argument_php'] .= ' return $args['. $field['position'] .'];'."\n"; + $field['argoptions']['default_argument_php'] .= '}'; + $field['argoptions']['validate_fail'] = $actions[$field['argdefault']]; + } + else { + $field['argoptions']['default_action'] = $actions[$field['argdefault']]; + } + if (!empty($field['title'])) { + $field['argoptions']['title'] = $field['title']; + } + if (!empty($field['wildcard'])) { + $field['argoptions']['wildcard'] = $field['wildcard']; + } + if (!empty($field['wildcard_substitution'])) { + $field['argoptions']['wildcard_substitution'] = $field['wildcard_substitution']; + } + // Arguments didn't used to be identified by table.name so we just have to + // leave that out. + foreach (module_implements('views_convert') as $module) { + module_invoke($module, 'views_convert', 'default', 'argument', $view, $field, NULL); + } + } + foreach ($imported->filter as $field) { + $options = $field['value'] == '' ? array() : array('value' => $field['value']); + $id = $view->add_item('default', 'filter', $field['tablename'], $field['field'], $options); + foreach (module_implements('views_convert') as $module) { + module_invoke($module, 'views_convert', 'default', 'filter', $view, $field, $id); + } + } + // Exposed filters now get added to the filter array, not as a separate array. + $count = 0; + foreach ($imported->exposed_filter as $field) { + list(, $id) = explode('.', $field['field'], 2); + $item = $view->get_item('default', 'filter', $id); + if (views_get_handler($item['table'], $item['field'], 'filter')) { + $item['exposed'] = TRUE; + + // Use the count to emulate the old, hardcoded filter naming. + $item['expose']['identifier'] = 'filter' . $count; + $item['expose']['label'] = $field['label']; + $item['expose']['operator'] = $field['operator'] ? 'op' . $count : ''; + $item['expose']['optional'] = $field['optional']; + $item['expose']['single'] = $field['single']; + $view->set_item('default', 'filter', $id, $item); + } + $count++; + foreach (module_implements('views_convert') as $module) { + module_invoke($module, 'views_convert', 'default', 'exposed_filter', $view, $field, $id); + } + } + + return $view; +} + +function views1_convert_style(&$view, &$handler, $type) { + switch ($type) { + case 'list': + $handler->set_option('style_plugin', 'list'); + $handler->set_option('style_options', array('type' => 'ul')); + $handler->set_option('row_plugin', 'fields'); + break; + case 'node': + $handler->set_option('row_plugin', 'node'); + $handler->set_option('row_options', array('teaser' => FALSE, 'links' => TRUE)); + break; + case 'teaser': + $handler->set_option('row_plugin', 'node'); + $handler->set_option('row_options', array('teaser' => TRUE, 'links' => TRUE)); + break; + case 'table': + $options = array(); + $options['columns'] = array(); + $options['default'] = ''; + $options['info'] = array(); + $options['override'] = FALSE; + $options['order'] = 'asc'; + + $handler->set_option('style_plugin', 'table'); + $handler->set_option('style_options', $options); + break; + default: + // Ask around if anybody else knows. + foreach (module_implements('views_convert') as $module) { + module_invoke($module, 'views_convert', $handler->display->id, 'style', $view, $type); + } + } +} +/** + * Load a version 1 view from the database. + * + */ +function views1_load($arg) { + static $cache = array(); + $which = is_numeric($arg) ? 'vid' : 'name'; + if (isset($cache[$which][$arg])) { + return $cache[$which][$arg]; + } + + $where = (is_numeric($arg) ? "v.vid = %d" : "v.name = '%s'"); + $view = db_fetch_object(db_query("SELECT v.* FROM {view_view} v WHERE $where", $arg)); + + if (!$view->name) { + return NULL; + } + + $view->access = ($view->access ? explode(', ', $view->access) : array()); + + // load the sorting criteria too. + $result = db_query("SELECT * FROM {view_sort} vs WHERE vid = $view->vid ORDER BY position ASC"); + + $view->sort = array(); + while ($sort = db_fetch_array($result)) { + if (substr($sort['field'], 0, 2) == 'n.') { + $sort['field'] = 'node' . substr($sort['field'], 1); + } + $sort['id'] = $sort['field']; + $bits = explode('.', $sort['field']); + $sort['tablename'] = $bits[0]; + $sort['field'] = $bits[1]; + $view->sort[$sort['position']] = $sort; + } + + $result = db_query("SELECT * FROM {view_argument} WHERE vid = $view->vid ORDER BY position ASC"); + + $view->argument = array(); + while ($arg = db_fetch_array($result)) { + $arg['id'] = $arg['type']; + $view->argument[$arg['position']] = $arg; + } + + $result = db_query("SELECT * FROM {view_tablefield} WHERE vid = $view->vid ORDER BY position ASC"); + + $view->field = array(); + while ($arg = db_fetch_array($result)) { + if ($arg['tablename'] == 'n') { + $arg['tablename'] = 'node'; + } + $arg['id'] = $arg['fullname'] = "$arg[tablename].$arg[field]"; + $arg['queryname'] = "$arg[tablename]_$arg[field]"; + $view->field[] = $arg; + } + + $result = db_query("SELECT * FROM {view_filter} WHERE vid = $view->vid ORDER BY position ASC"); + + // TODO - Is it safe to ignore this $filters variable? This function depends + // on lots of additional code needed to call hook_implements and construct + // all the views tables, so using it will add a lot of code to this file. + //$filters = _views_get_filters(); + $view->filter = array(); + while ($filter = db_fetch_array($result)) { + if (substr($filter['field'], 0, 2) == 'n.') { + $filter['field'] = 'node' . substr($filter['field'], 1); + } + + if ($filter['operator'] == 'AND' || + $filter['operator'] == 'OR' || + $filter['operator'] == 'NOR') { + // TODO - need another way to identify this type of filter + // without being able to call hook_implements(). + //|| $filters[$filter['field']]['value-type'] == 'array' ) { + if ($filter['value'] !== NULL && $filter['value'] !== '') { + $filter['value'] = explode(',', $filter['value']); + } + else { + $filter['value'] = array(); + } + } + $filter['id'] = $filter['field']; + $bits = explode('.', $filter['field']); + $filter['tablename'] = $bits[0]; + $filter['field'] = $bits[1]; + $view->filter[$filter['position']] = $filter; + } + + $result = db_query("SELECT * FROM {view_exposed_filter} WHERE vid = $view->vid ORDER BY position ASC"); + + $view->exposed_filter = array(); + while ($arg = db_fetch_array($result)) { + $arg['id'] = $arg['field']; + $view->exposed_filter[] = $arg; + } + + $cache['vid'][$view->vid] = $view; + $cache['name'][$view->name] = $view; + + return $view; +} + +/** + * Delete a version 1 view from the database. + * + */ +function views1_delete($arg) { + static $cache = array(); + $where = (is_numeric($arg) ? "v.vid = %d" : "v.name = '%s'"); + $view = db_fetch_object(db_query("SELECT v.* FROM {view_view} v WHERE $where", $arg)); + + if (!$view->name) { + return NULL; + } + + + + db_delete('view_sort') + ->condition('vid', $view->vid) + ->execute(); + db_delete('view_argument') + ->condition('vid', $view->vid) + ->execute(); + db_delete('view_tablefield') + ->condition('vid', $view->vid) + ->execute(); + db_delete('view_filter') + ->condition('vid', $view->vid) + ->execute(); + db_delete('view_exposed_filter') + ->condition('vid', $view->vid) + ->execute(); + db_delete('view_view') + ->condition('vid', $view->vid) + ->execute(); +} + diff --git a/sites/all/modules/views/includes/form.inc b/sites/all/modules/views/includes/form.inc new file mode 100644 index 0000000000000000000000000000000000000000..5517f1fbe8db1af88f01a23840e2fbe5feb77e65 --- /dev/null +++ b/sites/all/modules/views/includes/form.inc @@ -0,0 +1,8 @@ +<?php +// $Id: form.inc,v 1.11.4.3 2010/04/12 21:59:58 dereine Exp $ + +/** + * @file form.inc + * Views' replacements for Drupal's form functions. + * + */ diff --git a/sites/all/modules/views/includes/handlers.inc b/sites/all/modules/views/includes/handlers.inc new file mode 100644 index 0000000000000000000000000000000000000000..fe8acea17e9d7b7ddc73e772901329a9f3bdf3ce --- /dev/null +++ b/sites/all/modules/views/includes/handlers.inc @@ -0,0 +1,1380 @@ +<?php +// $Id: handlers.inc,v 1.119.4.22 2011/01/05 22:40:08 dereine Exp $ +/** + * @file handlers.inc + * Defines the various handler objects to help build and display views. + */ + +/** + * Instantiate and construct a new handler + */ +function _views_create_handler($definition, $type = 'handler') { +// debug('Instantiating handler ' . $definition['handler']); + if (empty($definition['handler'])) { + return; + } + + // class_exists will automatically load the code file. + if (!empty($definition['override handler']) && + !class_exists($definition['override handler'])) { + return; + } + + if (!class_exists($definition['handler'])) { + return; + } + + if (!empty($definition['override handler'])) { + $handler = new $definition['override handler']; + } + else { + $handler = new $definition['handler']; + } + + $handler->set_definition($definition); + // let the handler have something like a constructor. + $handler->construct(); + + return $handler; +} + +/** + * Prepare a handler's data by checking defaults and such. + */ +function _views_prepare_handler($definition, $data, $field) { + foreach (array('group', 'title', 'title short', 'help', 'real field') as $key) { + if (!isset($definition[$key])) { + // First check the field level + if (!empty($data[$field][$key])) { + $definition[$key] = $data[$field][$key]; + } + // Then if that doesn't work, check the table level + elseif (!empty($data['table'][$key])) { + $definition[$key] = $data['table'][$key]; + } + } + } + + return _views_create_handler($definition); +} + +/** + * Fetch a handler to join one table to a primary table from the data cache + */ +function views_get_table_join($table, $base_table) { + $data = views_fetch_data($table); + if (isset($data['table']['join'][$base_table])) { + $h = $data['table']['join'][$base_table]; + if (!empty($h['handler']) && class_exists($h['handler'])) { + $handler = new $h['handler']; + } + else { + $handler = new views_join(); + } + + // Fill in some easy defaults + $handler->definition = $h; + if (empty($handler->definition['table'])) { + $handler->definition['table'] = $table; + } + // If this is empty, it's a direct link. + if (empty($handler->definition['left_table'])) { + $handler->definition['left_table'] = $base_table; + } + + if (isset($h['arguments'])) { + call_user_func_array(array(&$handler, 'construct'), $h['arguments']); + } + else { + $handler->construct(); + } + + return $handler; + } + // DEBUG -- identify missing handlers + vpr("Missing join: $table $base_table"); +} + +/** + * Base handler, from which all the other handlers are derived. + * It creates a common interface to create consistency amongst + * handlers and data. + * + * This class would be abstract in PHP5, but PHP4 doesn't understand that. + * + * Definition terms: + * - table: The actual table this uses; only specify if different from + * the table this is attached to. + * - real field: The actual field this uses; only specify if different from + * the field this item is attached to. + * - group: A text string representing the 'group' this item is attached to, + * for display in the UI. Examples: "Node", "Taxonomy", "Comment", + * "User", etc. This may be inherited from the parent definition or + * the 'table' definition. + * - title: The title for this handler in the UI. This may be inherited from + * the parent definition or the 'table' definition. + * - help: A more informative string to give to the user to explain what this + * field/handler is or does. + * - access callback: If this field should have access control, this could + * be a function to use. 'user_access' is a common + * function to use here. If not specified, no access + * control is provided. + * - access arguments: An array of arguments for the access callback. + */ +class views_handler extends views_object { + /** + * init the handler with necessary data. + * @param $view + * The $view object this handler is attached to. + * @param $options + * The item from the database; the actual contents of this will vary + * based upon the type of handler. + */ + function init(&$view, &$options) { + $this->view = &$view; + $this->unpack_options($this->options, $options); + + // This exist on most handlers, but not all. So they are still optional. + if (isset($options['table'])) { + $this->table = $options['table']; + } + + if (isset($this->definition['real field'])) { + $this->real_field = $this->definition['real field']; + } + + if (isset($this->definition['field'])) { + $this->real_field = $this->definition['field']; + } + + if (isset($options['field'])) { + $this->field = $options['field']; + if (!isset($this->real_field)) { + $this->real_field = $options['field']; + } + } + + $this->query = &$view->query; + } + + function option_definition() { + $options = parent::option_definition(); + + $options['id'] = array('default' => ''); + $options['table'] = array('default' => ''); + $options['field'] = array('default' => ''); + $options['relationship'] = array('default' => 'none'); + $options['group_type'] = array('default' => 'group'); + $options['ui_name'] = array('default' => ''); + + return $options; + } + + /** + * Return a string representing this handler's name in the UI. + */ + function ui_name($short = FALSE) { + if (!empty($this->options['ui_name'])) { + $title = check_plain($this->options['ui_name']); + return $title; + } + $title = ($short && isset($this->definition['title short'])) ? $this->definition['title short'] : $this->definition['title']; + return t('!group: !title', array('!group' => $this->definition['group'], '!title' => $title)); + } + + /** + * Shortcut to get a handler's raw field value. + * + * This should be overridden for handlers with formulae or other + * non-standard fields. Because this takes an argument, fields + * overriding this can just call return parent::get_field($formula) + */ + function get_field($field = NULL) { + if (!isset($field)) { + if (!empty($this->formula)) { + $field = $this->get_formula(); + } + else { + $field = $this->table_alias . '.' . $this->real_field; + } + } + + // If grouping, check to see if the aggregation method needs to modify the field. + if ($this->view->display_handler->use_group_by()) { + $info = $this->query->get_aggregation_info(); + if (!empty($info[$this->options['group_type']]['method']) && function_exists($info[$this->options['group_type']]['method'])) { + return $info[$this->options['group_type']]['method']($this->options['group_type'], $field); + } + } + + return $field; + } + + /** + * Validate the options form. + */ + function options_validate(&$form, &$form_state) { } + + function options_form(&$form, &$form_state) { + $form['ui_name'] = array( + '#type' => 'textfield', + '#title' => t('Administrative Title'), + '#description' => t('This title will be displayed on the views edit page instead of the default one. This might be useful if you have the same item twice.'), + '#default_value' => $this->options['ui_name'], + ); + } + + /** + * 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) { } + + /** + * Provide a form for groupby settings. + */ + function groupby_form(&$form, &$form_state) { + $view = &$form_state['view']; + $display_id = $form_state['display_id']; + $types = views_object_types(); + $type = $form_state['type']; + $id = $form_state['id']; + + $form['#title'] = check_plain($view->display[$display_id]->display_title) . ': '; + $form['#title'] .= t('Configure group settings for @type %item', array('@type' => $types[$type]['lstitle'], '%item' => $this->ui_name())); + + $form['#section'] = $display_id . '-' . $type . '-' . $id; + + $info = $view->query->get_aggregation_info(); + foreach ($info as $id => $aggregate) { + $group_types[$id] = $aggregate['title']; + } + + $form['group_type'] = array( + '#type' => 'select', + '#title' => t('Group type'), + '#default_value' => $this->options['group_type'], + '#description' => t('Select the grouping function to use on this field.'), + '#options' => $group_types, + ); + } + + /** + * Perform any necessary changes to the form values prior to storage. + * There is no need for this function to actually store the data. + */ + function groupby_form_submit(&$form, &$form_state) { + $item =& $form_state['handler']->options; + + $item['group_type'] = $form_state['values']['group_type']; + } + + /** + * If a handler has 'extra options' it will get a little settings widget and + * another form called extra_options. + */ + function has_extra_options() { return FALSE; } + + /** + * Provide defaults for the handler. + */ + function extra_options(&$option) { } + + /** + * Provide a form for setting options. + */ + function extra_options_form(&$form, &$form_state) { } + + /** + * Validate the options form. + */ + function extra_options_validate($form, &$form_state) { } + + /** + * Perform any necessary changes to the form values prior to storage. + * There is no need for this function to actually store the data. + */ + function extra_options_submit($form, &$form_state) { } + + /** + * Determine if a handler can be exposed. + */ + function can_expose() { return FALSE; } + + /** + * Set new exposed option defaults when exposed setting is flipped + * on. + */ + function expose_options() { } + + /** + * Get information about the exposed form for the form renderer. + */ + function exposed_info() { } + + /** + * Render our chunk of the exposed handler form when selecting + */ + function exposed_form(&$form, &$form_state) { } + + /** + * Validate the exposed handler form + */ + function exposed_validate(&$form, &$form_state) { } + + /** + * Submit the exposed handler form + */ + function exposed_submit(&$form, &$form_state) { } + + /** + * Overridable form for exposed handler options. + * + * If overridden, it is best to call the parent or re-implement + * the stuff here. + * + * Many handlers will need to override this in order to provide options + * that are nicely tailored to the given filter. + */ + function expose_form(&$form, &$form_state) { + $form['expose']['start_left'] = array( + '#markup' => '<div class="views-left-50">', + ); + + $this->expose_form_left($form, $form_state); + + $form['expose']['end_left'] = array( + '#markup' => '</div>', + ); + + $form['expose']['start_checkboxes'] = array( + '#markup' => '<div class="form-checkboxes views-left-40 clearfix">', + ); + + $this->expose_form_right($form, $form_state); + + $form['expose']['end_checkboxes'] = array( + '#markup' => '</div>', + ); + } + + function expose_form_left(&$form, &$form_state) { } + + function expose_form_right(&$form, &$form_state){ } + + /** + * Validate the options form. + */ + function expose_validate($form, &$form_state) { } + + /** + * Perform any necessary changes to the form exposes prior to storage. + * There is no need for this function to actually store the data. + */ + function expose_submit($form, &$form_state) { } + + /** + * Shortcut to display the expose/hide button. + */ + function show_expose_button(&$form, &$form_state) { + $form['expose_button'] = array( + '#prefix' => '<div class="views-expose clearfix">', + '#suffix' => '</div>', + ); + if (empty($this->options['exposed'])) { + $form['expose_button']['button'] = array( + '#type' => 'submit', + '#value' => t('Expose'), + '#submit' => array('views_ui_config_item_form_expose'), + ); + $form['expose_button']['markup'] = array( + '#markup' => '<div class="description">' . t('This item is currently not exposed. If you <strong>expose</strong> it, users will be able to change the filter as they view it.') . '</div>', + ); + } + else { + $form['expose_button']['button'] = array( + '#type' => 'submit', + '#value' => t('Hide'), + '#submit' => array('views_ui_config_item_form_expose'), + ); + $form['expose_button']['markup'] = array( + '#markup' => '<div class="description">' . t('This item is currently exposed. If you <strong>hide</strong> it, users will not be able to change the filter as they view it.') . '</div>', ); + } + } + + /** + * Shortcut to display the exposed options form. + */ + function show_expose_form(&$form, &$form_state) { + if (empty($this->options['exposed'])) { + return; + } + + $form['expose'] = array( + '#prefix' => '<div class="views-expose-options clearfix">', + '#suffix' => '</div>', + ); + $this->expose_form($form, $form_state); + + // When we click the expose button, we add new gadgets to the form but they + // have no data in $_POST so their defaults get wiped out. This prevents + // these defaults from getting wiped out. This setting will only be TRUE + // during a 2nd pass rerender. + if (!empty($form_state['force_expose_options'])) { + foreach (element_children($form['expose']) as $id) { + if (isset($form['expose'][$id]['#default_value']) && !isset($form['expose'][$id]['#value'])) { + $form['expose'][$id]['#value'] = $form['expose'][$id]['#default_value']; + } + } + } + } + + /** + * Check whether current user has access to this handler. + * + * @return boolean + */ + function access() { + if (isset($this->definition['access callback']) && function_exists($this->definition['access callback'])) { + if (isset($this->definition['access arguments']) && is_array($this->definition['access arguments'])) { + return call_user_func_array($this->definition['access callback'], $this->definition['access arguments']); + } + return $this->definition['access callback'](); + } + + return TRUE; + } + + /** + * Run before the view is built. + * + * This gives all the handlers some time to set up before any handler has + * been fully run. + */ + function pre_query() { } + + /** + * Provides a unique placeholders for handlers. + */ + function placeholder() { + return $this->query->placeholder($this->options['table'] . '_' . $this->options['field']); + } + + /** + * Called just prior to query(), this lets a handler set up any relationship + * it needs. + */ + function set_relationship() { + // Ensure this gets set to something. + $this->relationship = NULL; + + // Don't process non-existant relationships. + if (empty($this->options['relationship']) || $this->options['relationship'] == 'none') { + return; + } + + $relationship = $this->options['relationship']; + + // Ignore missing/broken relationships. + if (empty($this->view->relationship[$relationship])) { + return; + } + + // Check to see if the relationship has already processed. If not, then we + // cannot process it. + if (empty($this->view->relationship[$relationship]->alias)) { + return; + } + + // Finally! + $this->relationship = $this->view->relationship[$relationship]->alias; + } + + /** + * Ensure the main table for this handler is in the query. This is used + * a lot. + */ + function ensure_my_table() { + if (!isset($this->table_alias)) { + if (!method_exists($this->query, 'ensure_table')) { vpr_trace(); exit; } + $this->table_alias = $this->query->ensure_table($this->table, $this->relationship); + } + return $this->table_alias; + } + + /** + * Provide text for the administrative summary + */ + function admin_summary() { } + + /** + * Determine if the argument needs a style plugin. + * + * @return TRUE/FALSE + */ + function needs_style_plugin() { return FALSE; } + + /** + * Determine if this item is 'exposed', meaning it provides form elements + * to let users modify the view. + * + * @return TRUE/FALSE + */ + function is_exposed() { + return !empty($this->options['exposed']); + } + + /** + * Take input from exposed handlers and assign to this handler, if necessary. + */ + function accept_exposed_input($input) { return TRUE; } + + /** + * If set to remember exposed input in the session, store it there. + */ + function store_exposed_input($input, $status) { return TRUE; } + + /** + * Get the join object that should be used for this handler. + * + * This method isn't used a great deal, but it's very handy for easily + * getting the join if it is necessary to make some changes to it, such + * as adding an 'extra'. + */ + function get_join() { + // get the join from this table that links back to the base table. + // Determine the primary table to seek + if (empty($this->query->relationships[$this->relationship])) { + $base_table = $this->query->base_table; + } + else { + $base_table = $this->query->relationships[$this->relationship]['base']; + } + + $join = views_get_table_join($this->table, $base_table); + if ($join) { + return clone $join; + } + } + + /** + * Validates the handler against the complete View. + * + * This is called when the complete View is being validated. For validating + * the handler options form use options_validate(). + * + * @see views_handler::options_validate() + * + * @return + * Empty array if the handler is valid; an array of error strings if it is not. + */ + function validate() { return array(); } + + /** + * Determine if the handler is considered 'broken', meaning it's a + * a placeholder used when a handler can't be found. + */ + function broken() { } +} + +/** + * This many to one helper object is used on both arguments and filters. + * + * @todo This requires extensive documentation on how this class is to + * be used. For now, look at the arguments and filters that use it. Lots + * of stuff is just pass-through but there are definitely some interesting + * areas where they interact. + * + * Any handler that uses this can have the following possibly additional + * definition terms: + * - numeric: If true, treat this field as numeric, using %d instead of %s in + * queries. + * + */ +class views_many_to_one_helper { + function views_many_to_one_helper(&$handler) { + $this->handler = &$handler; + } + + function option_definition(&$options) { + $options['reduce_duplicates'] = array('default' => FALSE); + } + + function options_form(&$form, &$form_state) { + $form['reduce_duplicates'] = array( + '#type' => 'checkbox', + '#title' => t('Reduce duplicates'), + '#description' => t('This filter can cause items that have more than one of the selected options to appear as duplicate results. If this filter causes duplicate results to occur, this checkbox can reduce those duplicates; however, the more terms it has to search for, the less performant the query will be, so use this with caution. Shouldn\'t be set on single-value fields, as it may cause values to disappear from display, if used on an incompatible field.'), + '#default_value' => !empty($this->handler->options['reduce_duplicates']), + ); + } + + /** + * Sometimes the handler might want us to use some kind of formula, so give + * it that option. If it wants us to do this, it must set $helper->formula = TRUE + * and implement handler->get_formula(); + */ + function get_field() { + if (!empty($this->formula)) { + return $this->handler->get_formula(); + } + else { + return $this->handler->table_alias . '.' . $this->handler->real_field; + } + } + + /** + * Add a table to the query. + * + * This is an advanced concept; not only does it add a new instance of the table, + * but it follows the relationship path all the way down to the relationship + * link point and adds *that* as a new relationship and then adds the table to + * the relationship, if necessary. + */ + function add_table($join = NULL, $alias = NULL) { + // This is used for lookups in the many_to_one table. + $field = $this->handler->table . '.' . $this->handler->field; + + if (empty($join)) { + $join = $this->get_join(); + } + + // See if there's a chain between us and the base relationship. If so, we need + // to create a new relationship to use. + $relationship = $this->handler->relationship; + + // Determine the primary table to seek + if (empty($this->handler->query->relationships[$relationship])) { + $base_table = $this->handler->query->base_table; + } + else { + $base_table = $this->handler->query->relationships[$relationship]['base']; + } + + // Cycle through the joins. This isn't as error-safe as the normal + // ensure_path logic. Perhaps it should be. + $r_join = clone $join; + while ($r_join->left_table != $base_table) { + $r_join = views_get_table_join($r_join->left_table, $base_table); + } + // If we found that there are tables in between, add the relationship. + if ($r_join->table != $join->table) { + $relationship = $this->handler->query->add_relationship($this->handler->table . '_' . $r_join->table, $r_join, $r_join->table, $this->handler->relationship); + } + + // And now add our table, using the new relationship if one was used. + $alias = $this->handler->query->add_table($this->handler->table, $relationship, $join, $alias); + + // Store what values are used by this table chain so that other chains can + // automatically discard those values. + if (empty($this->handler->view->many_to_one_tables[$field])) { + $this->handler->view->many_to_one_tables[$field] = $this->handler->value; + } + else { + $this->handler->view->many_to_one_tables[$field] = array_merge($this->handler->view->many_to_one_tables[$field], $this->handler->value); + } + + return $alias; + } + + function get_join() { + return $this->handler->get_join(); + } + + /** + * Provide the proper join for summary queries. This is important in part because + * it will cooperate with other arguments if possible. + */ + function summary_join() { + $field = $this->handler->table . '.' . $this->handler->field; + $join = $this->get_join(); + + // shortcuts + $options = $this->handler->options; + $view = &$this->handler->view; + $query = &$this->handler->query; + + if (!empty($options['require_value'])) { + $join->type = 'INNER'; + } + + if (empty($options['add_table']) || empty($view->many_to_one_tables[$field])) { + return $query->ensure_table($this->handler->table, $this->handler->relationship, $join); + } + else { + if (!empty($view->many_to_one_tables[$field])) { + foreach ($view->many_to_one_tables[$field] as $value) { + $join->extra = array( + array( + 'field' => $this->handler->real_field, + 'operator' => '!=', + 'value' => $value, + 'numeric' => !empty($this->definition['numeric']), + ), + ); + } + } + return $this->add_table($join); + } + } + + /** + * Override ensure_my_table so we can control how this joins in. + * The operator actually has influence over joining. + */ + function ensure_my_table() { + if (!isset($this->handler->table_alias)) { + // For 'or' if we're not reducing duplicates, we get the absolute simplest: + $field = $this->handler->table . '.' . $this->handler->field; + if ($this->handler->operator == 'or' && empty($this->handler->options['reduce_duplicates'])) { + if (empty($this->handler->options['add_table']) && empty($this->handler->view->many_to_one_tables[$field])) { + // query optimization, INNER joins are slightly faster, so use them + // when we know we can. + $join = $this->get_join(); + $join->type = 'INNER'; + $this->handler->table_alias = $this->handler->query->ensure_table($this->handler->table, $this->handler->relationship, $join); + $this->handler->view->many_to_one_tables[$field] = $this->handler->value; + } + else { + $join = $this->get_join(); + $join->type = 'LEFT'; + if (!empty($this->handler->view->many_to_one_tables[$field])) { + foreach ($this->handler->view->many_to_one_tables[$field] as $value) { + $join->extra = array( + array( + 'field' => $this->handler->real_field, + 'operator' => '!=', + 'value' => $value, + 'numeric' => !empty($this->handler->definition['numeric']), + ), + ); + } + } + + $this->handler->table_alias = $this->add_table($join); + } + + return $this->handler->table_alias; + } + + if ($this->handler->operator != 'not') { + // If it's an and or an or, we do one join per selected value. + // Clone the join for each table: + $this->handler->table_aliases = array(); + foreach ($this->handler->value as $value) { + $join = $this->get_join(); + if ($this->handler->operator == 'and') { + $join->type = 'INNER'; + } + $join->extra = array( + array( + 'field' => $this->handler->real_field, + 'value' => $value, + 'numeric' => !empty($this->handler->definition['numeric']), + ), + ); + + // The table alias needs to be unique to this value across the + // multiple times the filter or argument is called by the view. + if (!isset($this->handler->view->many_to_one_aliases[$field][$value])) { + if (!isset($this->handler->view->many_to_one_count[$this->handler->table])) { + $this->handler->view->many_to_one_count[$this->handler->table] = 0; + } + $this->handler->view->many_to_one_aliases[$field][$value] = $this->handler->table . '_value_' . ($this->handler->view->many_to_one_count[$this->handler->table]++); + } + $alias = $this->handler->table_aliases[$value] = $this->add_table($join, $this->handler->view->many_to_one_aliases[$field][$value]); + + // and set table_alias to the first of these. + if (empty($this->handler->table_alias)) { + $this->handler->table_alias = $alias; + } + } + } + else { + // For not, we just do one join. We'll add a where clause during + // the query phase to ensure that $table.$field IS NULL. + $join = $this->get_join(); + $join->type = 'LEFT'; + $join->extra = array(); + $join->extra_type = 'OR'; + foreach ($this->handler->value as $value) { + $join->extra[] = array( + 'field' => $this->handler->real_field, + 'value' => $value, + 'numeric' => !empty($this->handler->definition['numeric']), + ); + } + + $this->handler->table_alias = $this->add_table($join); + } + } + return $this->handler->table_alias; + } + + /** + * Provides a unique placeholders for handlers. + */ + function placeholder() { + return $this->handler->query->placeholder($this->handler->options['table'] . '_' . $this->handler->options['field']); + } + + function add_filter() { + if (empty($this->handler->value)) { + return; + } + $this->handler->ensure_my_table(); + + // Shorten some variables: + $field = $this->get_field(); + $options = $this->handler->options; + $operator = $this->handler->operator; + $formula = !empty($this->formula); + if (empty($options['group'])) { + $options['group'] = 0; + } + + $add_condition = TRUE; + if ($operator == 'not') { + $value = NULL; + $operator = 'IS NULL'; + $add_condition = FALSE; + } + elseif ($operator == 'or' && empty($options['reduce_duplicates'])) { + if (count($this->handler->value) > 1) { + $value = $this->handler->value; + $operator = 'IN'; + } + else { + $value = is_array($this->handler->value) ? array_pop($this->handler->value) : $this->handler->value; + $operator = '='; + } + $add_condition = FALSE; + } + + if ($formula) { + $placeholder = $this->placeholder(); + if ($operator == 'IN') { + $operator = "$operator IN($placeholder)"; + } + else { + $operator = "$operator $placeholder"; + } + $placeholders = array( + $placeholder => $value, + ) + $this->placeholders; + $this->handler->query->add_where_expression($options['group'], "$field $operator", $placeholders); + } + else { + $this->handler->query->add_where($options['group'], $field, $value, $operator); + } + + if ($add_condition) { + $field = $this->handler->real_field; + $clause = $operator == 'or' ? db_or() : db_and(); + foreach ($this->handler->table_aliases as $value => $alias) { + $clause->condition("$alias.$field", $this->handler->value); + } + + // implode on either AND or OR. + $this->handler->query->add_where($options['group'], $clause); + } + } +} + +/* + * Break x,y,z and x+y+z into an array. Numeric only. + * + * @param $str + * The string to parse. + * @param $filter + * The filter object to use as a base. If not specified one will + * be created. + * + * @return $filter + * The new filter object. + */ +function views_break_phrase($str, $filter = NULL) { + if (!$filter) { + $filter = new stdClass(); + } + + // Set up defaults: + + if (!isset($filter->value)) { + $filter->value = array(); + } + + if (!isset($filter->operator)) { + $filter->operator = 'or'; + } + + if (empty($str)) { + return $filter; + } + + if (preg_match('/^([0-9]+[+ ])+[0-9]+$/', $str)) { + // The '+' character in a query string may be parsed as ' '. + $filter->operator = 'or'; + $filter->value = preg_split('/[+ ]/', $str); + } + elseif (preg_match('/^([0-9]+,)*[0-9]+$/', $str)) { + $filter->operator = 'and'; + $filter->value = explode(',', $str); + } + + // Keep an 'error' value if invalid strings were given. + if (!empty($str) && (empty($filter->value) || !is_array($filter->value))) { + $filter->value = array(-1); + return $filter; + } + + // Doubly ensure that all values are numeric only. + foreach ($filter->value as $id => $value) { + $filter->value[$id] = intval($value); + } + + return $filter; +} + +// -------------------------------------------------------------------------- +// Date helper functions + +/** + * Figure out what timezone we're in; needed for some date manipulations. + */ +function views_get_timezone() { + global $user; + if (variable_get('configurable_timezones', 1) && $user->uid && strlen($user->timezone)) { + $timezone = $user->timezone; + } + else { + $timezone = variable_get('date_default_timezone', 0); + } + + // set up the database timezone + if (in_array(db_driver(), array('mysql', 'mysqli', 'pgsql'))) { + $offset = '+00:00'; + static $already_set = FALSE; + if (!$already_set) { + if (db_driver() == 'pgsql') { + db_query("SET TIME ZONE INTERVAL '$offset' HOUR TO MINUTE"); + } + elseif (db_driver() == 'mysql') { + db_query("SET @@session.time_zone = '$offset'"); + } + + $already_set = true; + } + } + + return $timezone; +} + +/** + * Helper function to create cross-database SQL dates. + * + * @param $field + * The real table and field name, like 'tablename.fieldname'. + * @param $field_type + * The type of date field, 'int' or 'datetime'. + * @param $set_offset + * The name of a field that holds the timezone offset or a fixed timezone + * offset value. If not provided, the normal Drupal timezone handling + * will be used, i.e. $set_offset = 0 will make no timezone adjustment. + * @return + * An appropriate SQL string for the db type and field type. + */ +function views_date_sql_field($field, $field_type = 'int', $set_offset = NULL) { + $db_type = db_driver(); + $offset = $set_offset !== NULL ? $set_offset : views_get_timezone(); + if (isset($offset) && !is_numeric($offset)) { + $tz = date_default_timezone_get(); + $current = time('Z'); + date_default_timezone_set($offset); + $offset_seconds = $current - time('Z'); + date_default_timezone_set($tz); + } + + switch ($db_type) { + case 'mysql': + case 'mysqli': + switch ($field_type) { + case 'int': + $field = "DATE_ADD('19700101', INTERVAL $field SECOND)"; + break; + case 'datetime': + break; + } + if (!empty($offset)) { + $field = "($field + INTERVAL $offset_seconds SECOND)"; + } + return $field; + case 'pgsql': + switch ($field_type) { + case 'int': + $field = "TO_TIMESTAMP($field)"; + break; + case 'datetime': + break; + } + if (!empty($offset)) { + $field = "($field + INTERVAL '$offset_seconds SECONDS')"; + } + return $field; + } +} + +/** + * Helper function to create cross-database SQL date formatting. + * + * @param $format + * A format string for the result, like 'Y-m-d H:i:s'. + * @param $field + * The real table and field name, like 'tablename.fieldname'. + * @param $field_type + * The type of date field, 'int' or 'datetime'. + * @param $set_offset + * The name of a field that holds the timezone offset or a fixed timezone + * offset value. If not provided, the normal Drupal timezone handling + * will be used, i.e. $set_offset = 0 will make no timezone adjustment. + * @return + * An appropriate SQL string for the db type and field type. + */ +function views_date_sql_format($format, $field, $field_type = 'int', $set_offset = NULL) { + $db_type = db_driver(); + $field = views_date_sql_field($field, $field_type, $set_offset); + switch ($db_type) { + case 'mysql': + case 'mysqli': + $replace = array( + 'Y' => '%Y', + 'y' => '%y', + 'M' => '%b', + 'm' => '%m', + 'n' => '%c', + 'F' => '%M', + 'D' => '%a', + 'd' => '%d', + 'l' => '%W', + 'j' => '%e', + 'W' => '%v', + 'H' => '%H', + 'h' => '%h', + 'i' => '%i', + 's' => '%s', + 'A' => '%p', + ); + $format = strtr($format, $replace); + return "DATE_FORMAT($field, '$format')"; + case 'pgsql': + $replace = array( + 'Y' => 'YYYY', + 'y' => 'YY', + 'M' => 'Mon', + 'm' => 'MM', + 'n' => 'MM', // no format for Numeric representation of a month, without leading zeros + 'F' => 'Month', + 'D' => 'Dy', + 'd' => 'DD', + 'l' => 'Day', + 'j' => 'DD', // no format for Day of the month without leading zeros + 'W' => 'WW', + 'H' => 'HH24', + 'h' => 'HH12', + 'i' => 'MI', + 's' => 'SS', + 'A' => 'AM', + ); + $format = strtr($format, $replace); + return "TO_CHAR($field, '$format')"; + } +} + +/** + * Helper function to create cross-database SQL date extraction. + * + * @param $extract_type + * The type of value to extract from the date, like 'MONTH'. + * @param $field + * The real table and field name, like 'tablename.fieldname'. + * @param $field_type + * The type of date field, 'int' or 'datetime'. + * @param $set_offset + * The name of a field that holds the timezone offset or a fixed timezone + * offset value. If not provided, the normal Drupal timezone handling + * will be used, i.e. $set_offset = 0 will make no timezone adjustment. + * @return + * An appropriate SQL string for the db type and field type. + */ +function views_date_sql_extract($extract_type, $field, $field_type = 'int', $set_offset = NULL) { + $db_type = db_driver(); + $field = views_date_sql_field($field, $field_type, $set_offset); + + // Note there is no space after FROM to avoid db_rewrite problems + // see http://drupal.org/node/79904. + switch ($extract_type) { + case('DATE'): + return $field; + case('YEAR'): + return "EXTRACT(YEAR FROM($field))"; + case('MONTH'): + return "EXTRACT(MONTH FROM($field))"; + case('DAY'): + return "EXTRACT(DAY FROM($field))"; + case('HOUR'): + return "EXTRACT(HOUR FROM($field))"; + case('MINUTE'): + return "EXTRACT(MINUTE FROM($field))"; + case('SECOND'): + return "EXTRACT(SECOND FROM($field))"; + case('WEEK'): // ISO week number for date + switch ($db_type) { + case('mysql'): + case('mysqli'): + // WEEK using arg 3 in mysql should return the same value as postgres EXTRACT + return "WEEK($field, 3)"; + case('pgsql'): + return "EXTRACT(WEEK FROM($field))"; + } + case('DOW'): + switch ($db_type) { + case('mysql'): + case('mysqli'): + // mysql returns 1 for Sunday through 7 for Saturday + // php date functions and postgres use 0 for Sunday and 6 for Saturday + return "INTEGER(DAYOFWEEK($field) - 1)"; + case('pgsql'): + return "EXTRACT(DOW FROM($field))"; + } + case('DOY'): + switch ($db_type) { + case('mysql'): + case('mysqli'): + return "DAYOFYEAR($field)"; + case('pgsql'): + return "EXTRACT(DOY FROM($field))"; + } + } +} + +/** + * @} + */ + +/** + * @defgroup views_join_handlers Views' join handlers + * @{ + * Handlers to tell Views how to join tables together. + + * Here is how you do complex joins: + * + * @code + * class views_join_complex extends views_join { + * // PHP 4 doesn't call constructors of the base class automatically from a + * // constructor of a derived class. It is your responsibility to propagate + * // the call to constructors upstream where appropriate. + * function construct($table, $left_table, $left_field, $field, $extra = array(), $type = 'LEFT') { + * parent::construct($table, $left_table, $left_field, $field, $extra, $type); + * } + * + * function join($table, &$query) { + * $output = parent::join($table, $query); + * } + * $output .= "AND foo.bar = baz.boing"; + * return $output; + * } + * @endcode + */ +/** + * A function class to represent a join and create the SQL necessary + * to implement the join. + * + * This is the Delegation pattern. If we had PHP5 exclusively, we would + * declare this an interface. + * + * Extensions of this class can be used to create more interesting joins. + * + * join definition + * - table: table to join (right table) + * - field: field to join on (right field) + * - left_table: The table we join to + * - left_field: The field we join to + * - type: either LEFT (default) or INNER + * - extra: Either a string that's directly added, or an array of items: + * - - table: if not set, current table; if NULL, no table. This field can't + * be set in the cached definition because it can't know aliases; this field + * can only be used by realtime joins. + * - - field: Field or formula + * - - operator: defaults to = + * - - value: Must be set. If an array, operator will be defaulted to IN. + * - - numeric: If true, the value will not be surrounded in quotes. + * - extra type: How all the extras will be combined. Either AND or OR. Defaults to AND. + */ +class views_join { + /** + * Construct the views_join object. + */ + function construct($table = NULL, $left_table = NULL, $left_field = NULL, $field = NULL, $extra = array(), $type = 'LEFT') { + $this->extra_type = 'AND'; + if (!empty($table)) { + $this->table = $table; + $this->left_table = $left_table; + $this->left_field = $left_field; + $this->field = $field; + $this->extra = $extra; + $this->type = strtoupper($type); + } + elseif (!empty($this->definition)) { + // if no arguments, construct from definition. + // These four must exist or it will throw notices. + $this->table = $this->definition['table']; + $this->left_table = $this->definition['left_table']; + $this->left_field = $this->definition['left_field']; + $this->field = $this->definition['field']; + if (!empty($this->definition['extra'])) { + $this->extra = $this->definition['extra']; + } + if (!empty($this->definition['extra type'])) { + $this->extra_type = strtoupper($this->definition['extra type']); + } + + $this->type = !empty($this->definition['type']) ? strtoupper($this->definition['type']) : 'LEFT'; + } + } + + /** + * Build the SQL for the join this object represents. + * + * @param $select_query + * An implementation of SelectQueryInterface. + * @param $table + * The base table to join. + * @param $view_query + * The source query, implementation of views_plugin_query. + * @return + * + */ + function build_join($select_query, $table, $view_query) { + if (empty($this->definition['table formula'])) { + $right_table = "{" . $this->table . "}"; + } + else { + $right_table = $this->definition['table formula']; + } + + if ($this->left_table) { + $left = $view_query->get_table_info($this->left_table); + $left_field = "$left[alias].$this->left_field"; + } + else { + // This can be used if left_field is a formula or something. It should be used only *very* rarely. + $left_field = $this->left_field; + } + + $condition = "$left_field = $table[alias].$this->field"; + $arguments = array(); + + // Tack on the extra. + if (isset($this->extra)) { + if (is_array($this->extra)) { + $extras = array(); + foreach ($this->extra as $info) { + $extra = ''; + // Figure out the table name. Remember, only use aliases provided + // if at all possible. + $join_table = ''; + if (!array_key_exists('table', $info)) { + $join_table = $table['alias'] . '.'; + } + elseif (isset($info['table'])) { + $join_table = $info['table'] . '.'; + } + + $placeholder = ':views_join_condition_' . $select_query->nextPlaceholder(); + + if (is_array($info['value'])) { + $operator = !empty($info['operator']) ? $info['operator'] : 'IN'; + // Transform from IN() notation to = notation if just one value. + if (count($info['value']) == 1) { + $info['value'] = array_shift($info['value']); + $operator = $operator == 'NOT IN' ? '!=' : '='; + } + } + else { + $operator = !empty($info['operator']) ? $info['operator'] : '='; + } + + $extras[] = "$join_table$info[field] $operator $placeholder"; + $arguments[$placeholder] = $info['value']; + } + + if ($extras) { + if (count($extras) == 1) { + $condition .= ' AND ' . array_shift($extras); + } + else { + $condition .= ' AND (' . implode(' ' . $this->extra_type . ' ', $extras) . ')'; + } + } + } + elseif ($this->extra && is_string($this->extra)) { + $condition .= " AND ($this->extra)"; + } + } + + $select_query->addJoin($this->type, $right_table, $table['alias'], $condition, $arguments); + } +} + +/** + * @} + */ + +// Declare API compatibility on behalf of core modules: + +/** + * Implements hook_views_api(). + * + * This one is used as the base to reduce errors when updating. + */ +function views_views_api() { + return array( + // in your modules do *not* use views_api_version()!!! + 'api' => views_api_version(), + 'path' => drupal_get_path('module', 'views') . '/modules', + ); +} + +function aggregator_views_api() { return views_views_api(); } + +function book_views_api() { return views_views_api(); } + +function comment_views_api() { return views_views_api(); } + +function locale_views_api() { return views_views_api(); } + +function field_views_api() { return views_views_api(); } + +function filter_views_api() { return views_views_api(); } + +function node_views_api() { return views_views_api(); } + +function poll_views_api() { return views_views_api(); } + +function profile_views_api() { return views_views_api(); } + +function search_views_api() { return views_views_api(); } + +function statistics_views_api() { return views_views_api(); } + +function system_views_api() { return views_views_api(); } + +function taxonomy_views_api() { return views_views_api(); } + +function translation_views_api() { return views_views_api(); } + +function upload_views_api() { return views_views_api(); } + +function user_views_api() { return views_views_api(); } + +function contact_views_api() { return views_views_api(); } diff --git a/sites/all/modules/views/includes/plugins.inc b/sites/all/modules/views/includes/plugins.inc new file mode 100644 index 0000000000000000000000000000000000000000..6b01af91c760ce937ff0b124bbce894df06892e1 --- /dev/null +++ b/sites/all/modules/views/includes/plugins.inc @@ -0,0 +1,474 @@ +<?php +// $Id: plugins.inc,v 1.156.4.14 2010/12/04 07:39:35 dereine Exp $ +/** + * @file plugins.inc + * Built in plugins for Views output handling. + * + */ + +/** + * Implements hook_views_plugins + */ +function views_views_plugins() { + $js_path = drupal_get_path('module', 'ctools') . '/js'; + $plugins = array( + // display, style, row, argument default, argument validator and access. + 'display' => array( + // Default settings for all display plugins. + 'default' => array( + 'title' => t('Defaults'), + 'help' => t('Default settings for this view.'), + 'handler' => 'views_plugin_display_default', + 'theme' => 'views_view', + 'no ui' => TRUE, + 'no remove' => TRUE, + 'js' => array('misc/form.js', 'misc/collapse.js', 'misc/textarea.js', 'misc/tabledrag.js', 'misc/autocomplete.js', "$js_path/dependent.js"), + 'use ajax' => TRUE, + 'use pager' => TRUE, + 'use more' => TRUE, + 'accept attachments' => TRUE, + 'help topic' => 'display-default', + ), + 'page' => array( + 'title' => t('Page'), + 'help' => t('Display the view as a page, with a URL and menu links.'), + 'handler' => 'views_plugin_display_page', + 'theme' => 'views_view', + 'uses hook menu' => TRUE, + 'use ajax' => TRUE, + 'use pager' => TRUE, + 'accept attachments' => TRUE, + 'admin' => t('Page'), + 'help topic' => 'display-page', + ), + 'block' => array( + 'title' => t('Block'), + 'help' => t('Display the view as a block.'), + 'handler' => 'views_plugin_display_block', + 'theme' => 'views_view', + 'uses hook block' => TRUE, + 'use ajax' => TRUE, + 'use pager' => TRUE, + 'use more' => TRUE, + 'accept attachments' => TRUE, + 'admin' => t('Block'), + 'help topic' => 'display-block', + ), + 'attachment' => array( + 'title' => t('Attachment'), + 'help' => t('Attachments added to other displays to achieve multiple views in the same view.'), + 'handler' => 'views_plugin_display_attachment', + 'theme' => 'views_view', + 'use ajax' => TRUE, + 'use pager' => FALSE, + 'accept attachments' => FALSE, + 'help topic' => 'display-attachment', + ), + 'feed' => array( + 'title' => t('Feed'), + 'help' => t('Display the view as a feed, such as an RSS feed.'), + 'handler' => 'views_plugin_display_feed', + 'uses hook menu' => TRUE, + 'use ajax' => FALSE, + 'use pager' => FALSE, + 'accept attachments' => FALSE, + 'admin' => t('Feed'), + 'help topic' => 'display-feed', + ), + ), + 'style' => array( + // Default settings for all style plugins. + 'default' => array( + 'title' => t('Unformatted'), + 'help' => t('Displays rows one after another.'), + 'handler' => 'views_plugin_style_default', + 'theme' => 'views_view_unformatted', + 'uses row plugin' => TRUE, + 'uses row class' => TRUE, + 'uses grouping' => TRUE, + 'uses options' => TRUE, + 'type' => 'normal', + 'help topic' => 'style-unformatted', + ), + 'list' => array( + 'title' => t('HTML List'), + 'help' => t('Displays rows as an HTML list.'), + 'handler' => 'views_plugin_style_list', + 'theme' => 'views_view_list', + 'uses row plugin' => TRUE, + 'uses row class' => TRUE, + 'uses options' => TRUE, + 'type' => 'normal', + 'help topic' => 'style-list', + ), + 'grid' => array( + 'title' => t('Grid'), + 'help' => t('Displays rows in a grid.'), + 'handler' => 'views_plugin_style_grid', + 'theme' => 'views_view_grid', + 'uses row plugin' => TRUE, + 'uses row class' => TRUE, + 'uses options' => TRUE, + 'type' => 'normal', + 'help topic' => 'style-grid', + ), + 'table' => array( + 'title' => t('Table'), + 'help' => t('Displays rows in a table.'), + 'handler' => 'views_plugin_style_table', + 'theme' => 'views_view_table', + 'uses row plugin' => FALSE, + 'uses row class' => TRUE, + 'uses fields' => TRUE, + 'uses options' => TRUE, + 'type' => 'normal', + 'help topic' => 'style-table', + ), + 'default_summary' => array( + 'title' => t('List'), + 'help' => t('Displays the default summary as a list.'), + 'handler' => 'views_plugin_style_summary', + 'theme' => 'views_view_summary', + 'type' => 'summary', // only shows up as a summary style + 'uses options' => TRUE, + 'help topic' => 'style-summary', + ), + 'unformatted_summary' => array( + 'title' => t('Unformatted'), + 'help' => t('Displays the summary unformatted, with option for one after another or inline.'), + 'handler' => 'views_plugin_style_summary_unformatted', + 'theme' => 'views_view_summary_unformatted', + 'type' => 'summary', // only shows up as a summary style + 'uses options' => TRUE, + 'help topic' => 'style-summary-unformatted', + ), + 'rss' => array( + 'title' => t('RSS Feed'), + 'help' => t('Generates an RSS feed from a view.'), + 'handler' => 'views_plugin_style_rss', + 'theme' => 'views_view_rss', + 'uses row plugin' => TRUE, + 'uses options' => TRUE, + 'type' => 'feed', + 'help topic' => 'style-rss', + ), + ), + 'row' => array( + 'fields' => array( + 'title' => t('Fields'), + 'help' => t('Displays the fields with an optional template.'), + 'handler' => 'views_plugin_row_fields', + 'theme' => 'views_view_fields', + 'uses fields' => TRUE, + 'uses options' => TRUE, + 'type' => 'normal', + 'help topic' => 'style-row-fields', + ), + ), + 'argument default' => array( + 'parent' => array( + 'no ui' => TRUE, + 'handler' => 'views_plugin_argument_default', + 'parent' => '', + ), + 'fixed' => array( + 'title' => t('Fixed entry'), + 'handler' => 'views_plugin_argument_default_fixed', + ), + 'php' => array( + 'title' => t('PHP Code'), + 'handler' => 'views_plugin_argument_default_php', + ), + ), + 'argument validator' => array( + 'php' => array( + 'title' => t('PHP Code'), + 'handler' => 'views_plugin_argument_validate_php', + ), + 'numeric' => array( + 'title' => t('Numeric'), + 'handler' => 'views_plugin_argument_validate_numeric', + ), + ), + 'access' => array( + 'none' => array( + 'title' => t('None'), + 'help' => t('Will be available to all users.'), + 'handler' => 'views_plugin_access_none', + 'help topic' => 'access-none', + ), + 'role' => array( + 'title' => t('Role'), + 'help' => t('Access will be granted to users with any of the specified roles.'), + 'handler' => 'views_plugin_access_role', + 'uses options' => TRUE, + 'help topic' => 'access-role', + ), + 'perm' => array( + 'title' => t('Permission'), + 'help' => t('Access will be granted to users with the specified permission string.'), + 'handler' => 'views_plugin_access_perm', + 'uses options' => TRUE, + 'help topic' => 'access-perm', + ), + ), + 'query' => array( + 'parent' => array( + 'no ui' => TRUE, + 'handler' => 'views_plugin_query', + 'parent' => '', + ), + 'views_query' => array( + 'title' => t('SQL Query'), + 'help' => t('Query will be generated and run using the Drupal database API.'), + 'handler' => 'views_plugin_query_default' + ), + ), + 'cache' => array( + 'parent' => array( + 'no ui' => TRUE, + 'handler' => 'views_plugin_cache', + 'parent' => '', + ), + 'none' => array( + 'title' => t('None'), + 'help' => t('No caching of Views data.'), + 'handler' => 'views_plugin_cache_none', + 'help topic' => 'cache-none', + ), + 'time' => array( + 'title' => t('Time-based'), + 'help' => t('Simple time-based caching of data.'), + 'handler' => 'views_plugin_cache_time', + 'uses options' => TRUE, + 'help topic' => 'cache-time', + ), + ), + 'exposed_form' => array( + 'parent' => array( + 'no ui' => TRUE, + 'handler' => 'views_plugin_exposed_form', + 'parent' => '', + ), + 'basic' => array( + 'title' => t('Basic'), + 'help' => t('Basic exposed form'), + 'handler' => 'views_plugin_exposed_form_basic', + 'uses options' => TRUE, + 'help topic' => 'exposed-form-basic', + ), + 'input_required' => array( + 'title' => t('Input required'), + 'help' => t('An exposed form that only renders a view if the form contains user input.'), + 'handler' => 'views_plugin_exposed_form_input_required', + 'uses options' => TRUE, + 'help topic' => 'exposed-form-input-required', + ), + ), + 'pager' => array( + 'parent' => array( + 'no ui' => TRUE, + 'handler' => 'views_plugin_pager', + 'parent' => '', + ), + 'none' => array( + 'title' => t('Display all items'), + 'help' => t("Display all items that this view might find"), + 'handler' => 'views_plugin_pager_none', + 'help topic' => 'pager-none', + 'uses options' => TRUE, + 'type' => 'basic', + ), + 'some' => array( + 'title' => t('Display a specified number of items'), + 'help' => t('Display a limited number items that this view might find.'), + 'handler' => 'views_plugin_pager_some', + 'help topic' => 'pager-some', + 'uses options' => TRUE, + 'type' => 'basic', + ), + 'full' => array( + 'title' => t('Paged output, full pager'), + 'help' => t('Paged output, full Drupal style'), + 'handler' => 'views_plugin_pager_full', + 'help topic' => 'pager-full', + 'uses options' => TRUE, + ), + 'mini' => array( + 'title' => t('Paged output, mini pager'), + 'help' => t('Use the mini pager output.'), + 'handler' => 'views_plugin_pager_mini', + 'help topic' => 'pager-mini', + 'uses options' => TRUE, + 'parent' => 'full', + ), + ), + 'localization' => array( + 'parent' => array( + 'no ui' => TRUE, + 'handler' => 'views_plugin_localization', + 'parent' => '', + ), + 'none' => array( + 'title' => t('None'), + 'help' => t('Do not pass admin strings for translation.'), + 'handler' => 'views_plugin_localization_none', + 'help topic' => 'localization-none', + ), + 'core' => array( + 'title' => t('Core'), + 'help' => t("Use Drupal core t() function. Not recommended, as it doesn't support updates to existing strings."), + 'handler' => 'views_plugin_localization_core', + 'help topic' => 'localization-core', + ), + ), + ); + // Add a help message pointing to the i18views module if it is not present. + if (!module_exists('i18nviews')) { + $plugins['localization']['core']['help'] .= ' ' . t('If you need to translate Views labels into other languages, consider installing the <a href="!path">Internationalization</a> package\'s Views translation module.', array('!path' => url('http://drupal.org/project/i18n', array('absolute' => TRUE)))); + } + + if (module_invoke('ctools', 'api_version', '1.3')) { + $plugins['style']['jump_menu_summary'] = array( + 'title' => t('Jump menu'), + 'help' => t('Puts all of the results into a select box and allows the user to go to a different page based upon the results.'), + 'handler' => 'views_plugin_style_summary_jump_menu', + 'theme' => 'views_view_summary_jump_menu', + 'type' => 'summary', // only shows up as a summary style + 'uses options' => TRUE, + 'help topic' => 'style-summary-jump-menu', + ); + $plugins['style']['jump_menu'] = array( + 'title' => t('Jump menu'), + 'help' => t('Puts all of the results into a select box and allows the user to go to a different page based upon the results.'), + 'handler' => 'views_plugin_style_jump_menu', + 'theme' => 'views_view_jump_menu', + 'uses row plugin' => TRUE, + 'uses fields' => TRUE, + 'uses options' => TRUE, + 'type' => 'normal', + 'help topic' => 'style-jump-menu', + ); + } + + return $plugins; +} + +/** + * Builds and return a list of all plugins available in the system. + * + * @return Nested array of plugins, grouped by type. + */ +function views_discover_plugins() { + $cache = array('display' => array(), 'style' => array(), 'row' => array(), 'argument default' => array(), 'argument validator' => array(), 'access' => array(), 'cache' => array(), 'exposed_form' => array()); + // Get plugins from all mdoules. + foreach (module_implements('views_plugins') as $module) { + $function = $module . '_views_plugins'; + $result = $function(); + if (!is_array($result)) { + continue; + } + + $module_dir = isset($result['module']) ? $result['module'] : $module; + // Setup automatic path/file finding for theme registration + if ($module_dir == 'views') { + $theme_path = drupal_get_path('module', $module_dir) . '/theme'; + $theme_file = 'theme.inc'; + $path = drupal_get_path('module', $module_dir) . '/plugins'; + } + else { + $theme_path = $path = drupal_get_path('module', $module_dir); + $theme_file = "$module.views.inc"; + } + + foreach ($result as $type => $info) { + if ($type == 'module') { + continue; + } + foreach ($info as $plugin => $def) { + $def['module'] = $module_dir; + if (!isset($def['theme path'])) { + $def['theme path'] = $theme_path; + } + if (!isset($def['theme file'])) { + $def['theme file'] = $theme_file; + } + if (!isset($def['path'])) { + $def['path'] = $path; + } + if (!isset($def['file'])) { + $def['file'] = $def['handler'] . '.inc'; + } + if (!isset($def['parent'])) { + $def['parent'] = 'parent'; + } + // merge the new data in + $cache[$type][$plugin] = $def; + } + } + } + + // Let other modules modify the plugins. + drupal_alter('views_plugins', $cache); + return $cache; +} + +/** + * Abstract base class to provide interface common to all plugins. + */ +class views_plugin extends views_object { + /** + * Init will be called after construct, when the plugin is attached to a + * view and a display. + */ + + /** + * Provide a form to edit options for this plugin. + */ + function options_form(&$form, &$form_state) { } + + /** + * Validate the options form. + */ + function options_validate(&$form, &$form_state) { } + + /** + * Handle any special handling on the validate form. + */ + function options_submit(&$form, &$form_state) { } + + /** + * Add anything to the query that we might need to. + */ + function query() { } + + /** + * Provide a full list of possible theme templates used by this style. + */ + function theme_functions() { + return views_theme_functions($this->definition['theme'], $this->view, $this->display); + } + + /** + * Provide a list of additional theme functions for the theme information page + */ + function additional_theme_functions() { + $funcs = array(); + if (!empty($this->definition['additional themes'])) { + foreach ($this->definition['additional themes'] as $theme => $type) { + $funcs[] = views_theme_functions($theme, $this->view, $this->display); + } + } + return $funcs; + } + + /** + * Validate that the plugin is correct and can be saved. + * + * @return + * An array of error strings to tell the user what is wrong with this + * plugin. + */ + function validate() { return array(); } +} + diff --git a/sites/all/modules/views/includes/tabs.inc b/sites/all/modules/views/includes/tabs.inc new file mode 100644 index 0000000000000000000000000000000000000000..09237196d60a30b329255638246a6282637529f8 --- /dev/null +++ b/sites/all/modules/views/includes/tabs.inc @@ -0,0 +1,196 @@ +<?php +// $Id: tabs.inc,v 1.7.6.3 2010/03/20 23:16:37 dereine Exp $ +/** + * @file + * + * Classes and theme functions for rendering javascript UI tabs. + */ + +/** + * Contain a set of tabs as well as the ability to render them. + * + * There are three 'areas' of a tabset. + * - title: The clickable link to display the tab area. These are always visible. + * - body: The actual HTML body of the tab. Only one body is visible at a time. + * - extra: An optional decorative area around the tabs. + */ +class views_tabset { + var $tabs = array(); + var $extra = ''; + var $selected = NULL; + + /** + * Add a tab to the tabset. + * + * @param $name + * The name of the tab; this is the internal identifier and must be + * unique within the tabset. + * @param $title + * If given, this will be the visible title of the tab. This can also + * be set via $tabset->set(). This will be the link to click on to + * view the tab. + * @param $body + * If given, this is the body of the tab itself. It will display + * when the tab title is clicked on. + */ + function add($name, $title = '', $body = '') { + if (is_object($name) && is_subclass_of($name, 'views_tab')) { + $this->add_tab($name); + } + elseif (is_array($name)) { + foreach ($name as $real_tab) { + $this->add($real_tab); + } + } + else { + $this->add_tab(new views_tab($name, $title, $body)); + } + } + + /** + * Add a fully realized tab object to the tabset. + * + * @param $tab + * A fully populated views_tab object. + */ + function add_tab($tab) { + $this->tabs[$tab->name] = $tab; + } + + /** + * Set the values of a tab. + * + * @param $name + * The unique identifier of the tab to set. + * @param $title + * The title of the tab; this will be clickable. + * @param $body + * The HTML body of the tab. + */ + function set($name, $title, $body = NULL) { + if (empty($this->tabs[$name])) { + return $this->add($name, $title, $body); + } + $this->tabs[$name]->title = $title; + if (isset($body)) { + $this->tabs[$name]->body = $body; + } + } + + /** + * Set the body of a tab. + */ + function set_body($name, $body) { + if (empty($this->tabs[$name])) { + return $this->add($name, '', $body); + } + $this->tabs[$name]->body = $body; + } + + /** + * Add text to the 'extra' region of the tabset. + */ + function add_extra($text) { + $this->extra .= $text; + } + + /** + * Remove a tab. + * + * @param $tab + * May be the name of the tab or a views_tab object. + */ + function remove($tab) { + if (is_string($tab)) { + unset($this->tabs[$tab]); + } + else { + unset($this->tabs[$tab->name]); + } + } + + /** + * Control which tab will be selected when it is rendered. + */ + function set_selected($name) { + $this->selected = $name; + } + + /** + * Output the HTML for the tabs. + * + * @return + * HTML representation of the tabs. + */ + function render() { + views_add_js('tabs'); + views_add_css('views-tabs'); + + if (empty($this->selected)) { + $keys = array_keys($this->tabs); + $this->selected = array_shift($keys); + } + + drupal_alter('views_tabset', $this); + return theme('views_tabset', array('tabs' => $this->tabs, 'extra' => $this->extra, 'selected' => $this->selected)); + } +} + +/** + * An object to represent an individual tab within a tabset. + */ +class views_tab { + var $title; + var $body; + var $name; + + /** + * Construct a new tab. + */ + function views_tab($name, $title, $body = NULL) { + $this->name = $name; + $this->title = $title; + $this->body = $body; + } + + /** + * Generate HTML output for a tab. + */ + function render() { + return theme('views_tab', array('body' => $this->body)); + } +} + +/** + * Render a tabset. + * + * @todo Turn this into a template. + */ +function theme_views_tabset($variables) { + $tabs = $variables['tabs']; + $extra = isset($variables['extra']) ? $variables['extra'] : NULL; + $selected = isset($variables['selected']) ? $variables['selected'] : NULL; + $link_output = "<div class=\"views-tabs\"><ul id=\"views-tabset\">\n"; + $tab_output = "<div class=\"views-tab-area\">\n"; + + foreach ($tabs as $name => $tab) { + $link_output .= '<li' . ($name == $selected ? ' class="active"': '') . '><a href="#views-tab-' . $tab->name . '" id="views-tab-title-' . $tab->name . '">' . check_plain($tab->title) . '</a></li>' . "\n"; + $tab_output .= '<div id="views-tab-' . $tab->name . '" class="views-tab">' . $tab->render() . "</div>\n"; + } + $link_output .= "</ul>\n"; + + if ($extra) { + $link_output .= "<div class=\"extra\">$extra</div>\n"; + } + + $link_output .= "</div>\n"; + $tab_output .= "</div>\n"; + return '<div class="views-tabset clearfix">' . $link_output . $tab_output . '</div>'; +} + +/** + * Theme a simple tab. + */ +function theme_views_tab($variables) { + return $variables['body']; +} diff --git a/sites/all/modules/views/includes/view.inc b/sites/all/modules/views/includes/view.inc new file mode 100644 index 0000000000000000000000000000000000000000..4e665987e762fa73959700d1027691117244e6ab --- /dev/null +++ b/sites/all/modules/views/includes/view.inc @@ -0,0 +1,2155 @@ +<?php +// $Id: view.inc,v 1.167.4.40 2011/01/05 21:20:09 dereine Exp $ +/** + * @file view.inc + * Provides the view object type and associated methods. + */ + +/** + * @defgroup views_objects Objects that represent a View or part of a view. + * @{ + * These objects are the core of Views do the bulk of the direction and + * storing of data. All database activity is in these objects. + */ + +/** + * An object to contain all of the data to generate a view, plus the member + * functions to build the view query, execute the query and render the output. + */ +class view extends views_db_object { + var $db_table = 'views_view'; + var $base_table = 'node'; + var $base_field = 'nid'; + + // State variables + var $built = FALSE; + var $executed = FALSE; + var $editing = FALSE; + + var $args = array(); + var $build_info = array(); + + var $use_ajax = FALSE; + + // Where the results of a query will go. + var $result = array(); + + // May be used to override the current pager info. + var $current_page = NULL; + var $items_per_page = NULL; + var $offset = NULL; + var $total_rows = NULL; + + // Places to put attached renderings: + var $attachment_before = ''; + var $attachment_after = ''; + + // Exposed widget input + var $exposed_data = array(); + var $exposed_input = array(); + + // Used to store views that were previously running if we recurse. + var $old_view = array(); + + // Where the $query object will reside: + var $query = NULL; + + /** + * Constructor + */ + function __construct() { + parent::init(); + // Make sure all of our sub objects are arrays. + foreach ($this->db_objects() as $object) { + $this->$object = array(); + } + } + + /** + * Returns a list of the sub-object types used by this view. These types are + * stored on the display, and are used in the build process. + */ + function display_objects() { + return array('argument', 'field', 'sort', 'filter', 'relationship', 'header', 'footer', 'empty'); + } + + /** + * Returns the complete list of dependent objects in a view, for the purpose + * of initialization and loading/saving to/from the database. + */ + static function db_objects() { + return array('display'); + } + + /** + * Set the arguments that come to this view. Usually from the URL + * but possibly from elsewhere. + */ + function set_arguments($args) { + $this->args = $args; + } + + /** + * Change/Set the current page for the pager. + */ + function set_current_page($page) { + $this->current_page = $page; + } + + /** + * Get the current page from the pager. + */ + function get_current_page() { + if (!empty($this->query->pager)) { + return $this->query->pager->get_current_page(); + } + } + + /** + * Get the items per page from the pager. + */ + function get_items_per_page() { + if (!empty($this->query->pager)) { + return $this->query->pager->get_items_per_page(); + } + } + + /** + * Set the items per page on the pager. + */ + function set_items_per_page($items_per_page) { + $this->items_per_page = $items_per_page; + + // If the pager is already initialized, pass it through to the pager. + if (!empty($this->query->pager)) { + $this->query->pager->set_items_per_page($items_per_page); + } + } + + /** + * Get the pager offset from the pager. + */ + function get_offset() { + if (!empty($this->query->pager)) { + return $this->query->pager->get_offset(); + } + } + + /** + * Set the offset on the pager. + */ + function set_offset($offset) { + $this->offset = $offset; + + // If the pager is already initialized, pass it through to the pager. + if (!empty($this->query->pager)) { + $this->query->pager->set_offset($offset); + } + } + + /** + * Whether or not AJAX should be used. If AJAX is used, paging, + * tablesorting and exposed filters will be fetched via an AJAX call + * rather than a page refresh. + */ + function set_use_ajax($use_ajax) { + $this->use_ajax = $use_ajax; + } + + /** + * Set the exposed filters input to an array. If unset they will be taken + * from $_GET when the time comes. + */ + function set_exposed_input($filters) { + $this->exposed_input = $filters; + } + + /** + * Figure out what the exposed input for this view is. + */ + function get_exposed_input() { + // Fill our input either from $_GET or from something previously set on the + // view. + if (empty($this->exposed_input)) { + $this->exposed_input = $_GET; + // unset items that are definitely not our input: + foreach (array('page', 'q') as $key) { + if (isset($this->exposed_input[$key])) { + unset($this->exposed_input[$key]); + } + } + + // If we have no input at all, check for remembered input via session. + + // If filters are not overridden, store the 'remember' settings on the + // default display. If they are, store them on this display. This way, + // multiple displays in the same view can share the same filters and + // remember settings. + $display_id = ($this->display_handler->is_defaulted('filters')) ? 'default' : $this->current_display; + + if (empty($this->exposed_input) && !empty($_SESSION['views'][$this->name][$display_id])) { + $this->exposed_input = $_SESSION['views'][$this->name][$display_id]; + } + } + + return $this->exposed_input; + } + + /** + * Set the display for this view and initialize the display handler. + */ + function init_display($reset = FALSE) { + // The default display is always the first one in the list. + if (isset($this->current_display)) { + return TRUE; + } + + // Instantiate all displays + foreach (array_keys($this->display) as $id) { + // Correct for shallow cloning + // Often we'll have a cloned view so we don't mess up each other's + // displays, but the clone is pretty shallow and doesn't necessarily + // clone the displays. We can tell this by looking to see if a handler + // has already been set; if it has, but $this->current_display is not + // set, then something is dreadfully wrong. + if (!empty($this->display[$id]->handler)) { + $this->display[$id] = clone $this->display[$id]; + unset($this->display[$id]->handler); + } + $this->display[$id]->handler = views_get_plugin('display', $this->display[$id]->display_plugin); + if (!empty($this->display[$id]->handler)) { + // Initialize the new display handler with data. + $this->display[$id]->handler->init($this, $this->display[$id]); + // If this is NOT the default display handler, let it know which is + // since it may well utilize some data from the default. + // This assumes that the 'default' handler is always first. It always + // is. Make sure of it. + if ($id != 'default') { + $this->display[$id]->handler->default_display = &$this->display['default']->handler; + } + } + } + + $this->current_display = 'default'; + $this->display_handler = &$this->display['default']->handler; + + return TRUE; + } + + /** + * Get the first display that is accessible to the user. + * + * @param $displays + * Either a single display id or an array of display ids. + */ + function choose_display($displays) { + if (!is_array($displays)) { + return $displays; + } + + $this->init_display(); + + foreach ($displays as $display_id) { + if ($this->display[$display_id]->handler->access()) { + return $display_id; + } + } + + return 'default'; + } + + /** + * Set the display as current. + * + * @param $display_id + * The id of the display to mark as current. + */ + function set_display($display_id = NULL) { + // If we have not already initialized the display, do so. But be careful. + if (empty($this->current_display)) { + $this->init_display(); + + // If handlers were not initialized, and no argument was sent, set up + // to the default display. + if (empty($display_id)) { + $display_id = 'default'; + } + } + + $display_id = $this->choose_display($display_id); + + // If no display id sent in and one wasn't chosen above, we're finished. + if (empty($display_id)) { + return FALSE; + } + + // Ensure the requested display exists. + if (empty($this->display[$display_id])) { + $display_id = 'default'; + if (empty($this->display[$display_id])) { + debug(t('set_display() called with invalid display id @display.', array('@display' => $display_id))); + return FALSE; + } + } + + // Set the current display. + $this->current_display = $display_id; + + // Ensure requested display has a working handler. + if (empty($this->display[$display_id]->handler)) { + return FALSE; + } + + // Set a shortcut + $this->display_handler = &$this->display[$display_id]->handler; + + return TRUE; + } + + /** + * Find and initialize the style plugin. + * + * Note that arguments may have changed which style plugin we use, so + * check the view object first, then ask the display handler. + */ + function init_style() { + if (isset($this->style_plugin)) { + return is_object($this->style_plugin); + } + + if (!isset($this->plugin_name)) { + $this->plugin_name = $this->display_handler->get_option('style_plugin'); + $this->style_options = $this->display_handler->get_option('style_options'); + } + + $this->style_plugin = views_get_plugin('style', $this->plugin_name); + + if (empty($this->style_plugin)) { + return FALSE; + } + + // init the new style handler with data. + $this->style_plugin->init($this, $this->display[$this->current_display], $this->style_options); + return TRUE; + } + + /** + * Acquire and attach all of the handlers. + */ + function init_handlers() { + if (empty($this->inited)) { + foreach (views_object_types() as $key => $info) { + $this->_init_handler($key, $info); + } + $this->inited = TRUE; + } + } + + /** + * Initialize the pager + * + * Like style initialization, pager initialization is held until late + * to allow for overrides. + */ + function init_pager() { + if (empty($this->query->pager)) { + $this->query->pager = $this->display_handler->get_plugin('pager'); + + if ($this->query->pager->use_pager()) { + $this->query->pager->set_current_page($this->current_page); + } + + // These overrides may have been set earlier via $view->set_* + // functions. + if (isset($this->items_per_page)) { + $this->query->pager->set_items_per_page($this->items_per_page); + } + + if (isset($this->offset)) { + $this->query->pager->set_offset($this->offset); + } + } + } + + /** + * Create a list of base tables eligible for this view. Used primarily + * for the UI. Display must be already initialized. + */ + function get_base_tables() { + $base_tables = array( + $this->base_table => TRUE, + '#global' => TRUE, + ); + + foreach ($this->display_handler->get_handlers('relationship') as $handler) { + $base_tables[$handler->definition['base']] = TRUE; + } + return $base_tables; + } + + /** + * Run the pre_query() on all active handlers. + */ + function _pre_query() { + foreach (views_object_types() as $key => $info) { + $handlers = &$this->$key; + $position = 0; + foreach ($handlers as $id => $handler) { + $handlers[$id]->position = $position; + $handlers[$id]->pre_query(); + $position++; + } + } + } + + /** + * Attach all of the handlers for each type. + * + * @param $key + * One of 'argument', 'field', 'sort', 'filter', 'relationship' + * @param $info + * The $info from views_object_types for this object. + */ + function _init_handler($key, $info) { + // Load the requested items from the display onto the object. + $this->$key = $this->display_handler->get_handlers($key); + + // This reference deals with difficult PHP indirection. + $handlers = &$this->$key; + + // Run through and test for accessibility. + foreach ($handlers as $id => $handler) { + if (!$handler->access()) { + unset($handlers[$id]); + } + } + } + + /** + * Build all the arguments. + */ + function _build_arguments() { + // Initially, we want to build sorts and fields. This can change, though, + // if we get a summary view. + if (empty($this->argument)) { + return TRUE; + } + + // build arguments. + $position = -1; + + // Create a title for use in the breadcrumb trail. + $title = $this->display_handler->get_option('title'); + + $this->build_info['breadcrumb'] = array(); + $breadcrumb_args = array(); + $substitutions = array(); + + $status = TRUE; + + // Iterate through each argument and process. + foreach ($this->argument as $id => $arg) { + $position++; + $argument = &$this->argument[$id]; + + if ($argument->broken()) { + continue; + } + + $argument->set_relationship(); + + $arg = isset($this->args[$position]) ? $this->args[$position] : NULL; + $argument->position = $position; + + if (isset($arg) || $argument->has_default_argument()) { + if (!isset($arg)) { + $arg = $argument->get_default_argument(); + // make sure default args get put back. + if (isset($arg)) { + $this->args[$position] = $arg; + } + } + + // Set the argument, which will also validate that the argument can be set. + if (!$argument->set_argument($arg)) { + $status = $argument->validate_fail($arg); + break; + } + + if ($argument->is_wildcard()) { + $arg_title = $argument->wildcard_title(); + } + else { + $arg_title = $argument->get_title(); + $argument->query($this->display_handler->use_group_by()); + } + + // Add this argument's substitution + $substitutions['%' . ($position + 1)] = $arg_title; + + // Since we're really generating the breadcrumb for the item above us, + // check the default action of this argument. + if ($this->display_handler->uses_breadcrumb() && $argument->uses_breadcrumb()) { + $path = $this->get_url($breadcrumb_args); + if (strpos($path, '%') === FALSE) { + $breadcrumb = !empty($argument->options['breadcrumb'])? $argument->options['breadcrumb'] : $title; + $this->build_info['breadcrumb'][$path] = str_replace(array_keys($substitutions), $substitutions, $breadcrumb); + } + } + + // Allow the argument to muck with this breadcrumb. + $argument->set_breadcrumb($this->build_info['breadcrumb']); + + // Test to see if we should use this argument's title + if (!empty($argument->options['title'])) { + $title = $argument->options['title']; + } + + $breadcrumb_args[] = $arg; + } + else { + // determine default condition and handle. + $status = $argument->default_action(); + break; + } + + // Be safe with references and loops: + unset($argument); + } + + // set the title in the build info. + if (!empty($title)) { + $this->build_info['title'] = str_replace(array_keys($substitutions), $substitutions, $title); + } + + // Store the arguments for later use. + $this->build_info['substitutions'] = $substitutions; + + return $status; + } + + /** + * Do some common building initialization. + */ + function init_query() { + if (!empty($this->query)) { + $class = get_class($this->query); + if ($class && $class != 'stdClass') { + // return if query is already initialized. + return TRUE; + } + } + + // Create and initialize the query object. + $views_data = views_fetch_data($this->base_table); + $this->base_field = $views_data['table']['base']['field']; + if (!empty($views_data['table']['base']['database'])) { + $this->base_database = $views_data['table']['base']['database']; + } + + // Load the options. + $query_options = $this->display_handler->get_option('query'); + + // Create and initialize the query object. + $plugin = !empty($views_data['table']['base']['query class']) ? $views_data['table']['base']['query class'] : 'views_query'; + $this->query = views_get_plugin('query', $plugin); + + if (empty($this->query)) { + return FALSE; + } + + $this->query->init($this->base_table, $this->base_field, $query_options['options']); + return TRUE; + } + + /** + * Build the query for the view. + */ + function build($display_id = NULL) { + if (!empty($this->built)) { + return; + } + + if (empty($this->current_display) || $display_id) { + if (!$this->set_display($display_id)) { + return FALSE; + } + } + + // Let modules modify the view just prior to building it. + foreach (module_implements('views_pre_build') as $module) { + $function = $module . '_views_pre_build'; + $function($this); + } + + // Attempt to load from cache. + // @todo Load a build_info from cache. + + $start = microtime(TRUE); + // If that fails, let's build! + $this->build_info = array( + 'query' => '', + 'count_query' => '', + 'query_args' => array(), + ); + + $this->init_query(); + + // Call a module hook and see if it wants to present us with a + // pre-built query or instruct us not to build the query for + // some reason. + // @todo: Implement this. Use the same mechanism Panels uses. + + // Run through our handlers and ensure they have necessary information. + $this->init_handlers(); + + // Let the handlers interact with each other if they really want. + $this->_pre_query(); + + if ($this->display_handler->uses_exposed()) { + $exposed_form = $this->display_handler->get_plugin('exposed_form'); + $this->exposed_widgets = $exposed_form->render_exposed_form(); + if (form_set_error() || !empty($this->build_info['abort'])) { + $this->built = TRUE; + // Don't execute the query, but rendering will still be executed to display the empty text. + $this->executed = TRUE; + return empty($this->build_info['fail']); + } + } + + // Build all the relationships first thing. + $this->_build('relationship'); + + // Set the filtering groups. + if (!empty($this->filter)) { + $filter_groups = $this->display_handler->get_option('filter_groups'); + if ($filter_groups) { + $this->query->set_group_operator($filter_groups['operator']); + foreach($filter_groups['groups'] as $id => $operator) { + $this->query->set_where_group($operator, $id); + } + } + } + + // Build all the filters. + $this->_build('filter'); + + $this->build_sort = TRUE; + + // Arguments can, in fact, cause this whole thing to abort. + if (!$this->_build_arguments()) { + $this->build_time = microtime(TRUE) - $start; + $this->attach_displays(); + return $this->built; + } + + // Initialize the style; arguments may have changed which style we use, + // so waiting as long as possible is important. But we need to know + // about the style when we go to build fields. + if (!$this->init_style()) { + $this->build_info['fail'] = TRUE; + return FALSE; + } + + if ($this->style_plugin->uses_fields()) { + $this->_build('field'); + } + + // Build our sort criteria if we were instructed to do so. + if (!empty($this->build_sort)) { + // Allow the style handler to deal with sorting. + if ($this->style_plugin->build_sort()) { + $this->_build('sort'); + } + // allow the plugin to build second sorts as well. + $this->style_plugin->build_sort_post(); + } + + // Allow display handler to affect the query: + $this->display_handler->query($this->display_handler->use_group_by()); + + // Allow style handler to affect the query: + $this->style_plugin->query($this->display_handler->use_group_by()); + + // Allow exposed form to affect the query: + if (isset($exposed_form)) { + $exposed_form->query(); + } + + if (variable_get('views_sql_signature', FALSE)) { + $this->query->add_signature($this); + } + + // Let modules modify the query just prior to finalizing it. + $this->query->alter($this); + + // Only build the query if we weren't interrupted. + if (empty($this->built)) { + // Build the necessary info to execute the query. + $this->query->build($this); + } + + $this->built = TRUE; + $this->build_time = microtime(TRUE) - $start; + + // Attach displays + $this->attach_displays(); + + // Let modules modify the view just after building it. + foreach (module_implements('views_post_build') as $module) { + $function = $module . '_views_post_build'; + $function($this); + } + + return TRUE; + } + + /** + * Internal method to build an individual set of handlers. + */ + function _build($key) { + $handlers = &$this->$key; + foreach ($handlers as $id => $data) { + if (!empty($handlers[$id]) && is_object($handlers[$id])) { + // Give this handler access to the exposed filter input. + if (!empty($this->exposed_data)) { + $rc = $handlers[$id]->accept_exposed_input($this->exposed_data); + $handlers[$id]->store_exposed_input($this->exposed_data, $rc); + if (!$rc) { + continue; + } + } + $handlers[$id]->set_relationship(); + $handlers[$id]->query($this->display_handler->use_group_by()); + } + } + } + + /** + * Execute the view's query. + */ + function execute($display_id = NULL) { + if (empty($this->built)) { + if (!$this->build($display_id)) { + return FALSE; + } + } + + if (!empty($this->executed)) { + return TRUE; + } + + // Don't allow to use deactivated displays. + if (!$this->display[$this->current_display]->handler->get_option('enabled')) { + $this->build_info['fail'] = TRUE; + return FALSE; + } + + // Let modules modify the view just prior to executing it. + foreach (module_implements('views_pre_execute') as $module) { + $function = $module . '_views_pre_execute'; + $function($this); + } + + // Check for already-cached results. + if (!empty($this->live_preview)) { + $cache = FALSE; + } + else { + $cache = $this->display_handler->get_plugin('cache'); + } + if ($cache && $cache->cache_get('results')) { + } + else { + $this->query->execute($this); + if ($cache) { + $cache->cache_set('results'); + } + } + + // Let modules modify the view just after executing it. + foreach (module_implements('views_post_execute') as $module) { + $function = $module . '_views_post_execute'; + $function($this); + } + + $this->executed = TRUE; + } + + /** + * Render this view for display. + */ + function render($display_id = NULL) { + $this->execute($display_id); + + // Check to see if the build failed. + if (!empty($this->build_info['fail'])) { + return; + } + + drupal_theme_initialize(); + + $start = microtime(TRUE); + if (!empty($this->live_preview) && variable_get('views_show_additional_queries', FALSE)) { + $this->start_query_capture(); + } + + $exposed_form = $this->display_handler->get_plugin('exposed_form'); + $exposed_form->pre_render($this->result); + + // Check for already-cached output. + if (!empty($this->live_preview)) { + $cache = FALSE; + } + else { + $cache = $this->display_handler->get_plugin('cache'); + } + if ($cache && $cache->cache_get('output')) { + } + else { + if ($cache) { + $cache->cache_start(); + } + + // Initialize the style plugin. + $this->init_style(); + + $this->style_plugin->pre_render($this->result); + + // Let modules modify the view just prior to rendering it. + foreach (module_implements('views_pre_render') as $module) { + $function = $module . '_views_pre_render'; + $function($this); + } + + // Let the theme play too, because pre render is a very themey thing. + $function = $GLOBALS['theme'] . '_views_pre_render'; + if (function_exists($function)) { + $function($this, $this->display_handler->output, $cache); + } + + // Give field handlers the opportunity to perform additional queries + // using the entire resultset prior to rendering. + if ($this->style_plugin->uses_fields()) { + foreach ($this->field as $id => $handler) { + if (!empty($this->field[$id])) { + $this->field[$id]->pre_render($this->result); + } + } + } + $this->display_handler->output = $this->display_handler->render(); + if ($cache) { + $cache->cache_set('output'); + } + } + + $exposed_form->post_render($this->display_handler->output); + + if ($cache) { + $cache->post_render($this->display_handler->output); + } + + // Let modules modify the view output after it is rendered. + foreach (module_implements('views_post_render') as $module) { + $function = $module . '_views_post_render'; + $function($this, $this->display_handler->output, $cache); + } + + // Let the theme play too, because post render is a very themey thing. + $function = $GLOBALS['theme'] . '_views_post_render'; + if (function_exists($function)) { + $function($this, $this->display_handler->output, $cache); + } + + if (!empty($this->live_preview) && variable_get('views_show_additional_queries', FALSE)) { + $this->end_query_capture(); + } + $this->render_time = microtime(TRUE) - $start; + + return $this->display_handler->output; + } + + /** + * Render a specific field via the field ID and the row #. + */ + function render_field($field, $row) { + if (isset($this->field[$field]) && isset($this->result[$row])) { + return $this->field[$field]->advanced_render($this->result[$row]); + } + } + + /** + * Execute the given display, with the given arguments. + * To be called externally by whatever mechanism invokes the view, + * such as a page callback, hook_block, etc. + * + * This function should NOT be used by anything external as this + * returns data in the format specified by the display. It can also + * have other side effects that are only intended for the 'proper' + * use of the display, such as setting page titles and breadcrumbs. + * + * If you simply want to view the display, use view::preview() instead. + */ + function execute_display($display_id = NULL, $args = array()) { + if (empty($this->current_display) || $this->current_display != $this->choose_display($display_id)) { + if (!$this->set_display($display_id)) { + return FALSE; + } + } + + $this->pre_execute($args); + + // Execute the view + $output = $this->display_handler->execute(); + + $this->post_execute(); + return $output; + } + + /** + * Preview the given display, with the given arguments. + * + * To be called externally, probably by an AJAX handler of some flavor. + * Can also be called when views are embedded, as this guarantees + * normalized output. + */ + function preview($display_id = NULL, $args = array()) { + if (empty($this->current_display) || ((!empty($display_id)) && $this->current_display != $display_id)) { + if (!$this->set_display($display_id)) { + return FALSE; + } + } + + $this->preview = TRUE; + $this->pre_execute($args); + // Preview the view. + $output = $this->display_handler->preview(); + + $this->post_execute(); + return $output; + } + + /** + * Run attachments and let the display do what it needs to do prior + * to running. + */ + function pre_execute($args = array()) { + $this->old_view[] = views_get_current_view(); + views_set_current_view($this); + $display_id = $this->current_display; + + // Let modules modify the view just prior to executing it. + foreach (module_implements('views_pre_view') as $module) { + $function = $module . '_views_pre_view'; + $function($this, $display_id, $args); + } + + // Prepare the view with the information we have, but only if we were + // passed arguments, as they may have been set previously. + if ($args) { + $this->set_arguments($args); + } + +// $this->attach_displays(); + + // Allow the display handler to set up for execution + $this->display_handler->pre_execute(); + } + + /** + * Unset the current view, mostly. + */ + function post_execute() { + // unset current view so we can be properly destructed later on. + // Return the previous value in case we're an attachment. + + if ($this->old_view) { + $old_view = array_pop($this->old_view); + } + + views_set_current_view(isset($old_view) ? $old_view : FALSE); + } + + /** + * Run attachment displays for the view. + */ + function attach_displays() { + if (!empty($this->is_attachment)) { + return; + } + + if (!$this->display_handler->accept_attachments()) { + return; + } + + $this->is_attachment = TRUE; + // Give other displays an opportunity to attach to the view. + foreach ($this->display as $id => $display) { + if (!empty($this->display[$id]->handler)) { + $this->display[$id]->handler->attach_to($this->current_display); + } + } + $this->is_attachment = FALSE; + } + + /** + * Called to get hook_menu() information from the view and the named display handler. + * + * @param $display_id + * A display id. + * @param $callbacks + * A menu callback array passed from views_menu_alter(). + */ + function execute_hook_menu($display_id = NULL, $callbacks = array()) { + // Prepare the view with the information we have. + + // This was probably already called, but it's good to be safe. + if (!$this->set_display($display_id)) { + return FALSE; + } + + // Execute the view + if (isset($this->display_handler)) { + return $this->display_handler->execute_hook_menu($callbacks); + } + } + + /** + * Called to get hook_block information from the view and the + * named display handler. + */ + function execute_hook_block_list($display_id = NULL) { + // Prepare the view with the information we have. + + // This was probably already called, but it's good to be safe. + if (!$this->set_display($display_id)) { + return FALSE; + } + + // Execute the view + if (isset($this->display_handler)) { + return $this->display_handler->execute_hook_block_list(); + } + } + + /** + * Determine if the given user has access to the view. Note that + * this sets the display handler if it hasn't been. + */ + function access($displays = NULL, $account = NULL) { + // Noone should have access to disabled views. + if (!empty($this->disabled)) { + return FALSE; + } + + if (!isset($this->current_display)) { + $this->init_display(); + } + + if (!$account) { + $account = $GLOBALS['user']; + } + + // We can't use choose_display() here because that function + // calls this one. + $displays = (array)$displays; + foreach ($displays as $display_id) { + if (!empty($this->display[$display_id]->handler)) { + if ($this->display[$display_id]->handler->access($account)) { + return TRUE; + } + } + } + + return FALSE; + } + + /** + * Get the view's current title. This can change depending upon how it + * was built. + */ + function get_title() { + if (empty($this->display_handler)) { + if (!$this->set_display('default')) { + return FALSE; + } + } + + // During building, we might find a title override. If so, use it. + if (!empty($this->build_info['title'])) { + $title = $this->build_info['title']; + } + else { + $title = $this->display_handler->get_option('title'); + } + + return $title; + } + + /** + * Force the view to build a title. + */ + function build_title() { + $this->init_display(); + + if (empty($this->built)) { + $this->init_query(); + } + + $this->init_handlers(); + + $this->_build_arguments(); + } + + /** + * Get the URL for the current view. + * + * This URL will be adjusted for arguments. + */ + function get_url($args = NULL, $path = NULL) { + if (!isset($path)) { + $path = $this->get_path(); + } + if (!isset($args)) { + $args = $this->args; + } + // Don't bother working if there's nothing to do: + if (empty($path) || (empty($args) && strpos($path, '%') === FALSE)) { + return $path; + } + + $pieces = array(); + $arguments = isset($arguments) ? $arguments : $this->display_handler->get_option('arguments'); + $argument_keys = isset($arguments) ? array_keys($arguments) : array(); + $id = current($argument_keys); + foreach (explode('/', $path) as $piece) { + if ($piece != '%') { + $pieces[] = $piece; + } + else { + if (empty($args)) { + // Try to never put % in a url; use the wildcard instead. + if ($id && !empty($arguments[$id]['wildcard'])) { + $pieces[] = $arguments[$id]['wildcard']; + } + else { + $pieces[] = '*'; // gotta put something if there just isn't one. + } + + } + else { + $pieces[] = array_shift($args); + } + + if ($id) { + $id = next($argument_keys); + } + } + } + + if (!empty($args)) { + $pieces = array_merge($pieces, $args); + } + return implode('/', $pieces); + } + + /** + * Get the base path used for this view. + */ + function get_path() { + if (!empty($this->override_path)) { + return $this->override_path; + } + + if (empty($this->display_handler)) { + if (!$this->set_display('default')) { + return FALSE; + } + } + return $this->display_handler->get_path(); + } + + /** + * Get the breadcrumb used for this view. + * + * @param $set + * If true, use drupal_set_breadcrumb() to install the breadcrumb. + */ + function get_breadcrumb($set = FALSE) { + // Now that we've built the view, extract the breadcrumb. + $base = TRUE; + $breadcrumb = array(); + + if (!empty($this->build_info['breadcrumb'])) { + foreach ($this->build_info['breadcrumb'] as $path => $title) { + // Check to see if the frontpage is in the breadcrumb trail; if it + // is, we'll remove that from the actual breadcrumb later. + if ($path == variable_get('site_frontpage', 'node')) { + $base = FALSE; + $title = t('Home'); + } + if ($title) { + $breadcrumb[] = l($title, $path, array('html' => true)); + } + } + + if ($set) { + if ($base) { + $breadcrumb = array_merge(drupal_get_breadcrumb(), $breadcrumb); + } + drupal_set_breadcrumb($breadcrumb); + } + } + return $breadcrumb; + } + + /** + * Is this view cacheable? + */ + function is_cacheable() { + return $this->is_cacheable; + } + + /** + * Set up query capturing. + * + * db_query() stores the queries that it runs in global $queries, + * bit only if dev_query is set to true. In this case, we want + * to temporarily override that setting if it's not and we + * can do that without forcing a db rewrite by just manipulating + * $conf. This is kind of evil but it works. + */ + function start_query_capture() { + global $conf, $queries; + if (empty($conf['dev_query'])) { + $this->fix_dev_query = TRUE; + $conf['dev_query'] = TRUE; + } + + // Record the last query key used; anything already run isn't + // a query that we are interested in. + $this->last_query_key = NULL; + + if (!empty($queries)) { + $keys = array_keys($queries); + $this->last_query_key = array_pop($keys); + } + } + + /** + * Add the list of queries run during render to buildinfo. + * + * @see view::start_query_capture() + */ + function end_query_capture() { + global $conf, $queries; + if (!empty($this->fix_dev_query)) { + $conf['dev_query'] = FALSE; + } + + // make a copy of the array so we can manipulate it with array_splice. + $temp = $queries; + + // Scroll through the queries until we get to our last query key. + // Unset anything in our temp array. + if (isset($this->last_query_key)) { + while (list($id, $query) = each($queries)) { + if ($id == $this->last_query_key) { + break; + } + + unset($temp[$id]); + } + } + + $this->additional_queries = $temp; + } + + /** + * Load a view from the database based upon either vid or name. + * + * This is a static factory method that implements internal caching for + * view objects. + * + * @param $arg + * The name of the view or its internal view id (vid) + * @param $reset + * If TRUE, reset this entry in the load cache. + * @return A view object or NULL if it was not available. + */ + static function &load($arg, $reset = FALSE) { + static $cache = array(); + + // We want a NULL value to return TRUE here, so we can't use isset() or empty(). + if (!array_key_exists($arg, $cache) || $reset) { + $result = db_select('views_view', 'v') + ->fields('v') + ->condition(is_numeric($arg) ? 'vid' : 'name', $arg) + ->execute(); + foreach ($result as $data) { + if (empty($data)) { + $cache[$arg] = NULL; + } + else { + $view = new view(); + $view->load_row($data); + $view->type = t('Normal'); + // Load all of our subtables. + foreach ($view->db_objects() as $key) { + $object_name = "views_$key"; + $result = db_select($object_name, 'v') + ->fields('v') + ->condition('vid', $view->vid) + ->orderBy('position') + ->execute(); + foreach ($result as $data) { + $object = new $object_name(FALSE); + $object->load_row($data); + + // Because it can get complicated with this much indirection, + // make a shortcut reference. + $location = &$view->$key; + + // If we have a basic id field, load the item onto the view based on + // this ID, otherwise push it on. + if (!empty($object->id)) { + $location[$object->id] = $object; + } + else { + $location[] = $object; + } + } + } + } + + $view->loaded = TRUE; + $cache[$arg] = $view; + } + } + + return $cache[$arg]; + } + + /** + * Static factory method to load a list of views based upon a $where clause. + * + * Although this method could be implemented to simply iterate over views::load(), + * that would be very slow. Buiding the views externally from unified queries is + * much faster. + */ + static function load_views() { + $result = db_query("SELECT DISTINCT v.* FROM {views_view} v"); + $views = array(); + $vids = array(); + + // Load all the views. + foreach ($result as $data) { + $view = new view; + $view->load_row($data); + $view->loaded = TRUE; + $view->type = t('Normal'); + $views[$view->name] = $view; + $names[$view->vid] = $view->name; + } + + // Stop if we didn't get any views. + if (!$views) { + return array(); + } + + $vids = implode(', ', array_keys($names)); + // Now load all the subtables: + foreach (view::db_objects() as $key) { + $object_name = "views_$key"; + $result = db_query("SELECT * FROM {{$object_name}} WHERE vid IN (:vids) ORDER BY vid, position", + array(':vids' => array_keys($names))); + + foreach ($result as $data) { + $object = new $object_name(FALSE); + $object->load_row($data); + + // Because it can get complicated with this much indirection, + // make a shortcut reference. + $location = &$views[$names[$object->vid]]->$key; + + // If we have a basic id field, load the item onto the view based on + // this ID, otherwise push it on. + if (!empty($object->id)) { + $location[$object->id] = $object; + } + else { + $location[] = $object; + } + } + } + return $views; + } + + /** + * Save the view to the database. If the view does not already exist, + * A vid will be assigned to the view and also returned from this function. + */ + function save() { + if ($this->vid == 'new') { + $this->vid = NULL; + } + + // If we have no vid or our vid is a string, this is a new view. + if (!empty($this->vid)) { + // remove existing table entries + foreach ($this->db_objects() as $key) { + db_delete('views_' . $key) + ->condition('vid', $this->vid) + ->execute(); + } + } + + $this->save_row(!empty($this->vid) ? 'vid' : FALSE); + + // Save all of our subtables. + foreach ($this->db_objects() as $key) { + $this->_save_rows($key); + } + + cache_clear_all('views_urls', 'cache_views'); + cache_clear_all(); // clear the page cache as well. + } + + /** + * Save a row to the database for the given key, which is one of the + * keys from view::db_objects() + */ + function _save_rows($key) { + $count = 0; + foreach ($this->$key as $position => $object) { + $object->position = ++$count; + $object->vid = $this->vid; + $object->save_row(); + } + } + + /** + * Delete the view from the database. + */ + function delete($clear = TRUE) { + if (empty($this->vid)) { + return; + } + + db_delete('views_view') + ->condition('vid', $this->vid) + ->execute(); + // Delete from all of our subtables as well. + foreach ($this->db_objects() as $key) { + db_delete('views_'. $key) + ->condition('vid', $this->vid) + ->execute(); + } + + cache_clear_all('views_query:' . $this->name, 'cache_views'); + + if ($clear) { + cache_clear_all(); // this clears the block and page caches only. + menu_rebuild(); // force a menu rebuild when a view is deleted. + } + } + + /** + * Export a view as PHP code. + */ + function export($indent = '') { + $this->init_display(); + $output = ''; + $output .= $this->export_row('view', $indent); + // Set the API version + $output .= $indent . '$view->api_version = \'' . views_api_version() . "';\n"; + $output .= $indent . '$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */' . "\n"; + + foreach ($this->display as $id => $display) { + $output .= "\n" . $indent . "/* Display: $display->display_title */\n"; + $output .= $indent . '$handler = $view->new_display(' . views_var_export($display->display_plugin, $indent) . ', ' . views_var_export($display->display_title, $indent) . ', \'' . $id . "');\n"; + if (empty($display->handler)) { + // @todo -- probably need a method of exporting broken displays as + // they may simply be broken because a module is not installed. That + // does not invalidate the display. + continue; + } + + $output .= $display->handler->export_options($indent, '$handler->options'); + } + + // Give the localization system a chance to export translatables to code. + if ($this->init_localization()) { + $this->export_locale_strings('export'); + $translatables = $this->localization_plugin->export_render($indent); + if (!empty($translatables)) { + $output .= $translatables; + } + } + + return $output; + } + + /** + * Make a copy of this view that has been sanitized of all database IDs + * and handlers and other stuff. + * + * I'd call this clone() but it's reserved. + */ + function copy() { + $code = $this->export(); + eval($code); + return $view; + } + + /** + * Safely clone a view. + * + * Because views are complicated objects within objects, and PHP loves to + * do references to everything, if a View is not properly and safely + * cloned it will still have references to the original view, and can + * actually cause the original view to point to objects in the cloned + * view. This gets ugly fast. + * + * This will completely wipe a view clean so it can be considered fresh. + */ + function clone_view() { + $clone = version_compare(phpversion(), '5.0') < 0 ? $this : clone($this); + + $keys = array('current_display', 'display_handler', 'build_info', 'built', 'executed', 'attachment_before', 'attachment_after', 'field', 'argument', 'filter', 'sort', 'relationship', 'header', 'footer', 'empty', 'query', 'inited', 'style_plugin', 'plugin_name', 'exposed_data', 'exposed_input', 'exposed_widgets', 'many_to_one_tables', 'feed_icon'); + foreach ($keys as $key) { + if (isset($clone->$key)) { + unset($clone->$key); + } + } + $clone->built = $clone->executed = FALSE; + $clone->build_info = array(); + $clone->attachment_before = ''; + $clone->attachment_after = ''; + $clone->result = array(); + + // shallow cloning means that all the display objects + // *were not cloned*. We must clone them ourselves. + $displays = array(); + foreach ($clone->display as $id => $display) { + $displays[$id] = clone $display; + if (isset($displays[$id]->handler)) { + unset($displays[$id]->handler); + } + } + $clone->display = $displays; + + return $clone; + } + + /** + * Unset references so that a $view object may be properly garbage + * collected. + */ + function destroy() { + foreach (array_keys($this->display) as $display_id) { + if (isset($this->display[$display_id]->handler)) { + $this->display[$display_id]->handler->destroy(); + unset($this->display[$display_id]->handler); + } + + foreach (views_object_types() as $type => $info) { + if (isset($this->$type)) { + $handlers = &$this->$type; + foreach ($handlers as $id => $item) { + $handlers[$id]->destroy(); + } + unset($handlers); + } + } + + if (isset($this->style_plugin)) { + $this->style_plugin->destroy(); + unset($this->style_plugin); + } + + // Clear these to make sure the view can be processed/used again. + if (isset($this->display_handler)) { + unset($this->display_handler); + } + + if (isset($this->current_display)) { + unset($this->current_display); + } + + if (isset($this->query)) { + unset($this->query); + } + + $keys = array('current_display', 'display_handler', 'build_info', 'built', 'executed', 'attachment_before', 'attachment_after', 'field', 'argument', 'filter', 'sort', 'relationship', 'header', 'footer', 'empty', 'query', 'result', 'inited', 'style_plugin', 'plugin_name', 'exposed_data', 'exposed_input', 'many_to_one_tables'); + foreach ($keys as $key) { + if (isset($this->$key)) { + unset($this->$key); + } + } + $this->built = $this->executed = FALSE; + $this->build_info = array(); + $this->attachment_before = ''; + $this->attachment_after = ''; + } + } + + /** + * Make sure the view is completely valid. + * + * @return + * TRUE if the view is valid; an array of error strings if it is not. + */ + function validate() { + $this->init_display(); + + $errors = array(); + + foreach ($this->display as $id => $display) { + if ($display->handler) { + if (!empty($display->deleted)) { + continue; + } + + $result = $this->display[$id]->handler->validate(); + if (!empty($result) && is_array($result)) { + $errors = array_merge($errors, $result); + } + } + } + + return $errors ? $errors : TRUE; + } + + /** + * Find and initialize the localizer plugin. + */ + function init_localization() { + if (isset($this->localization_plugin) && is_object($this->localization_plugin)) { + return TRUE; + } + + $this->localization_plugin = views_get_plugin('localization', variable_get('views_localization_plugin', 'core')); + + if (empty($this->localization_plugin)) { + return FALSE; + } + + /** + * Figure out whether there should be options. + */ + $this->localization_plugin->init($this); + + return $this->localization_plugin->translate; + } + + /** + * Determine whether a view supports admin string translation. + */ + function is_translatable() { + // If the view is normal or overridden, use admin string translation. + // A newly created view won't have a type. Accept this. + return (!isset($this->type) || in_array($this->type, array(t('Normal'), t('Overridden')))) ? TRUE : FALSE; + } + + /** + * Send strings for localization. + */ + function save_locale_strings() { + $this->process_locale_strings('save'); + } + + /** + * Delete localized strings. + */ + function delete_locale_strings() { + $this->process_locale_strings('delete'); + } + + /** + * Export localized strings. + */ + function export_locale_strings() { + $this->process_locale_strings('export'); + } + + /** + * Process strings for localization, deletion or export to code. + */ + function process_locale_strings($op) { + // Ensure this view supports translation, we have a display, and we + // have a localization plugin. + // @fixme Export does not init every handler. + if (($this->is_translatable() || $op == 'export') && $this->init_display() && $this->init_localization()) { + $this->localization_plugin->process_locale_strings($op); + } + } + +} + +/** + * Base class for views' database objects. + */ +class views_db_object { + /** + * Initialize this object, setting values from schema defaults. + * + * @param $init + * If an array, this is a set of values from db_fetch_object to + * load. Otherwse, if TRUE values will be filled in from schema + * defaults. + */ + function init($init = TRUE) { + if (is_array($init)) { + return $this->load_row($init); + } + + if (!$init) { + return; + } + + $schema = drupal_get_schema($this->db_table); + + if (!$schema) { + return; + } + + // Go through our schema and build correlations. + foreach ($schema['fields'] as $field => $info) { + if ($info['type'] == 'serial') { + $this->$field = NULL; + } + if (!isset($this->$field)) { + if (!empty($info['serialize']) && isset($info['serialized default'])) { + $this->$field = unserialize($info['serialized default']); + } + elseif (isset($info['default'])) { + $this->$field = $info['default']; + } + else { + $this->$field = ''; + } + } + } + } + + /** + * Write the row to the database. + * + * @param $update + * If true this will be an UPDATE query. Otherwise it will be an INSERT. + */ + function save_row($update = NULL) { + $fields = $defs = $values = $serials = array(); + $schema = drupal_get_schema($this->db_table); + + // Go through our schema and build correlations. + foreach ($schema['fields'] as $field => $info) { + // special case -- skip serial types if we are updating. + if ($info['type'] == 'serial') { + $serials[] = $field; + continue; + } + elseif ($info['type'] == 'int') { + $this->$field = (int) $this->$field; + } + $fields[$field] = empty($info['serialize']) ? $this->$field : serialize($this->$field); + } + if (!$update) { + $query = db_insert($this->db_table); + } + else { + $query = db_update($this->db_table) + ->condition($update, $this->$update); + } + $return = $query + ->fields($fields) + ->execute(); + + if ($serials && !$update) { + // get last insert ids and fill them in. + // Well, one ID. + foreach ($serials as $field) { + $this->$field = $return; + } + } + } + + /** + * Load the object with a row from the database. + * + * This method is separate from the constructor in order to give us + * more flexibility in terms of how the view object is built in different + * contexts. + * + * @param $data + * An object from db_fetch_object. It should contain all of the fields + * that are in the schema. + */ + function load_row($data) { + $schema = drupal_get_schema($this->db_table); + + // Go through our schema and build correlations. + foreach ($schema['fields'] as $field => $info) { + $this->$field = empty($info['serialize']) ? $data->$field : unserialize($data->$field); + } + } + + /** + * Export a loaded row, such as an argument, field or the view itself to PHP code. + * + * @param $identifier + * The variable to assign the PHP code for this object to. + * @param $indent + * An optional indentation for prettifying nested code. + */ + function export_row($identifier = NULL, $indent = '') { + if (!$identifier) { + $identifier = $this->db_table; + } + $schema = drupal_get_schema($this->db_table); + + $output = $indent . '$' . $identifier . ' = new ' . get_class($this) . ";\n"; + // Go through our schema and build correlations. + foreach ($schema['fields'] as $field => $info) { + if (!empty($info['no export'])) { + continue; + } + if (!isset($this->$field)) { + if (isset($info['default'])) { + $this->$field = $info['default']; + } + else { + $this->$field = ''; + } + + // serialized defaults must be set as serialized. + if (isset($info['serialize'])) { + $this->$field = unserialize(db_decode_blob($this->$field)); + } + } + $value = $this->$field; + if ($info['type'] == 'int') { + if (isset($info['size']) && $info['size'] == 'tiny') { + $value = (bool) $value; + } + else { + $value = (int) $value; + } + } + + $output .= $indent . '$' . $identifier . '->' . $field . ' = ' . views_var_export($value, $indent) . ";\n"; + } + return $output; + } + + /** + * Add a new display handler to the view, automatically creating an id. + * + * @param $type + * The plugin type from the views plugin data. Defaults to 'page'. + * @param $title + * The title of the display; optional, may be filled in from default. + * @param $id + * The id to use. + * @return + * The key to the display in $view->display, so that the new display + * can be easily located. + */ + function add_display($type = 'page', $title = NULL, $id = NULL) { + if (empty($type)) { + return FALSE; + } + + $plugin = views_fetch_plugin_data('display', $type); + if (empty($plugin)) { + $plugin['title'] = t('Broken'); + } + + + if (empty($id)) { + $title = $plugin['title']; + + $id = $this->generate_display_id($type); + $count = str_replace($type . '_', '', $id); + if (empty($title)) { + $title = $plugin['title'] . ' ' . $count; + } + } + + // Create the new display object + $display = new views_display; + $display->options($type, $id, $title); + + // Add the new display object to the view. + $this->display[$id] = $display; + return $id; + } + + /** + * Generate a display id of a certain plugin type. + * + * @param $type + * Which plugin should be used for the new display id. + */ + function generate_display_id($type) { + // 'default' is singular and is unique, so just go with 'default' + // for it. For all others, start counting. + if ($type == 'default') { + return 'default'; + } + // Initial id. + $id = $type . '_1'; + $count = 1; + + // Loop through IDs based upon our style plugin name until + // we find one that is unused. + while (!empty($this->display[$id])) { + $id = $type . '_' . ++$count; + } + + return $id; + } + + /** + * Create a new display and a display handler for it. + * @param $type + * The plugin type from the views plugin data. Defaults to 'page'. + * @param $title + * The title of the display; optional, may be filled in from default. + * @param $id + * The id to use. + * @return + * A reference to the new handler object. + */ + function &new_display($type = 'page', $title = NULL, $id = NULL) { + $id = $this->add_display($type, $title, $id); + + // Create a handler + $this->display[$id]->handler = views_get_plugin('display', $this->display[$id]->display_plugin); + if (empty($this->display[$id]->handler)) { + // provide a 'default' handler as an emergency. This won't work well but + // it will keep things from crashing. + $this->display[$id]->handler = views_get_plugin('display', 'default'); + } + + if (!empty($this->display[$id]->handler)) { + // Initialize the new display handler with data. + $this->display[$id]->handler->init($this, $this->display[$id]); + // If this is NOT the default display handler, let it know which is + if ($id != 'default') { + $this->display[$id]->handler->default_display = &$this->display['default']->handler; + } + } + + return $this->display[$id]->handler; + } + + /** + * Add an item with a handler to the view. + * + * These items may be fields, filters, sort criteria, or arguments. + */ + function add_item($display_id, $type, $table, $field, $options = array(), $id = NULL) { + $types = views_object_types(); + $this->set_display($display_id); + + $fields = $this->display[$display_id]->handler->get_option($types[$type]['plural']); + + if (empty($id)) { + $count = 0; + $id = $field; + while (!empty($fields[$id])) { + $id = $field . '_' . ++$count; + } + } + + $new_item = array( + 'id' => $id, + 'table' => $table, + 'field' => $field, + ) + $options; + + if (!empty($types[$type]['type'])) { + $handler_type = $types[$type]['type']; + } + else { + $handler_type = $type; + } + + $handler = views_get_handler($table, $field, $handler_type); + + $fields[$id] = $new_item; + $this->display[$display_id]->handler->set_option($types[$type]['plural'], $fields); + + return $id; + } + + /** + * Get an array of items for the current display. + */ + function get_items($type, $display_id = NULL) { + $this->set_display($display_id); + + if (!isset($display_id)) { + $display_id = $this->current_display; + } + + // Get info about the types so we can get the right data. + $types = views_object_types(); + return $this->display[$display_id]->handler->get_option($types[$type]['plural']); + } + + /** + * Get the configuration of an item (field/sort/filter/etc) on a given + * display. + */ + function get_item($display_id, $type, $id) { + // Get info about the types so we can get the right data. + $types = views_object_types(); + // Initialize the display + $this->set_display($display_id); + + // Get the existing configuration + $fields = $this->display[$display_id]->handler->get_option($types[$type]['plural']); + + return isset($fields[$id]) ? $fields[$id] : NULL; + } + + /** + * Get the configuration of an item (field/sort/filter/etc) on a given + * display. + * + * Pass in NULL for the $item to remove an item. + */ + function set_item($display_id, $type, $id, $item) { + // Get info about the types so we can get the right data. + $types = views_object_types(); + // Initialize the display + $this->set_display($display_id); + + // Get the existing configuration + $fields = $this->display[$display_id]->handler->get_option($types[$type]['plural']); + if (isset($item)) { + $fields[$id] = $item; + } + else { + unset($fields[$id]); + } + + // Store. + $this->display[$display_id]->handler->set_option($types[$type]['plural'], $fields); + } + + /** + * Set an option on an item. + * + * Use this only if you have just 1 or 2 options to set; if you have + * many, consider getting the item, adding the options and doing + * set_item yourself. + */ + function set_item_option($display_id, $type, $id, $option, $value) { + $item = $this->get_item($display_id, $type, $id); + $item[$option] = $value; + $this->set_item($display_id, $type, $id, $item); + } +} + +/** + * A display type in a view. + * + * This is just the database storage mechanism, and isn't terribly important + * to the behavior of the display at all. + */ +class views_display extends views_db_object { + var $db_table = 'views_display'; + function views_display($init = TRUE) { + parent::init($init); + } + + function options($type, $id, $title) { + $this->display_plugin = $type; + $this->id = $id; + $this->display_title = $title; + } +} + +/** + * Provide a list of views object types used in a view, with some information + * about them. + */ +function views_object_types() { + static $retval = NULL; + + // statically cache this so t() doesn't run a bajillion times. + if (!isset($retval)) { + $retval = array( + 'field' => array( + 'title' => t('Fields'), // title + 'ltitle' => t('fields'), // lowercase title for mid-sentence + 'stitle' => t('Field'), // singular title + 'lstitle' => t('field'), // singular lowercase title for mid sentence + 'plural' => 'fields', + ), + 'argument' => array( + 'title' => t('Arguments'), + 'ltitle' => t('arguments'), + 'stitle' => t('Argument'), + 'lstitle' => t('Argument'), + 'plural' => 'arguments', + ), + 'sort' => array( + 'title' => t('Sort criteria'), + 'ltitle' => t('sort criteria'), + 'stitle' => t('Sort criterion'), + 'lstitle' => t('sort criterion'), + 'plural' => 'sorts', + ), + 'filter' => array( + 'title' => t('Filters'), + 'ltitle' => t('filters'), + 'stitle' => t('Filter'), + 'lstitle' => t('filter'), + 'plural' => 'filters', + 'options' => 'views_ui_config_filters_form', + ), + 'relationship' => array( + 'title' => t('Relationships'), + 'ltitle' => t('relationships'), + 'stitle' => t('Relationship'), + 'lstitle' => t('Relationship'), + 'plural' => 'relationships', + ), + 'header' => array( + 'title' => t('Header'), + 'ltitle' => t('header'), + 'stitle' => t('Header'), + 'lstitle' => t('Header'), + 'plural' => 'header', + 'type' => 'area', + ), + 'footer' => array( + 'title' => t('Footer'), + 'ltitle' => t('footer'), + 'stitle' => t('Footer'), + 'lstitle' => t('Footer'), + 'plural' => 'footer', + 'type' => 'area', + ), + 'empty' => array( + 'title' => t('Empty text'), + 'ltitle' => t('empty text'), + 'stitle' => t('Empty text'), + 'lstitle' => t('Empty text'), + 'plural' => 'empty', + 'type' => 'area', + ), + ); + } + + return $retval; +} + +/** + * @} + */ diff --git a/sites/all/modules/views/js/ajax.js b/sites/all/modules/views/js/ajax.js new file mode 100644 index 0000000000000000000000000000000000000000..3fa17cd689c93bd3afef145f1a2d21588fe298d0 --- /dev/null +++ b/sites/all/modules/views/js/ajax.js @@ -0,0 +1,129 @@ +// $Id: ajax.js,v 1.26.4.12 2010/08/03 05:54:01 dereine Exp $ +/** + * @file ajax_admin.js + * + * Handles AJAX submission and response in Views UI. + */ +(function ($) { + + Drupal.ajax.prototype.commands.viewsSetForm = function(ajax, response, status) { + var ajax_title = Drupal.settings.views.ajax.title; + var ajax_area = Drupal.settings.views.ajax.id; + $(ajax_title).html(response.title); + $(ajax_area).html(response.output); + Drupal.attachBehaviors($(ajax_area).add($(ajax_title)), ajax.settings); + if (response.url) { + var submit = $('input[type=submit]', ajax_area).unbind('click').click(function() { + $('form', ajax_area).append('<input type="hidden" name="' + $(this).attr('name') + '" value="' + $(this).val() + '">'); + $(this).after('<span class="views-throbbing"> </span>'); + }) + $('form', ajax_area).once('views-ajax-submit-processed').each(function() { + var element_settings = { 'url': response.url, 'event': 'submit', 'progress': { 'type': 'throbber' } }; + var form = $(this)[0]; + form.form = form; + Drupal.ajax[$(this).attr('id')] = new Drupal.ajax($(this).attr('id'), form, element_settings); + }); + } + }; + + Drupal.ajax.prototype.commands.viewsDismissForm = function(ajax, response, status) { + Drupal.ajax.prototype.commands.viewsSetForm({}, {'title': '', 'output': Drupal.settings.views.ajax.defaultForm}); + } + + Drupal.ajax.prototype.commands.viewsHilite = function(ajax, response, status) { + $('.hilited').removeClass('hilited'); + $(response.selector).addClass('hilited'); + }; + + Drupal.ajax.prototype.commands.viewsAddTab = function(ajax, response, status) { + var id = '#views-tab-' + response.id; + $('#views-tabset').viewsAddTab(id, response.title, 0); + $(id).html(response.body).addClass('views-tab'); + + // Update the preview widget to preview the new tab. + var display_id = id.replace('#views-tab-', ''); + $("#preview-display-id").append('<option selected="selected" value="' + display_id + '">' + response.title + '</option>'); + + Drupal.attachBehaviors(id); + var instance = $.viewsUi.tabs.instances[$('#views-tabset').get(0).UI_TABS_UUID]; + $('#views-tabset').viewsClickTab(instance.$tabs.length); + }; + + Drupal.ajax.prototype.commands.viewsDisableButtons = function(ajax, response, status) { + $('#views-ui-edit-view-form input').attr('disabled', 'disabled'); + } + + Drupal.ajax.prototype.commands.viewsEnableButtons = function(ajax, response, status) { + $('#views-ui-edit-view-form input').removeAttr('disabled'); + } + + Drupal.ajax.prototype.commands.viewsTriggerPreview = function(ajax, response, status) { + if ($('#views-live-preview div.form-item-live-preview input').is(':checked')) { + $('#views-live-preview input[type=submit]').trigger('click'); + } + } + + /** + * Get rid of irritating tabledrag messages + */ + Drupal.theme.tableDragChangedWarning = function () { + return []; + } + + /** + * Sync preview display. + */ + Drupal.behaviors.syncPreviewDisplay = { + attach: function(context) { + $("#views-tabset a").once('views-ajax-processed').click(function() { + var href = $(this).attr('href'); + // Cut of #views-tabset. + var display_id = href.substr(11); + // Set the form element. + $("#views-live-preview #preview-display-id").val(display_id); + }).addClass('views-ajax-processed'); + } + } + + Drupal.behaviors.viewsAjax = { + attach: function(context) { + var base_element_settings = { + 'event': 'click', + 'progress': { 'type': 'throbber' } + }; + // Bind AJAX behaviors to all items showing the class. + $('.views-ajax-link', context).once('views-ajax-processed').each(function () { + var element_settings = base_element_settings; + // Set the URL to go to the anchor. + if ($(this).attr('href')) { + element_settings.url = $(this).attr('href'); + } + var base = $(this).attr('id'); + Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings); + }); + + $('div#views-live-preview form input[type=submit], div#views-live-preview a') + .once('views-ajax-processed').each(function () { + var element_settings = base_element_settings; + // Set the URL to go to the anchor. + if ($(this).attr('href')) { + element_settings.url = $(this).attr('href'); + if (element_settings.url.substring(0, 22) != '/admin/structure/views') { + return true; + } + } + else if ($(this).attr('action')) { + element_settings.url = $(this).attr('action'); + } + else if (this.form && $(this.form).attr('action')) { + element_settings.url = $(this.form).attr('action'); + } + + var base = $(this).attr('id'); + Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings); + }); + + } + }; + +})(jQuery); diff --git a/sites/all/modules/views/js/ajax_view.js b/sites/all/modules/views/js/ajax_view.js new file mode 100644 index 0000000000000000000000000000000000000000..8ed6466a53c50d2954d924b6f9e01322d425a64c --- /dev/null +++ b/sites/all/modules/views/js/ajax_view.js @@ -0,0 +1,84 @@ +// $Id: ajax_view.js,v 1.19.4.4 2011/01/03 22:56:39 merlinofchaos Exp $ + +/** + * @file ajaxView.js + * + * Handles AJAX fetching of views, including filter submission and response. + */ +(function ($) { + +/** + * Attaches the AJAX behavior to Views exposed filter forms and key View links. + */ +Drupal.behaviors.ViewsAjaxView = {}; +Drupal.behaviors.ViewsAjaxView.attach = function() { + if (Drupal.settings && Drupal.settings.views && Drupal.settings.views.ajaxViews) { + // Retrieve the path to use for views' ajax. + var ajax_path = Drupal.settings.views.ajax_path; + + // If there are multiple views this might've ended up showing up multiple times. + if (ajax_path.constructor.toString().indexOf("Array") != -1) { + ajax_path = ajax_path[0]; + } + + $.each(Drupal.settings.views.ajaxViews, function(i, settings) { + var view = '.view-dom-id-' + settings.view_dom_id; + var element_settings = { + url: ajax_path, + submit: settings, + setClick: true, + event: 'click', + selector: view, + progress: { type: 'throbber' } + }; + + // Process exposed filter forms. + $('form#views-exposed-form-' + settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-')) + .filter(':not(.views-processed)') + .each(function () { + var button = $('input[type=submit]', this); + button.form = this; + + var ajax = new Drupal.ajax($(button).attr('id'), button, element_settings); + }) + .addClass('views-processed') + + $(view).filter(':not(.views-processed)') + // Don't attach to nested views. Doing so would attach multiple behaviors + // to a given element. + .filter(function() { + // If there is at least one parent with a view class, this view + // is nested (e.g., an attachment). Bail. + return !$(this).parents('.view').size(); + }) + .each(function() { + // Set a reference that will work in subsequent calls. + var target = this; + $(this) + .addClass('views-processed') + // Process pager, tablesort, and attachment summary links. + .find('ul.pager > li > a, th.views-field a, .attachment .views-summary a') + .each(function () { + var viewData = {}; + // Construct an object using the settings defaults and then overriding + // with data specific to the link. + $.extend( + viewData, + settings, + Drupal.Views.parseQueryString($(this).attr('href')), + // Extract argument data from the URL. + Drupal.Views.parseViewArgs($(this).attr('href'), settings.view_base_path) + ); + + // For anchor tags, these will go to the target of the anchor rather + // than the usual location. + $.extend(viewData, Drupal.Views.parseViewArgs($(this).attr('href'), settings.view_base_path)); + + element_settings.submit = viewData; + var ajax = new Drupal.ajax(false, this, element_settings); + }); // .each function () { + }); // $view.filter().each + }); // .each Drupal.settings.views.ajaxViews + } // if +}; +})(jQuery); diff --git a/sites/all/modules/views/js/base.js b/sites/all/modules/views/js/base.js new file mode 100644 index 0000000000000000000000000000000000000000..c1373a3dd9f9e88d183af615fa8a02576a5b3489 --- /dev/null +++ b/sites/all/modules/views/js/base.js @@ -0,0 +1,140 @@ +// $Id: base.js,v 1.11.4.5 2010/11/20 23:49:29 dereine Exp $ +/** + * @file base.js + * + * Some basic behaviors and utility functions for Views. + */ +(function ($) { + +Drupal.Views = {}; + +/** + * jQuery UI tabs, Views integration component + */ +Drupal.behaviors.viewsTabs = { + attach: function (context) { + if ($.viewsUi && $.viewsUi.tabs) { + $('#views-tabset').once('views-processed').viewsTabs({ + selectedClass: 'active' + }); + } + + $('a.views-remove-link').once('views-processed').click(function() { + var id = $(this).attr('id').replace('views-remove-link-', ''); + $('#views-row-' + id).hide(); + $('#views-removed-' + id).attr('checked', true); + return false; + }); + /** + * Here is to handle display deletion + * (checking in the hidden checkbox and hiding out the row) + */ + $('a.display-remove-link') + .addClass('display-processed') + .click(function() { + var id = $(this).attr('id').replace('display-remove-link-', ''); + $('#display-row-' + id).hide(); + $('#display-removed-' + id).attr('checked', true); + return false; + }); + } +}; + +/** + * For IE, attach some javascript so that our hovers do what they're supposed + * to do. + */ +Drupal.behaviors.viewsHoverlinks = function() { + if ($.browser.msie) { + // If IE, attach a hover event so we can see our admin links. + $("div.view:not(.views-hover-processed)").addClass('views-hover-processed').hover( + function() { + $('div.views-hide', this).addClass("views-hide-hover"); return true; + }, + function(){ + $('div.views-hide', this).removeClass("views-hide-hover"); return true; + } + ); + $("div.views-admin-links:not(.views-hover-processed)") + .addClass('views-hover-processed') + .hover( + function() { + $(this).addClass("views-admin-links-hover"); return true; + }, + function(){ + $(this).removeClass("views-admin-links-hover"); return true; + } + ); + } +} + +/** + * Helper function to parse a querystring. + */ +Drupal.Views.parseQueryString = function (query) { + var args = {}; + var pos = query.indexOf('?'); + if (pos != -1) { + query = query.substring(pos + 1); + } + var pairs = query.split('&'); + for(var i in pairs) { + if (typeof(pairs[i]) == 'string') { + var pair = pairs[i].split('='); + // Ignore the 'q' path argument, if present. + if (pair[0] != 'q' && pair[1]) { + args[pair[0]] = decodeURIComponent(pair[1].replace(/\+/g, ' ')); + } + } + } + return args; +}; + +/** + * Helper function to return a view's arguments based on a path. + */ +Drupal.Views.parseViewArgs = function (href, viewPath) { + var returnObj = {}; + var path = Drupal.Views.getPath(href); + // Ensure we have a correct path. + if (viewPath && path.substring(0, viewPath.length + 1) == viewPath + '/') { + var args = decodeURIComponent(path.substring(viewPath.length + 1, path.length)); + returnObj.view_args = args; + returnObj.view_path = path; + } + return returnObj; +}; + +/** + * Strip off the protocol plus domain from an href. + */ +Drupal.Views.pathPortion = function (href) { + // Remove e.g. http://example.com if present. + var protocol = window.location.protocol; + if (href.substring(0, protocol.length) == protocol) { + // 2 is the length of the '//' that normally follows the protocol + href = href.substring(href.indexOf('/', protocol.length + 2)); + } + return href; +}; + +/** + * Return the Drupal path portion of an href. + */ +Drupal.Views.getPath = function (href) { + href = Drupal.Views.pathPortion(href); + href = href.substring(Drupal.settings.basePath.length, href.length); + // 3 is the length of the '?q=' added to the url without clean urls. + if (href.substring(0, 3) == '?q=') { + href = href.substring(3, href.length); + } + var chars = ['#', '?', '&']; + for (i in chars) { + if (href.indexOf(chars[i]) > -1) { + href = href.substr(0, href.indexOf(chars[i])); + } + } + return href; +}; + +})(jQuery); diff --git a/sites/all/modules/views/js/tabs.js b/sites/all/modules/views/js/tabs.js new file mode 100644 index 0000000000000000000000000000000000000000..89aef3f179d9faa2bce1043f95fd4ef1ab4819a9 --- /dev/null +++ b/sites/all/modules/views/js/tabs.js @@ -0,0 +1,438 @@ +// $Id: tabs.js,v 1.4.4.4 2010/03/20 23:16:37 dereine Exp $ + +/** + * @file tabs.js + * jQuery UI Tabs (Tabs 3) + * + * This is nothing more than the pure jquery UI tabs implementation. + */ +(function($) { + + // if the UI scope is not availalable, add it + $.viewsUi = $.viewsUi || {}; + + $.fn.viewsTabs = function(initial, options) { + if (initial && initial.constructor == Object) { // shift arguments + options = initial; + initial = null; + } + options = options || {}; + + // first get initial tab from options + initial = initial && initial.constructor == Number && --initial || 0; + + return this.each(function() { + new $.viewsUi.tabs(this, $.extend(options, { initial: initial })); + }); + }; + + // chainable tabs methods + $.each(['Add', 'Remove', 'Enable', 'Disable', 'Click', 'Load'], function(i, method) { + $.fn['views' + method + 'Tab'] = function() { + var args = arguments; + return this.each(function() { + var instance = $.viewsUi.tabs.instances[this.UI_TABS_UUID]; + instance[method.toLowerCase()].apply(instance, args); + }); + }; + }); + $.fn.viewsSelectedTab = function(returnElement) { + var selected; + if (returnElement) { + + } else { + + } + return selected; + }; + + $.viewsUi.tabs = function(el, options) { + + this.source = el; + + this.options = $.extend({ + + // basic setup + initial: 0, + event: 'click', + disabled: [], + // TODO bookmarkable: $.ajaxHistory ? true : false, + unselected: false, + toggle: options.unselected ? true : false, + + // Ajax + spinner: 'Loading…', + cache: false, + hashPrefix: 'tab-', + + // animations + /*fxFade: null, + fxSlide: null, + fxShow: null, + fxHide: null,*/ + fxSpeed: 'normal', + /*fxShowSpeed: null, + fxHideSpeed: null,*/ + + // callbacks + add: function() {}, + remove: function() {}, + enable: function() {}, + disable: function() {}, + click: function() {}, + hide: function() {}, + show: function() {}, + load: function() {}, + + // CSS classes + navClass: 'ui-tabs-nav', + selectedClass: 'ui-tabs-selected', + disabledClass: 'ui-tabs-disabled', + containerClass: 'ui-tabs-container', + hideClass: 'ui-tabs-hide', + loadingClass: 'ui-tabs-loading' + + }, options); + + this.tabify(true); + + // save instance for later + var uuid = 'instance-' + $.viewsUi.tabs.prototype.count++; + $.viewsUi.tabs.instances[uuid] = this; + this.source['UI_TABS_UUID'] = uuid; + + }; + + // static + $.viewsUi.tabs.instances = {}; + + $.extend($.viewsUi.tabs.prototype, { + animating: false, + count: 0, + tabify: function(init) { + + this.$tabs = $('a:first-child', this.source); + this.$containers = $([]); + + var self = this, o = this.options; + + this.$tabs.each(function(i, a) { + // inline tab + if (a.hash && a.hash.replace('#', '')) { // safari 2 reports '#' for an empty hash + self.$containers = self.$containers.add(a.hash); + } + // remote tab + else { + var id = a.title && a.title.replace(/\s/g, '_') || o.hashPrefix + (self.count + 1) + '-' + (i + 1), url = a.href; + a.href = '#' + id; + a.url = url; + self.$containers = self.$containers.add( + $('#' + id)[0] || $('<div id="' + id + '" class="' + o.containerClass + '"></div>') + .insertAfter( self.$containers[i - 1] || self.source ) + ); + } + }); + + if (init) { + + // Try to retrieve initial tab from fragment identifier in url if present, + // otherwise try to find selected class attribute on <li>. + this.$tabs.each(function(i, a) { + if (location.hash) { + if (a.hash == location.hash) { + o.initial = i; + // prevent page scroll to fragment + //if (($.browser.msie || $.browser.opera) && !o.remote) { + if ($.browser.msie || $.browser.opera) { + var $toShow = $(location.hash), toShowId = $toShow.attr('id'); + $toShow.attr('id', ''); + setTimeout(function() { + $toShow.attr('id', toShowId); // restore id + }, 500); + } + scrollTo(0, 0); + return false; // break + } + } else if ( $(a).parents('li:eq(0)').is('li.' + o.selectedClass) ) { + o.initial = i; + return false; // break + } + }); + + // attach necessary classes for styling if not present + $(this.source).is('.' + o.navClass) || $(this.source).addClass(o.navClass); + this.$containers.each(function() { + var $this = $(this); + $this.is('.' + o.containerClass) || $this.addClass(o.containerClass); + }); + + // highlight tab accordingly + var $lis = $('li', this.source); + this.$containers.addClass(o.hideClass); + $lis.removeClass(o.selectedClass); + if (!o.unselected) { + this.$containers.slice(o.initial, o.initial + 1).css('display', 'block'); + $lis.slice(o.initial, o.initial + 1).addClass(o.selectedClass); + } + + // trigger load of initial tab is remote tab + if (this.$tabs[o.initial].url) { + this.load(o.initial + 1, this.$tabs[o.initial].url); + if (o.cache) { + this.$tabs[o.initial].url = null; // if loaded once do not load them again + } + } + + // disabled tabs + for (var i = 0, position; position = o.disabled[i]; i++) { + this.disable(position); + } + + } + + // setup animations + var showAnim = {}, hideAnim = {}, showSpeed = o.fxShowSpeed || o.fxSpeed, + hideSpeed = o.fxHideSpeed || o.fxSpeed; + if (o.fxSlide || o.fxFade) { + if (o.fxSlide) { + showAnim['height'] = 'show'; + hideAnim['height'] = 'hide'; + } + if (o.fxFade) { + showAnim['opacity'] = 'show'; + hideAnim['opacity'] = 'hide'; + } + } else { + if (o.fxShow) { + showAnim = o.fxShow; + } else { // use some kind of animation to prevent browser scrolling to the tab + showAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox + showSpeed = 1; // as little as 1 is sufficient + } + if (o.fxHide) { + hideAnim = o.fxHide; + } else { // use some kind of animation to prevent browser scrolling to the tab + hideAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox + hideSpeed = 1; // as little as 1 is sufficient + } + } + + // callbacks + var click = o.click, hide = o.hide, show = o.show; + + // reset some styles to maintain print style sheets etc. + var resetCSS = { display: '', overflow: '', height: '' }; + if (!$.browser.msie) { // not in IE to prevent ClearType font issue + resetCSS['opacity'] = ''; + } + + // hide a tab, animation prevents browser scrolling to fragment + function hideTab(clicked, $hide, $show) { + $hide.animate(hideAnim, hideSpeed, function() { // + $hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc. + hide(clicked, $show, $hide[0]); + if ($show) { + showTab(clicked, $hide, $show); + } + }); + } + + // show a tab, animation prevents browser scrolling to fragment + function showTab(clicked, $hide, $show) { + // show next tab + if (!(o.fxSlide || o.fxFade || o.fxShow)) { + $show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab containers + } + $show.animate(showAnim, showSpeed, function() { + $show.removeClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc. + if ($.browser.msie) { + $hide[0].style.filter = ''; + $show[0].style.filter = ''; + } + show(clicked, $show[0], $hide[0]); + self.animating = false; + }); + + } + + // switch a tab + function switchTab(clicked, $hide, $show) { + /*if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click + $.ajaxHistory.update(clicked.hash); + }*/ + $(clicked).parents('li:eq(0)').addClass(o.selectedClass) + .siblings().removeClass(o.selectedClass); + hideTab(clicked, $hide, $show); + } + + // tab click handler + function tabClick(e) { + + //var trueClick = e.clientX; // add to history only if true click occured, not a triggered click + var $li = $(this).parents('li:eq(0)'), $hide = self.$containers.filter(':visible'), $show = $(this.hash); + + // if tab may be closed + if (o.toggle && !$li.is('.' + o.disabledClass) && !self.animating) { + if ($li.is('.' + o.selectedClass)) { + $li.removeClass(o.selectedClass); + hideTab(this, $hide); + this.blur(); + return false; + } else if (!$hide.length) { + $li.addClass(o.selectedClass); + showTab(this, $hide, $show); + this.blur(); + return false; + } + } + + // If tab is already selected or disabled, animation is still running or click callback + // returns false stop here. + // Check if click handler returns false last so that it is not executed for a disabled tab! + if ($li.is('.' + o.selectedClass + ', .' + o.disabledClass) + || self.animating || click(this, $show[0], $hide[0]) === false) { + this.blur(); + return false; + } + + self.animating = true; + + // show new tab + if ($show.length) { + + // prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled + /*if ($.browser.msie && o.bookmarkable) { + var showId = this.hash.replace('#', ''); + $show.attr('id', ''); + setTimeout(function() { + $show.attr('id', showId); // restore id + }, 0); + }*/ + + if (this.url) { // remote tab + var a = this; + self.load(self.$tabs.index(this) + 1, this.url, function() { + switchTab(a, $hide, $show); + }); + if (o.cache) { + this.url = null; // if loaded once do not load them again + } + } else { + switchTab(this, $hide, $show); + } + + // Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash + /*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0; + var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0; + setTimeout(function() { + scrollTo(scrollX, scrollY); + }, 0);*/ + + } else { + throw Drupal.t('jQuery UI Tabs: Mismatching fragment identifier.'); + } + + this.blur(); // prevent IE from keeping other link focussed when using the back button + + //return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE + return false; + + } + + // attach click event, avoid duplicates from former tabifying + this.$tabs.unbind(o.event, tabClick).bind(o.event, tabClick); + + }, + add: function(url, text, position) { + if (url && text) { + var o = this.options; + position = position || this.$tabs.length; // append by default + if (position >= this.$tabs.length) { + var method = 'insertAfter'; + position = this.$tabs.length; + } else { + var method = 'insertBefore'; + } + if (url.indexOf('#') == 0) { // ajax container is created by tabify automatically + var $container = $(url); + // try to find an existing element before creating a new one + ($container.length && $container || $('<div id="' + url.replace('#', '') + '" class="' + o.containerClass + ' ' + o.hideClass + '"></div>')) + [method](this.$containers[position - 1]); + } + $('<li><a href="' + url + '"><span>' + text + '</span></a></li>') + [method](this.$tabs.slice(position - 1, position).parents('li:eq(0)')); + this.tabify(); + o.add(this.$tabs[position - 1], this.$containers[position - 1]); // callback + } else { + throw Drupal.t('jQuery UI Tabs: Not enough arguments to add tab.'); + } + }, + remove: function(position) { + if (position && position.constructor == Number) { + this.$tabs.slice(position - 1, position).parents('li:eq(0)').remove(); + this.$containers.slice(position - 1, position).remove(); + this.tabify(); + } + this.options.remove(); // callback + }, + enable: function(position) { + var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options; + $li.removeClass(o.disabledClass); + if ($.browser.safari) { // fix disappearing tab after enabling in Safari... TODO check Safari 3 + $li.animate({ opacity: 1 }, 1, function() { + $li.css({ opacity: '' }); + }); + } + o.enable(this.$tabs[position - 1], this.$containers[position - 1]); // callback + }, + disable: function(position) { + var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options; + if ($.browser.safari) { // fix opacity of tab after disabling in Safari... TODO check Safari 3 + $li.animate({ opacity: 0 }, 1, function() { + $li.css({ opacity: '' }); + }); + } + $li.addClass(this.options.disabledClass); + o.disable(this.$tabs[position - 1], this.$containers[position - 1]); // callback + }, + click: function(position) { + this.$tabs.slice(position - 1, position).trigger('click'); + }, + load: function(position, url, callback) { + var self = this, + o = this.options, + $a = this.$tabs.slice(position - 1, position).addClass(o.loadingClass), + $span = $('span', $a), + text = $span.html(); + + // shift arguments + if (url && url.constructor == Function) { + callback = url; + } + + // set new URL + if (url) { + $a[0].url = url; + } + + // load + if (o.spinner) { + $span.html('<em>' + o.spinner + '</em>'); + } + setTimeout(function() { // timeout is again required in IE, "wait" for id being restored + $($a[0].hash).load(url, function() { + if (o.spinner) { + $span.html(text); + } + $a.removeClass(o.loadingClass); + // This callback is needed because the switch has to take place after loading + // has completed. + if (callback && callback.constructor == Function) { + callback(); + } + o.load(self.$tabs[position - 1], self.$containers[position - 1]); // callback + }); + }, 0); + } + }); +})(jQuery); diff --git a/sites/all/modules/views/modules/aggregator.views.inc b/sites/all/modules/views/modules/aggregator.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..014b426a23f837e8ae2b80f5892cd3dc1c011028 --- /dev/null +++ b/sites/all/modules/views/modules/aggregator.views.inc @@ -0,0 +1,416 @@ +<?php +// $Id: aggregator.views.inc,v 1.3.4.7 2010/11/16 00:01:25 merlinofchaos Exp $ +/** + * @file + * Provide views data and handlers for aggregator.module + */ + +/** + * @defgroup views_aggregator_module aggregator.module handlers + * + * Includes the core 'aggregator_feed,' 'aggregator_category,' and 'aggregator_item' + * tables. + * + * @{ + */ + +/** + * Implements hook_views_data() + */ +function aggregator_views_data() { + // ---------------------------------------------------------------------- + // Main Aggregator Item base table + + // Define the base group of this table. Fields that don't + // have a group defined will go into this field by default. + $data['aggregator_item']['table']['group'] = t('Aggregator'); + + // Advertise this table as a possible base table + $data['aggregator_item']['table']['base'] = array( + 'field' => 'iid', + 'title' => t('Aggregator item'), + 'help' => t("Aggregator items are imported from external RSS and Atom news feeds."), + ); + + // ---------------------------------------------------------------- + // Fields + + // item id. + $data['aggregator_item']['iid'] = array( + 'title' => t('Feed Item ID'), + 'help' => t('The unique ID of the aggregator item.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + 'numeric' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // iid + $data['aggregator_item']['iid'] = array( + 'title' => t('Item ID'), + 'help' => t('The unique ID of the aggregator item.'), // The help that appears on the UI, + // Information for displaying the iid + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + // Information for accepting a iid as an argument + 'argument' => array( + 'handler' => 'views_handler_argument_aggregator_iid', + 'name field' => 'title', // the field to display in the summary. + 'numeric' => TRUE, + ), + // Information for accepting a nid as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + // Information for sorting on a nid. + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // title + $data['aggregator_item']['title'] = array( + 'title' => t('Title'), // The item it appears as on the UI, + 'help' => t('The title of the aggregator item.'), + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_aggregator_title_link', + 'extra' => array('link'), + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + // Information for accepting a title as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + // link + $data['aggregator_item']['link'] = array( + 'title' => t('Link'), // The item it appears as on the UI, + 'help' => t('The link to the original source URL of the item.'), + 'field' => array( + 'handler' => 'views_handler_field_url', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + // Information for accepting a title as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + // author + $data['aggregator_item']['author'] = array( + 'title' => t('Author'), // The item it appears as on the UI, + 'help' => t('The author of the original imported item.'), + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_aggregator_xss', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + // Information for accepting a title as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // guid + $data['aggregator_item']['guid'] = array( + 'title' => t('GUID'), // The item it appears as on the UI, + 'help' => t('The guid of the original imported item.'), + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_xss', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + // Information for accepting a title as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // feed body + $data['aggregator_item']['description'] = array( + 'title' => t('Body'), // The item it appears as on the UI, + 'help' => t('The actual content of the imported item.'), + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_aggregator_xss', + 'click sortable' => FALSE, + ), + // Information for accepting a title as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + // item timestamp + $data['aggregator_item']['timestamp'] = array( + 'title' => t('Timestamp'), // The item it appears as on the UI, + 'help' => t('The date the original feed item was posted. (With some feeds, this will be the date it was imported.)'), + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + // Information for accepting a title as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_date', + ), + ); + + + // ---------------------------------------------------------------------- + // Aggregator feed table + + $data['aggregator_feed']['table']['group'] = t('Aggregator feed'); + + // Explain how this table joins to others. + $data['aggregator_feed']['table']['join'] = array( + 'aggregator_item' => array( + 'left_field' => 'fid', + 'field' => 'fid', + ), + ); + + // fid + $data['aggregator_feed']['fid'] = array( + 'title' => t('Feed ID'), + 'help' => t('The unique ID of the aggregator feed.'), // The help that appears on the UI, + // Information for displaying the fid + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + // Information for accepting a fid as an argument + 'argument' => array( + 'handler' => 'views_handler_argument_aggregator_fid', + 'name field' => 'title', // the field to display in the summary. + 'numeric' => TRUE, + ), + // Information for accepting a nid as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + // Information for sorting on a fid. + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // title + $data['aggregator_feed']['title'] = array( + 'title' => t('Title'), // The item it appears as on the UI, + 'help' => t('The title of the aggregator feed.'), + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_aggregator_title_link', + 'extra' => array('link'), + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + // Information for accepting a title as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + // link + $data['aggregator_feed']['link'] = array( + 'title' => t('Link'), // The item it appears as on the UI, + 'help' => t('The link to the source URL of the feed.'), + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_url', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + // Information for accepting a title as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + // feed last updated + $data['aggregator_feed']['checked'] = array( + 'title' => t('Last checked'), // The item it appears as on the UI, + 'help' => t('The date the feed was last checked for new content.'), + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + // Information for accepting a title as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_date', + ), + ); + + // feed description + $data['aggregator_feed']['description'] = array( + 'title' => t('Description'), // The item it appears as on the UI, + 'help' => t('The description of the aggregator feed.'), + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_xss', + 'click sortable' => FALSE, + ), + // Information for accepting a title as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + // feed last updated + $data['aggregator_feed']['modified'] = array( + 'title' => t('Last modified'), // The item it appears as on the UI, + 'help' => t('The date of the most recent new content onf the feed.'), + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + // Information for accepting a title as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_date', + ), + ); + + // ---------------------------------------------------------------------- + // Aggregator category feed table + + $data['aggregator_category_feed']['table']['join'] = array( + 'aggregator_item' => array( + 'left_field' => 'fid', + 'field' => 'fid', + ), + ); + + // ---------------------------------------------------------------------- + // Aggregator category table + + $data['aggregator_category']['table']['group'] = t('Aggregator category'); + + $data['aggregator_category']['table']['join'] = array( + 'aggregator_item' => array( + 'left_table' => 'aggregator_category_feed', + 'left_field' => 'cid', + 'field' => 'cid', + ), + ); + + // cid + $data['aggregator_category']['cid'] = array( + 'title' => t('Category ID'), + 'help' => t('The unique ID of the aggregator category.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_aggregator_category_cid', + 'name field' => 'title', + 'numeric' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_aggregator_category_cid', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // title + $data['aggregator_category']['title'] = array( + 'title' => t('Category'), + 'help' => t('The title of the aggregator category.'), + 'field' => array( + 'handler' => 'views_handler_field_aggregator_category', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + return $data; +} + +/** + * Implements hook_views_plugins + */ +function aggregator_views_plugins() { + return array( + 'module' => 'views', // This just tells our themes are elsewhere. + 'row' => array( + 'aggregator_rss' => array( + 'title' => t('Aggregator item'), + 'help' => t('Display the aggregator item using the data from the original source.'), + 'handler' => 'views_plugin_row_aggregator_rss', + 'path' => drupal_get_path('module', 'views') . '/modules/node', // not necessary for most modules + 'theme' => 'views_view_row_rss', + 'base' => array('aggregator_item'), // only works with 'node' as base. + 'uses options' => TRUE, + 'type' => 'feed', + 'help topic' => 'style-aggregator-rss', + ), + ), + ); +} +/** + * @} + */ diff --git a/sites/all/modules/views/modules/aggregator/views_handler_argument_aggregator_category_cid.inc b/sites/all/modules/views/modules/aggregator/views_handler_argument_aggregator_category_cid.inc new file mode 100644 index 0000000000000000000000000000000000000000..084f954ff5e9a3fb88aef52e783392a266af3ee6 --- /dev/null +++ b/sites/all/modules/views/modules/aggregator/views_handler_argument_aggregator_category_cid.inc @@ -0,0 +1,20 @@ +<?php +// $Id: views_handler_argument_aggregator_category_cid.inc,v 1.1.6.2 2009/11/13 12:36:05 dereine Exp $ + +/** + * Argument handler to accept an aggregator category id. + */ +class views_handler_argument_aggregator_category_cid extends views_handler_argument_numeric { + /** + * Override the behavior of title(). Get the title of the category. + */ + function title_query() { + $titles = array(); + + $result = db_query("SELECT c.title FROM {aggregator_category} c WHERE c.cid IN (:cid)", array(':cid' => $this->value)); + foreach ($result as $term) { + $titles[] = check_plain($term->title); + } + return $titles; + } +} diff --git a/sites/all/modules/views/modules/aggregator/views_handler_argument_aggregator_fid.inc b/sites/all/modules/views/modules/aggregator/views_handler_argument_aggregator_fid.inc new file mode 100644 index 0000000000000000000000000000000000000000..5da5b13c26af30aa6b41c901bdcedeb7296c55e8 --- /dev/null +++ b/sites/all/modules/views/modules/aggregator/views_handler_argument_aggregator_fid.inc @@ -0,0 +1,20 @@ +<?php +// $Id: views_handler_argument_aggregator_fid.inc,v 1.1.6.2 2010/10/23 06:30:12 dereine Exp $ + +/** + * Argument handler to accept an aggregator feed id. + */ +class views_handler_argument_aggregator_fid extends views_handler_argument_numeric { + /** + * Override the behavior of title(). Get the title of the feed. + */ + function title_query() { + $titles = array(); + + $result = db_query("SELECT f.title FROM {aggregator_feed} f WHERE f.fid IN (:fids)", array(':fids' => $this->value)); + foreach ($result as $term) { + $titles[] = check_plain($term->title); + } + return $titles; + } +} diff --git a/sites/all/modules/views/modules/aggregator/views_handler_argument_aggregator_iid.inc b/sites/all/modules/views/modules/aggregator/views_handler_argument_aggregator_iid.inc new file mode 100644 index 0000000000000000000000000000000000000000..cf3e5a8176d1a30b0f581160ce219f2a11241c64 --- /dev/null +++ b/sites/all/modules/views/modules/aggregator/views_handler_argument_aggregator_iid.inc @@ -0,0 +1,24 @@ +<?php +// $Id: views_handler_argument_aggregator_iid.inc,v 1.1.6.2 2010/10/16 08:19:05 dereine Exp $ + +/** + * Argument handler to accept an aggregator item id. + */ +class views_handler_argument_aggregator_iid extends views_handler_argument_numeric { + /** + * Override the behavior of title(). Get the title of the category. + */ + function title_query() { + $titles = array(); + $placeholders = implode(', ', array_fill(0, sizeof($this->value), '%d')); + + $result = db_select('aggregator_item') + ->condition('iid', $this->value, 'IN') + ->fields(array('title')) + ->execute(); + foreach ($result as $term) { + $titles[] = check_plain($term->title); + } + return $titles; + } +} diff --git a/sites/all/modules/views/modules/aggregator/views_handler_field_aggregator_category.inc b/sites/all/modules/views/modules/aggregator/views_handler_field_aggregator_category.inc new file mode 100644 index 0000000000000000000000000000000000000000..c7a72e955b48c821512b1d547c1e944eb0f6b04b --- /dev/null +++ b/sites/all/modules/views/modules/aggregator/views_handler_field_aggregator_category.inc @@ -0,0 +1,53 @@ +<?php +// $Id: views_handler_field_aggregator_category.inc,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * Field handler to provide simple renderer that allows linking to aggregator + * category. + */ +class views_handler_field_aggregator_category extends views_handler_field { + /** + * Constructor to provide additional field to add. + */ + function construct() { + parent::construct(); + $this->additional_fields['cid'] = 'cid'; + } + + function option_definition() { + $options = parent::option_definition(); + $options['link_to_category'] = array('default' => FALSE); + return $options; + } + + /** + * Provide link to category option + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_to_category'] = array( + '#title' => t('Link this field to its aggregator category page'), + '#description' => t('This will override any other link you have set.'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['link_to_category']), + ); + } + + /** + * Render whatever the data is as a link to the category. + * + * Data should be made XSS safe prior to calling this function. + */ + function render_link($data, $values) { + if (!empty($this->options['link_to_category']) && !empty($values->{$this->aliases['cid']}) && $data !== NULL && $data !== '') { + $cid = $values->{$this->aliases['cid']}; + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "aggregator/category/$cid"; + } + return $data; + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->field_alias}), $values); + } +} diff --git a/sites/all/modules/views/modules/aggregator/views_handler_field_aggregator_title_link.inc b/sites/all/modules/views/modules/aggregator/views_handler_field_aggregator_title_link.inc new file mode 100644 index 0000000000000000000000000000000000000000..1399c52ba2ec040c55bc8852a3d019a2a61d027f --- /dev/null +++ b/sites/all/modules/views/modules/aggregator/views_handler_field_aggregator_title_link.inc @@ -0,0 +1,49 @@ +<?php +// $Id: views_handler_field_aggregator_title_link.inc,v 1.1.6.1 2010/11/18 07:29:03 dereine Exp $ + + /** + * Field handler that turns an item's title into a clickable link to the original + * source article. + */ +class views_handler_field_aggregator_title_link extends views_handler_field { + function construct() { + parent::construct(); + $this->additional_fields['link'] = 'link'; + } + + function option_definition() { + $options = parent::option_definition(); + + $options['display_as_link'] = array('default' => TRUE); + + return $options; + } + + /** + * Provide link to the page being visited. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['display_as_link'] = array( + '#title' => t('Display as link'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['display_as_link']), + ); + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->field_alias}), $values); + } + + function render_link($data, $values) { + $value = $values->{$this->field_alias}; + $link = $values->{$this->aliases['link']}; + if (!empty($this->options['display_as_link'])) { + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = $link; + $this->options['alter']['html'] = TRUE; + } + + return $data; + } +} \ No newline at end of file diff --git a/sites/all/modules/views/modules/aggregator/views_handler_field_aggregator_xss.inc b/sites/all/modules/views/modules/aggregator/views_handler_field_aggregator_xss.inc new file mode 100644 index 0000000000000000000000000000000000000000..b7cb9bf4141d50ef229415d9a59db69c3b83a1e5 --- /dev/null +++ b/sites/all/modules/views/modules/aggregator/views_handler_field_aggregator_xss.inc @@ -0,0 +1,14 @@ +<?php +// $Id: views_handler_field_aggregator_xss.inc,v 1.1.2.2 2010/11/16 00:01:25 merlinofchaos Exp $ +/** + * @file + * Filters htmls tags from item. + */ + +class views_handler_field_aggregator_xss extends views_handler_field { + function render($values) { + $value = $values->{$this->field_alias}; + return aggregator_filter_xss($value); + } + +} \ No newline at end of file diff --git a/sites/all/modules/views/modules/aggregator/views_handler_filter_aggregator_category_cid.inc b/sites/all/modules/views/modules/aggregator/views_handler_filter_aggregator_category_cid.inc new file mode 100644 index 0000000000000000000000000000000000000000..3c995b5a03a94a9b1b80bb252530b81863d5b19c --- /dev/null +++ b/sites/all/modules/views/modules/aggregator/views_handler_filter_aggregator_category_cid.inc @@ -0,0 +1,20 @@ +<?php +// $Id: views_handler_filter_aggregator_category_cid.inc,v 1.2.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * Filter by aggregator category cid + */ +class views_handler_filter_aggregator_category_cid extends views_handler_filter_in_operator { + function get_value_options() { + if (isset($this->value_options)) { + return; + } + + $this->value_options = array(); + + $result = db_query('SELECT * FROM {aggregator_category} ORDER BY title'); + foreach ($result as $category) { + $this->value_options[$category->cid] = $category->title; + } + } +} diff --git a/sites/all/modules/views/modules/aggregator/views_plugin_row_aggregator_rss.inc b/sites/all/modules/views/modules/aggregator/views_plugin_row_aggregator_rss.inc new file mode 100644 index 0000000000000000000000000000000000000000..87258d46d67b4ace79fa5ef686bf4206d73b6650 --- /dev/null +++ b/sites/all/modules/views/modules/aggregator/views_plugin_row_aggregator_rss.inc @@ -0,0 +1,73 @@ +<?php +// $Id: views_plugin_row_aggregator_rss.inc,v 1.1.6.2 2010/01/27 23:28:35 dereine Exp $ +/** + * @file + * Contains the Aggregator Item RSS row style plugin. + */ + +/** + * Plugin which loads an aggregator item and formats it as an RSS item. + */ +class views_plugin_row_aggregator_rss extends views_plugin_row { + var $base_table = 'aggregator_item'; + var $base_field = 'iid'; + + function option_definition() { + $options = parent::option_definition(); + + $options['item_length'] = array('default' => 'default'); + + return $options; + } + + function options_form(&$form, &$form_state) { + $form['item_length'] = array( + '#type' => 'select', + '#title' => t('Display type'), + '#options' => array( + 'fulltext' => t('Full text'), + 'teaser' => t('Title plus teaser'), + 'title' => t('Title only'), + 'default' => t('Use default RSS settings'), + ), + '#default_value' => $this->options['item_length'], + ); + } + + function render($row) { + $iid = $row->{$this->field_alias}; + $sql = "SELECT ai.iid, ai.fid, ai.title, ai.link, ai.author, ai.description, "; + $sql .= "ai.timestamp, ai.guid, af.title AS feed_title, ai.link AS feed_LINK "; + $sql .= "FROM {aggregator_item} ai LEFT JOIN {aggregator_feed} af ON ai.fid = af.fid "; + $sql .= "WHERE ai.iid = :iid"; + + $item = db_query($sql, array(':iid' => $iid))->fetchObject(); + + $item->elements = array( + array('key' => 'pubDate', 'value' => gmdate('r', $item->timestamp)), + array( + 'key' => 'dc:creator', + 'value' => $item->author, + 'namespace' => array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/'), + ), + array( + 'key' => 'guid', + 'value' => $item->guid, + 'attributes' => array('isPermaLink' => 'false') + ), + ); + + foreach ($item->elements as $element) { + if (isset($element['namespace'])) { + $this->view->style_plugin->namespaces = array_merge($this->view->style_plugin->namespaces, $element['namespace']); + } + } + + return theme($this->theme_functions(), array( + 'view' => $this->view, + 'options' => $this->options, + 'row' => $item + )); + } +} + diff --git a/sites/all/modules/views/modules/book.views.inc b/sites/all/modules/views/modules/book.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..4736ec68eed286fa977af7cb2001b8110456e092 --- /dev/null +++ b/sites/all/modules/views/modules/book.views.inc @@ -0,0 +1,124 @@ +<?php +// $Id: book.views.inc,v 1.5.6.4 2009/12/03 20:57:04 merlinofchaos Exp $ +/** + * @file + * Provide views data and handlers for book.module + */ + +/** + * @defgroup views_book_module book.module handlers + * + * @{ + */ + +/** + * Implements hook_views_data() + */ +function book_views_data() { + // ---------------------------------------------------------------------- + // book table + + $data['book']['table']['group'] = t('Book'); + $data['book']['table']['join'] = array( + 'node' => array( + 'left_field' => 'nid', + 'field' => 'nid', + ), + ); + + $data['book']['bid'] = array( + 'title' => t('Top level book'), + 'help' => t('The book the node is in.'), + 'relationship' => array( + 'base' => 'node', + 'handler' => 'views_handler_relationship', + 'label' => t('Book'), + ), + // There is no argument here; if you need an argument, add the relationship + // and use the node: nid argument. + ); + + // ---------------------------------------------------------------------- + // menu_links table -- this is aliased so we can get just book relations + + // Book hierarchy and weight data are now in {menu_links}. + $data['book_menu_links']['table']['group'] = t('Book'); + $data['book_menu_links']['table']['join'] = array( + 'node' => array( + 'table' => 'menu_links', + 'left_table' => 'book', + 'left_field' => 'mlid', + 'field' => 'mlid', + ), + ); + + $data['book_menu_links']['weight'] = array( + 'title' => t('Weight'), + 'help' => t('The weight of the book page.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + $data['book_menu_links']['depth'] = array( + 'title' => t('Depth'), + 'help' => t('The depth of the book page in the hierarchy; top level books have a depth of 1.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'argument' => array( + 'handler' => 'views_handler_argument', + ), + ); + + $data['book_menu_links']['p'] = array( + 'title' => t('Hierarchy'), + 'help' => t('The order of pages in the book hierarchy.'), + 'sort' => array( + 'handler' => 'views_handler_sort_menu_hierarchy', + ), + ); + + // ---------------------------------------------------------------------- + // book_parent table -- this is an alias of the book table which + // represents the parent book. + + // The {book} record for the parent node. + $data['book_parent']['table']['group'] = t('Book'); + $data['book_parent']['table']['join'] = array( + 'node' => array( + 'table' => 'book', + 'left_table' => 'book_menu_links', + 'left_field' => 'plid', + 'field' => 'mlid', + ), + ); + + $data['book_parent']['nid'] = array( + 'title' => t('Parent'), + 'help' => t('The parent book node.'), + 'relationship' => array( + 'base' => 'node', + 'base field' => 'nid', + 'handler' => 'views_handler_relationship', + 'label' => t('Book parent'), + ), + ); + + return $data; +} + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/book.views_convert.inc b/sites/all/modules/views/modules/book.views_convert.inc new file mode 100644 index 0000000000000000000000000000000000000000..9e2e52f47105bfbe52bae5520d7fe038e942c983 --- /dev/null +++ b/sites/all/modules/views/modules/book.views_convert.inc @@ -0,0 +1,81 @@ +<?php +// $Id: book.views_convert.inc,v 1.3.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * @file + * Field conversion for fields handled by this module. + */ + +/** + * Implements hook_views_convert(). + */ +function book_views_convert($display, $type, &$view, $field, $id = NULL) { + switch ($type) { + case 'field': + switch ($field['tablename']) { + case 'book_parent_node': + switch ($field['field']) { + case 'title': + $item = $view->get_item($display, 'field', $id); + if ($field['handler'] == 'views_handler_field_book_parent_title') { + $item['link_to_node'] = TRUE; + } + $item['relationship'] = $view->add_item($display, 'relationship', 'book_parent', 'nid', array(), 'book_parent_nid'); + $item['table'] = 'node'; + $item['field'] = 'title'; + $view->set_item($display, 'field', $id, $item); + break; + } + break; + } + break; + case 'filter': + switch ($field['tablename']) { + case 'book': + switch ($field['field']) { + case 'parent': + $operators = array('AND' => '=', 'OR' => '=', 'NOT' => '!='); + $item = $view->get_item($display, 'filter', $id); + $item['operator'] = $operators[$field['operator']]; + $item['relationship'] = $view->add_item($display, 'relationship', 'book_parent', 'nid', array(), 'book_parent_nid'); + $item['table'] = 'node'; + $item['field'] = 'nid'; + $view->set_item($display, 'filter', $id, $item); + break; + } + break; + } + break; + case 'sort': + switch ($field['tablename']) { + case 'book': + switch ($field['field']) { + case 'weight': + $view->set_item_option($display, 'sort', $id, 'table', 'book_menu_links'); + break; + } + break; + case 'book_parent_node': + switch ($field['field']) { + case 'title': + $item = $view->get_item($display, 'sort', $id); + $item['relationship'] = $view->add_item($display, 'relationship', 'book_parent', 'nid', array(), 'book_parent_nid'); + $item['table'] = 'node'; + $item['field'] = 'title'; + $view->set_item($display, 'sort', $id, $item); + break; + } + break; + } + break; + case 'argument': + $options = $field['argoptions']; + switch ($field['type']) { + case 'book_parent': + $options['relationship'] = $view->add_item($display, 'relationship', 'book_parent', 'nid', array(), 'book_parent_nid'); + $view->add_item($display, 'argument', 'node', 'nid', $options, $field['id']); + break; + } + break; + } +} diff --git a/sites/all/modules/views/modules/comment.views.inc b/sites/all/modules/views/modules/comment.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..8c1ad8024c988f832e4172e90a30fb0a05c22306 --- /dev/null +++ b/sites/all/modules/views/modules/comment.views.inc @@ -0,0 +1,551 @@ +<?php +// $Id: comment.views.inc,v 1.33.4.17 2010/11/25 20:56:40 dereine Exp $ +/** + * @file + * Provide views data and handlers for comment.module + */ + +/** + * @defgroup views_comment_module comment.module handlers + * + * Includes the tables 'comments' and 'node_comment_statistics' + * @{ + */ + +/** + * Implements hook_views_data() + */ + +function comment_views_data() { + // Define the base group of this table. Fields that don't + // have a group defined will go into this field by default. + $data['comment']['table']['group'] = t('Comment'); + + $data['comment']['table']['base'] = array( + 'field' => 'cid', + 'title' => t('Comment'), + 'help' => t("Comments are responses to node content."), + ); + + //joins + $data['comment']['table']['join'] = array( + //...to the node table + 'node' => array( + 'left_field' => 'nid', + 'field' => 'nid', + ), + ); + + // ---------------------------------------------------------------- + // Fields + + // subject + $data['comment']['subject'] = array( + 'title' => t('Title'), + 'help' => t('The title of the comment.'), + 'field' => array( + 'handler' => 'views_handler_field_comment', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // cid + $data['comment']['cid'] = array( + 'title' => t('ID'), + 'help' => t('The comment ID of the field'), + 'field' => array( + 'handler' => 'views_handler_field_comment', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + ), + ); + + // name (of comment author) + $data['comment']['name'] = array( + 'title' => t('Author'), + 'help' => t("The name of the comment's author. Can be rendered as a link to the author's homepage."), + 'field' => array( + 'handler' => 'views_handler_field_comment_username', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // homepage + $data['comment']['homepage'] = array( + 'title' => t("Author's website"), + 'help' => t("The website address of the comment's author. Can be rendered as a link. Will be empty if the author is a registered user."), + 'field' => array( + 'handler' => 'views_handler_field_url', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // hostname + $data['comment']['hostname'] = array( + 'title' => t('Hostname'), + 'help' => t('Hostname of user that posted the comment.'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // mail + $data['comment']['mail'] = array( + 'title' => t('Mail'), + 'help' => t('Email of user that posted the comment. Will be empty if the author is a registered user.'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // created (when comment was posted) + $data['comment']['created'] = array( + 'title' => t('Post date'), + 'help' => t('Date and time of when the comment was created.'), + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + ); + + // changed (when comment was last updated) + $data['comment']['changed'] = array( + 'title' => t('Post date'), + 'help' => t('Date and time of when the comment was last updated.'), + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + ); + + $data['comments']['timestamp_fulldate'] = array( + 'title' => t('Created date'), + 'help' => t('In the form of CCYYMMDD.'), + 'argument' => array( + 'field' => 'timestamp', + 'handler' => 'views_handler_argument_node_created_fulldate', + ), + ); + + $data['comments']['timestamp_year_month'] = array( + 'title' => t('Created year + month'), + 'help' => t('In the form of YYYYMM.'), + 'argument' => array( + 'field' => 'timestamp', + 'handler' => 'views_handler_argument_node_created_year_month', + ), + ); + + $data['comments']['timestamp_year'] = array( + 'title' => t('Created year'), + 'help' => t('In the form of YYYY.'), + 'argument' => array( + 'field' => 'timestamp', + 'handler' => 'views_handler_argument_node_created_year', + ), + ); + + $data['comments']['timestamp_month'] = array( + 'title' => t('Created month'), + 'help' => t('In the form of MM (01 - 12).'), + 'argument' => array( + 'field' => 'timestamp', + 'handler' => 'views_handler_argument_node_created_month', + ), + ); + + $data['comments']['timestamp_day'] = array( + 'title' => t('Created day'), + 'help' => t('In the form of DD (01 - 31).'), + 'argument' => array( + 'field' => 'timestamp', + 'handler' => 'views_handler_argument_node_created_day', + ), + ); + + $data['comments']['timestamp_week'] = array( + 'title' => t('Created week'), + 'help' => t('In the form of WW (01 - 53).'), + 'argument' => array( + 'field' => 'timestamp', + 'handler' => 'views_handler_argument_node_created_week', + ), + ); + + // status (approved or not) + $data['comment']['status'] = array( + 'title' => t('Approved'), + 'help' => t('Whether the comment is approved (or still in the moderation queue).'), + 'field' => array( + 'handler' => 'views_handler_field_boolean', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_boolean_operator', + 'label' => t('Approved comment'), + 'type' => 'yes-no', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // link to view comment + $data['comment']['view_comment'] = array( + 'field' => array( + 'title' => t('View link'), + 'help' => t('Provide a simple link to view the comment.'), + 'handler' => 'views_handler_field_comment_link', + ), + ); + + // link to edit comment + $data['comment']['edit_comment'] = array( + 'field' => array( + 'title' => t('Edit link'), + 'help' => t('Provide a simple link to edit the comment.'), + 'handler' => 'views_handler_field_comment_link_edit', + ), + ); + + // link to delete comment + $data['comment']['delete_comment'] = array( + 'field' => array( + 'title' => t('Delete link'), + 'help' => t('Provide a simple link to delete the comment.'), + 'handler' => 'views_handler_field_comment_link_delete', + ), + ); + + // link to reply to comment + $data['comment']['replyto_comment'] = array( + 'field' => array( + 'title' => t('Reply-to link'), + 'help' => t('Provide a simple link to reply to the comment.'), + 'handler' => 'views_handler_field_comment_link_reply', + ), + ); + + $data['comment']['thread'] = array( + 'field' => array( + 'title' => t('Depth'), + 'help' => t('Display the depth of the comment if it is threaded.'), + 'handler' => 'views_handler_field_comment_depth', + ), + 'sort' => array( + 'title' => t('Thread'), + 'help' => t('Sort by the threaded order. This will keep child comments together with their parents.'), + 'handler' => 'views_handler_sort_comment_thread', + ), + ); + + $data['comment']['nid'] = array( + 'title' => t('Node'), + 'help' => t('The node the comment is a reply to.'), + 'relationship' => array( + 'base' => 'node', + 'base field' => 'nid', + 'handler' => 'views_handler_relationship', + 'label' => t('Node'), + ), + ); + + $data['comment']['uid'] = array( + 'title' => t('User'), + 'help' => t("The User ID of the comment's author."), + 'relationship' => array( + 'base' => 'users', + 'base field' => 'uid', + 'handler' => 'views_handler_relationship', + 'label' => t('User'), + ), + ); + + $data['comment']['pid'] = array( + 'title' => t('Parent CID'), + 'help' => t('The Comment ID of the parent comment.'), + 'field' => array( + 'handler' => 'views_handler_field', + ), + 'relationship' => array( + 'title' => t('Parent comment'), + 'help' => t('The parent comment.'), + 'base' => 'comment', + 'base field' => 'cid', + 'handler' => 'views_handler_relationship', + 'label' => t('Parent comment'), + ), + ); + + // ---------------------------------------------------------------------- + // node_comment_statistics table + + // define the group + $data['node_comment_statistics']['table']['group'] = t('Node'); + + // joins + $data['node_comment_statistics']['table']['join'] = array( + //...to the node table + 'node' => array( + 'type' => 'INNER', + 'left_field' => 'nid', + 'field' => 'nid', + ), + ); + + // last_comment_timestamp + $data['node_comment_statistics']['last_comment_timestamp'] = array( + 'title' => t('Last comment time'), + 'help' => t('Date and time of when the last comment was posted.'), + 'field' => array( + 'handler' => 'views_handler_field_last_comment_timestamp', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + ); + + // last_comment_name (author's name) + $data['node_comment_statistics']['last_comment_name'] = array( + 'title' => t("Last comment author"), + 'help' => t('The name of the author of the last posted comment.'), + 'field' => array( + 'handler' => 'views_handler_field_ncs_last_comment_name', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_ncs_last_comment_name', + ), + ); + + // comment_count + $data['node_comment_statistics']['comment_count'] = array( + 'title' => t('Comment count'), + 'help' => t('The number of comments a node has.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'argument' => array( + 'handler' => 'views_handler_argument', + ), + ); + + // last_comment_timestamp + $data['node_comment_statistics']['last_updated'] = array( + 'title' => t('Updated/commented date'), + 'help' => t('The most recent of last comment posted or node updated time.'), + 'field' => array( + 'handler' => 'views_handler_field_ncs_last_updated', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_ncs_last_updated', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_ncs_last_updated', + ), + ); + + $data['node_comment_statistics']['cid'] = array( + 'title' => t('Last comment CID'), + 'help' => t('Display the last comment of a node'), + 'relationship' => array( + 'title' => t('Last Comment'), + 'help' => t('The last comment of a node.'), + 'group' => t('Comment'), + 'base' => 'comment', + 'base field' => 'cid', + 'handler' => 'views_handler_relationship', + 'label' => t('Last Comment'), + ), + ); + + return $data; +} + +/** + * Use views_data_alter to add items to the node table that are + * relevant to comments. + */ +function comment_views_data_alter(&$data) { + // new comments + $data['node']['new_comments'] = array( + 'title' => t('New comments'), + 'help' => t('The number of new comments on the node.'), + 'field' => array( + 'handler' => 'views_handler_field_node_new_comments', + 'no group by' => TRUE, + ), + ); + + $data['node']['comments_link'] = array( + 'field' => array( + 'title' => t('Add comment link'), + 'help' => t('Display the standard add comment link used on regular nodes, which will only display if the viewing user has access to add a comment.'), + 'handler' => 'views_handler_field_comment_node_link', + ), + ); + + // Comment status of the node + $data['node']['comment'] = array( + 'title' => t('Comment status'), + 'help' => t('Whether comments are enabled or disabled on the node.'), + 'field' => array( + 'handler' => 'views_handler_field_node_comment', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_node_comment', + ), + ); + + $data['node']['uid_touch'] = array( + 'title' => t('User posted or commented'), + 'help' => t('Display nodes only if a user posted the node or commented on the node.'), + 'argument' => array( + 'field' => 'uid', + 'name table' => 'users', + 'name field' => 'name', + 'handler' => 'views_handler_argument_comment_user_uid', + ), + 'filter' => array( + 'field' => 'uid', + 'name table' => 'users', + 'name field' => 'name', + 'handler' => 'views_handler_filter_comment_user_uid' + ), + ); + +} + +/** + * Implements hook_views_plugins + */ +function comment_views_plugins() { + return array( + 'module' => 'views', + 'row' => array( + 'comment' => array( + 'title' => t('Comment'), + 'help' => t('Display the comment with standard comment view.'), + 'handler' => 'views_plugin_row_comment_view', + 'theme' => 'views_view_row_comment', + 'path' => drupal_get_path('module', 'views') . '/modules/comment', // not necessary for most modules + 'base' => array('comment'), // only works with 'comment' as base. + 'uses options' => TRUE, + 'type' => 'normal', + 'help topic' => 'style-comment', + ), + 'comment_rss' => array( + 'title' => t('Comment'), + 'help' => t('Display the comment as RSS.'), + 'handler' => 'views_plugin_row_comment_rss', + 'theme' => 'views_view_row_rss', + 'path' => drupal_get_path('module', 'views') . '/modules/comment', // not necessary for most modules + 'base' => array('comment'), // only works with 'comment' as base. + 'type' => 'feed', + 'help topic' => 'style-comment-rss', + ), + ), + ); +} + +/** + * Template helper for theme_views_view_row_comment + */ +function template_preprocess_views_view_row_comment(&$vars) { + $options = $vars['options']; + $view = &$vars['view']; + $plugin = &$view->style_plugin->row_plugin; + $comment = $plugin->comments[$vars['row']->{$vars['field_alias']}]; + $node = node_load($comment->nid); + // Put the view on the node so we can retrieve it in the preprocess. + $node->view = &$view; + + $vars['comment'] = drupal_render(comment_view_multiple(array($comment->cid => $comment), $node)); +} + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/comment.views_convert.inc b/sites/all/modules/views/modules/comment.views_convert.inc new file mode 100644 index 0000000000000000000000000000000000000000..d6222115265a2ac7ce9b94ff3178488b32f84490 --- /dev/null +++ b/sites/all/modules/views/modules/comment.views_convert.inc @@ -0,0 +1,132 @@ +<?php +//$Id: comment.views_convert.inc,v 1.4.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * @file + * Field conversion for fields handled by this module. + */ + +/** + * Implements 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 comment_views_convert($display, $type, &$view, $field, $id = NULL) { + switch ($type) { + case 'field': + switch ($field['tablename']) { + case 'comments': + switch ($field['field']) { + case 'subject': + if ($field['options'] = 'nolink') { + $view->set_item_option($display, 'field', $id, 'link_to_comment', FALSE); + } + break; + case 'cid': + $view->set_item_option($display, 'field', $id, 'link_to_comment', FALSE); + break; + case 'timestamp': + $handlers = array( + 'views_handler_field_date_small' => 'small', + 'views_handler_field_date' => 'medium', + 'views_handler_field_date_large' => 'large', + 'views_handler_field_date_custom' => 'custom', + 'views_handler_field_since' => 'time ago', + ); + $view->set_item_option($display, 'field', $id, 'date_format', $handlers[$field['handler']]); + if (!empty($field['options'])) { + $view->set_item_option($display, 'field', $id, 'custom_date_format', $field['options']); + } + break; + case 'add': + $view->set_item_option($display, 'field', $id, 'field', 'replyto_comment'); + break; + } + break; + case 'node_comment_statistics': + switch ($field['field']) { + case 'last_comment_timestamp': + $handlers = array( + 'views_handler_field_date_small' => 'small', + 'views_handler_field_date' => 'medium', + 'views_handler_field_date_large' => 'large', + 'views_handler_field_date_custom' => 'custom', + 'views_handler_field_since' => 'time ago', + ); + $view->set_item_option($display, 'field', $id, 'date_format', $handlers[$field['handler']]); + if (!empty($field['options'])) { + $view->set_item_option($display, 'field', $id, 'custom_date_format', $field['options']); + } + break; + case 'last_changed': + $handlers = array( + 'views_handler_field_date_small' => 'small', + 'views_handler_field_date' => 'medium', + 'views_handler_field_date_large' => 'large', + 'views_handler_field_date_custom' => 'custom', + 'views_handler_field_since' => 'time ago', + ); + $item = $view->get_item($display, 'field', $id); + $item['date_format'] = $handlers[$field['handler']]; + if (!empty($field['options'])) { + $item['custom_date_format'] = $field['options']; + } + $item['field'] = 'last_updated'; + $view->set_item($display, 'field', $id, $item); + break; + } + break; + } + break; + case 'filter': + switch ($field['tablename']) { + case 'node_comment_statistics': + switch ($field['field']) { + case 'comment_count': + $view->set_item_option($display, 'filter', $id, 'operator', $field['operator']); + break; + case 'last_changed': + $field['field'] = 'last_updated'; + case 'last_comment_timestamp': + $item = $view->get_item($display, 'filter', $id); + $item['operator'] = $field['operator']; + $item['value'] = array( + 'type' => $field['value'] == 'now' ? 'offset' : 'date', + 'value' => $field['value'], + ); + if (!empty($field['options'])) { + $item['value']['value'] = intval($field['options']) .' seconds'; + } + $item['field'] = $field['field']; + $view->set_item($display, 'filter', $id, $item); + break; + } + break; + } + break; + case 'sort': + switch ($field['tablename']) { + case 'comments': + switch ($field['field']) { + case 'timestamp': + $field['options'] = $field['options'] == 'normal' ? 'second' : $field['options']; + $view->set_item_option($display, 'sort', $id, 'granularity', $field['options']); + break; + } + break; + case 'node_comment_statistics': + switch ($field['field']) { + case 'last_changed': + $view->set_item_option($display, 'sort', $id, 'field', 'last_updated'); + case 'last_comment_timestamp': + $field['options'] = $field['options'] == 'normal' ? 'second' : $field['options']; + $view->set_item_option($display, 'sort', $id, 'granularity', $field['options']); + break; + } + break; + } + break; + } +} diff --git a/sites/all/modules/views/modules/comment.views_default.inc b/sites/all/modules/views/modules/comment.views_default.inc new file mode 100644 index 0000000000000000000000000000000000000000..6641c47d0e36d72db8a4ac6067878f0f0db5d38f --- /dev/null +++ b/sites/all/modules/views/modules/comment.views_default.inc @@ -0,0 +1,319 @@ +<?php +// $Id: comment.views_default.inc,v 1.7.6.7 2011/01/05 23:14:39 dereine Exp $ +/** + * @file + * Contains default views on behalf of the comment module. + */ + +/** + * Implements hook_views_default_views(). + */ +function comment_views_default_views() { + $view = new view; + $view->name = 'comments_recent'; + $view->description = 'Contains a block and a page to list recent comments; the block will automatically link to the page, which displays the comment body as well as a link to the node.'; + $view->tag = 'default'; + $view->base_table = 'comment'; + $view->api_version = 2; + $view->version = 7; + $view->disabled = TRUE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['title'] = 'Recent comments'; + $handler->display->display_options['use_more'] = TRUE; + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'some'; + $handler->display->display_options['pager']['options']['items_per_page'] = 5; + $handler->display->display_options['style_plugin'] = 'list'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Relationship: Comment: Node */ + $handler->display->display_options['relationships']['nid']['id'] = 'nid'; + $handler->display->display_options['relationships']['nid']['table'] = 'comment'; + $handler->display->display_options['relationships']['nid']['field'] = 'nid'; + /* Field: Comment: Title */ + $handler->display->display_options['fields']['subject']['id'] = 'subject'; + $handler->display->display_options['fields']['subject']['table'] = 'comment'; + $handler->display->display_options['fields']['subject']['field'] = 'subject'; + $handler->display->display_options['fields']['subject']['label'] = ''; + $handler->display->display_options['fields']['subject']['link_to_comment'] = 1; + /* Field: Comment: Post date */ + $handler->display->display_options['fields']['timestamp']['id'] = 'timestamp'; + $handler->display->display_options['fields']['timestamp']['table'] = 'comment'; + $handler->display->display_options['fields']['timestamp']['field'] = 'changed'; + $handler->display->display_options['fields']['timestamp']['label'] = ''; + $handler->display->display_options['fields']['timestamp']['date_format'] = 'time ago'; + /* Sort criterion: Comment: Post date */ + $handler->display->display_options['sorts']['timestamp']['id'] = 'timestamp'; + $handler->display->display_options['sorts']['timestamp']['table'] = 'comment'; + $handler->display->display_options['sorts']['timestamp']['field'] = 'changed'; + $handler->display->display_options['sorts']['timestamp']['order'] = 'DESC'; + /* Filter: Node: Published or admin */ + $handler->display->display_options['filters']['status_extra']['id'] = 'status_extra'; + $handler->display->display_options['filters']['status_extra']['table'] = 'node'; + $handler->display->display_options['filters']['status_extra']['field'] = 'status_extra'; + $handler->display->display_options['filters']['status_extra']['relationship'] = 'nid'; + $handler->display->display_options['filters']['status_extra']['group'] = 0; + + /* Display: Page */ + $handler = $view->new_display('page', 'Page', 'page'); + $handler->display->display_options['defaults']['items_per_page'] = FALSE; + $handler->display->display_options['defaults']['style_plugin'] = FALSE; + $handler->display->display_options['style_plugin'] = 'list'; + $handler->display->display_options['defaults']['style_options'] = FALSE; + $handler->display->display_options['defaults']['row_plugin'] = FALSE; + $handler->display->display_options['row_plugin'] = 'fields'; + $handler->display->display_options['row_options']['inline'] = array( + 'title' => 'title', + 'timestamp' => 'timestamp', + ); + $handler->display->display_options['row_options']['separator'] = ' '; + $handler->display->display_options['defaults']['row_options'] = FALSE; + $handler->display->display_options['defaults']['fields'] = FALSE; + /* Field: Node: Title */ + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['relationship'] = 'nid'; + $handler->display->display_options['fields']['title']['label'] = 'Reply to'; + $handler->display->display_options['fields']['title']['link_to_node'] = 1; + /* Field: Comment: Post date */ + $handler->display->display_options['fields']['timestamp']['id'] = 'timestamp'; + $handler->display->display_options['fields']['timestamp']['table'] = 'comment'; + $handler->display->display_options['fields']['timestamp']['field'] = 'changed'; + $handler->display->display_options['fields']['timestamp']['label'] = ''; + $handler->display->display_options['fields']['timestamp']['date_format'] = 'time ago'; + /* Field: Comment: Title */ + $handler->display->display_options['fields']['subject']['id'] = 'subject'; + $handler->display->display_options['fields']['subject']['table'] = 'comment'; + $handler->display->display_options['fields']['subject']['field'] = 'subject'; + $handler->display->display_options['fields']['subject']['label'] = ''; + $handler->display->display_options['fields']['subject']['link_to_comment'] = 1; + /* Field: Comment: Body */ + $handler->display->display_options['fields']['comment']['id'] = 'comment'; + $handler->display->display_options['fields']['comment']['table'] = 'comment'; + $handler->display->display_options['fields']['comment']['field'] = 'comment'; + $handler->display->display_options['fields']['comment']['label'] = ''; + $handler->display->display_options['path'] = 'comments/recent'; + + /* Display: Block */ + $handler = $view->new_display('block', 'Block', 'block'); + $handler->display->display_options['block_description'] = 'Recent comments view'; + $views[$view->name] = $view; + + $view = new view; + $view->name = 'tracker'; + $view->description = 'Shows all new activity on system.'; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->api_version = 2; + $view->version = 7; + $view->disabled = TRUE; /* Edit this to true to make a default view disabled initially */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->override_option('fields', array( + 'type' => array( + 'id' => 'type', + 'table' => 'node', + 'field' => 'type', + 'label' => 'Type', + ), + 'title' => array( + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'label' => 'Title', + 'link_to_node' => TRUE, + ), + 'name' => array( + 'id' => 'name', + 'table' => 'users', + 'field' => 'name', + 'label' => 'Author', + 'link_to_user' => TRUE, + ), + 'comment_count' => array( + 'id' => 'comment_count', + 'table' => 'node_comment_statistics', + 'field' => 'comment_count', + 'label' => 'Replies', + 'set_precision' => FALSE, + 'precision' => 0, + 'decimal' => '.', + 'separator' => ',', + 'prefix' => '', + 'suffix' => '', + ), + 'last_comment_timestamp' => array( + 'id' => 'last_comment_timestamp', + 'table' => 'node_comment_statistics', + 'field' => 'last_comment_timestamp', + 'label' => 'Last Post', + 'date_format' => 'small', + 'custom_date_format' => '', + ), + 'timestamp' => array( + 'id' => 'timestamp', + 'table' => 'history', + 'field' => 'timestamp', + 'label' => '', + 'comments' => 1, + 'relationship' => 'none', + 'link_to_node' => 0, + 'comment' => 1, + ), + 'new_comments' => array( + 'id' => 'new_comments', + 'table' => 'node', + 'field' => 'new_comments', + 'label' => '', + 'set_precision' => FALSE, + 'precision' => 0, + 'decimal' => '.', + 'separator' => ',', + 'prefix' => '', + 'suffix' => ' new', + 'link_to_comment' => 1, + 'no_empty' => 1, + 'relationship' => 'none', + ), + )); + $handler->override_option('sorts', array( + 'last_comment_timestamp' => array( + 'id' => 'last_comment_timestamp', + 'table' => 'node_comment_statistics', + 'field' => 'last_comment_timestamp', + 'order' => 'ASC', + 'granularity' => 'second', + ), + )); + $handler->override_option('arguments', array( + 'uid_touch' => array( + 'id' => 'uid_touch', + 'table' => 'node', + 'field' => 'uid_touch', + 'default_action' => 'ignore', + 'style_plugin' => 'default_summary', + 'style_options' => array( + 'count' => TRUE, + 'override' => FALSE, + 'items_per_page' => 25, + ), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => 'Recent posts for %1', + 'default_argument_type' => 'fixed', + 'default_argument' => '', + 'validate_type' => 'none', + 'validate_fail' => 'not found', + 'relationship' => 'none', + 'default_argument_fixed' => '', + 'default_argument_php' => '', + 'validate_argument_node_type' => array( + 'album' => 0, + 'artist' => 0, + 'book' => 0, + 'page' => 0, + 'story' => 0, + 'track' => 0, + ), + 'validate_argument_php' => '', + ), + )); + $handler->override_option('filters', array( + 'status' => array( + 'id' => 'status', + 'table' => 'node', + 'field' => 'status', + 'operator' => '=', + 'value' => '1', + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'status' => array( + 'id' => 'status', + 'table' => 'comments', + 'field' => 'status', + 'operator' => '=', + 'value' => 1, + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'relationship' => 'none', + ), + ), + )); + $handler->override_option('access', array( + 'type' => 'none', + 'role' => array(), + 'perm' => '', + )); + $handler->override_option('title', 'Recent posts'); + $handler->override_option('items_per_page', '25'); + $handler->override_option('use_pager', TRUE); + $handler->override_option('style_plugin', 'table'); + $handler->override_option('style_options', array( + 'override' => 1, + 'order' => 'desc', + 'columns' => array( + 'type' => 'type', + 'title' => 'title', + 'name' => 'name', + 'comment_count' => 'comment_count', + 'last_comment_timestamp' => 'last_comment_timestamp', + 'timestamp' => 'title', + 'new_comments' => 'comment_count', + ), + 'info' => array( + 'type' => array( + 'sortable' => 1, + 'separator' => '', + ), + 'title' => array( + 'sortable' => 1, + 'separator' => ' ', + ), + 'name' => array( + 'sortable' => 1, + 'separator' => '', + ), + 'comment_count' => array( + 'sortable' => 1, + 'separator' => '<br />', + ), + 'last_comment_timestamp' => array( + 'sortable' => 1, + 'separator' => ' ', + ), + 'timestamp' => array( + 'separator' => '', + ), + 'new_comments' => array( + 'separator' => '', + ), + ), + 'default' => 'last_comment_timestamp', + )); + $handler = $view->new_display('page', 'Page', 'page'); + $handler->override_option('path', 'tracker'); + $handler->override_option('menu', array( + 'type' => 'normal', + 'title' => 'Recent posts', + 'weight' => 0, + )); + $handler->override_option('tab_options', array( + 'type' => 'none', + 'title' => NULL, + 'weight' => NULL, + )); + $views[$view->name] = $view; + + return $views; +} diff --git a/sites/all/modules/views/modules/comment/views_handler_argument_comment_user_uid.inc b/sites/all/modules/views/modules/comment/views_handler_argument_comment_user_uid.inc new file mode 100644 index 0000000000000000000000000000000000000000..af3bd52f0f9740e57635175be285c25c1d61914f --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_argument_comment_user_uid.inc @@ -0,0 +1,56 @@ +<?php +// $Id: views_handler_argument_comment_user_uid.inc,v 1.2.4.4 2010/12/09 23:36:00 dereine Exp $ + +/** + * Argument handler to accept a user id to check for nodes that + * user posted or commented on. + */ +class views_handler_argument_comment_user_uid extends views_handler_argument { + function title() { + if (!$this->argument) { + $title = variable_get('anonymous', t('Anonymous')); + } + else { + $title = db_query('SELECT u.name FROM {users} u WHERE u.uid = :uid', array(':uid' => $this->argument))->fetchField(); + } + if (empty($title)) { + return t('No user'); + } + + return check_plain($title); + } + + function default_actions($which = NULL) { + // Disallow summary views on this argument. + if (!$which) { + $actions = parent::default_actions(); + unset($actions['summary asc']); + unset($actions['summary desc']); + return $actions; + } + + if ($which != 'summary asc' && $which != 'summary desc') { + return parent::default_actions($which); + } + } + + function query() { + $this->ensure_my_table(); + + $nid_alias = $this->query->add_field('node', 'nid'); + + $subselect = db_select('comment', 'c'); + $subselect->addField('c', 'cid'); + // @TODO: Figure out why condition/placeholders doesn't work here. + $subselect->where("c.uid = $this->argument"); + $subselect->where("c.nid = $nid_alias"); + $subselect = $subselect->countQuery(); + $subselect->preExecute(); + + $condition = db_or() + ->condition("$this->table_alias.uid", $this->argument, '=') + ->where("0 < (" . (string) $subselect . ")"); + + $this->query->add_where(0, $condition); + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_field_comment.inc b/sites/all/modules/views/modules/comment/views_handler_field_comment.inc new file mode 100644 index 0000000000000000000000000000000000000000..4542da79216eca038132a6f58c39906981ba8de1 --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_field_comment.inc @@ -0,0 +1,50 @@ +<?php +// $Id: views_handler_field_comment.inc,v 1.5 2009/02/10 20:37:49 merlinofchaos Exp $ +/** + * Field handler to allow linking to a comment + */ +class views_handler_field_comment extends views_handler_field { + /** + * Override init function to provide generic option to link to comment. + */ + function init(&$view, &$options) { + parent::init($view, $options); + if (!empty($this->options['link_to_comment'])) { + $this->additional_fields['cid'] = 'cid'; + $this->additional_fields['nid'] = 'nid'; + } + } + + function option_definition() { + $options = parent::option_definition(); + $options['link_to_comment'] = array('default' => TRUE); + return $options; + } + + /** + * Provide link-to-comment option + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_to_comment'] = array( + '#title' => t('Link this field to its comment'), + '#description' => t('This will override any other link you have set.'), + '#type' => 'checkbox', + '#default_value' => $this->options['link_to_comment'], + ); + } + + function render_link($data, $values) { + if (!empty($this->options['link_to_comment']) && $data !== NULL && $data !== '') { + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "node/". $values->{$this->aliases['nid']}; + $this->options['alter']['fragment'] = "comment-" . $values->{$this->aliases['cid']}; + } + + return $data; + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->field_alias}), $values); + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_field_comment_depth.inc b/sites/all/modules/views/modules/comment/views_handler_field_comment_depth.inc new file mode 100644 index 0000000000000000000000000000000000000000..272d689baeb96ca1a0afda538c6317f70fd93ce8 --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_field_comment_depth.inc @@ -0,0 +1,14 @@ +<?php +// $Id: views_handler_field_comment_depth.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos Exp $ +/** + * Field handler to display the depth of a comment + */ +class views_handler_field_comment_depth extends views_handler_field { + /** + * Work out the depth of this comment + */ + function render($values) { + return count(explode('.', $values->comments_thread)) - 1; + } +} + diff --git a/sites/all/modules/views/modules/comment/views_handler_field_comment_link.inc b/sites/all/modules/views/modules/comment/views_handler_field_comment_link.inc new file mode 100644 index 0000000000000000000000000000000000000000..77eb6456d570f401e7d265b5d413014342bbb24a --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_field_comment_link.inc @@ -0,0 +1,47 @@ +<?php +// $Id: views_handler_field_comment_link.inc,v 1.2.6.2 2010/11/30 20:36:00 merlinofchaos Exp $ +/** + * Base field handler to present a link. + */ +class views_handler_field_comment_link extends views_handler_field { + function construct() { + parent::construct(); + $this->additional_fields['cid'] = 'cid'; + $this->additional_fields['nid'] = 'nid'; + } + + function option_definition() { + $options = parent::option_definition(); + $options['text'] = array('default' => '', 'translatable' => TRUE); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['text'] = array( + '#type' => 'textfield', + '#title' => t('Text to display'), + '#default_value' => $this->options['text'], + ); + } + + function query() { + $this->ensure_my_table(); + $this->add_additional_fields(); + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->aliases['nid']}), $values); + } + + function render_link($data, $values) { + $text = !empty($this->options['text']) ? $this->options['text'] : t('view'); + + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "node/" . $values->{$this->aliases['nid']}; + $this->options['alter']['html'] = TRUE; + $this->options['alter']['fragment'] = "comment-" . $values->{$this->aliases['cid']}; + + return $text; + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_field_comment_link_delete.inc b/sites/all/modules/views/modules/comment/views_handler_field_comment_link_delete.inc new file mode 100644 index 0000000000000000000000000000000000000000..7d0256f8101cb1743dcc5867721fd66227e6d366 --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_field_comment_link_delete.inc @@ -0,0 +1,21 @@ +<?php +// $Id: views_handler_field_comment_link_delete.inc,v 1.1.6.1 2010/11/18 07:29:03 dereine Exp $ +/** + * Field handler to present a link to delete a node. + */ +class views_handler_field_comment_link_delete extends views_handler_field_comment_link { + function access() { + //needs permission to administer comments in general + return user_access('administer comments'); + } + + function render_link($data, $values) { + $text = !empty($this->options['text']) ? $this->options['text'] : t('delete'); + + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "comment/delete/" . $values->{$this->aliases['cid']}; + $this->options['alter']['query'] = drupal_get_destination(); + + return $text; + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_field_comment_link_edit.inc b/sites/all/modules/views/modules/comment/views_handler_field_comment_link_edit.inc new file mode 100644 index 0000000000000000000000000000000000000000..8ed994d58db47657291814ebc3c3d94e55b70837 --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_field_comment_link_edit.inc @@ -0,0 +1,50 @@ +<?php +// $Id: views_handler_field_comment_link_edit.inc,v 1.1.6.2 2010/11/18 07:29:03 dereine Exp $ +/** + * Field handler to present a link node edit. + */ +class views_handler_field_comment_link_edit extends views_handler_field_comment_link { + function construct() { + parent::construct(); + $this->additional_fields['uid'] = 'uid'; + } + + function option_definition() { + $options = parent::option_definition(); + $options['destination'] = array('default' => FALSE); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $form['destination'] = array( + '#type' => 'checkbox', + '#title' => t('Use destination'), + '#description' => t('Add destination to the link'), + '#default_value' => $this->options['destination'], + ); + } + + function render_link($data, $values) { + parent::render_link($data, $values); + // ensure user has access to edit this comment. + $comment = new stdClass(); + $comment->cid = $values->{$this->aliases['cid']}; + $comment->uid = $values->{$this->aliases['uid']}; + if (!comment_access('edit', $comment)) { + return; + } + + $text = !empty($this->options['text']) ? $this->options['text'] : t('edit'); + unset($this->options['alter']['fragment']); + + if (!empty($this->options['destination'])) { + $this->options['alter']['query'] = drupal_get_destination(); + } + + return $text; + } +} + diff --git a/sites/all/modules/views/modules/comment/views_handler_field_comment_link_reply.inc b/sites/all/modules/views/modules/comment/views_handler_field_comment_link_reply.inc new file mode 100644 index 0000000000000000000000000000000000000000..8bf1fc4de3d02341bafe5071e0099dc0c451c4be --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_field_comment_link_reply.inc @@ -0,0 +1,21 @@ +<?php +// $Id: views_handler_field_comment_link_reply.inc,v 1.1.6.1 2010/11/18 07:29:03 dereine Exp $ + +/** + * Field handler to present a link to delete a node. + */ +class views_handler_field_comment_link_reply extends views_handler_field_comment_link { + function access() { + //check for permission to reply to comments + return user_access('post comments'); + } + + function render_link($data, $values) { + $text = !empty($this->options['text']) ? $this->options['text'] : t('reply'); + + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "comment/reply/" . $values->{$this->aliases['nid']} . '/' . $values->{$this->aliases['cid']}; + + return $text; + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_field_comment_node_link.inc b/sites/all/modules/views/modules/comment/views_handler_field_comment_node_link.inc new file mode 100644 index 0000000000000000000000000000000000000000..549f5815e8f846350e3cfff6d7c2f2bb00e88ce5 --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_field_comment_node_link.inc @@ -0,0 +1,62 @@ +<?php +// $Id: views_handler_field_comment_node_link.inc,v 1.1.6.4 2010/11/16 17:01:44 dereine Exp $ +/** +* Handler for showing comment module's node link. + */ +class views_handler_field_comment_node_link extends views_handler_field { + function construct() { + parent::construct(); + + // Add the node fields that comment_link will need.. + $this->additional_fields['nid'] = array( + 'field' => 'nid', + ); + $this->additional_fields['type'] = array( + 'field' => 'type', + ); + $this->additional_fields['comment'] = array( + 'field' => 'comment', + ); + } + + function option_definition() { + $options = parent::option_definition(); + $options['teaser'] = array('default' => 0); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $form['teaser'] = array( + '#type' => 'checkbox', + '#title' => t('Show teaser-style link'), + '#default_value' => $this->options['teaser'], + '#description' => t('Show the comment link in the form used on standard node teasers, rather than the full node form.'), + ); + + } + + function query() { + $this->ensure_my_table(); + $this->add_additional_fields(); + } + + function render($values) { + // Build fake $node. + $node = new stdClass(); + $node->nid = $values->{$this->aliases['nid']}; + $node->type = $values->{$this->aliases['type']}; + $node->comment = $values->{$this->aliases['comment']}; + + // Call comment.module's hook_link: comment_link($type, $node = NULL, $teaser = FALSE) + // Call node by reference so that something is changed here + comment_node_view($node, $this->options['teaser'] ? 'teaser' : 'full'); + // question: should we run these through: drupal_alter('link', $links, $node); + // might this have unexpected consequences if these hooks expect items in $node that we don't have? + + // Only render the links, if they are defined. + return !empty($node->content['links']['comment']) ? drupal_render($node->content['links']['comment']) : ''; + } +} + diff --git a/sites/all/modules/views/modules/comment/views_handler_field_comment_username.inc b/sites/all/modules/views/modules/comment/views_handler_field_comment_username.inc new file mode 100644 index 0000000000000000000000000000000000000000..39df0d89313f3dd571b5a267644cf5fc66a1f341 --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_field_comment_username.inc @@ -0,0 +1,50 @@ +<?php +// $Id: views_handler_field_comment_username.inc,v 1.2.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ +/** + * Field handler to allow linking to a user account or homepage + */ +class views_handler_field_comment_username extends views_handler_field { + /** + * Override init function to add uid and homepage fields. + */ + function init(&$view, &$data) { + parent::init($view, $data); + $this->additional_fields['uid'] = 'uid'; + $this->additional_fields['homepage'] = 'homepage'; + } + + function option_definition() { + $options = parent::option_definition(); + $options['link_to_user'] = array('default' => TRUE); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_to_user'] = array( + '#title' => t("Link this field to its user or an author's homepage"), + '#type' => 'checkbox', + '#default_value' => $this->options['link_to_user'], + ); + } + + function render_link($data, $values) { + if (!empty($this->options['link_to_user'])) { + $account->uid = $values->{$this->aliases['uid']}; + $account->name = $values->{$this->field_alias}; + $account->homepage = $values->{$this->aliases['homepage']}; + + return theme('username', array( + 'account' => $account + )); + } + else { + return $data; + } + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->field_alias}), $values); + } + +} diff --git a/sites/all/modules/views/modules/comment/views_handler_field_last_comment_timestamp.inc b/sites/all/modules/views/modules/comment/views_handler_field_last_comment_timestamp.inc new file mode 100644 index 0000000000000000000000000000000000000000..8b0c778628febf000dea9fcb0d6d4dc4a7d69dca --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_field_last_comment_timestamp.inc @@ -0,0 +1,18 @@ +<?php +// $Id: views_handler_field_last_comment_timestamp.inc,v 1.1.6.2 2010/10/16 08:36:43 dereine Exp $ + +class views_handler_field_last_comment_timestamp extends views_handler_field_date { + function construct() { + parent::construct(); + $this->additional_fields['comment_count'] = 'comment_count'; + } + + function render($values) { + if (empty($this->options['empty_zero']) || $values->{$this->aliases['comment_count']}) { + return parent::render($values); + } + else { + return NULL; + } + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_field_ncs_last_comment_name.inc b/sites/all/modules/views/modules/comment/views_handler_field_ncs_last_comment_name.inc new file mode 100644 index 0000000000000000000000000000000000000000..511a5283e5a5261e084ec9657f021ffc513b592f --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_field_ncs_last_comment_name.inc @@ -0,0 +1,48 @@ +<?php +// $Id: views_handler_field_ncs_last_comment_name.inc,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * Field handler to present the name of the last comment poster + */ +class views_handler_field_ncs_last_comment_name extends views_handler_field { + function query() { + // last_comment_name only contains data if the user is anonymous. So we + // have to join in a specially related user table. + $this->ensure_my_table(); + // join 'users' to this table via vid + $join = new views_join(); + $join->construct('users', $this->table_alias, 'last_comment_uid', 'uid'); + $join->extra = array(array('field' => 'uid', 'operator' => '!=', 'value' => '0')); + + // ncs_user alias so this can work with the sort handler, below. +// $this->user_table = $this->query->add_relationship(NULL, $join, 'users', $this->relationship); + $this->user_table = $this->query->ensure_table('ncs_users', $this->relationship, $join); + + $this->field_alias = $this->query->add_field(NULL, "COALESCE($this->user_table.name, $this->table_alias.$this->field)", $this->table_alias . '_' . $this->field); + + $this->user_field = $this->query->add_field($this->user_table, 'name'); + $this->uid = $this->query->add_field($this->table_alias, 'last_comment_uid'); + } + + function option_definition() { + $options = parent::option_definition(); + + $options['link_to_user'] = array('default' => TRUE); + + return $options; + } + + function render($values) { + if (!empty($this->options['link_to_user'])) { + $account = new stdClass(); + $account->name = $values->{$this->field_alias}; + $account->uid = $values->{$this->uid}; + return theme('username', array( + 'account' => $account + )); + } + else { + return check_plain($values->{$this->field_alias}); + } + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_field_ncs_last_updated.inc b/sites/all/modules/views/modules/comment/views_handler_field_ncs_last_updated.inc new file mode 100644 index 0000000000000000000000000000000000000000..c7a5d7f306c64c4eccd013c12c644f91fc45a7ed --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_field_ncs_last_updated.inc @@ -0,0 +1,12 @@ +<?php +// $Id: views_handler_field_ncs_last_updated.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos Exp $ +/** + * Field handler to display the newer of last comment / node updated + */ +class views_handler_field_ncs_last_updated extends views_handler_field_date { + function query() { + $this->ensure_my_table(); + $this->node_table = $this->query->ensure_table('node', $this->relationship); + $this->field_alias = $this->query->add_field(NULL, "GREATEST(" . $this->node_table . ".changed, " . $this->table_alias . ".last_comment_timestamp)", $this->table_alias . '_' . $this->field); + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_field_node_comment.inc b/sites/all/modules/views/modules/comment/views_handler_field_node_comment.inc new file mode 100644 index 0000000000000000000000000000000000000000..0ab7ba43eef101b5ece062db7ed5cee138b0f68c --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_field_node_comment.inc @@ -0,0 +1,19 @@ +<?php +// $Id: views_handler_field_node_comment.inc,v 1.1.6.1 2010/12/19 10:31:18 dereine Exp $ + +/** + * Display node comment status + */ +class views_handler_field_node_comment extends views_handler_field { + function render($values) { + switch ($values->{$this->field_alias}) { + case COMMENT_NODE_HIDDEN: + default: + return t('Hidden'); + case COMMENT_NODE_CLOSED: + return t('Closed'); + case COMMENT_NODE_OPEN: + return t('Open'); + } + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_field_node_new_comments.inc b/sites/all/modules/views/modules/comment/views_handler_field_node_new_comments.inc new file mode 100644 index 0000000000000000000000000000000000000000..a1778b8bbb4d302634bee873e6c1974bba717cb6 --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_field_node_new_comments.inc @@ -0,0 +1,107 @@ +<?php +// $Id: views_handler_field_node_new_comments.inc,v 1.7.4.4 2010/11/18 07:50:23 dereine Exp $ + +/** + * Field handler to display the number of new comments + */ +class views_handler_field_node_new_comments extends views_handler_field_numeric { + function init(&$view, &$options) { + parent::init($view, $options); + + // translate an older setting: + if (!empty($options['no_empty'])) { + $this->options['hide_empty'] = TRUE; + unset($this->options['no_empty']); + } + } + + function construct() { + parent::construct(); + $this->additional_fields['nid'] = 'nid'; + $this->additional_fields['type'] = 'type'; + $this->additional_fields['comment_count'] = array('table' => 'node_comment_statistics', 'field' => 'comment_count'); + } + + function option_definition() { + $options = parent::option_definition(); + + $options['link_to_comment'] = array('default' => TRUE); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_to_comment'] = array( + '#title' => t('Link this field to new comments'), + '#description' => t('This will override any other link you have set.'), + '#type' => 'checkbox', + '#default_value' => $this->options['link_to_comment'], + ); + } + + function query() { + $this->ensure_my_table(); + $this->add_additional_fields(); + $this->field_alias = $this->table . '_' . $this->field; + } + + function pre_render(&$values) { + global $user; + if (!$user->uid || empty($values)) { + return; + } + + $nids = array(); + $ids = array(); + foreach ($values as $id => $result) { + $nids[] = $result->{$this->aliases['nid']}; + $values[$id]->{$this->field_alias} = 0; + // Create a reference so we can find this record in the values again. + if (empty($ids[$result->{$this->aliases['nid']}])) { + $ids[$result->{$this->aliases['nid']}] = array(); + } + $ids[$result->{$this->aliases['nid']}][] = $id; + } + + if ($nids) { + $result = db_query("SELECT n.nid, COUNT(c.cid) as num_comments FROM {node} n INNER JOIN {comment} c ON n.nid = c.nid + LEFT JOIN {history} h ON h.nid = n.nid AND h.uid = :h_uid WHERE n.nid IN (:nids) + AND c.changed > GREATEST(COALESCE(h.timestamp, :timestamp), :timestamp) AND c.status = :status GROUP BY n.nid ", array( + ':status' => COMMENT_PUBLISHED, + ':h_uid' => $user->uid, + ':nids' => $nids, + ':timestamp' => NODE_NEW_LIMIT, + )); + + foreach ($result as $node) { + foreach ($ids[$node->nid] as $id) { + $values[$id]->{$this->field_alias} = $node->num_comments; + } + } + } + } + + function render_link($data, $values) { + if (!empty($this->options['link_to_comment']) && $data !== NULL && $data !== '') { + $node = new stdClass(); + $node->nid = $values->{$this->aliases['nid']}; + $node->type = $values->{$this->aliases['type']}; + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = 'node/' . $node->nid; + $this->options['alter']['query'] = comment_new_page_count($values->{$this->aliases['comment_count']}, $values->{$this->field_alias}, $node); + $this->options['alter']['fragment'] = 'new'; + } + + return $data; + } + + function render($values) { + if (!empty($values->{$this->field_alias})) { + return $this->render_link(parent::render($values), $values); + } + else { + $this->options['alter']['make_link'] = FALSE; + } + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_filter_comment_user_uid.inc b/sites/all/modules/views/modules/comment/views_handler_filter_comment_user_uid.inc new file mode 100644 index 0000000000000000000000000000000000000000..8467d07896fdb03a18dc0f9c4d9813aeeaede22d --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_filter_comment_user_uid.inc @@ -0,0 +1,24 @@ +<?php +// $Id: views_handler_filter_comment_user_uid.inc,v 1.2.4.2 2009/11/13 12:36:06 dereine Exp $ + +/** + * Filter handler to accept a user id to check for nodes that user posted or + * commented on. + */ +class views_handler_filter_comment_user_uid extends views_handler_filter_user_name { + function query() { + $this->ensure_my_table(); + + $subselect = db_select('comments', 'c'); + $subselect->addField('c', 'cid'); + $subselect->condition('uid', $this->value, $this->operator); + $subselect->condition('nid', "$this->table_alias.nid"); + $subselect = $subselect->countQuery(); + + $condition = db_or() + ->condition("$this->table_alias.uid", $this->value, $this->operator) + ->condition(0, $subselect, '<'); + + $this->query->add_where(0, $condition); + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_filter_ncs_last_updated.inc b/sites/all/modules/views/modules/comment/views_handler_filter_ncs_last_updated.inc new file mode 100644 index 0000000000000000000000000000000000000000..c8f4cbe231f074fc01fdb6c002d2d13abab805a3 --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_filter_ncs_last_updated.inc @@ -0,0 +1,18 @@ +<?php +// $Id: views_handler_filter_ncs_last_updated.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos Exp $ +/** + * Filter handler for the newer of last comment / node updated + */ +class views_handler_filter_ncs_last_updated extends views_handler_filter_date { + function query() { + $this->ensure_my_table(); + $this->node_table = $this->query->ensure_table('node', $this->relationship); + + $field = "GREATEST(" . $this->node_table . ".changed, " . $this->table_alias . ".last_comment_timestamp)"; + + $info = $this->operators(); + if (!empty($info[$this->operator]['method'])) { + $this->{$info[$this->operator]['method']}($field); + } + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_filter_node_comment.inc b/sites/all/modules/views/modules/comment/views_handler_filter_node_comment.inc new file mode 100644 index 0000000000000000000000000000000000000000..87831fd98354a020660337bd868a89b9d2079dcd --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_filter_node_comment.inc @@ -0,0 +1,15 @@ +<?php +// $Id: views_handler_filter_node_comment.inc,v 1.1.6.1 2010/12/19 10:31:18 dereine Exp $ + +/** + * Filter based on comment node status + */ +class views_handler_filter_node_comment extends views_handler_filter_in_operator { + function get_value_options() { + $this->value_options = array( + COMMENT_NODE_HIDDEN => t('Hidden'), + COMMENT_NODE_CLOSED => t('Closed'), + COMMENT_NODE_OPEN => t('Open'), + ); + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_sort_comment_thread.inc b/sites/all/modules/views/modules/comment/views_handler_sort_comment_thread.inc new file mode 100644 index 0000000000000000000000000000000000000000..1427bb4c03a6e0b65b8a21662cb7668a561a0576 --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_sort_comment_thread.inc @@ -0,0 +1,21 @@ +<?php +// $Id: views_handler_sort_comment_thread.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos Exp $ +/** + * Sort handler for ordering by thread + */ +class views_handler_sort_comment_thread extends views_handler_sort { + function query() { + $this->ensure_my_table(); + + //Read comment_render() in comment.module for an explanation of the + //thinking behind this sort. + if ($this->options['order'] == 'DESC') { + $this->query->add_orderby($this->table_alias, $this->real_field, $this->options['order']); + } + else { + $alias = $this->table_alias . '_' . $this->real_field . 'asc'; + //@todo is this secure? + $this->query->add_orderby(NULL, "SUBSTRING({$this->table_alias}.{$this->real_field}, 1, (LENGTH({$this->table_alias}.{$this->real_field}) - 1))", $this->options['order'], $alias); + } + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_sort_ncs_last_comment_name.inc b/sites/all/modules/views/modules/comment/views_handler_sort_ncs_last_comment_name.inc new file mode 100644 index 0000000000000000000000000000000000000000..61b73313048f30643009840f1a9300dfbec35b27 --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_sort_ncs_last_comment_name.inc @@ -0,0 +1,23 @@ +<?php +// $Id: views_handler_sort_ncs_last_comment_name.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos Exp $ +/** + * Sort handler to sort by last comment name which might be in 2 different + * fields + */ +class views_handler_sort_ncs_last_comment_name extends views_handler_sort { + function query() { + $this->ensure_my_table(); + $join = new views_join(); + $join->construct('users', $this->table_alias, 'last_comment_uid', 'uid'); + + // @todo this might be safer if we had an ensure_relationship rather than guessing + // the table alias. Though if we did that we'd be guessing the relationship name + // so that doesn't matter that much. +// $this->user_table = $this->query->add_relationship(NULL, $join, 'users', $this->relationship); + $this->user_table = $this->query->ensure_table('ncs_users', $this->relationship, $join); + $this->user_field = $this->query->add_field($this->user_table, 'name'); + + // Add the field. + $this->query->add_orderby(NULL, "LOWER(COALESCE($this->user_table.name, $this->table_alias.$this->field))", $this->options['order'], $this->table_alias . '_' . $this->field); + } +} diff --git a/sites/all/modules/views/modules/comment/views_handler_sort_ncs_last_updated.inc b/sites/all/modules/views/modules/comment/views_handler_sort_ncs_last_updated.inc new file mode 100644 index 0000000000000000000000000000000000000000..5e55d7e55f7f2f90754592adc6e08357e4432efb --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_handler_sort_ncs_last_updated.inc @@ -0,0 +1,13 @@ +<?php +// $Id: views_handler_sort_ncs_last_updated.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos Exp $ +/** + * Sort handler for the newer of last comment / node updated + */ +class views_handler_sort_ncs_last_updated extends views_handler_sort_date { + function query() { + $this->ensure_my_table(); + $this->node_table = $this->query->ensure_table('node', $this->relationship); + $this->field_alias = $this->query->add_orderby(NULL, "GREATEST(" . $this->node_table . ".changed, " . $this->table_alias . ".last_comment_timestamp)", $this->options['order'], $this->table_alias . '_' . $this->field); + } +} + diff --git a/sites/all/modules/views/modules/comment/views_plugin_row_comment_rss.inc b/sites/all/modules/views/modules/comment/views_plugin_row_comment_rss.inc new file mode 100644 index 0000000000000000000000000000000000000000..9212b86210ff565e1569425aaf595e6ef4c24124 --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_plugin_row_comment_rss.inc @@ -0,0 +1,65 @@ +<?php +// $Id: views_plugin_row_comment_rss.inc,v 1.3.6.3 2010/05/21 20:32:06 dereine Exp $ +/** + * @file + * Contains the comment RSS row style plugin. + */ + +/** + * Plugin which formats the comments as RSS items. + */ +class views_plugin_row_comment_rss extends views_plugin_row { + var $base_table = 'comment'; + var $base_field = 'cid'; + + function pre_render($result) { + $cids = array(); + $this->comments = array(); + + foreach ($result as $row) { + $cids[] = $row->cid; + } + + $cresult = comment_load_multiple($cids); + foreach ($cresult as $comment) { + $comment = drupal_unpack($comment); + $comment->name = $comment->uid ? $comment->registered_name : $comment->name; + $comment->depth = count(explode('.', $comment->thread)) - 1; + $this->comments[$comment->cid] = $comment; + } + } + + function render($row) { + global $base_url; + + // Load the specified comment: + $comment = $this->comments[$row->{$this->field_alias}]; + + $item = new stdClass(); + $item->title = $comment->subject; + $item->link = url('node/' . $comment->nid, array('absolute' => TRUE, 'fragment' => 'comment-' . $comment->cid)); + $item->description = check_markup($comment->comment, $comment->format); + $item->elements = array( + array('key' => 'pubDate', 'value' => gmdate('r', $comment->timestamp)), + array('key' => 'dc:creator', 'value' => $comment->name), + array( + 'key' => 'guid', + 'value' => 'comment ' . $row->cid . ' at ' . $base_url, + 'attributes' => array('isPermaLink' => 'false'), + 'namespace' => array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/'), + ), + ); + + foreach ($item->elements as $element) { + if (isset($element['namespace'])) { + $this->view->style_plugin->namespaces = array_merge($this->view->style_plugin->namespaces, $element['namespace']); + } + } + + return theme($this->theme_functions(), array( + 'view' => $this->view, + 'options' => $this->options, + 'row' => $item + )); + } +} diff --git a/sites/all/modules/views/modules/comment/views_plugin_row_comment_view.inc b/sites/all/modules/views/modules/comment/views_plugin_row_comment_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..cc1dba9eeb2c304aedaaae76eee7e45c2aac419e --- /dev/null +++ b/sites/all/modules/views/modules/comment/views_plugin_row_comment_view.inc @@ -0,0 +1,46 @@ +<?php +// $Id: views_plugin_row_comment_view.inc,v 1.1.6.2 2010/01/28 00:00:56 dereine Exp $ +/** + * @file + * Contains the node RSS row style plugin. + */ + +/** + * Plugin which performs a comment_view on the resulting object. + */ +class views_plugin_row_comment_view extends views_plugin_row { + var $base_table = 'comment'; + var $base_field = 'cid'; + + function option_definition() { + $options = parent::option_definition(); + $options['links'] = array('default' => TRUE); + return $options; + } + + function options_form(&$form, &$form_state) { + $form['links'] = array( + '#type' => 'checkbox', + '#title' => t('Display links'), + '#default_value' => $this->options['links'], + ); + } + + function pre_render($result) { + $cids = array(); + $this->comments = array(); + + foreach ($result as $row) { + $cids[] = $row->cid; + } + + $cresult = comment_load_multiple($cids); + foreach ($cresult as $comment) { + $comment = drupal_unpack($comment); + $comment->name = $comment->uid ? $comment->registered_name : $comment->name; + $comment->depth = count(explode('.', $comment->thread)) - 1; + $this->comments[$comment->cid] = $comment; + } + } +} + diff --git a/sites/all/modules/views/modules/contact.views.inc b/sites/all/modules/views/modules/contact.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..15268841bd66baf377653da541699fcfb62f4ee7 --- /dev/null +++ b/sites/all/modules/views/modules/contact.views.inc @@ -0,0 +1,18 @@ +<?php +//$Id: contact.views.inc,v 1.1.6.2 2010/07/19 09:18:42 dereine Exp $ +/** + * @file + * Provide views data and handlers for contact.module + */ + +function contact_views_data() { + $data['users']['contact'] = array( + 'field' => array( + 'title' => t('Link to contact page'), + 'help' => t('Provide a simple link to the user contact page.'), + 'handler' => 'views_handler_field_contact_link', + ), + ); + return $data; +} + diff --git a/sites/all/modules/views/modules/contact/views_handler_field_contact_link.inc b/sites/all/modules/views/modules/contact/views_handler_field_contact_link.inc new file mode 100644 index 0000000000000000000000000000000000000000..f2456f4f37f4a7227f843ffd68db3aeda81e662d --- /dev/null +++ b/sites/all/modules/views/modules/contact/views_handler_field_contact_link.inc @@ -0,0 +1,77 @@ +<?php +// $Id: views_handler_field_contact_link.inc,v 1.2.4.5 2010/12/23 05:44:54 dereine Exp $ +/** + * A field that links to the user contact page, if access is permitted. + */ +class views_handler_field_contact_link extends views_handler_field_user_link { + + function option_definition() { + $options = parent::option_definition(); + $options['link_display'] = array('default' => 'link', 'translatable' => FALSE); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_display'] = array( + '#title' => t('Type of link'), + '#default_value' => $this->options['link_display'], + '#type' => 'select', + '#options' => array( + 'link' => t('Link'), + 'icon' => t('Icon'), + ), + ); + $form['text']['#title'] = t('Link label'); + $form['text']['#required'] = TRUE; + $form['text']['#default_value'] = empty($this->options['text']) ? t('contact') : $this->options['text']; + } + + // An example of field level access control. + // We must override the access method in the parent class, as that requires + // the 'access user profiles' permission, which the contact form does not. + function access() { + global $user; + + // Only registered users can view other registered user's contact page. + if (empty($user->uid)) { + return FALSE; + } + + return TRUE; + } + + function render_link($data, $values) { + global $user; + $uid = $values->{$this->aliases['uid']}; + + if (empty($uid)) { + return; + } + + $account = user_load($uid); + if (empty($account)) { + return; + } + + // Check access when we pull up the user account so we know + // if the user has made the contact page available. + if (!_contact_personal_tab_access($account) || empty($account->contact)) { + return; + } + + $this->options['alter']['path'] = 'user/'. $account->uid .'/contact'; + $this->options['alter']['attributes'] = array('title' => t('Contact %user', array('%user' => $account->name))); + + if ($this->options['link_display'] == 'icon') { + $text = theme('image', array('path' => 'misc/forum-new.png')); + $this->options['alter']['html'] = TRUE; + } + else { + $text = $this->options['text']; + } + + return $text; + } +} + diff --git a/sites/all/modules/views/modules/field.views.inc b/sites/all/modules/views/modules/field.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..7c2ac663b2aabaceff283e37d667a3d08e4694e9 --- /dev/null +++ b/sites/all/modules/views/modules/field.views.inc @@ -0,0 +1,271 @@ +<?php +// $Id: field.views.inc,v 1.1.2.17 2011/01/04 23:54:35 dereine Exp $ + +/** + * @file + * Provide Views data and handlers for field.module + */ + +/** + * @defgroup views_field_module field.module handlers + * + * @{ + */ + +/** + * Implements hook_views_data() + */ +function field_views_data() { + $data = array(); + foreach (field_info_fields() as $field) { + if ($field['storage']['type'] != 'field_sql_storage') { + continue; + } + + $module = $field['module']; + $result = (array) module_invoke($module, 'field_views_data', $field); + + if (empty($result)) { + $result = field_views_field_default_views_data($field); + } + drupal_alter('field_views_data', $result, $field, $module); + + if (is_array($result)) { + $data = array_merge($data, $result); + } + } + + return $data; +} + +/** + * Default views data implementation for a field. + */ +function field_views_field_default_views_data($field) { + $field_types = field_info_field_types(); + + // Check the field module is available. + if (!isset($field_types[$field['type']])) { + return; + } + + $data = array(); + + $current_table = _field_sql_storage_tablename($field); + $revision_table = _field_sql_storage_revision_tablename($field); + + // The list of entity:bundle that this field is used in. + $bundles_names = array(); + $supports_revisions = FALSE; + $entity_tables = array(); + + // Build the relationships between the field table and the entity tables. + foreach ($field['bundles'] as $entity => $bundles) { + $entity_info = entity_get_info($entity); + $entity_tables[$entity_info['base table']] = $entity; + + $data[$current_table]['table']['join'][$entity_info['base table']] = array( + 'left_field' => $entity_info['entity keys']['id'], + 'field' => 'entity_id', + 'extra' => array( + array('field' => 'entity_type', 'value' => $entity), + array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE), + ), + ); + + if (!empty($entity_info['entity keys']['revision']) && !empty($entity_info['revision table'])) { + $data[$revision_table]['table']['join'][$entity_info['revision table']] = array( + 'left_field' => $entity_info['entity keys']['revision'], + 'field' => 'revision_id', + 'extra' => array( + array('field' => 'entity_type', 'value' => $entity), + array('field' => 'deleted', 'value' => 0, 'numeric' => TRUE), + ), + ); + + $supports_revisions = TRUE; + } + + foreach ($bundles as $bundle) { + $bundles_names[] = t('@entity:@bundle', array('@entity' => $entity, '@bundle' => $bundle)); + } + } + + $tables = array(); + $tables[FIELD_LOAD_CURRENT] = $current_table; + if ($supports_revisions) { + $tables[FIELD_LOAD_REVISION] = $revision_table; + } + + $add_fields = array('entity_type', 'delta', 'language', 'bundle'); + foreach ($field['columns'] as $column_name => $attributes) { + $add_fields[] = _field_sql_storage_columnname($field['field_name'], $column_name); + } + + // Add the field handler for this field. + $title_short = $field['field_name']; + foreach ($tables as $type => $table) { + if ($type == FIELD_LOAD_CURRENT) { + $group = t('Fields'); + $column = 'entity_id'; + } + else { + $group = t('Fields (historical data)'); + $column = 'revision_id'; + } + + $data[$table][$column] = array( + 'group' => $group, + 'title' => $title_short, + 'title short' => $title_short, + 'help' => t('Appears in: @bundles', array('@bundles' => implode(', ', $bundles_names))), + ); + $data[$table][$column]['field'] = array( + 'field' => $column, + 'table' => $table, + 'handler' => 'views_handler_field_field', + 'click sortable' => TRUE, + 'field_name' => $field['field_name'], + 'additional fields' => $add_fields, + 'entity_tables' => $entity_tables, + 'field_info' => $field, + ); + } + + foreach ($field['columns'] as $column => $attributes) { + $allow_sort = TRUE; + + // 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': + case 'numeric': + case 'float': + $filter = 'views_handler_filter_numeric'; + $argument = 'views_handler_argument_numeric'; + $sort = 'views_handler_sort'; + break; + case 'text': + case 'blob': + // It does not make sense to sort by blob or text. + $allow_sort = FALSE; + default: + $filter = 'views_handler_filter_string'; + $argument = 'views_handler_argument_string'; + $sort = 'views_handler_sort'; + break; + } + + // Note: we don't have a label available here, because we are at the field + // level, not at the instance level. + if (count($field['columns']) == 1 && $column == 'value') { + $title = t('@label (!name)', array('@label' => $field['field_name'], '!name' => $field['field_name'])); + $title_short = $field['field_name']; + } + else { + $title = t('@label (!name) - !column', array('@label' => $field['field_name'], '!name' => $field['field_name'], '!column' => $column)); + $title_short = t('@label-truncated - !column', array('@label-truncated' => $field['field_name'], '!column' => $column)); + } + + foreach ($tables as $type => $table) { + $group = $type == FIELD_LOAD_CURRENT ? t('Fields') : t('Fields (historical data)'); + $column_real_name = $field['storage']['details']['sql'][$type][$table][$column]; + + // Load all the fields from the table by default. + $additional_fields = array_values($field['storage']['details']['sql'][$type][$table]); + + $data[$table][$column_real_name] = array( + 'group' => $group, + 'title' => $title, + 'title short' => $title_short, + 'help' => t('Appears in: @bundles', array('@bundles' => implode(', ', $bundles_names))), + ); + + $data[$table][$column_real_name]['argument'] = array( + 'field' => $column_real_name, + 'table' => $table, + 'handler' => $argument, + 'additional fields' => $additional_fields, + 'field_name' => $field['field_name'], + 'empty field name' => t('<No value>'), + ); + $data[$table][$column_real_name]['filter'] = array( + 'field' => $column_real_name, + 'table' => $table, + 'handler' => $filter, + 'additional fields' => $additional_fields, + 'field_name' => $field['field_name'], + 'allow empty' => TRUE, + ); + if (!empty($allow_sort)) { + $data[$table][$column_real_name]['sort'] = array( + 'field' => $column_real_name, + 'table' => $table, + 'handler' => $sort, + 'additional fields' => $additional_fields, + 'field_name' => $field['field_name'], + ); + } + + // Expose additional delta column for multiple value fields. + if ($field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED) { + $title = t('@label (!name) - delta', array('@label' => $field['field_name'], '!name' => $field['field_name'])); + $title_short = t('!name - delta', array('!name' => $field['field_name'])); + + $data[$table]['delta'] = array( + 'group' => $group, + 'title' => $title, + 'title short' => $title_short, + 'help' => t('Delta - Appears in: @bundles', array('@bundles' => implode(', ', $bundles_names))), + ); + $data[$table]['delta']['argument'] = array( + 'field' => 'delta', + 'table' => $table, + 'handler' => 'views_handler_argument_numeric', + 'additional fields' => $additional_fields, + 'empty field name' => t('<No value>'), + 'field_name' => $field['field_name'], + ); + $data[$table]['delta']['filter'] = array( + 'field' => 'delta', + 'table' => $table, + 'handler' => 'views_handler_filter_numeric', + 'additional fields' => $additional_fields, + 'field_name' => $field['field_name'], + 'allow empty' => TRUE, + ); + $data[$table]['delta']['sort'] = array( + 'field' => 'delta', + 'table' => $table, + 'handler' => 'views_handler_sort', + 'additional fields' => $additional_fields, + 'field_name' => $field['field_name'], + ); + } + } + } + + return $data; +} + +/** + * Have a different filter handler for lists. This should allow to select values of the list. + */ +function list_field_views_data($field) { + $data = field_views_field_default_views_data($field); + foreach ($data as $table_name => $table_data) { + foreach ($table_data as $field_name => $field_data) { + if (!in_array($field_name, array('table', 'entity_id', 'revision_id'))) { + $data[$table_name][$field_name]['filter']['handler'] = 'views_handler_filter_field_list'; + } + } + } + return $data; +} + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/field/views_handler_field_field.inc b/sites/all/modules/views/modules/field/views_handler_field_field.inc new file mode 100644 index 0000000000000000000000000000000000000000..e3cd7f8229d29bf12c034a2079f6d3fea4522eb6 --- /dev/null +++ b/sites/all/modules/views/modules/field/views_handler_field_field.inc @@ -0,0 +1,339 @@ +<?php +// $Id: views_handler_field_field.inc,v 1.1.2.20 2011/01/06 00:37:05 dereine Exp $ + +/** + * Helper function: Return an array of formatter options for a field type. + * + * Borrowed from field_ui. + */ +function _field_view_formatter_options($field_type = NULL) { + $options = &drupal_static(__FUNCTION__); + + if (!isset($options)) { + $field_types = field_info_field_types(); + $options = array(); + foreach (field_info_formatter_types() as $name => $formatter) { + foreach ($formatter['field types'] as $formatter_field_type) { + // Check that the field type exists. + if (isset($field_types[$formatter_field_type])) { + $options[$formatter_field_type][$name] = $formatter['label']; + } + } + } + } + + if ($field_type) { + return !empty($options[$field_type]) ? $options[$field_type] : array(); + } + return $options; +} + +/** + * A field that displays fields. + */ +class views_handler_field_field extends views_handler_field { + /** + * Called to add the field to a query. + * + * By default, the only columns added to the query are entity_id and + * entity_type. This is because other needed data is fetched by entity_load(). + * Other columns are added only if they are used in groupings, or if + * 'add fields to query' is specifically set to TRUE in the field definition. + * + * The 'add fields to query' switch is used by modules which need all data + * present in the query itself (such as "sphinx"). + */ + function query($use_groupby = FALSE) { + $base_table = $this->view->base_table; + $base_field = $this->view->base_field; + + // If the current field is under a relationship you can't be sure that the + // base table of the view is the base table of the current field. + // For example a field from a node author on a node view does have users as base table. + if (!empty($this->relationship)) { + foreach ($this->view->relationship as $relationship) { + if ($relationship->alias == $this->relationship) { + $base_table = $relationship->definition['base']; + $base_field = $relationship->definition['base field']; + } + } + } + + $params = array(); + if ($use_groupby) { + // When grouping on a "field API" field (whose "real_field" is set to + // entity_id), retrieve the minimum entity_id to have a valid entity_id to + // pass to field_view_field(). + $params = array( + 'function' => 'min', + ); + } + + // We always need the base field (entity_id / revision_id). + $this->field_alias = $this->query->add_field($base_table, $base_field, '', $params); + + // Get the entity type according to the base table of the field. + // Then add it to the query as a formula. That way we can avoid joining + // the field table if all we need is entity_id and entity_type. + $this->entity_type = $entity_type = $this->definition['entity_tables'][$base_table]; + // The alias needs to be unique, so we use both the field table and the entity type. + $entity_type_alias = $this->definition['table'] . '_' . $entity_type . '_entity_type'; + $this->aliases['entity_type'] = $this->query->add_field(NULL, "'$entity_type'", $entity_type_alias); + + $fields = $this->additional_fields; + + // We've already added entity_type, so we can remove it from the list. + $entity_type_key = array_search('entity_type', $fields); + if ($entity_type_key !== FALSE) { + unset($fields[$entity_type_key]); + } + + if ($use_groupby) { + // Remove additional fields that are not the group_column or are not in + // the additional group_columns as their presence in the query inhibits + // grouping. + $group_field_name = $this->definition['field_name'] . '_' . $this->options['group_column']; + if (in_array($group_field_name, $fields)) { + $fields = array($group_field_name => $group_field_name) + $this->options['group_columns']; + } + } + + // Add additional fields (and the table join itself) if needed. + if ($use_groupby || !empty($this->definition['add fields to query'])) { + $this->ensure_my_table(); + $this->add_additional_fields($fields); + + // Filter by language, if field translation is enabled. + $field = $this->definition['field_info']; + if (field_is_translatable($entity_type, $field)) { + $column = $this->table_alias . ".language"; + $this->query->add_where(0, $column, $this->query->options['field_language']); + } + } + + // The revision id inhibits grouping. + // So, stop here if we're using grouping, or if aren't adding all columns to + // the query. + if ($use_groupby || empty($this->definition['add fields to query'])) { + return; + } + + $this->add_additional_fields(array('revision_id')); + } + + /** + * Called to determine what to tell the clicksorter. + */ + function click_sort($order) { + $column = _field_sql_storage_columnname($this->definition['field_name'], $this->options['click_sort_column']); + // The field has already been added to the query, just add a sort on it. + $this->query->add_orderby(NULL, NULL, $order, $this->aliases[$column]); + } + + function option_definition() { + $options = parent::option_definition(); + + $field = $this->definition['field_info']; + $field_type = field_info_field_types($field['type']); + $column_names = array_keys($field['columns']); + + // If the field has a "value" column, we probably need that one. + $options['click_sort_column'] = array( + 'default' => in_array('value', $column_names) ? 'value' : '', + ); + $options['type'] = array( + 'default' => $field_type['default_formatter'], + ); + $options['settings'] = array( + 'default' => array(), + ); + $options['group_column'] = array( + 'default' => in_array('value', $column_names) ? 'value' : $column_names[0], + ); + $options['group_columns'] = array( + 'default' => array(), + ); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $field = $this->definition['field_info']; + $formatters = _field_view_formatter_options($field['type']); + $column_names = array_keys($field['columns']); + + // No need to ask the user anything if the field has only one column. + if (count($field['columns']) == 1) { + $form['click_sort_column'] = array( + '#type' => 'value', + '#value' => $column_names[0], + ); + } + else { + $form['click_sort_column'] = array( + '#type' => 'select', + '#title' => t('Click sort column'), + '#options' => drupal_map_assoc($column_names), + '#default_value' => $this->options['click_sort_column'], + '#description' => t('Used by Style: Table to determine the actual column to click sort the field on. The default is usually fine.'), + ); + } + + $form['type'] = array( + '#type' => 'select', + '#title' => t('Formatter'), + '#options' => $formatters, + '#default_value' => $this->options['type'], + '#ajax' => array( + 'path' => views_ui_build_form_url($form_state), + ), + ); + + // Get the currently selected formatter. + if (isset($form_state['values']['options']['type'])) { + $format = $form_state['values']['options']['type']; + } + else { + $format = $this->options['type']; + } + $formatter = field_info_formatter_types($format); + $settings = $this->options['settings'] + field_info_formatter_settings($format); + + // Provide an instance array for hook_field_formatter_settings_form(). + ctools_include('fields'); + $instance = ctools_fields_fake_field_instance($this->definition['field_name'], '_dummy', $formatter, $settings); + + // Store the settings in a '_dummy' view mode. + $instance['display']['_dummy'] = array( + 'type' => $format, + 'settings' => $settings, + ); + + // Get the settings form. + $settings_form = array('#value' => array()); + $function = $formatter['module'] . '_field_formatter_settings_form'; + if (function_exists($function)) { + $settings_form = $function($field, $instance, '_dummy', $form, $form_state); + } + $form['settings'] = $settings_form; + } + + /** + * Extend the groupby form with group columns. + */ + function groupby_form(&$form, &$form_state) { + parent::groupby_form($form, $form_state); + // With "field API" fields, the column target of the grouping function + // and any additional grouping columns must be specified. + $group_columns = drupal_map_assoc(array_keys($this->definition['field_info']['columns']), 'ucfirst'); + $form['group_column'] = array( + '#type' => 'select', + '#title' => t('Group column'), + '#default_value' => $this->options['group_column'], + '#description' => t('Select the column of this field to apply the grouping function selected above.'), + '#options' => $group_columns, + ); + + $options = drupal_map_assoc(array('bundle', 'language', 'entity_type'), 'ucfirst'); + $form['group_columns'] = array( + '#type' => 'checkboxes', + '#title' => t('Group columns (additional)'), + '#default_value' => $this->options['group_columns'], + '#description' => t('Select any additional columns of this field to include in the query and to group on.'), + '#options' => $options, + ); + } + + function groupby_form_submit(&$form, &$form_state) { + parent::groupby_form_submit($form, $form_state); + $item =& $form_state['handler']->options; + + if ($item['group_type'] != 'group') { + unset($item['group_column']); + unset($item['group_columns']); + } + else { + // Add settings for "field API" fields. + $item['group_column'] = $form_state['values']['group_column']; + $item['group_columns'] = array_filter($form_state['values']['group_columns']); + } + } + + /** + * Load the entities for all fields that are about to be displayed. + */ + function pre_render(&$values) { + if (!empty($values)) { + // Divide the entity ids by entity type, so they can be loaded in bulk. + $entities_by_type = array(); + foreach ($values as $key => $object) { + if (isset($object->{$this->field_alias}) && !isset($values[$key]->_field_data[$this->field_alias])) { + $entity_type = $object->{$this->aliases['entity_type']}; + $entity_id = $object->{$this->field_alias}; + $entities_by_type[$entity_type][$key] = $entity_id; + } + } + + // Load the entities. + foreach ($entities_by_type as $entity_type => $entity_ids) { + $entities = entity_load($entity_type, $entity_ids); + + foreach ($entity_ids as $key => $entity_id) { + $values[$key]->_field_data[$this->field_alias] = array( + 'entity_type' => $entity_type, + 'entity' => $entities[$entity_id], + ); + } + } + } + } + + function render($values) { + if (isset($values->_field_data[$this->field_alias])) { + // Prepare arguments for rendering based on the objects cached in the + // pre-render phase and the display options for this field. + $entity_type = $values->_field_data[$this->field_alias]['entity_type']; + $entity = $values->_field_data[$this->field_alias]['entity']; + + // The field we are trying to display doesn't exist on this entity. + if (!isset($entity->{$this->definition['field_name']})) { + return ''; + } + + $display = array( + 'type' => $this->options['type'], + 'settings' => $this->options['settings'], + 'label' => 'hidden', + ); + + $langcode = $this->field_language(); + $render_array = field_view_field($entity_type, $entity, $this->definition['field_name'], $display, $langcode); + return drupal_render($render_array); + } + else { + return ''; + } + } + + /** + * Return the language code of the language the field should be displayed in, + * according to the settings. + */ + function field_language() { + global $language_content; + + if (field_is_translatable($this->entity_type, $this->definition['field_info'])) { + $default_language = language_default('language'); + $language = str_replace(array('***CURRENT_LANGUAGE***', '***DEFAULT_LANGUAGE***'), + array($language_content->language, $default_language), + $this->query->options['field_language']); + + return $language; + } + else { + return LANGUAGE_NONE; + } + } +} diff --git a/sites/all/modules/views/modules/field/views_handler_filter_field_list.inc b/sites/all/modules/views/modules/field/views_handler_filter_field_list.inc new file mode 100644 index 0000000000000000000000000000000000000000..a43e465f61e2e81bd0760da242d0876dc3ee3b19 --- /dev/null +++ b/sites/all/modules/views/modules/field/views_handler_filter_field_list.inc @@ -0,0 +1,9 @@ +<?php +// $Id: views_handler_filter_field_list.inc,v 1.1.2.2 2010/09/30 20:07:59 dereine Exp $ + +class views_handler_filter_field_list extends views_handler_filter_in_operator { + function get_value_options() { + $field = field_info_field($this->definition['field_name']); + $this->value_options = list_allowed_values($field); + } +} diff --git a/sites/all/modules/views/modules/filter.views.inc b/sites/all/modules/views/modules/filter.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..1251c9d62d81a1fb8b50fc7a0822171506165fdc --- /dev/null +++ b/sites/all/modules/views/modules/filter.views.inc @@ -0,0 +1,41 @@ +<?php +// $Id: filter.views.inc,v 1.1.6.2 2010/07/19 09:18:42 dereine Exp $ +/** + * @file + * Provide basic views data for filter.module. + */ + +/** + * @defgroup views_filter_module filter.module handlers + * + * Only includes the table 'filter_formats'. + * @{ + */ + +/** + * Implements hook_views_data() + */ +function filter_views_data() { + // ---------------------------------------------------------------------- + // filter_formats table + + // Have not defined $data['filter_formats']['table']['group'] since + // no fields are defined here yet. + $data['filter_formats']['table']['join'] = array( + 'node_revisions' => array( + 'left_field' => 'format', + 'field' => 'format', + ), + 'node' => array( + 'left_table' => 'node_revisions', + 'left_field' => 'format', + 'field' => 'format', + ), + ); + + return $data; +} + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/filter/views_handler_field_filter_format_name.inc b/sites/all/modules/views/modules/filter/views_handler_field_filter_format_name.inc new file mode 100644 index 0000000000000000000000000000000000000000..301b17a0da54fdae30b0337826f0127215c6f2b4 --- /dev/null +++ b/sites/all/modules/views/modules/filter/views_handler_field_filter_format_name.inc @@ -0,0 +1,29 @@ +<?php +// $Id: views_handler_field_filter_format_name.inc,v 1.2.4.2 2010/05/22 11:57:38 dereine Exp $ +/** + * Field handler to output the name of an input format. + */ +class views_handler_field_filter_format_name extends views_handler_field { + function construct() { + parent::construct(); + // Be explicit about the table we are using. + $this->additional_fields['name'] = array('table' => 'filter_formats', 'field' => 'name'); + } + + function query() { + $this->ensure_my_table(); + $this->add_additional_fields(); + } + + function render($values) { + $format_name = $values->{$this->aliases['name']}; + if (!$format_name) { + // Default or invalid input format. + // filter_formats() will reliably return the default format even if the + // current user is unprivileged. + $format = filter_formats(filter_default_format()); + return check_plain($format->name); + } + return check_plain($format_name); + } +} diff --git a/sites/all/modules/views/modules/locale.views.inc b/sites/all/modules/views/modules/locale.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..50ead26925f983e74a42cd62c3f6791380555150 --- /dev/null +++ b/sites/all/modules/views/modules/locale.views.inc @@ -0,0 +1,207 @@ +<?php +// $Id: locale.views.inc,v 1.1.6.2 2010/07/19 09:18:42 dereine Exp $ + +/** + * @file + * + * Provides views data and handlers for locale.module. + */ + +/** + * @defgroup views_locale_module locale.module handlers + * + * @{ + */ + +/** + * Implements hook_views_data(). + */ +function locale_views_data() { + // Basic table information. + + // Define the base group of this table. + $data['locales_source']['table']['group'] = t('Locale source'); + + // Advertise this table as a possible base table. + $data['locales_source']['table']['base'] = array( + 'field' => 'lid', + 'title' => t('Locale source'), + 'help' => t('A source string for translation, in English or the default site language.'), + ); + + // lid + $data['locales_source']['lid'] = array( + 'title' => t('LID'), + 'help' => t('The ID of the source string.'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + 'numeric' => TRUE, + 'validate type' => 'lid', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // location + $data['locales_source']['location'] = array( + 'group' => t('Locale source'), + 'title' => t('Location'), + 'help' => t('A description of the location or context of the string.'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // Group field + $data['locales_source']['textgroup'] = array( + 'group' => t('Locale source'), + 'title' => t('Group'), + 'help' => t('The group the translation is in.'), + 'field' => array( + 'handler' => 'views_handler_field_locale_group', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_locale_group', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_locale_group', + ), + ); + + // Source field + $data['locales_source']['source'] = array( + 'group' => t('Locale source'), + 'title' => t('Source'), + 'help' => t('The full original string.'), + 'field' => array( + 'handler' => 'views_handler_field', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + // Version field + $data['locales_source']['version'] = array( + 'group' => t('Locale source'), + 'title' => t('Version'), + 'help' => t('The version of Drupal core that this string is for.'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_locale_version', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + $data['locales_source']['edit_lid'] = array( + 'group' => t('Locale source'), + 'field' => array( + 'title' => t('Edit link'), + 'help' => t('Provide a simple link to edit the translations.'), + 'handler' => 'views_handler_field_locale_link_edit', + ), + ); + + // ---------------------------------------------------------------------- + // Locales target table + + // Define the base group of this table. Fields that don't + // have a group defined will go into this field by default. + $data['locales_target']['table']['group'] = t('Locale target'); + + // Join information + $data['locales_target']['table']['join'] = array( + 'locales_source' => array( + 'left_field' => 'lid', + 'field' => 'lid', + ), + ); + + // Translation field + $data['locales_target']['translation'] = array( + 'group' => t('Locale target'), + 'title' => t('Translation'), + 'help' => t('The full translation string.'), + 'field' => array( + 'handler' => 'views_handler_field', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + // Language field + $data['locales_target']['language'] = array( + 'group' => t('Locale target'), + 'title' => t('Language'), + 'help' => t('The language this translation is in.'), + 'field' => array( + 'handler' => 'views_handler_field_locale_language', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_locale_language', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_locale_language', + ), + ); + + $data['locales_target']['plid'] = array( + 'group' => t('Locale target'), + 'title' => t('Singular LID'), + 'help' => t('The ID of the parent translation.'), + 'field' => array( + 'handler' => 'views_handler_field', + ), + ); + + // Plural + $data['locales_target']['plural'] = array( + 'group' => t('Locale target'), + 'title' => t('Plural'), + 'help' => t('Whether or not the translation is plural.'), + 'field' => array( + 'handler' => 'views_handler_field_boolean', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_boolean_operator', + 'label' => t('Plural'), + 'type' => 'yes-no', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + return $data; +} + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/locale/views_handler_argument_locale_group.inc b/sites/all/modules/views/modules/locale/views_handler_argument_locale_group.inc new file mode 100644 index 0000000000000000000000000000000000000000..e199e67fe5f0f7ce11b449742321ea5daf8f9c6a --- /dev/null +++ b/sites/all/modules/views/modules/locale/views_handler_argument_locale_group.inc @@ -0,0 +1,35 @@ +<?php +// $Id: views_handler_argument_locale_group.inc,v 1.1 2009/02/20 23:02:09 merlinofchaos Exp $ + +/** + * Argument handler to accept a language. + */ +class views_handler_argument_locale_group extends views_handler_argument { + function construct() { + parent::construct('group'); + } + + /** + * Override the behavior of summary_name(). Get the user friendly version + * of the group. + */ + function summary_name($data) { + return $this->locale_group($data->{$this->name_alias}); + } + + /** + * Override the behavior of title(). Get the user friendly version + * of the language. + */ + function title() { + return $this->locale_group($this->argument); + } + + function locale_group($group) { + $groups = module_invoke_all('locale', 'groups'); + // Sort the list. + asort($groups); + return isset($groups[$group]) ? $groups[$group] : t('Unknown group'); + } +} + diff --git a/sites/all/modules/views/modules/locale/views_handler_argument_locale_language.inc b/sites/all/modules/views/modules/locale/views_handler_argument_locale_language.inc new file mode 100644 index 0000000000000000000000000000000000000000..32b8288d6eda3f140dffc84750ee0eb394755376 --- /dev/null +++ b/sites/all/modules/views/modules/locale/views_handler_argument_locale_language.inc @@ -0,0 +1,33 @@ +<?php +// $Id: views_handler_argument_locale_language.inc,v 1.1 2009/02/20 23:02:09 merlinofchaos Exp $ + +/** + * Argument handler to accept a language. + */ +class views_handler_argument_locale_language extends views_handler_argument { + function construct() { + parent::construct('language'); + } + + /** + * Override the behavior of summary_name(). Get the user friendly version + * of the language. + */ + function summary_name($data) { + return $this->locale_language($data->{$this->name_alias}); + } + + /** + * Override the behavior of title(). Get the user friendly version + * of the language. + */ + function title() { + return $this->locale_language($this->argument); + } + + function locale_language($langcode) { + $languages = locale_language_list(); + return isset($languages[$langcode]) ? $languages[$langcode] : t('Unknown language'); + } +} + diff --git a/sites/all/modules/views/modules/locale/views_handler_field_locale_group.inc b/sites/all/modules/views/modules/locale/views_handler_field_locale_group.inc new file mode 100644 index 0000000000000000000000000000000000000000..ffd0d43c50d86dc4e3c4cccfbcba69f136eab405 --- /dev/null +++ b/sites/all/modules/views/modules/locale/views_handler_field_locale_group.inc @@ -0,0 +1,14 @@ +<?php +// $Id: views_handler_field_locale_group.inc,v 1.1 2009/02/20 23:02:09 merlinofchaos Exp $ + +/** + * Field handler to translate a group into its readable form. + */ +class views_handler_field_locale_group extends views_handler_field { + function render($values) { + $groups = module_invoke_all('locale', 'groups'); + // Sort the list. + asort($groups); + return isset($groups[$values->{$this->field_alias}]) ? $groups[$values->{$this->field_alias}] : ''; + } +} diff --git a/sites/all/modules/views/modules/locale/views_handler_field_locale_language.inc b/sites/all/modules/views/modules/locale/views_handler_field_locale_language.inc new file mode 100644 index 0000000000000000000000000000000000000000..d35242721d96b5fa6f5bc8c8ddd890c472dd0590 --- /dev/null +++ b/sites/all/modules/views/modules/locale/views_handler_field_locale_language.inc @@ -0,0 +1,12 @@ +<?php +// $Id: views_handler_field_locale_language.inc,v 1.1 2009/02/20 23:02:09 merlinofchaos Exp $ + +/** + * Field handler to translate a language into its readable form. + */ +class views_handler_field_locale_language extends views_handler_field { + function render($values) { + $languages = language_list(); + return isset($languages[$values->{$this->field_alias}]) ? $languages[$values->{$this->field_alias}]->name : ''; + } +} diff --git a/sites/all/modules/views/modules/locale/views_handler_field_locale_link_edit.inc b/sites/all/modules/views/modules/locale/views_handler_field_locale_link_edit.inc new file mode 100644 index 0000000000000000000000000000000000000000..62d3c3b97421fa14f076e4cb36c6a887f07f3d83 --- /dev/null +++ b/sites/all/modules/views/modules/locale/views_handler_field_locale_link_edit.inc @@ -0,0 +1,53 @@ +<?php +// $Id: views_handler_field_locale_link_edit.inc,v 1.1.6.2 2010/11/30 20:36:01 merlinofchaos Exp $ + +/** + * Field handler to present a link to edit a translation. + */ +class views_handler_field_locale_link_edit extends views_handler_field { + function construct() { + parent::construct(); + $this->additional_fields['lid'] = 'lid'; + } + + function option_definition() { + $options = parent::option_definition(); + + $options['text'] = array('default' => '', 'translatable' => TRUE); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['text'] = array( + '#type' => 'textfield', + '#title' => t('Text to display'), + '#default_value' => $this->options['text'], + ); + } + + function query() { + $this->ensure_my_table(); + $this->add_additional_fields(); + } + + function access() { + // Ensure user has access to edit translations. + return user_access('translate interface'); + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->aliases['lid']}), $values); + } + + function render_link($data, $values) { + $text = !empty($this->options['text']) ? $this->options['text'] : t('edit'); + + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = 'admin/build/translate/edit/' . $values->{$this->aliases['lid']}; + $this->options['alter']['query'] = drupal_get_destination(); + + return $text; + } +} diff --git a/sites/all/modules/views/modules/locale/views_handler_filter_locale_group.inc b/sites/all/modules/views/modules/locale/views_handler_filter_locale_group.inc new file mode 100644 index 0000000000000000000000000000000000000000..ae0526f8709fc0ec38d4baa8d1f83f9746341d64 --- /dev/null +++ b/sites/all/modules/views/modules/locale/views_handler_filter_locale_group.inc @@ -0,0 +1,18 @@ +<?php +// $Id: views_handler_filter_locale_group.inc,v 1.1 2009/02/20 23:02:09 merlinofchaos Exp $ + +/** + * Filter by locale group. + */ +class views_handler_filter_locale_group extends views_handler_filter_in_operator { + function get_value_options() { + if (!isset($this->value_options)) { + $this->value_title = t('Group'); + $groups = module_invoke_all('locale', 'groups'); + // Sort the list. + asort($groups); + $this->value_options = $groups; + } + } +} + diff --git a/sites/all/modules/views/modules/locale/views_handler_filter_locale_language.inc b/sites/all/modules/views/modules/locale/views_handler_filter_locale_language.inc new file mode 100644 index 0000000000000000000000000000000000000000..1c215055aabcaede3717599bddb379387b0fcd16 --- /dev/null +++ b/sites/all/modules/views/modules/locale/views_handler_filter_locale_language.inc @@ -0,0 +1,20 @@ +<?php +// $Id: views_handler_filter_locale_language.inc,v 1.1.6.1 2011/01/06 00:37:05 dereine Exp $ + +/** + * Filter by language. + */ +class views_handler_filter_locale_language extends views_handler_filter_in_operator { + function get_value_options() { + if (!isset($this->value_options)) { + $this->value_title = t('Language'); + $languages = array( + '***CURRENT_LANGUAGE***' => t("Current user's language"), + '***DEFAULT_LANGUAGE***' => t("Default site language"), + LANGUAGE_NONE => t('No language') + ); + $languages = array_merge($languages, locale_language_list()); + $this->value_options = $languages; + } + } +} diff --git a/sites/all/modules/views/modules/locale/views_handler_filter_locale_version.inc b/sites/all/modules/views/modules/locale/views_handler_filter_locale_version.inc new file mode 100644 index 0000000000000000000000000000000000000000..45cbcad2c4650b738e5bb0f05310b8ba767328d1 --- /dev/null +++ b/sites/all/modules/views/modules/locale/views_handler_filter_locale_version.inc @@ -0,0 +1,22 @@ +<?php +// $Id: views_handler_filter_locale_version.inc,v 1.1.6.2 2009/11/13 12:36:05 dereine Exp $ + +/** + * Filter by version. + */ +class views_handler_filter_locale_version extends views_handler_filter_in_operator { + function get_value_options() { + if (!isset($this->value_options)) { + $this->value_title = t('Version'); + // Enable filtering by the current installed Drupal version. + $versions = array('***CURRENT_VERSION***' => t('Current installed version')); + $result = db_query('SELECT DISTINCT(version) FROM {locales_source} ORDER BY version'); + foreach ($result as $row) { + if (!empty($row->version)) { + $versions[$row->version] = $row->version; + } + } + $this->value_options = $versions; + } + } +} diff --git a/sites/all/modules/views/modules/node.views.inc b/sites/all/modules/views/modules/node.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..8609260db0a8eb0ceed54e834f438f820b97d920 --- /dev/null +++ b/sites/all/modules/views/modules/node.views.inc @@ -0,0 +1,728 @@ +<?php +// $Id: node.views.inc,v 1.97.4.25 2010/12/27 08:02:28 dereine Exp $ +/** + * @file + * Provide views data and handlers for node.module + */ + +/** + * @defgroup views_node_module node.module handlers + * + * Includes the tables 'node', 'node_revision' and 'history'. + * @{ + */ + +/** + * Implements hook_views_data() + */ +function node_views_data() { + // ---------------------------------------------------------------- + // node table -- basic table information. + + // Define the base group of this table. Fields that don't + // have a group defined will go into this field by default. + $data['node']['table']['group'] = t('Node'); + + // Advertise this table as a possible base table + $data['node']['table']['base'] = array( + 'field' => 'nid', + 'title' => t('Node'), + 'help' => t("Nodes are a Drupal site's primary content."), + 'weight' => -10, + 'access query tag' => 'node_access', + ); + + // For other base tables, explain how we join + $data['node']['table']['join'] = array( + // this explains how the 'node' table (named in the line above) + // links toward the node_revision table. + 'node_revision' => array( + 'handler' => 'views_join', // this is actually optional + 'left_table' => 'node_revision', // Because this is a direct link it could be left out. + 'left_field' => 'nid', + 'field' => 'nid', + // also supported: + // 'type' => 'INNER', + // 'extra' => array(array('field' => 'fieldname', 'value' => 'value', 'operator' => '=')) + // Unfortunately, you can't specify other tables here, but you can construct + // alternative joins in the handlers that can do that. + // 'table' => 'the actual name of this table in the database', + ), + ); + + // ---------------------------------------------------------------- + // node table -- fields + + // nid + $data['node']['nid'] = array( + 'title' => t('Nid'), + 'help' => t('The node ID of the node.'), // The help that appears on the UI, + // Information for displaying the nid + 'field' => array( + 'handler' => 'views_handler_field_node', + 'click sortable' => TRUE, + ), + // Information for accepting a nid as an argument + 'argument' => array( + 'handler' => 'views_handler_argument_node_nid', + 'name field' => 'title', // the field to display in the summary. + 'numeric' => TRUE, + 'validate type' => 'nid', + ), + // Information for accepting a nid as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + // Information for sorting on a nid. + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // title + // This definition has more items in it than it needs to as an example. + $data['node']['title'] = array( + 'title' => t('Title'), // The item it appears as on the UI, + 'help' => t('The title of the node.'), // The help that appears on the UI, + // Information for displaying a title as a field + 'field' => array( + 'field' => 'title', // the real field. This could be left out since it is the same. + 'group' => t('Node'), // The group it appears in on the UI. Could be left out. + 'handler' => 'views_handler_field_node', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + // Information for accepting a title as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // created field + $data['node']['created'] = array( + 'title' => t('Post date'), // The item it appears as on the UI, + 'help' => t('The date the node was posted.'), // The help that appears on the UI, + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + ); + + // changed field + $data['node']['changed'] = array( + 'title' => t('Updated date'), // The item it appears as on the UI, + 'help' => t('The date the node was last updated.'), // The help that appears on the UI, + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + ); + + // Node type + $data['node']['type'] = array( + 'title' => t('Type'), // The item it appears as on the UI, + 'help' => t('The type of a node (for example, "blog entry", "forum post", "story", etc).'), // The help that appears on the UI, + 'field' => array( + 'handler' => 'views_handler_field_node_type', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_node_type', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_node_type', + ), + ); + + // published status + $data['node']['status'] = array( + 'title' => t('Published'), + 'help' => t('Whether or not the node is published.'), + 'field' => array( + 'handler' => 'views_handler_field_boolean', + 'click sortable' => TRUE, + 'output formats' => array( + 'published-notpublished' => array(t('Published'), t('Not published')), + ), + ), + 'filter' => array( + 'handler' => 'views_handler_filter_boolean_operator', + 'label' => t('Published'), + 'type' => 'yes-no', + 'use equal' => TRUE, // Use status = 1 instead of status <> 0 in WHERE statment + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // published status + extra + $data['node']['status_extra'] = array( + 'title' => t('Published or admin'), + 'help' => t('Filters out unpublished nodes if the current user cannot view them.'), + 'filter' => array( + 'field' => 'status', + 'handler' => 'views_handler_filter_node_status', + 'label' => t('Published or admin'), + ), + ); + + // promote status + $data['node']['promote'] = array( + 'title' => t('Promoted to front page'), + 'help' => t('Whether or not the node is promoted to the front page.'), + 'field' => array( + 'handler' => 'views_handler_field_boolean', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_boolean_operator', + 'label' => t('Promoted to front page'), + 'type' => 'yes-no', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // sticky + $data['node']['sticky'] = array( + 'title' => t('Sticky'), // The item it appears as on the UI, + 'help' => t('Whether or not the node is sticky.'), // The help that appears on the UI, + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_boolean', + 'click sortable' => TRUE, + 'output formats' => array( + 'sticky' => array('', t('Sticky')), + ), + ), + 'filter' => array( + 'handler' => 'views_handler_filter_boolean_operator', + 'label' => t('Sticky'), + 'type' => 'yes-no', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + 'help' => t('Whether or not the node is sticky. To list sticky nodes first, set this to descending.'), + ), + ); + + // links to operate on the node + + $data['node']['view_node'] = array( + 'field' => array( + 'title' => t('Link'), + 'help' => t('Provide a simple link to the node.'), + 'handler' => 'views_handler_field_node_link', + ), + ); + + $data['node']['edit_node'] = array( + 'field' => array( + 'title' => t('Edit link'), + 'help' => t('Provide a simple link to edit the node.'), + 'handler' => 'views_handler_field_node_link_edit', + ), + ); + + $data['node']['delete_node'] = array( + 'field' => array( + 'title' => t('Delete link'), + 'help' => t('Provide a simple link to delete the node.'), + 'handler' => 'views_handler_field_node_link_delete', + ), + ); + + $data['node']['path'] = array( + 'field' => array( + 'title' => t('Path'), + 'help' => t('The aliased path to this node.'), + 'handler' => 'views_handler_field_node_path', + ), + ); + + + // Bogus fields for aliasing purposes. + + $data['node']['created_fulldate'] = array( + 'title' => t('Created date'), + 'help' => t('In the form of CCYYMMDD.'), + 'argument' => array( + 'field' => 'created', + 'handler' => 'views_handler_argument_node_created_fulldate', + ), + ); + + $data['node']['created_year_month'] = array( + 'title' => t('Created year + month'), + 'help' => t('In the form of YYYYMM.'), + 'argument' => array( + 'field' => 'created', + 'handler' => 'views_handler_argument_node_created_year_month', + ), + ); + + $data['node']['created_year'] = array( + 'title' => t('Created year'), + 'help' => t('In the form of YYYY.'), + 'argument' => array( + 'field' => 'created', + 'handler' => 'views_handler_argument_node_created_year', + ), + ); + + $data['node']['created_month'] = array( + 'title' => t('Created month'), + 'help' => t('In the form of MM (01 - 12).'), + 'argument' => array( + 'field' => 'created', + 'handler' => 'views_handler_argument_node_created_month', + ), + ); + + $data['node']['created_day'] = array( + 'title' => t('Created day'), + 'help' => t('In the form of DD (01 - 31).'), + 'argument' => array( + 'field' => 'created', + 'handler' => 'views_handler_argument_node_created_day', + ), + ); + + $data['node']['created_week'] = array( + 'title' => t('Created week'), + 'help' => t('In the form of WW (01 - 53).'), + 'argument' => array( + 'field' => 'created', + 'handler' => 'views_handler_argument_node_created_week', + ), + ); + + $data['node']['changed_fulldate'] = array( + 'title' => t('Updated date'), + 'help' => t('In the form of CCYYMMDD.'), + 'argument' => array( + 'field' => 'changed', + 'handler' => 'views_handler_argument_node_created_fulldate', + ), + ); + + $data['node']['changed_year_month'] = array( + 'title' => t('Updated year + month'), + 'help' => t('In the form of YYYYMM.'), + 'argument' => array( + 'field' => 'changed', + 'handler' => 'views_handler_argument_node_created_year_month', + ), + ); + + $data['node']['changed_year'] = array( + 'title' => t('Updated year'), + 'help' => t('In the form of YYYY.'), + 'argument' => array( + 'field' => 'changed', + 'handler' => 'views_handler_argument_node_created_year', + ), + ); + + $data['node']['changed_month'] = array( + 'title' => t('Updated month'), + 'help' => t('In the form of MM (01 - 12).'), + 'argument' => array( + 'field' => 'changed', + 'handler' => 'views_handler_argument_node_created_month', + ), + ); + + $data['node']['changed_day'] = array( + 'title' => t('Updated day'), + 'help' => t('In the form of DD (01 - 31).'), + 'argument' => array( + 'field' => 'changed', + 'handler' => 'views_handler_argument_node_created_day', + ), + ); + + $data['node']['changed_week'] = array( + 'title' => t('Updated week'), + 'help' => t('In the form of WW (01 - 53).'), + 'argument' => array( + 'field' => 'changed', + 'handler' => 'views_handler_argument_node_created_week', + ), + ); + + // uid field + $data['node']['uid'] = array( + 'title' => t('Author'), + 'help' => t('Relate a node to the user who created it.'), + 'relationship' => array( + 'handler' => 'views_handler_relationship', + 'base' => 'users', + 'field' => 'uid', + 'label' => t('user'), + ), + ); + + // ---------------------------------------------------------------------- + // Node revision table + + // Define the base group of this table. Fields that don't + // have a group defined will go into this field by default. + $data['node_revision']['table']['group'] = t('Node revision'); + + // Advertise this table as a possible base table + $data['node_revision']['table']['base'] = array( + 'field' => 'vid', + 'title' => t('Node revision'), + 'help' => t('Node revision are a history of changes to nodes.'), + ); + + // For other base tables, explain how we join + $data['node_revision']['table']['join'] = array( + // Directly links to node table. + 'node' => array( + 'left_field' => 'vid', + 'field' => 'vid', + ), + ); + + // uid field for node revision + $data['node_revision']['uid'] = array( + 'title' => t('User'), + 'help' => t('Relate a node revision to the user who created the revision.'), + 'relationship' => array( + 'handler' => 'views_handler_relationship', + 'base' => 'users', + 'base field' => 'uid', + 'label' => t('revision user'), + ), + ); + + // nid + $data['node_revision']['vid'] = array( + 'title' => t('Vid'), + 'help' => t('The revision ID of the node revision.'), // The help that appears on the UI, + // Information for displaying the nid + 'field' => array( + 'click sortable' => TRUE, + ), + // Information for accepting a nid as an argument + 'argument' => array( + 'handler' => 'views_handler_argument_node_vid', + 'click sortable' => TRUE, + 'numeric' => TRUE, + ), + // Information for accepting a nid as a filter + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + // Information for sorting on a nid. + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'relationship' => array( + 'handler' => 'views_handler_relationship', + 'base' => 'node', + 'base field' => 'nid', + 'title' => t('Node'), + 'label' => t('Get the actual node from a node revision.'), + ), + ); + + // title + $data['node_revision']['title'] = array( + 'title' => t('Title'), // The item it appears as on the UI, + 'help' => t('The title of the node.'), // The help that appears on the UI, + // Information for displaying a title as a field + 'field' => array( + 'field' => 'title', // the real field + 'handler' => 'views_handler_field_node_revision', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // log field + $data['node_revision']['log'] = array( + 'title' => t('Log message'), // The item it appears as on the UI, + 'help' => t('The log message entered when the revision was created.'), // The help that appears on the UI, + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_xss', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + // revision timestamp + // changed field + $data['node_revision']['timestamp'] = array( + 'title' => t('Created date'), // The item it appears as on the UI, + 'help' => t('The date the node revision was created.'), // The help that appears on the UI, + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + ); + + $data['node_revision']['revert_revision'] = array( + 'field' => array( + 'title' => t('Revert link'), + 'help' => t('Provide a simple link to revert to the revision.'), + 'handler' => 'views_handler_field_node_revision_link_revert', + ), + ); + + $data['node_revision']['delete_revision'] = array( + 'field' => array( + 'title' => t('Delete link'), + 'help' => t('Provide a simple link to delete the node revision.'), + 'handler' => 'views_handler_field_node_revision_link_delete', + ), + ); + + // ---------------------------------------------------------------------- + // Node access table + + // Define the base group of this table. Fields that don't + // have a group defined will go into this field by default. + $data['node_access']['table']['group'] = t('Node access'); + + // For other base tables, explain how we join + $data['node_access']['table']['join'] = array( + // Directly links to node table. + 'node' => array( + 'left_field' => 'nid', + 'field' => 'nid', + ), + ); + // nid field + $data['node_access']['nid'] = array( + 'title' => t('Access'), + 'help' => t('Filter by access.'), + 'filter' => array( + 'handler' => 'views_handler_filter_node_access', + 'help' => t('Filter for nodes by view access. <strong>Not necessary if you are using node as your base table.</strong>'), + ), + ); + + // ---------------------------------------------------------------------- + // History table + + // We're actually defining a specific instance of the table, so let's + // alias it so that we can later add the real table for other purposes if we + // need it. + $data['history']['table']['group'] = t('Node'); + + // Explain how this table joins to others. + $data['history']['table']['join'] = array( + // Directly links to node table. + 'node' => array( + 'table' => 'history', + 'left_field' => 'nid', + 'field' => 'nid', + 'extra' => array( + array('field' => 'uid', 'value' => '***CURRENT_USER***', 'numeric' => TRUE), + ), + ), + ); + + $data['history']['timestamp'] = array( + 'title' => t('Has new content'), + 'field' => array( + 'handler' => 'views_handler_field_history_user_timestamp', + 'help' => t('Show a marker if the node has new or updated content.'), + ), + 'filter' => array( + 'help' => t('Show only nodes that have new content.'), + 'handler' => 'views_handler_filter_history_user_timestamp', + ), + ); + return $data; +} + +/** + * Implements hook_views_plugins + */ +function node_views_plugins() { + return array( + 'module' => 'views', // This just tells our themes are elsewhere. + 'row' => array( + 'node' => array( + 'title' => t('Node'), + 'help' => t('Display the node with standard node view.'), + 'handler' => 'views_plugin_row_node_view', + 'path' => drupal_get_path('module', 'views') . '/modules/node', // not necessary for most modules + 'theme' => 'views_view_row_node', + 'base' => array('node'), // only works with 'node' as base. + 'uses options' => TRUE, + 'type' => 'normal', + 'help topic' => 'style-node', + ), + 'node_rss' => array( + 'title' => t('Node'), + 'help' => t('Display the node with standard node view.'), + 'handler' => 'views_plugin_row_node_rss', + 'path' => drupal_get_path('module', 'views') . '/modules/node', // not necessary for most modules + 'theme' => 'views_view_row_rss', + 'base' => array('node'), // only works with 'node' as base. + 'uses options' => TRUE, + 'type' => 'feed', + 'help topic' => 'style-node-rss', + ), + ), + 'argument validator' => array( + 'node' => array( + 'title' => t('Node'), + 'handler' => 'views_plugin_argument_validate_node', + ), + ), + 'argument default' => array( + 'node' => array( + 'title' => t('Node ID from URL'), + 'handler' => 'views_plugin_argument_default_node' + ), + ), + ); +} + +/** + * Template helper for theme_views_view_row_node + */ +function template_preprocess_views_view_row_node(&$vars) { + $options = $vars['options']; + + // Make sure the variables are defined. + $vars['node'] = ''; + $vars['comments'] = ''; + + if (!empty($vars['row']->{$vars['field_alias']})) { + $nid = $vars['row']->{$vars['field_alias']}; + } + if (!is_numeric($nid)) { + return; + } + + $row_plugin = $vars['view']->style_plugin->row_plugin; + $node = $row_plugin->nodes[$nid]; + + if (empty($node)) { + return; + } + + $node->view = $vars['view']; + // Detect which build module should be used. + $node->build_mode = (!empty($options['build_mode'])) ? $options['build_mode'] : 'full'; + $content = node_view_multiple(array($node->nid => $node), $node->build_mode); + $content = $content['nodes'][$node->nid]; + if (!$options['links']) { + unset($content['links']); + } + + if (!empty($options['comments']) && user_access('access comments') && $node->comment) { + $vars['comments'] = drupal_render(comment_node_page_additions($node)); + } + + $vars['node'] = drupal_render($content); + +} + +/** + * Implements hook_views_query_substitutions(). + */ +function node_views_query_substitutions() { + return array( + '***ADMINISTER_NODES***' => intval(user_access('administer nodes')), + '***VIEW_OWN_UNPUBLISHED_NODES***' => intval(user_access('view own unpublished content')), + ); +} + +/** + * Implements hook_views_analyze(). + */ +function node_views_analyze($view) { + $ret = array(); + // Check for something other than the default display: + if ($view->base_table == 'node') { + foreach ($view->display as $id => $display) { + if (!$display->handler->is_defaulted('access') || !$display->handler->is_defaulted('filters')) { + // check for no access control + $access = $display->handler->get_option('access'); + if (empty($access['type']) || $access['type'] == 'none') { + $select = db_select('role', 'r'); + $select->innerJoin('role_permission', 'p', 'r.rid = p.rid'); + $result = $select->fields('r', array('name')) + ->fields('p', array('permission')) + ->condition('r.name', array('anonymous user', 'authenticated user'), 'IN') + ->condition('p.permission', 'access content') + ->execute(); + + foreach ($result as $role) { + $role->safe = TRUE; + $roles[$role->name] = $role; + } + if (!($roles['anonymous user']->safe && $roles['authenticated user']->safe)) { + $ret[] = views_ui_analysis(t('Some roles lack permission to access content, but display %display has no access control.', array('%display' => $display->display_title)), 'warning'); + } + $filters = $display->handler->get_option('filters'); + foreach ($filters as $filter) { + if ($filter['table'] == 'node' && ($filter['field'] == 'status' || $filter['field'] == 'status_extra')) { + continue 2; + } + } + $ret[] = views_ui_analysis(t('Display %display has no access control but does not contain a filter for published nodes.', array('%display' => $display->display_title)), 'warning'); + } + } + } + } + foreach ($view->display as $id => $display) { + if ($display->display_plugin == 'page') { + if ($display->handler->get_option('path') == 'node/%') { + $ret[] = views_ui_analysis(t('Display %display has set node/% as path. This will not produce what you want. If you want to have multiple versions of the node view, use panels.', array('%display' => $display->display_title)), 'warning'); + } + } + } + + return $ret; +} + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/node.views_convert.inc b/sites/all/modules/views/modules/node.views_convert.inc new file mode 100644 index 0000000000000000000000000000000000000000..a31198fda3eac8137c04e8ce758656b6fa1cf8af --- /dev/null +++ b/sites/all/modules/views/modules/node.views_convert.inc @@ -0,0 +1,182 @@ +<?php +//$Id: node.views_convert.inc,v 1.7.4.2 2010/02/06 16:29:52 dereine Exp $ + +/** + * @file + * Field conversion for fields handled by this module. + */ + +/** + * Implements 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 node_views_convert($display, $type, &$view, $field, $id = NULL) { + switch ($type) { + case 'field': + switch ($field['tablename']) { + case 'node': + switch ($field['field']) { + case 'title': + if ($field['options'] != 'no_link') { + $view->set_item_option($display, 'field', $id, 'link_to_node', TRUE); + } + break; + case 'created': + case 'changed': + $handlers = array( + 'views_handler_field_date_small' => 'small', + 'views_handler_field_date' => 'medium', + 'views_handler_field_date_large' => 'large', + 'views_handler_field_date_custom' => 'custom', + 'views_handler_field_since' => 'time ago', + ); + $view->set_item_option($display, 'field', $id, 'date_format', $handlers[$field['handler']]); + if (!empty($field['options'])) { + $view->set_item_option($display, 'field', $id, 'custom_date_format', $field['options']); + } + break; + case 'body': + $field['field'] = $field['handler'] == 'views_handler_field_teaser' ? 'teaser' : $field['field']; + $view->set_item_option($display, 'field', $id, 'field', $field['field']); + $view->set_item_option($display, 'field', $id, 'table', 'node_revisions'); + break; + case 'link': + case 'edit': + case 'delete': + case 'view': + $field['field'] = $field['field'] == 'link' ? 'view_node' : "$field[field]_node"; + $view->set_item_option($display, 'field', $id, 'field', $field['field']); + if (!empty($field['options'])) { + $view->set_item_option($display, 'field', $id, 'text', $field['options']); + } + break; + } + break; + } + break; + case 'filter': + switch ($field['tablename']) { + case 'node': + switch ($field['field']) { + case 'type': + $operators = array('OR' => 'IN', 'NOR' => 'NOT IN'); + $view->set_item_option($display, 'filter', $id, 'operator', $operators[$field['operator']]); + break; + case 'anon': + $item = $view->get_item($display, 'filter', $id); + $item['value'] = array(0); + $item['table'] = 'users'; + $item['field'] = 'uid'; + $view->set_item($display, 'filter', $id, $item); + break; + case 'currentuid': + $operators = array('=' => TRUE, '!=' => FALSE); + $item = $view->get_item($display, 'filter', $id); + $item['value'] = $operators[$field['operator']]; + $item['table'] = 'users'; + $item['field'] = 'uid_current'; + $view->set_item($display, 'filter', $id, $item); + break; + case 'currentuidtouched': + $view->set_item_option($display, 'filter', $id, 'value', '='); + $view->set_item_option($display, 'filter', $id, 'field', 'uid_touch'); + break; + case 'distinct': + $view->display_handler->set_option('distinct', $field['operator'] == '=' && $field['value'] == 'distinct'); + $view->set_item($display, 'filter', $id, NULL); + break; + case 'title': + $item = $view->get_item($display, 'filter', $id); + $item['operator'] = $field['operator']; + $item['case'] = FALSE; + $view->set_item($display, 'filter', $id, $item); + break; + case 'created': + case 'changed': + $item = $view->get_item($display, 'filter', $id); + $item['operator'] = $field['operator']; + $item['value'] = array( + 'type' => $field['value'] == 'now' ? 'offset' : 'date', + 'value' => $field['value'], + ); + if (!empty($field['options'])) { + $item['value']['value'] = intval($field['options']) .' seconds'; + } + $view->set_item($display, 'filter', $id, $item); + break; + case 'body': + $item = $view->get_item($display, 'filter', $id); + $item['operator'] = $field['operator']; + $item['case'] = FALSE; + $item['table'] = 'node_revisions'; + $view->set_item($display, 'filter', $id, $item); + break; + } + break; + case 'history': + switch ($field['field']) { + case 'timestamp': + $view->set_item_option($display, 'filter', $id, 'table', 'history'); + break; + } + break; + } + break; + case 'sort': + switch ($field['tablename']) { + case 'node': + switch ($field['field']) { + case 'created': + case 'changed': + $field['options'] = $field['options'] == 'normal' ? 'second' : $field['options']; + $view->set_item_option($display, 'sort', $id, 'granularity', $field['options']); + break; + case 'random': + $view->set_item_option($display, 'sort', $id, 'table', 'views'); + break; + } + break; + } + break; + case 'argument': + $options = $field['argoptions']; + switch ($field['type']) { + case 'nodetype': + $view->add_item($display, 'argument', 'node', 'type', $options, $field['id']); + break; + case 'nodeletter': + if (!empty($field['options'])) { + $options['glossary'] = TRUE; + $options['limit'] = $field['options']; + } + $options['case'] = 'upper'; + $view->add_item($display, 'argument', 'node', 'title', $options, $field['id']); + break; + case 'year': + $view->add_item($display, 'argument', 'node', 'created_year', $options, $field['id']); + break; + case 'month': + $view->add_item($display, 'argument', 'node', 'created_month', $options, $field['id']); + break; + case 'week': + $view->add_item($display, 'argument', 'node', 'created_week', $options, $field['id']); + break; + case 'monthyear': + $view->add_item($display, 'argument', 'node', 'created_year_month', $options, $field['id']); + break; + case 'fulldate': + $view->add_item($display, 'argument', 'node', 'created_fulldate', $options, $field['id']); + break; + case 'nid': + if (!empty($field['options'])) { + $options['not'] = TRUE; + } + $view->add_item($display, 'argument', 'node', 'nid', $options, $field['id']); + break; + } + break; + } +} diff --git a/sites/all/modules/views/modules/node.views_default.inc b/sites/all/modules/views/modules/node.views_default.inc new file mode 100644 index 0000000000000000000000000000000000000000..4c8ae67017401fda8e8323fd094effba5e0312be --- /dev/null +++ b/sites/all/modules/views/modules/node.views_default.inc @@ -0,0 +1,380 @@ +<?php +// $Id: node.views_default.inc,v 1.11.6.5 2011/01/05 23:14:39 dereine Exp $ +/** + * @file + * Contains default views on behalf of the node module. + */ + +/** + * Implements hook_views_default_views(). + */ +function node_views_default_views() { + $view = new view; + $view->name = 'frontpage'; + $view->description = 'Emulates the default Drupal front page; you may set the default home page path to this view to make it your front page.'; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->api_version = 2; + $view->version = 7; + $view->disabled = TRUE; /* Edit this to true to make a default view disabled initially */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->override_option('sorts', array( + 'sticky' => array( + 'id' => 'sticky', + 'table' => 'node', + 'field' => 'sticky', + 'order' => 'DESC', + ), + 'created' => array( + 'id' => 'created', + 'table' => 'node', + 'field' => 'created', + 'order' => 'DESC', + 'relationship' => 'none', + 'granularity' => 'second', + ), + )); + $handler->override_option('filters', array( + 'promote' => array( + 'id' => 'promote', + 'table' => 'node', + 'field' => 'promote', + 'operator' => '=', + 'value' => '1', + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + ), + 'status' => array( + 'id' => 'status', + 'table' => 'node', + 'field' => 'status', + 'operator' => '=', + 'value' => '1', + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + ), + )); + $handler->override_option('access', array( + 'type' => 'none', + 'role' => array(), + 'perm' => '', + )); + $handler->override_option('header_format', '1'); + $handler->override_option('footer_format', '1'); + $handler->override_option('empty_format', '1'); + $handler->override_option('use_pager', '1'); + $handler->override_option('row_plugin', 'node'); + $handler->override_option('row_options', array( + 'teaser' => 1, + 'links' => 1, + )); + $handler = $view->new_display('page', 'Page', 'page'); + $handler->override_option('path', 'frontpage'); + $handler->override_option('menu', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $handler->override_option('tab_options', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $handler = $view->new_display('feed', 'Feed', 'feed'); + $handler->override_option('sitename_title', '1'); + $handler->override_option('title', 'Front page feed'); + $handler->override_option('style_options', array( + 'description' => '', + )); + $handler->override_option('row_plugin', 'node_rss'); + $handler->override_option('row_options', array( + 'item_length' => 'default', + )); + $handler->override_option('path', 'rss.xml'); + $handler->override_option('menu', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $handler->override_option('tab_options', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $handler->override_option('displays', array( + 'default' => 'default', + 'page' => 'page', + )); + $views[$view->name] = $view; + + $view = new view; + $view->name = 'glossary'; + $view->description = 'A list of all content, by letter.'; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->api_version = 2; + $view->version = 7; + $view->disabled = TRUE; /* Edit this to true to make a default view disabled initially */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->override_option('fields', array( + 'title' => array( + 'label' => 'Title', + 'link_to_node' => 1, + 'exclude' => 0, + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'relationship' => 'none', + ), + 'name' => array( + 'label' => 'Author', + 'link_to_user' => 1, + 'exclude' => 0, + 'id' => 'name', + 'table' => 'users', + 'field' => 'name', + 'relationship' => 'none', + ), + 'changed' => array( + 'label' => 'Last update', + 'date_format' => 'large', + 'custom_date_format' => '', + 'exclude' => 0, + 'id' => 'changed', + 'table' => 'node', + 'field' => 'changed', + 'relationship' => 'none', + ), + )); + $handler->override_option('arguments', array( + 'title' => array( + 'default_action' => 'default', + 'style_plugin' => 'default_summary', + 'style_options' => array(), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => '', + 'default_argument_type' => 'fixed', + 'default_argument' => '', + 'validate_type' => 'none', + 'validate_fail' => 'not found', + 'glossary' => 1, + 'limit' => '1', + 'case' => 'upper', + 'path_case' => 'lower', + 'transform_dash' => 0, + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'relationship' => 'none', + 'default_argument_user' => 0, + 'default_argument_fixed' => 'a', + 'default_argument_php' => '', + 'validate_argument_vocabulary' => array(), + 'validate_argument_type' => 'tid', + 'validate_argument_php' => '', + ), + )); + $handler->override_option('access', array( + 'type' => 'none', + 'role' => array(), + 'perm' => '', + )); + $handler->override_option('use_ajax', '1'); + $handler->override_option('items_per_page', 36); + $handler->override_option('use_pager', '1'); + $handler->override_option('style_plugin', 'table'); + $handler->override_option('style_options', array( + 'grouping' => '', + 'override' => 1, + 'sticky' => 0, + 'order' => 'asc', + 'columns' => array( + 'title' => 'title', + 'name' => 'name', + 'changed' => 'changed', + ), + 'info' => array( + 'title' => array( + 'sortable' => 1, + 'separator' => '', + ), + 'name' => array( + 'sortable' => 1, + 'separator' => '', + ), + 'changed' => array( + 'sortable' => 1, + 'separator' => '', + ), + ), + 'default' => 'title', + )); + $handler = $view->new_display('page', 'Page', 'page'); + $handler->override_option('path', 'glossary'); + $handler->override_option('menu', array( + 'type' => 'normal', + 'title' => 'Glossary', + 'weight' => '0', + )); + $handler->override_option('tab_options', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $handler = $view->new_display('attachment', 'Attachment', 'attachment'); + $handler->override_option('arguments', array( + 'title' => array( + 'default_action' => 'summary asc', + 'style_plugin' => 'unformatted_summary', + 'style_options' => array( + 'count' => 1, + 'override' => 0, + 'items_per_page' => '25', + 'inline' => 1, + 'separator' => ' | ', + ), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => '', + 'default_argument_type' => 'fixed', + 'default_argument' => '', + 'validate_type' => 'none', + 'validate_fail' => 'not found', + 'glossary' => 1, + 'limit' => '1', + 'case' => 'upper', + 'path_case' => 'lower', + 'transform_dash' => 0, + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'relationship' => 'none', + 'default_argument_user' => 0, + 'default_argument_fixed' => 'a', + 'validate_argument_vocabulary' => array(), + 'validate_argument_php' => '', + ), + )); + $handler->override_option('inherit_arguments', 0); + $handler->override_option('displays', array( + 'default' => 'default', + 'page' => 'page', + )); + $views[$view->name] = $view; + + $view = new view; + $view->name = 'archive'; + $view->description = 'Display a list of months that link to content for that month.'; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->api_version = 2; + $view->version = 7; + $view->disabled = TRUE; /* Edit this to true to make a default view disabled initially */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->override_option('title', 'Monthly archive'); + $handler->override_option('sorts', array( + 'created' => array( + 'id' => 'created', + 'table' => 'node', + 'field' => 'created', + 'order' => 'DESC', + 'granularity' => 'second', + 'relationship' => 'none', + ), + )); + $handler->override_option('arguments', array( + 'created_year_month' => array( + 'id' => 'created_year_month', + 'table' => 'node', + 'field' => 'created_year_month', + 'default_action' => 'summary desc', + 'style_plugin' => 'default_summary', + 'style_options' => array( + 'count' => 1, + 'override' => 1, + 'items_per_page' => '30', + ), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => '%1', + 'relationship' => 'none', + 'validate_type' => 'none', + 'validate_fail' => 'not found', + 'default_argument_type' => 'fixed', + ), + )); + $handler->override_option('filters', array( + 'status' => array( + 'id' => 'status', + 'table' => 'node', + 'field' => 'status', + 'operator' => '=', + 'value' => 1, + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'relationship' => 'none', + ), + )); + $handler->override_option('access', array( + 'type' => 'none', + 'role' => array(), + 'perm' => '', + )); + $handler->override_option('use_pager', '1'); + $handler->override_option('row_plugin', 'node'); + $handler->override_option('row_options', array( + 'teaser' => TRUE, + 'links' => TRUE, + )); + $handler = $view->new_display('page', 'Page', 'page'); + $handler->override_option('path', 'archive'); + $handler->override_option('menu', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $handler->override_option('tab_options', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $handler = $view->new_display('block', 'Block', 'block'); + $handler->override_option('arguments', array( + 'created_year_month' => array( + 'id' => 'created_year_month', + 'table' => 'node', + 'field' => 'created_year_month', + 'default_action' => 'summary asc', + 'style_plugin' => 'default_summary', + 'style_options' => array( + 'count' => 1, + 'override' => 0, + 'items_per_page' => '30', + ), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => '%1', + 'relationship' => 'none', + 'validate_type' => 'none', + 'validate_fail' => 'not found', + 'default_argument_type' => 'fixed', + ), + )); + $handler->override_option('block_description', 'Archive list'); + $views[$view->name] = $view; + + return $views; +} diff --git a/sites/all/modules/views/modules/node/views_handler_argument_dates_various.inc b/sites/all/modules/views/modules/node/views_handler_argument_dates_various.inc new file mode 100644 index 0000000000000000000000000000000000000000..33a7e738791c0306a47fd495fa8ea2203b486f49 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_argument_dates_various.inc @@ -0,0 +1,170 @@ +<?php +// $Id: views_handler_argument_dates_various.inc,v 1.4.6.3 2010/09/19 08:18:11 dereine Exp $ +/** + * Argument handler for a full date (CCYYMMDD) + */ +class views_handler_argument_node_created_fulldate extends views_handler_argument_date { + /** + * Constructor implementation + */ + function construct() { + parent::construct(); + $this->format = 'F j, Y'; + $this->arg_format = 'Ymd'; + $this->formula = views_date_sql_format($this->arg_format, "***table***.$this->real_field"); + } + + /** + * Provide a link to the next level of the view + */ + function summary_name($data) { + $created = $data->{$this->name_alias}; + return format_date(strtotime($created . " 00:00:00 UTC"), 'custom', $this->format, 'UTC'); + } + + /** + * Provide a link to the next level of the view + */ + function title() { + return format_date(strtotime($this->argument . " 00:00:00 UTC"), 'custom', $this->format, 'UTC'); + } +} + +/** + * Argument handler for a year (CCYY) + */ +class views_handler_argument_node_created_year extends views_handler_argument_date { + /** + * Constructor implementation + */ + function construct() { + parent::construct(); + $this->arg_format = 'Y'; + $this->formula = views_date_sql_extract('YEAR', "***table***.$this->real_field"); + } +} + +/** + * Argument handler for a year plus month (CCYYMM) + */ +class views_handler_argument_node_created_year_month extends views_handler_argument_date { + /** + * Constructor implementation + */ + function construct() { + parent::construct(); + $this->format = 'F Y'; + $this->arg_format = 'Ym'; + $this->formula = views_date_sql_format($this->arg_format, "***table***.$this->real_field"); + } + + /** + * Provide a link to the next level of the view + */ + function summary_name($data) { + $created = $data->{$this->name_alias}; + return format_date(strtotime($created . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC'); + } + + /** + * Provide a link to the next level of the view + */ + function title() { + return format_date(strtotime($this->argument . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC'); + } +} + +/** + * Argument handler for a month (MM) + */ +class views_handler_argument_node_created_month extends views_handler_argument_date { + /** + * Constructor implementation + */ + function construct() { + parent::construct(); + $this->formula = views_date_sql_extract('MONTH', "***table***.$this->real_field"); + $this->format = 'F'; + $this->arg_format = 'm'; + } + + /** + * Provide a link to the next level of the view + */ + function summary_name($data) { + $month = str_pad($data->{$this->name_alias}, 2, '0', STR_PAD_LEFT); + return format_date(strtotime("2005" . $month . "15" . " 00:00:00 UTC" ), 'custom', $this->format, 'UTC'); + } + + /** + * Provide a link to the next level of the view + */ + function title() { + $month = str_pad($this->argument, 2, '0', STR_PAD_LEFT); + return format_date(strtotime("2005" . $month . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC'); + } + + function summary_argument($data) { + // Make sure the argument contains leading zeroes. + return str_pad($data->{$this->base_alias}, 2, '0', STR_PAD_LEFT); + } +} + +/** + * Argument handler for a day (DD) + */ +class views_handler_argument_node_created_day extends views_handler_argument_date { + /** + * Constructor implementation + */ + function construct() { + parent::construct(); + $this->formula = views_date_sql_extract('DAY', "***table***.$this->real_field"); + $this->format = 'j'; + $this->arg_format = 'd'; + } + + /** + * Provide a link to the next level of the view + */ + function summary_name($data) { + $day = str_pad($data->{$this->name_alias}, 2, '0', STR_PAD_LEFT); + // strtotime respects server timezone, so we need to set the time fixed as utc time + return format_date(strtotime("2005" . "05" . $day . " 00:00:00 UTC"), 'custom', $this->format, 'UTC'); + } + + /** + * Provide a link to the next level of the view + */ + function title() { + $day = str_pad($this->argument, 2, '0', STR_PAD_LEFT); + return format_date(strtotime("2005" . "05" . $day . " 00:00:00 UTC"), 'custom', $this->format, 'UTC'); + } + + function summary_argument($data) { + // Make sure the argument contains leading zeroes. + return str_pad($data->{$this->base_alias}, 2, '0', STR_PAD_LEFT); + } +} + +/** + * Argument handler for a week. + */ +class views_handler_argument_node_created_week extends views_handler_argument_date { + /** + * Constructor implementation + */ + function construct() { + parent::construct(); + $this->arg_format = 'w'; + $this->formula = views_date_sql_extract('WEEK', "***table***.$this->real_field"); + } + + /** + * Provide a link to the next level of the view + */ + function summary_name($data) { + $created = $data->{$this->name_alias}; + return t('Week @week', array('@week' => $created)); + } +} diff --git a/sites/all/modules/views/modules/node/views_handler_argument_node_language.inc b/sites/all/modules/views/modules/node/views_handler_argument_node_language.inc new file mode 100644 index 0000000000000000000000000000000000000000..fad8680c32bd41cdb3d0ac2ceaaef75ebb6466a6 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_argument_node_language.inc @@ -0,0 +1,32 @@ +<?php +// $Id: views_handler_argument_node_language.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos Exp $ +/** + * Argument handler to accept a language. + */ +class views_handler_argument_node_language extends views_handler_argument { + function construct() { + parent::construct('language'); + } + + /** + * Override the behavior of summary_name(). Get the user friendly version + * of the language. + */ + function summary_name($data) { + return $this->node_language($data->{$this->name_alias}); + } + + /** + * Override the behavior of title(). Get the user friendly version of the + * node type. + */ + function title() { + return $this->node_language($this->argument); + } + + function node_language($langcode) { + $languages = locale_language_list(); + return isset($languages[$langcode]) ? $languages[$langcode] : t('Unknown language'); + } +} + diff --git a/sites/all/modules/views/modules/node/views_handler_argument_node_nid.inc b/sites/all/modules/views/modules/node/views_handler_argument_node_nid.inc new file mode 100644 index 0000000000000000000000000000000000000000..4b51049083de23d605d69b8356f4bb7e8b302cc8 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_argument_node_nid.inc @@ -0,0 +1,25 @@ +<?php +// $Id: views_handler_argument_node_nid.inc,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ +/** + * @file + * Provide node nid argument handler. + */ + +/** + * Argument handler to accept a node id. + */ +class views_handler_argument_node_nid extends views_handler_argument_numeric { + /** + * Override the behavior of title(). Get the title of the node. + */ + function title_query() { + $titles = array(); + + $result = db_query("SELECT n.title FROM {node} n WHERE n.nid IN (:nids)", array(':nids' => $this->value)); + foreach ($result as $term) { + $titles[] = check_plain($term->title); + } + return $titles; + } +} + diff --git a/sites/all/modules/views/modules/node/views_handler_argument_node_type.inc b/sites/all/modules/views/modules/node/views_handler_argument_node_type.inc new file mode 100644 index 0000000000000000000000000000000000000000..04aa7e0dcb1c2ff48f6126bfbf72c487fb05b67e --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_argument_node_type.inc @@ -0,0 +1,34 @@ +<?php +// $Id: views_handler_argument_node_type.inc,v 1.2.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ +/** + * Argument handler to accept a node type. + */ +class views_handler_argument_node_type extends views_handler_argument { + function construct() { + parent::construct('type'); + } + + /** + * Override the behavior of summary_name(). Get the user friendly version + * of the node type. + */ + function summary_name($data) { + return $this->node_type($data->{$this->name_alias}); + } + + /** + * Override the behavior of title(). Get the user friendly version of the + * node type. + */ + function title() { + return $this->node_type($this->argument); + } + + function node_type($type) { + $output = node_type_get_name($type); + if (empty($output)) { + $output = t('Unknown node type'); + } + return check_plain($output); + } +} diff --git a/sites/all/modules/views/modules/node/views_handler_argument_node_vid.inc b/sites/all/modules/views/modules/node/views_handler_argument_node_vid.inc new file mode 100644 index 0000000000000000000000000000000000000000..4a20d5809cc691073d8829f222a3593447a7b1dc --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_argument_node_vid.inc @@ -0,0 +1,27 @@ +<?php +// $Id: views_handler_argument_node_vid.inc,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ +/** + * @file + * Provide node vid argument handler. + */ + +/** + * Argument handler to accept a node revision id. + */ +class views_handler_argument_node_vid extends views_handler_argument_numeric { + // No constructor is necessary. + + /** + * Override the behavior of title(). Get the title of the revision. + */ + function title_query() { + $titles = array(); + + $result = db_query("SELECT n.title FROM {node_revision} n WHERE n.nid IN (:nids)", array(':nids' => $this->value)); + foreach ($result as $term) { + $titles[] = check_plain($term->title); + } + return $titles; + } +} + diff --git a/sites/all/modules/views/modules/node/views_handler_field_history_user_timestamp.inc b/sites/all/modules/views/modules/node/views_handler_field_history_user_timestamp.inc new file mode 100644 index 0000000000000000000000000000000000000000..5d11c7e055b451778a433fe1f427fe30174d5dc4 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_field_history_user_timestamp.inc @@ -0,0 +1,74 @@ +<?php +// $Id: views_handler_field_history_user_timestamp.inc,v 1.1.6.3 2010/08/26 09:41:55 dereine Exp $ +/** + * Field handler to display the marker for new content. + * + * The handler is named history_user, because of compability reasons, the table is history. + */ +class views_handler_field_history_user_timestamp extends views_handler_field_node { + function init(&$view, &$options) { + parent::init($view, $options); + global $user; + if ($user->uid) { + $this->additional_fields['created'] = array('table' => 'node', 'field' => 'created'); + $this->additional_fields['changed'] = array('table' => 'node', 'field' => 'changed'); + if (module_exists('comment') && !empty($this->options['comments'])) { + $this->additional_fields['last_comment'] = array('table' => 'node_comment_statistics', 'field' => 'last_comment_timestamp'); + } + } + } + + function option_definition() { + $options = parent::option_definition(); + + $options['comments'] = array('default' => FALSE); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + if (module_exists('comment')) { + $form['comments'] = array( + '#type' => 'checkbox', + '#title' => t('Check for new comments as well'), + '#default_value' => !empty($this->options['comments']), + ); + } + } + + function query() { + // Only add ourselves to the query if logged in. + global $user; + if (!$user->uid) { + return; + } + parent::query(); + } + + function render($values) { + // Let's default to 'read' state. + // This code shadows node_mark, but it reads from the db directly and + // we already have that info. + $mark = MARK_READ; + global $user; + if ($user->uid) { + $last_read = $values->{$this->field_alias}; + $created = $values->{$this->aliases['created']}; + $changed = $values->{$this->aliases['changed']}; + + $last_comment = module_exists('comment') && !empty($this->options['comments']) ? $values->{$this->aliases['last_comment']} : 0; + + if (!$last_read && $created > NODE_NEW_LIMIT) { + $mark = MARK_NEW; + } + elseif ($changed > $last_read && $changed > NODE_NEW_LIMIT) { + $mark = MARK_UPDATED; + } + elseif ($last_comment > $last_read && $last_comment > NODE_NEW_LIMIT) { + $mark = MARK_UPDATED; + } + return $this->render_link(theme('mark', array('type' => $mark)), $values); + } + } +} diff --git a/sites/all/modules/views/modules/node/views_handler_field_node.inc b/sites/all/modules/views/modules/node/views_handler_field_node.inc new file mode 100644 index 0000000000000000000000000000000000000000..b405b0d8c42a21ad21efa1ae5083ee0311105a7e --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_field_node.inc @@ -0,0 +1,72 @@ +<?php +// $Id: views_handler_field_node.inc,v 1.7.4.8 2010/11/18 23:32:04 merlinofchaos Exp $ +/** + * @file + * Contains the basic 'node' field handler. + */ + +/** + * Field handler to provide simple renderer that allows linking to a node. + */ +class views_handler_field_node extends views_handler_field { + + function init(&$view, &$options) { + parent::init($view, $options); + if (!empty($this->options['link_to_node'])) { + $this->additional_fields['nid'] = array('table' => 'node', 'field' => 'nid'); + if (module_exists('translation')) { + $this->additional_fields['language'] = array('table' => 'node', 'field' => 'language'); + } + } + } + + function option_definition() { + $options = parent::option_definition(); + $options['link_to_node'] = array('default' => TRUE); + return $options; + } + + /** + * Provide link to node option + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_to_node'] = array( + '#title' => t('Link this field to its node'), + '#description' => t('This will override any other link you have set.'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['link_to_node']), + ); + } + + /** + * Render whatever the data is as a link to the node. + * + * Data should be made XSS safe prior to calling this function. + */ + function render_link($data, $values) { + if (!empty($this->options['link_to_node'])) { + if ($data !== NULL && $data !== '') { + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "node/" . $values->{$this->aliases['nid']}; + if (isset($this->aliases['language'])) { + $languages = language_list(); + if (isset($languages[$values->{$this->aliases['language']}])) { + $this->options['alter']['language'] = $languages[$values->{$this->aliases['language']}]; + } + else { + unset($this->options['alter']['language']); + } + } + } + else { + $this->options['alter']['make_link'] = FALSE; + } + } + return $data; + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->field_alias}), $values); + } +} diff --git a/sites/all/modules/views/modules/node/views_handler_field_node_link.inc b/sites/all/modules/views/modules/node/views_handler_field_node_link.inc new file mode 100644 index 0000000000000000000000000000000000000000..c75569ddfcd6b259f2cd2a8ef55e3984f991ee07 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_field_node_link.inc @@ -0,0 +1,45 @@ +<?php +// $Id: views_handler_field_node_link.inc,v 1.1.6.2 2010/11/30 20:36:01 merlinofchaos Exp $ +/** + * Field handler to present a link to the node. + */ +class views_handler_field_node_link extends views_handler_field { + function construct() { + parent::construct(); + $this->additional_fields['nid'] = 'nid'; + } + + function option_definition() { + $options = parent::option_definition(); + + $options['text'] = array('default' => '', 'translatable' => TRUE); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['text'] = array( + '#type' => 'textfield', + '#title' => t('Text to display'), + '#default_value' => $this->options['text'], + ); + } + + function query() { + $this->ensure_my_table(); + $this->add_additional_fields(); + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->aliases['nid']}), $values); + } + + function render_link($data, $values) { + $nid = $values->{$this->aliases['nid']}; + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "node/$nid"; + $text = !empty($this->options['text']) ? $this->options['text'] : t('view'); + return $text; + } +} diff --git a/sites/all/modules/views/modules/node/views_handler_field_node_link_delete.inc b/sites/all/modules/views/modules/node/views_handler_field_node_link_delete.inc new file mode 100644 index 0000000000000000000000000000000000000000..fb2771acd41bb3d8b0ed59fd8da17b91968cecfb --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_field_node_link_delete.inc @@ -0,0 +1,32 @@ +<?php +// $Id: views_handler_field_node_link_delete.inc,v 1.1.6.2 2010/11/18 07:29:03 dereine Exp $ +/** + * Field handler to present a link to delete a node. + */ +class views_handler_field_node_link_delete extends views_handler_field_node_link { + function construct() { + parent::construct(); + $this->additional_fields['type'] = 'type'; + $this->additional_fields['uid'] = 'uid'; + } + + function render_link($data, $values) { + // ensure user has access to edit this node. + $node = new stdClass(); + $node->nid = $values->{$this->aliases['nid']}; + $node->uid = $values->{$this->aliases['uid']}; + $node->type = $values->{$this->aliases['type']}; + $node->status = 1; // unpublished nodes ignore access control + if (!node_access('delete', $node)) { + return; + } + + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "node/$node->nid/delete"; + $this->options['alter']['query'] = drupal_get_destination(); + + $text = !empty($this->options['text']) ? $this->options['text'] : t('delete'); + return $text; + } +} + diff --git a/sites/all/modules/views/modules/node/views_handler_field_node_link_edit.inc b/sites/all/modules/views/modules/node/views_handler_field_node_link_edit.inc new file mode 100644 index 0000000000000000000000000000000000000000..e137b67be3bfbaef5685eb64b25d0a576e0ebe01 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_field_node_link_edit.inc @@ -0,0 +1,32 @@ +<?php +// $Id: views_handler_field_node_link_edit.inc,v 1.1.6.2 2010/11/18 07:29:03 dereine Exp $ +/** + * Field handler to present a link node edit. + */ +class views_handler_field_node_link_edit extends views_handler_field_node_link { + function construct() { + parent::construct(); + $this->additional_fields['uid'] = 'uid'; + $this->additional_fields['type'] = 'type'; + } + + function render_link($data, $values) { + // ensure user has access to edit this node. + $node = new stdClass(); + $node->nid = $values->{$this->aliases['nid']}; + $node->uid = $values->{$this->aliases['uid']}; + $node->type = $values->{$this->aliases['type']}; + $node->status = 1; // unpublished nodes ignore access control + if (!node_access('update', $node)) { + return; + } + + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "node/$node->nid/edit"; + $this->options['alter']['query'] = drupal_get_destination(); + + $text = !empty($this->options['text']) ? $this->options['text'] : t('edit'); + return $text; + } +} + diff --git a/sites/all/modules/views/modules/node/views_handler_field_node_path.inc b/sites/all/modules/views/modules/node/views_handler_field_node_path.inc new file mode 100644 index 0000000000000000000000000000000000000000..3924d2779c67cfdb9b4cce502e13742496b4cd59 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_field_node_path.inc @@ -0,0 +1,39 @@ +<?php +// $Id: +/** + * Field handler to present the path to the node. + */ +class views_handler_field_node_path extends views_handler_field { + + function option_definition() { + $options = parent::option_definition(); + $options['absolute'] = array('default' => FALSE); + + return $options; + } + + function construct() { + parent::construct(); + $this->additional_fields['nid'] = 'nid'; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['absolute'] = array( + '#type' => 'checkbox', + '#title' => t('Use absolute link (begins with "http://")'), + '#default_value' => $this->options['absolute'], + '#description' => t('If you want to use this as in "output this field as link" in "link path", you have to enabled this option.'), + ); + } + + function query() { + $this->ensure_my_table(); + $this->add_additional_fields(); + } + + function render($values) { + $nid = $values->{$this->aliases['nid']}; + return url("node/$nid", array('absolute' => $this->options['absolute'])); + } +} diff --git a/sites/all/modules/views/modules/node/views_handler_field_node_revision.inc b/sites/all/modules/views/modules/node/views_handler_field_node_revision.inc new file mode 100644 index 0000000000000000000000000000000000000000..e8ca371fd68e7291766a23e638ced475081db0d9 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_field_node_revision.inc @@ -0,0 +1,60 @@ +<?php +// $Id: views_handler_field_node_revision.inc,v 1.1.6.3 2010/08/26 09:41:55 dereine Exp $ +/** + * @file + * Contains the basic 'node_revision' field handler. + */ + +class views_handler_field_node_revision extends views_handler_field_node { + function init(&$view, &$options) { + parent::init($view, $options); + if (!empty($this->options['link_to_node_revision'])) { + $this->additional_fields['vid'] = 'vid'; + $this->additional_fields['nid'] = 'nid'; + if (module_exists('translation')) { + $this->additional_fields['language'] = array('table' => 'node', 'field' => 'language'); + } + } + } + function option_definition() { + $options = parent::option_definition(); + $options['link_to_node_revision'] = array('default' => FALSE); + return $options; + } + + /** + * Provide link to revision option. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_to_node_revision'] = array( + '#title' => t('Link this field to its node revision'), + '#description' => t('This will override any other link you have set.'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['link_to_node_revision']), + ); + } + + /** + * Render whatever the data is as a link to the node. + * + * Data should be made XSS safe prior to calling this function. + */ + function render_link($data, $values) { + if (!empty($this->options['link_to_node_revision']) && $data !== NULL && $data !== '') { + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "node/" . $values->{$this->aliases['nid']} . '/revisions/' . $values->{$this->aliases['vid']} .'/view'; + if (isset($this->aliases['language'])) { + $languages = language_list(); + if (isset($languages[$values->{$this->aliases['language']}])) { + $this->options['alter']['language'] = $languages[$values->{$this->aliases['language']}]; + } + } + } + else { + return parent::render_link($data, $values); + } + return $data; + } +} + diff --git a/sites/all/modules/views/modules/node/views_handler_field_node_revision_link_delete.inc b/sites/all/modules/views/modules/node/views_handler_field_node_revision_link_delete.inc new file mode 100644 index 0000000000000000000000000000000000000000..de9c36105ebdcee3d001927aa757b5555cb57991 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_field_node_revision_link_delete.inc @@ -0,0 +1,42 @@ +<?php +// $Id: views_handler_field_node_revision_link_delete.inc,v 1.1.6.2 2010/11/18 07:29:03 dereine Exp $ +/** + * Field handler to present delete a node revision. + */ +class views_handler_field_node_revision_link_delete extends views_handler_field_node_link { + function construct() { + parent::construct(); + $this->additional_fields['uid'] = array('table' => 'node', 'field' => 'uid'); + $this->additional_fields['node_vid'] = array('table' => 'node', 'field' => 'vid'); + $this->additional_fields['vid'] = 'vid'; + } + + function access() { + return user_access('delete revisions') || user_access('administer nodes'); + } + + function render_link($data, $values) { + // ensure user has access to delete this node. + $node = new stdClass(); + $node->nid = $values->{$this->aliases['nid']}; + $node->vid = $values->{$this->aliases['vid']}; + $node->uid = $values->{$this->aliases['uid']}; + $node->status = 1; // unpublished nodes ignore access control + if (!node_access('delete', $node)) { + return; + } + + // Current revision cannot be deleted. + if ($node->vid == $values->{$this->aliases['node_vid']}) { + return; + } + + $text = !empty($this->options['text']) ? $this->options['text'] : t('delete'); + + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "node/$node->nid/revisions/$node->vid/delete"; + $this->options['alter']['query'] = drupal_get_destination(); + + return $text; + } +} diff --git a/sites/all/modules/views/modules/node/views_handler_field_node_revision_link_revert.inc b/sites/all/modules/views/modules/node/views_handler_field_node_revision_link_revert.inc new file mode 100644 index 0000000000000000000000000000000000000000..4e2fc757bceaf9418e8c5b5390ac2fecfb96b613 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_field_node_revision_link_revert.inc @@ -0,0 +1,42 @@ +<?php +// $Id: views_handler_field_node_revision_link_revert.inc,v 1.1.6.2 2010/11/18 07:29:03 dereine Exp $ +/** + * Field handler to present a link to revert a node to a revision + */ +class views_handler_field_node_revision_link_revert extends views_handler_field_node_link { + function construct() { + parent::construct(); + $this->additional_fields['uid'] = array('table' => 'node', 'field' => 'uid'); + $this->additional_fields['node_vid'] = array('table' => 'node', 'field' => 'vid'); + $this->additional_fields['vid'] = 'vid'; + } + + function access() { + return user_access('revert revisions') || user_access('administer nodes'); + } + + function render_link($data, $values) { + // ensure user has access to edit this node. + $node = new stdClass(); + $node->nid = $values->{$this->aliases['nid']}; + $node->vid = $values->{$this->aliases['vid']}; + $node->uid = $values->{$this->aliases['uid']}; + $node->status = 1; // unpublished nodes ignore access control + if (!node_access('update', $node)) { + return; + } + + // Current revision cannot be reverted. + if ($node->vid == $values->{$this->aliases['node_vid']}) { + return; + } + + $text = !empty($this->options['text']) ? $this->options['text'] : t('revert'); + + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "node/$node->nid/revisions/$node->vid/revert"; + $this->options['alter']['query'] = drupal_get_destination(); + + return $text; + } +} diff --git a/sites/all/modules/views/modules/node/views_handler_field_node_type.inc b/sites/all/modules/views/modules/node/views_handler_field_node_type.inc new file mode 100644 index 0000000000000000000000000000000000000000..038fa004a84b58cfbcf67899db8ad8351e9fec91 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_field_node_type.inc @@ -0,0 +1,42 @@ +<?php +// $Id: views_handler_field_node_type.inc,v 1.2.4.4 2010/04/29 18:33:29 merlinofchaos Exp $ + +/** + * Field handler to translate a node type into its readable form. + */ +class views_handler_field_node_type extends views_handler_field_node { + function option_definition() { + $options = parent::option_definition(); + $options['machine_name'] = array('default' => FALSE); + + return $options; + } + + /** + * Provide machine_name option for to node type display. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['machine_name'] = array( + '#title' => t('Output machine name'), + '#description' => t('Display field as the node type machine name.'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['machine_name']), + ); + } + + /** + * Render node type as human readable name, unless using machine_name option. + */ + function render_name($data, $values) { + if ($this->options['machine_name'] != 1 && $data !== NULL && $data !== '') { + return t(check_plain(node_type_get_name($data))); + } + return check_plain($data); + } + + function render($values) { + return $this->render_link($this->render_name($values->{$this->field_alias}, $values), $values); + } +} + diff --git a/sites/all/modules/views/modules/node/views_handler_filter_history_user_timestamp.inc b/sites/all/modules/views/modules/node/views_handler_filter_history_user_timestamp.inc new file mode 100644 index 0000000000000000000000000000000000000000..04219e6d94b66ca76920e96b0411a6b5ec5772de --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_filter_history_user_timestamp.inc @@ -0,0 +1,73 @@ +<?php +// $Id: views_handler_filter_history_user_timestamp.inc,v 1.3.4.4 2010/12/25 22:03:47 dereine Exp $ +/** + * Filter for new content + * + * The handler is named history_user, because of compability reasons, the table is history. + */ +class views_handler_filter_history_user_timestamp extends views_handler_filter { + // Don't display empty space where the operator would be. + var $no_operator = TRUE; + + function expose_form_right() { + // We don't want any of the usual options for exposed filters. + } + + function value_form(&$form, &$form_state) { + // Only present a checkbox for the exposed filter itself. There's no way + // to tell the difference between not checked and the default value, so + // specifying the default value via the views UI is meaningless. + if (!empty($form_state['exposed'])) { + if (isset($this->options['expose']['label'])) { + $label = $this->options['expose']['label']; + } + else { + $label = t('Has new content'); + } + $form['value'] = array( + '#type' => 'checkbox', + '#title' => $label, + '#default_value' => $this->value, + ); + } + } + + function query() { + global $user; + // This can only work if we're logged in. + if (!$user || !$user->uid) { + return; + } + + // Don't filter if we're exposed and the checkbox isn't selected. + if ((!empty($this->options['exposed'])) && empty($this->value)) { + return; + } + + // Hey, Drupal kills old history, so nodes that haven't been updated + // since NODE_NEW_LIMIT are bzzzzzzzt outta here! + + $limit = REQUEST_TIME - NODE_NEW_LIMIT; + + $this->ensure_my_table(); + $field = "$this->table_alias.$this->real_field"; + $node = $this->query->ensure_table('node', $this->relationship); + + if (module_exists('comment')) { + $ncs = $this->query->ensure_table('node_comment_statistics', $this->relationship); + $clause = ("OR $ncs.last_comment_timestamp > (***CURRENT_TIME*** - $limit)"); + $clause2 = "OR $field < $ncs.last_comment_timestamp"; + } + + // NULL means a history record doesn't exist. That's clearly new content. + // Unless it's very very old content. Everything in the query is already + // type safe cause none of it is coming from outside here. + $this->query->add_where($this->options['group'], "($field IS NULL AND ($node.changed > (***CURRENT_TIME*** - $limit) $clause)) OR $field < $node.changed $clause2", array(), 'formula'); + } + + function admin_summary() { + if (!empty($this->options['exposed'])) { + return t('exposed'); + } + } +} diff --git a/sites/all/modules/views/modules/node/views_handler_filter_node_access.inc b/sites/all/modules/views/modules/node/views_handler_filter_node_access.inc new file mode 100644 index 0000000000000000000000000000000000000000..0ae2a62b2155566ae2b54b967f0ed27a6c744ee4 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_filter_node_access.inc @@ -0,0 +1,33 @@ +<?php +// $Id: views_handler_filter_node_access.inc,v 1.2.4.2 2010/08/26 09:41:55 dereine Exp $ +/** + * Filter by node_access records. + */ +class views_handler_filter_node_access extends views_handler_filter { + function admin_summary() { } + function operator_form(&$form, &$form_state) { } + function can_expose() { + return FALSE; + } + + /** + * See _node_access_where_sql() for a non-views query based implementation. + */ + function query() { + if (!user_access('administer nodes')) { + $table = $this->ensure_my_table(); + $grants = db_or(); + foreach (node_access_grants('view') as $realm => $gids) { + foreach ($gids as $gid) { + $grants->condition(db_and() + ->condition($table . '.gid', $gid) + ->condition($table . '.realm', $realm) + ); + } + } + + $this->query->add_where('AND', $grants); + $this->query->add_where('AND', $table . '.grant_view', 1, '>='); + } + } +} diff --git a/sites/all/modules/views/modules/node/views_handler_filter_node_status.inc b/sites/all/modules/views/modules/node/views_handler_filter_node_status.inc new file mode 100644 index 0000000000000000000000000000000000000000..634ac690e271e2201e0b442015ebafa4dda9e76c --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_filter_node_status.inc @@ -0,0 +1,14 @@ +<?php +// $Id: views_handler_filter_node_status.inc,v 1.2.4.6 2010/11/18 00:43:18 merlinofchaos Exp $ +/** + * Filter by published status + */ +class views_handler_filter_node_status extends views_handler_filter { + function admin_summary() { } + function operator_form(&$form, &$form_state) { } + + function query() { + $table = $this->ensure_my_table(); + $this->query->add_where($this->options['group'], "$table.status = 1 OR ($table.uid = ***CURRENT_USER*** AND ***CURRENT_USER*** <> 0 AND ***VIEW_OWN_UNPUBLISHED_NODES*** = 1) OR ***ADMINISTER_NODES*** = 1", array(), 'formula'); + } +} diff --git a/sites/all/modules/views/modules/node/views_handler_filter_node_type.inc b/sites/all/modules/views/modules/node/views_handler_filter_node_type.inc new file mode 100644 index 0000000000000000000000000000000000000000..5c543429a276d87ce136cb95481d891bba8b13d0 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_handler_filter_node_type.inc @@ -0,0 +1,17 @@ +<?php +// $Id: views_handler_filter_node_type.inc,v 1.2.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ +/** + * Filter by node type + */ +class views_handler_filter_node_type extends views_handler_filter_in_operator { + function get_value_options() { + if (!isset($this->value_options)) { + $this->value_title = t('Node type'); + $types = node_type_get_types(); + foreach ($types as $type => $info) { + $options[$type] = t($info->name); + } + $this->value_options = $options; + } + } +} diff --git a/sites/all/modules/views/modules/node/views_plugin_argument_default_node.inc b/sites/all/modules/views/modules/node/views_plugin_argument_default_node.inc new file mode 100644 index 0000000000000000000000000000000000000000..6fc68d0071d93fa7165f2ee34f73f0ce72ea34d5 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_plugin_argument_default_node.inc @@ -0,0 +1,27 @@ +<?php +// $Id: views_plugin_argument_default_node.inc,v 1.1.6.1 2010/01/28 22:44:36 dereine Exp $ +/** + * @file + * Contains the node from URL argument default plugin. + */ + +/** + * Default argument plugin to extract a node via menu_get_object + * + * This plugin actually has no options so it odes not need to do a great deal. + */ +class views_plugin_argument_default_node extends views_plugin_argument_default { + function get_argument() { + foreach (range(1, 3) as $i) { + $node = menu_get_object('node', $i); + if (!empty($node)) { + return $node->nid; + } + } + + if (arg(0) == 'node' && is_numeric(arg(1))) { + return arg(1); + } + } +} + diff --git a/sites/all/modules/views/modules/node/views_plugin_argument_validate_node.inc b/sites/all/modules/views/modules/node/views_plugin_argument_validate_node.inc new file mode 100644 index 0000000000000000000000000000000000000000..8d3779f4cee2c7a4f9c780313ae409e3bdc4f51f --- /dev/null +++ b/sites/all/modules/views/modules/node/views_plugin_argument_validate_node.inc @@ -0,0 +1,126 @@ +<?php +// $Id: views_plugin_argument_validate_node.inc,v 1.2.4.3 2010/05/15 08:11:14 dereine Exp $ +/** + * @file + * Contains the 'node' argument validator plugin. + */ + +/** + * Validate whether an argument is an acceptable node. + */ +class views_plugin_argument_validate_node extends views_plugin_argument_validate { + function option_definition() { + $options = parent::option_definition(); + $options['types'] = array('default' => array()); + $options['access'] = array('default' => FALSE); + $options['nid_type'] = array('default' => 'nid'); + + return $options; + } + + function options_form(&$form, &$form_state) { + $types = node_type_get_types(); + foreach ($types as $type => $info) { + $options[$type] = check_plain(t($info->name)); + } + + $form['types'] = array( + '#type' => 'checkboxes', + '#title' => t('Types'), + '#options' => $options, + '#default_value' => $this->options['types'], + '#description' => t('If you wish to validate for specific node types, check them; if none are checked, all nodes will pass.'), + ); + + $form['access'] = array( + '#type' => 'checkbox', + '#title' => t('Validate user has access to the node'), + '#default_value' => $this->options['access'], + ); + + $form['nid_type'] = array( + '#type' => 'select', + '#title' => t('Argument type'), + '#options' => array( + 'nid' => t('Node ID'), + 'nids' => t('Node IDs separated by , or +'), + ), + '#default_value' => $this->options['nid_type'], + ); + } + + function options_submit(&$form, &$form_state, &$options) { + // filter trash out of the options so we don't store giant unnecessary arrays + $options['types'] = array_filter($options['types']); + } + + function convert_options(&$options) { + if (!isset($options['types']) && !empty($this->argument->options['validate_argument_node_type'])) { + $options['types'] = $this->argument->options['validate_argument_node_type']; + $options['access'] = !empty($this->argument->options['validate_argument_node_access']); + $options['nid_type'] = isset($this->argument->options['validate_argument_nid_type']) ? $this->argument->options['validate_argument_nid_type'] : array(); + } + } + + function validate_argument($argument) { + $types = $this->options['types']; + + switch ($this->options['nid_type']) { + case 'nid': + if (!is_numeric($argument)) { + return FALSE; + } + $node = node_load($argument); + if (!$node) { + return FALSE; + } + + if (!empty($this->options['access'])) { + if (!node_access('view', $node)) { + return FALSE; + } + } + + // Save the title() handlers some work. + $this->argument->validated_title = check_plain($node->title); + + if (empty($types)) { + return TRUE; + } + + return isset($types[$node->type]); + break; + case 'nids': + $nids = new stdClass(); + $nids->value = array($argument); + $nids = views_nid_type($argument, $nids); + if ($nids->value == -1) { + return FALSE; + } + + $test = drupal_map_assoc($nids->value); + $titles = array(); + + $result = db_query("SELECT * FROM {node} WHERE nid IN (:nids)", array(':nids' => $nids->value)); + foreach ($result as $node) { + if ($types && empty($types[$node->type])) { + return FALSE; + } + + if (!empty($this->options['access'])) { + if (!node_access('view', $node)) { + return FALSE; + } + } + + $titles[] = check_plain($node->title); + unset($test[$node->nid]); + } + + $this->argument->validated_title = implode($nids->operator == 'or' ? ' + ' : ', ', $titles); + // If this is not empty, we did not find a nid. + return empty($test); + } + } +} + diff --git a/sites/all/modules/views/modules/node/views_plugin_row_node_rss.inc b/sites/all/modules/views/modules/node/views_plugin_row_node_rss.inc new file mode 100644 index 0000000000000000000000000000000000000000..6c3f966c5965b74ffc56697ce20ac8378f710051 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_plugin_row_node_rss.inc @@ -0,0 +1,113 @@ +<?php +// $Id: views_plugin_row_node_rss.inc,v 1.7.4.7 2010/11/11 19:41:11 dereine Exp $ +/** + * @file + * Contains the node RSS row style plugin. + */ + +/** + * Plugin which performs a node_view on the resulting object + * and formats it as an RSS item. + */ +class views_plugin_row_node_rss extends views_plugin_row { + // Basic properties that let the row style follow relationships. + var $base_table = 'node'; + var $base_field = 'nid'; + + // Stores the nodes loaded with pre_render. + var $nodes = array(); + + function option_definition() { + $options = parent::option_definition(); + + $options['item_length'] = array('default' => 'default'); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $form['item_length'] = array( + '#type' => 'select', + '#title' => t('Display type'), + '#options' => array( + 'fulltext' => t('Full text'), + 'teaser' => t('Title plus teaser'), + 'title' => t('Title only'), + 'default' => t('Use default RSS settings'), + ), + '#default_value' => $this->options['item_length'], + ); + } + + function pre_render($values) { + foreach ($values as $row) { + $nids[] = $row->{$this->field_alias}; + } + $this->nodes = node_load_multiple($nids); + } + + function render($row) { + // For the most part, this code is taken from node_feed() in node.module + global $base_url; + + $nid = $row->{$this->field_alias}; + if (!is_numeric($nid)) { + return; + } + + $item_length = $this->options['item_length']; + if ($item_length == 'default') { + $item_length = variable_get('feed_item_length', 'teaser'); + } + + // Load the specified node: + $node = $this->nodes[$nid]; + if (empty($node)) { + return; + } + + $item_text = ''; + + $node->rss_namespaces = array(); + $node->rss_elements = array( + array('key' => 'pubDate', 'value' => gmdate('r', $node->created)), + array('key' => 'dc:creator', 'value' => $node->name, 'namespace' => array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/')), + array('key' => 'guid', 'value' => $node->nid . ' at ' . $base_url, 'attributes' => array('isPermaLink' => 'false')) + ); + + // The node gets built and modules add to or modify $node->rss_elements + // and $node->rss_namespaces. + node_build_content($node, 'rss'); + + foreach ($node->rss_elements as $element) { + if (isset($element['namespace'])) { + $this->view->style_plugin->namespaces = array_merge($this->view->style_plugin->namespaces, $element['namespace']); + } + } + + if ($item_length != 'title' && !empty($node->content)) { + // We render node contents and force links to be last. + $links = drupal_render($node->content['links']); + $item_text .= drupal_render($node->content) . $links; + } + + $item->description = $item_text; + $item->title = $node->title; + $item->link = url("node/$node->nid", array('absolute' => TRUE)); + $item->elements = $node->rss_elements; + $item->nid = $node->nid; + if (isset($node->readmore)) { + $item->readmore = $node->readmore; + } + + return theme($this->theme_functions(), + array( + 'view' => $this->view, + 'options' => $this->options, + 'row' => $item + )); + } +} + diff --git a/sites/all/modules/views/modules/node/views_plugin_row_node_view.inc b/sites/all/modules/views/modules/node/views_plugin_row_node_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..af70597714160cc96af5cb83beaa2b44a15ecd06 --- /dev/null +++ b/sites/all/modules/views/modules/node/views_plugin_row_node_view.inc @@ -0,0 +1,81 @@ +<?php +// $Id: views_plugin_row_node_view.inc,v 1.3.6.3 2010/12/03 11:26:09 dereine Exp $ +/** + * @file + * Contains the node view row style plugin. + */ + +/** + * Plugin which performs a node_view on the resulting object. + * + * Most of the code on this object is in the theme function. + */ +class views_plugin_row_node_view extends views_plugin_row { + // Basic properties that let the row style follow relationships. + var $base_table = 'node'; + var $base_field = 'nid'; + + // Stores the nodes loaded with pre_render. + var $nodes = array(); + + function init(&$view, &$display, $options = NULL) { + parent::init($view, $display, $options); + // Handle existing views with the deprecated 'teaser' option. + if (isset($this->options['teaser'])) { + $this->options['build_mode'] = $this->options['teaser'] ? 'teaser' : 'full'; + } + } + + function option_definition() { + $options = parent::option_definition(); + + $options['build_mode'] = array('default' => 'teaser'); + $options['links'] = array('default' => TRUE); + $options['comments'] = array('default' => FALSE); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $entity_info = entity_get_info('node'); + $options = array(); + if (!empty($entity_info['view modes'])) { + foreach ($entity_info['view modes'] as $mode => $settings) { + $options[$mode] = $settings['label']; + } + } + if (empty($options)) { + $options = array( + 'teaser' => t('Teaser'), + 'full' => t('Full node') + ); + } + + $form['build_mode'] = array( + '#type' => 'select', + '#options' => $options, + '#title' => t('Build mode'), + '#default_value' => $this->options['build_mode'], + ); + $form['links'] = array( + '#type' => 'checkbox', + '#title' => t('Display links'), + '#default_value' => $this->options['links'], + ); + $form['comments'] = array( + '#type' => 'checkbox', + '#title' => t('Display node comments'), + '#default_value' => $this->options['comments'], + ); + } + + function pre_render($values) { + $nids = array(); + foreach ($values as $row) { + $nids[] = $row->{$this->field_alias}; + } + $this->nodes = node_load_multiple($nids); + } +} diff --git a/sites/all/modules/views/modules/poll.views.inc b/sites/all/modules/views/modules/poll.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..d759e8b96ab4e153b880bca142f56c61b41c4f8d --- /dev/null +++ b/sites/all/modules/views/modules/poll.views.inc @@ -0,0 +1,56 @@ +<?php +// $Id: poll.views.inc,v 1.4.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ +/** + * @file + * Provide views data and handlers for poll.module + */ + +/** + * @defgroup views_poll_module poll.module handlers + * + * Includes only the core 'poll' table for now. + * @{ + */ + +/** + * Implements hook_views_data() + */ +function poll_views_data() { + // Basic table information. + $data['poll']['table']['group'] = t('Poll'); + + // Join to 'node' as a base table. + $data['poll']['table']['join'] = array( + 'node' => array( + 'left_field' => 'nid', + 'field' => 'nid', + ), + ); + + // ---------------------------------------------------------------- + // Fields + + // poll active status + $data['poll']['active'] = array( + 'title' => t('Active'), + 'help' => t('Whether the poll is open for voting.'), + 'field' => array( + 'handler' => 'views_handler_field_boolean', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_boolean_operator', + 'label' => t('Active'), + 'type' => 'yes-no', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + return $data; +} + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/profile.views.inc b/sites/all/modules/views/modules/profile.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..9fe790746ea890c4552b0aebca3af1f9eae64683 --- /dev/null +++ b/sites/all/modules/views/modules/profile.views.inc @@ -0,0 +1,224 @@ +<?php +//$Id: profile.views.inc,v 1.10.4.8 2010/12/16 06:50:28 merlinofchaos Exp $ +/** + * @file + * Provide views data and handlers for user.module + */ + +/** + * @defgroup views_profile_module profile.module handlers + * + * @{ + */ + +/** + * Implements hook_views_data() + */ +function profile_views_data() { + // Define the base group of this table. Fields that don't + // have a group defined will go into this field by default. + $data['profile_value']['table']['group'] = t('Profile'); + + $data['profile_value']['table']['join'] = array( + 'node' => array( + 'left_table' => 'profile_value', + 'left_field' => 'uid', + 'field' => 'uid', + ), + 'users' => array( + 'left_table' => 'profile_value', + 'left_field' => 'uid', + 'field' => 'uid', + ), + ); + + $fields = profile_views_get_fields(); + foreach ($fields as $field) { + $table_name = 'profile_value_' . str_replace('-', '_', $field->name); + $data[$table_name] = array( + 'table' => array( + 'group' => t('Profile'), + 'join' => array( + 'node' => array( + 'table' => 'profile_value', + 'left_table' => 'users', + 'left_field' => 'uid', + 'field' => 'uid', + 'extra' => array(array('field' => 'fid', 'value' => $field->fid)), + ), + 'users' => array( + 'table' => 'profile_value', + 'left_field' => 'uid', + 'field' => 'uid', + 'extra' => array(array('field' => 'fid', 'value' => $field->fid)), + ), + ), + ), + ); + // All fields in the table are named 'value'. + $data[$table_name]['value'] = profile_views_fetch_field($field); + } + + return $data; +} + +/** + * Get all profile fields + */ +function profile_views_get_fields() { + static $fields = NULL; + + if (!isset($fields)) { + $fields = array(); + $results = db_query("SELECT * FROM {profile_field} ORDER BY category, weight"); + + foreach ($results as $row) { + if (!empty($row->options)) { + if (!in_array(substr($row->options, 0, 2), array('a:', 'b:', 'i:', 'f:', 'o:', 's:', ))) { + // unserialized fields default version + $options = $row->options; + unset($row->options); + $row->options = $options; + } + else { + // serialized fields or modified version + $row->options = unserialize(db_decode_blob($row->options)); + } + } + $fields[$row->fid] = $row; + } + } + return $fields; +} + + +/** + * Add profile fields to view table + */ +function profile_views_fetch_field($field) { + $data = array( + 'title' => t('@category: @field-name', array('@category' => $field->category, '@field-name' => $field->title)), + ); + + // Add fields specific to the profile type. + switch ($field->type) { + case 'textfield': + $data += array( + 'help' => t('Profile textfield'), + 'field' => array( + 'handler' => 'views_handler_field_user', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + break; + case 'textarea': + $data += array( + 'help' => t('Profile textarea'), + 'field' => array( + 'handler' => 'views_handler_field_markup', + 'format' => filter_default_format(), + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + break; + case 'checkbox': + $data += array( + 'help' => t('Profile checkbox'), + 'field' => array( + 'handler' => 'views_handler_field_boolean', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_boolean_operator', + 'accept null' => TRUE, + ), + // @todo there ought to be a boolean argument handler + ); + + break; + case 'url': + $data += array( + 'help' => t('Profile URL'), + 'field' => array( + 'handler' => 'views_handler_field_url', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + break; + case 'selection': + $data += array( + 'help' => t('Profile selection'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_profile_selection', + 'fid' => $field->fid, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + break; + case 'list': + $data += array( + 'help' => t('Profile freeform list %field-name.', array('%field-name' => $field->title)), + 'field' => array( + 'handler' => 'views_handler_field_profile_list', + 'no group by' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + break; + case 'date': + $data += array( + 'help' => t('Profile date %field-name.', array('%field-name' => $field->title)), + 'field' => array( + 'handler' => 'views_handler_field_profile_date', + ), + ); + + break; + } + + // @todo: add access control to hidden fields. + return $data; +} + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/profile.views_convert.inc b/sites/all/modules/views/modules/profile.views_convert.inc new file mode 100644 index 0000000000000000000000000000000000000000..4819dda688d06e76bd2bc2e7784e4e775db4a33a --- /dev/null +++ b/sites/all/modules/views/modules/profile.views_convert.inc @@ -0,0 +1,40 @@ +<?php +// $Id: profile.views_convert.inc,v 1.2.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * @file + * Field conversion for fields handled by this module. + */ + +/** + * Implements 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 profile_views_convert($display, $type, &$view, $field, $id = NULL) { + static $profile_fields; + if (!isset($profile_fields)) { + $profile_fields = array(); + foreach (profile_views_get_fields() as $profile_field) { + $profile_fields['profile_values_'. $profile_field->name] = $profile_field; + } + } + switch ($type) { + case 'filter': + if (isset($tables[$field['tablename']])) { + switch ($profile_fields[$field['tablename']]->type) { + case 'vocabulary': + case 'selection': + $operators = array('AND' => 'in', 'OR' => 'in', 'NOR' => 'not in'); + $view->set_item_option($display, 'filter', $id, 'operator', $operators[$field['operator']]); + break; + default: + $view->set_item_option($display, 'filter', $id, 'operator', $field['operator']); + break; + } + } + break; + } +} \ No newline at end of file diff --git a/sites/all/modules/views/modules/profile/views_handler_field_profile_date.inc b/sites/all/modules/views/modules/profile/views_handler_field_profile_date.inc new file mode 100644 index 0000000000000000000000000000000000000000..8f61976565cc316e5e4e9b5f9161cb8d74c44ce8 --- /dev/null +++ b/sites/all/modules/views/modules/profile/views_handler_field_profile_date.inc @@ -0,0 +1,82 @@ +<?php +// $Id: views_handler_field_profile_date.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos Exp $ +/** + * Field handler display a profile date + * + * The dates are stored serialized, which makes them mostly useless from + * SQL. About all we can do is unserialize and display them. + */ +class views_handler_field_profile_date extends views_handler_field_date { + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + // we can't do "time ago" so remove it from the form. + unset($form['date_format']['#options']['time ago']); + } + + /** + * Display a profile field of type 'date' + */ + function render($value) { + if (!$value->{$this->field_alias}) { + return; + } + $value = unserialize($value->{$this->field_alias}); + $format = $this->options['date_format']; + switch ($format) { + case 'custom': + $format = $this->options['custom_date_format']; + break; + case 'small': + $format = variable_get('date_format_short', 'm/d/Y - H:i'); + break; + case 'medium': + $format = variable_get('date_format_medium', 'D, m/d/Y - H:i'); + break; + case 'large': + $format = variable_get('date_format_long', 'l, F j, Y - H:i'); + break; + } + + // Note: Avoid PHP's date() because it does not handle dates before + // 1970 on Windows. This would make the date field useless for e.g. + // birthdays. + + // But we *can* deal with non-year stuff: + $date = gmmktime(0, 0, 0, $value['month'], $value['day'], 1970); + $replace = array( + // day + 'd' => sprintf('%02d', $value['day']), + 'D' => NULL, + 'l' => NULL, + 'N' => NULL, + 'S' => date('S', $date), + 'w' => NULL, + 'j' => $value['day'], + // month + 'F' => date('F', $date), + 'm' => sprintf('%02d', $value['month']), + 'M' => date('M', $date), + 'n' => date('n', $date), + + 'Y' => $value['year'], + 'y' => substr($value['year'], 2, 2), + + // kill time stuff + 'a' => NULL, + 'A' => NULL, + 'g' => NULL, + 'G' => NULL, + 'h' => NULL, + 'H' => NULL, + 'i' => NULL, + 's' => NULL, + ':' => NULL, + 'T' => NULL, + ' - ' => NULL, + ':' => NULL, + ); + + return strtr($format, $replace); + } +} + diff --git a/sites/all/modules/views/modules/profile/views_handler_field_profile_list.inc b/sites/all/modules/views/modules/profile/views_handler_field_profile_list.inc new file mode 100644 index 0000000000000000000000000000000000000000..84861e57440b13105d3c7855d5a7a17c200b5a2d --- /dev/null +++ b/sites/all/modules/views/modules/profile/views_handler_field_profile_list.inc @@ -0,0 +1,34 @@ +<?php +// $Id: views_handler_field_profile_list.inc,v 1.4.4.4 2010/12/20 20:14:28 dereine Exp $ +/** + * Field handler display a profile list item. + */ +class views_handler_field_profile_list extends views_handler_field_prerender_list { + /** + * Break up our field into a proper list. + */ + function pre_render(&$values) { + $this->items = array(); + foreach ($values as $value) { + $field = $value->{$this->field_alias}; + $this->items[$field] = array(); + foreach (preg_split("/[,\n\r]/", $field) as $item) { + if ($item != '' && $item !== NULL) { + $this->items[$field][] = array('item' => $item); + } + } + } + } + + function render_item($count, $item) { + return $item['item']; + } + + function document_self_tokens(&$tokens) { + $tokens['[' . $this->options['id'] . '-item' . ']'] = t('The text of the profile item.'); + } + + function add_self_tokens(&$tokens, $item) { + $tokens['[' . $this->options['id'] . '-item' . ']'] = $item['item']; + } +} diff --git a/sites/all/modules/views/modules/profile/views_handler_filter_profile_selection.inc b/sites/all/modules/views/modules/profile/views_handler_filter_profile_selection.inc new file mode 100644 index 0000000000000000000000000000000000000000..2e54351ba2759b6cc8ebe4529c8db3a291cbf822 --- /dev/null +++ b/sites/all/modules/views/modules/profile/views_handler_filter_profile_selection.inc @@ -0,0 +1,24 @@ +<?php +// $Id: views_handler_filter_profile_selection.inc,v 1.1.6.1 2010/12/20 20:14:28 dereine Exp $ + +/** + * Filter by a selection widget in the profile. + */ +class views_handler_filter_profile_selection extends views_handler_filter_in_operator { + function get_value_options() { + if (isset($this->value_options)) { + return; + } + + $this->value_options = array(); + $all_options = profile_views_get_fields(); + $field = $all_options[$this->definition['fid']]; + + $lines = preg_split("/[,\n\r]/", $field->options); + foreach ($lines as $line) { + if ($line = trim($line)) { + $this->value_options[$line] = $line; + } + } + } +} diff --git a/sites/all/modules/views/modules/search.views.inc b/sites/all/modules/views/modules/search.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..a75e397153339520de7839dfa5f597f736b9bc8b --- /dev/null +++ b/sites/all/modules/views/modules/search.views.inc @@ -0,0 +1,207 @@ +<?php +// $Id: search.views.inc,v 1.18.4.3 2010/07/19 09:18:42 dereine Exp $ +/** + * @file + * Provide views data and handlers for search.module + */ + +/** + * @defgroup views_search_module search.module handlers + * + * Includes the tables 'search_index' + * @{ + */ + +/** + * Implements hook_views_data() + */ +function search_views_data() { + // Basic table information. + + // Define the base group of this table. Fields that don't + // have a group defined will go into this field by default. + $data['search_index']['table']['group'] = t('Search'); + + // For other base tables, explain how we join + $data['search_index']['table']['join'] = array( + 'node' => array( + 'left_field' => 'nid', + 'field' => 'sid', + ), + ); + + $data['search_total']['table']['join'] = array( + 'node' => array( + 'left_table' => 'search_index', + 'left_field' => 'word', + 'field' => 'word', + ), + 'users' => array( + 'left_table' => 'search_index', + 'left_field' => 'word', + 'field' => 'word', + ) + ); + + $data['search_dataset']['table']['join'] = array( + 'node' => array( + 'left_table' => 'search_index', + 'left_field' => 'sid', + 'field' => 'sid', + 'extra' => 'search_index.type = search_dataset.type', + 'type' => 'INNER', + ), + 'users' => array( + 'left_table' => 'search_index', + 'left_field' => 'sid', + 'field' => 'sid', + 'extra' => 'search_index.type = search_dataset.type', + 'type' => 'INNER', + ), + ); + + // ---------------------------------------------------------------- + // Fields + + // score + $data['search_index']['score'] = array( + 'title' => t('Score'), + 'help' => t('The score of the search item. This will not be used if the search filter is not also present.'), + 'field' => array( + 'handler' => 'views_handler_field_search_score', + 'click sortable' => TRUE, + 'float' => TRUE, + ), + // Information for sorting on a search score. + 'sort' => array( + 'handler' => 'views_handler_sort_search_score', + ), + ); + + // Search node links: forward links. + $data['search_node_links_from']['table']['group'] = t('Search'); + $data['search_node_links_from']['table']['join'] = array( + 'node' => array( + 'arguments' => array('search_node_links', 'node', 'nid', 'nid', NULL, 'INNER'), + ), + ); + $data['search_node_links_from']['sid'] = array( + 'title' => t('Links from'), + 'help' => t('Other nodes that are linked from the node.'), + 'argument' => array( + 'handler' => 'views_handler_argument_node_nid', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_equality', + ), + ); + + // Search node links: backlinks. + $data['search_node_links_to']['table']['group'] = t('Search'); + $data['search_node_links_to']['table']['join'] = array( + 'node' => array( + 'arguments' => array('search_node_links', 'node', 'nid', 'sid', NULL, 'INNER'), + ), + ); + $data['search_node_links_to']['nid'] = array( + 'title' => t('Links to'), + 'help' => t('Other nodes that link to the node.'), + 'argument' => array( + 'handler' => 'views_handler_argument_node_nid', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_equality', + ), + ); + + // search filter + $data['search_index']['keys'] = array( + 'title' => t('Search Terms'), // The item it appears as on the UI, + 'help' => t('The terms to search for.'), // The help that appears on the UI, + // Information for searching terms using the full search syntax + 'filter' => array( + 'handler' => 'views_handler_filter_search', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_search', + ), + ); + + return $data; +} + +/** + * Implements hook_views_plugins + */ +function search_views_plugins() { + return; + // DISABLED. This currently doesn't work. + return array( + 'module' => 'views', // This just tells our themes are elsewhere. + 'row' => array( + 'search' => array( + 'title' => t('Search'), + 'help' => t('Display the results with standard search view.'), + 'handler' => 'views_plugin_row_search_view', + 'theme' => 'views_view_row_search', + 'path' => drupal_get_path('module', 'views') . '/modules/search', // not necessary for most modules + 'base' => array('node'), // only works with 'node' as base. + 'type' => 'normal', + ), + 'views_handler_argument_search' => array( + 'parent' => 'views_handler_argument', + ), + ), + ); +} + +/** + * Template helper for theme_views_view_row_search + */ +function template_preprocess_views_view_row_search(&$vars) { + $vars['node'] = ''; // make sure var is defined. + $nid = $vars['row']->nid; + if (!is_numeric($nid)) { + return; + } + + $node = node_load($nid); + + if (empty($node)) { + return; + } + + // Build the node body. + $node = node_build_content($node, FALSE, FALSE); + $node->body = drupal_render($node->content); + + // Fetch comments for snippet + $node->body .= module_invoke('comment', 'nodeapi', $node, 'update index'); + + // Fetch terms for snippet + $node->body .= module_invoke('taxonomy', 'nodeapi', $node, 'update index'); + + $vars['url'] = url('node/' . $nid); + $vars['title'] = check_plain($node->title); + + $info = array(); + $info['type'] = node_type_get_name($node); + $info['user'] = theme('username', array('acccount' => $node)); + $info['date'] = format_date($node->changed, 'small'); + $extra = module_invoke_all('node_search_result', $node); + if (isset($extra) && is_array($extra)) { + $info = array_merge($info, $extra); + } + $vars['info_split'] = $info; + $vars['info'] = implode(' - ', $info); + + $vars['node'] = $node; + // @todo: get score from ??? +//$vars['score'] = $item->score; + $vars['snippet'] = search_excerpt($vars['view']->value, $node->body); +} + + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/search.views_convert.inc b/sites/all/modules/views/modules/search.views_convert.inc new file mode 100644 index 0000000000000000000000000000000000000000..ab1a1ccedbde0921a5f588c91332a05b4d54cf27 --- /dev/null +++ b/sites/all/modules/views/modules/search.views_convert.inc @@ -0,0 +1,24 @@ +<?php +// $Id: search.views_convert.inc,v 1.2.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * @file + * Field conversion for fields handled by this module. + */ + +function search_views_convert($display, $type, &$view, $field, $id = NULL) { + switch ($type) { + case 'filter': + switch ($field['tablename']) { + case 'temp_search_results': + switch ($field['field']) { + case 'word': + $view->set_item_option($display, 'filter', $id, 'table', 'search_index'); + $view->set_item_option($display, 'filter', $id, 'field', 'keys'); + break; + } + break; + } + break; + } +} diff --git a/sites/all/modules/views/modules/search.views_default.inc b/sites/all/modules/views/modules/search.views_default.inc new file mode 100644 index 0000000000000000000000000000000000000000..2bbfd522407007f6d385b9730137ee93eeb4b000 --- /dev/null +++ b/sites/all/modules/views/modules/search.views_default.inc @@ -0,0 +1,151 @@ +<?php +// $Id: search.views_default.inc,v 1.6.6.4 2011/01/05 23:14:39 dereine Exp $ +/** + * @file + * Contains default views on behalf of the search module. + */ + +/** + * Implements hook_views_default_views(). + */ +function search_views_default_views() { + $view = new view; + $view->name = 'backlinks'; + $view->description = 'Displays a list of nodes that link to the node, using the search backlinks table.'; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->api_version = 2; + $view->version = 7; + $view->disabled = TRUE; /* Edit this to true to make a default view disabled initially */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->override_option('fields', array( + 'title' => array( + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'label' => '', + 'relationship' => 'none', + 'link_to_node' => 1, + ), + )); + $handler->override_option('arguments', array( + 'nid' => array( + 'id' => 'nid', + 'table' => 'search_node_links_to', + 'field' => 'nid', + 'default_action' => 'not found', + 'style_plugin' => 'default_summary', + 'style_options' => array( + 'count' => TRUE, + 'override' => FALSE, + 'items_per_page' => 25, + ), + 'wildcard' => '', + 'wildcard_substitution' => '', + 'title' => 'Pages that link to %1', + 'default_argument_type' => 'fixed', + 'default_argument' => '', + 'validate_type' => 'node', + 'validate_fail' => 'not found', + 'relationship' => 'none', + 'default_argument_fixed' => '', + 'default_argument_php' => '', + 'validate_argument_node_type' => array(), + 'validate_argument_php' => '', + ), + )); + $handler->override_option('filters', array( + 'status' => array( + 'id' => 'status', + 'table' => 'node', + 'field' => 'status', + 'operator' => '=', + 'value' => 1, + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'relationship' => 'none', + ), + )); + $handler->override_option('access', array( + 'type' => 'none', + 'role' => array(), + 'perm' => '', + )); + $handler->override_option('empty', 'No backlinks found.'); + $handler->override_option('empty_format', '1'); + $handler->override_option('items_per_page', 30); + $handler->override_option('use_pager', '1'); + $handler->override_option('style_plugin', 'list'); + $handler->override_option('style_options', array( + 'type' => 'ol', + )); + $handler = $view->new_display('page', 'Page', 'page'); + $handler->override_option('path', 'node/%/backlinks'); + $handler->override_option('menu', array( + 'type' => 'tab', + 'title' => 'What links here', + 'weight' => '0', + )); + $handler->override_option('tab_options', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $handler = $view->new_display('block', 'Block', 'block'); + $handler->override_option('arguments', array( + 'nid' => array( + 'id' => 'nid', + 'table' => 'search_node_links_to', + 'field' => 'nid', + 'default_action' => 'default', + 'style_plugin' => 'default_summary', + 'style_options' => array( + 'count' => TRUE, + 'override' => FALSE, + 'items_per_page' => 25, + ), + 'wildcard' => '', + 'wildcard_substitution' => '', + 'title' => 'What links here', + 'default_argument_type' => 'node', + 'default_argument' => '', + 'validate_type' => 'node', + 'validate_fail' => 'not found', + 'relationship' => 'none', + 'default_argument_fixed' => '', + 'default_argument_php' => 'return ($node = menu_get_object()) ? $node->nid : FALSE;', + 'validate_argument_node_type' => array( + 'album' => 0, + 'artist' => 0, + 'book' => 0, + 'page' => 0, + 'story' => 0, + 'track' => 0, + ), + 'validate_argument_php' => '', + 'default_argument_user' => 0, + 'validate_argument_vocabulary' => array( + '3' => 0, + '4' => 0, + '1' => 0, + '5' => 0, + '2' => 0, + ), + 'validate_argument_type' => 'tid', + ), + )); + $handler->override_option('items_per_page', 6); + $handler->override_option('use_more', 1); + $handler->override_option('style_plugin', 'list'); + $handler->override_option('style_options', array( + 'type' => 'ul', + )); + $handler->override_option('block_description', 'What links here'); + $views[$view->name] = $view; + + return $views; +} diff --git a/sites/all/modules/views/modules/search/views_handler_argument_search.inc b/sites/all/modules/views/modules/search/views_handler_argument_search.inc new file mode 100644 index 0000000000000000000000000000000000000000..cf3f20a5f37609b3b0765b370efdaabc79e2d629 --- /dev/null +++ b/sites/all/modules/views/modules/search/views_handler_argument_search.inc @@ -0,0 +1,50 @@ +<?php +// $Id: views_handler_argument_search.inc,v 1.1.2.2 2010/01/24 22:37:52 dereine Exp $ + +/** + * Argument that accepts query keys for search. + */ +class views_handler_argument_search extends views_handler_argument { + + /** + * Add this argument to the query. + */ + function query() { + $this->search_query = search_parse_query($this->argument); + + if (!isset($this->search_query) || empty($this->search_query[3])) { + if ($this->operator == 'required') { + $this->query->add_where($this->options['group'], '0'); + } + } + else { + $search_index = $this->ensure_my_table(); + $this->search_query[2] = str_replace('i.', "$search_index.", $this->search_query[2]); + + // Create a new join to relate the 'search_total' table to our current 'search_index' table. + $join = new views_join; + $join->construct('search_total', $search_index, 'word', 'word'); + $search_total = $this->query->add_relationship('search_total', $join, $search_index); + + $this->search_score = $this->query->add_field('', "SUM($search_index.score * $search_total.count)", 'score', array('aggregate' => TRUE)); + + $this->query->add_where($this->options['group'], $this->search_query[2], $this->search_query[3]); + + if (empty($this->query->relationships[$this->relationship])) { + $base_table = $this->query->base_table; + } + else { + $base_table = $this->query->relationships[$this->relationship]['base']; + } + $this->query->add_where($this->options['group'], "$search_index.type = '%s'", $base_table); + if (!$this->search_query[5]) { + $search_dataset = $this->query->add_table('search_dataset'); + $this->search_query[0] = str_replace('d.', "$search_dataset.", $this->search_query[0]); + $this->query->add_where($this->options['group'], $this->search_query[0], $this->search_query[1]); + } + + $this->query->add_groupby("$search_index.sid"); + $this->query->add_having($this->options['group'], 'COUNT(*)', $this->search_query[4], '>='); + } + } +} diff --git a/sites/all/modules/views/modules/search/views_handler_field_search_score.inc b/sites/all/modules/views/modules/search/views_handler_field_search_score.inc new file mode 100644 index 0000000000000000000000000000000000000000..3f0b248533d0c34ef4faeacfd3085a3ea85e772d --- /dev/null +++ b/sites/all/modules/views/modules/search/views_handler_field_search_score.inc @@ -0,0 +1,76 @@ +<?php +// $Id: views_handler_field_search_score.inc,v 1.2.6.1 2010/12/09 21:31:10 merlinofchaos Exp $ + +/** + * Field handler to provide simple renderer that allows linking to a node. + */ +class views_handler_field_search_score extends views_handler_field_numeric { + function option_definition() { + $options = parent::option_definition(); + + $options['alternate_sort'] = array('default' => ''); + $options['alternate_order'] = array('default' => 'asc'); + + return $options; + } + + function options_form(&$form, &$form_state) { + $style_options = $this->view->display_handler->get_option('style_options'); + if (isset($style_options['default']) && $style_options['default'] == $this->options['id']) { + $handlers = $this->view->display_handler->get_handlers('field'); + $options = array('' => t('No alternate')); + foreach ($handlers as $id => $handler) { + $options[$id] = $handler->ui_name(); + } + + $form['alternate_sort'] = array( + '#type' => 'select', + '#title' => t('Alternative sort'), + '#description' => t('If no search is performed and this field does not appear, pick an alternative default table sort field.'), + '#options' => $options, + '#default_value' => $this->options['alternate_sort'], + ); + + $form['alternate_order'] = array( + '#type' => 'select', + '#title' => t('Alternate sort order'), + '#options' => array('asc' => t('Ascending'), 'desc' => t('Descending')), + '#default_value' => $this->options['alternate_order'], + ); + } + + parent::options_form($form, $form_state); + } + + function query() { + // Check to see if the search filter added 'score' to the table. + // Our filter stores it as $handler->search_score -- and we also + // need to check its relationship to make sure that we're using the same + // one or obviously this won't work. + foreach ($this->view->filter as $handler) { + if (isset($handler->search_score) && $handler->relationship == $this->relationship) { + $this->field_alias = $handler->search_score; + $this->table_alias = $handler->table_alias; + return; + } + } + + // Hide this field if no search filter is in place. + $this->options['exclude'] = TRUE; + if (!empty($this->options['alternate_sort'])) { + if (isset($this->view->style_plugin->options['default']) && $this->view->style_plugin->options['default'] == $this->options['id']) { + // Since the style handler initiates fields, we plug these values right into the active handler. + $this->view->style_plugin->options['default'] = $this->options['alternate_sort']; + $this->view->style_plugin->options['order'] = $this->options['alternate_order']; + } + } + } + + function render($values) { + // Only render if we exist. + if (isset($this->table_alias)) { + return parent::render($values); + } + } + +} diff --git a/sites/all/modules/views/modules/search/views_handler_filter_search.inc b/sites/all/modules/views/modules/search/views_handler_filter_search.inc new file mode 100644 index 0000000000000000000000000000000000000000..48ccb6ed93a0cbe241ffe8ff8e700c1a3ee314f1 --- /dev/null +++ b/sites/all/modules/views/modules/search/views_handler_filter_search.inc @@ -0,0 +1,113 @@ +<?php +// $Id: views_handler_filter_search.inc,v 1.5.6.2 2009/12/24 00:37:00 merlinofchaos Exp $ + +/** + * Field handler to provide simple renderer that allows linking to a node. + */ +class views_handler_filter_search extends views_handler_filter { + var $no_single = TRUE; + function option_definition() { + $options = parent::option_definition(); + + $options['operator']['default'] = 'optional'; + + return $options; + } + + /** + * Provide simple equality operator + */ + function operator_form(&$form, &$form_state) { + $form['operator'] = array( + '#type' => 'radios', + '#title' => t('On empty input'), + '#default_value' => $this->operator, + '#options' => array( + 'optional' => t('Show All'), + 'required' => t('Show None'), + ), + ); + } + + /** + * Provide a simple textfield for equality + */ + function exposed_form(&$form, &$form_state) { + if (isset($this->options['expose']['identifier'])) { + $key = $this->options['expose']['identifier']; + $form[$key] = array( + '#type' => 'textfield', + '#size' => 15, + '#default_value' => $this->value, + '#attributes' => array('title' => t('Enter the terms you wish to search for.')), + ); + } + } + + /** + * Validate the options form. + */ + function exposed_validate($form, &$form_state) { + if (!isset($this->options['expose']['identifier'])) { + return; + } + + $key = $this->options['expose']['identifier']; + if (!empty($form_state['values'][$key])) { + $this->search_query = search_parse_query($form_state['values'][$key]); + + if ($this->search_query[2] == '') { + form_set_error($key, t('You must include at least one positive keyword with @count characters or more.', array('@count' => variable_get('minimum_word_size', 3)))); + } + if ($this->search_query[6]) { + if ($this->search_query[6] == 'or') { + drupal_set_message(t('Search for either of the two terms with uppercase <strong>OR</strong>. For example, <strong>cats OR dogs</strong>.')); + } + } + } + } + + /** + * Add this filter to the query. + * + * Due to the nature of fapi, the value and the operator have an unintended + * level of indirection. You will find them in $this->operator + * and $this->value respectively. + */ + function query() { + if (!isset($this->search_query) || empty($this->search_query[3])) { + if ($this->operator == 'required') { + $this->query->add_where($this->options['group'], 'FALSE'); + } + } + else { + $search_index = $this->ensure_my_table(); + $this->search_query[2] = str_replace('i.', "$search_index.", $this->search_query[2]); + + // Create a new join to relate the 'serach_total' table to our current 'search_index' table. + $join = new views_join; + $join->construct('search_total', $search_index, 'word', 'word'); + $search_total = $this->query->add_relationship('search_total', $join, $search_index); + + $this->search_score = $this->query->add_field('', "SUM($search_index.score * $search_total.count)", 'score', array('aggregate' => TRUE)); + + $this->query->add_where($this->options['group'], $this->search_query[2], $this->search_query[3]); + + if (empty($this->query->relationships[$this->relationship])) { + $base_table = $this->query->base_table; + } + else { + $base_table = $this->query->relationships[$this->relationship]['base']; + } + $this->query->add_where($this->options['group'], "$search_index.type = '%s'", $base_table); + if (!$this->search_query[5]) { + $search_dataset = $this->query->add_table('search_dataset'); + $this->search_query[0] = str_replace('d.', "$search_dataset.", $this->search_query[0]); + $this->query->add_where($this->options['group'], $this->search_query[0], $this->search_query[1]); + } + + $this->query->add_groupby("$search_index.sid"); + $this->query->add_having($this->options['group'], 'COUNT(*)', $this->search_query[4], '>='); + } + } +} diff --git a/sites/all/modules/views/modules/search/views_handler_sort_search_score.inc b/sites/all/modules/views/modules/search/views_handler_sort_search_score.inc new file mode 100644 index 0000000000000000000000000000000000000000..48a938cae4040ccf55f60b8b17bd8a05958b6817 --- /dev/null +++ b/sites/all/modules/views/modules/search/views_handler_sort_search_score.inc @@ -0,0 +1,25 @@ +<?php +// $Id: views_handler_sort_search_score.inc,v 1.1 2009/02/23 22:19:47 merlinofchaos Exp $ + +/** + * Field handler to provide simple renderer that allows linking to a node. + */ +class views_handler_sort_search_score extends views_handler_sort { + function query() { + // Check to see if the search filter added 'score' to the table. + // Our filter stores it as $handler->search_score -- and we also + // need to check its relationship to make sure that we're using the same + // one or obviously this won't work. + foreach ($this->view->filter as $handler) { + if (isset($handler->search_score) && $handler->relationship == $this->relationship) { + $this->query->add_orderby(NULL, NULL, $this->options['order'], $handler->search_score); + $this->table_alias = $handler->table_alias; + return; + } + } + + // Do absolutely nothing if there is no filter in place; there is no reason to + // sort on the raw scores with this handler. + } +} + diff --git a/sites/all/modules/views/modules/search/views_plugin_row_search_view.inc b/sites/all/modules/views/modules/search/views_plugin_row_search_view.inc new file mode 100644 index 0000000000000000000000000000000000000000..6311676f66e8d66baf0861ff389511fad93a3007 --- /dev/null +++ b/sites/all/modules/views/modules/search/views_plugin_row_search_view.inc @@ -0,0 +1,39 @@ +<?php +// $Id: views_plugin_row_search_view.inc,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ +/** + * @file + * Contains the search row style plugin. + */ + +/** + * Plugin which performs a node_view on the resulting object. + */ +class views_plugin_row_search_view extends views_plugin_row { + function option_definition() { + $options = parent::option_definition(); + + $options['score'] = array('default' => TRUE); + + return $options; + } + + function options_form(&$form, &$form_state) { + $form['score'] = array( + '#type' => 'checkbox', + '#title' => t('Display score'), + '#default_value' => $this->options['score'], + ); + } + + /** + * Override the behavior of the render() function. + */ + function render($row) { + return theme($this->theme_functions(), + array( + 'view' => $this->view, + 'options' => $this->options, + 'row' => $row + )); + } +} diff --git a/sites/all/modules/views/modules/statistics.views.inc b/sites/all/modules/views/modules/statistics.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..5ee89ecb1b3fb1e39a00dfea65ec57aa26cb3835 --- /dev/null +++ b/sites/all/modules/views/modules/statistics.views.inc @@ -0,0 +1,251 @@ +<?php +// $Id: statistics.views.inc,v 1.9.6.3 2010/07/19 09:18:42 dereine Exp $ +/** + * @file + * Provide views data and handlers for statistics.module + */ + +/** + * @defgroup views_statistics_module statistics.module handlers + * + * Includes the ability to create views of just the statistics table. + * @{ + */ + +/** + * Implements hook_views_data() + */ +function statistics_views_data() { + // Basic table information. + + // ---------------------------------------------------------------- + // node_counter table + + $data['node_counter']['table']['group'] = t('Node statistics'); + + $data['node_counter']['table']['join'] = array( + // ...to the node table + 'node' => array( + 'left_field' => 'nid', + 'field' => 'nid', + ), + ); + + // totalcount + $data['node_counter']['totalcount'] = array( + 'title' => t('Total views'), + 'help' => t('The total number of times the node has been viewed.'), + + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // daycount + $data['node_counter']['daycount'] = array( + 'title' => t('Views today'), + 'help' => t('The total number of times the node has been viewed today.'), + + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // timestamp + $data['node_counter']['timestamp'] = array( + 'title' => t('Most recent view'), + 'help' => t('The most recent time the node has been viewed.'), + + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + + // ---------------------------------------------------------------- + // accesslog table + + $data['accesslog']['table']['group'] = t('Access log'); + + // Advertise this table as a possible base table + $data['accesslog']['table']['base'] = array( + 'field' => 'aid', + 'title' => t('Access log'), + 'help' => t('Stores site access information.'), + 'weight' => 10, + ); + + // For other base tables, explain how we join + $data['accesslog']['table']['join'] = array( + 'users' => array( + 'field' => 'uid', + 'left_field' => 'uid', + ), + ); + + // session id + $data['accesslog']['sid'] = array( + 'title' => t('Session ID'), + 'help' => t('Browser session ID of user that visited page.'), + + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // title + $data['accesslog']['title'] = array( + 'title' => t('Page title'), + 'help' => t('Title of page visited.'), + + 'field' => array( + 'handler' => 'views_handler_field_accesslog_path', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // path + $data['accesslog']['path'] = array( + 'title' => t('Path'), + 'help' => t('Internal path to page visited (relative to Drupal root.)'), + + 'field' => array( + 'handler' => 'views_handler_field_accesslog_path', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + //No argument here. Can't send forward slashes as arguments. + //Can be worked around by node ID. + //(but what about aliases?) + ); + + // referrer + $data['accesslog']['url'] = array( + 'title' => t('Referrer'), + 'help' => t('Referrer URI.'), + 'field' => array( + 'handler' => 'views_handler_field_url', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // hostname + $data['accesslog']['hostname'] = array( + 'title' => t('Hostname'), + 'help' => t('Hostname of user that visited the page.'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // user + $data['accesslog']['uid'] = array( + 'title' => t('User'), + 'help' => t('The user who visited the site.'), + 'relationship' => array( + 'handler' => 'views_handler_relationship', + 'base' => 'users', + 'base field' => 'uid', + ), + ); + + // timer + $data['accesslog']['timer'] = array( + 'title' => t('Timer'), + 'help' => t('Time in milliseconds that the page took to load.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // timestamp + $data['accesslog']['timestamp'] = array( + 'title' => t('Timestamp'), + 'help' => t('Timestamp of when the page was visited.'), + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + ); + + + return $data; +} + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/statistics.views_convert.inc b/sites/all/modules/views/modules/statistics.views_convert.inc new file mode 100644 index 0000000000000000000000000000000000000000..90785d99dd308e49ec5d2dce030f36ffd0a3e4be --- /dev/null +++ b/sites/all/modules/views/modules/statistics.views_convert.inc @@ -0,0 +1,52 @@ +<?php +// $Id: statistics.views_convert.inc,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * @file + * Field conversion for fields handled by this module. + */ + +/** + * Implements 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 statistics_views_convert($display, $type, &$view, $field, $id = NULL) { + switch ($type) { + case 'field': + switch ($field['tablename']) { + case 'node_counter': + switch ($field['field']) { + case 'timestamp': + $handlers = array( + 'views_handler_field_date_small' => 'small', + 'views_handler_field_date' => 'medium', + 'views_handler_field_date_large' => 'large', + 'views_handler_field_date_custom' => 'custom', + 'views_handler_field_since' => 'time ago', + ); + $view->set_item_option($display, 'field', $id, 'date_format', $handlers[$field['handler']]); + if (!empty($field['options'])) { + $view->set_item_option($display, 'field', $id, 'custom_date_format', $field['options']); + } + break; + } + break; + } + break; + case 'sort': + switch ($field['tablename']) { + case 'node_counter': + switch ($field['field']) { + case 'timestamp': + $field['options'] = $field['options'] == 'normal' ? 'second' : $field['options']; + $view->set_item_option($display, 'sort', $id, 'granularity', $field['options']); + break; + } + break; + } + break; + } +} diff --git a/sites/all/modules/views/modules/statistics.views_default.inc b/sites/all/modules/views/modules/statistics.views_default.inc new file mode 100644 index 0000000000000000000000000000000000000000..eb92fdea8883bdc0bf07234fdd55278f5ef7fcd5 --- /dev/null +++ b/sites/all/modules/views/modules/statistics.views_default.inc @@ -0,0 +1,304 @@ +<?php +// $Id: statistics.views_default.inc,v 1.5.6.5 2011/01/05 23:14:39 dereine Exp $ +/** + * @file + * Contains default views on behalf of the statistics module. + */ + +/** + * Implements hook_views_default_views(). + */ +function statistics_views_default_views() { + $view = new view; + $view->name = 'popular'; + $view->description = 'Shows the most-viewed nodes on the site. This requires the statistics to be enabled at administer >> reports >> access log settings.'; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->api_version = 2; + $view->version = 7; + $view->disabled = TRUE; /* Edit this to true to make a default view disabled initially */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->override_option('fields', array( + 'type' => array( + 'id' => 'type', + 'table' => 'node', + 'field' => 'type', + 'label' => 'Type', + ), + 'title' => array( + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'label' => 'Title', + 'link_to_node' => TRUE, + ), + 'name' => array( + 'id' => 'name', + 'table' => 'users', + 'field' => 'name', + 'label' => 'Author', + 'link_to_user' => TRUE, + ), + 'timestamp' => array( + 'id' => 'timestamp', + 'table' => 'history', + 'field' => 'timestamp', + 'label' => '', + 'comments' => 1, + 'relationship' => 'none', + 'link_to_node' => 0, + 'comment' => 1, + ), + )); + $handler->override_option('sorts', array( + 'totalcount' => array( + 'id' => 'totalcount', + 'table' => 'node_counter', + 'field' => 'totalcount', + 'order' => 'DESC', + 'relationship' => 'none', + ), + )); + $handler->override_option('filters', array( + 'status' => array( + 'id' => 'status', + 'table' => 'node', + 'field' => 'status', + 'operator' => '=', + 'value' => '1', + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + ), + 'totalcount' => array( + 'id' => 'totalcount', + 'table' => 'node_counter', + 'field' => 'totalcount', + 'operator' => '>', + 'value' => array( + 'value' => '0', + 'min' => '', + 'max' => '', + ), + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'relationship' => 'none', + ), + )); + $handler->override_option('access', array( + 'type' => 'none', + 'role' => array(), + 'perm' => '', + )); + $handler->override_option('title', 'Popular content'); + $handler->override_option('items_per_page', '25'); + $handler->override_option('use_pager', TRUE); + $handler->override_option('use_more', 1); + $handler->override_option('style_plugin', 'table'); + $handler->override_option('style_options', array( + 'override' => 0, + 'order' => 'desc', + 'columns' => array( + 'type' => 'type', + 'title' => 'title', + 'name' => 'name', + 'timestamp' => 'title', + 'totalcount' => 'totalcount', + ), + 'info' => array( + 'type' => array( + 'sortable' => 0, + 'separator' => '', + ), + 'title' => array( + 'sortable' => 0, + 'separator' => '', + ), + 'name' => array( + 'sortable' => 0, + 'separator' => '', + ), + 'timestamp' => array( + 'separator' => '', + ), + 'totalcount' => array( + 'sortable' => 0, + 'separator' => '', + ), + ), + 'default' => '-1', + )); + $handler = $view->new_display('page', 'Popular (page)', 'page'); + $handler->override_option('path', 'popular/all'); + $handler->override_option('menu', array( + 'type' => 'default tab', + 'title' => 'Popular content', + 'weight' => '-1', + )); + $handler->override_option('tab_options', array( + 'type' => 'normal', + 'title' => 'Popular content', + 'weight' => '', + )); + $handler = $view->new_display('page', 'Today (page)', 'page_1'); + $handler->override_option('fields', array( + 'type' => array( + 'id' => 'type', + 'table' => 'node', + 'field' => 'type', + 'label' => 'Type', + ), + 'title' => array( + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'label' => 'Title', + 'link_to_node' => TRUE, + ), + 'name' => array( + 'id' => 'name', + 'table' => 'users', + 'field' => 'name', + 'label' => 'Author', + 'link_to_user' => TRUE, + ), + 'timestamp' => array( + 'id' => 'timestamp', + 'table' => 'history', + 'field' => 'timestamp', + 'label' => '', + 'comments' => 1, + 'relationship' => 'none', + 'link_to_node' => 0, + 'comment' => 1, + ), + 'daycount' => array( + 'id' => 'daycount', + 'table' => 'node_counter', + 'field' => 'daycount', + 'label' => 'Views today', + 'set_precision' => FALSE, + 'precision' => 0, + 'decimal' => '.', + 'separator' => ',', + 'prefix' => '', + 'suffix' => '', + 'relationship' => 'none', + ), + )); + $handler->override_option('sorts', array( + 'daycount' => array( + 'id' => 'daycount', + 'table' => 'node_counter', + 'field' => 'daycount', + 'order' => 'DESC', + 'relationship' => 'none', + ), + )); + $handler->override_option('path', 'popular/today'); + $handler->override_option('menu', array( + 'type' => 'tab', + 'title' => 'Today\'s popular content', + 'weight' => '0', + )); + $handler->override_option('tab_options', array( + 'type' => 'normal', + 'title' => 'Popular content', + 'weight' => '0', + )); + $handler = $view->new_display('block', 'Popular (block)', 'block'); + $handler->override_option('fields', array( + 'title' => array( + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'label' => '', + 'link_to_node' => 1, + 'relationship' => 'none', + ), + 'totalcount' => array( + 'id' => 'totalcount', + 'table' => 'node_counter', + 'field' => 'totalcount', + 'label' => '', + 'set_precision' => FALSE, + 'precision' => 0, + 'decimal' => '.', + 'separator' => ',', + 'prefix' => ' (', + 'suffix' => ')', + 'relationship' => 'none', + ), + )); + $handler->override_option('items_per_page', 5); + $handler->override_option('style_plugin', 'list'); + $handler->override_option('style_options', array( + 'type' => 'ul', + )); + $handler->override_option('row_options', array( + 'inline' => array( + 'title' => 'title', + 'totalcount' => 'totalcount', + ), + 'separator' => '', + )); + $handler->override_option('block_description', 'Popular content'); + $handler = $view->new_display('block', 'Today (block)', 'block_1'); + $handler->override_option('fields', array( + 'title' => array( + 'id' => 'title', + 'table' => 'node', + 'field' => 'title', + 'label' => '', + 'link_to_node' => 1, + 'relationship' => 'none', + ), + 'daycount' => array( + 'id' => 'daycount', + 'table' => 'node_counter', + 'field' => 'daycount', + 'label' => '', + 'set_precision' => FALSE, + 'precision' => 0, + 'decimal' => '.', + 'separator' => ',', + 'prefix' => ' (', + 'suffix' => ')', + 'relationship' => 'none', + ), + )); + $handler->override_option('sorts', array( + 'daycount' => array( + 'id' => 'daycount', + 'table' => 'node_counter', + 'field' => 'daycount', + 'order' => 'DESC', + 'relationship' => 'none', + ), + )); + $handler->override_option('title', 'Today\'s popular content'); + $handler->override_option('items_per_page', 5); + $handler->override_option('link_display', 'page_1'); + $handler->override_option('style_plugin', 'list'); + $handler->override_option('style_options', array( + 'type' => 'ul', + )); + $handler->override_option('row_options', array( + 'inline' => array( + 'title' => 'title', + 'daycount' => 'daycount', + ), + 'separator' => '', + )); + $handler->override_option('block_description', 'Today\'s popular content'); + $views[$view->name] = $view; + + return $views; +} diff --git a/sites/all/modules/views/modules/statistics/views_handler_field_accesslog_path.inc b/sites/all/modules/views/modules/statistics/views_handler_field_accesslog_path.inc new file mode 100644 index 0000000000000000000000000000000000000000..8cf1b9d0aa46c28fea51593011137d21bbe13e38 --- /dev/null +++ b/sites/all/modules/views/modules/statistics/views_handler_field_accesslog_path.inc @@ -0,0 +1,50 @@ +<?php +// $Id: views_handler_field_accesslog_path.inc,v 1.1.6.1 2010/11/18 07:29:03 dereine Exp $ +/** + * Field handler to provide simple renderer that turns a URL into a clickable link. + */ +class views_handler_field_accesslog_path extends views_handler_field { + /** + * Override init function to provide generic option to link to node. + */ + function init(&$view, &$data) { + parent::init($view, $data); + if (isset($data['display_as_link'])) { + $this->additional_fields[] = 'path'; + } + } + + function option_definition() { + $options = parent::option_definition(); + + $options['display_as_link'] = array('default' => TRUE); + + return $options; + } + + /** + * Provide link to the page being visited. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['display_as_link'] = array( + '#title' => t('Display as link'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['display_as_link']), + ); + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->field_alias}), $values); + } + + function render_link($data, $values) { + if (!empty($this->options['display_as_link'])) { + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = $values->{$this->aliases['path']}; + $this->options['alter']['html'] = TRUE; + } + + return $data; + } +} diff --git a/sites/all/modules/views/modules/system.views.inc b/sites/all/modules/views/modules/system.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..7c5ba6d5c3372f6857c1678212a2bb46fbf22756 --- /dev/null +++ b/sites/all/modules/views/modules/system.views.inc @@ -0,0 +1,471 @@ +<?php +// $Id: system.views.inc,v 1.7.6.7 2010/10/16 09:06:51 dereine Exp $ +/** + * @file + * + * Provide views data and handlers for system tables that are not represented by + * their own module. + */ + +/** + * @defgroup views_system_module system.module handlers + * + * @{ + */ + +/** + * Implements hook_views_data() + */ +function system_views_data() { + $data = array(); + + // ---------------------------------------------------------------------- + // file_managed table + + $data['file_managed']['table']['group'] = t('File'); + + // Advertise this table as a possible base table + $data['file_managed']['table']['base'] = array( + 'field' => 'fid', + 'title' => t('File'), + 'help' => t("Files maintained by Drupal and various modules."), + ); + + // The file table does not inherently join to the node table, + // but may things (such as upload.module) can add relationships + // that allow file fields to be used. + + // For other base tables, explain how we join + $data['file_managed']['table']['join'] = array( + 'users' => array( + // direct join to the users table via 'uid' field. + 'left_field' => 'uid', + 'field' => 'uid', + ), + ); + + // fid + $data['file_managed']['fid'] = array( + 'title' => t('File ID'), + 'help' => t('The ID of the file.'), + 'field' => array( + 'handler' => 'views_handler_field_file', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_file_fid', + 'name field' => 'filename', // the field to display in the summary. + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // filename + $data['file_managed']['filename'] = array( + 'title' => t('Name'), + 'help' => t('The name of the file.'), + 'field' => array( + 'handler' => 'views_handler_field_file', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // uri + $data['file_managed']['uri'] = array( + 'title' => t('Path'), + 'help' => t('The path of the file.'), + 'field' => array( + 'handler' => 'views_handler_field_file_uri', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // filemime + $data['file_managed']['filemime'] = array( + 'title' => t('Mime type'), + 'help' => t('The mime type of the file.'), + 'field' => array( + 'handler' => 'views_handler_field_file_filemime', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // extension + $data['files']['extension'] = array( + 'title' => t('Extension'), + 'help' => t('The extension of the file.'), + 'real field' => 'filename', + 'field' => array( + 'handler' => 'views_handler_field_file_extension', + 'click sortable' => FALSE, + ), + ); + + // filesize + $data['file_managed']['filesize'] = array( + 'title' => t('Size'), + 'help' => t('The size of the file.'), + 'field' => array( + 'handler' => 'views_handler_field_file_size', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + ); + + // status + $data['file_managed']['status'] = array( + 'title' => t('Status'), + 'help' => t('The status of the file.'), + 'field' => array( + 'handler' => 'views_handler_field_file_status', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_file_status', + ), + ); + + // timestamp field + $data['file_managed']['timestamp'] = array( + 'title' => t('Upload date'), + 'help' => t('The date the file was uploaded.'), + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + ); + + // ---------------------------------------------------------------------- + // file_usage table + + $data['file_usage']['table']['group'] = t('File Usage'); + + // Provide field-type-things to several base tables; on the core files table ("file_managed") so + // that we can create relationships from files to entities, and then on each core entity type base + // table so that we can provide general relationships between entities and files. + $data['file_usage']['table']['join'] = array( + // Link ourself to the {file_managed} table so we can provide file->entity relationships. + 'file_managed' => array( + 'field' => 'fid', + 'left_field' => 'fid', + ), + // Link ourself to the {node} table so we can provide node->file relationships. + 'node' => array( + 'field' => 'id', + 'left_field' => 'nid', + 'extra' => array(array('table' => 'file_usage', 'field' => 'type', 'value' => 'node')), + ), + // Link ourself to the {users} table so we can provide user->file relationships. + 'users' => array( + 'field' => 'id', + 'left_field' => 'uid', + 'extra' => array(array('table' => 'file_usage', 'field' => 'type', 'value' => 'user')), + ), + // Link ourself to the {comment} table so we can provide comment->file relationships. + 'comment' => array( + 'field' => 'id', + 'left_field' => 'cid', + 'extra' => array(array('table' => 'file_usage', 'field' => 'type', 'value' => 'comment')), + ), + // Link ourself to the {taxonomy_term_data} table so we can provide taxonomy_term->file relationships. + 'taxonomy_term_data' => array( + 'field' => 'id', + 'left_field' => 'tid', + 'extra' => array(array('table' => 'file_usage', 'field' => 'type', 'value' => 'taxonomy_term')), + ), + // Link ourself to the {taxonomy_vocabulary} table so we can provide taxonomy_vocabulary->file relationships. + 'taxonomy_vocabulary' => array( + 'field' => 'id', + 'left_field' => 'vid', + 'extra' => array(array('table' => 'file_usage', 'field' => 'type', 'value' => 'taxonomy_vocabulary')), + ), + ); + + // Provide a relationship between the files table and each entity type, and between each entity + // type and the files table. Entity->file relationships are type-restricted in the joins + // declared above, and file->entity relationships are type-restricted in the relationship + // declarations below. + + // Relationships between files and nodes. + $data['file_usage']['file_to_node'] = array( + 'title' => t('Node'), + 'help' => t('A node that is associated with this file, usually because this file is in a field on the node.'), + // Only provide this field/relationship/etc. when the 'file_managed' base table is present. + 'skip base' => array('node', 'node_revision', 'users', 'comment', 'taxonomy_term_data', 'taxonomy_vocabulary'), + 'real field' => 'id', + 'relationship' => array( + 'title' => t('Node'), + 'label' => t('Node'), + 'base' => 'node', + 'base field' => 'nid', + 'relationship field' => 'id', + 'extra' => array(array('table' => 'file_usage', 'field' => 'type', 'operator' => '=', 'value' => 'node')), + ), + ); + $data['file_usage']['node_to_file'] = array( + 'title' => t('File'), + 'help' => t('A file that is associated with this node, usually because it is in a field on the node.'), + // Only provide this field/relationship/etc. when the 'node' base table is present. + 'skip base' => array('file_managed', 'users', 'comment', 'taxonomy_term_data', 'taxonomy_vocabulary'), + 'real field' => 'fid', + 'relationship' => array( + 'title' => t('File'), + 'label' => t('File'), + 'base' => 'file_managed', + 'base field' => 'fid', + 'relationship field' => 'fid', + ), + ); + + // Relationships between files and users. + $data['file_usage']['file_to_user'] = array( + 'title' => t('User'), + 'help' => t('A user that is associated with this file, usually because this file is in a field on the user.'), + // Only provide this field/relationship/etc. when the 'file_managed' base table is present. + 'skip base' => array('node', 'node_revision', 'users', 'comment', 'taxonomy_term_data', 'taxonomy_vocabulary'), + 'real field' => 'id', + 'relationship' => array( + 'title' => t('User'), + 'label' => t('User'), + 'base' => 'users', + 'base field' => 'uid', + 'relationship field' => 'id', + 'extra' => array(array('table' => 'file_usage', 'field' => 'type', 'operator' => '=', 'value' => 'user')), + ), + ); + $data['file_usage']['user_to_file'] = array( + 'title' => t('File'), + 'help' => t('A file that is associated with this user, usually because it is in a field on the user.'), + // Only provide this field/relationship/etc. when the 'users' base table is present. + 'skip base' => array('file_managed', 'node', 'node_revision', 'comment', 'taxonomy_term_data', 'taxonomy_vocabulary'), + 'real field' => 'fid', + 'relationship' => array( + 'title' => t('File'), + 'label' => t('File'), + 'base' => 'file_managed', + 'base field' => 'fid', + 'relationship field' => 'fid', + ), + ); + + // Relationships between files and comments. + $data['file_usage']['file_to_comment'] = array( + 'title' => t('Comment'), + 'help' => t('A comment that is associated with this file, usually because this file is in a field on the comment.'), + // Only provide this field/relationship/etc. when the 'file_managed' base table is present. + 'skip base' => array('node', 'node_revision', 'users', 'comment', 'taxonomy_term_data', 'taxonomy_vocabulary'), + 'real field' => 'id', + 'relationship' => array( + 'title' => t('Comment'), + 'label' => t('Comment'), + 'base' => 'comment', + 'base field' => 'cid', + 'relationship field' => 'id', + 'extra' => array(array('table' => 'file_usage', 'field' => 'type', 'operator' => '=', 'value' => 'comment')), + ), + ); + $data['file_usage']['comment_to_file'] = array( + 'title' => t('File'), + 'help' => t('A file that is associated with this comment, usually because it is in a field on the comment.'), + // Only provide this field/relationship/etc. when the 'comment' base table is present. + 'skip base' => array('file_managed', 'node', 'node_revision', 'users', 'taxonomy_term_data', 'taxonomy_vocabulary'), + 'real field' => 'fid', + 'relationship' => array( + 'title' => t('File'), + 'label' => t('File'), + 'base' => 'file_managed', + 'base field' => 'fid', + 'relationship field' => 'fid', + ), + ); + + // Relationships between files and taxonomy_terms. + $data['file_usage']['file_to_taxonomy_term'] = array( + 'title' => t('Taxonomy Term'), + 'help' => t('A taxonomy term that is associated with this file, usually because this file is in a field on the taxonomy term.'), + // Only provide this field/relationship/etc. when the 'file_managed' base table is present. + 'skip base' => array('node', 'node_revision', 'users', 'comment', 'taxonomy_term_data', 'taxonomy_vocabulary'), + 'real field' => 'id', + 'relationship' => array( + 'title' => t('Taxonomy Term'), + 'label' => t('Taxonomy Term'), + 'base' => 'taxonomy_term_data', + 'base field' => 'tid', + 'relationship field' => 'id', + 'extra' => array(array('table' => 'file_usage', 'field' => 'type', 'operator' => '=', 'value' => 'taxonomy_term')), + ), + ); + $data['file_usage']['taxonomy_term_to_file'] = array( + 'title' => t('File'), + 'help' => t('A file that is associated with this taxonomy term, usually because it is in a field on the taxonomy term.'), + // Only provide this field/relationship/etc. when the 'taxonomy_term_data' base table is present. + 'skip base' => array('file_managed', 'node', 'node_revision', 'users', 'comment', 'taxonomy_vocabulary'), + 'real field' => 'fid', + 'relationship' => array( + 'title' => t('File'), + 'label' => t('File'), + 'base' => 'file_managed', + 'base field' => 'fid', + 'relationship field' => 'fid', + ), + ); + + // Relationships between files and taxonomy_vocabulary items. + $data['file_usage']['file_to_taxonomy_vocabulary'] = array( + 'title' => t('Taxonomy Vocabulary'), + 'help' => t('A taxonomy vocabulary that is associated with this file, usually because this file is in a field on the taxonomy vocabulary.'), + // Only provide this field/relationship/etc. when the 'file_managed' base table is present. + 'skip base' => array('node', 'node_revision', 'users', 'comment', 'taxonomy_term_data', 'taxonomy_vocabulary'), + 'real field' => 'id', + 'relationship' => array( + 'title' => t('Taxonomy Vocabulary'), + 'label' => t('Taxonomy Vocabulary'), + 'base' => 'taxonomy_vocabulary', + 'base field' => 'vid', + 'relationship field' => 'id', + 'extra' => array(array('table' => 'file_usage', 'field' => 'type', 'operator' => '=', 'value' => 'taxonomy_vocabulary')), + ), + ); + $data['file_usage']['taxonomy_vocabulary_to_file'] = array( + 'title' => t('File'), + 'help' => t('A file that is associated with this taxonomy vocabulary, usually because it is in a field on the taxonomy vocabulary.'), + // Only provide this field/relationship/etc. when the 'taxonomy_vocabulary' base table is present. + 'skip base' => array('file_managed', 'node', 'node_revision', 'users', 'comment', 'taxonomy_term_data'), + 'real field' => 'fid', + 'relationship' => array( + 'title' => t('File'), + 'label' => t('File'), + 'base' => 'file_managed', + 'base field' => 'fid', + 'relationship field' => 'fid', + ), + ); + + // Provide basic fields from the {file_usage} table to all of the base tables we've declared + // joins to (because there is no 'skip base' property on these fields). + $data['file_usage']['module'] = array( + 'title' => t('Module'), + 'help' => t('The module managing this file relationship.'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + $data['file_usage']['type'] = array( + 'title' => t('Entity type'), + 'help' => t('The type of entity that is related to the file.'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + $data['file_usage']['count'] = array( + 'title' => t('Use count'), + 'help' => t('The number of times the file is used by this entity.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + return $data; +} + +function _views_file_status($choice = NULL) { + $status = array( + 0 => t('Temporary'), + FILE_STATUS_PERMANENT => t('Permanent'), + ); + + if (isset($choice)) { + return isset($status[$choice]) ? $status[$choice] : t('Unknown'); + } + + return $status; +} + + // uid field + $data['files']['uid'] = array( + 'title' => t('User'), + 'help' => t('The user, who uploaded the file.'), + 'relationship' => array( + 'base' => 'users', + 'base field' => 'uid', + 'handler' => 'views_handler_relationship', + 'label' => t('User'), + ), + ); + + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/system/views_handler_argument_file_fid.inc b/sites/all/modules/views/modules/system/views_handler_argument_file_fid.inc new file mode 100644 index 0000000000000000000000000000000000000000..91181e04ee3055a060e0eb8fec2f55ba6e35879b --- /dev/null +++ b/sites/all/modules/views/modules/system/views_handler_argument_file_fid.inc @@ -0,0 +1,22 @@ +<?php +// $Id: views_handler_argument_file_fid.inc,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ +/** + * Argument handler to accept a file id. + */ +class views_handler_argument_file_fid extends views_handler_argument { + /** + * Override the behavior of title(). Get the title of the file. + */ + function title() { + $title = db_select('files', 'f') + ->addField('f', 'filename') + ->condition('fid', $this->argument) + ->execute() + ->fetchField(); + if (empty($title)) { + return t('No title'); + } + + return check_plain($title); + } +} diff --git a/sites/all/modules/views/modules/system/views_handler_field_file.inc b/sites/all/modules/views/modules/system/views_handler_field_file.inc new file mode 100644 index 0000000000000000000000000000000000000000..8dddb4380c2b73d95ce0f8550d58aec40f35fbb5 --- /dev/null +++ b/sites/all/modules/views/modules/system/views_handler_field_file.inc @@ -0,0 +1,53 @@ +<?php +// $Id: views_handler_field_file.inc,v 1.3.6.3 2010/10/06 17:47:37 dereine Exp $ +/** + * Field handler to provide simple renderer that allows linking to a file. + */ +class views_handler_field_file extends views_handler_field { + /** + * Constructor to provide additional field to add. + */ + function init(&$view, &$options) { + parent::init($view, $options); + if (!empty($options['link_to_file'])) { + $this->additional_fields['uri'] = 'uri'; + } + } + + function option_definition() { + $options = parent::option_definition(); + $options['link_to_file'] = array('default' => FALSE); + return $options; + } + + /** + * Provide link to file option + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_to_file'] = array( + '#title' => t('Link this field to download the file'), + '#description' => t('This will override any other link you have set.'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['link_to_file']), + ); + } + + /** + * Render whatever the data is as a link to the file. + * + * Data should be made XSS safe prior to calling this function. + */ + function render_link($data, $values) { + if (!empty($this->options['link_to_file']) && $data !== NULL && $data !== '') { + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = file_create_url($values->{$this->aliases['uri']}); + } + + return $data; + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->field_alias}), $values); + } +} \ No newline at end of file diff --git a/sites/all/modules/views/modules/system/views_handler_field_file_extension.inc b/sites/all/modules/views/modules/system/views_handler_field_file_extension.inc new file mode 100644 index 0000000000000000000000000000000000000000..c5b7ae2e695fecea15e78ac08a6abb1c47c72baa --- /dev/null +++ b/sites/all/modules/views/modules/system/views_handler_field_file_extension.inc @@ -0,0 +1,15 @@ +<?php +// $Id: views_handler_field_file_extension.inc,v 1.1.4.2 2010/10/16 09:06:51 dereine Exp $ +/** + * @file + * Returns a pure file extension of the file, for example 'module'. + */ + +class views_handler_field_file_extension extends views_handler_field { + function render($values) { + $value = $values->{$this->field_alias}; + if (preg_match('/\.([^\.]+)$/', $value, $match)) { + return check_plain($match[1]); + } + } +} diff --git a/sites/all/modules/views/modules/system/views_handler_field_file_filemime.inc b/sites/all/modules/views/modules/system/views_handler_field_file_filemime.inc new file mode 100644 index 0000000000000000000000000000000000000000..1193d1b6231872f589a2eb9bf6b27829d62348d7 --- /dev/null +++ b/sites/all/modules/views/modules/system/views_handler_field_file_filemime.inc @@ -0,0 +1,32 @@ +<?php +// $Id: views_handler_field_file_filemime.inc,v 1.1.2.1 2010/10/06 17:47:37 dereine Exp $ + +/** + * Field handler to add rendering MIME type images as an option on the filemime field. + */ +class views_handler_field_file_filemime extends views_handler_field_file { + function option_definition() { + $options = parent::option_definition(); + $options['filemime_image'] = array('default' => FALSE); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['filemime_image'] = array( + '#title' => t('Display an image representing the MIME type instead of the MIME text.'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['filemime_image']), + ); + } + + function render($values) { + $data = $values->{$this->field_alias}; + if (!empty($this->options['filemime_image']) && $data !== NULL && $data !== '') { + $fake_file = (object) array('filemime' => $data); + $data = theme('file_icon', array('file' => $fake_file)); + } + + return $this->render_link($data, $values); + } +} \ No newline at end of file diff --git a/sites/all/modules/views/modules/system/views_handler_field_file_status.inc b/sites/all/modules/views/modules/system/views_handler_field_file_status.inc new file mode 100644 index 0000000000000000000000000000000000000000..9b89c0fae543cf2c9e06b889ce4e48ba9c185168 --- /dev/null +++ b/sites/all/modules/views/modules/system/views_handler_field_file_status.inc @@ -0,0 +1,11 @@ +<?php +// $Id: views_handler_field_file_status.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $ +/** + * Field handler to translate a node type into its readable form. + */ +class views_handler_field_file_status extends views_handler_field { + function render($values) { + return _views_file_status($values->{$this->field_alias}); + } +} + diff --git a/sites/all/modules/views/modules/system/views_handler_field_file_uri.inc b/sites/all/modules/views/modules/system/views_handler_field_file_uri.inc new file mode 100644 index 0000000000000000000000000000000000000000..2ec18a09fa3ecb3cb4a06e481242618d92dd7f0e --- /dev/null +++ b/sites/all/modules/views/modules/system/views_handler_field_file_uri.inc @@ -0,0 +1,31 @@ +<?php +// $Id: views_handler_field_file_uri.inc,v 1.1.2.1 2010/10/06 17:47:37 dereine Exp $ + +/** + * Field handler to add rendering file paths as file URLs instead of as internal file URIs. + */ +class views_handler_field_file_uri extends views_handler_field_file { + function option_definition() { + $options = parent::option_definition(); + $options['file_download_path'] = array('default' => FALSE); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['file_download_path'] = array( + '#title' => t('Display download path instead of file storage URI'), + '#description' => t('This will provide the full download URL rather than the internal filestream address.'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['file_download_path']), + ); + } + + function render($values) { + $data = $values->{$this->field_alias}; + if (!empty($this->options['file_download_path']) && $data !== NULL && $data !== '') { + $data = file_create_url($data); + } + return $this->render_link($data, $values); + } +} diff --git a/sites/all/modules/views/modules/system/views_handler_filter_file_status.inc b/sites/all/modules/views/modules/system/views_handler_filter_file_status.inc new file mode 100644 index 0000000000000000000000000000000000000000..9a80d90dcca20690dac59de2a4cd4f4d764136c7 --- /dev/null +++ b/sites/all/modules/views/modules/system/views_handler_filter_file_status.inc @@ -0,0 +1,13 @@ +<?php +// $Id: views_handler_filter_file_status.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $ +/** + * Filter by file status + */ +class views_handler_filter_file_status extends views_handler_filter_in_operator { + function get_value_options() { + if (!isset($this->value_options)) { + $this->value_options = _views_file_status(); + } + } +} + diff --git a/sites/all/modules/views/modules/taxonomy.views.inc b/sites/all/modules/views/modules/taxonomy.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..98ded4a4516aa82c84122df771da613087d4ce44 --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy.views.inc @@ -0,0 +1,444 @@ +<?php +// $Id: taxonomy.views.inc,v 1.57.4.18 2010/12/04 07:46:13 dereine Exp $ +/** + * @file + * + * Provide views data and handlers for taxonomy.module + */ + +/** + * @defgroup views_taxonomy_module taxonomy.module handlers + * + * @{ + */ + +/** + * Implements hook_views_data() + */ +function taxonomy_views_data() { + $data = array(); + + // ---------------------------------------------------------------------- + // taxonomy_vocabulary table + + $data['taxonomy_vocabulary']['table']['group'] = t('Taxonomy'); + + $data['taxonomy_vocabulary']['table']['join'] = array( + // vocabulary links to taxonomy_term_data directly via vid. + 'taxonomy_term_data' => array( + 'left_field' => 'vid', + 'field' => 'vid', + ), + // vocabulary links to node through taxonomy_term_data via vid + 'node' => array( + 'left_table' => 'taxonomy_term_data', + 'left_field' => 'vid', + 'field' => 'vid', + ), + ); + + // vocabulary name + $data['taxonomy_vocabulary']['name'] = array( + 'title' => t('Vocabulary name'), // The item it appears as on the UI, + 'field' => array( + 'help' => t('Name of the vocabulary a term is a member of. This will be the vocabulary that whichever term the "Taxonomy: Term" field is; and can similarly cause duplicates.'), + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + 'help' => t('The taxonomy vocabulary name'), + ), + ); + $data['taxonomy_vocabulary']['machine_name'] = array( + 'title' => t('Vocabulary machine name'), // The item it appears as on the UI, + 'field' => array( + 'help' => t('Machine-Name of the vocabulary a term is a member of. This will be the vocabulary that whichever term the "Taxonomy: Term" field is; and can similarly cause duplicates.'), + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'help' => t('Filter the results of "Taxonomy: Term" to a particular vocabulary.'), + 'handler' => 'views_handler_filter_vocabulary_machine_name', + ), + ); + $data['taxonomy_vocabulary']['vid'] = array( + 'title' => t('Vocabulary ID'), // The item it appears as on the UI, + 'help' => t('The taxonomy vocabulary ID'), + 'argument' => array( + 'handler' => 'views_handler_argument_vocabulary_vid', + 'name field' => 'name', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // ---------------------------------------------------------------------- + // taxonomy_term_data table + + $data['taxonomy_term_data']['table']['group'] = t('Taxonomy'); + $data['taxonomy_term_data']['table']['base'] = array( + 'field' => 'tid', + 'title' => t('Term'), + 'help' => t('Taxonomy terms are attached to nodes.'), + 'access query tag' => 'term_access', + ); + + + // The term data table + $data['taxonomy_term_data']['table']['join'] = array( + 'node' => array( + 'left_table' => 'taxonomy_index', + 'left_field' => 'tid', + 'field' => 'tid', + ), + 'taxonomy_vocabulary' => array( + 'field' => 'vid', + 'left_field' => 'vid', + ), + // This is provided for many_to_one argument + 'taxonomy_index' => array( + 'field' => 'tid', + 'left_field' => 'tid', + ), + ); + + // tid field + $data['taxonomy_term_data']['tid'] = array( + 'title' => t('Term ID'), + 'help' => t('The taxonomy term ID'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + 'name field' => 'name', + 'skip base' => array('node'), + 'zero is null' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_term_node_tid', + 'hierarchy table' => 'taxonomy_term_hierarchy', + 'numeric' => TRUE, + 'skip base' => array('node'), + ), + ); + + // Term name field + $data['taxonomy_term_data']['name'] = array( + 'title' => t('Term'), + 'help' => t('Taxonomy terms. Note that using this can cause duplicate nodes to appear in views; you must add filters to reduce the result set.'), + 'field' => array( + 'handler' => 'views_handler_field_taxonomy', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + 'help' => t('Taxonomy term name.'), + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + 'help' => t('Taxonomy term name.'), + 'many to one' => TRUE, + 'empty field name' => t('Uncategorized'), + ), + ); + + // taxonomy weight + $data['taxonomy_term_data']['weight'] = array( + 'title' => t('Weight'), + 'help' => t('The term weight field'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // Term description + $data['taxonomy_term_data']['description'] = array( + 'title' => t('Term description'), // The item it appears as on the UI, + 'help' => t('The description associated with a taxonomy term.'), + 'field' => array( + 'field' => 'description', // the real field + 'group' => t('Taxonomy'), // The group it appears in on the UI, + 'handler' => 'views_handler_field_markup', + 'format' => array('field' => 'format'), + ), + ); + + // Term vocabulary + $data['taxonomy_term_data']['vid'] = array( + 'title' => t('Vocabulary'), + 'help' => t('Filter the results of "Taxonomy: Term" to a particular vocabulary.'), + 'filter' => array( + 'handler' => 'views_handler_filter_vocabulary_vid', + ), + ); + + // Link to edit the term + $data['taxonomy_term_data']['edit_term'] = array( + 'field' => array( + 'title' => t('Term edit link'), + 'help' => t('Provide a simple link to edit the term.'), + 'handler' => 'views_handler_field_term_link_edit', + ), + ); + + // ---------------------------------------------------------------------- + // taxonomy_index table + + $data['taxonomy_index']['table']['group'] = t('Taxonomy'); + + $data['taxonomy_index']['table']['join'] = array( + 'taxonomy_term_data' => array( + // links directly to taxonomy_term_data via tid + 'left_field' => 'tid', + 'field' => 'tid', + ), + 'node' => array( + // links directly to node via vid + 'left_field' => 'nid', + 'field' => 'nid', + ), + 'taxonomy_term_hierarchy' => array( + 'left_field' => 'tid', + 'field' => 'tid', + ), + ); + + $data['taxonomy_index']['nid'] = array( + 'title' => t('Node'), + 'help' => t('Get all nodes tagged with a term.'), + 'relationship' => array( + 'handler' => 'views_handler_relationship', + 'base' => 'node', + 'base field' => 'nid', + 'label' => t('node'), + ), + ); + + // tid field + $data['taxonomy_index']['tid'] = array( + 'title' => t('Term ID'), + 'help' => t('The taxonomy term ID'), + 'field' => array( + 'title' => t('All terms'), + 'help' => t('Display all taxonomy terms associated with a node from specified vocabularies.'), + 'handler' => 'views_handler_field_term_node_tid', + 'skip base' => 'taxonomy_term_data', + 'no group by' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_term_node_tid', + 'name table' => 'taxonomy_term_data', + 'name field' => 'name', + 'empty field name' => t('Uncategorized'), + 'numeric' => TRUE, + 'skip base' => 'taxonomy_term_data', + ), + 'filter' => array( + 'title' => t('Term'), + 'handler' => 'views_handler_filter_term_node_tid', + 'hierarchy table' => 'taxonomy_term_hierarchy', + 'numeric' => TRUE, + 'skip base' => 'taxonomy_term_data', + 'allow empty' => TRUE, + ), + ); + + // ---------------------------------------------------------------------- + // term_hierarchy table + + $data['taxonomy_term_hierarchy']['table']['group'] = t('Taxonomy'); + + $data['taxonomy_term_hierarchy']['table']['join'] = array( + 'taxonomy_term_hierarchy' => array( + // links to self through left.parent = right.tid (going down in depth) + 'left_field' => 'tid', + 'field' => 'parent', + ), + 'taxonomy_term_data' => array( + // links directly to taxonomy_term_data via tid + 'left_field' => 'tid', + 'field' => 'tid', + ), + 'node' => array( + // links to node thorugh taxonomy_term_data + 'left_table' => 'taxonomy_term_data', + 'left_field' => 'tid', + 'field' => 'tid', + ), + ); + + $data['taxonomy_term_hierarchy']['parent'] = array( + 'title' => t('Parent term'), + 'help' => t('The parent term of the term. This can produce duplicate entries if you are using a vocabulary that allows multiple parents.'), + 'relationship' => array( + 'base' => 'taxonomy_term_data', + 'field' => 'parent', + 'label' => t('Parent'), + ), + 'argument' => array( + 'help' => t('The parent term of the term.'), + 'handler' => 'views_handler_argument_numeric', + ), + ); + + // ---------------------------------------------------------------------- + // term_synonym table + + $data['term_synonym']['table']['group'] = t('Taxonomy'); + + $data['term_synonym']['table']['join'] = array( + 'taxonomy_term_data' => array( + // links directly to taxonomy_term_data via tid + 'left_field' => 'tid', + 'field' => 'tid', + ), + 'node' => array( + 'left_table' => 'taxonomy_index', + 'left_field' => 'tid', + 'field' => 'tid', + ), + ); + + $data['term_synonym']['name'] = array( + 'title' => t('Term synonym'), + 'help' => t('Term synonyms may be used to find terms by alternate names.'), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + 'many to one' => TRUE, + 'empty field name' => t('Uncategorized'), + ), + ); + return $data; +} + +/** + * Implements hook_views_data_alter(). + */ +function taxonomy_views_data_alter(&$data) { + $data['node']['term_node_tid'] = array( + 'group' => t('Taxonomy'), + 'title' => t('Related terms'), + 'help' => t('Relate nodes to taxonomy terms, specifiying which vocabulary or vocabularies to use. This relationship will cause duplicated records if there are multiple terms.'), + 'relationship' => array( + 'handler' => 'views_handler_relationship_node_term_data', + 'label' => t('term'), + 'base' => 'taxonomy_term_data', + ), + ); + + $data['node']['term_node_tid_depth'] = array( + 'group' => t('Taxonomy'), + 'title' => t('Term ID (with depth)'), + 'help' => t('The depth filter is more complex, so provides fewer options.'), + 'real field' => 'nid', + 'argument' => array( + 'handler' => 'views_handler_argument_term_node_tid_depth', + 'accept depth modifier' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_term_node_tid_depth', + ), + ); + + $data['node']['term_node_tid_depth_modifier'] = array( + 'group' => t('Taxonomy'), + 'title' => t('Term ID depth modifier'), + 'help' => t('Allows the "depth" for Taxonomy: Term ID (with depth) to be modified via an additional argument.'), + 'argument' => array( + 'handler' => 'views_handler_argument_term_node_tid_depth_modifier', + ), + ); +} + +/** + * Implements hook_field_views_data(). + * + * Views integration for taxonomy_term_reference fields. Adds a term relationship to the default + * field data. + * + * @see field_views_field_default_views_data() + */ +function taxonomy_field_views_data($field) { + $data = field_views_field_default_views_data($field); + foreach ($data as $table_name => $table_data) { + foreach ($table_data as $field_name => $field_data) { + if (!in_array($field_name, array('table', 'entity_id', 'revision_id'))) { + $data[$table_name][$field_name]['relationship'] = array( + 'handler' => 'views_handler_relationship', + 'base' => 'taxonomy_term_data', + 'base field' => 'tid', + 'label' => t('term from !field_name', array('!field_name' => $field['field_name'])), + ); + } + } + } + return $data; +} + +/** + * Implements hook_views_plugins + */ +function taxonomy_views_plugins() { + return array( + 'module' => 'views', // This just tells our themes are elsewhere. + 'argument validator' => array( + 'taxonomy_term' => array( + 'title' => t('Taxonomy term'), + 'handler' => 'views_plugin_argument_validate_taxonomy_term', + 'path' => drupal_get_path('module', 'views') . '/modules/taxonomy', // not necessary for most modules + ), + ), + 'argument default' => array( + 'taxonomy_tid' => array( + 'title' => t('Taxonomy Term ID from URL'), + 'handler' => 'views_plugin_argument_default_taxonomy_tid', + 'path' => drupal_get_path('module', 'views') . '/modules/taxonomy', + 'parent' => 'fixed', + ), + ), + ); +} + +/** + * Helper function to set a breadcrumb for taxonomy. + */ +function views_taxonomy_set_breadcrumb(&$breadcrumb, &$argument) { + if (empty($argument->options['set_breadcrumb'])) { + return; + } + + $args = $argument->view->args; + $parents = taxonomy_get_parents_all($argument->argument); + foreach (array_reverse($parents) as $parent) { + // Unfortunately parents includes the current argument. Skip. + if ($parent->tid == $argument->argument) { + continue; + } + if ($argument->options['use_taxonomy_term_path']) { + $path = taxonomy_term_path($parent); + } + else { + $args[$argument->position] = $parent->tid; + $path = $argument->view->get_url($args); + } + $breadcrumb[$path] = check_plain($parent->name); + } +} + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/taxonomy.views_convert.inc b/sites/all/modules/views/modules/taxonomy.views_convert.inc new file mode 100644 index 0000000000000000000000000000000000000000..0fe5efa3e9b240796a243d164121907b8af7f99b --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy.views_convert.inc @@ -0,0 +1,95 @@ +<?php +//$Id: taxonomy.views_convert.inc,v 1.4.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * @file + * Field conversion for fields handled by this module. + */ + +/** + * Implements 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 taxonomy_views_convert($display, $type, &$view, $field, $id = NULL) { + switch ($type) { + case 'field': + if ($field['tablename'] == 'term_node' || !strncmp($field['tablename'], 'term_node_', 10)) { + switch ($field['field']) { + case 'name': + $item = $view->get_item($display, 'field', $id); + if ($field['options'] != 'nolink') { + $item['link_to_taxonomy'] = TRUE; + } + if (!empty($field['vocabulary'])) { + $item['limit'] = TRUE; + $item['vids'] = array($field['vocabulary']); + } + $view->set_item($display, 'field', $id, $item); + break; + } + } + elseif ($field['tablename'] == 'term_data') { + switch ($field['field']) { + case 'name': + if ($field['field'] == 'views_handler_field_tid_link') { + $view->set_item_option($display, 'field', $id, 'link_to_taxonomy', TRUE); + } + break; + } + } + break; + case 'filter': + if ($field['tablename'] == 'term_node' || !strncmp($field['tablename'], 'term_node_', 10)) { + switch ($field['field']) { + case 'tid': + $operators = array('AND' => 'and', 'OR' => 'or', 'NOR' => 'not'); + $item = $view->get_item($display, 'filter', $id); + if ($vid = (integer) substr($field['tablename'], 10)) { + $item['table'] = 'term_node'; + $item['vid'] = $vid; + } + else { + $item['limit'] = FALSE; + } + $item['operator'] = $operators[$field['operator']]; + $item['type'] = 'select'; + $view->set_item($display, 'filter', $id, $item); + break; + } + } + elseif ($field['tablename'] == 'term_data') { + switch ($field['field']) { + case 'vid': + $operators = array('AND' => 'IN', 'OR' => 'IN', 'NOR' => 'NOT IN'); + $view->set_item_option($display, 'filter', $id, 'operator', $operators[$field['operator']]); + break; + } + } + break; + case 'argument': + $options = $field['argoptions']; + switch ($field['type']) { + case 'taxid': + if (!empty($field['options'])) { + $options['depth'] = $field['options']; + } + $options['break_phrase'] = TRUE; + $view->add_item($display, 'argument', 'node', 'term_node_tid_depth', $options, $field['id']); + break; + case 'taxletter': + if (!empty($field['options'])) { + $options['glossary'] = TRUE; + $options['limit'] = $field['options']; + } + $view->add_item($display, 'argument', 'term_data', 'name', $options, $field['id']); + break; + case 'vocid': + $view->add_item($display, 'argument', 'vocabulary', 'vid', $options, $field['id']); + break; + } + break; + } +} diff --git a/sites/all/modules/views/modules/taxonomy.views_default.inc b/sites/all/modules/views/modules/taxonomy.views_default.inc new file mode 100644 index 0000000000000000000000000000000000000000..cb8049d8d20b18908520ffe5d8b691f3ca729b95 --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy.views_default.inc @@ -0,0 +1,184 @@ +<?php +// $Id: taxonomy.views_default.inc,v 1.3.6.4 2011/01/05 23:14:39 dereine Exp $ +/** + * @file + * Contains default views on behalf of the statistics module. + */ + +/** + * Implements hook_views_default_views(). + */ +function taxonomy_views_default_views() { + $view = new view; + $view->name = 'taxonomy_term'; + $view->description = 'A view to emulate Drupal core\'s handling of taxonomy/term; it also emulates Views 1\'s handling by having two possible feeds.'; + $view->tag = 'default'; + $view->base_table = 'node'; + $view->api_version = 2; + $view->version = 7; + $view->disabled = TRUE; /* Edit this to true to make a default view disabled initially */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->override_option('sorts', array( + 'sticky' => array( + 'id' => 'sticky', + 'table' => 'node', + 'field' => 'sticky', + 'order' => 'DESC', + 'relationship' => 'none', + ), + 'created' => array( + 'id' => 'created', + 'table' => 'node', + 'field' => 'created', + 'order' => 'DESC', + 'granularity' => 'second', + 'relationship' => 'none', + ), + )); + $handler->override_option('arguments', array( + 'term_node_tid_depth' => array( + 'id' => 'term_node_tid_depth', + 'table' => 'node', + 'field' => 'term_node_tid_depth', + 'default_action' => 'not found', + 'style_plugin' => 'default_summary', + 'style_options' => array( + 'count' => TRUE, + 'override' => FALSE, + 'items_per_page' => 25, + ), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => '%1', + 'default_argument_type' => 'fixed', + 'default_argument' => '', + 'validate_type' => 'taxonomy_term', + 'validate_fail' => 'not found', + 'depth' => '0', + 'break_phrase' => 1, + 'relationship' => 'none', + 'default_argument_fixed' => '', + 'default_argument_php' => '', + 'validate_argument_node_type' => array( + 'album' => 0, + 'artist' => 0, + 'book' => 0, + 'page' => 0, + 'story' => 0, + 'track' => 0, + ), + 'validate_argument_vocabulary' => array( + '3' => 0, + '4' => 0, + '1' => 0, + '5' => 0, + '2' => 0, + ), + 'validate_argument_type' => 'tids', + 'validate_argument_php' => '', + ), + 'term_node_tid_depth_modifier' => array( + 'id' => 'term_node_tid_depth_modifier', + 'table' => 'node', + 'field' => 'term_node_tid_depth_modifier', + 'default_action' => 'ignore', + 'style_plugin' => 'default_summary', + 'style_options' => array( + 'count' => TRUE, + 'override' => FALSE, + 'items_per_page' => 25, + ), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => '', + 'default_argument_type' => 'fixed', + 'default_argument' => '', + 'validate_type' => 'none', + 'validate_fail' => 'not found', + ), + )); + $handler->override_option('filters', array( + 'status_extra' => array( + 'id' => 'status_extra', + 'table' => 'node', + 'field' => 'status_extra', + 'operator' => '=', + 'value' => '', + 'group' => 0, + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'relationship' => 'none', + ), + )); + $handler->override_option('access', array( + 'type' => 'none', + 'role' => array(), + 'perm' => '', + )); + $handler->override_option('use_pager', '1'); + $handler->override_option('row_plugin', 'node'); + $handler->override_option('row_options', array( + 'teaser' => TRUE, + 'links' => TRUE, + )); + $handler = $view->new_display('page', 'Page', 'page'); + $handler->override_option('path', 'taxonomy/term/%'); + $handler->override_option('menu', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $handler->override_option('tab_options', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $handler = $view->new_display('feed', 'Core feed', 'feed'); + $handler->override_option('items_per_page', 15); + $handler->override_option('use_pager', '1'); + $handler->override_option('row_plugin', 'node_rss'); + $handler->override_option('row_options', array( + 'item_length' => 'default', + )); + $handler->override_option('path', 'taxonomy/term/%/%/feed'); + $handler->override_option('menu', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $handler->override_option('tab_options', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $handler->override_option('displays', array( + 'page' => 'page', + 'default' => 0, + )); + $handler = $view->new_display('feed', 'Views 1 feed', 'feed_1'); + $handler->override_option('items_per_page', 15); + $handler->override_option('use_pager', '1'); + $handler->override_option('row_plugin', 'node_rss'); + $handler->override_option('row_options', array( + 'item_length' => 'default', + )); + $handler->override_option('path', 'taxonomy/term/%/feed'); + $handler->override_option('menu', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $handler->override_option('tab_options', array( + 'type' => 'none', + 'title' => '', + 'weight' => 0, + )); + $views[$view->name] = $view; + + return $views; +} + + diff --git a/sites/all/modules/views/modules/taxonomy/views_handler_argument_taxonomy.inc b/sites/all/modules/views/modules/taxonomy/views_handler_argument_taxonomy.inc new file mode 100644 index 0000000000000000000000000000000000000000..9fd0ae00895cfaede0e91937306ede53ff598d9e --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_handler_argument_taxonomy.inc @@ -0,0 +1,20 @@ +<?php +// $Id: views_handler_argument_taxonomy.inc,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * Argument handler for basic taxonomy tid. + */ +class views_handler_argument_taxonomy extends views_handler_argument { + + /** + * Override the behavior of title(). Get the title of the node. + */ + function title() { + $term = taxonomy_term_load($this->argument); + if (!empty($term)) { + return check_plain($term->name); + } + // TODO review text + return t('No name'); + } +} diff --git a/sites/all/modules/views/modules/taxonomy/views_handler_argument_term_node_tid.inc b/sites/all/modules/views/modules/taxonomy/views_handler_argument_term_node_tid.inc new file mode 100644 index 0000000000000000000000000000000000000000..c3c7c9aeff82273cd663d02a6b3f108d58fa57bf --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_handler_argument_term_node_tid.inc @@ -0,0 +1,42 @@ +<?php +// $Id: views_handler_argument_term_node_tid.inc,v 1.1.6.5 2010/10/27 05:12:52 dereine Exp $ +/** + * Allow taxonomy term ID(s) as argument + */ +class views_handler_argument_term_node_tid extends views_handler_argument_many_to_one { + function option_definition() { + $options = parent::option_definition(); + $options['set_breadcrumb'] = array('default' => FALSE); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['set_breadcrumb'] = array( + '#type' => 'checkbox', + '#title' => t("Set the breadcrumb for the term parents"), + '#description' => t('If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received.'), + '#default_value' => !empty($this->options['set_breadcrumb']), + ); + } + + function set_breadcrumb(&$breadcrumb) { + if (empty($this->options['set_breadcrumb']) || !is_numeric($this->argument)) { + return; + } + + return views_taxonomy_set_breadcrumb($breadcrumb, $this); + } + + function title_query() { + $titles = array(); + $result = db_select('taxonomy_term_data', 'td') + ->fields('td', array('name')) + ->condition('td.tid', $this->value) + ->execute(); + foreach ($result as $term) { + $titles[] = check_plain($term->name); + } + return $titles; + } +} diff --git a/sites/all/modules/views/modules/taxonomy/views_handler_argument_term_node_tid_depth.inc b/sites/all/modules/views/modules/taxonomy/views_handler_argument_term_node_tid_depth.inc new file mode 100644 index 0000000000000000000000000000000000000000..5d1922fd1459cc9e5ecb14134061270f19c71ea5 --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_handler_argument_term_node_tid_depth.inc @@ -0,0 +1,137 @@ +<?php +// $Id: views_handler_argument_term_node_tid_depth.inc,v 1.3.4.7 2010/11/27 20:53:28 dereine Exp $ +/** + * Argument handler for taxonomy terms with depth. + * + * This handler is actually part of the node table and has some restrictions, + * because it uses a subquery to find nodes with + */ +class views_handler_argument_term_node_tid_depth extends views_handler_argument { + function option_definition() { + $options = parent::option_definition(); + + $options['depth'] = array('default' => 0); + $options['break_phrase'] = array('default' => FALSE); + $options['set_breadcrumb'] = array('default' => FALSE); + $options['use_taxonomy_term_path'] = array('default' => FALSE); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['depth'] = array( + '#type' => 'weight', + '#title' => t('Depth'), + '#default_value' => $this->options['depth'], + '#description' => t('The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term "fruit" and a child term "apple", with a depth of 1 (or higher) then filtering for the term "fruit" will get nodes that are tagged with "apple" as well as "fruit". If negative, the reverse is true; searching for "apple" will also pick up nodes tagged with "fruit" if depth is -1 (or lower).'), + ); + + $form['break_phrase'] = array( + '#type' => 'checkbox', + '#title' => t('Allow multiple terms per argument'), + '#description' => t('If selected, users can enter multiple arguments in the form of 1+2+3. Due to the number of JOINs it would require, AND will be treated as OR with this argument.'), + '#default_value' => !empty($this->options['break_phrase']), + ); + + $form['set_breadcrumb'] = array( + '#type' => 'checkbox', + '#title' => t("Set the breadcrumb for the term parents"), + '#description' => t('If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received.'), + '#default_value' => !empty($this->options['set_breadcrumb']), + ); + + $form['use_taxonomy_term_path'] = array( + '#type' => 'checkbox', + '#title' => t("Use Drupal's taxonomy term path to create breadcrumb links"), + '#description' => t('If selected, the links in the breadcrumb trail will be created using the standard drupal method instead of the custom views method. This is useful if you are using modules like taxonomy redirect to modify your taxonomy term links.'), + '#default_value' => !empty($this->options['use_taxonomy_term_path']), + '#process' => array('form_process_checkbox', 'ctools_dependent_process'), + '#dependency' => array('edit-options-set-breadcrumb' => array(TRUE)), + ); + } + + function set_breadcrumb(&$breadcrumb) { + if (empty($this->options['set_breadcrumb']) || !is_numeric($this->argument)) { + return; + } + + return views_taxonomy_set_breadcrumb($breadcrumb, $this); + } + + /** + * Override default_actions() to remove summary actions. + */ + function default_actions($which = NULL) { + if ($which) { + if (in_array($which, array('ignore', 'not found', 'empty', 'default'))) { + return parent::default_actions($which); + } + return; + } + $actions = parent::default_actions(); + unset($actions['summary asc']); + unset($actions['summary desc']); + return $actions; + } + + function query() { + $this->ensure_my_table(); + + if (!empty($this->options['break_phrase'])) { + $tids = new stdClass(); + $tids->value = $this->argument; + $tids = views_break_phrase($this->argument, $tids); + if ($tids->value == -1) { + return FALSE; + } + + if (count($tids->value) > 1) { + $operator = 'IN'; + } + else { + $operator = '='; + } + + $tids = $tids->value; + } + else { + $operator = "="; + $tids = array($this->argument); + } + // Now build the subqueries. + $subquery = db_select('taxonomy_index', 'tn'); + $subquery->addField('tn', 'nid'); + $where = db_or()->condition('tn.tid', $tids, $operator); + $last = "tn"; + + if ($this->options['depth'] > 0) { + $subquery->leftJoin('taxonomy_term_hierarchy', 'th', "th.tid = tn.tid"); + $last = "th"; + foreach (range(1, abs($this->options['depth'])) as $count) { + $subquery->leftJoin('taxonomy_term_hierarchy', "th$count", "$last.parent = th$count.tid"); + $where->condition("th$count.tid", $tids, $operator); + $last = "th$count"; + } + } + elseif ($this->options['depth'] < 0) { + foreach (range(1, abs($this->options['depth'])) as $count) { + $subquery->leftJoin('taxonomy_term_hierarchy', "th$count", "$last.tid = th$count.parent"); + $where->condition("th$count.tid", $tids, $operator); + $last = "th$count"; + } + } + + $subquery->condition($where); + $this->query->add_where(0, "$this->table_alias.$this->real_field", $subquery, 'IN'); + } + + function title() { + $term = taxonomy_term_load($this->argument); + if (!empty($term)) { + return check_plain($term->name); + } + // TODO review text + return t('No name'); + } +} diff --git a/sites/all/modules/views/modules/taxonomy/views_handler_argument_term_node_tid_depth_modifier.inc b/sites/all/modules/views/modules/taxonomy/views_handler_argument_term_node_tid_depth_modifier.inc new file mode 100644 index 0000000000000000000000000000000000000000..9bde14ccaa97dff045f11e08eac39881163063bf --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_handler_argument_term_node_tid_depth_modifier.inc @@ -0,0 +1,59 @@ +<?php +// $Id: views_handler_argument_term_node_tid_depth_modifier.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $ + +/** + * Argument handler for to modify depth for a previous term. + * + * This handler is actually part of the node table and has some restrictions, + * because it uses a subquery to find nodes with + */ +class views_handler_argument_term_node_tid_depth_modifier extends views_handler_argument { + function options_form(&$form, &$form_state) { } + function query() { } + function pre_query() { + // We don't know our argument yet, but it's based upon our position: + $argument = isset($this->view->args[$this->position]) ? $this->view->args[$this->position] : NULL; + if (!is_numeric($argument)) { + return; + } + + if ($argument > 10) { + $argument = 10; + } + + if ($argument < -10) { + $argument = -10; + } + + // figure out which argument preceded us. + $keys = array_reverse(array_keys($this->view->argument)); + $skip = TRUE; + foreach ($keys as $key) { + if ($key == $this->options['id']) { + $skip = FALSE; + continue; + } + + if ($skip) { + continue; + } + + if (empty($this->view->argument[$key])) { + continue; + } + + if (isset($handler)) { + unset($handler); + } + + $handler = &$this->view->argument[$key]; + if (empty($handler->definition['accept depth modifier'])) { + continue; + } + + // Finally! + $handler->options['depth'] = $argument; + } + } +} + diff --git a/sites/all/modules/views/modules/taxonomy/views_handler_argument_vocabulary_vid.inc b/sites/all/modules/views/modules/taxonomy/views_handler_argument_vocabulary_vid.inc new file mode 100644 index 0000000000000000000000000000000000000000..0564416d9d4cfd2f3c2c4260899ef5cbb7d61916 --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_handler_argument_vocabulary_vid.inc @@ -0,0 +1,20 @@ +<?php +// $Id: views_handler_argument_vocabulary_vid.inc,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * Argument handler to accept a vocabulary id. + */ +class views_handler_argument_vocabulary_vid extends views_handler_argument { + /** + * Override the behavior of title(). Get the name of the user. + */ + function title() { + $title = db_query("SELECT v.name FROM {taxonomy_vocabulary} v WHERE v.vid = :vid", array(':vid' => $this->argument))->fetchField(); + + if (empty($title)) { + return t('No vocabulary'); + } + + return check_plain($title); + } +} diff --git a/sites/all/modules/views/modules/taxonomy/views_handler_field_taxonomy.inc b/sites/all/modules/views/modules/taxonomy/views_handler_field_taxonomy.inc new file mode 100644 index 0000000000000000000000000000000000000000..4713e09ce2d39234e3891dda2444e7e459a3b467 --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_handler_field_taxonomy.inc @@ -0,0 +1,65 @@ +<?php +// $Id: views_handler_field_taxonomy.inc,v 1.3.6.3 2010/09/19 09:40:34 dereine Exp $ + +/** + * Field handler to provide simple renderer that allows linking to a taxonomy + * term. + */ +class views_handler_field_taxonomy extends views_handler_field { + /** + * Constructor to provide additional field to add. + * + * This constructer assumes the taxonomy_term_data table. If using another + * table, we'll need to be more specific. + */ + function construct() { + parent::construct(); + $this->additional_fields['vid'] = 'vid'; + $this->additional_fields['tid'] = 'tid'; + $this->additional_fields['vocabulary_machine_name'] = array( + 'table' => 'taxonomy_vocabulary', + 'field' => 'machine_name', + ); + } + + function option_definition() { + $options = parent::option_definition(); + $options['link_to_taxonomy'] = array('default' => FALSE); + return $options; + } + + /** + * Provide link to taxonomy option + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_to_taxonomy'] = array( + '#title' => t('Link this field to its taxonomy term page'), + '#description' => t('This will override any other link you have set.'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['link_to_taxonomy']), + ); + } + + /** + * Render whatever the data is as a link to the taxonomy. + * + * Data should be made XSS safe prior to calling this function. + */ + function render_link($data, $values) { + if (!empty($this->options['link_to_taxonomy']) && !empty($values->{$this->aliases['tid']}) && $data !== NULL && $data !== '') { + $term = new stdClass(); + $term->tid = $values->{$this->aliases['tid']}; + $term->vid = $values->{$this->aliases['vid']}; + $term->vocabulary_machine_name = $values->{$this->aliases['vocabulary_machine_name']}; + $this->options['alter']['make_link'] = TRUE; + $uri = entity_uri('taxonomy_term', $term); + $this->options['alter']['path'] = $uri['path']; + } + return $data; + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->field_alias}), $values); + } +} diff --git a/sites/all/modules/views/modules/taxonomy/views_handler_field_term_link_edit.inc b/sites/all/modules/views/modules/taxonomy/views_handler_field_term_link_edit.inc new file mode 100644 index 0000000000000000000000000000000000000000..43a812d444cd6ff337bbd6685e2f7e234b2140c5 --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_handler_field_term_link_edit.inc @@ -0,0 +1,53 @@ +<?php +// $Id: views_handler_field_term_link_edit.inc,v 1.1.4.3 2010/12/19 10:33:13 dereine Exp $ + +/** + * Field handler to present a term edit link . + */ +class views_handler_field_term_link_edit extends views_handler_field { + function construct() { + parent::construct(); + $this->additional_fields['tid'] = 'tid'; + $this->additional_fields['vid'] = 'vid'; + $this->additional_fields['vocabulary_machine_name'] = array( + 'table' => 'taxonomy_vocabulary', + 'field' => 'machine_name', + ); + } + + function option_definition() { + $options = parent::option_definition(); + + $options['text'] = array('default' => '', 'translatable' => TRUE); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['text'] = array( + '#type' => 'textfield', + '#title' => t('Text to display'), + '#default_value' => $this->options['text'], + ); + } + + function query() { + $this->ensure_my_table(); + $this->add_additional_fields(); + } + + function render($values) { + // Mock a term object for taxonomy_term_edit_access(). Use machine name and + // vid to ensure compatibility with vid based and machine name based + // access checks. See http://drupal.org/node/995156 + $term = new stdClass(); + $term->vid = $values->{$this->aliases['vid']}; + $term->vocabulary_machine_name = $values->{$this->aliases['vocabulary_machine_name']}; + if (taxonomy_term_edit_access($term)) { + $text = !empty($this->options['text']) ? $this->options['text'] : t('edit'); + return l($text, 'taxonomy/term/'. $values->{$this->aliases['tid']} .'/edit', array('query' => drupal_get_destination())); + } + } +} + diff --git a/sites/all/modules/views/modules/taxonomy/views_handler_field_term_node_tid.inc b/sites/all/modules/views/modules/taxonomy/views_handler_field_term_node_tid.inc new file mode 100644 index 0000000000000000000000000000000000000000..be9ad2eb292a0743f565115b8a4c4bf5dcf2dbb3 --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_handler_field_term_node_tid.inc @@ -0,0 +1,139 @@ +<?php +// $Id: views_handler_field_term_node_tid.inc,v 1.4.4.10 2011/01/04 00:11:54 dereine Exp $ + +/** + * Field handler for terms. + */ +class views_handler_field_term_node_tid extends views_handler_field_prerender_list { + function init(&$view, &$options) { + parent::init($view, $options); + if ($view->base_table == 'node_revisions') { + $this->additional_fields['nid'] = array('table' => 'node_revisions', 'field' => 'nid'); + } + else { + $this->additional_fields['nid'] = array('table' => 'node', 'field' => 'nid'); + } + + // Convert legacy vids option to machine name vocabularies. + if (!empty($this->options['vids'])) { + $vocabularies = taxonomy_get_vocabularies(); + foreach ($this->options['vids'] as $vid) { + if (isset($vocabularies[$vid], $vocabularies[$vid]->machine_name)) { + $this->options['vocabularies'][$vocabularies[$vid]->machine_name] = $vocabularies[$vid]->machine_name; + } + } + } + } + + function option_definition() { + $options = parent::option_definition(); + + $options['link_to_taxonomy'] = array('default' => TRUE); + $options['limit'] = array('default' => FALSE); + $options['vocabularies'] = array('default' => array()); + + return $options; + } + + /** + * Provide "link to term" option. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_to_taxonomy'] = array( + '#title' => t('Link this field to its term page'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['link_to_taxonomy']), + ); + + $form['limit'] = array( + '#type' => 'checkbox', + '#title' => t('Limit terms by vocabulary'), + '#default_value'=> $this->options['limit'], + ); + + $options = array(); + $vocabularies = taxonomy_get_vocabularies(); + foreach ($vocabularies as $voc) { + $options[$voc->machine_name] = check_plain($voc->name); + } + + $form['vocabularies'] = array( + '#prefix' => '<div><div id="edit-options-vocabularies">', + '#suffix' => '</div></div>', + '#type' => 'checkboxes', + '#title' => t('Vocabularies'), + '#options' => $options, + '#default_value' => $this->options['vocabularies'], + '#process' => array('form_process_checkboxes', 'ctools_dependent_process'), + '#dependency' => array('edit-options-limit' => array(TRUE)), + ); + } + + /** + * Add this term to the query + */ + function query() { + $this->add_additional_fields(); + } + + function pre_render(&$values) { + $this->field_alias = $this->aliases['nid']; + $nids = array(); + foreach ($values as $result) { + if (!empty($result->{$this->aliases['nid']})) { + $nids[] = $result->{$this->aliases['nid']}; + } + } + + if ($nids) { + $query = db_select('taxonomy_term_data', 'td'); + $query->innerJoin('taxonomy_index', 'tn', 'td.tid = tn.tid'); + $query->innerJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid'); + $query->fields('td'); + $query->addField('tn', 'nid', 'node_nid'); + $query->addField('tv', 'name', 'vocabulary'); + $query->addField('tv', 'machine_name', 'vocabulary_machine_name'); + $query->orderby('td.weight'); + $query->orderby('td.name'); + $query->condition('tn.nid', $nids); + $query->addTag('term_access'); + $vocabs = array_filter($this->options['vocabularies']); + if (!empty($this->options['limit']) && !empty($vocabs)) { + $query->condition('tv.machine_name', $vocabs); + } + $result = $query->execute(); + + foreach ($result as $term) { + $this->items[$term->node_nid][$term->tid]['name'] = check_plain($term->name); + $this->items[$term->node_nid][$term->tid]['tid'] = $term->tid; + $this->items[$term->node_nid][$term->tid]['vocabulary_machine_name'] = check_plain($term->vocabulary_machine_name); + $this->items[$term->node_nid][$term->tid]['vocabulary'] = check_plain($term->vocabulary); + + if (!empty($this->options['link_to_taxonomy'])) { + $this->items[$term->node_nid][$term->tid]['make_link'] = TRUE; + $this->items[$term->node_nid][$term->tid]['path'] = 'taxonomy/term/' . $term->tid; + } + } + } + } + + function render_item($count, $item) { + return $item['name']; + } + + function document_self_tokens(&$tokens) { + $tokens['[' . $this->options['id'] . '-tid' . ']'] = t('The taxonomy term ID for the term.'); + $tokens['[' . $this->options['id'] . '-name' . ']'] = t('The taxonomy term name for the term.'); + $tokens['[' . $this->options['id'] . '-vocabulary-machine-name' . ']'] = t('The machine name for the vocabulary the term belongs to.'); + $tokens['[' . $this->options['id'] . '-vocabulary' . ']'] = t('The name for the vocabulary the term belongs to.'); + } + + function add_self_tokens(&$tokens, $item) { + $tokens['[' . $this->options['id'] . '-tid' . ']'] = $item['tid']; + $tokens['[' . $this->options['id'] . '-name' . ']'] = $item['name']; + $tokens['[' . $this->options['id'] . '-vocabulary-machine-name' . ']'] = $item['vocabulary_machine_name']; + $tokens['[' . $this->options['id'] . '-vocabulary' . ']'] = $item['vocabulary']; + } +} + diff --git a/sites/all/modules/views/modules/taxonomy/views_handler_filter_term_node_tid.inc b/sites/all/modules/views/modules/taxonomy/views_handler_filter_term_node_tid.inc new file mode 100644 index 0000000000000000000000000000000000000000..c7b0a4ffeb2e3864505d31b17c3c2e3b51ef86a7 --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_handler_filter_term_node_tid.inc @@ -0,0 +1,337 @@ +<?php +// $Id: views_handler_filter_term_node_tid.inc,v 1.8.6.14 2010/12/24 13:42:01 dereine Exp $ + +/** + * Filter by term id + */ +class views_handler_filter_term_node_tid extends views_handler_filter_many_to_one { + function init(&$view, &$options) { + parent::init($view, $options); + + // Convert legacy vid option to machine name vocabulary. + if (!empty($this->options['vid']) & empty($this->options['vocabulary'])) { + $vocabularies = taxonomy_get_vocabularies(); + $vid = $this->options['vid']; + if (isset($vocabularies[$vid], $vocabularies[$vid]->machine_name)) { + $this->options['vocabulary'] = $vocabularies[$vid]->machine_name; + } + } + } + + function has_extra_options() { return TRUE; } + + function get_value_options() { /* don't overwrite the value options */ } + + function option_definition() { + $options = parent::option_definition(); + + $options['type'] = array('default' => 'textfield'); + $options['limit'] = array('default' => TRUE); + $options['vocabulary'] = array('default' => 0); + $options['hierarchy'] = array('default' => 0); + $options['error_message'] = array('default' => TRUE); + + return $options; + } + + function extra_options_form(&$form, &$form_state) { + $vocabularies = taxonomy_get_vocabularies(); + foreach ($vocabularies as $voc) { + $options[$voc->machine_name] = check_plain($voc->name); + } + + if ($this->options['limit']) { + // We only do this when the form is displayed. + if ($this->options['vid'] == 0) { + $first_vocabulary = reset($vocabularies); + $this->options['vid'] = $first_vocabulary->vid; + } + + $form['vocabulary'] = array( + '#prefix' => '<div class="views-left-40">', + '#suffix' => '</div>', + '#type' => 'radios', + '#title' => t('Vocabulary'), + '#options' => $options, + '#description' => t('Select which vocabulary to show terms for in the regular options.'), + '#default_value' => $this->options['vocabulary'], + ); + } + + $form['markup_start'] = array( + '#markup' => '<div class="views-left-40">', + ); + + $form['type'] = array( + '#type' => 'radios', + '#title' => t('Selection type'), + '#options' => array('select' => t('Dropdown'), 'textfield' => t('Autocomplete')), + '#default_value' => $this->options['type'], + ); + + $form['hierarchy'] = array( + '#type' => 'checkbox', + '#title' => t('Show hierarchy in dropdown'), + '#default_value' => !empty($this->options['hierarchy']), + '#process' => array('form_process_checkbox', 'ctools_dependent_process'), + '#dependency' => array('radio:options[type]' => array('select')), + ); + + $form['markup_end'] = array( + '#markup' => '</div>', + ); + } + + function value_form(&$form, &$form_state) { + $vocabulary = taxonomy_vocabulary_machine_name_load($this->options['vocabulary']); + if (empty($vocabulary) && $this->options['limit']) { + $form['markup'] = array( + '#markup' => '<div class="form-item">' . t('An invalid vocabulary is selected. Please change it in the options.') . '</div>', + ); + return; + } + + if ($this->options['type'] == 'textfield') { + $default = ''; + if ($this->value) { + $result = db_select('taxonomy_term_data', 'td') + ->fields('td') + ->condition('td.tid', $this->value) + ->execute(); + foreach ($result as $term) { + if ($default) { + $default .= ', '; + } + $default .= $term->name; + } + } + + $form['value'] = array( + '#title' => $this->options['limit'] ? t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->name)) : t('Select terms'), + '#type' => 'textfield', + '#default_value' => $default, + ); + + if ($this->options['limit']) { + $form['value']['#autocomplete_path'] = 'admin/views/ajax/autocomplete/taxonomy/' . $vocabulary->vid; + } + } + else { + if (!empty($this->options['hierarchy']) && $this->options['limit']) { + $tree = taxonomy_get_tree($vocabulary->vid); + $options = array(); + + if ($tree) { + foreach ($tree as $term) { + $choice = new stdClass(); + $choice->option = array($term->tid => str_repeat('-', $term->depth) . $term->name); + $options[] = $choice; + } + } + } + else { + $options = array(); + $query = db_select('taxonomy_term_data', 'td'); + $query->innerJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid'); + $query->fields('td'); + $query->orderby('tv.weight'); + $query->orderby('tv.name'); + $query->orderby('td.weight'); + $query->orderby('td.name'); + $query->addTag('term_access'); + if ($this->options['limit']) { + $query->condition('tv.machine_name', $vocabulary->machine_name); + } + $result = $query->execute(); + foreach ($result as $term) { + $options[$term->tid] = $term->name; + } + } + + $default_value = (array) $this->value; + + if (!empty($form_state['exposed'])) { + $identifier = $this->options['expose']['identifier']; + + if (!empty($this->options['expose']['reduce'])) { + $options = $this->reduce_value_options($options); + + if (empty($this->options['expose']['single']) && !empty($this->options['expose']['optional'])) { + $default_value = array(); + } + } + + if (!empty($this->options['expose']['single'])) { + if (!empty($this->options['expose']['optional']) && (empty($default_value) || !empty($this->options['expose']['reduce']))) { + $default_value = 'All'; + } + elseif (empty($default_value)) { + $keys = array_keys($options); + $default_value = array_shift($keys); + } + else { + $copy = $default_value; + $default_value = array_shift($copy); + } + } + } + $form['value'] = array( + '#type' => 'select', + '#title' => $this->options['limit'] ? t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->name)) : t('Select terms'), + '#multiple' => TRUE, + '#options' => $options, + '#size' => min(9, count($options)), + '#default_value' => $default_value, + ); + + if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) { + $form_state['input'][$identifier] = $default_value; + } + } + + + if (empty($form_state['exposed'])) { + // Retain the helper option + $this->helper->options_form($form, $form_state); + } + } + + function value_validate(&$form, &$form_state) { + // We only validate if they've chosen the text field style. + if ($this->options['type'] != 'textfield') { + return; + } + + $values = drupal_explode_tags($form_state['values']['options']['value']); + $tids = $this->validate_term_strings($form['value'], $values); + + if ($tids) { + $form_state['values']['options']['value'] = $tids; + } + } + + function accept_exposed_input($input) { + if (empty($this->options['exposed'])) { + return TRUE; + } + + // If it's optional and there's no value don't bother filtering. + if ($this->options['expose']['optional'] && empty($this->validated_exposed_input)) { + return FALSE; + } + + $rc = parent::accept_exposed_input($input); + if ($rc) { + // If we have previously validated input, override. + if (isset($this->validated_exposed_input)) { + $this->value = $this->validated_exposed_input; + } + } + + return $rc; + } + + function exposed_validate(&$form, &$form_state) { + if (empty($this->options['exposed'])) { + return; + } + + $identifier = $this->options['expose']['identifier']; + + // We only validate if they've chosen the text field style. + if ($this->options['type'] != 'textfield') { + if ($form_state['values'][$identifier] != 'All') { + $this->validated_exposed_input = (array) $form_state['values'][$identifier]; + } + return; + } + + if (empty($this->options['expose']['identifier'])) { + return; + } + + $values = drupal_explode_tags($form_state['values'][$identifier]); + + $tids = $this->validate_term_strings($form[$identifier], $values); + if ($tids) { + $this->validated_exposed_input = $tids; + } + } + + /** + * Validate the user string. Since this can come from either the form + * or the exposed filter, this is abstracted out a bit so it can + * handle the multiple input sources. + */ + function validate_term_strings(&$form, $values) { + if (empty($values)) { + return array(); + } + + $tids = array(); + $placeholders = array(); + $args = array(); + $results = array(); + foreach ($values as $value) { + $missing[strtolower($value)] = TRUE; + $names[] = $value; + } + + if (!$names) { + return; + } + + $query = db_select('taxonomy_term_data', 'td'); + $query->innerJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid'); + $query->fields('td'); + $query->condition('td.name', $names); + $query->condition('tv.machine_name', $this->options['vocabulary']); + $query->addTag('term_access'); + $result = $query->execute(); + foreach ($result as $term) { + unset($missing[strtolower($term->name)]); + $tids[] = $term->tid; + } + + if ($missing && !empty($this->options['error_message'])) { + form_error($form, format_plural(count($missing), 'Unable to find term: @terms', 'Unable to find terms: @terms', array('@terms' => implode(', ', array_keys($missing))))); + } + elseif ($missing && empty($this->options['error_message'])) { + $tids = array(0); + } + + return $tids; + } + + function value_submit($form, &$form_state) { + // prevent array_filter from messing up our arrays in parent submit. + } + + function expose_form_right(&$form, &$form_state) { + parent::expose_form_right($form, $form_state); + if ($this->options['type'] != 'select') { + unset($form['expose']['reduce']); + } + $form['error_message'] = array( + '#type' => 'checkbox', + '#title' => t('Display error message'), + '#default_value' => !empty($this->options['error_message']), + ); + } + + function admin_summary() { + // set up $this->value_options for the parent summary + $this->value_options = array(); + + if ($this->value) { + $result = db_select('taxonomy_term_data', 'td') + ->fields('td') + ->condition('td.tid', $this->value) + ->execute(); + foreach ($result as $term) { + $this->value_options[$term->tid] = $term->name; + } + } + return parent::admin_summary(); + } +} diff --git a/sites/all/modules/views/modules/taxonomy/views_handler_filter_term_node_tid_depth.inc b/sites/all/modules/views/modules/taxonomy/views_handler_filter_term_node_tid_depth.inc new file mode 100644 index 0000000000000000000000000000000000000000..b00d59bafb11fd9c3e2252428ba482f0f8d8a601 --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_handler_filter_term_node_tid_depth.inc @@ -0,0 +1,89 @@ +<?php +// $Id: views_handler_filter_term_node_tid_depth.inc,v 1.1.6.4 2010/09/09 21:31:49 dereine Exp $ +/** + * Filter handler for taxonomy terms with depth. + * + * This handler is actually part of the node table and has some restrictions, + * because it uses a subquery to find nodes with + */ +class views_handler_filter_term_node_tid_depth extends views_handler_filter_term_node_tid { + function operator_options() { + return array( + 'or' => t('Is one of'), + ); + } + + function option_definition() { + $options = parent::option_definition(); + + $options['depth'] = array('default' => 0); + + return $options; + } + + function extra_options_form(&$form, &$form_state) { + parent::extra_options_form($form, $form_state); + + $form['depth'] = array( + '#type' => 'weight', + '#title' => t('Depth'), + '#default_value' => $this->options['depth'], + '#description' => t('The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term "fruit" and a child term "apple", with a depth of 1 (or higher) then filtering for the term "fruit" will get nodes that are tagged with "apple" as well as "fruit". If negative, the reverse is true; searching for "apple" will also pick up nodes tagged with "fruit" if depth is -1 (or lower).'), + ); + } + + function query() { + // If no filter values are present, then do nothing. + if (count($this->value) == 0) { + return; + } + elseif (count($this->value) == 1) { + $operator = '='; + } + else { + $operator = 'IN';# " IN (" . implode(', ', array_fill(0, sizeof($this->value), '%d')) . ")"; + } + + // The normal use of ensure_my_table() here breaks Views. + // So instead we trick the filter into using the alias of the base table. + // See http://drupal.org/node/271833 + // If a relationship is set, we must use the alias it provides. + if (!empty($this->relationship)) { + $this->table_alias = $this->relationship; + } + // If no relationship, then use the alias of the base table. + elseif (isset($this->query->table_queue[$this->query->base_table]['alias'])) { + $this->table_alias = $this->query->table_queue[$this->query->base_table]['alias']; + } + // This should never happen, but if it does, we fail quietly. + else { + return; + } + + // Now build the subqueries. + $subquery = db_select('taxonomy_index', 'tn'); + $subquery->addField('tn', 'nid'); + $where = db_or()->condition('tn.tid', $this->value, $operator); + $last = "tn"; + + if ($this->options['depth'] > 0) { + $subquery->leftJoin('taxonomy_term_hierarchy', 'th', "th.tid = tn.tid"); + $last = "th"; + foreach (range(1, abs($this->options['depth'])) as $count) { + $subquery->leftJoin('taxonomy_term_hierarchy', "th$count", "$last.parent = th$count.tid"); + $where->condition("th$count.tid", $this->value, $operator); + $last = "th$count"; + } + } + elseif ($this->options['depth'] < 0) { + foreach (range(1, abs($this->options['depth'])) as $count) { + $subquery->leftJoin('taxonomy_term_hierarchy', "th$count", "$last.tid = th$count.parent"); + $where->condition("th$count.tid", $this->value, $operator); + $last = "th$count"; + } + } + + $subquery->condition($where); + $this->query->add_where(0, "$this->table_alias.$this->real_field", $subquery, 'IN'); + } +} diff --git a/sites/all/modules/views/modules/taxonomy/views_handler_filter_vocabulary_machine_name.inc b/sites/all/modules/views/modules/taxonomy/views_handler_filter_vocabulary_machine_name.inc new file mode 100644 index 0000000000000000000000000000000000000000..2fc68e88f0ede189ebe6ce12e9c13d65dd1289e6 --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_handler_filter_vocabulary_machine_name.inc @@ -0,0 +1,19 @@ +<?php +// $Id: views_handler_filter_vocabulary_machine_name.inc,v 1.1.2.1 2010/10/17 10:48:08 dereine Exp $ + +/** + * Filter by vocabulary machine name + */ +class views_handler_filter_vocabulary_machine_name extends views_handler_filter_in_operator { + function get_value_options() { + if (isset($this->value_options)) { + return; + } + + $this->value_options = array(); + $vocabularies = taxonomy_get_vocabularies(); + foreach ($vocabularies as $voc) { + $this->value_options[$voc->machine_name] = $voc->name; + } + } +} diff --git a/sites/all/modules/views/modules/taxonomy/views_handler_filter_vocabulary_vid.inc b/sites/all/modules/views/modules/taxonomy/views_handler_filter_vocabulary_vid.inc new file mode 100644 index 0000000000000000000000000000000000000000..0afdfe532801dd78c7578d9e855f4ab2d3008931 --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_handler_filter_vocabulary_vid.inc @@ -0,0 +1,19 @@ +<?php +// $Id: views_handler_filter_vocabulary_vid.inc,v 1.3.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * Filter by vocabulary id + */ +class views_handler_filter_vocabulary_vid extends views_handler_filter_in_operator { + function get_value_options() { + if (isset($this->value_options)) { + return; + } + + $this->value_options = array(); + $vocabularies = taxonomy_get_vocabularies(); + foreach ($vocabularies as $voc) { + $this->value_options[$voc->vid] = $voc->name; + } + } +} diff --git a/sites/all/modules/views/modules/taxonomy/views_handler_relationship_node_term_data.inc b/sites/all/modules/views/modules/taxonomy/views_handler_relationship_node_term_data.inc new file mode 100644 index 0000000000000000000000000000000000000000..558ed550ed13937f4fded63a3e55a0892e9eacd7 --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_handler_relationship_node_term_data.inc @@ -0,0 +1,94 @@ +<?php +// $Id: views_handler_relationship_node_term_data.inc,v 1.3.4.3 2010/10/07 19:40:02 dereine Exp $ +/** + * @file + * Views' relationship handlers. + */ + +class views_handler_relationship_node_term_data extends views_handler_relationship { + function init(&$view, &$options) { + parent::init($view, $options); + + // Convert legacy vids option to machine name vocabularies. + if (!empty($this->options['vids'])) { + $vocabularies = taxonomy_get_vocabularies(); + foreach ($this->options['vids'] as $vid) { + if (isset($vocabularies[$vid], $vocabularies[$vid]->machine_name)) { + $this->options['vocabularies'][$vocabularies[$vid]->machine_name] = $vocabularies[$vid]->machine_name; + } + } + } + } + + function option_definition() { + $options = parent::option_definition(); + $options['vocabularies'] = array('default' => array()); + return $options; + } + + /** + * Default options form that provides the label widget that all fields + * should have. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $vocabularies = taxonomy_get_vocabularies(); + $options = array(); + foreach ($vocabularies as $voc) { + $options[$voc->machine_name] = check_plain($voc->name); + } + + $form['vocabularies'] = array( + '#type' => 'checkboxes', + '#title' => t('Vocabularies'), + '#options' => $options, + '#default_value' => $this->options['vocabularies'], + '#description' => t('Choose which vocabularies you wish to relate. Remember that every term found will create a new record, so this relationship is best used on just one vocabulary that has only one term per node.'), + ); + } + + /** + * Called to implement a relationship in a query. + */ + function query() { + $this->ensure_my_table(); + + $def = $this->definition; + $def['table'] = 'taxonomy_term_data'; + + if (!array_filter($this->options['vocabularies'])) { + $term_node = $this->query->add_table('taxonomy_index', $this->relationship); + $def['left_table'] = 'taxonomy_index'; + $def['left_field'] = 'tid'; + $def['field'] = 'tid'; + $def['type'] = empty($this->options['required']) ? 'LEFT' : 'INNER'; + } + else { + // If vocabularies are supplied join a subselect instead + $def['left_table'] = $this->table_alias; + $def['left_field'] = 'nid'; + $def['field'] = 'nid'; + $def['type'] = empty($this->options['required']) ? 'LEFT' : 'INNER'; + + $query = db_select('taxonomy_term_data', 'td'); + $query->addJoin($def['type'], 'taxonomy_vocabulary', 'tv', 'td.vid = tv.vid'); + $query->addJoin($def['type'], 'taxonomy_index', 'tn', 'tn.tid = td.tid'); + $query->condition('tv.machine_name', array_filter($this->options['vocabularies'])); + $query->addTag('term_access'); + $query->fields('td'); + $query->fields('tn', array('nid')); + $def['table formula'] = $query; + } + + $join = new views_join(); + + $join->definition = $def; + $join->construct(); + $join->adjusted = TRUE; + + // use a short alias for this: + $alias = $def['table'] . '_' . $this->table; + + $this->alias = $this->query->add_relationship($alias, $join, 'taxonomy_term_data', $this->relationship); + } +} diff --git a/sites/all/modules/views/modules/taxonomy/views_plugin_argument_default_taxonomy_tid.inc b/sites/all/modules/views/modules/taxonomy/views_plugin_argument_default_taxonomy_tid.inc new file mode 100644 index 0000000000000000000000000000000000000000..eb743c612b0faf7ea3ba622eea5e968c039709ec --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_plugin_argument_default_taxonomy_tid.inc @@ -0,0 +1,130 @@ +<?php +// $Id: views_plugin_argument_default_taxonomy_tid.inc,v 1.1.2.9 2010/12/03 20:17:14 dereine Exp $ +/** + * @file + * Taxonomy tid default argument. + */ + +class views_plugin_argument_default_taxonomy_tid extends views_plugin_argument_default { + function init(&$view, &$argument, &$options) { + parent::init($view, $argument, $options); + + // Convert legacy vids option to machine name vocabularies. + if (!empty($this->options['vids'])) { + $vocabularies = taxonomy_get_vocabularies(); + foreach ($this->options['vids'] as $vid) { + if (isset($vocabularies[$vid], $vocabularies[$vid]->machine_name)) { + $this->options['vocabularies'][$vocabularies[$vid]->machine_name] = $vocabularies[$vid]->machine_name; + } + } + } + } + + function option_definition() { + $options = parent::option_definition(); + + $options['term_page'] = array('default' => TRUE); + $options['node'] = array('default' => FALSE); + $options['limit'] = array('default' => FALSE); + $options['vocabularies'] = array('default' => array()); + + return $options; + } + + function options_form(&$form, &$form_state) { + $form['term_page'] = array( + '#type' => 'checkbox', + '#title' => t('Load default argument from term page'), + '#default_value' => $this->options['term_page'], + ); + $form['node'] = array( + '#type' => 'checkbox', + '#title' => t('Load default argument from node page, thats good for related taxonomy blocks.'), + '#default_value' => $this->options['node'], + ); + + $form['limit'] = array( + '#type' => 'checkbox', + '#title' => t('Limit terms by vocabulary'), + '#default_value'=> $this->options['limit'], + '#process' => array('form_process_checkbox', 'ctools_dependent_process'), + '#dependency' => array( + 'edit-options-argument-default-taxonomy-tid-node' => array(1), + ), + ); + + $options = array(); + $vocabularies = taxonomy_get_vocabularies(); + foreach ($vocabularies as $voc) { + $options[$voc->machine_name] = check_plain($voc->name); + } + + $form['vocabularies'] = array( + '#prefix' => '<div><div id="edit-options-vids">', + '#suffix' => '</div></div>', + '#type' => 'checkboxes', + '#title' => t('Vocabularies'), + '#options' => $options, + '#default_value' => $this->options['vocabularies'], + '#process' => array('form_process_checkboxes', 'ctools_dependent_process'), + '#dependency' => array( + 'edit-options-argument-default-taxonomy-tid-limit' => array(1), + 'edit-options-argument-default-taxonomy-tid-node' => array(1), + ), + ); + } + + function options_submit(&$form, &$form_state, &$options) { + // Clear checkbox values. + $options['vocabularies'] = array_filter($options['vocabularies']); + } + + function get_argument() { + // Load default argument from taxonomy page. + if (!empty($this->options['term_page'])) { + if (arg(0) == 'taxonomy' && arg(1) == 'term' && is_numeric(arg(2))) { + return arg(2); + } + } + // Load default argument from node. + if (!empty($this->options['node'])) { + foreach (range(1, 3) as $i) { + $node = menu_get_object('node', $i); + if (!empty($node)) { + break; + } + } + // Just check, if a node could be detected. + if ($node) { + $taxonomy = array(); + $fields = field_info_instances('node', $node->type); + foreach ($fields as $name => $info) { + $field_info = field_info_field($name); + if ($field_info['type'] == 'taxonomy_term_reference') { + $items = field_get_items('node', $node, $name); + if (is_array($items)) { + foreach ($items as $item) { + $taxonomy[$item['tid']] = $field_info['settings']['allowed_values'][0]['vocabulary']; + } + } + } + } + if (!empty($this->options['limit'])) { + $tids = array(); + // filter by vocabulary + foreach ($taxonomy as $tid => $vocab) { + if (!empty($this->options['vocabularies'][$vocab])) { + $tids[] = $tid; + } + } + return implode(",", $tids); + } + // Return all tids. + else { + return implode(",", array_keys($taxonomy)); + } + } + } + } +} + diff --git a/sites/all/modules/views/modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc b/sites/all/modules/views/modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc new file mode 100644 index 0000000000000000000000000000000000000000..6c046ea3b8c99622a3e7e7f4fa01068cf7d7ae88 --- /dev/null +++ b/sites/all/modules/views/modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc @@ -0,0 +1,188 @@ +<?php +// $Id: views_plugin_argument_validate_taxonomy_term.inc,v 1.6.4.8 2010/12/14 22:32:11 dereine Exp $ +/** + * @file + * Contains the 'taxonomy term' argument validator plugin. + */ + +/** + * Validate whether an argument is an acceptable node. + */ +class views_plugin_argument_validate_taxonomy_term extends views_plugin_argument_validate { + function init(&$view, &$argument, &$options) { + parent::init($view, $argument, $options); + + // Convert legacy vids option to machine name vocabularies. + if (!empty($this->options['vids'])) { + $vocabularies = taxonomy_get_vocabularies(); + foreach ($this->options['vids'] as $vid) { + if (isset($vocabularies[$vid], $vocabularies[$vid]->machine_name)) { + $this->options['vocabularies'][$vocabularies[$vid]->machine_name] = $vocabularies[$vid]->machine_name; + } + } + } + } + + function option_definition() { + $options = parent::option_definition(); + $options['vocabularies'] = array('default' => array()); + $options['type'] = array('default' => 'tid'); + $options['transform'] = array('default' => FALSE); + + return $options; + } + + function options_form(&$form, &$form_state) { + $vocabularies = taxonomy_get_vocabularies(); + $options = array(); + foreach ($vocabularies as $voc) { + $options[$voc->machine_name] = check_plain($voc->name); + } + + $form['vocabularies'] = array( + '#type' => 'checkboxes', + '#prefix' => '<div id="edit-options-validate-argument-vocabulary-wrapper">', + '#suffix' => '</div>', + '#title' => t('Vocabularies'), + '#options' => $options, + '#default_value' => $this->options['vocabularies'], + '#description' => t('If you wish to validate for specific vocabularies, check them; if none are checked, all terms will pass.'), + ); + + $form['type'] = array( + '#type' => 'select', + '#title' => t('Argument type'), + '#options' => array( + 'tid' => t('Term ID'), + 'tids' => t('Term IDs separated by , or +'), + 'name' => t('Term name'), + 'convert' => t('Term name converted to Term ID'), + ), + '#default_value' => $this->options['type'], + '#description' => t('Select the form of this argument; if using term name, it is generally more efficient to convert it to a term ID and use Taxonomy: Term ID rather than Taxonomy: Term Name" as an argument.'), + ); + + $form['transform'] = array( + '#type' => 'checkbox', + '#title' => t('Transform dashes in URL to spaces in term name arguments'), + '#default_value' => $this->options['transform'], + ); + } + + function options_submit(&$form, &$form_state, &$options) { + // filter trash out of the options so we don't store giant unnecessary arrays + $options['vocabularies'] = array_filter($options['vocabularies']); + } + + function convert_options(&$options) { + if (!isset($options['vocabularies']) && !empty($this->argument->options['validate_argument_vocabulary'])) { + $options['vocabularies'] = $this->argument->options['validate_argument_vocabulary']; + $options['type'] = $this->argument->options['validate_argument_type']; + $options['transform'] = isset($this->argument->options['validate_argument_transform']) ? $this->argument->options['validate_argument_transform'] : FALSE; + } + } + + function validate_argument($argument) { + $vocabularies = array_filter($this->options['vocabularies']); + $type = $this->options['type']; + $transform = $this->options['transform']; + + switch ($type) { + case 'tid': + if (!is_numeric($argument)) { + return FALSE; + } + + $query = db_select('taxonomy_term_data', 'td'); + $query->leftJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid'); + $query->fields('td'); + $query->fields('tv', array('machine_name')); + $query->condition('td.tid', $argument); + $query->addTag('term_access'); + $term = $query->execute()->fetchObject(); + if (!$term) { + return FALSE; + } + return empty($vocabularies) || !empty($vocabularies[$term->machine_name]); + + case 'tids': + $tids = new stdClass(); + $tids->value = $argument; + $tids = views_break_phrase($argument, $tids); + if ($tids->value == array(-1)) { + return FALSE; + } + + $test = drupal_map_assoc($tids->value); + $titles = array(); + + // check, if some tids already verified + static $validated_cache = array(); + foreach ($test as $tid) { + if (isset($validated_cache[$tid])) { + if ($validated_cache[$tid] === FALSE) { + return FALSE; + } + else { + $titles[] = $validated_cache[$tid]; + unset($test[$tid]); + } + } + } + + // if unverified tids left - verify them and cache results + if (count($test)) { + $query = db_select('taxonomy_term_data', 'td'); + $query->leftJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid'); + $query->fields('td'); + $query->fields('tv', array('machine_name')); + $query->condition('td.tid', $test); + + $result = $query->execute(); + + foreach ($result as $term) { + if ($vocabularies && empty($vocabularies[$term->machine_name])) { + $validated_cache[$term->tid] = FALSE; + return FALSE; + } + + $titles[] = $validated_cache[$term->tid] = check_plain($term->name); + unset($test[$term->tid]); + } + } + + // Remove duplicate titles + $titles = array_unique($titles); + + $this->argument->validated_title = implode($tids->operator == 'or' ? ' + ' : ', ', $titles); + // If this is not empty, we did not find a tid. + return empty($test); + + case 'name': + case 'convert': + $query = db_select('taxonomy_term_data', 'td'); + $query->leftJoin('taxonomy_vocabulary', 'tv', 'td.vid = tv.vid'); + $query->fields('td'); + $query->fields('tv', array('machine_name')); + if (!empty($vocabularies)) { + $query->condition('tv.machine_name', $vocabularies); + } + if ($transform) { + $query->where("replace(td.name, ' ', '-') = :name", array(':name' => $argument)); + } + else { + $query->condition('td.name', $argument); + } + $term = $query->execute()->fetchObject(); + + if ($term && (empty($vocabularies) || !empty($vocabularies[$term->machine_name]))) { + if ($type == 'convert') { + $this->argument->argument = $term->tid; + $this->argument->validated_title = check_plain($term->name); + } + return TRUE; + } + return FALSE; + } + } +} diff --git a/sites/all/modules/views/modules/translation.views.inc b/sites/all/modules/views/modules/translation.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..f47ddd1c01d0e5f48c3fb3f79764238b2e7da8fd --- /dev/null +++ b/sites/all/modules/views/modules/translation.views.inc @@ -0,0 +1,151 @@ +<?php +// $Id: translation.views.inc,v 1.8.6.5 2010/12/09 01:10:24 merlinofchaos Exp $ + +/** + * @file + * + * Provide views data and handlers for translation.module + */ + +/** + * @defgroup views_translation_module translation.module handlers + * + * @{ + */ + +/** + * Implements hook_views_data_alter(). + * + * Add translation information to the node table. + */ +function translation_views_data_alter(&$data) { + + // Joins + $data['node']['table']['join']['node'] = array( + 'left_field' => 'tnid', + 'field' => 'tnid', + ); + + // Language field + $data['node']['language'] = array( + 'group' => t('Node translation'), + 'title' => t('Language'), + 'help' => t('The language the content is in.'), + 'field' => array( + 'handler' => 'views_handler_field_node_language', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_node_language', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_node_language', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // The translation ID (nid of the "source" translation) + $data['node']['tnid'] = array( + 'group' => t('Node translation'), + 'title' => t('Translation set node ID'), + 'help' => t('The ID of the translation set the content belongs to.'), + 'field' => array( + 'handler' => 'views_handler_field_node', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_node_tnid', + 'name field' => 'title', // the field to display in the summary. + 'numeric' => TRUE, + 'validate type' => 'tnid', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'relationship' => array( + 'title' => t('Source translation'), + 'help' => t('The source that this content was translated from.'), + 'base' => 'node', + 'base field' => 'nid', + 'handler' => 'views_handler_relationship', + 'label' => t('Source translation'), + ), + ); + + // The source translation. + $data['node']['translation'] = array( + 'group' => t('Node translation'), + 'title' => t('Translations'), + 'help' => t('Versions of content in different languages.'), + 'relationship' => array( + 'title' => t('Translations'), + 'help' => t('Versions of content in different languages.'), + 'base' => 'node', + 'base field' => 'tnid', + 'relationship table' => 'node', + 'relationship field' => 'nid', + 'handler' => 'views_handler_relationship_translation', + 'label' => t('Translations'), + ), + ); + + // The source translation. + $data['node']['source_translation'] = array( + 'group' => t('Node translation'), + 'title' => t('Source translation'), + 'help' => t('Nodes that are either untranslated or are the original versions of a translation set.'), + 'filter' => array( + 'handler' => 'views_handler_filter_node_tnid', + ), + ); + + // The source translation. + $data['node']['child_translation'] = array( + 'group' => t('Node translation'), + 'title' => t('Child translation'), + 'help' => t('Nodes that are translations of a source translation.'), + 'filter' => array( + 'handler' => 'views_handler_filter_node_tnid_child', + ), + ); + + // Translation status + $data['node']['translate'] = array( + 'group' => t('Node translation'), + 'title' => t('Translation status'), + 'help' => t('The translation status of the node--whether or not the translation needs to be updated.'), + 'field' => array( + 'handler' => 'views_handler_field_boolean', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_boolean_operator', + 'label' => t('Outdated'), + 'type' => 'yes-no', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // Translate node link. + $data['node']['translate_node'] = array( + 'group' => t('Node translation'), + 'title' => t('Translate link'), + 'help' => t('Provide a simple link to translate the node.'), + 'field' => array( + 'handler' => 'views_handler_field_node_link_translate', + ), + ); + + +} + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/translation/views_handler_argument_node_tnid.inc b/sites/all/modules/views/modules/translation/views_handler_argument_node_tnid.inc new file mode 100644 index 0000000000000000000000000000000000000000..d9699a0bd0715f52591927383361de30f0f620a3 --- /dev/null +++ b/sites/all/modules/views/modules/translation/views_handler_argument_node_tnid.inc @@ -0,0 +1,25 @@ +<?php +// $Id: views_handler_argument_node_tnid.inc,v 1.1.6.1 2009/11/02 22:01:26 merlinofchaos Exp $ +/** + * @file + * Provide node tnid argument handler. + */ + +/** + * Argument handler to accept a node translation id. + */ +class views_handler_argument_node_tnid extends views_handler_argument_numeric { + /** + * Override the behavior of title(). Get the title of the node. + */ + function title_query() { + $titles = array(); + + $result = db_query("SELECT n.title FROM {node} n WHERE n.tnid IN (:tnids)", array(':tnis' => $this->value)); + foreach ($result as $term) { + $titles[] = check_plain($term->title); + } + return $titles; + } +} + diff --git a/sites/all/modules/views/modules/translation/views_handler_field_node_language.inc b/sites/all/modules/views/modules/translation/views_handler_field_node_language.inc new file mode 100644 index 0000000000000000000000000000000000000000..5e7cbfdf13145700bd26b5d95d8c0bd9e07b2dde --- /dev/null +++ b/sites/all/modules/views/modules/translation/views_handler_field_node_language.inc @@ -0,0 +1,13 @@ +<?php +// $Id: views_handler_field_node_language.inc,v 1.2 2008/10/28 17:46:14 merlinofchaos Exp $ + +/** + * Field handler to translate a language into its readable form. + */ +class views_handler_field_node_language extends views_handler_field_node { + function render($values) { + $languages = locale_language_list(); + $value = isset($languages[$values->{$this->field_alias}]) ? $languages[$values->{$this->field_alias}] : ''; + return $this->render_link($value, $values); + } +} diff --git a/sites/all/modules/views/modules/translation/views_handler_field_node_link_translate.inc b/sites/all/modules/views/modules/translation/views_handler_field_node_link_translate.inc new file mode 100644 index 0000000000000000000000000000000000000000..6cdf3136172f03e5392d3fd0c9be9242128360f7 --- /dev/null +++ b/sites/all/modules/views/modules/translation/views_handler_field_node_link_translate.inc @@ -0,0 +1,32 @@ +<?php +// $Id: views_handler_field_node_link_translate.inc,v 1.1.6.2 2010/05/11 21:41:18 dereine Exp $ +/** + * Field handler to present a link node translate. + */ +class views_handler_field_node_link_translate extends views_handler_field_node_link { + function construct() { + parent::construct(); + $this->additional_fields['uid'] = 'uid'; + $this->additional_fields['type'] = 'type'; + $this->additional_fields['language'] = 'language'; + $this->additional_fields['format'] = array('table' => 'node_revisions', 'field' => 'format'); + } + + function render($values) { + // ensure user has access to edit this node. + $node = new stdClass(); + $node->nid = $values->{$this->aliases['nid']}; + $node->uid = $values->{$this->aliases['uid']}; + $node->type = $values->{$this->aliases['type']}; + $node->format = $values->{$this->aliases['format']}; + $node->language = $values->{$this->aliases['language']}; + $node->status = 1; // unpublished nodes ignore access control + if (empty($node->language) || !translation_supported_type($node->type) || !node_access('view', $node) || !user_access('translate content')) { + return; + } + + $text = !empty($this->options['text']) ? $this->options['text'] : t('translate'); + return l($text, "node/$node->nid/translate", array('query' => drupal_get_destination())); + } +} + diff --git a/sites/all/modules/views/modules/translation/views_handler_field_node_translation_link.inc b/sites/all/modules/views/modules/translation/views_handler_field_node_translation_link.inc new file mode 100644 index 0000000000000000000000000000000000000000..356ba13a4c38f04fc997e1c98d897350256b007d --- /dev/null +++ b/sites/all/modules/views/modules/translation/views_handler_field_node_translation_link.inc @@ -0,0 +1,40 @@ +<?php +// $Id: views_handler_field_node_translation_link.inc,v 1.1.6.3 2010/12/09 21:45:49 dereine Exp $ +/** + * Field handler to present a link to the node. + */ +class views_handler_field_node_translation_link extends views_handler_field { + function construct() { + parent::construct(); + $this->additional_fields['nid'] = 'nid'; + $this->additional_fields['tnid'] = 'tnid'; + $this->additional_fields['title'] = 'title'; + $this->additional_fields['language'] = 'language'; + } + + function query() { + $this->ensure_my_table(); + $this->add_additional_fields(); + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->aliases['tnid']}), $values); + } + + function render_link($data, $values) { + global $language; + $tnid = $values->{$this->aliases['tnid']}; + // Only load translations if the node isn't in the current language. + if ($values->{$this->aliases['language']} != $language->language) { + $translations = translation_node_get_translations($tnid); + if (isset($translations[$language->language])) { + $values->{$this->aliases['nid']} = $translations[$language->language]->nid; + $values->{$this->aliases['title']} = $translations[$language->language]->title; + } + } + + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "node/" . $values->{$this->aliases['nid']}; + return $values->{$this->aliases['title']}; + } +} diff --git a/sites/all/modules/views/modules/translation/views_handler_filter_node_language.inc b/sites/all/modules/views/modules/translation/views_handler_filter_node_language.inc new file mode 100644 index 0000000000000000000000000000000000000000..1da3b98a59a213f2d1dd95e2ceb6d9affcc1fc0b --- /dev/null +++ b/sites/all/modules/views/modules/translation/views_handler_filter_node_language.inc @@ -0,0 +1,19 @@ +<?php +// $Id: views_handler_filter_node_language.inc,v 1.1.6.1 2011/01/06 00:37:05 dereine Exp $ +/** + * Filter by language + */ +class views_handler_filter_node_language extends views_handler_filter_in_operator { + function get_value_options() { + if (!isset($this->value_options)) { + $this->value_title = t('Language'); + $languages = array( + '***CURRENT_LANGUAGE***' => t("Current user's language"), + '***DEFAULT_LANGUAGE***' => t("Default site language"), + LANGUAGE_NONE => t('No language') + ); + $languages = array_merge($languages, locale_language_list()); + $this->value_options = $languages; + } + } +} diff --git a/sites/all/modules/views/modules/translation/views_handler_filter_node_tnid.inc b/sites/all/modules/views/modules/translation/views_handler_filter_node_tnid.inc new file mode 100644 index 0000000000000000000000000000000000000000..47fce79f65ebc0b33ea20399cec1558f38a3e795 --- /dev/null +++ b/sites/all/modules/views/modules/translation/views_handler_filter_node_tnid.inc @@ -0,0 +1,39 @@ +<?php +// $Id: views_handler_filter_node_tnid.inc,v 1.1 2008/12/02 16:34:24 merlinofchaos Exp $ +/** + * Filter by whether the node is the original translation. + */ +class views_handler_filter_node_tnid extends views_handler_filter { + function admin_summary() { } + function option_definition() { + $options = parent::option_definition(); + + $options['operator']['default'] = 1; + + return $options; + } + + /** + * Provide simple boolean operator + */ + function operator_form(&$form, &$form_state) { + $form['operator'] = array( + '#type' => 'radios', + '#title' => t('Include untranslated nodes'), + '#default_value' => $this->operator, + '#options' => array( + 1 => t('Yes'), + 0 => t('No'), + ), + ); + } + + function can_expose() { return FALSE; } + + function query() { + $table = $this->ensure_my_table(); + // Select for source translations (tnid = nid). Conditionally, also accept either untranslated nodes (tnid = 0). + $this->query->add_where($this->options['group'], "$table.tnid = $table.nid" . ($this->operator ? " OR $table.tnid = 0" : '')); + } +} + diff --git a/sites/all/modules/views/modules/translation/views_handler_filter_node_tnid_child.inc b/sites/all/modules/views/modules/translation/views_handler_filter_node_tnid_child.inc new file mode 100644 index 0000000000000000000000000000000000000000..6a35c2ebf38b08715d2099ac5a856c5dcb72a2db --- /dev/null +++ b/sites/all/modules/views/modules/translation/views_handler_filter_node_tnid_child.inc @@ -0,0 +1,16 @@ +<?php +// $Id: views_handler_filter_node_tnid_child.inc,v 1.1 2008/12/02 18:57:27 merlinofchaos Exp $ +/** + * Filter by whether the node is not the original translation. + */ +class views_handler_filter_node_tnid_child extends views_handler_filter { + function admin_summary() { } + function operator_form(&$form, &$form_state) { } + function can_expose() { return FALSE; } + + function query() { + $table = $this->ensure_my_table(); + $this->query->add_where($this->options['group'], "$table.tnid <> $table.nid AND $table.tnid > 0"); + } +} + diff --git a/sites/all/modules/views/modules/translation/views_handler_relationship_translation.inc b/sites/all/modules/views/modules/translation/views_handler_relationship_translation.inc new file mode 100644 index 0000000000000000000000000000000000000000..448de5a6376de90cd76d931f576bee89047d9345 --- /dev/null +++ b/sites/all/modules/views/modules/translation/views_handler_relationship_translation.inc @@ -0,0 +1,97 @@ +<?php +// $Id: views_handler_relationship_translation.inc,v 1.1 2008/09/30 22:07:15 merlinofchaos Exp $ + +/** + * Handles relationships for content translation sets and provides multiple + * options. + */ +class views_handler_relationship_translation extends views_handler_relationship { + function option_definition() { + $options = parent::option_definition(); + $options['language'] = array('default' => 'current'); + + return $options; + } + + /** + * Add a translation selector. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $options = array( + 'all' => t('All'), + 'current' => t('Current language'), + 'default' => t('Default language'), + ); + $options = array_merge($options, locale_language_list()); + $form['language'] = array( + '#type' => 'select', + '#options' => $options, + '#default_value' => $this->options['language'], + '#title' => t('Translation option'), + '#description' => t('The translation options allows you to select which translation or translations in a translation set join on. Select "Current language" or "Default language" to join on the translation in the current or default language respectively. Select a specific language to join on a translation in that language. If you select "All", each translation will create a new row, which may appear to cause duplicates.'), + ); + } + + /** + * Called to implement a relationship in a query. + */ + function query() { + // Figure out what base table this relationship brings to the party. + $table_data = views_fetch_data($this->definition['base']); + $base_field = empty($this->definition['base field']) ? $table_data['table']['base']['field'] : $this->definition['base field']; + + $this->ensure_my_table(); + + $def = $this->definition; + $def['table'] = $this->definition['base']; + $def['field'] = $base_field; + $def['left_table'] = $this->table_alias; + $def['left_field'] = $this->field; + if (!empty($this->options['required'])) { + $def['type'] = 'INNER'; + } + + $def['extra'] = array(); + if ($this->options['language'] != 'all') { + switch ($this->options['language']) { + case 'current': + $def['extra'][] = array( + 'field' => 'language', + 'value' => '***CURRENT_LANGUAGE***', + ); + break; + case 'default': + $def['extra'][] = array( + 'field' => 'language', + 'value' => '***DEFAULT_LANGUAGE***', + ); + break; + // Other values will be the language codes. + default: + $def['extra'][] = array( + 'field' => 'language', + 'value' => $this->options['language'], + ); + break; + } + } + + if (!empty($def['join_handler']) && class_exists($def['join_handler'])) { + $join = new $def['join_handler']; + } + else { + $join = new views_join(); + } + + $join->definition = $def; + $join->construct(); + $join->adjusted = TRUE; + + // use a short alias for this: + $alias = $def['table'] . '_' . $this->table; + + $this->alias = $this->query->add_relationship($alias, $join, $this->definition['base'], $this->relationship); + } +} diff --git a/sites/all/modules/views/modules/upload.views.inc b/sites/all/modules/views/modules/upload.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..57f3f31ceaf53677df1aa1afb1d7cda30ab77a4f --- /dev/null +++ b/sites/all/modules/views/modules/upload.views.inc @@ -0,0 +1,142 @@ +<?php +// $Id: upload.views.inc,v 1.16.4.5 2010/07/19 09:18:42 dereine Exp $ +/** + * @file + * + * Provide views data and handlers for upload tables that are not represented by + * their own module. + */ + +/** + * @defgroup views_upload_module upload.module handlers + * + * @{ + */ + +/** + * Implements hook_views_data() + */ +function upload_views_data() { + $data = array(); + + // ---------------------------------------------------------------------- + // upload table + + $data['upload']['table']['group'] = t('Upload'); + + $data['upload']['table']['join'] = array( + 'node' => array( + 'left_field' => 'vid', + 'field' => 'vid', + ), + 'node_revisions' => array( + 'left_field' => 'vid', + 'field' => 'vid', + ), + 'file_managed' => array( + 'left_field' => 'fid', + 'field' => 'fid', + ), + ); + + $data['upload']['vid'] = array( + 'title' => t('Node'), + 'help' => t('The node the uploaded file is attached to'), + 'relationship' => array( + 'label' => t('upload'), + 'base' => 'node', + 'base field' => 'vid', + // This allows us to not show this relationship if the base is already + // node so users won't create circular relationships. + 'skip base' => array('node', 'node_revisions'), + ), + ); + + $data['upload']['description'] = array( + 'title' => t('Description'), + 'help' => t('The description of the uploaded file.'), + 'field' => array( + 'handler' => 'views_handler_field_upload_description', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + $data['upload']['list'] = array( + 'title' => t('Listed'), + 'help' => t('Whether or not the file is marked to be listed.'), + 'field' => array( + 'handler' => 'views_handler_field_boolean', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_boolean_operator', + 'label' => t('Published'), + 'type' => 'yes-no', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + $data['upload']['weight'] = array( + 'title' => t('Weight'), + 'help' => t('The weight, used for sorting.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + ); + + return $data; +} + +/** + * Implements hook_views_data_alter() + */ +function upload_views_data_alter(&$data) { + $data['node']['upload_fid'] = array( + 'group' => t('Upload'), + 'title' => t('Attached files'), + 'help' => t('All files attached to a node with upload.module.'), + 'real field' => 'vid', + 'field' => array( + 'handler' => 'views_handler_field_upload_fid', + 'no group by' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_upload_fid', + 'title' => t('Has attached files'), + 'type' => 'yes-no', + 'help' => t('Only display items with attached files. This can cause duplicates if there are multiple attached files.'), + ), + 'relationship' => array( + 'title' => t('Attached files'), + 'help' => t('Add a relationship to gain access to more file data for files uploaded by upload.module. Note that this relationship will cause duplicate nodes if there are multiple files attached to the node.'), + 'relationship table' => 'upload', + 'relationship field' => 'fid', + 'base' => 'file_managed', + 'base field' => 'fid', + 'handler' => 'views_handler_relationship', + 'label' => t('Files'), + ), + ); +} + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/upload.views_convert.inc b/sites/all/modules/views/modules/upload.views_convert.inc new file mode 100644 index 0000000000000000000000000000000000000000..1ee2b2e23cdaf7ccc987c98fa0cef7ea559ad2d0 --- /dev/null +++ b/sites/all/modules/views/modules/upload.views_convert.inc @@ -0,0 +1,108 @@ +<?php +//$Id: upload.views_convert.inc,v 1.4.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * @file + * Field conversion for fields handled by this module. + */ + +/** + * Implements 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 upload_views_convert($display, $type, &$view, $field, $id = NULL) { + switch ($type) { + case 'field': + switch ($field['tablename']) { + case 'file_revisions': + switch ($field['field']) { + case 'fid': + $relationship = $view->add_item($display, 'relationship', 'node', 'upload_fid', array(), 'node_upload_fid'); + $view->set_item_option($display, 'field', $id, 'relationship', $relationship); + $view->set_item_option($display, 'field', $id, 'table', 'files'); + break; + } + break; + case 'files': + switch ($field['field']) { + case 'all_files': + $item = $view->get_item($display, 'field', $id); + switch ($field['options']) { + case 'link': + $item['link_to_file'] = TRUE; + break; + case 'linkdesc': + $item['link_to_file'] = TRUE; + case 'nolinkdesc': + $item['alter']['alter_text'] = TRUE; + $item['alter']['text'] = '['. $view->add_item($display, 'field', 'upload', 'description', array('exclude' => TRUE)) .']'; + break; + } + if ($field['handler'] == 'views_handler_file_listed_files') { + $item['only_listed'] = TRUE; + } + $item['table'] = 'node'; + $item['field'] = 'upload_fid'; + $view->set_item($display, 'field', $id, $item); + break; + case 'filename': + if ($field['handler'] == 'views_handler_file_filename_download') { + $view->set_item_option($display, 'field', $id, 'link_to_file', TRUE); + } + $relationship = $view->add_item($display, 'relationship', 'node', 'upload_fid', array(), 'node_upload_fid'); + $view->set_item_option($display, 'field', $id, 'relationship', $relationship); + break; + } + break; + } + break; + case 'filter': + switch ($field['tablename']) { + case 'file_revisions': + switch ($field['field']) { + case 'fid': + $view->set_item_option($display, 'filter', $id, 'table', 'node'); + $view->set_item_option($display, 'filter', $id, 'field', 'upload_fid'); + break; + case 'list': + $view->set_item_option($display, 'filter', $id, 'table', 'upload'); + break; + } + break; + case 'files': + switch ($field['field']) { + case 'filename': + case 'filemime': + $item = $view->get_item($display, 'filter', $id); + $item['operator'] = $field['operator']; + $item['case'] = FALSE; + $item['relationship'] = $view->add_item($display, 'relationship', 'node', 'upload_fid', array(), 'node_upload_fid'); + $view->set_item($display, 'filter', $id, $item); + break; + case 'filesize': + $relationship = $view->add_item($display, 'relationship', 'node', 'upload_fid', array(), 'node_upload_fid'); + $view->set_item_option($display, 'filter', $id, 'relationship', $relationship); + $view->set_item_option($display, 'filter', $id, 'operator', $field['operator']); + break; + } + break; + } + break; + case 'sorts': + switch ($field['tablename']) { + case 'file_revisions': + switch ($field['field']) { + case 'fid': + $relationship = $view->add_item($display, 'relationship', 'node', 'upload_fid', array(), 'node_upload_fid'); + $view->set_item_option($display, 'field', $id, 'relationship', $relationship); + $view->set_item_option($display, 'field', $id, 'table', 'files'); + break; + } + break; + } + break; + } +} diff --git a/sites/all/modules/views/modules/upload/views_handler_field_upload_description.inc b/sites/all/modules/views/modules/upload/views_handler_field_upload_description.inc new file mode 100644 index 0000000000000000000000000000000000000000..24ecc0c25bb4d6a6f7eff4db36838ed757b7ce44 --- /dev/null +++ b/sites/all/modules/views/modules/upload/views_handler_field_upload_description.inc @@ -0,0 +1,73 @@ +<?php +// $Id: views_handler_field_upload_description.inc,v 1.5.4.3 2010/12/03 20:46:32 dereine Exp $ + +/** + * Field handler to provide a list of roles. + */ +class views_handler_field_upload_description extends views_handler_field { + function init(&$view, &$options) { + parent::init($view, $options); + if (!empty($options['link_to_file'])) { + $this->additional_fields['fid'] = 'fid'; + } + } + + function option_definition() { + $options = parent::option_definition(); + $options['link_to_file'] = array('default' => FALSE); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_to_file'] = array( + '#title' => t('Link this field to download the file'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['link_to_file']), + ); + } + + function pre_render(&$values) { + if (empty($this->options['link_to_file'])) { + return; + } + + $fids = array(); + $this->items = array(); + + $data = array(); + foreach ($values as $result) { + if ($result->{$this->aliases['fid']}) { + $fids[] = $result->{$this->aliases['fid']}; + } + } + + if ($fids) { + $result = db_query("SELECT f.fid, f.uri FROM {files} f WHERE f.fid IN (:fids)", array(':fids' => $fids)); + foreach ($result as $file) { + $this->items[$file->fid] = $file; + } + } + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->field_alias}), $values); + } + + /** + * Render whatever the data is as a link to the file. + * + * Data should be made XSS safe prior to calling this function. + */ + function render_link($data, $value) { + if (!empty($this->options['link_to_file']) && $value->{$this->aliases['fid']} && $data !== NULL && $data !== '') { + $values = $this->items[$value->{$this->aliases['fid']}]; + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = file_create_url($values->uri); + } + else { + $this->options['alter']['make_link'] = FALSE; + } + return $data; + } +} diff --git a/sites/all/modules/views/modules/upload/views_handler_field_upload_fid.inc b/sites/all/modules/views/modules/upload/views_handler_field_upload_fid.inc new file mode 100644 index 0000000000000000000000000000000000000000..566cfe21893f0e2ceec96c8b7989dcd98a9b5e8f --- /dev/null +++ b/sites/all/modules/views/modules/upload/views_handler_field_upload_fid.inc @@ -0,0 +1,88 @@ +<?php +// $Id: views_handler_field_upload_fid.inc,v 1.10.4.5 2010/12/03 20:46:32 dereine Exp $ +/** + * Field handler to provide a list of roles. + */ +class views_handler_field_upload_fid extends views_handler_field_prerender_list { + function construct() { + parent::construct(); + } + + function option_definition() { + $options = parent::option_definition(); + $options['link_to_file'] = array('default' => FALSE); + $options['only_listed'] = array('default' => FALSE); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_to_file'] = array( + '#title' => t('Link this field to download the file'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['link_to_file']), + ); + + $form['only_listed'] = array( + '#title' => t('Only show "listed" file attachments'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['only_listed']), + ); + } + + function pre_render(&$values) { + $vids = array(); + $this->items = array(); + + foreach ($values as $result) { + $vids[] = $result->{$this->field_alias}; + } + + if ($vids) { + // Support "only listed files" option. + $where = ''; + if (!empty($this->options['only_listed'])) { + $where = " AND u.list <> 0"; + } + $result = db_query("SELECT u.vid, u.fid, f.filename, f.uri, f.filesize, f.filemime, u.description FROM {upload} u LEFT JOIN {file_managed} f ON f.fid = u.fid WHERE u.vid IN (" . implode(', ', $vids) . ")$where ORDER BY u.weight")->fetchAssoc(); + foreach ($result as $file) { + $file['filename'] = check_plain($file['filename']); + $file['filemime'] = check_plain($file['filemime']); + $file['description'] = check_plain($file['description']); + $file['filesize'] = format_size($file['filesize']); + $file['uri'] = file_create_url($file['uri']); + if (!empty($this->options['link_to_file']) ) { + $file['make_link'] = TRUE; + $file['path'] = $file['uri']; + } + $this->items[$file['vid']][$file['fid']] = $file; + } + } + } + + function render_item($count, $item) { + return $item['description']; + } + + function document_self_tokens(&$tokens) { + $tokens['[' . $this->options['id'] . '-fid' . ']'] = t('The file ID for the file.'); + $tokens['[' . $this->options['id'] . '-name' . ']'] = t('The name of the attached file.'); + $tokens['[' . $this->options['id'] . '-type' . ']'] = t('The MIME type of the attached file.'); + $tokens['[' . $this->options['id'] . '-description' . ']'] = t('The name of the attached file.'); + $tokens['[' . $this->options['id'] . '-path' . ']'] = t('The path of the attached file.'); + $tokens['[' . $this->options['id'] . '-url' . ']'] = t('The url of the attached file.'); + $tokens['[' . $this->options['id'] . '-uri' . ']'] = t('The path of the attached file.'); + $tokens['[' . $this->options['id'] . '-size' . ']'] = t('The size of the attached file.'); + } + + function add_self_tokens(&$tokens, $item) { + $tokens['[' . $this->options['id'] . '-fid' . ']'] = $item['fid']; + $tokens['[' . $this->options['id'] . '-name' . ']'] = $item['filename']; + $tokens['[' . $this->options['id'] . '-type' . ']'] = $item['filemime']; + $tokens['[' . $this->options['id'] . '-description' . ']'] = $item['description']; + $tokens['[' . $this->options['id'] . '-path' . ']'] = $item['uri']; + $tokens['[' . $this->options['id'] . '-url' . ']'] = url($item['uri']); + $tokens['[' . $this->options['id'] . '-uri' . ']'] = $item['uri']; + $tokens['[' . $this->options['id'] . '-size' . ']'] = $item['filesize']; + } +} diff --git a/sites/all/modules/views/modules/upload/views_handler_filter_upload_fid.inc b/sites/all/modules/views/modules/upload/views_handler_filter_upload_fid.inc new file mode 100644 index 0000000000000000000000000000000000000000..e05ce80f4ca9be73bc4eda1e56a4dc921b14ea87 --- /dev/null +++ b/sites/all/modules/views/modules/upload/views_handler_filter_upload_fid.inc @@ -0,0 +1,18 @@ +<?php +// $Id: views_handler_filter_upload_fid.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $ + +/** + * Filter by whether or not a node has attached files from the upload module + */ +class views_handler_filter_upload_fid extends views_handler_filter_boolean_operator { + function construct() { + parent::construct(); + $this->value_value = t('Has attached files'); + } + + function query() { + $this->ensure_my_table(); + $this->query->add_where($this->options['group'], "(SELECT COUNT(*) FROM {upload} u WHERE u.vid = $this->table_alias.$this->real_field) " . (empty($this->value) ? '=' : '<>') . " 0"); + } +} + diff --git a/sites/all/modules/views/modules/user.views.inc b/sites/all/modules/views/modules/user.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..68a60e4fac272721a0cbd333bf96745c1cda5947 --- /dev/null +++ b/sites/all/modules/views/modules/user.views.inc @@ -0,0 +1,434 @@ +<?php +//$Id: user.views.inc,v 1.59.4.13 2010/09/22 21:31:29 dereine Exp $ +/** + * @file + * Provide views data and handlers for user.module + */ + +/** + * @defgroup views_user_module user.module handlers + * + * @{ + */ + +/** + * Implements hook_views_data() + */ +function user_views_data() { + // ---------------------------------------------------------------- + // users table + + // Define the base group of this table. Fields that don't + // have a group defined will go into this field by default. + $data['users']['table']['group'] = t('User'); + + $data['users']['table']['base'] = array( + 'field' => 'uid', + 'title' => t('User'), + 'help' => t('Users who have created accounts on your site.'), + 'access query tag' => 'user_access', + ); + + $data['users']['table']['join'] = array( + 'node' => array( + 'left_field' => 'uid', + 'field' => 'uid', + 'type' => 'INNER', // all nodes have an author. + ), + // This goes to the node so that we have consistent authorship. + 'node_revisions' => array( + 'left_table' => 'node', + 'left_field' => 'uid', + 'field' => 'uid', + 'type' => 'INNER', // all nodes have an author. + ), + ); + + // uid + $data['users']['uid'] = array( + 'title' => t('Uid'), + 'help' => t('The user ID'), // The help that appears on the UI, + 'field' => array( + 'handler' => 'views_handler_field_user', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_user_uid', + 'name field' => 'name', // display this field in the summary + ), + 'filter' => array( + 'title' => t('Name'), + 'handler' => 'views_handler_filter_user_name', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'relationship' => array( + 'title' => t('Nodes authored'), + 'help' => t('Relate nodes to the user who created it. This relationship will create one record for every node created by the user.'), + 'handler' => 'views_handler_relationship', + 'base' => 'node', + 'base field' => 'uid', + 'field' => 'uid', + 'label' => t('nodes'), + ), + ); + + // uid + $data['users']['uid_current'] = array( + 'real field' => 'uid', + 'title' => t('Current'), + 'help' => t('Filter the view to the currently logged in user.'), + 'filter' => array( + 'handler' => 'views_handler_filter_user_current', + 'type' => 'yes-no', + ), + ); + + // name + $data['users']['name'] = array( + 'title' => t('Name'), // The item it appears as on the UI, + 'help' => t('The user or author name.'), // The help that appears on the UI, + 'field' => array( + 'handler' => 'views_handler_field_user_name', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + 'title' => t('Name (raw)'), + 'help' => t('The user or author name. This filter does not check if the user exists and allows partial matching. Does not utilize autocomplete.') + ), + ); + + // mail + // Note that this field implements field level access control. + $data['users']['mail'] = array( + 'title' => t('E-mail'), // The item it appears as on the UI, + 'help' => t('Email address for a given user. This field is normally not shown to users, so be cautious when using it.'), // The help that appears on the UI, + 'field' => array( + 'handler' => 'views_handler_field_user_mail', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + // language + $data['users']['language'] = array( + 'title' => t('Language'), // The item it appears as on the UI, + 'help' => t('Language of the user'), + 'field' => array( + 'handler' => 'views_handler_field_user_language', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_node_language', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_node_language', + ), + ); + + // picture + $data['users']['picture'] = array( + 'title' => t('Picture'), + 'help' => t("The user's picture, if allowed."), // The help that appears on the UI, + // Information for displaying the uid + 'field' => array( + 'handler' => 'views_handler_field_user_picture', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_boolean_operator_string', + 'label' => t('Has Avatar'), + 'type' => 'yes-no', + ), + ); + + // created field + $data['users']['created'] = array( + 'title' => t('Created date'), // The item it appears as on the UI, + 'help' => t('The date the user was created.'), // The help that appears on the UI, + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + ); + + // access field + $data['users']['access'] = array( + 'title' => t('Last access'), // The item it appears as on the UI, + 'help' => t("The user's last access date."), // The help that appears on the UI, + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + ); + + // login field + $data['users']['login'] = array( + 'title' => t('Last login'), // The item it appears as on the UI, + 'help' => t("The user's last login date."), // The help that appears on the UI, + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + ); + + // active status + $data['users']['status'] = array( + 'title' => t('Active'), // The item it appears as on the UI, + 'help' => t('Whether a user is active or blocked.'), // The help that appears on the UI, + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_boolean', + 'click sortable' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_boolean_operator', + 'label' => t('Active'), + 'type' => 'yes-no', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + + // log field + $data['users']['signature'] = array( + 'title' => t('Signature'), // The item it appears as on the UI, + 'help' => t("The user's signature."), // The help that appears on the UI, + // Information for displaying a title as a field + 'field' => array( + 'handler' => 'views_handler_field_markup', + 'format' => filter_fallback_format(), + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + ); + + $data['users']['edit_node'] = array( + 'field' => array( + 'title' => t('Edit link'), + 'help' => t('Provide a simple link to edit the user.'), + 'handler' => 'views_handler_field_user_link_edit', + ), + ); + + $data['users']['delete_node'] = array( + 'field' => array( + 'title' => t('Delete link'), + 'help' => t('Provide a simple link to delete the user.'), + 'handler' => 'views_handler_field_user_link_delete', + ), + ); + + // ---------------------------------------------------------------------- + // users_roles table + + $data['users_roles']['table']['group'] = t('User'); + + // Explain how this table joins to others. + $data['users_roles']['table']['join'] = array( + // Directly links to users table. + 'users' => array( + 'left_field' => 'uid', + 'field' => 'uid', + ), + 'node' => array( + 'left_field' => 'uid', + 'field' => 'uid', + ), + 'node_revisions' => array( + 'left_table' => 'node', + 'left_field' => 'uid', + 'field' => 'uid', + ), + ); + + $data['users_roles']['rid'] = array( + 'title' => t('Roles'), + 'help' => t('Roles that a user belongs to.'), + 'field' => array( + 'handler' => 'views_handler_field_user_roles', + 'no group by' => TRUE, + ), + 'filter' => array( + 'handler' => 'views_handler_filter_user_roles', + 'numeric' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_users_roles_rid', + 'name table' => 'role', + 'name field' => 'name', + 'empty field name' => t('No role'), + 'zero is null' => TRUE, + 'numeric' => TRUE, + ), + ); + + // ---------------------------------------------------------------------- + // role table + + $data['role']['table']['join'] = array( + // Directly links to users table. + 'users' => array( + 'left_table' => 'users_roles', + 'left_field' => 'rid', + 'field' => 'rid', + ), + // needed for many to one helper sometimes + 'users_roles' => array( + 'left_field' => 'rid', + 'field' => 'rid', + ), + 'node' => array( + 'left_table' => 'users_roles', + 'left_field' => 'rid', + 'field' => 'rid', + ), + 'node_revisions' => array( + 'left_table' => 'users_roles', + 'left_field' => 'rid', + 'field' => 'rid', + ), + ); + + // ---------------------------------------------------------------------- + // authmap table + + $data['authmap']['table']['group'] = t('User'); + $data['authmap']['table']['join'] = array( + // Directly links to users table. + 'users' => array( + 'left_field' => 'uid', + 'field' => 'uid', + ), + 'node' => array( + 'left_table' => 'users', + 'left_field' => 'uid', + 'field' => 'uid', + ), + ); + $data['authmap']['aid'] = array( + 'title' => t('Authmap ID'), + 'help' => t('The Authmap ID.'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + 'numeric' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + 'numeric' => TRUE, + ), + ); + $data['authmap']['authname'] = array( + 'title' => t('Authentication name'), + 'help' => t('The unique authentication name.'), + 'field' => array( + 'handler' => 'views_handler_field', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + $data['authmap']['module'] = array( + 'title' => t('Authentication module'), + 'help' => t('The name of the module managing the authentication entry.'), + 'field' => array( + 'handler' => 'views_handler_field', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + ); + + return $data; +} + +/** + * Implements hook_views_plugins + */ +function user_views_plugins() { + return array( + 'module' => 'views', // This just tells our themes are elsewhere. + 'argument default' => array( + 'user' => array( + 'title' => t('User ID from URL'), + 'handler' => 'views_plugin_argument_default_user', + 'path' => drupal_get_path('module', 'views') . '/modules/user', // not necessary for most modules + ), + 'current_user' => array( + 'title' => t('User ID from logged in user'), + 'handler' => 'views_plugin_argument_default_current_user', + 'path' => drupal_get_path('module', 'views') . '/modules/user', // not necessary for most modules + ), + ), + 'argument validator' => array( + 'user' => array( + 'title' => t('User'), + 'handler' => 'views_plugin_argument_validate_user', + 'path' => drupal_get_path('module', 'views') . '/modules/user', // not necessary for most modules + ), + ), + ); +} + +/** + * Allow replacement of current userid so we can cache these queries + */ +function user_views_query_substitutions($view) { + global $user; + return array('***CURRENT_USER***' => intval($user->uid)); +} + +/** + * @} + */ diff --git a/sites/all/modules/views/modules/user.views_convert.inc b/sites/all/modules/views/modules/user.views_convert.inc new file mode 100644 index 0000000000000000000000000000000000000000..4d5f95307edaf7be05a905d829f41275a5eaac31 --- /dev/null +++ b/sites/all/modules/views/modules/user.views_convert.inc @@ -0,0 +1,61 @@ +<?php +// $Id: user.views_convert.inc,v 1.3.4.1 2009/11/02 22:01:26 merlinofchaos Exp $ + +/** + * @file + * Field conversion for fields handled by this module. + */ + +/** + * Implements hook_views_convert(). + */ +function user_views_convert($display, $type, &$view, $field, $id = NULL) { + switch ($type) { + case 'field': + switch ($field['tablename']) { + case 'users': + switch ($field['field']) { + case 'uid': + $view->set_item_option($display, 'field', $id, 'field', 'picture'); + break; + } + break; + } + break; + case 'filter': + if ($field['tablename'] == 'users' || !strncmp($field['tablename'], 'users_role_', 11)) { + switch ($field['field']) { + case 'uid': + $operators = array('OR' => 'IN', 'NOR' => 'NOT IN'); + $view->set_item_option($display, 'filter', $id, 'operator', $operators[$field['operator']]); + if ($rid = (integer) substr($field['tablename'], 11)) { + $view->add_item($display, 'filter', 'users_roles', 'rid', array('value' => $rid)); + } + break; + } + } + elseif ($field['tablename'] == 'users_roles') { + switch ($field['field']) { + case 'rid': + $operators = array('AND' => 'and', 'OR' => 'or', 'NOR' => 'not'); + $view->set_item_option($display, 'filter', $id, 'operator', $operators[$field['operator']]); + break; + } + } + break; + case 'argument': + $options = $field['argoptions']; + switch ($field['type']) { + case 'uid': + $view->add_item($display, 'argument', 'users', 'uid', $options, $field['id']); + break; + case 'uidtouch': + $view->add_item($display, 'argument', 'node', 'uid_touch', $options, $field['id']); + break; + case 'username': + $view->add_item($display, 'argument', 'users', 'name', $options, $field['id']); + break; + } + break; + } +} diff --git a/sites/all/modules/views/modules/user/views_handler_argument_user_uid.inc b/sites/all/modules/views/modules/user/views_handler_argument_user_uid.inc new file mode 100644 index 0000000000000000000000000000000000000000..a53456a20dd258dee619d0b06bf7aacb7146f551 --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_argument_user_uid.inc @@ -0,0 +1,29 @@ +<?php +// $Id: views_handler_argument_user_uid.inc,v 1.1.6.1 2009/11/02 22:01:27 merlinofchaos Exp $ +/** + * @file + * Provide user uid argument handler. + */ + +/** + * Argument handler to accept a user id. + */ +class views_handler_argument_user_uid extends views_handler_argument_numeric { + /** + * Override the behavior of title(). Get the name of the user. + */ + function title_query() { + if (!$this->argument) { + return array(variable_get('anonymous', t('Anonymous'))); + } + + $titles = array(); + + $result = db_query("SELECT u.name FROM {users} u WHERE u.uid IN (:uids)", array(':uids' => $this->value)); + foreach ($result as $term) { + $titles[] = check_plain($term->name); + } + return $titles; + } +} + diff --git a/sites/all/modules/views/modules/user/views_handler_argument_users_roles_rid.inc b/sites/all/modules/views/modules/user/views_handler_argument_users_roles_rid.inc new file mode 100644 index 0000000000000000000000000000000000000000..1657d68e684e839225e845dd638ce129f1924080 --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_argument_users_roles_rid.inc @@ -0,0 +1,17 @@ +<?php +// $Id: views_handler_argument_users_roles_rid.inc,v 1.1.6.1 2009/11/02 22:01:27 merlinofchaos Exp $ +/** + * Allow role ID(s) as argument + */ +class views_handler_argument_users_roles_rid extends views_handler_argument_many_to_one { + function title_query() { + $titles = array(); + + $result = db_query("SELECT name FROM {role} WHERE rid IN (:rids)", array(':rids' => $this->value)); + foreach ($result as $term) { + $titles[] = check_plain($term->name); + } + return $titles; + } +} + diff --git a/sites/all/modules/views/modules/user/views_handler_field_user.inc b/sites/all/modules/views/modules/user/views_handler_field_user.inc new file mode 100644 index 0000000000000000000000000000000000000000..ebf1de2a3c2f819ca3ef9cd543c5c74a89169fc0 --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_field_user.inc @@ -0,0 +1,48 @@ +<?php +// $Id: views_handler_field_user.inc,v 1.3 2009/01/30 00:01:42 merlinofchaos Exp $ + +/** + * Field handler to provide simple renderer that allows linking to a user. + */ +class views_handler_field_user extends views_handler_field { + /** + * Override init function to provide generic option to link to user. + */ + function init(&$view, &$data) { + parent::init($view, $data); + if (!empty($this->options['link_to_user'])) { + $this->additional_fields['uid'] = 'uid'; + } + } + + function option_definition() { + $options = parent::option_definition(); + $options['link_to_user'] = array('default' => TRUE); + return $options; + } + + /** + * Provide link to node option + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_to_user'] = array( + '#title' => t('Link this field to its user'), + '#description' => t('This will override any other link you have set.'), + '#type' => 'checkbox', + '#default_value' => $this->options['link_to_user'], + ); + } + + function render_link($data, $values) { + if (!empty($this->options['link_to_user']) && user_access('access user profiles') && $values->{$this->aliases['uid']} && $data !== NULL && $data !== '') { + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "user/" . $values->{$this->aliases['uid']}; + } + return $data; + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->field_alias}), $values); + } +} diff --git a/sites/all/modules/views/modules/user/views_handler_field_user_language.inc b/sites/all/modules/views/modules/user/views_handler_field_user_language.inc new file mode 100644 index 0000000000000000000000000000000000000000..850911cc41ad99bbafe862d2846459ac74f0d0a9 --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_field_user_language.inc @@ -0,0 +1,29 @@ +<?php +// $Id: views_handler_field_user_language.inc,v 1.1.6.1 2009/11/02 22:01:27 merlinofchaos Exp $ +/** + * @file + * Views field handler for userlanguage. + */ + +class views_handler_field_user_language extends views_handler_field_user { + + function render_link($data, $values) { + if (!empty($this->options['link_to_user']) && user_access('access user profiles') && $values->{$this->aliases['uid']}) { + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = 'user/' . $values->{$this->aliases['uid']}; + } + if (empty($data)) { + $lang = language_default(); + } + else { + $lang = language_list(); + $lang = $lang[$data]; + } + + return check_plain($lang->name); + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->field_alias}), $values); + } +} diff --git a/sites/all/modules/views/modules/user/views_handler_field_user_link.inc b/sites/all/modules/views/modules/user/views_handler_field_user_link.inc new file mode 100644 index 0000000000000000000000000000000000000000..98e7e71fdc05aec9cd9f515fdcf77dae11ed4534 --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_field_user_link.inc @@ -0,0 +1,51 @@ +<?php +// $Id: views_handler_field_user_link.inc,v 1.1.6.2 2010/11/30 20:36:01 merlinofchaos Exp $ +/** + * Field handler to present a link to the user. + */ +class views_handler_field_user_link extends views_handler_field { + function construct() { + parent::construct(); + $this->additional_fields['uid'] = 'uid'; + } + + function option_definition() { + $options = parent::option_definition(); + $options['text'] = array('default' => '', 'translatable' => TRUE); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['text'] = array( + '#type' => 'textfield', + '#title' => t('Text to display'), + '#default_value' => $this->options['text'], + ); + } + + // An example of field level access control. + function access() { + return user_access('access user profiles'); + } + + function query() { + $this->ensure_my_table(); + $this->add_additional_fields(); + } + + function render($values) { + return $this->render_link(check_plain($values->{$this->aliases['uid']}), $values); + } + + function render_link($data, $values) { + $uid = $values->{$this->aliases['uid']}; + $text = !empty($this->options['text']) ? $this->options['text'] : t('view'); + + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "user/" . $uid; + + return $text; + } + +} diff --git a/sites/all/modules/views/modules/user/views_handler_field_user_link_delete.inc b/sites/all/modules/views/modules/user/views_handler_field_user_link_delete.inc new file mode 100644 index 0000000000000000000000000000000000000000..bf138d612f168b6d45ef6e244f61890e916b324c --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_field_user_link_delete.inc @@ -0,0 +1,24 @@ +<?php +// $Id: views_handler_field_user_link_delete.inc,v 1.1.6.1 2010/11/18 07:29:03 dereine Exp $ +/** + * Field handler to present a link to user delete. + */ +class views_handler_field_user_link_delete extends views_handler_field_user_link { + // An example of field level access control. + function access() { + return user_access('administer users'); + } + + function render_link($data, $values) { + $uid = $values->{$this->aliases['uid']}; + $this->options['alter']['make_link'] = TRUE; + + $text = !empty($this->options['text']) ? $this->options['text'] : t('delete'); + + $this->options['alter']['path'] = "user/$uid/delete"; + $this->options['alter']['query'] = drupal_get_destination(); + + return $text; + } +} + diff --git a/sites/all/modules/views/modules/user/views_handler_field_user_link_edit.inc b/sites/all/modules/views/modules/user/views_handler_field_user_link_edit.inc new file mode 100644 index 0000000000000000000000000000000000000000..928070a35537a68c4223331162b742b2c527ed22 --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_field_user_link_edit.inc @@ -0,0 +1,26 @@ +<?php +// $Id: views_handler_field_user_link_edit.inc,v 1.1.6.2 2010/11/18 07:29:03 dereine Exp $ +/** + * Field handler to present a link to user edit. + */ +class views_handler_field_user_link_edit extends views_handler_field_user_link { + + function render_link($data, $values) { + $uid = $values->{$this->aliases['uid']}; + // Build a pseudo account object to be able to check the access. + $account = new stdClass(); + $account->uid = $uid; + + if ($uid && user_edit_access($account)) { + $this->options['alter']['make_link'] = TRUE; + + $text = !empty($this->options['text']) ? $this->options['text'] : t('edit'); + + $this->options['alter']['path'] = "user/$uid/edit"; + $this->options['alter']['query'] = drupal_get_destination(); + + return $text; + } + } +} + diff --git a/sites/all/modules/views/modules/user/views_handler_field_user_mail.inc b/sites/all/modules/views/modules/user/views_handler_field_user_mail.inc new file mode 100644 index 0000000000000000000000000000000000000000..013f0aaaa8df4679be19a235fb4402aacf19461b --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_field_user_mail.inc @@ -0,0 +1,37 @@ +<?php +// $Id: views_handler_field_user_mail.inc,v 1.1.6.1 2010/11/18 07:29:03 dereine Exp $ +/** + * Field handler to provide acess control for the email field + */ +class views_handler_field_user_mail extends views_handler_field_user { + function option_definition() { + $options = parent::option_definition(); + $options['link_to_user'] = array('default' => 'mailto'); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['link_to_user'] = array( + '#title' => t('Link this field'), + '#type' => 'radios', + '#options' => array( + 0 => t('No link'), + 'user' => t('To the user'), + 'mailto' => t("With a mailto:"), + ), + '#default_value' => $this->options['link_to_user'], + ); + } + + function render_link($data, $values) { + parent::render_link(check_plain($values->{$this->field_alias}), $values); + + if ($this->options['link_to_user'] == 'mailto') { + $this->options['alter']['make_link'] = TRUE; + $this->options['alter']['path'] = "mailto:" . $data; + } + + return $data; + } +} diff --git a/sites/all/modules/views/modules/user/views_handler_field_user_name.inc b/sites/all/modules/views/modules/user/views_handler_field_user_name.inc new file mode 100644 index 0000000000000000000000000000000000000000..6008eb6e2e1f1d207c76ee5093331c96ebff9b9b --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_field_user_name.inc @@ -0,0 +1,63 @@ +<?php +// $Id: views_handler_field_user_name.inc,v 1.2.6.3 2010/11/05 07:20:54 dereine Exp $ +/** + * Field handler to provide simple renderer that allows using a themed user link + */ +class views_handler_field_user_name extends views_handler_field_user { + /** + * Add uid in the query so we can test for anonymous if needed. + */ + function init(&$view, &$data) { + parent::init($view, $data); + if (!empty($this->options['overwrite_anonymous'])) { + $this->additional_fields['uid'] = 'uid'; + } + } + + function option_definition() { + $options = parent::option_definition(); + + $options['overwrite_anonymous'] = array('default' => FALSE); + $options['anonymous_text'] = array('default' => '', 'translatable' => TRUE); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $form['overwrite_anonymous'] = array( + '#title' => t('Overwrite the value to display for anonymous users'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['overwrite_anonymous']), + '#description' => t('If selected, you will see a field to enter the text to use for anonymous users.'), + ); + $form['anonymous_text'] = array( + '#title' => t('Text to display for anonymous users'), + '#type' => 'textfield', + '#default_value' => $this->options['anonymous_text'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-options-overwrite-anonymous' => array(1), + ), + ); + } + + function render_link($data, $values) { + if (!empty($this->options['link_to_user']) || !empty($this->options['overwrite_anonymous'])) { + $account = new stdClass(); + $account->uid = $values->{$this->aliases['uid']}; + if (!empty($this->options['overwrite_anonymous']) && !$account->uid) { + // This is an anonymous user, and we're overriting the text. + return check_plain($this->options['anonymous_text']); + } + elseif (!empty($this->options['link_to_user'])) { + $account->name = $values->{$this->field_alias}; + return theme('username', array('account' => $account)); + } + } + // Otherwise, there's no special handling, so return the data directly. + return $data; + } +} + diff --git a/sites/all/modules/views/modules/user/views_handler_field_user_picture.inc b/sites/all/modules/views/modules/user/views_handler_field_user_picture.inc new file mode 100644 index 0000000000000000000000000000000000000000..2a470ed980522c19eeb360e9ad48aaa080439a7f --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_field_user_picture.inc @@ -0,0 +1,29 @@ +<?php +// $Id: views_handler_field_user_picture.inc,v 1.1.6.5 2010/12/16 18:23:42 dereine Exp $ + +/** + * Field handler to provide simple renderer that allows using a themed user link + */ +class views_handler_field_user_picture extends views_handler_field { + function construct() { + parent::construct(); + $this->additional_fields['uid'] = 'uid'; + $this->additional_fields['name'] = 'name'; + $this->additional_fields['mail'] = 'mail'; + } + + function element_type($none_supported = FALSE, $default_empty = FALSE) { + return 'div'; + } + + function render($values) { + // Fake an account object. + $account = new stdClass(); + $account->uid = $values->{$this->aliases['uid']}; + $account->name = $values->{$this->aliases['name']}; + $account->mail = $values->{$this->aliases['mail']}; + $account->picture = $values->{$this->field_alias}; + + return theme('user_picture', array('account' => $account)); + } +} diff --git a/sites/all/modules/views/modules/user/views_handler_field_user_roles.inc b/sites/all/modules/views/modules/user/views_handler_field_user_roles.inc new file mode 100644 index 0000000000000000000000000000000000000000..f121f21c228ff0c7edb335b6bcdc31b9df45f198 --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_field_user_roles.inc @@ -0,0 +1,48 @@ +<?php +// $Id: views_handler_field_user_roles.inc,v 1.2.4.2 2010/12/03 20:46:32 dereine Exp $ +/** + * Field handler to provide a list of roles. + */ +class views_handler_field_user_roles extends views_handler_field_prerender_list { + function construct() { + parent::construct(); + $this->additional_fields['uid'] = array('table' => 'users', 'field' => 'uid'); + } + + function query() { + $this->add_additional_fields(); + $this->field_alias = $this->aliases['uid']; + } + + function pre_render(&$values) { + $uids = array(); + $this->items = array(); + + foreach ($values as $result) { + $uids[] = $result->{$this->aliases['uid']}; + } + + if ($uids) { + $result = db_query("SELECT u.uid, u.rid, r.name FROM {role} r INNER JOIN {users_roles} u ON u.rid = r.rid WHERE u.uid IN (:uids) ORDER BY r.name", + array(':uids' => $uids)); + foreach ($result as $role) { + $this->items[$role->uid][$role->rid]['role'] = check_plain($role->name); + $this->items[$role->uid][$role->rid]['rid'] = $role->rid; + } + } + } + + function render_item($count, $item) { + return $item['role']; + } + + function document_self_tokens(&$tokens) { + $tokens['[' . $this->options['id'] . '-role' . ']'] = t('The name of the role.'); + $tokens['[' . $this->options['id'] . '-rid' . ']'] = t('The role ID of the role.'); + } + + function add_self_tokens(&$tokens, $item) { + $tokens['[' . $this->options['id'] . '-role' . ']'] = $item['role']; + $tokens['[' . $this->options['id'] . '-rid' . ']'] = $item['rid']; + } +} diff --git a/sites/all/modules/views/modules/user/views_handler_filter_user_current.inc b/sites/all/modules/views/modules/user/views_handler_filter_user_current.inc new file mode 100644 index 0000000000000000000000000000000000000000..e1dfb75bce40e8c6b741edd88d0cfe5fe3930d46 --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_filter_user_current.inc @@ -0,0 +1,30 @@ +<?php +// $Id: views_handler_filter_user_current.inc,v 1.2.4.2 2010/09/24 05:34:15 dereine Exp $ + +/** + * Filter handler for the current user + */ +class views_handler_filter_user_current extends views_handler_filter_boolean_operator { + function construct() { + parent::construct(); + $this->value_value = t('Is the logged in user'); + } + + function query() { + $this->ensure_my_table(); + + $field = $this->table_alias . '.' . $this->real_field . ' '; + $or = db_or(); + + if (empty($this->value)) { + $or->condition($field, '***CURRENT_USER***', '<>'); + if ($this->accept_null) { + $or->isNull($field); + } + } + else { + $or->condition($field, '***CURRENT_USER***', '='); + } + $this->query->add_where($this->options['group'], $or); + } +} diff --git a/sites/all/modules/views/modules/user/views_handler_filter_user_name.inc b/sites/all/modules/views/modules/user/views_handler_filter_user_name.inc new file mode 100644 index 0000000000000000000000000000000000000000..a38a97f33607a6a1c0190c427d21268c2127a1f7 --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_filter_user_name.inc @@ -0,0 +1,144 @@ +<?php +// $Id: views_handler_filter_user_name.inc,v 1.2.6.2 2010/08/26 09:41:55 dereine Exp $ + +/** + * Filter handler for usernames + */ +class views_handler_filter_user_name extends views_handler_filter_in_operator { + var $no_single = TRUE; + + function value_form(&$form, &$form_state) { + $values = array(); + if ($this->value) { + $result = db_query("SELECT * FROM {users} u WHERE uid IN (:uids)", array(':uids' => $this->value)); + foreach ($result as $account) { + if ($account->uid) { + $values[] = $account->name; + } + else { + $values[] = 'Anonymous'; // Intentionally NOT translated. + } + } + } + + sort($values); + $default_value = implode(', ', $values); + $form['value'] = array( + '#type' => 'textfield', + '#title' => t('Usernames'), + '#description' => t('Enter a comma separated list of user names.'), + '#default_value' => $default_value, + '#autocomplete_path' => 'admin/views/ajax/autocomplete/user', + ); + + if (!empty($form_state['exposed']) && !isset($form_state['input'][$this->options['expose']['identifier']])) { + $form_state['input'][$this->options['expose']['identifier']] = $default_value; + } + } + + function value_validate($form, &$form_state) { + $values = drupal_explode_tags($form_state['values']['options']['value']); + $uids = $this->validate_user_strings($form['value'], $values); + + if ($uids) { + $form_state['values']['options']['value'] = $uids; + } + } + + function accept_exposed_input($input) { + $rc = parent::accept_exposed_input($input); + + if ($rc) { + // If we have previously validated input, override. + if (isset($this->validated_exposed_input)) { + $this->value = $this->validated_exposed_input; + } + } + + return $rc; + } + + function exposed_validate(&$form, &$form_state) { + if (empty($this->options['exposed'])) { + return; + } + + if (empty($this->options['expose']['identifier'])) { + return; + } + + $identifier = $this->options['expose']['identifier']; + $values = drupal_explode_tags($form_state['values'][$identifier]); + + $uids = $this->validate_user_strings($form[$identifier], $values); + + if ($uids) { + $this->validated_exposed_input = $uids; + } + } + + /** + * Validate the user string. Since this can come from either the form + * or the exposed filter, this is abstracted out a bit so it can + * handle the multiple input sources. + */ + function validate_user_strings(&$form, $values) { + $uids = array(); + $placeholders = array(); + $args = array(); + $results = array(); + foreach ($values as $value) { + if (strtolower($value) == 'anonymous') { + $uids[] = 0; + } + else { + $missing[strtolower($value)] = TRUE; + $args[] = $value; + $placeholders[] = "'%s'"; + } + } + + if (!$args) { + return $uids; + } + + $result = db_query("SELECT * FROM {users} WHERE name IN (:names)", array(':names' => $args)); + foreach ($result as $account) { + unset($missing[strtolower($account->name)]); + $uids[] = $account->uid; + } + + if ($missing) { + form_error($form, format_plural(count($missing), 'Unable to find user: @users', 'Unable to find users: @users', array('@users' => implode(', ', array_keys($missing))))); + } + + return $uids; + } + + function value_submit() { + // prevent array filter from removing our anonymous user. + } + + // Override to do nothing. + function get_value_options() { } + + function admin_summary() { + // set up $this->value_options for the parent summary + $this->value_options = array(); + + if ($this->value) { + $result = db_query("SELECT * FROM {users} u WHERE uid IN (:uids)", array(':uids' => $this->value)); + + foreach ($result as $account) { + if ($account->uid) { + $this->value_options[$account->uid] = $account->name; + } + else { + $this->value_options[$account->uid] = 'Anonymous'; // Intentionally NOT translated. + } + } + } + + return parent::admin_summary(); + } +} diff --git a/sites/all/modules/views/modules/user/views_handler_filter_user_roles.inc b/sites/all/modules/views/modules/user/views_handler_filter_user_roles.inc new file mode 100644 index 0000000000000000000000000000000000000000..3978632970dd6efd449e6d3bfe473834e6faac89 --- /dev/null +++ b/sites/all/modules/views/modules/user/views_handler_filter_user_roles.inc @@ -0,0 +1,11 @@ +<?php +// $Id: views_handler_filter_user_roles.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $ +/** + * Filter handler for user roles + */ +class views_handler_filter_user_roles extends views_handler_filter_many_to_one { + function get_value_options() { + $this->value_options = user_roles(TRUE); + unset($this->value_options[DRUPAL_AUTHENTICATED_RID]); + } +} diff --git a/sites/all/modules/views/modules/user/views_plugin_argument_default_current_user.inc b/sites/all/modules/views/modules/user/views_plugin_argument_default_current_user.inc new file mode 100644 index 0000000000000000000000000000000000000000..f2ca6de414570fc508331b331f4a6f26c51acf79 --- /dev/null +++ b/sites/all/modules/views/modules/user/views_plugin_argument_default_current_user.inc @@ -0,0 +1,19 @@ +<?php +// $Id: views_plugin_argument_default_current_user.inc,v 1.1.6.1 2010/01/28 22:44:36 dereine Exp $ +/** + * @file + * Contains the current user argument default plugin. + */ + +/** + * Default argument plugin to extract the global $user + * + * This plugin actually has no options so it odes not need to do a great deal. + */ +class views_plugin_argument_default_current_user extends views_plugin_argument_default { + function get_argument() { + global $user; + return $user->uid; + } +} + diff --git a/sites/all/modules/views/modules/user/views_plugin_argument_default_user.inc b/sites/all/modules/views/modules/user/views_plugin_argument_default_user.inc new file mode 100644 index 0000000000000000000000000000000000000000..dee52c0b8bb30408dd804368fd64b5eab6f8aa8b --- /dev/null +++ b/sites/all/modules/views/modules/user/views_plugin_argument_default_user.inc @@ -0,0 +1,71 @@ +<?php +// $Id: views_plugin_argument_default_user.inc,v 1.1.6.2 2010/12/14 00:00:52 merlinofchaos Exp $ +/** + * @file + * Contains the user from URL argument default plugin. + */ + +/** + * Default argument plugin to extract a user via menu_get_object + */ +class views_plugin_argument_default_user extends views_plugin_argument_default { + function option_definition() { + $options = parent::option_definition(); + $options['user'] = array('default' => '', 'bool' => TRUE, 'translatable' => FALSE); + + return $options; + } + + function options_form(&$form, &$form_state) { + $form['user'] = array( + '#type' => 'checkbox', + '#title' => t('Also look for a node and use the node author'), + '#default_value' => $this->options['user'], + ); + } + + function convert_options(&$options) { + if (!isset($options['user']) && isset($this->argument->options['default_argument_user'])) { + $options['user'] = $this->argument->options['default_argument_user']; + } + } + + function get_argument() { + foreach (range(1, 3) as $i) { + $user = menu_get_object('user', $i); + if (!empty($user)) { + return $user->uid; + } + } + + foreach (range(1, 3) as $i) { + $user = menu_get_object('user_uid_optional', $i); + if (!empty($user)) { + return $user->uid; + } + } + + if (!empty($this->options['user'])) { + foreach (range(1, 3) as $i) { + $node = menu_get_object('node', $i); + if (!empty($node)) { + return $node->uid; + } + } + } + + if (arg(0) == 'user' && is_numeric(arg(1))) { + return arg(1); + } + + if (!empty($this->options['user'])) { + if (arg(0) == 'node' && is_numeric(arg(1))) { + $node = node_load(arg(1)); + if ($node) { + return $node->uid; + } + } + } + } +} + diff --git a/sites/all/modules/views/modules/user/views_plugin_argument_validate_user.inc b/sites/all/modules/views/modules/user/views_plugin_argument_validate_user.inc new file mode 100644 index 0000000000000000000000000000000000000000..3cf78655bc994e7979e4c0bdaa6f0834a3e33507 --- /dev/null +++ b/sites/all/modules/views/modules/user/views_plugin_argument_validate_user.inc @@ -0,0 +1,125 @@ +<?php +// $Id: views_plugin_argument_validate_user.inc,v 1.2.6.10 2010/11/05 07:20:54 dereine Exp $ + +/** + * Validate whether an argument is a valid user. + * + * This supports either numeric arguments (UID) or strings (username) and + * converts either one into the user's UID. This validator also sets the + * argument's title to the username. + */ +class views_plugin_argument_validate_user extends views_plugin_argument_validate { + function option_definition() { + $options = parent::option_definition(); + $options['type'] = array('default' => 'uid'); + $options['restrict_roles'] = array('default' => FALSE); + $options['roles'] = array('default' => array()); + + return $options; + } + + function options_form(&$form, &$form_state) { + $form['type'] = array( + '#type' => 'radios', + '#title' => t('Type of user argument to allow'), + '#options' => array( + 'uid' => t('Only allow numeric UIDs'), + 'name' => t('Only allow string usernames'), + 'either' => t('Allow both numeric UIDs and string usernames'), + ), + '#default_value' => $this->options['type'], + ); + + $form['restrict_roles'] = array( + '#type' => 'checkbox', + '#title' => t('Restrict user based on role'), + '#default_value' => $this->options['restrict_roles'], + ); + + $form['roles'] = array( + '#type' => 'checkboxes', + '#prefix' => '<div id="edit-options-argument-validate-user-roles-wrapper">', + '#suffix' => '</div>', + '#title' => t('Restrict to the selected roles'), + '#options' => user_roles(TRUE), + '#default_value' => $this->options['roles'], + '#description' => t('If no roles are selected, users from any role will be allowed.'), + '#process' => array('form_process_checkboxes', 'ctools_dependent_process'), + '#dependency' => array( + 'edit-options-argument-validate-user-restrict-roles' => array(1), + ), + ); + } + + function options_submit(&$form, &$form_state, &$options) { + // filter trash out of the options so we don't store giant unnecessary arrays + $options['roles'] = array_filter($options['roles']); + } + + function convert_options(&$options) { + if (!isset($options['type']) && isset($this->argument->options['validate_user_argument_type'])) { + $options['type'] = $this->argument->options['validate_user_argument_type']; + $options['restrict_roles'] = $this->argument->options['validate_user_restrict_roles']; + $options['roles'] = $this->argument->options['validate_user_roles']; + } + } + + function validate_argument($argument) { + $type = $this->options['type']; + // is_numeric() can return false positives, so we ensure it's an integer. + // However, is_integer() will always fail, since $argument is a string. + if (is_numeric($argument) && $argument == (int)$argument) { + if ($type == 'uid' || $type == 'either') { + if ($argument == $GLOBALS['user']->uid) { + // If you assign an object to a variable in PHP, the variable + // automatically acts as a reference, not a copy, so we use + // clone to ensure that we don't actually mess with the + // real global $user object. + $account = clone $GLOBALS['user']; + } + $where = 'uid = :argument'; + } + } + else { + if ($type == 'name' || $type == 'either') { + if ($argument == $GLOBALS['user']->name) { + $account = clone $GLOBALS['user']; + } + $where = "name = :argument"; + } + } + + // If we don't have a WHERE clause, the argument is invalid. + if (empty($where)) { + return FALSE; + } + + if (!isset($account)) { + $query = "SELECT uid, name FROM {users} WHERE $where"; + $account = db_query($query, array(':argument' => $argument))->fetchObject(); + } + if (empty($account)) { + // User not found. + return FALSE; + } + + // See if we're filtering users based on roles. + if (!empty($this->options['restrict_roles']) && !empty($this->options['roles'])) { + $roles = $this->options['roles']; + $account->roles = array(); + $account->roles[] = $account->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID; + $result = db_query('SELECT rid FROM {users_roles} WHERE uid = :uid', array(':uid' => $account->uid)); + foreach ($result as $role) { + $account->roles[] = $role->rid; + } + if (!(bool) array_intersect($account->roles, $roles)) { + return FALSE; + } + } + + $this->argument->argument = $account->uid; + $this->argument->validated_title = check_plain($account->name); + return TRUE; + } +} + diff --git a/sites/all/modules/views/modules/views.views.inc b/sites/all/modules/views/modules/views.views.inc new file mode 100644 index 0000000000000000000000000000000000000000..e686c8c18d87de19f4658604e093009cfcb19880 --- /dev/null +++ b/sites/all/modules/views/modules/views.views.inc @@ -0,0 +1,78 @@ +<?php +// $Id: views.views.inc,v 1.7.4.4 2010/11/05 21:55:20 dereine Exp $ +/** + * @file + * Provide views data and handlers that aren't tied to any other module. + */ + +/** + * @defgroup views_views_module miscellaneous handlers + * + * @{ + */ + +/** + * Implements hook_views_data() + */ +function views_views_data() { + $data['views']['table']['group'] = t('Global'); + $data['views']['table']['join'] = array( + '#global' => array(), + ); + + $data['views']['random'] = array( + 'title' => t('Random'), + 'help' => t('Randomize the display order.'), + 'sort' => array( + 'handler' => 'views_handler_sort_random', + ), + ); + + $data['views']['null'] = array( + 'title' => t('Null'), + 'help' => t('Allow an argument to be ignored. The query will not be altered by this argument.'), + 'argument' => array( + 'handler' => 'views_handler_argument_null', + ), + ); + + $data['views']['nothing'] = array( + 'title' => t('Custom text'), + 'help' => t('Provide custom text or link.'), + 'field' => array( + 'handler' => 'views_handler_field_custom', + ), + ); + + $data['views']['counter'] = array( + 'title' => t('View result counter'), + 'help' => t('Displays the actual position of the view result'), + 'field' => array( + 'handler' => 'views_handler_field_counter', + ), + ); + + $data['views']['area'] = array( + 'title' => t('Text area'), + 'help' => t('Provide markup text for the area.'), + 'area' => array( + 'handler' => 'views_handler_area_text', + ), + ); + + if (module_invoke('ctools', 'api_version', '1.7.1')) { + $data['views']['expression'] = array( + 'title' => t('Math expression'), + 'help' => t('Evaluates a mathematical expression and displays it.'), + 'field' => array( + 'handler' => 'views_handler_field_math', + ), + ); + } + + return $data; +} + +/** + * @} + */ diff --git a/sites/all/modules/views/plugins/views_plugin_access.inc b/sites/all/modules/views/plugins/views_plugin_access.inc new file mode 100644 index 0000000000000000000000000000000000000000..af8c1a299efa259be7bf85c863cdafcc83728814 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_access.inc @@ -0,0 +1,82 @@ +<?php +// $Id: views_plugin_access.inc,v 1.1.6.1 2009/11/13 23:19:22 dereine Exp $ + +/** + * The base plugin to handle access control. + * + * @ingroup views_access_plugins + */ +class views_plugin_access extends views_plugin { + /** + * Initialize the plugin. + * + * @param $view + * The view object. + * @param $display + * The display handler. + */ + function init(&$view, &$display) { + $this->view = &$view; + $this->display = &$display; + + if (is_object($display->handler)) { + $options = $display->handler->get_option('access'); + // Overlay incoming options on top of defaults + $this->unpack_options($this->options, $options); + } + } + + /** + * Retrieve the options when this is a new access + * control plugin + */ + function option_definition() { return array(); } + + /** + * Provide the default form for setting options. + */ + function options_form(&$form, &$form_state) { } + + /** + * Provide the default form form for validating options + */ + function options_validate(&$form, &$form_state) { } + + /** + * Provide the default form form for submitting options + */ + function options_submit(&$form, &$form_state) { } + + /** + * Return a string to display as the clickable title for the + * access control. + */ + function summary_title() { + return t('Unknown'); + } + + /** + * Determine if the current user has access or not. + */ + function access($account) { + // default to no access control. + return TRUE; + } + + /** + * Determine the access callback and arguments. + * + * This information will be embedded in the menu in order to reduce + * performance hits during menu item access testing, which happens + * a lot. + * + * @return an array; the first item should be the function to call, + * and the second item should be an array of arguments. The first + * item may also be TRUE (bool only) which will indicate no + * access control.) + */ + function get_access_callback() { + // default to no access control. + return TRUE; + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_access_none.inc b/sites/all/modules/views/plugins/views_plugin_access_none.inc new file mode 100644 index 0000000000000000000000000000000000000000..f39d76c704cb0cad411e0ca25664beb661cc7052 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_access_none.inc @@ -0,0 +1,11 @@ +<?php +// $Id: views_plugin_access_none.inc,v 1.1 2008/09/08 22:50:17 merlinofchaos Exp $ + +/** + * Access plugin that provides no access control at all. + */ +class views_plugin_access_none extends views_plugin_access { + function summary_title() { + return t('Unrestricted'); + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_access_perm.inc b/sites/all/modules/views/plugins/views_plugin_access_perm.inc new file mode 100644 index 0000000000000000000000000000000000000000..27a392a7f254f245980937b57a1095ae028d8fbf --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_access_perm.inc @@ -0,0 +1,45 @@ +<?php +// $Id: views_plugin_access_perm.inc,v 1.3.6.3 2010/03/10 21:03:19 merlinofchaos Exp $ + +/** + * Access plugin that provides permission-based access control. + */ +class views_plugin_access_perm extends views_plugin_access { + function access($account) { + return views_check_perm($this->options['perm'], $account); + } + + function get_access_callback() { + return array('views_check_perm', array($this->options['perm'])); + } + + function summary_title() { + return t($this->options['perm']); + } + + + function option_definition() { + $options = parent::option_definition(); + $options['perm'] = array('default' => 'access content'); + + return $options; + } + + function options_form(&$form, &$form_state) { + $perms = array(); + // Get list of permissions + foreach (module_implements('permission') as $module) { + $permissions = module_invoke($module, 'permission'); + foreach ($permissions as $name => $perm) { + $perms[$module][$name] = $perm['title']; + } + } + $form['perm'] = array( + '#type' => 'select', + '#options' => $perms, + '#title' => t('Permission'), + '#default_value' => $this->options['perm'], + '#description' => t('Only users with the selected permission flag will be able to access this display. Note that users with "access all views" can see any view, regardless of other permissions.'), + ); + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_access_role.inc b/sites/all/modules/views/plugins/views_plugin_access_role.inc new file mode 100644 index 0000000000000000000000000000000000000000..5a278d57351950959ed21e028d4e1d0e1e44dc22 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_access_role.inc @@ -0,0 +1,62 @@ +<?php +// $Id: views_plugin_access_role.inc,v 1.2.6.3 2010/03/10 21:03:19 merlinofchaos Exp $ + +/** + * Access plugin that provides role-based access control. + */ +class views_plugin_access_role extends views_plugin_access { + function access($account) { + return views_check_roles(array_filter($this->options['role']), $account); + } + + function get_access_callback() { + return array('views_check_roles', array(array_filter($this->options['role']))); + } + + function summary_title() { + $count = count($this->options['role']); + if ($count < 1) { + return t('No role(s) selected'); + } + elseif ($count > 1) { + return t('Multiple roles'); + } + else { + $rids = views_ui_get_roles(); + $rid = array_shift($this->options['role']); + return $rids[$rid]; + } + } + + + function option_definition() { + $options = parent::option_definition(); + $options['role'] = array('default' => array()); + + return $options; + } + + function options_form(&$form, &$form_state) { + $form['role'] = array( + '#type' => 'checkboxes', + '#title' => t('Role'), + '#default_value' => $this->options['role'], + '#options' => views_ui_get_roles(), + '#description' => t('Only the checked roles will be able to access this display. Note that users with "access all views" can see any view, regardless of role.'), + ); + } + + function options_validate(&$form, &$form_state) { + if (!array_filter($form_state['values']['access_options']['role'])) { + form_error($form['role'], t('You must select at least one role if type is "by role"')); + } + } + + function options_submit(&$form, &$form_state) { + // I hate checkboxes. + $form_state['values']['access_options']['role'] = array_filter($form_state['values']['access_options']['role']); + } +} + + + diff --git a/sites/all/modules/views/plugins/views_plugin_argument_default.inc b/sites/all/modules/views/plugins/views_plugin_argument_default.inc new file mode 100644 index 0000000000000000000000000000000000000000..d47fc9982617abfc355765f0d624239f4211acce --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_argument_default.inc @@ -0,0 +1,97 @@ +<?php +// $Id: views_plugin_argument_default.inc,v 1.2.4.2 2010/01/28 22:44:37 dereine Exp $ +/** + * @file + * Contains the fixed argument default plugin. + */ + +/** + * @defgroup views_argument_default_plugins Views' argument default plugins + * @{ + * + * Allow specialized methods of filling in arguments when they aren't + * provided. + * + * @see hook_views_plugins + */ + +/** + * The fixed argument default handler; also used as the base. + */ +class views_plugin_argument_default extends views_plugin { + /** + * Return the default argument. + * + * This needs to be overridden by every default argument handler to properly do what is needed. + */ + function get_argument() { } + + /** + * Initialize this plugin with the view and the argument + * it is linked to. + */ + function init(&$view, &$argument, $options) { + $this->view = &$view; + $this->argument = &$argument; + + $this->convert_options($options); + $this->unpack_options($this->options, $options); + } + + /** + * Retrieve the options when this is a new access + * control plugin + */ + function option_definition() { return array(); } + + /** + * Provide the default form for setting options. + */ + function options_form(&$form, &$form_state) { } + + /** + * Provide the default form form for validating options + */ + function options_validate(&$form, &$form_state) { } + + /** + * Provide the default form form for submitting options + */ + function options_submit(&$form, &$form_state) { } + + /** + * Determine if the administrator has the privileges to use this + * plugin + */ + function access() { return TRUE; } + + /** + * If we don't have access to the form but are showing it anyway, ensure that + * the form is safe and cannot be changed from user input. + * + * This is only called by child objects if specified in the options_form(), + * so it will not always be used. + */ + function check_access(&$form, $option_name) { + if (!$this->access()) { + $form[$option_name]['#disabled'] = TRUE; + $form[$option_name]['#value'] = $form[$this->option_name]['#default_value']; + $form[$option_name]['#description'] .= ' <strong>' . t('Note: you do not have permission to modify this. If you change the default argument type, this setting will be lost and you will NOT be able to get it back.') . '</strong>'; + } + } + + /** + * Convert options from the older style. + * + * In Views 3, the method of storing default argument options has changed + * and each plugin now gets its own silo. This method can be used to + * move arguments from the old style to the new style. See + * views_plugin_argument_default_fixed for a good example of this method. + */ + function convert_options(&$options) { } +} + +/** + * @} + */ + diff --git a/sites/all/modules/views/plugins/views_plugin_argument_default_fixed.inc b/sites/all/modules/views/plugins/views_plugin_argument_default_fixed.inc new file mode 100644 index 0000000000000000000000000000000000000000..0598f56ceca694e543f6d575ae8915ba28c5db67 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_argument_default_fixed.inc @@ -0,0 +1,44 @@ +<?php +// $Id: views_plugin_argument_default_fixed.inc,v 1.1.4.2 2010/01/28 22:45:04 dereine Exp $ +/** + * @file + * Contains the fixed argument default plugin. + */ + +/** + * The fixed argument default handler. + */ +class views_plugin_argument_default_fixed extends views_plugin_argument_default { + function option_definition() { + $options = parent::option_definition(); + $options['argument'] = array('default' => ''); + + return $options; + } + + function options_form(&$form, &$form_state) { + $form['argument'] = array( + '#type' => 'textfield', + '#title' => t('Default argument'), + '#default_value' => $this->options['argument'], + ); + } + + /** + * Return the default argument. + */ + function get_argument() { + return $this->options['argument']; + } + + function convert_options(&$options) { + if (!isset($options['argument']) && isset($this->argument->options['default_argument_fixed'])) { + $options['argument'] = $this->argument->options['default_argument_fixed']; + } + } +} + +/** + * @} + */ + diff --git a/sites/all/modules/views/plugins/views_plugin_argument_default_php.inc b/sites/all/modules/views/plugins/views_plugin_argument_default_php.inc new file mode 100644 index 0000000000000000000000000000000000000000..fee8d7fbcf1e53c59899b47db544c2ebfefc6a68 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_argument_default_php.inc @@ -0,0 +1,55 @@ +<?php +// $Id: views_plugin_argument_default_php.inc,v 1.1.6.4 2010/11/05 07:20:54 dereine Exp $ +/** + * @file + * Contains the php code argument default plugin. + */ + +/** + * Default argument plugin to provide a PHP code block. + */ +class views_plugin_argument_default_php extends views_plugin_argument_default { + function option_definition() { + $options = parent::option_definition(); + $options['code'] = array('default' => ''); + + return $options; + } + + function options_form(&$form, &$form_state) { + $form['code'] = array( + '#type' => 'textarea', + '#title' => t('PHP argument code'), + '#default_value' => $this->options['code'], + '#process' => array('ctools_dependent_process'), + '#description' => t('Enter PHP code that returns a value to use for this argument. Do not use <?php ?>. You must return only a single value for just this argument.'), + ); + + // Only do this if using one simple standard form gadget + $this->check_access($form, 'code'); + } + + function convert_options(&$options) { + if (!isset($options['code']) && isset($this->argument->options['default_argument_php'])) { + $options['code'] = $this->argument->options['default_argument_php']; + } + } + + /** + * Only let users with PHP block visibility permissions set/modify this + * default plugin. + */ + function access() { + return user_access('use PHP for settings'); + } + + function get_argument() { + // set up variables to make it easier to reference during the argument. + $view = &$this->view; + $argument = &$this->argument; + ob_start(); + $result = eval($this->options['code']); + ob_end_clean(); + return $result; + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_argument_validate.inc b/sites/all/modules/views/plugins/views_plugin_argument_validate.inc new file mode 100644 index 0000000000000000000000000000000000000000..2cabb5789f8aa8657550b2132cce170eeefe9822 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_argument_validate.inc @@ -0,0 +1,93 @@ +<?php +// $Id: views_plugin_argument_validate.inc,v 1.2.4.2 2010/01/28 22:44:37 dereine Exp $ +/** + * @file + * Contains the base argument validator plugin. + */ + +/** + * @defgroup views_argument_validate_plugins Views' argument validate plugins + * @{ + * + * Allow specialized methods of validating arguments. + * + * @see hook_views_plugins + */ + +/** + * Base argument validator plugin to provide basic functionality. + * + * @ingroup views_argument_validate_plugins + */ +class views_plugin_argument_validate extends views_plugin { + + /** + * Initialize this plugin with the view and the argument + * it is linked to. + */ + function init(&$view, &$argument, $options) { + $this->view = &$view; + $this->argument = &$argument; + + $this->convert_options($options); + $this->unpack_options($this->options, $options); + } + + /** + * Retrieve the options when this is a new access + * control plugin + */ + function option_definition() { return array(); } + + /** + * Provide the default form for setting options. + */ + function options_form(&$form, &$form_state) { } + + /** + * Provide the default form form for validating options + */ + function options_validate(&$form, &$form_state) { } + + /** + * Provide the default form form for submitting options + */ + function options_submit(&$form, &$form_state) { } + + /** + * Convert options from the older style. + * + * In Views 3, the method of storing default argument options has changed + * and each plugin now gets its own silo. This method can be used to + * move arguments from the old style to the new style. See + * views_plugin_argument_default_fixed for a good example of this method. + */ + function convert_options(&$options) { } + + /** + * Determine if the administrator has the privileges to use this plugin + */ + function access() { return TRUE; } + + /** + * If we don't have access to the form but are showing it anyway, ensure that + * the form is safe and cannot be changed from user input. + * + * This is only called by child objects if specified in the options_form(), + * so it will not always be used. + */ + function check_access(&$form, $option_name) { + if (!$this->access()) { + $form[$option_name]['#disabled'] = TRUE; + $form[$option_name]['#value'] = $form[$this->option_name]['#default_value']; + $form[$option_name]['#description'] .= ' <strong>' . t('Note: you do not have permission to modify this. If you change the default argument type, this setting will be lost and you will NOT be able to get it back.') . '</strong>'; + } + } + + function validate_argument($arg) { return TRUE; } +} + +/** + * @} + */ + diff --git a/sites/all/modules/views/plugins/views_plugin_argument_validate_numeric.inc b/sites/all/modules/views/plugins/views_plugin_argument_validate_numeric.inc new file mode 100644 index 0000000000000000000000000000000000000000..56552371f15f74f5398afa08754f40199f57ed5a --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_argument_validate_numeric.inc @@ -0,0 +1,18 @@ +<?php +// $Id: views_plugin_argument_validate_numeric.inc,v 1.1.6.1 2010/01/28 22:44:37 dereine Exp $ +/** + * @file + * Contains the numeric argument validator plugin. + */ + +/** + * Validate whether an argument is numeric or not. + * + * @ingroup views_argument_validate_plugins + */ +class views_plugin_argument_validate_numeric extends views_plugin_argument_validate { + function validate_argument($argument) { + return is_numeric($argument); + } +} + diff --git a/sites/all/modules/views/plugins/views_plugin_argument_validate_php.inc b/sites/all/modules/views/plugins/views_plugin_argument_validate_php.inc new file mode 100644 index 0000000000000000000000000000000000000000..8f4222b6376733d9703c7605fb7bad5c0fbe18f0 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_argument_validate_php.inc @@ -0,0 +1,57 @@ +<?php +// $Id: views_plugin_argument_validate_php.inc,v 1.1.6.2 2010/01/28 22:44:37 dereine Exp $ +/** + * @file + * Contains the php code argument validator plugin. + */ + +/** + * Provide PHP code to validate whether or not an argument is ok. + * + * @ingroup views_argument_validate_plugins + */ +class views_plugin_argument_validate_php extends views_plugin_argument_validate { + function option_definition() { + $options = parent::option_definition(); + $options['code'] = array('default' => ''); + + return $options; + } + + function options_form(&$form, &$form_state) { + $form['code'] = array( + '#type' => 'textarea', + '#title' => t('PHP validate code'), + '#default_value' => $this->options['code'], + '#description' => t('Enter PHP code that returns TRUE or FALSE. No return is the same as FALSE, so be SURE to return something if you do not want to declare the argument invalid. Do not use <?php ?>. The argument to validate will be "$argument" and the view will be "$view". You may change the argument by setting "$handler->argument". You may change the title used for substitutions for this argument by setting "$argument->validated_title".'), + ); + + $this->check_access($form, 'code'); + } + + /** + * Only let users with PHP block visibility permissions set/modify this + * validate plugin. + */ + function access() { + return user_access('use PHP for settings'); + } + + function convert_options(&$options) { + if (!isset($options['code']) && isset($this->argument->options['validate_argument_php'])) { + $options['code'] = $this->argument->options['validate_argument_php']; + } + } + + function validate_argument($argument) { + // set up variables to make it easier to reference during the argument. + $view = &$this->view; + $handler = &$this->argument; + + ob_start(); + $result = eval($this->options['code']); + ob_end_clean(); + return $result; + } +} + diff --git a/sites/all/modules/views/plugins/views_plugin_cache.inc b/sites/all/modules/views/plugins/views_plugin_cache.inc new file mode 100644 index 0000000000000000000000000000000000000000..1bbed02c03eaea4b2aec52c81d6d6748d0d3a78b --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_cache.inc @@ -0,0 +1,292 @@ +<?php +// $Id: views_plugin_cache.inc,v 1.5.4.5 2010/10/12 23:23:52 merlinofchaos Exp $ + +/** + * The base plugin to handle caching. + * + * @ingroup views_cache_plugins + */ +class views_plugin_cache extends views_plugin { + /** + * Contains all data that should be written/read from cache. + */ + var $storage = array(); + + /** + * What table to store data in. + */ + var $table = 'cache_views_data'; + + /** + * Initialize the plugin. + * + * @param $view + * The view object. + * @param $display + * The display handler. + */ + function init(&$view, &$display) { + $this->view = &$view; + $this->display = &$display; + + if (is_object($display->handler)) { + $options = $display->handler->get_option('cache'); + // Overlay incoming options on top of defaults + $this->unpack_options($this->options, $options); + } + } + + /** + * Return a string to display as the clickable title for the + * access control. + */ + function summary_title() { + return t('Unknown'); + } + + /** + * Determine the expiration time of the cache type, or NULL if no expire. + * + * Plugins must override this to implement expiration. + * + * @param $type + * The cache type, either 'query', 'result' or 'output'. + */ + function cache_expire($type) { } + + /** + * Determine expiration time in the cache table of the cache type + * or CACHE_PERMANENT if item shouldn't be removed automatically from cache. + * + * Plugins must override this to implement expiration in the cache table. + * + * @param $type + * The cache type, either 'query', 'result' or 'output'. + */ + function cache_set_expire($type) { + return CACHE_PERMANENT; + } + + + /** + * Save data to the cache. + * + * A plugin should override this to provide specialized caching behavior. + */ + function cache_set($type) { + switch ($type) { + case 'query': + // Not supported currently, but this is certainly where we'd put it. + break; + case 'results': + $data = array( + 'result' => $this->view->result, + 'total_rows' => isset($this->view->total_rows) ? $this->view->total_rows : 0, + 'current_page' => $this->view->get_current_page(), + ); + cache_set($this->get_results_key(), $data, $this->table, $this->cache_set_expire($type)); + break; + case 'output': + $this->gather_headers(); + $this->storage['output'] = $this->view->display_handler->output; + cache_set($this->get_output_key(), $this->storage, $this->table, $this->cache_set_expire($type)); + break; + } + } + + + /** + * Retrieve data from the cache. + * + * A plugin should override this to provide specialized caching behavior. + */ + function cache_get($type) { + $cutoff = $this->cache_expire($type); + switch ($type) { + case 'query': + // Not supported currently, but this is certainly where we'd put it. + return FALSE; + case 'results': + // Values to set: $view->result, $view->total_rows, $view->execute_time, + // $view->current_page. + if ($cache = cache_get($this->get_results_key(), $this->table)) { + if (!$cutoff || $cache->created > $cutoff) { + $this->view->result = $cache->data['result']; + $this->view->total_rows = $cache->data['total_rows']; + $this->view->set_current_page = $cache->data['current_page']; + $this->view->execute_time = 0; + return TRUE; + } + } + return FALSE; + case 'output': + if ($cache = cache_get($this->get_output_key(), $this->table)) { + if (!$cutoff || $cache->created > $cutoff) { + $this->storage = $cache->data; + $this->view->display_handler->output = $cache->data['output']; + $this->restore_headers(); + return TRUE; + } + } + return FALSE; + } + } + + /** + * Clear out cached data for a view. + * + * We're just going to nuke anything related to the view, regardless of display, + * to be sure that we catch everything. Maybe that's a bad idea. + */ + function cache_flush() { + cache_clear_all($this->view->name . ':', $this->table, TRUE); + } + + /** + * Post process any rendered data. + * + * This can be valuable to be able to cache a view and still have some level of + * dynamic output. In an ideal world, the actual output will include HTML + * comment based tokens, and then the post process can replace those tokens. + * + * Example usage. If it is known that the view is a node view and that the + * primary field will be a nid, you can do something like this: + * + * <!--post-FIELD-NID--> + * + * And then in the post render, create an array with the text that should + * go there: + * + * strtr($output, array('<!--post-FIELD-1-->', 'output for FIELD of nid 1'); + * + * All of the cached result data will be available in $view->result, as well, + * so all ids used in the query should be discoverable. + */ + function post_render(&$output) { } + + /** + * Start caching javascript, css and other out of band info. + * + * This takes a snapshot of the current system state so that we don't + * duplicate it. Later on, when gather_headers() is run, this information + * will be removed so that we don't hold onto it. + */ + function cache_start() { + $this->storage['head'] = drupal_add_html_head(); + $this->storage['css'] = drupal_add_css(); + $js = drupal_add_js(); + foreach ($js as $key => $data) { + if ($data['scope'] == 'header' || $data['scope'] == 'footer') { + $this->storage['js'][$data['scope']][$key] = $data; + } + } + } + + /** + * Gather out of band data, compare it to what we started with and store the difference. + */ + function gather_headers() { + // Simple replacement for head + if (isset($this->storage['head'])) { + $this->storage['head'] = str_replace($this->storage['head'], '', drupal_add_html_head()); + } + else { + $this->storage['head'] = ''; + } + + // Slightly less simple for CSS: + $css = drupal_add_css(); + $start = isset($this->storage['css']) ? $this->storage['css'] : array(); + $this->storage['css'] = array(); + + foreach ($css as $file => $data) { + if (!isset($this->storage['css'][$file])) { + $this->storage['css'][$file] = $data; + } + } + + $js = array(); + // A little less simple for js + foreach (array('header', 'footer') as $scope) { + $js[$scope] = drupal_add_js(NULL, NULL, $scope); + } + + $start = isset($this->storage['js']) ? $this->storage['js'] : array(); + $this->storage['js'] = array(); + +return; // @TODO: fixme + + foreach ($js as $key => $data) { + if (!isset($start[$key][$data['scope']][$key]) && ($data['scope'] == 'header' || $data['scope'] == 'footer')) { + $this->storage['js'][$data['scope']][$key] = $data; + } + } + } + + /** + * Restore out of band data saved to cache. Copied from Panels. + */ + function restore_headers() { + if (!empty($this->storage['head'])) { + drupal_add_html_head($this->storage['head']); + } + if (!empty($this->storage['css'])) { + foreach ($this->storage['css'] as $args) { + call_user_func_array('drupal_add_css', $args); + } + } + if (!empty($this->storage['js'])) { + foreach ($this->storage['js'] as $args) { + drupal_add_js($data); + } + } + } + + function get_results_key() { + global $user; + + if (!isset($this->_results_key)) { + + $build_info = $this->view->build_info; + + foreach (array('query', 'count_query') as $index) { + $query = clone $build_info[$index]; + $query->preExecute(); + $build_info[$index] = (string)$query; + } + $key_data = array( + 'build_info' => $build_info, + 'roles' => array_keys($user->roles), + 'super-user' => $user->uid == 1, // special caching for super user. + 'language' => $GLOBALS['language'], + ); + foreach (array('exposed_info', 'page', 'sort', 'order') as $key) { + if (isset($_GET[$key])) { + $key_data[$key] = $_GET[$key]; + } + } + + $this->_results_key = $this->view->name . ':' . $this->display->id . ':results:' . md5(serialize($key_data)); + } + + return $this->_results_key; + } + + function get_output_key() { + global $user; + if (!isset($this->_output_key)) { + $key_data = array( + 'result' => $this->view->result, + 'roles' => array_keys($user->roles), + 'super-user' => $user->uid == 1, // special caching for super user. + 'theme' => $GLOBALS['theme'], + 'language' => $GLOBALS['language'], + ); + + $this->_output_key = $this->view->name . ':' . $this->display->id . ':output:' . md5(serialize($key_data)); + } + + return $this->_output_key; + } + +} diff --git a/sites/all/modules/views/plugins/views_plugin_cache_none.inc b/sites/all/modules/views/plugins/views_plugin_cache_none.inc new file mode 100644 index 0000000000000000000000000000000000000000..bcfd8a7f59d1b9981e15d09b0d00ecf67637cdaf --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_cache_none.inc @@ -0,0 +1,19 @@ +<?php +// $Id: views_plugin_cache_none.inc,v 1.2.4.1 2009/11/02 22:01:27 merlinofchaos Exp $ + +/** + * Caching plugin that provides no caching at all. + */ +class views_plugin_cache_none extends views_plugin_cache { + function cache_start() { /* do nothing */ } + + function summary_title() { + return t('None'); + } + + function cache_get($type) { + return FALSE; + } + + function cache_set($type) { } +} diff --git a/sites/all/modules/views/plugins/views_plugin_cache_time.inc b/sites/all/modules/views/plugins/views_plugin_cache_time.inc new file mode 100644 index 0000000000000000000000000000000000000000..2857feff699e101c3c5942950fda0256d80397e0 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_cache_time.inc @@ -0,0 +1,59 @@ +<?php +// $Id: views_plugin_cache_time.inc,v 1.3.4.4 2010/11/18 00:56:20 merlinofchaos Exp $ + +/** + * Simple caching of query results for Views displays. + */ +class views_plugin_cache_time extends views_plugin_cache { + function option_definition() { + $options = parent::option_definition(); + $options['results_lifespan'] = array('default' => 3600); + $options['output_lifespan'] = array('default' => 3600); + + return $options; + } + + function options_form(&$form, &$form_state) { + $options = array(60, 300, 1800, 3600, 21600, 518400); + $options = drupal_map_assoc($options, 'format_interval'); + $options = array(-1 => t('Never cache')) + $options; + + $form['results_lifespan'] = array( + '#type' => 'select', + '#title' => t('Query results'), + '#description' => t('The length of time raw query results should be cached.'), + '#options' => $options, + '#default_value' => $this->options['results_lifespan'], + ); + $form['output_lifespan'] = array( + '#type' => 'select', + '#title' => t('Rendered output'), + '#description' => t('The length of time rendered HTML output should be cached.'), + '#options' => $options, + '#default_value' => $this->options['output_lifespan'], + ); + } + + function summary_title() { + return format_interval($this->options['results_lifespan'], 1) . '/' . format_interval($this->options['output_lifespan'], 1); + } + + function cache_expire($type) { + if ($lifespan = $this->options[$type . '_lifespan']) { + $cutoff = REQUEST_TIME - $lifespan; + return $cutoff; + } + else { + return FALSE; + } + } + + function cache_set_expire($type) { + if ($lifespan = $this->options[$type . '_lifespan']) { + return time() + $lifespan; + } + else { + return CACHE_PERMANENT; + } + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_display.inc b/sites/all/modules/views/plugins/views_plugin_display.inc new file mode 100644 index 0000000000000000000000000000000000000000..0660ce06ab98720e527656e67e9c5db421875740 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_display.inc @@ -0,0 +1,2586 @@ +<?php +// $Id: views_plugin_display.inc,v 1.27.4.49 2011/01/05 20:36:27 dereine Exp $ +/** + * @file + * Contains the base display plugin. + */ + +/** + * @defgroup views_display_plugins Views' display plugins + * @{ + * Display plugins control how Views interact with the rest of Drupal. + * + * They can handle creating Views from a Drupal page hook; they can + * handle creating Views from a Drupal block hook. They can also + * handle creating Views from an external module source, such as + * a Panels pane, or an insert view, or a CCK field type. + * + * @see hook_views_plugins + */ + +/** + * The default display plugin handler. Display plugins handle options and + * basic mechanisms for different output methods. + * + * @ingroup views_display_plugins + */ +class views_plugin_display extends views_plugin { + var $handlers = array(); + + function init(&$view, &$display, $options = NULL) { + $this->view = &$view; + $this->display = &$display; + + // Make some modifications: + if (!isset($options) && isset($display->display_options)) { + $options = $display->display_options; + } + + if ($this->is_default_display() && isset($options['defaults'])) { + unset($options['defaults']); + } + + $this->unpack_options($this->options, $options); + + // Translate changed settings: + // Check if any of the previous values now managed by + // pluggable pagers have been changed. + // If yes, perform the conversion + $items_per_page = $this->get_option('items_per_page'); + $offset = $this->get_option('offset'); + $type = $this->get_option('use_pager'); + if ((!empty($items_per_page) && $items_per_page != 10) || !empty($offset) || !empty($type)) { + if (!$type) { + $type = $items_per_page ? 'some' : 'none'; + } + + if ($type == 1) { + $type = 'full'; + } + + $pager = array( + 'type' => $type, + 'options' => array( + 'offset' => $offset + ), + ); + + if ($items_per_page) { + $pager['options']['items_per_page'] = $items_per_page; + } + if ($id = $this->get_option('pager_element')) { + $pager['options']['id'] = $id; + } + + // Unset the previous options + // After edit and save the view they will be erased + $this->set_option('items_per_page', NULL); + $this->set_option('offset', NULL); + $this->set_option('use_pager', NULL); + $this->set_option('pager', $pager); + } + + // Plugable headers, footer and empty texts are + // not compatible with previous version of views + // This code converts old values into a configured handler for each area + foreach (array('header', 'footer', 'empty') as $area) { + $converted = FALSE; + if (isset($this->options[$area]) && !is_array($this->options[$area])) { + if (!empty($this->options[$area])) { + $content = $this->get_option($area); + if (!empty($content) && !is_array($content)) { + $format = $this->get_option($area . '_format'); + $options = array( + 'id' => 'area', + 'table' => 'views', + 'field' => 'area', + 'label' => '', + 'relationship' => 'none', + 'group_type' => 'group', + 'content' => $content, + 'format' => !empty($format) ? $format : filter_default_format(), + ); + + if ($area != 'empty' && $empty = $this->get_option($area . '_empty')) { + $options['empty'] = $empty; + } + $this->set_option($area, array('text' => $options)); + $converted = TRUE; + } + } + // Ensure that options are at least an empty array + if (!$converted) { + $this->set_option($area, array()); + } + } + } + + // Convert distinct setting from display to query settings. + $distinct = $this->get_option('distinct'); + if (!empty($distinct)) { + $query_settings = $this->get_option('query'); + $query_settings['options']['distinct'] = $distinct; + $this->set_option('query', $query_settings); + // Clear the values + $this->set_option('distinct', NULL); + } + } + + function destroy() { + parent::destroy(); + + foreach ($this->handlers as $type => $handlers) { + foreach ($handlers as $id => $handler) { + if (is_object($handler)) { + $this->handlers[$type][$id]->destroy(); + } + } + } + + if (isset($this->default_display)) { + unset($this->default_display); + } + } + + /** + * Determine if this display is the 'default' display which contains + * fallback settings + */ + function is_default_display() { return FALSE; } + + /** + * Determine if this display uses exposed filters, so the view + * will know whether or not to build them. + */ + function uses_exposed() { + if (!isset($this->has_exposed)) { + foreach ($this->handlers as $type => $value) { + foreach ($this->view->$type as $id => $handler) { + if ($handler->can_expose() && $handler->is_exposed()) { + // one is all we need; if we find it, return true. + $this->has_exposed = TRUE; + return TRUE; + } + } + } + $pager = $this->get_plugin('pager'); + if (isset($pager) && $pager->uses_exposed()) { + $this->has_exposed = TRUE; + return TRUE; + } + $this->has_exposed = FALSE; + } + + return $this->has_exposed; + } + + /** + * 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() { + return TRUE; + } + + /** + * Does the display use AJAX? + */ + function use_ajax() { + if (!empty($this->definition['use ajax'])) { + return $this->get_option('use_ajax'); + } + return FALSE; + } + + /** + * Does the display have a pager enabled? + */ + function use_pager() { + $pager = $this->get_plugin('pager'); + if ($pager) { + return $pager->use_pager(); + } + } + + /** + * Does the display have a more link enabled? + */ + function use_more() { + if (!empty($this->definition['use more'])) { + return $this->get_option('use_more'); + } + return FALSE; + } + + /** + * Does the display have a more link enabled? + */ + function use_group_by() { + return $this->get_option('group_by'); + } + + /** + * Should the enabled display more link be shown when no more items? + */ + function use_more_always() { + if (!empty($this->definition['use more'])) { + return $this->get_option('use_more_always'); + } + return FALSE; + } + + /** + * Does the display have custom link text? + */ + function use_more_text() { + if (!empty($this->definition['use more'])) { + return $this->get_option('use_more_text'); + } + return FALSE; + } + + /** + * Can this display accept attachments? + */ + function accept_attachments() { + return !empty($this->definition['accept attachments']); + } + + /** + * Allow displays to attach to other views. + */ + function attach_to($display_id) { } + + /** + * Static member function to list which sections are defaultable + * and what items each section contains. + */ + function defaultable_sections($section = NULL) { + $sections = array( + 'access' => array('access'), + 'cache' => array('cache'), + 'title' => array('title'), + 'enabled' => array('enabled'), + 'css_class' => array('css_class'), + 'use_ajax' => array('use_ajax'), + 'query' => array('query'), + 'items_per_page' => array('items_per_page', 'offset', 'use_pager', 'pager_element'), + 'pager' => array('pager'), + 'use_more' => array('use_more', 'use_more_always', 'use_more_text'), + 'link_display' => array('link_display'), + 'exposed_block' => array('exposed_block'), + 'exposed_form' => array('exposed_form'), + + // Force these to cascade properly. + 'style_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'), + 'style_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'), + 'row_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'), + 'row_options' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'), + + // These guys are special + 'header' => array('header'), + 'footer' => array('footer'), + 'empty' => array('empty'), + 'relationships' => array('relationships'), + 'fields' => array('fields'), + 'sorts' => array('sorts'), + 'arguments' => array('arguments'), + 'filters' => array('filters', 'filter_groups'), + ); + + // If the display cannot use a pager, then we cannot default it. + if (empty($this->definition['use pager'])) { + unset($sections['pager']); + unset($sections['items_per_page']); + } + + if ($section) { + if (!empty($sections[$section])) { + return $sections[$section]; + } + } + else { + return $sections; + } + } + + function option_definition() { + $options = array( + 'defaults' => array( + 'default' => array( + 'access' => TRUE, + 'cache' => TRUE, + 'query' => TRUE, + 'title' => TRUE, + 'display_comment' => TRUE, + 'enabled' => TRUE, + 'css_class' => TRUE, + + 'display_description' => FALSE, + 'use_ajax' => TRUE, + 'items_per_page' => TRUE, + 'use_pager' => TRUE, + 'offset' => TRUE, + 'pager' => TRUE, + 'use_more' => TRUE, + 'use_more_always' => TRUE, + 'use_more_text' => TRUE, + 'exposed_block' => TRUE, + 'exposed_form' => TRUE, + + 'link_display' => TRUE, + 'group_by' => TRUE, + + 'style_plugin' => TRUE, + 'style_options' => TRUE, + 'row_plugin' => TRUE, + 'row_options' => TRUE, + + 'header' => TRUE, + 'footer' => TRUE, + 'empty' => TRUE, + + 'relationships' => TRUE, + 'fields' => TRUE, + 'sorts' => TRUE, + 'arguments' => TRUE, + 'filters' => TRUE, + 'filter_groups' => TRUE, + ), + 'export' => FALSE, + ), + + 'title' => array( + 'default' => '', + 'translatable' => TRUE, + ), + 'enabled' => array( + 'default' => TRUE, + 'translatable' => FALSE, + 'bool' => TRUE, + ), + 'display_comment' => array( + 'default' => '', + ), + 'css_class' => array( + 'default' => '', + 'translatable' => FALSE, + ), + 'display_description' => array( + 'default' => '', + 'translatable' => TRUE, + ), + 'use_ajax' => array( + 'default' => FALSE, + 'bool' => TRUE, + ), + 'items_per_page' => array( + 'default' => 10, + ), + 'offset' => array( + 'default' => 0, + ), + 'use_pager' => array( + 'default' => FALSE, + 'bool' => TRUE, + ), + 'use_more' => array( + 'default' => FALSE, + 'bool' => TRUE, + ), + 'use_more_always' => array( + 'default' => FALSE, + 'bool' => TRUE, + ), + 'use_more_text' => array( + 'default' => 'more', + 'translatable' => TRUE, + ), + 'link_display' => array( + 'default' => '', + ), + 'group_by' => array( + 'default' => FALSE, + 'bool' => TRUE, + ), + + // These types are all plugins that can have individual settings + // and therefore need special handling. + 'access' => array( + 'contains' => array( + 'type' => array('default' => 'none', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'), + ), + ), + 'cache' => array( + 'contains' => array( + 'type' => array('default' => 'none', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'), + ), + ), + 'query' => array( + 'contains' => array( + 'type' => array('default' => 'views_query', 'export' => 'export_plugin'), + 'options' => array('default' => array(), 'export' => FALSE), + ), + ), + // Note that exposed_form plugin has options in a separate array, + // while access and cache do not. access and cache are legacy and + // that pattern should not be repeated, but it is left as is to + // reduce the need to modify older views. Let's consider the + // pattern used here to be the template from which future plugins + // should be copied. + 'exposed_form' => array( + 'contains' => array( + 'type' => array('default' => 'basic', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'), + 'options' => array('default' => array(), 'export' => FALSE), + ), + ), + 'pager' => array( + 'contains' => array( + 'type' => array('default' => 'full', 'export' => 'export_plugin', 'unpack_translatable' => 'unpack_plugin'), + 'options' => array('default' => array(), 'export' => FALSE), + ), + ), + + // Note that the styles have their options completely independent. + // Like access and cache above, this is a legacy pattern and + // should not be repeated. + 'style_plugin' => array( + 'default' => 'default', + 'export' => 'export_style', + 'unpack_translatable' => 'unpack_style', + ), + 'style_options' => array( + 'default' => array(), + 'export' => FALSE, + ), + 'row_plugin' => array( + 'default' => 'fields', + 'export' => 'export_style', + 'unpack_translatable' => 'unpack_style', + ), + 'row_options' => array( + 'default' => array(), + 'export' => FALSE, + ), + + 'exposed_block' => array( + 'default' => FALSE, + ), + + 'header' => array( + 'default' => array(), + 'export' => 'export_handler', + 'unpack_translatable' => 'unpack_handler', + ), + 'footer' => array( + 'default' => array(), + 'export' => 'export_handler', + 'unpack_translatable' => 'unpack_handler', + ), + 'empty' => array( + 'default' => array(), + 'export' => 'export_handler', + 'unpack_translatable' => 'unpack_handler', + ), + + // We want these to export last. + // These are the 5 handler types. + 'relationships' => array( + 'default' => array(), + 'export' => 'export_handler', + 'unpack_translatable' => 'unpack_handler', + + ), + 'fields' => array( + 'default' => array(), + 'export' => 'export_handler', + 'unpack_translatable' => 'unpack_handler', + ), + 'sorts' => array( + 'default' => array(), + 'export' => 'export_handler', + 'unpack_translatable' => 'unpack_handler', + ), + 'arguments' => array( + 'default' => array(), + 'export' => 'export_handler', + 'unpack_translatable' => 'unpack_handler', + ), + 'filter_groups' => array( + 'contains' => array( + 'operator' => array('default' => 'AND'), + 'groups' => array('default' => array(0 => 'AND')), + ), + ), + 'filters' => array( + 'default' => array(), + 'export' => 'export_handler', + 'unpack_translatable' => 'unpack_handler', + ), + ); + + if (empty($this->definition['use pager'])) { + $options['defaults']['default']['use_pager'] = FALSE; + $options['defaults']['default']['items_per_page'] = FALSE; + $options['defaults']['default']['offset'] = FALSE; + $options['defaults']['default']['pager'] = FALSE; + $options['pager']['contains']['type']['default'] = 'some'; + } + + if ($this->is_default_display()) { + unset($options['defaults']); + } + return $options; + } + + /** + * Check to see if the display has a 'path' field. + * + * This is a pure function and not just a setting on the definition + * because some displays (such as a panel pane) may have a path based + * upon configuration. + * + * By default, displays do not have a path. + */ + function has_path() { return FALSE; } + + /** + * Check to see if the display has some need to link to another display. + * + * For the most part, displays without a path will use a link display. However, + * sometimes displays that have a path might also need to link to another display. + * This is true for feeds. + */ + function uses_link_display() { return !$this->has_path(); } + + /** + * Check to see which display to use when creating links within + * a view using this display. + */ + function get_link_display() { + $display_id = $this->get_option('link_display'); + // If unknown, pick the first one. + if (empty($display_id) || empty($this->view->display[$display_id])) { + foreach ($this->view->display as $display_id => $display) { + if (!empty($display->handler) && $display->handler->has_path()) { + return $display_id; + } + } + } + else { + return $display_id; + } + // fall-through returns NULL + } + + /** + * Return the base path to use for this display. + * + * This can be overridden for displays that do strange things + * with the path. + */ + function get_path() { + if ($this->has_path()) { + return $this->get_option('path'); + } + + $display_id = $this->get_link_display(); + if ($display_id && !empty($this->view->display[$display_id]) && is_object($this->view->display[$display_id]->handler)) { + return $this->view->display[$display_id]->handler->get_path(); + } + } + + /** + * Check to see if the display needs a breadcrumb + * + * By default, displays do not need breadcrumbs + */ + function uses_breadcrumb() { return FALSE; } + + /** + * Determine if a given option is set to use the default display or the + * current display + * + * @return + * TRUE for the default display + */ + function is_defaulted($option) { + return !$this->is_default_display() && !empty($this->default_display) && !empty($this->options['defaults'][$option]); + } + + /** + * Intelligently get an option either from this display or from the + * default display, if directed to do so. + */ + function get_option($option) { + if ($this->is_defaulted($option)) { + return $this->default_display->get_option($option); + } + + if (array_key_exists($option, $this->options)) { + return $this->options[$option]; + } + } + + /** + * Determine if the display's style uses fields. + */ + function uses_fields() { + $plugin = $this->get_plugin(); + if ($plugin) { + return $plugin->uses_fields(); + } + } + + /** + * Get the display or row plugin, if it exists. + */ + function get_plugin($type = 'style', $name = NULL) { + static $cache = array(); + if (!isset($cache[$type][$name])) { + switch ($type) { + case 'style': + case 'row': + $option_name = $type . '_plugin'; + $options = $this->get_option($type . '_options'); + if (!$name) { + $name = $this->get_option($option_name); + } + + break; + case 'query': + $views_data = views_fetch_data($this->view->base_table); + $name = !empty($views_data['table']['base']['query class']) ? $views_data['table']['base']['query class'] : 'views_query'; + default: + $option_name = $type; + $options = $this->get_option($type); + if (!$name) { + $name = $options['type']; + } + + // access & cache store their options as siblings with the + // type; all others use an 'options' array. + if ($type != 'access' && $type != 'cache') { + $options = $options['options']; + } + } + $plugin = views_get_plugin($type, $name); + + if (!$plugin) { + return; + } + if ($type != 'query') { + $plugin->init($this->view, $this->display, $options); + } + else { + if (!isset($this->base_field)) { + $views_data = views_fetch_data($this->view->base_table); + $this->view->base_field = $views_data['table']['base']['field']; + } + $plugin->init($this->view->base_table, $this->view->base_field, $options); + } + $cache[$type][$name] = $plugin; + } + + return $cache[$type][$name]; + } + + /** + * Get the handler object for a single handler. + */ + function &get_handler($type, $id) { + if (!isset($this->handlers[$type])) { + $this->get_handlers($type); + } + + if (isset($this->handlers[$type][$id])) { + return $this->handlers[$type][$id]; + } + + // So we can return a reference. + $null = NULL; + return $null; + } + + /** + * Get a full array of handlers for $type. This caches them. + */ + function get_handlers($type) { + if (!isset($this->handlers[$type])) { + $this->handlers[$type] = array(); + $types = views_object_types(); + $plural = $types[$type]['plural']; + foreach ($this->get_option($plural) as $id => $info) { + if ($info['id'] != $id) { + $info['id'] = $id; + } + + // If aggregation is on, the group type might override the actual + // handler that is in use. This piece of code checks that and, + // if necessary, sets the override handler. + $override = NULL; + if ($this->use_group_by() && !empty($info['group_type'])) { + if (empty($this->view->query)) { + $this->view->init_query(); + } + $aggregate = $this->view->query->get_aggregation_info(); + if (!empty($aggregate[$info['group_type']]['handler'][$type])) { + $override = $aggregate[$info['group_type']]['handler'][$type]; + } + } + + if (!empty($types[$type]['type'])) { + $handler_type = $types[$type]['type']; + } + else { + $handler_type = $type; + } + + $handler = views_get_handler($info['table'], $info['field'], $handler_type, $override); + if ($handler) { + $handler->init($this->view, $info); + $this->handlers[$type][$id] = &$handler; + } + + // Prevent reference problems. + unset($handler); + } + } + + return $this->handlers[$type]; + } + + /** + * Retrieve a list of fields for the current display with the + * relationship associated if it exists. + */ + function get_field_labels() { + $options = array(); + foreach ($this->get_handlers('relationship') as $relationship => $handler) { + if ($label = $handler->label()) { + $relationships[$relationship] = $label; + } + else { + $relationships[$relationship] = $handler->ui_name(); + } + } + + foreach ($this->get_handlers('field') as $id => $handler) { + if ($label = $handler->label()) { + $options[$id] = $label; + } + else { + $options[$id] = $handler->ui_name(); + } + if (!empty($handler->options['relationship']) && !empty($relationships[$handler->options['relationship']])) { + $options[$id] = '(' . $relationships[$handler->options['relationship']] . ') ' . $options[$id]; + } + } + return $options; + } + + /** + * Intelligently set an option either from this display or from the + * default display, if directed to do so. + */ + function set_option($option, $value) { + if ($this->is_defaulted($option)) { + return $this->default_display->set_option($option, $value); + } + + // Set this in two places: On the handler where we'll notice it + // but also on the display object so it gets saved. This should + // only be a temporary fix. + $this->display->display_options[$option] = $value; + return $this->options[$option] = $value; + } + + /** + * Set an option and force it to be an override. + */ + function override_option($option, $value) { + $this->set_override($option, FALSE); + $this->set_option($option, $value); + } + + /** + * Because forms may be split up into sections, this provides + * an easy URL to exactly the right section. Don't override this. + */ + function option_link($text, $section, $class = '', $title = '') { + views_add_js('ajax'); + if (!empty($class)) { + $text = '<span>' . $text . '</span>'; + } + + if (!trim($text)) { + $text = t('Broken field'); + } + + if (empty($title)) { + $title = $text; + } + + return l($text, 'admin/structure/views/nojs/display/' . $this->view->name . '/' . $this->display->id . '/' . $section, array('attributes' => array('class' => 'views-ajax-link ' . $class, 'title' => $title, 'id' => drupal_html_id('views-' . $this->display->id . '-' . $section)), 'html' => TRUE)); + } + + /** + * Provide the default summary for options in the views UI. + * + * This output is returned as an array. + */ + function options_summary(&$categories, &$options) { + $categories = array( + 'basic' => array( + 'title' => t('Basic settings'), + ), + 'advanced' => array( + 'title' => t('Advanced settings'), + ), + 'style' => array( + 'title' => t('Style settings'), + ), + 'exposed' => array( + 'title' => t('Exposed form'), + ), + ); + + if ($this->display->id != 'default') { + $options['display_id'] = array( + 'category' => 'basic', + 'title' => t('Machine Name'), + 'value' => !empty($this->display->new_id) ? check_plain($this->display->new_id) : check_plain($this->display->id), + 'desc' => t('Change the machine name of this display.'), + ); + } + + $options['display_title'] = array( + 'category' => 'basic', + 'title' => t('Name'), + 'value' => check_plain($this->display->display_title), + 'desc' => t('Change the name of this display.'), + ); + + $display_comment = drupal_substr($this->get_option('display_comment'), 0, 10); + $options['display_comment'] = array( + 'category' => 'basic', + 'title' => t('Comment'), + 'value' => !empty($display_comment) ? $display_comment : t('No comment'), + 'desc' => t('Comment or document this display.'), + ); + + $title = strip_tags($this->get_option('title')); + if (!$title) { + $title = t('None'); + } + + $options['title'] = array( + 'category' => 'basic', + 'title' => t('Title'), + 'value' => $title, + 'desc' => t('Change the title that this display will use.'), + ); + + $options['enabled'] = array( + 'category' => 'basic', + 'title' => t('Display status'), + 'value' => $this->get_option('enabled') ? t('Enabled') : t('Disabled'), + 'desc' => t('Define if this display is or is not enabled.'), + ); + + $style_plugin = views_fetch_plugin_data('style', $this->get_option('style_plugin')); + $style_title = empty($style_plugin['title']) ? t('Missing style plugin') : $style_plugin['title']; + + $style = ''; + + $options['style_plugin'] = array( + 'category' => 'style', + 'title' => t('Style'), + 'value' => $style_title, + 'desc' => t('Change the style plugin.'), + ); + + // This adds a 'Settings' link to the style_options setting if the style has options. + if (!empty($style_plugin['uses options'])) { + $options['style_plugin']['links']['style_options'] = t('Change settings for this style'); + } + + if (!empty($style_plugin['uses row plugin'])) { + $row_plugin = views_fetch_plugin_data('row', $this->get_option('row_plugin')); + $row_title = empty($row_plugin['title']) ? t('Missing style plugin') : $row_plugin['title']; + + $options['row_plugin'] = array( + 'category' => 'style', + 'title' => t('Row style'), + 'value' => $row_title, + 'desc' => t('Change the row plugin.'), + ); + // This adds a 'Settings' link to the row_options setting if the row style has options. + if (!empty($row_plugin['uses options'])) { + $options['row_plugin']['links']['row_options'] = t('Change settings for this style'); + } + } + if (!empty($this->definition['use ajax'])) { + $options['use_ajax'] = array( + 'category' => 'advanced', + 'title' => t('Use AJAX'), + 'value' => $this->get_option('use_ajax') ? t('Yes') : t('No'), + 'desc' => t('Change whether or not this display will use AJAX.'), + ); + } + + $pager_plugin = $this->get_plugin('pager'); + if (!$pager_plugin) { + // default to the no pager plugin. + $pager_plugin = views_get_plugin('pager', 'none'); + } + + $pager_str = $pager_plugin->summary_title(); + + $options['pager'] = array( + 'category' => 'basic', + 'title' => t('Use pager'), + 'value' => $pager_str, + 'desc' => t("Change this display's pager setting."), + ); + + // If pagers aren't allowed, change the text of the item: + if (empty($this->definition['use pager'])) { + $options['pager']['title'] = t('Items to display'); + } + + if (!empty($pager_plugin->definition['uses options'])) { + $options['pager']['links']['pager_options'] = t('Change settings for this pager type.'); + } + + if (!empty($this->definition['use more'])) { + $options['use_more'] = array( + 'category' => 'basic', + 'title' => t('More link'), + 'value' => $this->get_option('use_more') ? t('Yes') : t('No'), + 'desc' => t('Specify whether this display will provide a "more" link.'), + ); + } + + $this->view->init_query(); + if ($this->view->query->get_aggregation_info()) { + $options['group_by'] = array( + 'category' => 'advanced', + 'title' => t('Use grouping'), + 'value' => $this->get_option('group_by') ? t('Yes') : t('No'), + 'desc' => t('Allow grouping and aggregation (calculation) of fields.'), + ); + } + + $options['query'] = array( + 'category' => 'advanced', + 'title' => t('Query settings'), + 'value' => t('Settings'), + 'desc' => t('Allow to set some advanced settings for the query plugin'), + ); + + $access_plugin = $this->get_plugin('access'); + if (!$access_plugin) { + // default to the no access control plugin. + $access_plugin = views_get_plugin('access', 'none'); + } + + $access_str = $access_plugin->summary_title(); + + $options['access'] = array( + 'category' => 'basic', + 'title' => t('Access'), + 'value' => $access_str, + 'desc' => t('Specify access control type for this display.'), + ); + + if (!empty($access_plugin->definition['uses options'])) { + $options['access']['links']['access_options'] = t('Change settings for this access type.'); + } + + $cache_plugin = $this->get_plugin('cache'); + if (!$cache_plugin) { + // default to the no cache control plugin. + $cache_plugin = views_get_plugin('cache', 'none'); + } + + $cache_str = $cache_plugin->summary_title(); + + $options['cache'] = array( + 'category' => 'advanced', + 'title' => t('Caching'), + 'value' => $cache_str, + 'desc' => t('Specify caching type for this display.'), + ); + + if (!empty($cache_plugin->definition['uses options'])) { + $options['cache']['links']['cache_options'] = t('Change settings for this caching type.'); + } + + if (!empty($access_plugin->definition['uses options'])) { + $options['access']['links']['access_options'] = t('Change settings for this access type.'); + } + + if ($this->uses_link_display()) { + // Only show the 'link display' if there is more than one option. + $count = 0; + foreach ($this->view->display as $display_id => $display) { + if (is_object($display->handler) && $display->handler->has_path()) { + $count++; + } + if ($count > 1) { + break; + } + } + + if ($count > 1) { + $display_id = $this->get_link_display(); + $link_display = empty($this->view->display[$display_id]) ? t('None') : check_plain($this->view->display[$display_id]->display_title); + $options['link_display'] = array( + 'category' => 'basic', + 'title' => t('Link display'), + 'value' => $link_display, + 'desc' => t('Specify which display this display will link to.'), + ); + } + } + + $options['exposed_block'] = array( + 'category' => 'exposed', + 'title' => t('Exposed form in block'), + 'value' => $this->get_option('exposed_block') ? t('Yes') : t('No'), + 'desc' => t('Allow the exposed form to appear in a block instead of the view.'), + ); + + $exposed_form_plugin = $this->get_plugin('exposed_form'); + if (!$exposed_form_plugin) { + // default to the no cache control plugin. + $exposed_form_plugin = views_get_plugin('exposed_form', 'basic'); + } + + $exposed_form_str = $exposed_form_plugin->summary_title(); + + $options['exposed_form'] = array( + 'category' => 'exposed', + 'title' => t('Exposed form style'), + 'value' => $exposed_form_str, + 'desc' => t('Select the kind of exposed filter to use.'), + ); + + if (!empty($exposed_form_plugin->definition['uses options'])) { + $options['exposed_form']['links']['exposed_form_options'] = t('Exposed form settings for this exposed form style.'); + } + + $css_class = check_plain(trim($this->get_option('css_class'))); + if (!$css_class) { + $css_class = t('None'); + } + + $options['css_class'] = array( + 'category' => 'style', + 'title' => t('CSS class'), + 'value' => $css_class, + 'desc' => t('Change the CSS class name(s) that will be added to this display.'), + ); + + $options['analyze-theme'] = array( + 'category' => 'style', + 'title' => t('Theme'), + 'value' => t('Information'), + 'desc' => t('Get information on how to theme this display'), + ); + } + + /** + * Provide the default form for setting options. + */ + function options_form(&$form, &$form_state) { + if ($this->defaultable_sections($form_state['section'])) { + $this->add_override_button($form, $form_state, $form_state['section']); + } + $form['#title'] = check_plain($this->display->display_title) . ': '; + + // Set the 'section' to hilite on the form. + // If it's the item we're looking at is pulling from the default display, + // reflect that. Don't use is_defaulted since we want it to show up even + // on the default display. + if (!empty($this->options['defaults'][$form_state['section']])) { + $form['#section'] = 'default-' . $form_state['section']; + } + else { + $form['#section'] = $this->display->id . '-' . $form_state['section']; + } + + switch ($form_state['section']) { + case 'display_id': + $form['#title'] .= t('The machine name of this display'); + $form['display_id'] = array( + '#type' => 'textfield', + '#description' => t('This is machine name of the display.'), + '#default_value' => !empty($this->display->new_id) ? $this->display->new_id : $this->display->id, + '#required' => TRUE, + '#size' => 64, + ); + break; + case 'display_title': + $form['#title'] .= t('The name and the description of this display'); + $form['display_title'] = array( + '#title' => t('Name'), + '#type' => 'textfield', + '#description' => t('This name will appear only in the administrative interface for the View.'), + '#default_value' => $this->display->display_title, + ); + $form['display_description'] = array( + '#title' => t('Description'), + '#type' => 'textfield', + '#description' => t('This description will appear only in the administrative interface for the View.'), + '#default_value' => $this->get_option('display_description'), + ); + break; + case 'display_comment': + $form['#title'] .= t("This display's comments"); + $form['display_comment'] = array( + '#type' => 'textarea', + '#description' => t('This value will be seen and used only within the Views UI and can be used to document this display. You can use this to provide notes for other or future maintainers of your site about how or why this display is configured.'), + '#default_value' => $this->get_option('display_comment'), + ); + break; + case 'title': + $form['#title'] .= t('The title of this view'); + $form['title'] = array( + '#type' => 'textfield', + '#description' => t('This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc.'), + '#default_value' => $this->get_option('title'), + ); + break; + case 'enabled': + $form['#title'] .= t('Status of this display'); + $form['enabled'] = array( + '#type' => 'checkbox', + '#title' => t('Enable display'), + '#description' => t('If unchecked, this display will not be available in the site.'), + '#default_value' => $this->get_option('enabled'), + ); + break; + case 'css_class': + $form['#title'] .= t('CSS class'); + $form['css_class'] = array( + '#type' => 'textfield', + '#description' => t('The CSS class names will be added to the view. This enables you to use specific CSS code for each view. You may define multiples classes separated by spaces.'), + '#default_value' => $this->get_option('css_class'), + ); + break; + case 'use_ajax': + $form['#title'] .= t('Use AJAX when available to load this view'); + $form['description'] = array( + '#markup' => '<div class="description form-item">' . t('If set, this view will use an AJAX mechanism for paging, table sorting and exposed filters. This means the entire page will not refresh. It is not recommended that you use this if this view is the main content of the page as it will prevent deep linking to specific pages, but it is very useful for side content.') . '</div>', + ); + $form['use_ajax'] = array( + '#type' => 'radios', + '#options' => array(1 => t('Yes'), 0 => t('No')), + '#default_value' => $this->get_option('use_ajax') ? 1 : 0, + ); + break; + case 'use_more': + $form['#title'] .= t('Add a more link to the bottom of the display.'); + $form['use_more'] = array( + '#type' => 'checkbox', + '#title' => t('Create more link'), + '#description' => t("This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' above."), + '#default_value' => $this->get_option('use_more'), + ); + $form['use_more_always'] = array( + '#type' => 'checkbox', + '#title' => t('Always display more link'), + '#description' => t("This will display the more link even if there are no more items to display."), + '#default_value' => $this->get_option('use_more_always'), + ); + $form['#title'] .= t('Text to use for the more link.'); + $form['use_more_text'] = array( + '#type' => 'textfield', + '#title' => t('More link text'), + '#description' => t("The text to display for the more link."), + '#default_value' => $this->get_option('use_more_text'), + ); + break; + case 'group_by': + $form['#title'] .= t('Allow grouping and aggregation (calculation) of fields.'); + $form['group_by'] = array( + '#type' => 'checkbox', + '#title' => t('Group by'), + '#description' => t('If enabled, some fields may become unavailable. All fields that are selected for grouping will be collapsed to one record per distinct value. Other fields which are selected for aggregation will have the function run on them. For example, you can group nodes on title and count the number of nids in order to get a list of duplicate titles.'), + '#default_value' => $this->get_option('group_by'), + ); + break; + case 'access': + $form['#title'] .= t('Access restrictions'); + $form['access'] = array( + '#prefix' => '<div class="clearfix">', + '#suffix' => '</div>', + '#tree' => TRUE, + ); + + $access = $this->get_option('access'); + $form['access']['type'] = array( + '#type' => 'radios', + '#options' => views_fetch_plugin_names('access'), + '#default_value' => $access['type'], + ); + + $access_plugin = views_fetch_plugin_data('access', $access['type']); + if (!empty($access_plugin['uses options'])) { + $form['markup'] = array( + '#prefix' => '<div class="form-item description">', + '#markup' => t('You may also adjust the !settings for the currently selected access restriction by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'access_options'))), + '#suffix' => '</div>', + ); + } + + break; + case 'access_options': + $access = $this->get_option('access'); + $plugin = $this->get_plugin('access'); + $form['#title'] .= t('Access options'); + if ($plugin) { + $form['#help_topic'] = $plugin->definition['help topic']; + $form['#help_module'] = $plugin->definition['module']; + + $form['access_options'] = array( + '#tree' => TRUE, + ); + $form['access_options']['type'] = array( + '#type' => 'value', + '#value' => $access['type'], + ); + $plugin->options_form($form['access_options'], $form_state); + } + break; + case 'cache': + $form['#title'] .= t('Caching'); + $form['cache'] = array( + '#prefix' => '<div class="clearfix">', + '#suffix' => '</div>', + '#tree' => TRUE, + ); + + $cache = $this->get_option('cache'); + $form['cache']['type'] = array( + '#type' => 'radios', + '#options' => views_fetch_plugin_names('cache'), + '#default_value' => $cache['type'], + ); + + $cache_plugin = views_fetch_plugin_data('cache', $cache['type']); + if (!empty($cache_plugin['uses options'])) { + $form['markup'] = array( + '#prefix' => '<div class="form-item description">', + '#suffix' => '</div>', + '#markup' => t('You may also adjust the !settings for the currently selected cache mechanism by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'cache_options'))), + ); + } + break; + case 'cache_options': + $cache = $this->get_option('cache'); + $plugin = $this->get_plugin('cache'); + $form['#title'] .= t('Caching options'); + if ($plugin) { + $form['#help_topic'] = $plugin->definition['help topic']; + $form['#help_module'] = $plugin->definition['module']; + + $form['cache_options'] = array( + '#tree' => TRUE, + ); + $form['cache_options']['type'] = array( + '#type' => 'value', + '#value' => $cache['type'], + ); + $plugin->options_form($form['cache_options'], $form_state); + } + break; + case 'query': + $query_options = $this->get_option('query'); + $plugin_name = $query_options['type']; + + $form['#title'] .= t('Query options'); + $this->view->init_query(); + if ($this->view->query) { + if (isset($this->view->query->definition['help topic'])) { + $form['#help_topic'] = $this->view->query->definition['help topic']; + } + + if (isset($this->view->query->definition['module'])) { + $form['#help_module'] = $this->view->query->definition['module']; + } + + $form['query'] = array( + '#tree' => TRUE, + 'type' => array( + '#type' => 'value', + '#value' => $plugin_name, + ), + 'options' => array( + '#tree' => TRUE, + ), + ); + + $this->view->query->options_form($form['query']['options'], $form_state); + } + break; + case 'style_plugin': + $form['#title'] .= t('How should this view be styled'); + $form['#help_topic'] = 'style'; + $form['style_plugin'] = array( + '#type' => 'radios', + '#options' => views_fetch_plugin_names('style', $this->get_style_type(), array($this->view->base_table)), + '#default_value' => $this->get_option('style_plugin'), + '#description' => t('If the style you choose has settings, be sure to click the settings button that will appear next to it in the View summary.'), + ); + + $style_plugin = views_fetch_plugin_data('style', $this->get_option('style_plugin')); + if (!empty($style_plugin['uses options'])) { + $form['markup'] = array( + '#markup' => '<div class="form-item description">' . t('You may also adjust the !settings for the currently selected style by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'style_options'))) . '</div>', + ); + } + + break; + case 'style_options': + $form['#title'] .= t('Style options'); + $style = TRUE; + $type = 'style_plugin'; + $name = $this->get_option('style_plugin'); + + case 'row_options': + if (!isset($name)) { + $name = $this->get_option('row_plugin'); + } + // if row, $style will be empty. + if (empty($style)) { + $form['#title'] .= t('Row style options'); + $type = 'row_plugin'; + } + $plugin = $this->get_plugin(empty($style) ? 'row' : 'style'); + if ($plugin) { + if (isset($plugin->definition['help topic'])) { + $form['#help_topic'] = $plugin->definition['help topic']; + $form['#help_module'] = $plugin->definition['module']; + } + $form[$form_state['section']] = array( + '#tree' => TRUE, + ); + $plugin->options_form($form[$form_state['section']], $form_state); + } + break; + case 'row_plugin': + $form['#title'] .= t('How should each row in this view be styled'); + $form['#help_topic'] = 'style-row'; + $form['row_plugin'] = array( + '#type' => 'radios', + '#options' => views_fetch_plugin_names('row', $this->get_style_type(), array($this->view->base_table)), + '#default_value' => $this->get_option('row_plugin'), + ); + + $row_plugin = views_fetch_plugin_data('row', $this->get_option('row_plugin')); + if (!empty($row_plugin['uses options'])) { + $form['markup'] = array( + '#markup' => '<div class="form-item description">' . t('You may also adjust the !settings for the currently selected row style by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'row_options'))) . '</div>', + ); + } + + break; + case 'link_display': + $form['#title'] .= t('Which display to use for path'); + foreach ($this->view->display as $display_id => $display) { + if ($display->handler->has_path()) { + $options[$display_id] = $display->display_title; + } + } + $form['link_display'] = array( + '#type' => 'radios', + '#options' => $options, + '#description' => t("Which display to use to get this display's path for things like summary links, rss feed links, more links, etc."), + '#default_value' => $this->get_link_display(), + ); + break; + case 'analyze-theme': + $form['#title'] .= t('Theming information'); + $form['#help_topic'] = 'analyze-theme'; + + if (isset($_POST['theme'])) { + $this->theme = $_POST['theme']; + } + elseif (empty($this->theme)) { + $this->theme = variable_get('theme_default', 'bartik'); + } + + if (isset($GLOBALS['theme']) && $GLOBALS['theme'] == $this->theme) { + $this->theme_registry = theme_get_registry(); + $theme_engine = $GLOBALS['theme_engine']; + } + else { + $themes = list_themes(); + $theme = $themes[$this->theme]; + + // Find all our ancestor themes and put them in an array. + $base_theme = array(); + $ancestor = $this->theme; + while ($ancestor && isset($themes[$ancestor]->base_theme)) { + $ancestor = $themes[$ancestor]->base_theme; + $base_theme[] = $themes[$ancestor]; + } + + // The base themes should be initialized in the right order. + $base_theme = array_reverse($base_theme); + + // This code is copied directly from _drupal_theme_initialize() + $theme_engine = NULL; + + // Initialize the theme. + if (isset($theme->engine)) { + // Include the engine. + include_once DRUPAL_ROOT . '/' . $theme->owner; + + $theme_engine = $theme->engine; + if (function_exists($theme_engine . '_init')) { + foreach ($base_theme as $base) { + call_user_func($theme_engine . '_init', $base); + } + call_user_func($theme_engine . '_init', $theme); + } + } + else { + // include non-engine theme files + foreach ($base_theme as $base) { + // Include the theme file or the engine. + if (!empty($base->owner)) { + include_once DRUPAL_ROOT . '/' . $base->owner; + } + } + // and our theme gets one too. + if (!empty($theme->owner)) { + include_once DRUPAL_ROOT . '/' . $theme->owner; + } + } + $this->theme_registry = _theme_load_registry($theme, $base_theme, $theme_engine); + } + + // If there's a theme engine involved, we also need to know its extension + // so we can give the proper filename. + $this->theme_extension = '.tpl.php'; + if (isset($theme_engine)) { + $extension_function = $theme_engine . '_extension'; + if (function_exists($extension_function)) { + $this->theme_extension = $extension_function(); + } + } + + $funcs = array(); + // Get theme functions for the display. Note that some displays may + // not have themes. The 'feed' display, for example, completely + // delegates to the style. + if (!empty($this->definition['theme'])) { + $funcs[] = $this->option_link(t('Display output'), 'analyze-theme-display') . ': ' . $this->format_themes($this->theme_functions()); + $themes = $this->additional_theme_functions(); + if ($themes) { + foreach ($themes as $theme) { + $funcs[] = $this->option_link(t('Alternative display output'), 'analyze-theme-display') . ': ' . $this->format_themes($theme); + } + } + } + + $plugin = $this->get_plugin(); + if ($plugin) { + $funcs[] = $this->option_link(t('Style output'), 'analyze-theme-style') . ': ' . $this->format_themes($plugin->theme_functions(), $plugin->additional_theme_functions()); + $themes = $plugin->additional_theme_functions(); + if ($themes) { + foreach ($themes as $theme) { + $funcs[] = $this->option_link(t('Alternative style'), 'analyze-theme-style') . ': ' . $this->format_themes($theme); + } + } + + if ($plugin->uses_row_plugin()) { + $row_plugin = $this->get_plugin('row'); + if ($row_plugin) { + $funcs[] = $this->option_link(t('Row style output'), 'analyze-theme-row') . ': ' . $this->format_themes($row_plugin->theme_functions()); + $themes = $row_plugin->additional_theme_functions(); + if ($themes) { + foreach ($themes as $theme) { + $funcs[] = $this->option_link(t('Alternative row style'), 'analyze-theme-row') . ': ' . $this->format_themes($theme); + } + } + } + } + + if ($plugin->uses_fields()) { + foreach ($this->get_handlers('field') as $id => $handler) { + $funcs[] = $this->option_link(t('Field @field (ID: @id)', array('@field' => $handler->ui_name(), '@id' => $id)), 'analyze-theme-field') . ': ' . $this->format_themes($handler->theme_functions()); + } + } + } + + $form['important'] = array( + '#markup' => '<div class="form-item description"><p>' . t('This section lists all possible templates for the display plugin and for the style plugins, ordered roughly from the least specific to the most specific. The active template for each plugin -- which is the most specific template found on the system -- is highlighted in bold.') . '</p></div>', + ); + + if (isset($this->view->display[$this->view->current_display]->new_id)) { + $form['important']['new_id'] = array( + '#prefix' => '<div class="description">', + '#suffix' => '</div>', + '#value' => t("<strong>Important!</strong> You have changed the display's machine name. Anything that attached to this display specifically, such as theming, may stop working until it is updated. To see theme suggestions for it, you need to save the view."), + ); + } + + foreach (list_themes() as $key => $theme) { + $options[$key] = $theme->info['name']; + } + + $form['box'] = array( + '#prefix' => '<div class="container-inline">', + '#suffix' => '</div>', + ); + $form['box']['theme'] = array( + '#type' => 'select', + '#options' => $options, + '#default_value' => $this->theme, + ); + + $form['box']['change'] = array( + '#type' => 'submit', + '#value' => t('Change theme'), + '#submit' => array('views_ui_edit_display_form_change_theme'), + ); + + $form['analysis'] = array( + '#markup' => '<div class="form-item">' . theme('item_list', array('items' => $funcs)) . '</div>', + ); + + $form['rescan_button'] = array( + '#prefix' => '<div class="form-item">', + '#suffix' => '</div>', + ); + $form['rescan_button']['button'] = array( + '#type' => 'submit', + '#value' => t('Rescan template files'), + '#submit' => array('views_ui_config_item_form_rescan'), + ); + $form['rescan_button']['markup'] = array( + '#markup' => '<div class="description">' . t("<strong>Important!</strong> When adding, removing, or renaming template files, it is necessary to make Drupal aware of the changes by making it rescan the files on your system. By clicking this button you clear Drupal's theme registry and thereby trigger this rescanning process. The highlighted templates above will then reflect the new state of your system.") . '</div>', + ); + + $form_state['ok_button'] = TRUE; + break; + case 'analyze-theme-display': + $form['#title'] .= t('Theming information (display)'); + $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>'; + + if (empty($this->definition['theme'])) { + $output .= t('This display has no theming information'); + } + else { + $output .= '<p>' . t('This is the default theme template used for this display.') . '</p>'; + $output .= '<pre>' . check_plain(file_get_contents('./' . $this->definition['theme path'] . '/' . strtr($this->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>'; + } + + if (!empty($this->definition['additional themes'])) { + foreach ($this->definition['additional themes'] as $theme => $type) { + $output .= '<p>' . t('This is an alternative template for this display.') . '</p>'; + $output .= '<pre>' . check_plain(file_get_contents('./' . $this->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>'; + } + } + + $form['analysis'] = array( + '#markup' => '<div class="form-item">' . $output . '</div>', + ); + + $form_state['ok_button'] = TRUE; + break; + case 'analyze-theme-style': + $form['#title'] .= t('Theming information (style)'); + $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>'; + + $plugin = $this->get_plugin(); + + if (empty($plugin->definition['theme'])) { + $output .= t('This display has no style theming information'); + } + else { + $output .= '<p>' . t('This is the default theme template used for this style.') . '</p>'; + $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($plugin->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>'; + } + + if (!empty($plugin->definition['additional themes'])) { + foreach ($plugin->definition['additional themes'] as $theme => $type) { + $output .= '<p>' . t('This is an alternative template for this style.') . '</p>'; + $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>'; + } + } + + $form['analysis'] = array( + '#markup' => '<div class="form-item">' . $output . '</div>', + ); + + $form_state['ok_button'] = TRUE; + break; + case 'analyze-theme-row': + $form['#title'] .= t('Theming information (row style)'); + $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>'; + + $plugin = $this->get_plugin('row'); + + if (empty($plugin->definition['theme'])) { + $output .= t('This display has no row style theming information'); + } + else { + $output .= '<p>' . t('This is the default theme template used for this row style.') . '</p>'; + $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($plugin->definition['theme'], '_', '-') . '.tpl.php')) . '</pre>'; + } + + if (!empty($plugin->definition['additional themes'])) { + foreach ($plugin->definition['additional themes'] as $theme => $type) { + $output .= '<p>' . t('This is an alternative template for this row style.') . '</p>'; + $output .= '<pre>' . check_plain(file_get_contents('./' . $plugin->definition['theme path'] . '/' . strtr($theme, '_', '-') . '.tpl.php')) . '</pre>'; + } + } + + $form['analysis'] = array( + '#markup' => '<div class="form-item">' . $output . '</div>', + ); + + $form_state['ok_button'] = TRUE; + break; + case 'analyze-theme-field': + $form['#title'] .= t('Theming information (row style)'); + $output = '<p>' . t('Back to !info.', array('!info' => $this->option_link(t('theming information'), 'analyze-theme'))) . '</p>'; + + $output .= '<p>' . t('This is the default theme template used for this row style.') . '</p>'; + + // Field templates aren't registered the normal way...and they're always + // this one, anyhow. + $output .= '<pre>' . check_plain(file_get_contents(drupal_get_path('module', 'views') . '/theme/views-view-field.tpl.php')) . '</pre>'; + + $form['analysis'] = array( + '#markup' => '<div class="form-item">' . $output . '</div>', + ); + $form_state['ok_button'] = TRUE; + break; + + case 'exposed_block': + $form['#title'] .= t('Put the exposed form in a block'); + $form['description'] = array( + '#markup' => '<div class="description form-item">' . t('If set, any exposed widgets will not appear with this view. Instead, a block will be made available to the Drupal block administration system, and the exposed form will appear there. Note that this block must be enabled manually, Views will not enable it for you.') . '</div>', + ); + $form['exposed_block'] = array( + '#type' => 'radios', + '#options' => array(1 => t('Yes'), 0 => t('No')), + '#default_value' => $this->get_option('exposed_block') ? 1 : 0, + ); + break; + case 'exposed_form': + $form['#title'] .= t('Exposed Form'); + $form['exposed_form'] = array( + '#prefix' => '<div class="clearfix">', + '#suffix' => '</div>', + '#tree' => TRUE, + ); + + $exposed_form = $this->get_option('exposed_form'); + $form['exposed_form']['type'] = array( + '#type' => 'radios', + '#options' => views_fetch_plugin_names('exposed_form'), + '#default_value' => $exposed_form['type'], + ); + + $exposed_form_plugin = views_fetch_plugin_data('exposed_form', $exposed_form['type']); + if (!empty($exposed_form_plugin['uses options'])) { + $form['markup'] = array( + '#prefix' => '<div class="form-item description">', + '#suffix' => '</div>', + '#value' => t('You may also adjust the !settings for the currently selected style by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'exposed_form_options'))), + ); + } + break; + case 'exposed_form_options': + $plugin = $this->get_plugin('exposed_form'); + $form['#title'] .= t('Exposed form options'); + if ($plugin) { + $form['#help_topic'] = $plugin->definition['help topic']; + + $form['exposed_form_options'] = array( + '#tree' => TRUE, + ); + $plugin->options_form($form['exposed_form_options'], $form_state); + } + break; + case 'pager': + $form['#title'] .= t('Select which pager, if any, to use for this view'); + $form['pager'] = array( + '#prefix' => '<div class="clearfix">', + '#suffix' => '</div>', + '#tree' => TRUE, + ); + + $pager = $this->get_option('pager'); + $form['pager']['type'] = array( + '#type' => 'radios', + '#options' => views_fetch_plugin_names('pager', empty($this->definition['use pager']) ? 'basic' : NULL), + '#default_value' => $pager['type'], + ); + + $pager_plugin = views_fetch_plugin_data('pager', $pager['type']); + if (!empty($pager_plugin['uses options'])) { + $form['markup'] = array( + '#prefix' => '<div class="form-item description">', + '#suffix' => '</div>', + '#value' => t('You may also adjust the !settings for the currently selected pager by clicking on the icon.', array('!settings' => $this->option_link(t('settings'), 'pager_options'))), + ); + } + + break; + case 'pager_options': + $plugin = $this->get_plugin('pager'); + $form['#title'] .= t('Pager options'); + if ($plugin) { + $form['#help_topic'] = $plugin->definition['help topic']; + + $form['pager_options'] = array( + '#tree' => TRUE, + ); + $plugin->options_form($form['pager_options'], $form_state); + } + break; + } + + } + + /** + * Format a list of theme templates for output by the theme info helper. + */ + function format_themes($themes) { + $registry = $this->theme_registry; + $extension = $this->theme_extension; + + $output = ''; + $picked = FALSE; + foreach ($themes as $theme) { + $template = strtr($theme, '_', '-') . $extension; + if (!$picked && !empty($registry[$theme])) { + $template_path = isset($registry[$theme]['path']) ? $registry[$theme]['path'] . '/' : './'; + if (file_exists($template_path . $template)) { + $hint = t('File found in folder @template-path', array('@template-path' => $template_path)); + $template = '<strong title="'. $hint .'">' . $template . '</strong>'; + } + else { + $template = '<strong class="error">' . $template . ' ' . t('(File not found, in folder @template-path)', array('@template-path' => $template_path)) . '</strong>'; + } + $picked = TRUE; + } + $fixed[] = $template; + } + + return implode(', ', array_reverse($fixed)); + } + + /** + * Validate the options form. + */ + function options_validate(&$form, &$form_state) { + switch ($form_state['section']) { + case 'css_class': + $css_class = $form_state['values']['css_class']; + if (preg_match('/[^a-zA-Z0-9- ]/', $css_class)) { + form_error($form['css_class'], t('CSS classes must be alphanumeric or dashes only.')); + } + break; + case 'display_id': + if ($form_state['values']['display_id']) { + if (preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['display_id'])) { + form_error($form['display_id'], t('Display name must be letters, numbers, or underscores only.')); + } + + foreach ($this->view->display as $id => $display) { + if ($id != $this->view->current_display && ($form_state['values']['display_id'] == $id || $form_state['values']['display_id'] == $display->new_id)) { + form_error($form['display_id'], t('Display id should be unique.')); + } + } + } + break; + case 'style_options': + $style = TRUE; + case 'row_options': + // if row, $style will be empty. + $plugin = $this->get_plugin(empty($style) ? 'row' : 'style'); + if ($plugin) { + $plugin->options_validate($form[$form_state['section']], $form_state); + } + break; + case 'access_options': + $plugin = $this->get_plugin('access'); + if ($plugin) { + $plugin->options_validate($form['access_options'], $form_state); + } + break; + case 'query': + if ($this->view->query) { + $this->view->query->options_validate($form['query'], $form_state); + } + break; + case 'cache_options': + $plugin = $this->get_plugin('cache'); + if ($plugin) { + $plugin->options_validate($form['cache_options'], $form_state); + } + break; + case 'exposed_form_options': + $plugin = $this->get_plugin('exposed_form'); + if ($plugin) { + $plugin->options_validate($form['exposed_form_options'], $form_state); + } + break; + case 'pager_options': + $plugin = $this->get_plugin('pager'); + if ($plugin) { + $plugin->options_validate($form['pager_options'], $form_state); + } + 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) { + // Not sure I like this being here, but it seems (?) like a logical place. + $cache_plugin = $this->get_plugin('cache'); + if ($cache_plugin) { + $cache_plugin->cache_flush(); + } + + $section = $form_state['section']; + switch ($section) { + case 'display_id': + if (isset($form_state['values']['display_id'])) { + $this->display->new_id = $form_state['values']['display_id']; + } + break; + case 'display_title': + $this->display->display_title = $form_state['values']['display_title']; + $this->set_option('display_description', $form_state['values']['display_description']); + break; + case 'access': + $access = $this->get_option('access'); + if ($access['type'] != $form_state['values']['access']['type']) { + $plugin = views_get_plugin('access', $form_state['values']['access']['type']); + if ($plugin) { + $access = array('type' => $form_state['values']['access']['type']); + $this->set_option('access', $access); + if (!empty($plugin->definition['uses options'])) { + views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('access_options')); + } + } + } + + break; + case 'access_options': + $plugin = views_get_plugin('access', $form_state['values'][$section]['type']); + if ($plugin) { + $plugin->options_submit($form['access_options'], $form_state); + $this->set_option('access', $form_state['values'][$section]); + } + break; + case 'cache': + $cache = $this->get_option('cache'); + if ($cache['type'] != $form_state['values']['cache']['type']) { + $plugin = views_get_plugin('cache', $form_state['values']['cache']['type']); + if ($plugin) { + $cache = array('type' => $form_state['values']['cache']['type']); + $this->set_option('cache', $cache); + if (!empty($plugin->definition['uses options'])) { + views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('cache_options')); + } + } + } + + break; + case 'cache_options': + $plugin = views_get_plugin('cache', $form_state['values'][$section]['type']); + if ($plugin) { + $plugin->options_submit($form['cache_options'], $form_state); + $this->set_option('cache', $form_state['values'][$section]); + } + break; + case 'query': + $plugin = $this->get_plugin('query'); + if ($plugin) { + $plugin->options_submit($form['query']['options'], $form_state); + $this->set_option('query', $form_state['values'][$section]); + } + break; + + case 'title': + case 'css_class': + case 'link_display': + case 'display_comment': + $this->set_option($section, $form_state['values'][$section]); + break; + case 'enabled': + case 'use_ajax': + $this->set_option($section, (bool)$form_state['values'][$section]); + break; + case 'use_more': + $this->set_option($section, intval($form_state['values'][$section])); + $this->set_option('use_more_always', intval($form_state['values']['use_more_always'])); + $this->set_option('use_more_text', $form_state['values']['use_more_text']); + case 'distinct': + $this->set_option($section, $form_state['values'][$section]); + break; + case 'group_by': + $this->set_option($section, $form_state['values'][$section]); + break; + case 'row_plugin': + // This if prevents resetting options to default if they don't change + // the plugin. + if ($this->get_option($section) != $form_state['values'][$section]) { + $plugin = views_get_plugin('row', $form_state['values'][$section]); + if ($plugin) { + $this->set_option($section, $form_state['values'][$section]); + $this->set_option('row_options', array()); + + // send ajax form to options page if we use it. + if (!empty($plugin->definition['uses options'])) { + views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('row_options')); + } + } + } + break; + case 'style_plugin': + // This if prevents resetting options to default if they don't change + // the plugin. + if ($this->get_option($section) != $form_state['values'][$section]) { + $plugin = views_get_plugin('style', $form_state['values'][$section]); + if ($plugin) { + $this->set_option($section, $form_state['values'][$section]); + $this->set_option('style_options', array()); + // send ajax form to options page if we use it. + if (!empty($plugin->definition['uses options'])) { + views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('style_options')); + } + } + } + break; + case 'style_options': + $style = TRUE; + case 'row_options': + // if row, $style will be empty. + $plugin = $this->get_plugin(empty($style) ? 'row' : 'style'); + if ($plugin) { + $plugin->options_submit($form[$section], $form_state); + } + $this->set_option($section, $form_state['values'][$section]); + break; + case 'exposed_block': + $this->set_option($section, (bool) $form_state['values'][$section]); + break; + case 'exposed_form': + $exposed_form = $this->get_option('exposed_form'); + if ($exposed_form['type'] != $form_state['values']['exposed_form']['type']) { + $plugin = views_get_plugin('exposed_form', $form_state['values']['exposed_form']['type']); + if ($plugin) { + $exposed_form = array('type' => $form_state['values']['exposed_form']['type'], 'options' => array()); + $this->set_option('exposed_form', $exposed_form); + if (!empty($plugin->definition['uses options'])) { + views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('exposed_form_options')); + } + } + } + + break; + case 'exposed_form_options': + $plugin = $this->get_plugin('exposed_form'); + if ($plugin) { + $exposed_form = $this->get_option('exposed_form'); + $plugin->options_submit($form['exposed_form_options'], $form_state); + $exposed_form['options'] = $form_state['values'][$section]; + $this->set_option('exposed_form', $exposed_form); + } + break; + case 'pager': + $pager = $this->get_option('pager'); + if ($pager['type'] != $form_state['values']['pager']['type']) { + $plugin = views_get_plugin('pager', $form_state['values']['pager']['type']); + if ($plugin) { + // Because pagers have very similar options, let's allow pagers to + // try to carry the options over. + $plugin->init($this->view, $this->display, $pager['options']); + + $pager = array('type' => $form_state['values']['pager']['type'], 'options' => $plugin->options); + $this->set_option('pager', $pager); + if (!empty($plugin->definition['uses options'])) { + views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('pager_options')); + } + } + } + + break; + case 'pager_options': + $plugin = $this->get_plugin('pager'); + if ($plugin) { + $pager = $this->get_option('pager'); + $plugin->options_submit($form['pager_options'], $form_state); + $pager['options'] = $form_state['values'][$section]; + $this->set_option('pager', $pager); + } + break; + } + } + + /** + * Add an override button for a given section, allowing the user to + * change whether this info is stored on the default display or on + * the current display. + */ + function add_override_button(&$form, &$form_state, $section) { + if ($this->is_default_display()) { + return; + } + + $form['override'] = array( + '#prefix' => '<div class="views-override clearfix">', + '#suffix' => '</div>', + ); + if ($this->is_defaulted($section)) { + $form['override']['button'] = array( + '#type' => 'submit', + '#value' => t('Override'), + '#submit' => array('views_ui_edit_display_form_override'), + ); + $help = ''; + if (module_exists('advanced_help')) { + $help = theme('advanced_help_topic', array('module' => 'views', 'topic' => 'overrides')); + } + $form['override']['markup'] = array( + '#markup' => '<div class="description">' . $help . t('Status: using default values.') . '</div>', + ); + + $form_state['update_name'] = t('Update default display'); + } + else { + $form['override']['button'] = array( + '#type' => 'submit', + '#value' => t('Use default'), + '#submit' => array('views_ui_edit_display_form_override'), + ); + $help = ''; + if (module_exists('advanced_help')) { + $help = theme('advanced_help_topic', array('module' => 'views', 'topic' => 'overrides')); + } + $form['override']['markup'] = array( + '#markup' => '<div class="description">' . $help . t('Status: using overridden values.') . '</div>', + ); + + $form_state['update_name'] = NULL; + } + } + + /** + * If override/revert was clicked, perform the proper toggle. + */ + function options_override($form, &$form_state) { + $this->set_override($form_state['section']); + } + + /** + * Flip the override setting for the given section. + */ + function set_override($section, $new_state = NULL) { + $options = $this->defaultable_sections($section); + if (!$options) { + return; + } + + if (!isset($new_state)) { + $new_state = empty($this->options['defaults'][$section]); + } + + // For each option that is part of this group, fix our settings. + foreach ($options as $option) { + if ($new_state) { + // Revert to defaults. + unset($this->options[$option]); + unset($this->display->display_options[$option]); + } + else { + // copy existing values into our display. + $this->options[$option] = $this->get_option($option); + $this->display->display_options[$option] = $this->options[$option]; + } + $this->options['defaults'][$option] = $new_state; + $this->display->display_options['defaults'][$option] = $new_state; + } + } + + /** + * Inject anything into the query that the display handler needs. + */ + function query() { } + + /** + * Not all display plugins will support filtering + */ + function render_filters() { } + + /** + * Render the 'more' link + */ + function render_more_link() { + if ($this->use_more() && ($this->use_more_always() || $this->view->query->pager->has_more_records())) { + $path = $this->get_path(); + if ($path) { + $path = $this->view->get_url(NULL, $path); + $url_options = array(); + if (!empty($this->view->exposed_raw_input)) { + $url_options['query'] = $this->view->exposed_raw_input; + } + $theme = views_theme_functions('views_more', $this->view, $this->display); + $path = check_url(url($path, $url_options)); + + return theme($theme, array('more_url' => $path, 'link_text' => $this->use_more_text())); + } + } + } + + + /** + * Legacy functions. + */ + + /** + * Render the header of the view. + */ + function render_header() { + $empty = !empty($this->view->result); + return $this->render_area('header', $empty); + } + + /** + * Render the footer of the view. + */ + function render_footer() { + $empty = !empty($this->view->result); + return $this->render_area('footer', $empty); + } + + function render_empty() { + return $this->render_area('empty'); + } + + /** + * If this display creates a block, implement one of these. + */ + function hook_block_list($delta = 0, $edit = array()) { return array(); } + + /** + * If this display creates a page with a menu item, implement it here. + */ + function hook_menu() { return array(); } + + /** + * Render this display. + */ + function render() { + return theme($this->theme_functions(), array('view' => $this->view)); + } + + function render_area($area, $empty = FALSE) { + $return = ''; + foreach ($this->get_handlers($area) as $area) { + $return .= $area->render($empty); + } + return $return; + } + + + /** + * Determine if the user has access to this display of the view. + */ + function access($account = NULL) { + if (!isset($account)) { + global $user; + $account = $user; + } + + // Full override. + if (user_access('access all views', $account)) { + return TRUE; + } + + $plugin = $this->get_plugin('access'); + if ($plugin) { + return $plugin->access($account); + } + + // fallback to all access if no plugin. + return TRUE; + } + + /** + * Set up any variables on the view prior to execution. These are separated + * from execute because they are extremely common and unlikely to be + * overridden on an individual display. + */ + function pre_execute() { + $this->view->set_use_ajax($this->use_ajax()); + if ($this->use_more()) { + $this->view->get_total_rows = TRUE; + } + $this->view->init_handlers(); + if ($this->uses_exposed()) { + $exposed_form = $this->get_plugin('exposed_form'); + $exposed_form->pre_execute(); + } + } + + /** + * When used externally, this is how a view gets run and returns + * data in the format required. + * + * The base class cannot be executed. + */ + function execute() { } + + /** + * Fully render the display for the purposes of a live preview or + * some other AJAXy reason. + */ + function preview() { return $this->view->render(); } + + /** + * Displays can require a certain type of style plugin. By default, they will + * be 'normal'. + */ + function get_style_type() { return 'normal'; } + + /** + * Make sure the display and all associated handlers are valid. + * + * @return + * Empty array if the display is valid; an array of error strings if it is not. + */ + function validate() { + $errors = array(); + // Make sure displays that use fields HAVE fields. + if ($this->uses_fields()) { + $fields = FALSE; + foreach ($this->get_handlers('field') as $field) { + if (empty($field->options['exclude'])) { + $fields = TRUE; + } + } + + if (!$fields) { + $errors[] = t('Display "@display" uses fields but there are none defined for it or all are excluded.', array('@display' => $this->display->display_title)); + } + } + + if ($this->has_path() && !$this->get_option('path')) { + $errors[] = t('Display "@display" uses a path but the path is undefined.', array('@display' => $this->display->display_title)); + } + + // Validate style plugin + $style = $this->get_plugin(); + if (empty($style)) { + $errors[] = t('Display "@display" has an invalid style plugin.', array('@display' => $this->display->display_title)); + } + else { + $result = $style->validate(); + if (!empty($result) && is_array($result)) { + $errors = array_merge($errors, $result); + } + } + + // Validate handlers + foreach (views_object_types() as $type => $info) { + foreach ($this->get_handlers($type) as $handler) { + $result = $handler->validate(); + if (!empty($result) && is_array($result)) { + $errors = array_merge($errors, $result); + } + } + } + + return $errors; + } + + /** + * Check if the provided identifier is unique. + */ + function is_identifier_unique($id, $identifier) { + foreach (views_object_types() as $type => $info) { + foreach ($this->get_handlers($type) as $key => $handler) { + if ($handler->can_expose() && $handler->is_exposed()) { + if ($id != $key && $identifier == $handler->options['expose']['identifier']) { + return FALSE; + } + } + } + } + return TRUE; + } + + /** + * Provide the block system with any exposed widget blocks for this display. + */ + function get_special_blocks() { + $delta = '-exp-' . $this->view->name . '-' . $this->display->id; + $desc = t('Exposed form: @view-@display_id', array('@view' => $this->view->name, '@display_id' => $this->display->id)); + + return array( + $delta => array( + 'info' => $desc, + 'cache' => DRUPAL_NO_CACHE, + ) + ); + } + + /** + * Render any special blocks provided for this display. + */ + function view_special_blocks($type) { + if ($type == '-exp') { + // avoid interfering with the admin forms. + if (arg(0) == 'admin' && arg(1) == 'build' && arg(2) == 'views') { + return; + } + $this->view->init_handlers(); + if ($this->uses_exposed()) { + $exposed_form = $this->get_plugin('exposed_form'); + return array( + 'content' => $exposed_form->render_exposed_form(TRUE), + ); + } + } + } + + /** + * Override of export_option() + * + * Because displays do not want to export options that are NOT overridden from the + * default display, we need some special handling during the export process. + */ + function export_option($indent, $prefix, $storage, $option, $definition, $parents) { + // The $prefix is wrong because we store our actual options a little differently: + $prefix = '$handler->display->display_options'; + $output = ''; + if (!$parents && !$this->is_default_display()) { + // Do not export items that are not overridden. + if ($this->is_defaulted($option)) { + return; + } + + // If this is not defaulted and is overrideable, flip the switch to say this + // is overridden. + if ($this->defaultable_sections($option)) { + $output .= $indent . $prefix . "['defaults']['$option'] = FALSE;\n"; + } + } + + $output .= parent::export_option($indent, $prefix, $storage, $option, $definition, $parents); + return $output; + } + + /** + * Special method to export items that have handlers. + * + * This method was specified in the option_definition() as the method to utilize to + * export fields, filters, sort criteria, relationships and arguments. This passes + * the export off to the individual handlers so that they can export themselves + * properly. + */ + function export_handler($indent, $prefix, $storage, $option, $definition, $parents) { + $output = ''; + + // cut the 's' off because the data is stored as the plural form but we need + // the singular form. Who designed that anyway? Oh yeah, I did. :( + if ($option != 'header' && $option != 'footer' && $option != 'empty') { + $type = substr($option, 0, -1); + } + else { + $type = $option; + } + $types = views_object_types(); + foreach ($storage[$option] as $id => $info) { + if (!empty($types[$type]['type'])) { + $handler_type = $types[$type]['type']; + } + else { + $handler_type = $type; + } + $handler = views_get_handler($info['table'], $info['field'], $handler_type); + if ($handler) { + $handler->init($this->view, $info); + $output .= $indent . '/* ' . $types[$type]['stitle'] . ': ' . $handler->ui_name() . " */\n"; + $output .= $handler->export_options($indent, $prefix . "['$option']['$id']"); + } + + // Prevent reference problems. + unset($handler); + } + + return $output; + } + + /** + * Special handling for the style export. + * + * Styles are stored as style_plugin and style_options or row_plugin and + * row_options accordingly. The options are told not to export, and the + * export for the plugin should export both. + */ + function export_style($indent, $prefix, $storage, $option, $definition, $parents) { + $output = ''; + $style_plugin = $this->get_plugin(); + if ($option == 'style_plugin') { + $type = 'style'; + $options_field = 'style_options'; + $plugin = $style_plugin; + } + else { + if (!$style_plugin || !$style_plugin->uses_row_plugin()) { + return; + } + + $type = 'row'; + $options_field = 'row_options'; + $plugin = $this->get_plugin('row'); + // If the style plugin doesn't use row plugins, don't even bother. + } + + if ($plugin) { + // Write which plugin to use. + $value = $this->get_option($option); + $output .= $indent . $prefix . "['$option'] = '$value';\n"; + + // Pass off to the plugin to export itself. + $output .= $plugin->export_options($indent, $prefix . "['$options_field']"); + } + + return $output; + } + + /** + * Special handling for plugin export + * + * Plugins other than styles are stored in array with 'type' being the key + * to the plugin. For modern plugins, the options are stored in the 'options' + * array, but for legacy plugins (access and cache) options are stored as + * siblings to the type. + */ + function export_plugin($indent, $prefix, $storage, $option, $definition, $parents) { + $output = ''; + $plugin_type = end($parents); + $plugin = $this->get_plugin($plugin_type); + if ($plugin) { + // Write which plugin to use. + $value = $storage[$option]; + $new_prefix = $prefix . "['$plugin_type']"; + + $output .= $indent . $new_prefix . "['$option'] = '$value';\n"; + + if ($plugin_type != 'access' && $plugin_type!= 'cache') { + $new_prefix .= "['options']"; + } + + // Pass off to the plugin to export itself. + $output .= $plugin->export_options($indent, $new_prefix); + } + + return $output; + } + + function unpack_style($indent, $prefix, $storage, $option, $definition, $parents) { + $output = ''; + $style_plugin = $this->get_plugin(); + if ($option == 'style_plugin') { + $type = 'style'; + $options_field = 'style_options'; + $plugin = $style_plugin; + } + else { + if (!$style_plugin || !$style_plugin->uses_row_plugin()) { + return; + } + + $type = 'row'; + $options_field = 'row_options'; + $plugin = $this->get_plugin('row'); + // If the style plugin doesn't use row plugins, don't even bother. + } + + if ($plugin) { + return $plugin->unpack_translatables($translatable, $parents); + } + } + + /** + * Special handling for plugin unpacking. + */ + function unpack_plugin(&$translatable, $storage, $option, $definition, $parents) { + $plugin_type = end($parents); + $plugin = $this->get_plugin($plugin_type); + if ($plugin) { + // Write which plugin to use. + return $plugin->unpack_translatables($translatable, $parents); + } + } + + /** + * Special method to unpack items that have handlers. + * + * This method was specified in the option_definition() as the method to utilize to + * export fields, filters, sort criteria, relationships and arguments. This passes + * the export off to the individual handlers so that they can export themselves + * properly. + */ + function unpack_handler(&$translatable, $storage, $option, $definition, $parents) { + $output = ''; + + // cut the 's' off because the data is stored as the plural form but we need + // the singular form. Who designed that anyway? Oh yeah, I did. :( + if ($option != 'header' && $option != 'footer' && $option != 'empty') { + $type = substr($option, 0, -1); + } + else { + $type = $option; + } + $types = views_object_types(); + foreach ($storage[$option] as $id => $info) { + if (!empty($types[$type]['type'])) { + $handler_type = $types[$type]['type']; + } + else { + $handler_type = $type; + } + $handler = views_get_handler($info['table'], $info['field'], $handler_type); + if ($handler) { + $handler->init($this->view, $info); + $handler->unpack_translatables($translatable, array_merge($parents, array($handler_type, $info['table'], $info['field']))); + } + + // Prevent reference problems. + unset($handler); + } + + return $output; + } +} + + +/** + * @} + */ + diff --git a/sites/all/modules/views/plugins/views_plugin_display_attachment.inc b/sites/all/modules/views/plugins/views_plugin_display_attachment.inc new file mode 100644 index 0000000000000000000000000000000000000000..6cb34d71362f1b4091b2e7256a16bf7269946ce3 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_display_attachment.inc @@ -0,0 +1,277 @@ +<?php +// $Id: views_plugin_display_attachment.inc,v 1.6.4.3 2010/11/18 23:15:37 merlinofchaos Exp $ +/** + * @file + * Contains the attachment display plugin. + */ + +/** + * The plugin that handles an attachment display. + * + * Attachment displays are secondary displays that are 'attached' to a primary + * display. Effectively they are a simple way to get multiple views within + * the same view. They can share some information. + * + * @ingroup views_display_plugins + */ +class views_plugin_display_attachment extends views_plugin_display { + function option_definition () { + $options = parent::option_definition(); + + $options['attachment_position'] = array('default' => 'before'); + $options['inherit_arguments'] = array('default' => TRUE); + $options['inherit_exposed_filters'] = array('default' => FALSE); + $options['inherit_pager'] = array('default' => FALSE); + $options['render_pager'] = array('default' => FALSE); + $options['displays'] = array('default' => array()); + + return $options; + } + + function execute() { + return $this->view->render($this->display->id); + } + + function attachment_positions($position = NULL) { + $positions = array( + 'before' => t('Before'), + 'after' => t('After'), + 'both' => t('Both'), + ); + + if ($position) { + return $positions[$position]; + } + + return $positions; + } + + /** + * Provide the summary for attachment 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['attachment'] = array( + 'title' => t('Attachment settings'), + ); + + $options['inherit_arguments'] = array( + 'category' => 'attachment', + 'title' => t('Inherit arguments'), + 'value' => $this->get_option('inherit_arguments') ? t('Yes') : t('No'), + ); + + $options['inherit_exposed_filters'] = array( + 'category' => 'attachment', + 'title' => t('Inherit exposed filters'), + 'value' => $this->get_option('inherit_exposed_filters') ? t('Yes') : t('No'), + ); + + $options['inherit_pager'] = array( + 'category' => 'attachment', + 'title' => t('Inherit pager'), + 'value' => $this->get_option('inherit_pager') ? t('Yes') : t('No'), + ); + + $options['render_pager'] = array( + 'category' => 'attachment', + 'title' => t('Render pager'), + 'value' => $this->get_option('render_pager') ? t('Yes') : t('No'), + ); + + $options['attachment_position'] = array( + 'category' => 'attachment', + 'title' => t('Position'), + 'value' => $this->attachment_positions($this->get_option('attachment_position')), + ); + + $displays = array_filter($this->get_option('displays')); + if (count($displays) > 1) { + $attach_to = t('Multiple displays'); + } + elseif (count($displays) == 1) { + $display = array_shift($displays); + if (!empty($this->view->display[$display])) { + $attach_to = check_plain($this->view->display[$display]->display_title); + } + } + + if (!isset($attach_to)) { + $attach_to = t('None'); + } + + $options['displays'] = array( + 'category' => 'attachment', + 'title' => t('Attach to'), + 'value' => $attach_to, + ); + } + + /** + * 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 'inherit_arguments': + $form['#title'] .= t('Inherit arguments'); + $form['inherit_arguments'] = array( + '#type' => 'checkbox', + '#title' => t('Inherit'), + '#description' => t('Should this display inherit its arguments from the parent display to which it is attached?'), + '#default_value' => $this->get_option('inherit_arguments'), + ); + break; + case 'inherit_exposed_filters': + $form['#title'] .= t('Inherit exposed filters'); + $form['inherit_exposed_filters'] = array( + '#type' => 'checkbox', + '#title' => t('Inherit'), + '#description' => t('Should this display inherit its exposed filter values from the parent display to which it is attached?'), + '#default_value' => $this->get_option('inherit_exposed_filters'), + ); + break; + case 'inherit_pager': + $form['#title'] .= t('Inherit pager'); + $form['inherit_pager'] = array( + '#type' => 'checkbox', + '#title' => t('Inherit'), + '#description' => t('Should this display inherit its paging values from the parent display to which it is attached?'), + '#default_value' => $this->get_option('inherit_pager'), + ); + break; + case 'render_pager': + $form['#title'] .= t('Render pager'); + $form['render_pager'] = array( + '#type' => 'checkbox', + '#title' => t('Render'), + '#description' => t('Should this display render the pager values? This is only meaningful if inheriting a pager.'), + '#default_value' => $this->get_option('render_pager'), + ); + break; + case 'attachment_position': + $form['#title'] .= t('Position'); + $form['attachment_position'] = array( + '#type' => 'radios', + '#description' => t('Attach before or after the parent display?'), + '#options' => $this->attachment_positions(), + '#default_value' => $this->get_option('attachment_position'), + ); + break; + case 'displays': + $form['#title'] .= t('Attach to'); + $displays = array(); + foreach ($this->view->display as $display_id => $display) { + if (!empty($display->handler) && $display->handler->accept_attachments()) { + $displays[$display_id] = $display->display_title; + } + } + $form['displays'] = array( + '#type' => 'checkboxes', + '#description' => t('Select which display or displays this should attach to.'), + '#options' => $displays, + '#default_value' => $this->get_option('displays'), + ); + 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 'inherit_arguments': + case 'inherit_pager': + case 'render_pager': + case 'inherit_exposed_filters': + case 'attachment_position': + case 'displays': + $this->set_option($form_state['section'], $form_state['values'][$form_state['section']]); + break; + } + } + + /** + * Attach to another view. + */ + function attach_to($display_id) { + $displays = $this->get_option('displays'); + + if (empty($displays[$display_id])) { + return; + } + + if (!$this->access()) { + return; + } + + // Get a fresh view because our current one has a lot of stuff on it because it's + // already been executed. + $view = $this->view->clone_view(); + $view->original_args = $view->args; + + $args = $this->get_option('inherit_arguments') ? $this->view->args : array(); + $view->set_arguments($args); + $view->set_display($this->display->id); + if ($this->get_option('inherit_pager')) { + $view->display_handler->use_pager = $this->view->display[$display_id]->handler->use_pager(); + $view->display_handler->set_option('pager', $this->view->display[$display_id]->handler->get_option('pager')); + } + + $attachment = $view->execute_display($this->display->id, $args); + + switch ($this->get_option('attachment_position')) { + case 'before': + $this->view->attachment_before .= $attachment; + break; + case 'after': + $this->view->attachment_after .= $attachment; + break; + case 'both': + $this->view->attachment_before .= $attachment; + $this->view->attachment_after .= $attachment; + break; + } + + $view->destroy(); + } + + /** + * Attachment displays only use exposed widgets if + * they are set to inherit the exposed filter settings + * of their parent display. + */ + function uses_exposed() { + if (!empty($this->options['inherit_exposed_filters']) && parent::uses_exposed()) { + return TRUE; + } + return FALSE; + } + + /** + * If an attachment is set to inherit the exposed filter + * settings from its parent display, then don't render and + * display a second set of exposed filter widgets. + */ + function displays_exposed() { + return $this->options['inherit_exposed_filters'] ? FALSE : TRUE; + } + + function use_pager() { + return !empty($this->use_pager); + } + + function render_pager() { + return !empty($this->use_pager) && $this->get_option('render_pager'); + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_display_block.inc b/sites/all/modules/views/plugins/views_plugin_display_block.inc new file mode 100644 index 0000000000000000000000000000000000000000..e05efd5a50ddf2f2a13f75b53d8b65d7a305af51 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_display_block.inc @@ -0,0 +1,198 @@ +<?php +// $Id: views_plugin_display_block.inc,v 1.5.4.3 2010/08/04 05:54:08 dereine Exp $ +/** + * @file + * Contains the block display plugin. + */ + +/** + * The plugin that handles a block. + * + * @ingroup views_display_plugins + */ +class views_plugin_display_block extends views_plugin_display { + function option_definition() { + $options = parent::option_definition(); + + $options['block_description'] = array('default' => '', 'translatable' => TRUE); + $options['block_caching'] = array('default' => DRUPAL_NO_CACHE); + + return $options; + } + + /** + * The default block handler doesn't support configurable items, + * but extended block handlers might be able to do interesting + * stuff with it. + */ + function execute_hook_block_list($delta = 0, $edit = array()) { + $delta = $this->view->name . '-' . $this->display->id; + $desc = $this->get_option('block_description'); + + if (empty($desc)) { + $desc = t('@view: @display', array('@view' => $this->view->name, '@display' => $this->display->display_title)); + } + return array( + $delta => array( + 'info' => $desc, + 'cache' => $this->get_cache_type() + ), + ); + } + + /** + * The display block handler returns the structure necessary for a block. + */ + function execute() { + // Prior to this being called, the $view should already be set to this + // display, and arguments should be set on the view. + $info['content'] = $this->view->render(); + $info['subject'] = filter_xss_admin($this->view->get_title()); + if (!empty($this->view->result) || $this->get_option('empty') || !empty($this->view->style_plugin->definition['even empty'])) { + return $info; + } + } + + /** + * 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['block'] = array( + 'title' => t('Block settings'), + ); + + $block_description = strip_tags($this->get_option('block_description')); + if (empty($block_description)) { + $block_description = t('None'); + } + + if (strlen($block_description) > 16) { + $block_description = substr($block_description, 0, 16) . '...'; + } + + $options['block_description'] = array( + 'category' => 'block', + 'title' => t('Admin'), + 'value' => $block_description, + ); + + $cache_type = $this->get_option('block_caching'); + if (empty($cache_type)) { + $cache_type = DRUPAL_NO_CACHE; + } + + $types = $this->block_caching_modes(); + $options['block_caching'] = array( + 'category' => 'block', + 'title' => t('Caching'), + 'value' => $types[$this->get_cache_type()], + ); + } + + /** + * Provide a list of core's block caching modes. + */ + function block_caching_modes() { + return array( + DRUPAL_NO_CACHE => t('Do not cache'), + DRUPAL_CACHE_GLOBAL => t('Cache once for everything (global)'), + DRUPAL_CACHE_PER_PAGE => t('Per page'), + DRUPAL_CACHE_PER_ROLE => t('Per role'), + DRUPAL_CACHE_PER_ROLE | DRUPAL_CACHE_PER_PAGE => t('Per role per page'), + DRUPAL_CACHE_PER_USER => t('Per user'), + DRUPAL_CACHE_PER_USER | DRUPAL_CACHE_PER_PAGE => t('Per user per page'), + ); + } + + /** + * Provide a single method to figure caching type, keeping a sensible default + * for when it's unset. + */ + function get_cache_type() { + $cache_type = $this->get_option('block_caching'); + if (empty($cache_type)) { + $cache_type = DRUPAL_NO_CACHE; + } + return $cache_type; + } + + /** + * 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 'block_description': + $form['#title'] .= t('Block admin description'); + $form['block_description'] = array( + '#type' => 'textfield', + '#description' => t('This will appear as the name of this block in administer >> structure >> blocks.'), + '#default_value' => $this->get_option('block_description'), + ); + break; + case 'block_caching': + $form['#title'] .= t('Block caching type'); + + $form['block_caching'] = array( + '#type' => 'radios', + '#description' => t("This sets the default status for Drupal's built-in block caching method; this requires that caching be turned on in block administration, and be careful because you have little control over when this cache is flushed."), + '#options' => $this->block_caching_modes(), + '#default_value' => $this->get_cache_type(), + ); + 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 'block_description': + $this->set_option('block_description', $form_state['values']['block_description']); + break; + case 'block_caching': + $this->set_option('block_caching', $form_state['values']['block_caching']); + $this->save_block_cache($form_state['view']->name.'-'.$form_state['display_id'], $form_state['values']['block_caching']); + break; + } + } + + /** + * Block views use exposed widgets only if AJAX is set. + */ + function uses_exposed() { + if ($this->use_ajax()) { + return parent::uses_exposed(); + } + + return FALSE; + } + + /** + * Save the block cache setting in the blocks table if this block allready + * exists in the blocks table. Dirty fix untill http://drupal.org/node/235673 gets in. + */ + function save_block_cache($delta, $cache_setting) { + if ($bid = db_query("SELECT bid FROM {block} WHERE module = 'views' AND delta = :delta", array( + ':delta' => $delta))->fetchField()) { + db_update('block') + ->fields(array( + 'cache' => $cache_setting, + )) + ->condition('module','views') + ->condition('delta', $delta) + ->execute(); + } + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_display_default.inc b/sites/all/modules/views/plugins/views_plugin_display_default.inc new file mode 100644 index 0000000000000000000000000000000000000000..2708967d79d8c2906f73c28afd43a2925bba9231 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_display_default.inc @@ -0,0 +1,56 @@ +<?php +// $Id: views_plugin_display_default.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $ +/** + * @file + * Contains the default display plugin. + */ + +/** + * A plugin to handle defaults on a view. + * + * @ingroup views_display_plugins + */ +class views_plugin_display_default extends views_plugin_display { + /** + * Determine if this display is the 'default' display which contains + * fallback settings + */ + function is_default_display() { return TRUE; } + + /** + * The default execute handler fully renders the view. + * + * For the simplest use: + * @code + * $output = $view->execute_display('default', $args); + * @endcode + * + * For more complex usages, a view can be partially built: + * @code + * $view->set_arguments($args); + * $view->build('default'); // Build the query + * $view->execute(); // Run the query + * $output = $view->render(); // Render the view + * @endcode + * + * If short circuited at any point, look in $view->build_info for + * information about the query. After execute, look in $view->result + * for the array of objects returned from db_query. + * + * You can also do: + * @code + * $view->set_arguments($args); + * $output = $view->render('default'); // Render the view + * @endcode + * + * This illustrates that render is smart enough to call build and execute + * if these items have not already been accomplished. + * + * Note that execute also must accomplish other tasks, such + * as setting page titles, breadcrumbs, and generating exposed filter + * data if necessary. + */ + function execute() { + return $this->view->render($this->display->id); + } +} \ No newline at end of file diff --git a/sites/all/modules/views/plugins/views_plugin_display_feed.inc b/sites/all/modules/views/plugins/views_plugin_display_feed.inc new file mode 100644 index 0000000000000000000000000000000000000000..0d4f738a97f4ab26893bc8b8e32435abd6deb9f2 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_display_feed.inc @@ -0,0 +1,202 @@ +<?php +// $Id: views_plugin_display_feed.inc,v 1.7.4.5 2010/12/18 08:02:38 dereine Exp $ +/** + * @file + * Contains the feed display plugin. + */ + +/** + * The plugin that handles a feed, such as RSS or atom. + * + * For the most part, feeds are page displays but with some subtle differences. + * + * @ingroup views_display_plugins + */ +class views_plugin_display_feed extends views_plugin_display_page { + function uses_breadcrumb() { return FALSE; } + function get_style_type() { return 'feed'; } + + /** + * Feeds do not go through the normal page theming mechanism. Instead, they + * go through their own little theme function and then return NULL so that + * Drupal believes that the page has already rendered itself...which it has. + */ + function execute() { + $output = $this->view->render(); + if (empty($output)) { + return drupal_not_found(); + } + print $output; + } + + function preview() { + if (!empty($this->view->live_preview)) { + return '<pre>' . check_plain($this->view->render()) . '</pre>'; + } + return $this->view->render(); + } + + /** + * Instead of going through the standard views_view.tpl.php, delegate this + * to the style handler. + */ + function render() { + return $this->view->style_plugin->render($this->view->result); + } + + function defaultable_sections($section = NULL) { + if (in_array($section, array('style_options', 'style_plugin', 'row_options', 'row_plugin',))) { + return FALSE; + } + + $sections = parent::defaultable_sections($section); + + // Tell views our sitename_title option belongs in the title section. + if ($section == 'title') { + $sections[] = 'sitename_title'; + } + elseif (!$section) { + $sections['title'][] = 'sitename_title'; + } + return $sections; + } + + function option_definition() { + $options = parent::option_definition(); + + $options['displays'] = array('default' => array()); + + // Overrides for standard stuff: + $options['style_plugin']['default'] = 'rss'; + $options['style_options']['default'] = array('description' => ''); + $options['sitename_title']['default'] = FALSE; + $options['row_plugin']['default'] = ''; + $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; + } + + function options_summary(&$categories, &$options) { + // It is very important to call the parent function here: + parent::options_summary($categories, $options); + + // Since we're childing off the 'page' type, we'll still *call* our + // category 'page' but let's override it so it says feed settings. + $categories['page'] = array( + 'title' => t('Feed settings'), + ); + + if ($this->get_option('sitename_title')) { + $options['title']['value'] = t('Using the site name'); + } + + // I don't think we want to give feeds menus directly. + unset($options['menu']); + + $displays = array_filter($this->get_option('displays')); + if (count($displays) > 1) { + $attach_to = t('Multiple displays'); + } + elseif (count($displays) == 1) { + $display = array_shift($displays); + if (!empty($this->view->display[$display])) { + $attach_to = check_plain($this->view->display[$display]->display_title); + } + } + + if (!isset($attach_to)) { + $attach_to = t('None'); + } + + $options['displays'] = array( + 'category' => 'page', + 'title' => t('Attach to'), + 'value' => $attach_to, + ); + } + + /** + * 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 'title': + $title = $form['title']; + // A little juggling to move the 'title' field beyond our checkbox. + unset($form['title']); + $form['sitename_title'] = array( + '#type' => 'checkbox', + '#title' => t('Use the site name for the title'), + '#default_value' => $this->get_option('sitename_title'), + ); + $form['title'] = $title; + $form['title']['#process'] = array('ctools_dependent_process'); + $form['title']['#dependency'] = array('edit-sitename-title' => array(FALSE)); + break; + case 'displays': + $form['#title'] .= t('Attach to'); + $displays = array(); + foreach ($this->view->display as $display_id => $display) { + if (!empty($display->handler) && $display->handler->accept_attachments()) { + $displays[$display_id] = $display->display_title; + } + } + $form['displays'] = array( + '#type' => 'checkboxes', + '#description' => t('The feed icon will be available only to the selected displays.'), + '#options' => $displays, + '#default_value' => $this->get_option('displays'), + ); + break; + case 'path': + $form['path']['#description'] = t('This view will be displayed by visiting this path on your site. It is recommended that the path be something like "path/%/%/feed" or "path/%/%/rss.xml", putting one % in the path for each argument you have defined in the view.'); + } + } + + /** + * 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 'title': + $this->set_option('sitename_title', $form_state['values']['sitename_title']); + break; + case 'displays': + $this->set_option($form_state['section'], $form_state['values'][$form_state['section']]); + break; + } + } + + /** + * Attach to another view. + */ + function attach_to($display_id) { + $displays = $this->get_option('displays'); + if (empty($displays[$display_id])) { + return; + } + + // Defer to the feed style; it may put in meta information, and/or + // attach a feed icon. + $plugin = $this->get_plugin(); + if ($plugin) { + $clone = $this->view->clone_view(); + $clone->set_display($this->display->id); + $clone->build_title(); + $plugin->attach_to($display_id, $this->get_path(), $clone->get_title()); + } + } + + function uses_link_display() { + return TRUE; + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_display_page.inc b/sites/all/modules/views/plugins/views_plugin_display_page.inc new file mode 100644 index 0000000000000000000000000000000000000000..e7dabd40088698cd373b0c1d7877bcc286b33b1d --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_display_page.inc @@ -0,0 +1,529 @@ +<?php +// $Id: views_plugin_display_page.inc,v 1.8.4.14 2011/01/04 21:26:47 dereine Exp $ +/** + * @file + * Contains the page display plugin. + */ + +/** + * The plugin that handles a full page. + * + * @ingroup views_display_plugins + */ +class views_plugin_display_page extends views_plugin_display { + /** + * The page display has a path. + */ + function has_path() { return TRUE; } + function uses_breadcrumb() { return TRUE; } + + function option_definition() { + $options = parent::option_definition(); + + $options['path'] = array('default' => ''); + $options['menu'] = array( + 'contains' => array( + 'type' => array('default' => 'none'), + // Do not translate menu and title as menu system will. + 'title' => array('default' => '', 'translatable' => FALSE), + 'description' => array('default' => '', 'translatable' => FALSE), + 'weight' => array('default' => 0), + 'name' => array('default' => variable_get('menu_default_node_menu', 'navigation')), + ), + ); + $options['tab_options'] = array( + 'contains' => array( + 'type' => array('default' => 'none'), + // Do not translate menu and title as menu system will. + 'title' => array('default' => '', 'translatable' => FALSE), + 'description' => array('default' => '', 'translatable' => FALSE), + 'weight' => array('default' => 0), + 'name' => array('default' => 'navigation'), + ), + ); + + return $options; + } + + /** + * Add this display's path information to Drupal's menu system. + */ + function execute_hook_menu($callbacks) { + $items = array(); + // Replace % with the link to our standard views argument loader + // views_arg_load -- which lives in views.module + + $bits = explode('/', $this->get_option('path')); + $page_arguments = array($this->view->name, $this->display->id); + $view_arguments = $this->get_option('arguments'); + + // Replace % with %views_arg for menu autoloading and add to the + // page arguments so the argument actually comes through. + foreach($bits as $pos => $bit) { + if ($bit == '%') { + $argument = array_shift($view_arguments); + if (isset($argument['validate_type']) && $argument['validate_type'] != 'none') { + $bits[$pos] = '%views_arg'; + } + $page_arguments[] = $pos; + } + } + + $path = implode('/', $bits); + + $access_plugin = $this->get_plugin('access'); + if (!isset($access_plugin)) { + $access_plugin = views_get_plugin('access', 'none'); + } + + // Get access callback might return an array of the callback + the dynamic arguments. + $access_plugin_callback = $access_plugin->get_access_callback(); + + if (is_array($access_plugin_callback)) { + $access_arguments = array(); + + // Find the plugin arguments. + $access_plugin_method = array_shift($access_plugin_callback); + $access_plugin_arguments = array_shift($access_plugin_callback); + if (!is_array($access_plugin_arguments)) { + $access_plugin_arguments = array(); + } + + $access_arguments[0] = array($access_plugin_method, &$access_plugin_arguments); + + // Move the plugin arguments to the access arguments array. + $i = 1; + foreach ($access_plugin_arguments as $key => $value) { + if (is_int($value)) { + $access_arguments[$i] = $value; + $access_plugin_arguments[$key] = $i; + $i++; + } + } + } + else { + $access_arguments = array($access_plugin_callback); + } + + if ($path) { + $items[$path] = array( + // default views page entry + 'page callback' => 'views_page', + 'page arguments' => $page_arguments, + // Default access check (per display) + 'access callback' => 'views_access', + 'access arguments' => $access_arguments, + // Identify URL embedded arguments and correlate them to a handler + 'load arguments' => array($this->view->name, $this->display->id, '%index'), + ); + $menu = $this->get_option('menu'); + if (empty($menu)) { + $menu = array('type' => 'none'); + } + // Set the title and description if we have one. + if ($menu['type'] != 'none') { + $items[$path]['title'] = $menu['title']; + $items[$path]['description'] = $menu['description']; + } + + if (isset($menu['weight'])) { + $items[$path]['weight'] = intval($menu['weight']); + } + + switch ($menu['type']) { + case 'none': + default: + $items[$path]['type'] = MENU_CALLBACK; + break; + case 'normal': + $items[$path]['type'] = MENU_NORMAL_ITEM; + // Insert item into the proper menu + $items[$path]['menu_name'] = $menu['name']; + break; + case 'tab': + $items[$path]['type'] = MENU_LOCAL_TASK; + break; + case 'default tab': + $items[$path]['type'] = MENU_DEFAULT_LOCAL_TASK; + break; + } + + // If this is a 'default' tab, check to see if we have to create teh + // parent menu item. + if ($menu['type'] == 'default tab') { + $tab_options = $this->get_option('tab_options'); + if (!empty($tab_options['type']) && $tab_options['type'] != 'none') { + $bits = explode('/', $path); + // Remove the last piece. + $bit = array_pop($bits); + + // we can't do this if they tried to make the last path bit variable. + // @todo: We can validate this. + if ($bit != '%views_arg' && !empty($bits)) { + $default_path = implode('/', $bits); + $items[$default_path] = array( + // default views page entry + 'page callback' => 'views_page', + 'page arguments' => $page_arguments, + // Default access check (per display) + 'access callback' => 'views_access', + 'access arguments' => array($access_plugin->get_access_callback()), + // Identify URL embedded arguments and correlate them to a handler + 'load arguments' => array($this->view->name, $this->display->id, '%index'), + 'title' => $tab_options['title'], + 'description' => $tab_options['description'], + 'menu_name' => $tab_options['name'], + ); + switch ($tab_options['type']) { + default: + case 'normal': + $items[$default_path]['type'] = MENU_NORMAL_ITEM; + break; + case 'tab': + $items[$default_path]['type'] = MENU_LOCAL_TASK; + break; + } + if (isset($tab_options['weight'])) { + $items[$default_path]['weight'] = intval($tab_options['weight']); + } + } + } + } + } + + return $items; + } + + /** + * The display page handler returns a normal view, but it also does + * a drupal_set_title for the page, and does a views_set_page_view + * on the view. + */ + function execute() { + // Let the world know that this is the page view we're using. + views_set_page_view($this); + + // Prior to this being called, the $view should already be set to this + // display, and arguments should be set on the view. + $this->view->build(); + if (!empty($this->view->build_info['fail'])) { + return drupal_not_found(); + } + + $this->view->get_breadcrumb(TRUE); + + // And the title, which is much easier. + drupal_set_title(filter_xss_admin($this->view->get_title()), PASS_THROUGH); + + // And now render the view. + return $this->view->render(); + } + + /** + * 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['page'] = array( + 'title' => t('Page settings'), + ); + + $path = strip_tags($this->get_option('path')); + if (empty($path)) { + $path = t('None'); + } + + if (strlen($path) > 16) { + $path = substr($path, 0, 16) . '...'; + } + + $options['path'] = array( + 'category' => 'page', + 'title' => t('Path'), + 'value' => $path, + ); + + $menu = $this->get_option('menu'); + if (!is_array($menu)) { + $menu = array('type' => 'none'); + } + switch($menu['type']) { + case 'none': + default: + $menu_str = t('No menu'); + break; + case 'normal': + $menu_str = t('Normal: @title', array('@title' => $menu['title'])); + break; + case 'tab': + case 'default tab': + $menu_str = t('Tab: @title', array('@title' => $menu['title'])); + break; + } + + if (strlen($menu_str) > 16) { + $menu_str = substr($menu_str, 0, 16) . '...'; + } + + $options['menu'] = array( + 'category' => 'page', + 'title' => t('Menu'), + 'value' => $menu_str, + ); + + // This adds a 'Settings' link to the style_options setting if the style has options. + if ($menu['type'] == 'default tab') { + $options['menu']['links']['tab_options'] = t('Change settings for the parent menu'); + } + } + + /** + * 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 'path': + $form['#title'] .= t('The menu path or URL of this view'); + $form['#help_topic'] = 'path'; + $form['path'] = array( + '#type' => 'textfield', + '#description' => t('This view will be displayed by visiting this path on your site. You may use "%" in your URL to represent values that will be used for arguments: For example, "node/%/feed".'), + '#default_value' => $this->get_option('path'), + '#field_prefix' => '<span dir="ltr">' . url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q='), + '#field_suffix' => '</span>‎', + '#attributes' => array('dir'=>'ltr'), + ); + break; + case 'menu': + $form['#title'] .= t('Menu item entry'); + $form['#help_topic'] = 'menu'; + $form['menu'] = array( + '#prefix' => '<div class="clearfix">', + '#suffix' => '</div>', + '#tree' => TRUE, + ); + $menu = $this->get_option('menu'); + if (empty($menu)) { + $menu = array('type' => 'none', 'title' => '', 'weight' => 0); + } + $form['menu']['type'] = array( + '#prefix' => '<div class="views-left-30">', + '#suffix' => '</div>', + '#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( + '#prefix' => '<div class="views-left-50">', + '#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')), + ); + $form['menu']['description'] = array( + '#title' => t('Description'), + '#type' => 'textfield', + '#default_value' => $menu['description'], + '#description' => t("If set to normal or tab, enter the text to use for the menu item's description."), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:menu[type]' => array('normal', 'tab', 'default tab')), + ); + + // 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('form_process_select', 'ctools_dependent_process'), + '#dependency' => array('radio:menu[type]' => array('normal')), + ); + } + else { + $form['menu']['name'] = array( + '#type' => 'value', + '#value' => $menu['name'], + ); + $form['menu']['markup'] = array( + '#markup' => t('Menu selection requires the activation of menu module.'), + ); + } + $form['menu']['weight'] = array( + '#suffix' => '</div>', + '#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')), + ); + break; + case 'tab_options': + $form['#title'] .= t('Default tab options'); + $tab_options = $this->get_option('tab_options'); + if (empty($tab_options)) { + $tab_options = array('type' => 'none', 'title' => '', 'weight' => 0); + } + + $form['tab_markup'] = array( + '#markup' => '<div class="form-item description">' . t('When providing a menu item as a 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>.') . '</div>', + ); + + $form['tab_options'] = array( + '#prefix' => '<div class="clearfix">', + '#suffix' => '</div>', + '#tree' => TRUE, + ); + $form['tab_options']['type'] = array( + '#prefix' => '<div class="views-left-25">', + '#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' => $tab_options['type'], + ); + $form['tab_options']['title'] = array( + '#prefix' => '<div class="views-left-75">', + '#title' => t('Title'), + '#type' => 'textfield', + '#default_value' => $tab_options['title'], + '#description' => t('If creating a parent menu item, enter the title of the item.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:tab_options[type]' => array('normal', 'tab')), + ); + $form['tab_options']['description'] = array( + '#title' => t('Description'), + '#type' => 'textfield', + '#default_value' => $tab_options['description'], + '#description' => t('If creating a parent menu item, enter the description of the item.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('radio:tab_options[type]' => array('normal', 'tab')), + ); + // Only display the menu selector if menu module is enabled. + if (module_exists('menu')) { + $form['tab_options']['name'] = array( + '#title' => t('Menu'), + '#type' => 'select', + '#options' => menu_get_menus(), + '#default_value' => $tab_options['name'], + '#description' => t('Insert item into an available menu.'), + '#process' => array('form_process_select', 'ctools_dependent_process'), + '#dependency' => array('radio:tab_options[type]' => array('normal')), + ); + } + else { + $form['tab_options']['name'] = array( + '#type' => 'value', + '#value' => $tab_options['name'], + ); + $form['tab_options']['markup'] = array( + '#value' => t('Menu selection requires the activation of menu module.'), + ); + } + $form['tab_options']['weight'] = array( + '#suffix' => '</div>', + '#title' => t('Tab weight'), + '#type' => 'textfield', + '#default_value' => $tab_options['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:tab_options[type]' => array('tab')), + ); + break; + } + } + + function options_validate(&$form, &$form_state) { + // It is very important to call the parent function here: + parent::options_validate($form, $form_state); + switch ($form_state['section']) { + case 'path': + if (strpos($form_state['values']['path'], '$arg') !== FALSE) { + form_error($form['path'], t('"$arg" is no longer supported. Use % instead.')); + } + + if (strpos($form_state['values']['path'], '%') === 0) { + form_error($form['path'], t('"%" may not be used for the first segment of a path.')); + } + + // automatically remove '/' from path. + $form_state['values']['path'] = trim($form_state['values']['path'], '/'); + + break; + case 'menu': + $path = $this->get_option('path'); + if ($form_state['values']['menu']['type'] == 'normal' && strpos($path, '%') !== FALSE) { + form_error($form['menu']['type'], t('Views cannot create normal menu items for paths with a % in them.')); + } + + if ($form_state['values']['menu']['type'] == 'default tab' || $form_state['values']['menu']['type'] == 'tab') { + $bits = explode('/', $path); + $last = array_pop($bits); + if ($last == '%') { + form_error($form['menu']['type'], t('A display whose path ends with a % cannot be a tab.')); + } + } + + if ($form_state['values']['menu']['type'] != 'none' && empty($form_state['values']['menu']['title'])) { + form_error($form['menu']['title'], t('Title is required for this menu type.')); + } + break; + } + } + + 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 'path': + $this->set_option('path', $form_state['values']['path']); + break; + case 'menu': + $this->set_option('menu', $form_state['values']['menu']); + // send ajax form to options page if we use it. + if ($form_state['values']['menu']['type'] == 'default tab') { + views_ui_add_form_to_stack('display', $this->view, $this->display->id, array('tab_options')); + } + break; + case 'tab_options': + $this->set_option('tab_options', $form_state['values']['tab_options']); + break; + } + } + + function validate() { + $errors = parent::validate(); + + $menu = $this->get_option('menu'); + if (!empty($menu['type']) && $menu['type'] != 'none' && empty($menu['title'])) { + $errors[] = t('Display @display is set to use a menu but the menu title is not set.', array('@display' => $this->display->display_title)); + } + + if ($menu['type'] == 'default tab') { + $tab_options = $this->get_option('tab_options'); + if (!empty($tab_options['type']) && $tab_options['type'] != 'none' && empty($tab_options['title'])) { + $errors[] = t('Display @display is set to use a parent menu but the parent menu title is not set.', array('@display' => $this->display->display_title)); + } + } + + return $errors; + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_exposed_form.inc b/sites/all/modules/views/plugins/views_plugin_exposed_form.inc new file mode 100644 index 0000000000000000000000000000000000000000..8bef2f1b610bbb3424bbe498b52e083568950616 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_exposed_form.inc @@ -0,0 +1,248 @@ +<?php +// $Id: views_plugin_exposed_form.inc,v 1.2.2.18 2010/12/01 20:05:06 dereine Exp $ + +/** + * The base plugin to handle exposed filter forms. + */ +class views_plugin_exposed_form extends views_plugin { + + /** + * Initialize the plugin. + * + * @param $view + * The view object. + * @param $display + * The display handler. + */ + function init(&$view, &$display, $options = array()) { + $this->view = &$view; + $this->display = &$display; + + $this->unpack_options($this->options, $options); + } + + /** + * Return a string to display as the clickable title for the + * control. + */ + function summary_title() { + return t('Unknown'); + } + + function option_definition() { + $options = parent::option_definition(); + $options['submit_button'] = array('default' => t('Apply'), 'translatable' => TRUE); + $options['reset_button'] = array('default' => FALSE, 'bool' => TRUE); + $options['reset_button_label'] = array('default' => 'Reset', 'translatable' => TRUE); + $options['exposed_sorts_label'] = array('default' => 'Sort By', 'translatable' => TRUE); + $options['sort_asc_label'] = array('default' => 'Asc', 'translatable' => TRUE); + $options['sort_desc_label'] = array('default' => 'Desc', 'translatable' => TRUE); + return $options; + } + + function options_form(&$form, &$form_state) { + $form['submit_button'] = array( + '#type' => 'textfield', + '#title' => t('Submit button text'), + '#description' => t('Text to display in the submit button of the exposed form.'), + '#default_value' => $this->options['submit_button'], + '#required' => TRUE, + ); + + $form['reset_button'] = array ( + '#type' => 'checkbox', + '#title' => t('Include reset button'), + '#description' => t('If checked the exposed form will provide a button to reset all the applied exposed filters'), + '#default_value' => $this->options['reset_button'], + ); + + $form['reset_button_label'] = array( + '#type' => 'textfield', + '#title' => t('Reset button label'), + '#description' => t('Text to display in the reset button of the exposed form.'), + '#default_value' => $this->options['reset_button_label'], + '#required' => TRUE, + '#dependency' => array( + 'edit-exposed-form-options-reset-button' => array(1) + ), + '#process' => array('ctools_dependent_process'), + ); + + $form['exposed_sorts_label'] = array( + '#type' => 'textfield', + '#title' => t('Exposed sorts label'), + '#description' => t('Text to display as the label of the exposed sort select box.'), + '#default_value' => $this->options['exposed_sorts_label'], + '#required' => TRUE, + ); + + $form['sort_asc_label'] = array( + '#type' => 'textfield', + '#title' => t('Ascending'), + '#description' => t('Text to use when exposed sort is ordered ascending.'), + '#default_value' => $this->options['sort_asc_label'], + '#required' => TRUE, + ); + + $form['sort_desc_label'] = array( + '#type' => 'textfield', + '#title' => t('Descending'), + '#description' => t('Text to use when exposed sort is ordered descending.'), + '#default_value' => $this->options['sort_desc_label'], + '#required' => TRUE, + ); + } + + /** + * Render the exposed filter form. + * + * This actually does more than that; because it's using FAPI, the form will + * also assign data to the appropriate handlers for use in building the + * query. + */ + function render_exposed_form($block = FALSE) { + // Deal with any exposed filters we may have, before building. + $form_state = array( + 'view' => &$this->view, + 'display' => &$this->display, + 'method' => 'get', + 'rerender' => TRUE, + 'no_redirect' => TRUE, + 'always_process' => TRUE, + ); + + // Some types of displays (eg. attachments) may wish to use the exposed + // filters of their parent displays instead of showing an additional + // exposed filter form for the attachment as well as that for the parent. + if (!$this->view->display_handler->displays_exposed() || (!$block && $this->view->display_handler->get_option('exposed_block'))) { + unset($form_state['rerender']); + } + + if (!empty($this->ajax)) { + $form_state['ajax'] = TRUE; + } + + $form_state['exposed_form_plugin'] = $this; + $form = drupal_build_form('views_exposed_form', $form_state); + $output = drupal_render($form); + if (!empty($form_state['js settings'])) { + $this->view->js_settings = $form_state['js settings']; + } + + if (!$this->view->display_handler->displays_exposed() || (!$block && $this->view->display_handler->get_option('exposed_block'))) { + return ""; + } + else { + return $output; + } + } + + function query() { + $view = $this->view; + $exposed_data = isset($view->exposed_data) ? $view->exposed_data : array(); + $sort_by = isset($exposed_data['sort_by']) ? $exposed_data['sort_by'] : NULL; + if (!empty($sort_by)) { + $handler = $view->sort[$sort_by]; + if (isset($handler)) { + $view->query->orderby = array(); + if (isset($exposed_data['sort_order']) && in_array($exposed_data['sort_order'], array('ASC', 'DESC'))) { + $handler->options['order'] = $exposed_data['sort_order']; + } + $handler->query(); + foreach ($view->sort as $sort) { + if (!$sort->is_exposed()) { + $sort->query(); + } + } + } + } + } + + function pre_render($values) { } + + function post_render(&$output) { } + + function pre_execute() { } + + function post_execute() { } + + function exposed_form_alter(&$form, &$form_state) { + if (!empty($this->options['reset_button'])) { + $form['reset'] = array( + '#value' => $this->options['reset_button_label'], + '#type' => 'submit', + ); + } + + $form['submit']['#value'] = $this->options['submit_button']; + // Check if there is exposed sorts for this view + $exposed_sorts = array(); + foreach ($this->view->sort as $id => $handler) { + if ($handler->can_expose() && $handler->is_exposed()) { + $exposed_sorts[$id] = check_plain($handler->options['expose']['label']); + } + } + + if (count($exposed_sorts)) { + $form['sort_by'] = array( + '#type' => 'select', + '#options' => $exposed_sorts, + '#title' => t($this->options['exposed_sorts_label']), + ); + $sort_order = array( + 'ASC' => $this->options['sort_asc_label'], + 'DESC' => $this->options['sort_desc_label'], + ); + $first_sort = reset($this->view->sort); + $form['sort_order'] = array( + '#type' => 'select', + '#options' => $sort_order, + '#title' => t('Order'), + '#default_value' => $first_sort->options['order'], + ); + $form['submit']['#weight'] = 10; + if (isset($form['reset'])) { + $form['reset']['#weight'] = 10; + } + } + + $pager = $this->view->display_handler->get_plugin('pager'); + if ($pager) { + $pager->exposed_form_alter($form, $form_state); + $form_state['pager_plugin'] = $pager; + } + } + + function exposed_form_validate(&$form, &$form_state) { + if (isset($form_state['pager_plugin'])) { + $form_state['pager_plugin']->exposed_form_validate($form, $form_state); + } + } + + /** + * This function is executed when exposed form is submited. + * + * @param $form + * Nested array of form elements that comprise the form. + * @param $form_state + * A keyed array containing the current state of the form. + * @param $exclude + * Nested array of keys to exclude of insert into + * $view->exposed_raw_input + */ + function exposed_form_submit(&$form, &$form_state, &$exclude) { + if (!empty($form_state['values']['op']) && $form_state['values']['op'] == $this->options['reset_button_label']) { + $this->reset_form($form, $form_state); + } + if (isset($form_state['pager_plugin'])) { + $form_state['pager_plugin']->exposed_form_submit($form, $form_state, $exclude); + $exclude[] = 'pager_plugin'; + } + } + + function reset_form(&$form, &$form_state) { + unset($_SESSION['views'][$this->view->name][$this->view->current_display]); + $form_state = array(); + $form_state['values'] = array(); + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_exposed_form_basic.inc b/sites/all/modules/views/plugins/views_plugin_exposed_form_basic.inc new file mode 100644 index 0000000000000000000000000000000000000000..6e617f67d6846d6faa5dfb7cf9bc7ce604d91efa --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_exposed_form_basic.inc @@ -0,0 +1,13 @@ +<?php +// $Id: views_plugin_exposed_form_basic.inc,v 1.2.2.2 2009/12/26 20:36:39 dereine Exp $ + +/** + * Exposed form plugin that provides basic exposed form + */ +class views_plugin_exposed_form_basic extends views_plugin_exposed_form { + + function summary_title() { + return t('Basic'); + } + +} diff --git a/sites/all/modules/views/plugins/views_plugin_exposed_form_input_required.inc b/sites/all/modules/views/plugins/views_plugin_exposed_form_input_required.inc new file mode 100644 index 0000000000000000000000000000000000000000..89b5611e4841a9bc820239b6394b1e5b9636dd90 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_exposed_form_input_required.inc @@ -0,0 +1,93 @@ +<?php +// $Id: views_plugin_exposed_form_input_required.inc,v 1.2.2.8 2010/11/16 01:09:28 merlinofchaos Exp $ + +/** + * Exposed form plugin that provides basic exposed form + */ +class views_plugin_exposed_form_input_required extends views_plugin_exposed_form { + + function summary_title() { + return t('Input required'); + } + + function option_definition() { + $options = parent::option_definition(); + + $options['text_input_required'] = array('default' => t('Select any filter and click on Apply to see results'), 'translatable' => TRUE); + $options['text_input_required_format'] = array('default' => filter_default_format()); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $form['text_input_required'] = array( + '#type' => 'text_format', + '#title' => t('Text on demand'), + '#description' => t('Text to display instead of results until the user selects and applies an exposed filter.'), + '#default_value' => $this->options['text_input_required'], + '#format' => $this->options['text_input_required_format'], + ); + } + + function options_submit(&$form, &$form_state) { + $form_state['values']['exposed_form_options']['text_input_required_format'] = $form_state['values']['options']['text_input_required']['format']; + parent::options_submit($form, $form_state); + } + + function exposed_filter_applied() { + static $cache = NULL; + if (!isset($cache)) { + $view = $this->view; + $exposed_data = $view->exposed_data; + if (is_array($view->filter) && count($view->filter)) { + foreach ($view->filter as $filter_id => $filter) { + if ($filter->is_exposed()) { + $identifier = $filter->options['expose']['identifier']; + if (isset($view->exposed_input[$identifier])) { + $cache = TRUE; + return $cache; + } + } + } + } + $cache = FALSE; + } + + return $cache; + } + + function pre_render($values) { + if (!$this->exposed_filter_applied()) { + $options = array( + 'id' => 'area', + 'table' => 'views', + 'field' => 'area', + 'label' => '', + 'relationship' => 'none', + 'group_type' => 'group', + 'content' => $this->options['text_input_required'], + 'format' => $this->options['text_input_required_format'], + ); + $handler = views_get_handler('views', 'area', 'area'); + $handler->init($this->view, $options); + $this->display->handler->handlers['empty'] = array( + 'area' => $handler, + ); + $this->display->handler->set_option('empty', array('text' => $options)); + } + } + + function query() { + if (!$this->exposed_filter_applied()) { + // We return with no query; this will force the empty text. + $this->view->built = TRUE; + $this->view->executed = TRUE; + $this->view->result = array(); + } + else { + parent::query(); + } + } + +} diff --git a/sites/all/modules/views/plugins/views_plugin_localization.inc b/sites/all/modules/views/plugins/views_plugin_localization.inc new file mode 100644 index 0000000000000000000000000000000000000000..0dd1416c40fe4180fe82923830869fe5414239d4 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_localization.inc @@ -0,0 +1,156 @@ +<?php +// $Id: views_plugin_localization.inc,v 1.1.4.2 2010/12/01 20:05:06 dereine Exp $ + +/** + * @file + * Contains the base class for views localization plugins. + */ + +/** + * The base plugin to handle localization of Views strings. + * + * @ingroup views_localization_plugins + */ +class views_plugin_localization extends views_plugin { + // Store for exported strings + var $export_strings = array(); + var $translate = TRUE; + + /** + * Initialize the plugin. + * + * @param $view + * The view object. + */ + function init(&$view) { + $this->view = &$view; + } + + /** + * Translate a string / text with format + * + * The $source parameter is an array with the following elements: + * - value, source string + * - format, input format in case the text has some format to be applied + * - keys. An array of keys to identify the string. Generally constructed from + * view name, display_id, and a property, e.g., 'header'. + * + * @param $source + * Full data for the string to be translated. + * + * @return string + * Translated string / text + */ + function translate($source) { + // Allow other modules to make changes to the string before and after translation + $source['pre_process'] = $this->invoke_translation_process($source, 'pre'); + $source['translation'] = $this->translate_string($source['value'], $source['keys']); + $source['post_process'] = $this->invoke_translation_process($source, 'post'); + return $source['translation']; + } + + /** + * Translate a string. + * + * @param $string + * The string to be translated. + * @param $keys + * An array of keys to identify the string. Generally constructed from + * view name, display_id, and a property, e.g., 'header'. + */ + function translate_string($string, $keys = array()) {} + + /** + * Save string source for translation. + * + * @param $source + * Full data for the string to be translated. + */ + function save($source) { + // Allow other modules to make changes to the string before saving + $source['pre_process'] = $this->invoke_translation_process($source, 'pre'); + $this->save_string($source['value'], $source['keys']); + } + + /** + * Save a string for translation + * + * @param $string + * The string to be translated. + * @param $keys + * An array of keys to identify the string. Generally constructed from + * view name, display_id, and a property, e.g., 'header'. + */ + function save_string($string, $keys = array()) {} + + /** + * Delete a string. + * + * @param $source + * Full data for the string to be translated. + */ + function delete($source) { } + + /** + * Collect strings to be exported to code. + * + * @param $source + * Full data for the string to be translated. + */ + function export($source) { } + + /** + * Render any collected exported strings to code. + * + * @param $indent + * An optional indentation for prettifying nested code. + */ + function export_render($indent = ' ') { } + + /** + * Invoke hook_translation_pre_process() or hook_translation_post_process(). + * + * Like node_invoke_nodeapi(), this function is needed to enable both passing + * by reference and fetching return values. + */ + function invoke_translation_process(&$value, $op) { + $return = array(); + $hook = 'translation_' . $op . '_process'; + foreach (module_implements($hook) as $module) { + $function = $module . '_' . $hook; + $result = $function($value); + if (isset($result)) { + $return[$module] = $result; + } + } + return $return; + } + + function process_locale_strings($op) { + $this->view->init_display(); + + foreach ($this->view->display as $display_id => $display) { + $translatable = array(); + // Special handling for display title. + if (isset($display->display_title)) { + $translatable[] = array('value' => $display->display_title, 'keys' => array('display_title')); + } + // Unpack handlers. + $this->view->display[$display_id]->handler->unpack_translatables($translatable); + foreach ($translatable as $data) { + $data['keys'] = array_merge(array($this->view->name, $display_id), $data['keys']); + switch ($op) { + case 'save': + $this->save($data); + break; + case 'delete': + $this->delete($data); + break; + case 'export': + $this->export($data); + break; + } + } + } + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_localization_core.inc b/sites/all/modules/views/plugins/views_plugin_localization_core.inc new file mode 100644 index 0000000000000000000000000000000000000000..769e7d73199250f223fa910a55af3b6f8f9afec0 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_localization_core.inc @@ -0,0 +1,104 @@ +<?php +// $Id: views_plugin_localization_core.inc,v 1.1.4.2 2010/12/01 20:05:06 dereine Exp $ + +/** + * @file + * Contains the Drupal core localization plugin. + */ + +/** + * Localization plugin to pass translatable strings through t(). + * + * @ingroup views_localization_plugins + */ +class views_plugin_localization_core extends views_plugin_localization { + + /** + * Translate a string. + * + * @param $string + * The string to be translated. + * @param $keys + * An array of keys to identify the string. Generally constructed from + * view name, display_id, and a property, e.g., 'header'. + */ + function translate_string($string, $keys = array()) { + return t($string); + } + + /** + * Save a string for translation. + * + * @param $string + * The string to be translated. + * @param $keys + * An array of keys to identify the string. Generally constructed from + * view name, display_id, and a property, e.g., 'header'. + */ + function save_string($string, $keys = array()) { + global $language; + + // If the current language is 'en', we need to reset the language + // in order to trigger an update. + // TODO: add test for number of languages. + if ($language->language == 'en') { + $changed = TRUE; + $languages = language_list(); + $cached_language = $language; + unset($languages['en']); + $language = current($languages); + } + + t($string); + + if (isset($cached_language)) { + $language = $cached_language; + } + return TRUE; + } + + /** + * Delete a string. + * + * Deletion is not supported. + * + * @param $source + * Full data for the string to be translated. + */ + function delete($source) { + return FALSE; + } + + /** + * Collect strings to be exported to code. + * + * String identifiers are not supported so strings are anonymously in an array. + * + * @param $source + * Full data for the string to be translated. + */ + function export($source) { + if (!empty($source['value'])) { + $this->export_strings[] = $source['value']; + } + } + + /** + * Render any collected exported strings to code. + * + * @param $indent + * An optional indentation for prettifying nested code. + */ + function export_render($indent = ' ') { + $output = ''; + if (!empty($this->export_strings)) { + $this->export_strings = array_unique($this->export_strings); + $output = $indent . '$translatables[\'' . $this->view->name . '\'] = array(' . "\n"; + foreach ($this->export_strings as $string) { + $output .= $indent . " t('" . str_replace("'", "\'", $string) . "'),\n"; + } + $output .= $indent . ");\n"; + } + return $output; + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_localization_none.inc b/sites/all/modules/views/plugins/views_plugin_localization_none.inc new file mode 100644 index 0000000000000000000000000000000000000000..1e090926ce03030a777573833fe83abaf5a9d951 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_localization_none.inc @@ -0,0 +1,37 @@ +<?php +// $Id: views_plugin_localization_none.inc,v 1.1.4.2 2010/12/01 20:05:06 dereine Exp $ + +/** + * @file + * Contains the 'none' localization plugin. + */ + +/** + * Localization plugin for no localization. + * + * @ingroup views_localization_plugins + */ +class views_plugin_localization_none extends views_plugin_localization { + var $translate = FALSE; + + /** + * Translate a string; simply return the string. + */ + function translate($source) { + return $source['value']; + } + + /** + * Save a string for translation; not supported. + */ + function save($source) { + return FALSE; + } + + /** + * Delete a string; not supported. + */ + function delete($source) { + return FALSE; + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_pager.inc b/sites/all/modules/views/plugins/views_plugin_pager.inc new file mode 100644 index 0000000000000000000000000000000000000000..f4ba7d7a2b3992ce30b51a849b486c7fdf6748c8 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_pager.inc @@ -0,0 +1,214 @@ +<?php +// $Id: views_plugin_pager.inc,v 1.1.4.7 2010/04/29 18:39:26 merlinofchaos Exp $ + +/** + * The base plugin to handle pager. + * + * @ingroup views_pager_plugins + */ +class views_plugin_pager extends views_plugin { + var $current_page = NULL; + var $total_items = 0; + + /** + * Initialize the plugin. + * + * @param $view + * The view object. + * @param $display + * The display handler. + */ + function init(&$view, &$display, $options = array()) { + $this->view = &$view; + $this->display = &$display; + + $this->unpack_options($this->options, $options); + } + + /** + * Get how many items per page this pager will display. + * + * All but the leanest pagers should probably return a value here, so + * most pagers will not need to override this method. + */ + function get_items_per_page() { + return isset($this->options['items_per_page']) ? $this->options['items_per_page'] : 0; + } + + /** + * Set how many items per page this pager will display. + * + * This is mostly used for things that will override the value. + */ + function set_items_per_page($items) { + $this->options['items_per_page'] = $items; + } + + /** + * Get the page offset, or how many items to skip. + * + * Even pagers that don't actually page can skip items at the beginning, + * so few pagers will need to override this method. + */ + function get_offset() { + return isset($this->options['offset']) ? $this->options['offset'] : 0; + } + + /** + * Set the page offset, or how many items to skip. + */ + function set_offset($offset) { + $this->options['offset'] = $offset; + } + + /** + * Get the current page. + * + * If NULL, we do not know what the current page is. + */ + function get_current_page() { + return $this->current_page; + } + + /** + * Set the current page. + * + * @param $number + * If provided, the page number will be set to this. If NOT provided, + * the page number will be set from the global page array. + */ + function set_current_page($number = NULL) { + $this->current_page = $number; + } + + /** + * Get the total number of items. + * + * If NULL, we do not yet know what the total number of items are. + */ + function get_total_items() { + return $this->total_items; + } + + /** + * Get the pager id, if it exists + */ + function get_pager_id() { + return isset($this->options['id']) ? $this->options['id'] : 0; + } + + /** + * Provide the default form form for validating options + */ + function options_validate(&$form, &$form_state) { } + + /** + * Provide the default form form for submitting options + */ + function options_submit(&$form, &$form_state) { } + + /** + * Return a string to display as the clickable title for the + * pager plugin. + */ + function summary_title() { + return t('Unknown'); + } + + /** + * Determine if this pager actually uses a pager. + * + * Only a couple of very specific pagers will set this to false. + */ + function use_pager() { + return TRUE; + } + + /** + * Determine if a pager needs a count query. + * + * If a pager needs a count query, a simple query + */ + function use_count_query() { + return TRUE; + } + + /** + * Execute the count query, which will be done just prior to the query + * itself being executed. + */ + function execute_count_query(&$count_query) { + $this->total_items = $count_query->execute()->fetchField(); + if (!empty($this->options['offset'])) { + $this->total_items -= $this->options['offset']; + } + + $this->update_page_info(); + return $this->total_items; + } + + /** + * If there are pagers that need global values set, this method can + * be used to set them. It will be called when the count query is run. + */ + function update_page_info() { + + } + + /** + * Modify the query for paging + * + * This is called during the build phase and can directly modify the query. + */ + function query() { } + + /** + * Perform any needed actions just prior to the query executing. + */ + function pre_execute(&$query) { } + + /** + * Perform any needed actions just after the query executing. + */ + function post_execute(&$result) { } + + /** + * Render the pager. + * + * Called during the view render process, this will render the + * pager. + * + * @param $input + * Any extra GET parameters that should be retained, such as exposed + * input. + */ + function render($input) { } + + /** + * Determine if there are more records available. + * + * This is primarily used to control the display of a more link. + */ + function has_more_records() { + return $this->get_items_per_page() + && $this->total_items > (intval($this->current_page) + 1) * $this->get_items_per_page(); + } + + function exposed_form_alter(&$form, &$form_state) { } + + function exposed_form_validate(&$form, &$form_state) { } + + function exposed_form_submit(&$form, &$form_state, &$exclude) { } + + function uses_exposed() { + return FALSE; + } + + function items_per_page_exposed() { + return FALSE; + } + + function offset_exposed() { + return FALSE; + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_pager_full.inc b/sites/all/modules/views/plugins/views_plugin_pager_full.inc new file mode 100644 index 0000000000000000000000000000000000000000..4dcbee450d348f1990eb2667f720604f96c056bc --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_pager_full.inc @@ -0,0 +1,331 @@ +<?php +// $Id: views_plugin_pager_full.inc,v 1.1.4.14 2010/12/16 20:32:17 dereine Exp $ + +/** + * The plugin to handle full pager. + * + * @ingroup views_pager_plugins + */ +class views_plugin_pager_full extends views_plugin_pager { + function summary_title() { + if (!empty($this->options['offset'])) { + return format_plural($this->options['items_per_page'], 'Paged, @count item, skip @skip', 'Paged, @count items, skip @skip', array('@count' => $this->options['items_per_page'], '@skip' => $this->options['offset'])); + } + return format_plural($this->options['items_per_page'], 'Paged, @count item', 'Paged, @count items', array('@count' => $this->options['items_per_page'])); + } + + function option_definition() { + $options = parent::option_definition(); + $options['items_per_page'] = array('default' => 10); + $options['offset'] = array('default' => 0); + $options['id'] = array('default' => 0); + $options['total_pages'] = array('default' => ''); + $options['expose'] = array( + 'contains' => array( + 'items_per_page' => array('default' => FALSE, 'bool' => TRUE), + 'items_per_page_label' => array('default' => 'Items per page', 'translatable' => TRUE), + 'items_per_page_options' => array('default' => '5, 10, 20, 40, 60'), + 'items_per_page_options_all' => array('default' => FALSE), + 'items_per_page_options_all_label' => array('default' => '- All -', 'translatable' => TRUE), + + 'offset' => array('default' => FALSE, 'bool' => TRUE), + 'offset_label' => array('default' => 'Offset', 'translatable' => TRUE), + ), + ); + return $options; + } + + /** + * Provide the default form for setting options. + */ + function options_form(&$form, &$form_state) { + $form['items_per_page'] = array( + '#title' => t('Items per page'), + '#type' => 'textfield', + '#description' => t('The number of items to display per page. Enter 0 for no limit.'), + '#default_value' => $this->options['items_per_page'], + ); + + $form['offset'] = array( + '#type' => 'textfield', + '#title' => t('Offset'), + '#description' => t('The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed.'), + '#default_value' => $this->options['offset'], + ); + + $form['id'] = array( + '#type' => 'textfield', + '#title' => t('Pager ID'), + '#description' => t("Unless you're experiencing problems with pagers related to this view, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible."), + '#default_value' => $this->options['id'], + ); + + $form['total_pages'] = array( + '#type' => 'textfield', + '#title' => t('Number of pages'), + '#description' => t('The total number of pages. Leave empty to show all pages.'), + '#default_value' => $this->options['total_pages'], + ); + + $form['expose'] = array ( + '#type' => 'fieldset', + '#collapsible' => FALSE, + '#collapsed' => FALSE, + '#tree' => TRUE, + '#title' => t('Exposed options'), + '#input' => TRUE, + '#description' => t('Exposing this options allows users to define their values in a exposed form when view is displayed'), + ); + + $form['expose']['items_per_page'] = array( + '#type' => 'checkbox', + '#title' => t('Expose items per page'), + '#description' => t('When checked, users can determine how many items per page show in a view'), + '#default_value' => $this->options['expose']['items_per_page'], + ); + + $form['expose']['items_per_page_label'] = array( + '#type' => 'textfield', + '#title' => t('Items per page label'), + '#required' => TRUE, + '#description' => t('Label to use in the exposed items per page form element.'), + '#default_value' => $this->options['expose']['items_per_page_label'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-pager-options-expose-items-per-page' => array(1) + ), + ); + + $form['expose']['items_per_page_options'] = array( + '#type' => 'textfield', + '#title' => t('Exposed items per page options'), + '#required' => TRUE, + '#description' => t('Set between which values the user can choose when determining the items per page. Separated by comma.'), + '#default_value' => $this->options['expose']['items_per_page_options'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-pager-options-expose-items-per-page' => array(1) + ), + ); + + + $form['expose']['items_per_page_options_all'] = array( + '#type' => 'checkbox', + '#title' => t('Include all items option'), + '#description' => t('If checked, an extra item will be included to items per page to display all items'), + '#default_value' => $this->options['expose']['items_per_page_options_all'], + ); + + $form['expose']['items_per_page_options_all_label'] = array( + '#type' => 'textfield', + '#title' => t('All items label'), + '#description' => t('Which label will be used to display all items'), + '#default_value' => $this->options['expose']['items_per_page_options_all_label'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-items-per-page-options-all' => array(1), + ), + ); + + $form['expose']['offset'] = array( + '#type' => 'checkbox', + '#title' => t('Expose Offset'), + '#description' => t('When checked, users can determine how many items should be skipped at the beginning.'), + '#default_value' => $this->options['expose']['offset'], + ); + + $form['expose']['offset_label'] = array( + '#type' => 'textfield', + '#title' => t('Offset label'), + '#required' => TRUE, + '#description' => t('Label to use in the exposed offset form element.'), + '#default_value' => $this->options['expose']['offset_label'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array( + 'edit-pager-options-expose-offset' => array(1) + ), + ); + } + + function options_validate(&$form, &$form_state) { + // Only accept integer values. + $error = FALSE; + $exposed_options = $form_state['values']['pager_options']['expose']['items_per_page_options']; + if (strpos($exposed_options, '.') !== FALSE) { + $error = TRUE; + } + $options = explode(',',$exposed_options); + if (!$error && is_array($options)) { + foreach ($options as $option) { + if (!is_numeric($option) || intval($option) == 0) { + $error = TRUE; + } + } + } + else { + $error = TRUE; + } + if ($error) { + form_set_error('pager_options][expose][items_per_page_options', t('Please insert a list of integer numeric values separated by commas: e.g: 10, 20, 50, 100')); + } + } + + function query() { + if ($this->items_per_page_exposed()) { + if (!empty($_GET['items_per_page']) && $_GET['items_per_page'] > 0) { + $this->options['items_per_page'] = $_GET['items_per_page']; + } + elseif (!empty($_GET['items_per_page']) && $_GET['items_per_page'] == 'All' && $this->options['expose']['items_per_page_options_all']) { + $this->options['items_per_page'] = 0; + } + } + if ($this->offset_exposed()) { + if (isset($_GET['offset']) && $_GET['offset'] >= 0) { + $this->options['offset'] = $_GET['offset']; + } + } + + $limit = $this->options['items_per_page']; + $offset = $this->current_page * $this->options['items_per_page'] + $this->options['offset']; + if (!empty($this->options['total_pages'])) { + if ($this->current_page >= $this->options['total_pages']) { + $limit = $this->options['items_per_page']; + $offset = $this->options['total_pages'] * $this->options['items_per_page']; + } + } + + $this->view->query->set_limit($limit); + $this->view->query->set_offset($offset); + } + + function render($input) { + $pager_theme = views_theme_functions('pager', $this->view, $this->display); + $output = theme($pager_theme, array( + 'tags' => $input, 'element' => $this->options['id'])); + return $output; + } + + /** + * Set the current page. + * + * @param $number + * If provided, the page number will be set to this. If NOT provided, + * the page number will be set from the global page array. + */ + function set_current_page($number = NULL) { + if (isset($number)) { + $this->current_page = $number; + return; + } + + // If the current page number was not prespecified, default to pulling it from 'page' + // based upon + global $pager_page_array; + // Extract the ['page'] info. + $pager_page_array = isset($_GET['page']) ? explode(',', $_GET['page']) : array(0); + + $this->current_page = 0; + if (!empty($pager_page_array[$this->options['id']])) { + $this->current_page = intval($pager_page_array[$this->options['id']]); + } + } + + function get_pager_total() { + if ($items_per_page = intval($this->get_items_per_page())) { + return ceil($this->total_items / $items_per_page); + } + else { + return 1; + } + } + + /** + * Update global paging info. + * + * This is called after the count query has been run to set the total + * items available and to update the current page if the requested + * page is out of range. + */ + function update_page_info() { + if (!empty($this->options['total_pages'])) { + if (($this->options['total_pages'] * $this->options['items_per_page']) < $this->total_items) { + $this->total_items = $this->options['total_pages'] * $this->options['items_per_page']; + } + } + + // Don't set pager settings for items per page = 0. + $items_per_page = $this->get_items_per_page(); + if (!empty($items_per_page)) { + // Dump information about what we already know into the globals. + global $pager_page_array, $pager_total, $pager_total_items; + // Set the item count for the pager. + $pager_total_items[$this->options['id']] = $this->total_items; + // Calculate and set the count of available pages. + $pager_total[$this->options['id']] = $this->get_pager_total(); + + // See if the requested page was within range: + if ($this->current_page < 0) { + $this->current_page = 0; + } + else if ($this->current_page >= $pager_total[$this->options['id']]) { + // Pages are numbered from 0 so if there are 10 pages, the last page is 9. + $this->current_page = $pager_total[$this->options['id']] - 1; + } + + // Put this number in to guarantee that we do not generate notices when the pager + // goes to look for it later. + $pager_page_array[$this->options['id']] = $this->current_page; + } + } + + function uses_exposed() { + return $this->items_per_page_exposed() || $this->offset_exposed(); + } + + function items_per_page_exposed() { + return !empty($this->options['expose']['items_per_page']); + } + + function offset_exposed() { + return !empty($this->options['expose']['offset']); + } + + function exposed_form_alter(&$form, &$form_state) { + if ($this->items_per_page_exposed()) { + $options = explode(',', $this->options['expose']['items_per_page_options']); + $sanitized_options = array(); + if (is_array($options)) { + foreach ($options as $option) { + $sanitized_options[intval($option)] = intval($option); + } + if (!empty($this->options['expose']['items_per_page_options_all']) && !empty($this->options['expose']['items_per_page_options_all_label'])) { + $sanitized_options['All'] = $this->options['expose']['items_per_page_options_all_label']; + } + $form['items_per_page'] = array( + '#type' => 'select', + '#title' => $this->options['expose']['items_per_page_label'], + '#options' => $sanitized_options, + '#default_value' => $this->get_items_per_page(), + ); + } + } + + if ($this->offset_exposed()) { + $form['offset'] = array( + '#type' => 'textfield', + '#size' => 10, + '#maxlength' => 10, + '#title' => $this->options['expose']['offset_label'], + '#default_value' => $this->get_offset(), + ); + } + } + + function exposed_form_validate(&$form, &$form_state) { + if (!empty($form_state['values']['offset']) && trim($form_state['values']['offset'])) { + if (!is_numeric($form_state['values']['offset']) || $form_state['values']['offset'] < 0) { + form_set_error('offset', t('Offset must be an number greather or equal than 0.')); + } + } + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_pager_mini.inc b/sites/all/modules/views/plugins/views_plugin_pager_mini.inc new file mode 100644 index 0000000000000000000000000000000000000000..1ada3bc84700d9f625b6fd4f277a0fd4843ed0b2 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_pager_mini.inc @@ -0,0 +1,22 @@ +<?php +// $Id: views_plugin_pager_mini.inc,v 1.1.4.5 2011/01/04 00:00:20 dereine Exp $ + +/** + * The plugin to handle full pager. + * + * @ingroup views_pager_plugins + */ +class views_plugin_pager_mini extends views_plugin_pager_full { + function summary_title() { + if (!empty($this->options['offset'])) { + return format_plural($this->options['items_per_page'], 'Mini pager, @count item, skip @skip', 'Mini pager, @count items, skip @skip', array('@count' => $this->options['items_per_page'], '@skip' => $this->options['offset'])); + } + return format_plural($this->options['items_per_page'], 'Mini pager, @count item', 'Mini pager, @count items', array('@count' => $this->options['items_per_page'])); + } + + function render($input) { + $pager_theme = views_theme_functions('views_mini_pager', $this->view, $this->display); + return theme($pager_theme, array( + 'tags' => $input, 'element' => $this->options['id'])); + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_pager_none.inc b/sites/all/modules/views/plugins/views_plugin_pager_none.inc new file mode 100644 index 0000000000000000000000000000000000000000..dd3275bb942d3dcc624ec6b513bf8e7423294239 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_pager_none.inc @@ -0,0 +1,62 @@ +<?php +// $Id: views_plugin_pager_none.inc,v 1.1.4.3 2010/11/06 17:56:10 dereine Exp $ + +/** + * Plugin for views without pagers. + * + * @ingroup views_pager_plugins + */ +class views_plugin_pager_none extends views_plugin_pager { + function summary_title() { + if (!empty($this->options['offset'])) { + return t('All items, skip @skip', array('@skip' => $this->options['offset'])); + } + return t('All items'); + } + + function option_definition() { + $options = parent::option_definition(); + $options['offset'] = array('default' => 0); + + return $options; + } + + /** + * Provide the default form for setting options. + */ + function options_form(&$form, &$form_state) { + $form['offset'] = array( + '#type' => 'textfield', + '#title' => t('Offset'), + '#description' => t('The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed.'), + '#default_value' => $this->options['offset'], + ); + } + + function use_pager() { + return FALSE; + } + + function use_count_query() { + return FALSE; + } + + function get_items_per_page() { + return 0; + } + + function execute_count_query(&$count_query) { + // If we are displaying all items, never count. But we can update the count in post_execute. + } + + function post_execute(&$result) { + $this->total_items = count($result); + } + + function query() { + // The only query modifications we might do are offsets. + if (!empty($this->options['offset'])) { + $this->view->query->set_offset($this->options['offset']); + } + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_pager_some.inc b/sites/all/modules/views/plugins/views_plugin_pager_some.inc new file mode 100644 index 0000000000000000000000000000000000000000..a2001d25ff37176df05ae1362f99fe07578dd8f2 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_pager_some.inc @@ -0,0 +1,56 @@ +<?php +// $Id: views_plugin_pager_some.inc,v 1.1.4.3 2010/11/18 23:15:37 merlinofchaos Exp $ + +/** + * Plugin for views without pagers. + * + * @ingroup views_pager_plugins + */ +class views_plugin_pager_some extends views_plugin_pager { + function summary_title() { + if (!empty($this->options['offset'])) { + return format_plural($this->options['items_per_page'], '@count item, skip @skip', '@count items, skip @skip', array('@count' => $this->options['items_per_page'], '@skip' => $this->options['offset'])); + } + return format_plural($this->options['items_per_page'], '@count item', '@count items', array('@count' => $this->options['items_per_page'])); + } + + function option_definition() { + $options = parent::option_definition(); + $options['items_per_page'] = array('default' => 10); + $options['offset'] = array('default' => 0); + + return $options; + } + + /** + * Provide the default form for setting options. + */ + function options_form(&$form, &$form_state) { + $form['items_per_page'] = array( + '#title' => t('Items to display'), + '#type' => 'textfield', + '#description' => t('The number of items to display per page.'), + '#default_value' => $this->options['items_per_page'], + ); + + $form['offset'] = array( + '#type' => 'textfield', + '#title' => t('Offset'), + '#description' => t('The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed.'), + '#default_value' => $this->options['offset'], + ); + } + + function use_pager() { + return FALSE; + } + + function use_count_query() { + return FALSE; + } + + function query() { + $this->view->query->set_limit($this->options['items_per_page']); + $this->view->query->set_offset($this->options['offset']); + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_query.inc b/sites/all/modules/views/plugins/views_plugin_query.inc new file mode 100644 index 0000000000000000000000000000000000000000..0c5e3d05e2e5878b9cc38121d9e884b03758bfb2 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_query.inc @@ -0,0 +1,148 @@ +<?php +// $Id: views_plugin_query.inc,v 1.1.4.13 2011/01/04 01:11:34 merlinofchaos Exp $ +/** + * @file views_plugin_query.inc + * Defines the base query class, which is the underlying layer in a View. + */ + +/** + * Object used to create a SELECT query. + */ +class views_plugin_query extends views_plugin { + /** + * A pager plugin that should be provided by the display. + */ + var $pager = NULL; + + /** + * Constructor; Create the basic query object and fill with default values. + */ + function init($base_table, $base_field, $options) { + $this->base_table = $base_table; + $this->base_field = $base_field; + $this->unpack_options($this->options, $options); + } + + /** + * Generate a query and a countquery from all of the information supplied + * to the object. + * + * @param $get_count + * Provide a countquery if this is true, otherwise provide a normal query. + */ + function query($get_count = FALSE) { } + + /** + * Let modules modify the query just prior to finalizing it. + */ + function alter(&$view) { } + + /** + * Builds the necessary info to execute the query. + */ + function build(&$view) { } + + /** + * Executes the query and fills the associated view object with according + * values. + * + * Values to set: $view->result, $view->total_rows, $view->execute_time, + * $view->pager['current_page']. + */ + function execute(&$view) { } + + /** + * Add a signature to the query, if such a thing is feasible. + * + * This signature is something that can be used when perusing query logs to + * discern where particular queries might be coming from. + */ + function add_signature(&$view) { } + + /** + * Get aggregation info for group by queries. + * + * If NULL, aggregation is not allowed. + */ + function get_aggregation_info() { } + + /** + * Add settings for the ui. + */ + function options_form(&$form, &$form_state) { } + + function options_validate(&$form, &$form_state) { } + + function options_submit(&$form, &$form_state) { } + + function summary_title() { + return t('Settings'); + } + + /** + * Set a LIMIT on the query, specifying a maximum number of results. + */ + function set_limit($limit) { + $this->limit = $limit; + } + + /** + * Set an OFFSET on the query, specifying a number of results to skip + */ + function set_offset($offset) { + $this->offset = $offset; + } + + /** + * Render the pager, if necessary. + */ + function render_pager() { + if (!empty($this->pager) && $this->pager->use_pager()) { + $exposed_input = isset($this->view->exposed_data_raw) ? $this->view->exposed_data_raw : NULL; + return $this->pager->render($exposed_input); + } + return ''; + } + + /** + * Create a new grouping for the WHERE or HAVING clause. + * + * @param $type + * Either 'AND' or 'OR'. All items within this group will be added + * to the WHERE clause with this logical operator. + * @param $group + * An ID to use for this group. If unspecified, an ID will be generated. + * @param $where + * 'where' or 'having'. + * + * @return $group + * The group ID generated. + */ + function set_where_group($type = 'AND', $group = NULL, $where = 'where') { + // Set an alias. + $groups = &$this->$where; + + if (!isset($group)) { + $group = empty($groups) ? 1 : max(array_keys($groups)) + 1; + } + + // Create an empty group + if (empty($groups[$group])) { + $groups[$group] = array('conditions' => array(), 'args' => array()); + } + + $groups[$group]['type'] = strtoupper($type); + return $group; + } + + /** + * Control how all WHERE and HAVING groups are put together. + * + * @param $type + * Either 'AND' or 'OR' + */ + function set_group_operator($type = 'AND') { + $this->group_operator = strtoupper($type); + } + +} diff --git a/sites/all/modules/views/plugins/views_plugin_query_default.inc b/sites/all/modules/views/plugins/views_plugin_query_default.inc new file mode 100644 index 0000000000000000000000000000000000000000..bd0497eb7cd98a08b7a08b2d0dae73dc5d01358d --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_query_default.inc @@ -0,0 +1,1389 @@ +<?php +// $Id: views_plugin_query_default.inc,v 1.1.4.39 2011/01/06 00:37:05 dereine Exp $ +/** + * @file views_plugin_query_default.inc + * Defines the default query object which builds SQL to execute using the + * Drupal database API. + */ + +/** + * Object used to create a SELECT query. + */ +class views_plugin_query_default extends views_plugin_query { + + /** + * A list of tables in the order they should be added, keyed by alias. + */ + var $table_queue = array(); + + /** + * Holds an array of tables and counts added so that we can create aliases + */ + var $tables = array(); + + /** + * Holds an array of relationships, which are aliases of the primary + * table that represent different ways to join the same table in. + */ + var $relationships = array(); + + /** + * An array of sections of the WHERE query. Each section is in itself + * an array of pieces and a flag as to whether or not it should be AND + * or OR. + */ + var $where = array(); + /** + * An array of sections of the HAVING query. Each section is in itself + * an array of pieces and a flag as to whether or not it should be AND + * or OR. + */ + var $having = array(); + /** + * The default operator to use when connecting the WHERE groups. May be + * AND or OR. + */ + var $group_operator = 'AND'; + + /** + * A simple array of order by clauses. + */ + var $orderby = array(); + + /** + * A simple array of group by clauses. + */ + var $groupby = array(); + + /** + * The table header to use for tablesort. This matters because tablesort + * needs to modify the query and needs the header. + */ + var $header = array(); + + /** + * A flag as to whether or not to make the primary field distinct. + */ + var $distinct = FALSE; + + var $has_aggregate = FALSE; + + /** + * Should this query be optimized for counts, for example no sorts. + */ + var $get_count_optimized = NULL; + + /** + * Constructor; Create the basic query object and fill with default values. + */ + function init($base_table = 'node', $base_field = 'nid', $options) { + parent::init($base_table, $base_field, $options); + $this->base_table = $base_table; // Predefine these above, for clarity. + $this->base_field = $base_field; + $this->relationships[$base_table] = array( + 'link' => NULL, + 'table' => $base_table, + 'alias' => $base_table, + 'base' => $base_table + ); + + // init the table queue with our primary table. + $this->table_queue[$base_table] = array( + 'alias' => $base_table, + 'table' => $base_table, + 'relationship' => $base_table, + 'join' => NULL, + ); + + // init the tables with our primary table + $this->tables[$base_table][$base_table] = array( + 'count' => 1, + 'alias' => $base_table, + ); + +/** + * -- we no longer want the base field to appear automatigically. + if ($base_field) { + $this->fields[$base_field] = array( + 'table' => $base_table, + 'field' => $base_field, + 'alias' => $base_field, + ); + } + */ + + $this->count_field = array( + 'table' => $base_table, + 'field' => $base_field, + 'alias' => $base_field, + 'count' => TRUE, + ); + } + + // ---------------------------------------------------------------- + // Utility methods to set flags and data. + + /** + * Set the base field to be distinct. + */ + function set_distinct($value = TRUE) { + if (!(isset($this->no_distinct) && $value)) { + $this->distinct = $value; + } + } + + /** + * Set what field the query will count() on for paging. + */ + function set_count_field($table, $field, $alias = NULL) { + if (empty($alias)) { + $alias = $table . '_' . $field; + } + $this->count_field = array( + 'table' => $table, + 'field' => $field, + 'alias' => $alias, + 'count' => TRUE, + ); + } + + /** + * Set the table header; used for click-sorting because it's needed + * info to modify the ORDER BY clause. + */ + function set_header($header) { + $this->header = $header; + } + + function option_definition() { + $options = parent::option_definition(); + $options['disable_sql_rewrite'] = array( + 'default' => FALSE, + 'translatable' => FALSE, + 'bool' => TRUE, + ); + $options['distinct'] = array( + 'default' => FALSE, + 'bool' => TRUE, + ); + $options['slave'] = array( + 'default' => FALSE, + 'bool' => TRUE, + ); + $options['field_language'] = array( + 'default' => '***CURRENT_LANGUAGE***', + ); + + return $options; + } + + /** + * Add settings for the ui. + */ + function options_form(&$form, &$form_state) { + $form['disable_sql_rewrite'] = array( + '#title' => t('Disable SQL rewriting'), + '#description' => t('Disabling SQL rewriting will disable node_access checks as well as other modules that implement hook_db_rewrite_sql().'), + '#type' => 'checkbox', + '#default_value' => !empty($this->options['disable_sql_rewrite']), + '#prefix' => '<div class="messages warning">' . t('WARNING: Disabling SQL rewriting means that node access security is disabled. This may allow users to see data they should not be able to see if your view is misconfigured. Please use this option only if you understand and accept this security risk.') . '</div>', + ); + $form['distinct'] = array( + '#type' => 'checkbox', + '#title' => t('Distinct'), + '#description' => t('This will make the view display only distinct items. If there are multiple identical items, each will be displayed only once. You can use this to try and remove duplicates from a view, though it does not always work. Note that this can slow queries down, so use it with caution.'), + '#default_value' => !empty($this->options['distinct']), + ); + $form['slave'] = array( + '#type' => 'checkbox', + '#title' => t('Use Slave Server'), + '#description' => t('This will make the query attempt to connect to a slave server if available. If no slave server is defined or available, it will fall back to the default server.'), + '#default_value' => !empty($this->options['slave']), + ); + + $entities = entity_get_info(); + $entity_tables = array(); + $has_translation_handlers = FALSE; + foreach ($entities as $type => $entity_info) { + $entity_tables[] = $entity_info['base table']; + + if (!empty($entity_info['translation'])) { + $has_translation_handlers = TRUE; + } + } + + // Doesn't make sense to show a field setting here if we aren't querying + // an entity base table. Also, we make sure that there's at least one + // entity type with a translation handler attached. + if (in_array($this->base_table, $entity_tables) && $has_translation_handlers) { + $languages = array( + '***CURRENT_LANGUAGE***' => t("Current user's language"), + '***DEFAULT_LANGUAGE***' => t("Default site language"), + LANGUAGE_NONE => t('No language') + ); + $languages = array_merge($languages, locale_language_list()); + + $form['field_language'] = array( + '#type' => 'select', + '#title' => t('Field Language'), + '#description' => t('All fields which support translations will be displayed in the selected language.'), + '#options' => $languages, + '#default_value' => $this->options['field_language'], + ); + } + } + + // ---------------------------------------------------------------- + // Table/join adding + + /** + * A relationship is an alternative endpoint to a series of table + * joins. Relationships must be aliases of the primary table and + * they must join either to the primary table or to a pre-existing + * relationship. + * + * An example of a relationship would be a nodereference table. + * If you have a nodereference named 'book_parent' which links to a + * parent node, you could set up a relationship 'node_book_parent' + * to 'node'. Then, anything that links to 'node' can link to + * 'node_book_parent' instead, thus allowing all properties of + * both nodes to be available in the query. + * + * @param $alias + * What this relationship will be called, and is also the alias + * for the table. + * @param $join + * A views_join object (or derived object) to join the alias in. + * @param $base + * The name of the 'base' table this relationship represents; this + * tells the join search which path to attempt to use when finding + * the path to this relationship. + * @param $link_point + * If this relationship links to something other than the primary + * table, specify that table here. For example, a 'track' node + * might have a relationship to an 'album' node, which might + * have a relationship to an 'artist' node. + */ + function add_relationship($alias, $join, $base, $link_point = NULL) { + if (empty($link_point)) { + $link_point = $this->base_table; + } + elseif (!array_key_exists($link_point, $this->relationships)) { + return FALSE; + } + + // Make sure $alias isn't already used; if it, start adding stuff. + $alias_base = $alias; + $count = 1; + while (!empty($this->relationships[$alias])) { + $alias = $alias_base . '_' . $count++; + } + + // Make sure this join is adjusted for our relationship. + if ($link_point && isset($this->relationships[$link_point])) { + $join = $this->adjust_join($join, $link_point); + } + + // Add the table directly to the queue to avoid accidentally marking + // it. + $this->table_queue[$alias] = array( + 'table' => $join->table, + 'num' => 1, + 'alias' => $alias, + 'join' => $join, + 'relationship' => $link_point, + ); + + $this->relationships[$alias] = array( + 'link' => $link_point, + 'table' => $join->table, + 'base' => $base, + ); + + $this->tables[$this->base_table][$alias] = array( + 'count' => 1, + 'alias' => $alias, + ); + + return $alias; + } + + /** + * Add a table to the query, ensuring the path exists. + * + * This function will test to ensure that the path back to the primary + * table is valid and exists; if you do not wish for this testing to + * occur, use $query->queue_table() instead. + * + * @param $table + * The name of the table to add. It needs to exist in the global table + * array. + * @param $relationship + * An alias of a table; if this is set, the path back to this table will + * be tested prior to adding the table, making sure that all intermediary + * tables exist and are properly aliased. If set to NULL the path to + * the primary table will be ensured. If the path cannot be made, the + * table will NOT be added. + * @param $join + * In some join configurations this table may actually join back through + * a different method; this is most likely to be used when tracing + * a hierarchy path. (node->parent->parent2->parent3). This parameter + * will specify how this table joins if it is not the default. + * @param $alias + * A specific alias to use, rather than the default alias. + * + * @return $alias + * The alias of the table; this alias can be used to access information + * about the table and should always be used to refer to the table when + * adding parts to the query. Or FALSE if the table was not able to be + * added. + */ + function add_table($table, $relationship = NULL, $join = NULL, $alias = NULL) { + if (!$this->ensure_path($table, $relationship, $join)) { + return FALSE; + } + + return $this->queue_table($table, $relationship, $this->adjust_join($join, $relationship), $alias); + } + + /** + * Add a table to the query, without ensuring the path. + * + * This function will test to ensure that the path back to the primary + * table is valid and exists; if you do not wish for this testing to + * occur, use $query->queue_table() instead. + * + * @param $table + * The name of the table to add. It needs to exist in the global table + * array. + * @param $relationship + * The primary table alias this table is related to. If not set, the + * primary table will be used. + * @param $join + * In some join configurations this table may actually join back through + * a different method; this is most likely to be used when tracing + * a hierarchy path. (node->parent->parent2->parent3). This parameter + * will specify how this table joins if it is not the default. + * @param $alias + * A specific alias to use, rather than the default alias. + * + * @return $alias + * The alias of the table; this alias can be used to access information + * about the table and should always be used to refer to the table when + * adding parts to the query. Or FALSE if the table was not able to be + * added. + */ + function queue_table($table, $relationship = NULL, $join = NULL, $alias = NULL) { + // If the alias is set, make sure it doesn't already exist. + if (isset($this->table_queue[$alias])) { + return $alias; + } + + if (empty($relationship)) { + $relationship = $this->base_table; + } + + if (!array_key_exists($relationship, $this->relationships)) { + return FALSE; + } + + if (!$alias && $join && $relationship && !empty($join->adjusted) && $table != $join->table) { + if ($relationship == $this->base_table) { + $alias = $table; + } + else { + $alias = $relationship . '_' . $table; + } + } + + // Check this again to make sure we don't blow up existing aliases for already + // adjusted joins. + if (isset($this->table_queue[$alias])) { + return $alias; + } + + $alias = $this->mark_table($table, $relationship, $alias); + + // If no alias is specified, give it the default. + if (!isset($alias)) { + $alias = $this->tables[$relationship][$table]['alias'] . $this->tables[$relationship][$table]['count']; + } + + // If this is a relationship based table, add a marker with + // the relationship as a primary table for the alias. + if ($table != $alias) { + $this->mark_table($alias, $this->base_table, $alias); + } + + // If no join is specified, pull it from the table data. + if (!isset($join)) { + $join = $this->get_join_data($table, $this->relationships[$relationship]['base']); + if (empty($join)) { + return FALSE; + } + + $join = $this->adjust_join($join, $relationship); + } + + $this->table_queue[$alias] = array( + 'table' => $table, + 'num' => $this->tables[$relationship][$table]['count'], + 'alias' => $alias, + 'join' => $join, + 'relationship' => $relationship, + ); + + return $alias; + } + + function mark_table($table, $relationship, $alias) { + // Mark that this table has been added. + if (empty($this->tables[$relationship][$table])) { + if (!isset($alias)) { + $alias = ''; + if ($relationship != $this->base_table) { + // double underscore will help prevent accidental name + // space collisions. + $alias = $relationship . '__'; + } + $alias .= $table; + } + $this->tables[$relationship][$table] = array( + 'count' => 1, + 'alias' => $alias, + ); + } + else { + $this->tables[$relationship][$table]['count']++; + } + + return $alias; + } + + /** + * Ensure a table exists in the queue; if it already exists it won't + * do anything, but if it doesn't it will add the table queue. It will ensure + * a path leads back to the relationship table. + * + * @param $table + * The unaliased name of the table to ensure. + * @param $relationship + * The relationship to ensure the table links to. Each relationship will + * get a unique instance of the table being added. If not specified, + * will be the primary table. + * @param $join + * A views_join object (or derived object) to join the alias in. + * + * @return + * The alias used to refer to this specific table, or NULL if the table + * cannot be ensured. + */ + function ensure_table($table, $relationship = NULL, $join = NULL) { + // ensure a relationship + if (empty($relationship)) { + $relationship = $this->base_table; + } + + // If the relationship is the primary table, this actually be a relationship + // link back from an alias. We store all aliases along with the primary table + // to detect this state, because eventually it'll hit a table we already + // have and that's when we want to stop. + if ($relationship == $this->base_table && !empty($this->tables[$relationship][$table])) { + return $this->tables[$relationship][$table]['alias']; + } + + if (!array_key_exists($relationship, $this->relationships)) { + return FALSE; + } + + if ($table == $this->relationships[$relationship]['base']) { + return $relationship; + } + + // If we do not have join info, fetch it. + if (!isset($join)) { + $join = $this->get_join_data($table, $this->relationships[$relationship]['base']); + } + + // If it can't be fetched, this won't work. + if (empty($join)) { + return; + } + + // Adjust this join for the relationship, which will ensure that the 'base' + // table it links to is correct. Tables adjoined to a relationship + // join to a link point, not the base table. + $join = $this->adjust_join($join, $relationship); + + if ($this->ensure_path($table, $relationship, $join)) { + // Attempt to eliminate redundant joins. If this table's + // relationship and join exactly matches an existing table's + // relationship and join, we do not have to join to it again; + // just return the existing table's alias. See + // http://groups.drupal.org/node/11288 for details. + // + // This can be done safely here but not lower down in + // queue_table(), because queue_table() is also used by + // add_table() which requires the ability to intentionally add + // the same table with the same join multiple times. For + // example, a view that filters on 3 taxonomy terms using AND + // needs to join taxonomy_term_data 3 times with the same join. + + // scan through the table queue to see if a matching join and + // relationship exists. If so, use it instead of this join. + + // TODO: Scanning through $this->table_queue results in an + // O(N^2) algorithm, and this code runs every time the view is + // instantiated (Views 2 does not currently cache queries). + // There are a couple possible "improvements" but we should do + // some performance testing before picking one. + foreach ($this->table_queue as $queued_table) { + // In PHP 4 and 5, the == operation returns TRUE for two objects + // if they are instances of the same class and have the same + // attributes and values. + if ($queued_table['relationship'] == $relationship && $queued_table['join'] == $join) { + return $queued_table['alias']; + } + } + + return $this->queue_table($table, $relationship, $join); + } + } + + /** + * Make sure that the specified table can be properly linked to the primary + * table in the JOINs. This function uses recursion. If the tables + * needed to complete the path back to the primary table are not in the + * query they will be added, but additional copies will NOT be added + * if the table is already there. + */ + function ensure_path($table, $relationship = NULL, $join = NULL, $traced = array(), $add = array()) { + if (!isset($relationship)) { + $relationship = $this->base_table; + } + + if (!array_key_exists($relationship, $this->relationships)) { + return FALSE; + } + + // If we do not have join info, fetch it. + if (!isset($join)) { + $join = $this->get_join_data($table, $this->relationships[$relationship]['base']); + } + + // If it can't be fetched, this won't work. + if (empty($join)) { + return FALSE; + } + + // Does a table along this path exist? + if (isset($this->tables[$relationship][$table]) || + ($join && $join->left_table == $relationship) || + ($join && $join->left_table == $this->relationships[$relationship]['table'])) { + + // Make sure that we're linking to the correct table for our relationship. + foreach (array_reverse($add) as $table => $path_join) { + $this->queue_table($table, $relationship, $this->adjust_join($path_join, $relationship)); + } + return TRUE; + } + + // Have we been this way? + if (isset($traced[$join->left_table])) { + // we looped. Broked. + return FALSE; + } + + // Do we have to add this table? + $left_join = $this->get_join_data($join->left_table, $this->relationships[$relationship]['base']); + if (!isset($this->tables[$relationship][$join->left_table])) { + $add[$join->left_table] = $left_join; + } + + // Keep looking. + $traced[$join->left_table] = TRUE; + return $this->ensure_path($join->left_table, $relationship, $left_join, $traced, $add); + } + + /** + * Fix a join to adhere to the proper relationship; the left table can vary + * based upon what relationship items are joined in on. + */ + function adjust_join($join, $relationship) { + if (!empty($join->adjusted)) { + return $join; + } + + if (empty($relationship) || empty($this->relationships[$relationship])) { + return $join; + } + + // Adjusts the left table for our relationship. + if ($relationship != $this->base_table) { + // If we're linking to the primary table, the relationship to use will + // be the prior relationship. Unless it's a direct link. + + // Safety! Don't modify an original here. + $join = clone $join; + + // Do we need to try to ensure a path? + if ($join->left_table != $this->relationships[$relationship]['table'] && + $join->left_table != $this->relationships[$relationship]['base'] && + !isset($this->tables[$relationship][$join->left_table]['alias'])) { + $this->ensure_table($join->left_table, $relationship); + } + + // First, if this is our link point/anchor table, just use the relationship + if ($join->left_table == $this->relationships[$relationship]['table']) { + $join->left_table = $relationship; + } + // then, try the base alias. + elseif (isset($this->tables[$relationship][$join->left_table]['alias'])) { + $join->left_table = $this->tables[$relationship][$join->left_table]['alias']; + } + // But if we're already looking at an alias, use that instead. + elseif (isset($this->table_queue[$relationship]['alias'])) { + $join->left_table = $this->table_queue[$relationship]['alias']; + } + } + + $join->adjusted = TRUE; + return $join; + } + + /** + * Retrieve join data from the larger join data cache. + * + * @param $table + * The table to get the join information for. + * @param $base_table + * The path we're following to get this join. + * + * @return + * A views_join object or child object, if one exists. + */ + function get_join_data($table, $base_table) { + // Check to see if we're linking to a known alias. If so, get the real + // table's data instead. + if (!empty($this->table_queue[$table])) { + $table = $this->table_queue[$table]['table']; + } + return views_get_table_join($table, $base_table); + } + + /** + * Get the information associated with a table. + * + * If you need the alias of a table with a particular relationship, use + * ensure_table(). + */ + function get_table_info($table) { + if (!empty($this->table_queue[$table])) { + return $this->table_queue[$table]; + } + + // In rare cases we might *only* have aliased versions of the table. + if (!empty($this->tables[$this->base_table][$table])) { + $alias = $this->tables[$this->base_table][$table]['alias']; + if (!empty($this->table_queue[$alias])) { + return $this->table_queue[$alias]; + } + } + } + + /** + * Add a field to the query table, possibly with an alias. This will + * automatically call ensure_table to make sure the required table + * exists, *unless* $table is unset. + * + * @param $table + * The table this field is attached to. If NULL, it is assumed this will + * be a formula; otherwise, ensure_table is used to make sure the + * table exists. + * @param $field + * The name of the field to add. This may be a real field or a formula. + * @param $alias + * The alias to create. If not specified, the alias will be $table_$field + * unless $table is NULL. When adding formulae, it is recommended that an + * alias be used. + * @param $params + * An array of parameters additional to the field that will control items + * such as aggregation functions and DISTINCT. + * + * @return $name + * The name that this field can be referred to as. Usually this is the alias. + */ + function add_field($table, $field, $alias = '', $params = array()) { + // We check for this specifically because it gets a special alias. + if ($table == $this->base_table && $field == $this->base_field && empty($alias)) { + $alias = $this->base_field; + } + + if ($table && empty($this->table_queue[$table])) { + $this->ensure_table($table); + } + + if (!$alias && $table) { + $alias = $table . '_' . $field; + } + + // Make sure an alias is assigned + $alias = $alias ? $alias : $field; + + // PostgreSQL truncates aliases to 63 characters: http://drupal.org/node/571548 + + // We limit the length of the original alias up to 60 characters + // to get a unique alias later if its have duplicates + $alias = substr($alias, 0, 60); + + // Create a field info array. + $field_info = array( + 'field' => $field, + 'table' => $table, + 'alias' => $alias, + ) + $params; + + // Test to see if the field is actually the same or not. Due to + // differing parameters changing the aggregation function, we need + // to do some automatic alias collision detection: + $base = $alias; + $counter = 0; + while (!empty($this->fields[$alias]) && $this->fields[$alias] != $field_info) { + $field_info['alias'] = $alias = $base . '_' . ++$counter; + } + + if (empty($this->fields[$alias])) { + $this->fields[$alias] = $field_info; + } + + return $alias; + } + + /** + * Remove all fields that may've been added; primarily used for summary + * mode where we're changing the query because we didn't get data we needed. + */ + function clear_fields() { + $this->fields = array(); + } + + /** + * Add a simple WHERE clause to the query. The caller is responsible for + * ensuring that all fields are fully qualified (TABLE.FIELD) and that + * the table already exists in the query. + * + * @param $group + * The WHERE group to add these to; groups are used to create AND/OR + * sections. Groups cannot be nested. Use 0 as the default group. + * If the group does not yet exist it will be created as an AND group. + * @param $field + * The name of the field to check. + * @param $value + * The value to test the field against. In most cases, this is a scalar. For more + * complex options, it is an array. The meaning of each element in the array is + * dependent on the $operator. + * @param $operator + * The comparison operator, such as =, <, or >=. It also accepts more complex + * options such as IN, LIKE, or BETWEEN. Defaults to IN if $value is an array + * = otherwise. If $field is a string you have to use 'formula' here. + * + * @see QueryConditionInterface::condition() + */ + function add_where($group, $field, $value = NULL, $operator = NULL) { + // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all + // the default group. + if (empty($group)) { + $group = 0; + } + + // Check for a group. + if (!isset($this->where[$group])) { + $this->set_where_group('AND', $group); + } + + $this->where[$group]['conditions'][] = array( + 'field' => $field, + 'value' => $value, + 'operator' => $operator, + ); + } + + /** + * Add a complex WHERE clause to the query. + * + * The caller is reponsible for ensuring that all fields are fully qualified + * (TABLE.FIELD) and that the table already exists in the query. + * Internally the dbtng method "where" is used. + * + * @param $group + * The WHERE group to add these to; groups are used to create AND/OR + * sections. Groups cannot be nested. Use 0 as the default group. + * If the group does not yet exist it will be created as an AND group. + * @param $snippet + * The snippet to check. This can be either a column or + * a complex expression like "UPPER(table.field) = 'value'" + * @param $args + * An associative array of arguments. + * + * @see QueryConditionInterface::where() + */ + function add_where_expression($group, $snippet, $args = array()) { + // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all + // the default group. + if (empty($group)) { + $group = 0; + } + + // Check for a group. + if (!isset($this->where[$group])) { + $this->set_where_group('AND', $group); + } + + $this->where[$group]['conditions'][] = array( + 'field' => $snippet, + 'value' => $args, + 'operator' => 'formula', + ); + } + + /** + * Add a simple HAVING clause to the query. + * + * The caller is responsible for ensuring that all fields are fully qualified + * (TABLE.FIELD) and that the table and an appropriate GROUP BY already exist in the query. + * Internally the dbtng method "havingCondition" is used. + * + * @param $group + * The HAVING group to add these to; groups are used to create AND/OR + * sections. Groups cannot be nested. Use 0 as the default group. + * If the group does not yet exist it will be created as an AND group. + * @param $field + * The name of the field to check. + * @param $value + * The value to test the field against. In most cases, this is a scalar. For more + * complex options, it is an array. The meaning of each element in the array is + * dependent on the $operator. + * @param $operator + * The comparison operator, such as =, <, or >=. It also accepts more complex + * options such as IN, LIKE, or BETWEEN. Defaults to IN if $value is an array + * = otherwise. If $field is a string you have to use 'formula' here. + * + * @see SelectQueryInterface::havingCondition() + */ + function add_having($group, $field, $value = NULL, $operator = NULL) { + // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all + // the default group. + if (empty($group)) { + $group = 0; + } + + // Check for a group. + if (!isset($this->having[$group])) { + $this->set_where_group('AND', $group, 'having'); + } + + // Add the clause and the args. + $this->having[$group]['conditions'][] = array( + 'field' => $field, + 'value' => $value, + 'operator' => $operator, + ); + } + + /** + * Add a complex HAVING clause to the query. + * The caller is responsible for ensuring that all fields are fully qualified + * (TABLE.FIELD) and that the table and an appropriate GROUP BY already exist in the query. + * Internally the dbtng method "having" is used. + * + * @param $group + * The HAVING group to add these to; groups are used to create AND/OR + * sections. Groups cannot be nested. Use 0 as the default group. + * If the group does not yet exist it will be created as an AND group. + * @param $snippet + * The snippet to check. This can be either a column or + * a complex expression like "COUNT(table.field) > 3" + * @param $args + * An associative array of arguments. + * + * @see QueryConditionInterface::having() + */ + function add_having_expression($group, $snippet, $args = array()) { + // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all + // the default group. + if (empty($group)) { + $group = 0; + } + + // Check for a group. + if (!isset($this->having[$group])) { + $this->set_where_group('AND', $group, 'having'); + } + + // Add the clause and the args. + $this->having[$group]['conditions'][] = array( + 'field' => $snippet, + 'value' => $args, + 'operator' => 'formula', + ); + } + + /** + * Add an ORDER BY clause to the query. + * + * @param $table + * The table this field is part of. If a formula, enter NULL. + * @param $field + * The field or formula to sort on. If already a field, enter NULL + * and put in the alias. + * @param $order + * Either ASC or DESC. + * @param $alias + * The alias to add the field as. In SQL, all fields in the order by + * must also be in the SELECT portion. If an $alias isn't specified + * one will be generated for from the $field; however, if the + * $field is a formula, this alias will likely fail. + * @param $params + * Any params that should be passed through to the add_field. + */ + function add_orderby($table, $field, $order, $alias = '', $params = array()) { + if ($table) { + $this->ensure_table($table); + } + + // Only fill out this aliasing if there is a table; + // otherwise we assume it is a formula. + if (!$alias && $table) { + $as = $table . '_' . $field; + } + else { + $as = $alias; + } + + if ($field) { + $as = $this->add_field($table, $field, $as, $params); + } + + $this->orderby[] = array( + 'field' => $as, + 'direction' => strtoupper($order) + ); + + /** + * -- removing, this should be taken care of by field adding now. + * -- leaving commented because I am unsure. + // If grouping, all items in the order by must also be in the + // group by clause. Check $table to ensure that this is not a + // formula. + if ($this->groupby && $table) { + $this->add_groupby($as); + } + */ + } + + /** + * Add a simple GROUP BY clause to the query. The caller is responsible + * for ensuring that the fields are fully qualified and the table is properly + * added. + */ + function add_groupby($clause) { + // Only add it if it's not already in there. + if (!in_array($clause, $this->groupby)) { + $this->groupby[] = $clause; + } + } + + /** + * Generates a unique placeholder used in the db query. + */ + function placeholder($base = 'views') { + static $placeholders = array(); + if (!isset($placeholders[$base])) { + $placeholders[$base] = 0; + return ':' . $base; + } + else { + return ':' . $base . ++$placeholders[$base]; + } + } + + /** + * Construct the "WHERE" or "HAVING" part of the query. + * + * @param $where + * 'where' or 'having'. + */ + function build_condition($where = 'where') { + $has_condition = FALSE; + $main_group = $this->group_operator == 'OR' ? db_or() : db_and(); + foreach ($this->$where as $group => $info) { + $sub_group = $info['type'] == 'OR' ? db_or() : db_and(); + foreach ($info['conditions'] as $key => $clause) { + if ($clause['operator'] == 'formula') { + $has_condition = TRUE; + $sub_group->where($clause['field'], $clause['value']); + } + else { + $has_condition = TRUE; + $sub_group->condition($clause['field'], $clause['value'], $clause['operator']); + } + } + $main_group->condition($sub_group); + } + if ($has_condition) { + return $main_group; + } + } + + /** + * Build fields array. + */ + function compile_fields($fields_array, $query) { + $non_aggregates = array(); + foreach ($fields_array as $field) { + $string = ''; + if (!empty($field['table'])) { + $string .= $field['table'] . '.'; + } + $string .= $field['field']; + $fieldname = (!empty($field['alias']) ? $field['alias'] : $string); + + if (!empty($field['distinct'])) { + throw new Exception("Column-level distinct is not supported anymore."); + } + + if (!empty($field['count'])) { + // Retained for compatibility + $field['function'] = 'count'; + // It seems there's no way to abstract the table+column reference + // without adding a field, aliasing, and then using the alias. + } + + if (!empty($field['function'])) { + $info = $this->get_aggregation_info(); + if (!empty($info[$field['function']]['method']) && function_exists($info[$field['function']]['method'])) { + $string = $info[$field['function']]['method']($field['function'], $string); + $placeholders = !empty($field['placeholders']) ? $field['placeholders'] : array(); + $query->addExpression($string, $fieldname, $placeholders); + } + + $this->has_aggregate = TRUE; + } + // This is a formula, using no tables. + elseif (empty($field['table'])) { + $placeholders = !empty($field['placeholders']) ? $field['placeholders'] : array(); + $query->addExpression($string, $fieldname, $placeholders); + } + + elseif ($this->distinct && !in_array($fieldname, $this->groupby)) { + // d7cx: This code was there, apparently needed for PostgreSQL + // $string = db_driver() == 'pgsql' ? "FIRST($string)" : $string; + $query->addField(!empty($field['table']) ? $field['table'] : $this->base_table, $field['field'], $fieldname); + } + elseif (empty($field['aggregate'])) { + $non_aggregates[] = $fieldname; + $query->addField(!empty($field['table']) ? $field['table'] : $this->base_table, $field['field'], $fieldname); + } + + // @TODO Remove this old code. + if (!empty($field['distinct']) && empty($field['function'])) { + $distinct[] = $string; + } + else { + $fields[] = $string; + } + + if ($this->get_count_optimized) { + // We only want the first field in this case. + break; + } + } + return array( + $non_aggregates, + ); + } + + /** + * Generate a query and a countquery from all of the information supplied + * to the object. + * + * @param $get_count + * Provide a countquery if this is true, otherwise provide a normal query. + */ + function query($get_count = FALSE) { + // Check query distinct value. + if (empty($this->no_distinct) && $this->distinct && !empty($this->fields)) { + $base_field_alias = $this->add_field($this->base_table, $this->base_field); + $this->add_groupby($base_field_alias); + } + + /** + * An optimized count query includes just the base field instead of all the fields. + * Determine of this query qualifies by checking for a groupby or distinct. + */ + $fields_array = $this->fields; + if ($get_count && !$this->groupby) { + foreach ($fields_array as $field) { + if (!empty($field['distinct']) || !empty($field['function'])) { + $this->get_count_optimized = FALSE; + break; + } + } + } + else { + $this->get_count_optimized = FALSE; + } + if (!isset($this->get_count_optimized)) { + $this->get_count_optimized = TRUE; + } + + $options = array(); + // Detect an external database. + if (isset($this->view->base_database)) { + $options['target'] = $this->view->base_database; + } + + // Set the slave target if the slave option is set + if (!empty($this->options['slave'])) { + $options['target'] = 'slave'; + } + + // Go ahead and build the query. + $query = db_select($this->base_table, $this->base_table, $options)->addTag('views'); + + $joins = $where = $having = $orderby = $groupby = ''; + $fields = $distinct = array(); + + // Add all the tables to the query via joins. We assume all LEFT joins. + foreach ($this->table_queue as $table) { + if (is_object($table['join'])) { + $table['join']->build_join($query, $table, $this); + } + } + + $this->has_aggregate = FALSE; + $non_aggregates = array(); + + list($non_aggregates) = $this->compile_fields($fields_array, $query); + + if (count($this->having)) { + $this->has_aggregate = TRUE; + } + if ($this->has_aggregate || $this->groupby) { + $groupby = array_unique(array_merge($this->groupby, $non_aggregates)); + foreach ($groupby as $field) { + $query->groupBy($field); + } + if (!empty($this->having) && $condition = $this->build_condition('having')) { + $query->havingCondition($condition); + } + } + + if (!$this->get_count_optimized) { + // we only add the orderby if we're not counting. + if ($this->orderby) { + foreach ($this->orderby as $order) { + $query->orderBy($order['field'], $order['direction']); + } + } + } + + if (!empty($this->where) && $condition = $this->build_condition('where')) { + $query->condition($condition); + } + + // Add all query substitutions as metadata. + $query->addMetaData('views_substitutions', module_invoke_all('views_query_substitutions', $this)); + + return $query; + } + + /** + * Get the arguments attached to the WHERE and HAVING clauses of this query. + */ + function get_where_args() { + $args = array(); + foreach ($this->where as $group => $where) { + $args = array_merge($args, $where['args']); + } + foreach ($this->having as $group => $having) { + $args = array_merge($args, $having['args']); + } + return $args; + } + + /** + * Let modules modify the query just prior to finalizing it. + */ + function alter(&$view) { + foreach (module_implements('views_query_alter') as $module) { + $function = $module . '_views_query_alter'; + $function($view, $this); + } + } + + /** + * Builds the necessary info to execute the query. + */ + function build(&$view) { + // Make the query distinct if the option was set. + if (!empty($this->options['distinct'])) { + $this->set_distinct(); + } + + $view->init_pager(); + + // Let the pager modify the query to add limits. + $this->pager->query(); + + $view->build_info['query'] = $this->query(); + $view->build_info['count_query'] = $this->query(TRUE); + } + + /** + * Executes the query and fills the associated view object with according + * values. + * + * Values to set: $view->result, $view->total_rows, $view->execute_time, + * $view->current_page. + */ + function execute(&$view) { + $external = FALSE; // Whether this query will run against an external database. + $query = $view->build_info['query']; + $count_query = $view->build_info['count_query']; + + $query->addMetaData('view', $view); + $count_query->addMetaData('view', $view); + + if (empty($this->options['disable_sql_rewrite'])) { + $base_table_data = views_fetch_data($this->base_table); + if (isset($base_table_data['table']['base']['access query tag'])) { + $access_tag = $base_table_data['table']['base']['access query tag']; + $query->addTag($access_tag); + $count_query->addTag($access_tag); + } + } + + $items = array(); + if ($query) { + $additional_arguments = module_invoke_all('views_query_substitutions', $view); + // Build the count query. + $count_query = $count_query->countQuery(); + // $count_query->distinct = FALSE; + + // Add additional arguments as a fake condition. + // XXX: this doesn't work... because PDO mandates that all bound arguments + // are used on the query. TODO: Find a better way to do this. + if (!empty($additional_arguments)) { + // $query->where('1 = 1', $additional_arguments); + // $count_query->where('1 = 1', $additional_arguments); + } + + $start = microtime(TRUE); + + if ($this->pager->use_count_query() || !empty($view->get_total_rows)) { + $this->pager->execute_count_query($count_query); + } + + // Let the pager modify the query to add limits. + $this->pager->pre_execute($query); + + if (!empty($this->limit) || !empty($this->offset)) { + // We can't have an offset without a limit, so provide a very large limit instead. + $limit = intval(!empty($this->limit) ? $this->limit : 999999); + $offset = intval(!empty($this->offset) ? $this->offset : 0); + $query->range($offset, $limit); + } + + try { + $result = $query->execute(); + + $view->result = array(); + foreach ($result as $item) { + $view->result[] = $item; + } + + $this->pager->post_execute($view->result); + + if ($this->pager->use_pager()) { + $view->total_rows = $this->pager->get_total_items(); + } + } + catch (Exception $e) { + $view->result = array(); + debug('Exception: ' . $e->getMessage()); + } + + } + $view->execute_time = microtime(TRUE) - $start; + } + + function add_signature(&$view) { + $view->query->add_field(NULL, "'" . $view->name . ':' . $view->current_display . "'", 'view_name'); + } + + function get_aggregation_info() { + // @todo -- need a way to get database specific and customized aggregation + // functions into here. + return array( + 'group' => array( + 'title' => t('Group results together'), + 'is aggregate' => FALSE, + ), + 'count' => array( + 'title' => t('Count'), + 'method' => 'views_query_default_aggregation_method_simple', + 'handler' => array( + 'argument' => 'views_handler_argument_group_by_numeric', + 'field' => 'views_handler_field_group_by_numeric', + 'filter' => 'views_handler_filter_group_by_numeric', + 'sort' => 'views_handler_sort_group_by_numeric', + ), + ), + 'sum' => array( + 'title' => t('Sum'), + 'method' => 'views_query_default_aggregation_method_simple', + 'handler' => array( + 'argument' => 'views_handler_argument_group_by_numeric', + 'field' => 'views_handler_field_group_by_numeric', + 'filter' => 'views_handler_filter_group_by_numeric', + 'sort' => 'views_handler_sort_group_by_numeric', + ), + ), + 'avg' => array( + 'title' => t('Average'), + 'method' => 'views_query_default_aggregation_method_simple', + 'handler' => array( + 'argument' => 'views_handler_argument_group_by_numeric', + 'field' => 'views_handler_field_group_by_numeric', + 'filter' => 'views_handler_filter_group_by_numeric', + 'sort' => 'views_handler_sort_group_by_numeric', + ), + ), + 'min' => array( + 'title' => t('Minimum'), + 'method' => 'views_query_default_aggregation_method_simple', + 'handler' => array( + 'argument' => 'views_handler_argument_group_by_numeric', + 'field' => 'views_handler_field_group_by_numeric', + 'filter' => 'views_handler_filter_group_by_numeric', + 'sort' => 'views_handler_sort_group_by_numeric', + ), + ), + 'max' => array( + 'title' => t('Maximum'), + 'method' => 'views_query_default_aggregation_method_simple', + 'handler' => array( + 'argument' => 'views_handler_argument_group_by_numeric', + 'field' => 'views_handler_field_group_by_numeric', + 'filter' => 'views_handler_filter_group_by_numeric', + 'sort' => 'views_handler_sort_group_by_numeric', + ), + ), + ); + } +} + +function views_query_default_aggregation_method_simple($group_type, $field) { + return strtoupper($group_type) . '(' . $field . ')'; +} diff --git a/sites/all/modules/views/plugins/views_plugin_row.inc b/sites/all/modules/views/plugins/views_plugin_row.inc new file mode 100644 index 0000000000000000000000000000000000000000..55d9303a752f9bd27db190835f475ba34c523011 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_row.inc @@ -0,0 +1,148 @@ +<?php +// $Id: views_plugin_row.inc,v 1.4.4.4 2010/05/12 22:29:46 dereine Exp $ +/** + * @file + * Contains the base row style plugin. + */ + +/** + * @defgroup views_row_plugins Views' row plugins + * @{ + * + * Row plugins control how Views outputs an individual record. They are + * tightly coupled to style plugins, in that a style plugin is what calls + * the row plugin. + * + * @see hook_views_plugins + */ + +/** + * Default plugin to view a single row of a table. This is really just a wrapper around + * a theme function. + * + * @ingroup views_row_plugins + */ +class views_plugin_row extends views_plugin { + /** + * Initialize the row plugin. + */ + function init(&$view, &$display, $options = NULL) { + $this->view = &$view; + $this->display = &$display; + + // Overlay incoming options on top of defaults + $this->unpack_options($this->options, isset($options) ? $options : $display->handler->get_option('row_options')); + } + + function uses_fields() { + return !empty($this->definition['uses fields']); + } + + + function option_definition() { + $options = parent::option_definition(); + if (isset($this->base_table)) { + $options['relationship'] = array('default' => 'none'); + } + + return $options; + } + + /** + * Provide a form for setting options. + */ + function options_form(&$form, &$form_state) { + if (isset($this->base_table)) { + $view = &$form_state['view']; + + // A whole bunch of code to figure out what relationships are valid for + // this item. + $relationships = $view->display_handler->get_option('relationships'); + $relationship_options = array(); + + foreach ($relationships as $relationship) { + $relationship_handler = views_get_handler($relationship['table'], $relationship['field'], 'relationship'); + + // If this relationship is valid for this type, add it to the list. + $data = views_fetch_data($relationship['table']); + $base = $data[$relationship['field']]['relationship']['base']; + if ($base == $this->base_table) { + $relationship_handler->init($view, $relationship); + $relationship_options[$relationship['id']] = $relationship_handler->label(); + } + } + + if (!empty($relationship_options)) { + $relationship_options = array_merge(array('none' => t('Do not use a relationship')), $relationship_options); + $rel = empty($this->options['relationship']) ? 'none' : $this->options['relationship']; + if (empty($relationship_options[$rel])) { + // Pick the first relationship. + $rel = key($relationship_options); + } + + $form['relationship'] = array( + '#type' => 'select', + '#title' => t('Relationship'), + '#options' => $relationship_options, + '#default_value' => $rel, + ); + } + else { + $form['relationship'] = array( + '#type' => 'value', + '#value' => 'none', + ); + } + } + } + + /** + * Validate the options form. + */ + function options_validate(&$form, &$form_state) { } + + /** + * 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) { } + + function query() { + if (isset($this->base_table)) { + if (isset($this->options['relationship']) && isset($this->view->relationship[$this->options['relationship']])) { + $relationship = $this->view->relationship[$this->options['relationship']]; + $this->field_alias = $this->view->query->add_field($relationship->alias, $this->base_field); + } + else { + $this->field_alias = $this->view->query->add_field($this->base_table, $this->base_field); + } + } + } + + /** + * Allow the style to do stuff before each row is rendered. + * + * @param $result + * The full array of results from the query. + */ + function pre_render($result) { } + + /** + * Render a row object. This usually passes through to a theme template + * of some form, but not always. + */ + function render($row) { + return theme($this->theme_functions(), + array( + 'view' => $this->view, + 'options' => $this->options, + 'row' => $row, + 'field_alias' => isset($this->field_alias) ? $this->field_alias : '', + )); + } +} + +/** + * @} + */ + diff --git a/sites/all/modules/views/plugins/views_plugin_row_fields.inc b/sites/all/modules/views/plugins/views_plugin_row_fields.inc new file mode 100644 index 0000000000000000000000000000000000000000..9e3db8b9fb69c0de9fe90118cee607f0bde650c7 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_row_fields.inc @@ -0,0 +1,70 @@ +<?php +// $Id: views_plugin_row_fields.inc,v 1.2.4.4 2010/12/04 07:39:35 dereine Exp $ +/** + * @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 views_plugin_row_fields extends views_plugin_row { + function option_definition() { + $options = parent::option_definition(); + + $options['inline'] = array('default' => array()); + $options['separator'] = array('default' => ''); + $options['hide_empty'] = array('default' => FALSE); + return $options; + } + + /** + * Provide a form for setting options. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $options = $this->display->handler->get_field_labels(); + + if (empty($this->options['inline'])) { + $this->options['inline'] = array(); + } + + $form['inline'] = array( + '#type' => 'checkboxes', + '#title' => t('Inline fields'), + '#options' => $options, + '#default_value' => $this->options['inline'], + '#description' => t('Inline fields will be displayed next to each other rather than one after another.'), + ); + + $form['separator'] = array( + '#title' => t('Separator'), + '#type' => 'textfield', + '#size' => 10, + '#default_value' => isset($this->options['separator']) ? $this->options['separator'] : '', + '#description' => t('The separator may be placed between inline fields to keep them from squishing up next to each other. You can use HTML in this field.'), + ); + + $form['hide_empty'] = array( + '#type' => 'checkbox', + '#title' => t('Hide empty fields'), + '#default_value' => $this->options['hide_empty'], + '#description' => t('Do not display fields, labels or markup for fields that are empty.'), + ); + + } + + /** + * 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']); + } +} + diff --git a/sites/all/modules/views/plugins/views_plugin_style.inc b/sites/all/modules/views/plugins/views_plugin_style.inc new file mode 100644 index 0000000000000000000000000000000000000000..390ddf8dde982454fd1ced1343c0a7e1f0687030 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_style.inc @@ -0,0 +1,354 @@ +<?php +// $Id: views_plugin_style.inc,v 1.8.4.10 2010/12/10 08:12:31 dereine Exp $ + +/** + * @defgroup views_style_plugins Views' style plugins + * @{ + * Style plugins control how a view is rendered. For example, they + * can choose to display a collection of fields, node_view() output, + * table output, or any kind of crazy output they want. + * + * Many style plugins can have an optional 'row' plugin, that displays + * a single record. Not all style plugins can utilize this, so it is + * up to the plugin to set this up and call through to the row plugin. + * + * @see hook_views_plugins + */ + +/** + * Base class to define a style plugin handler. + */ +class views_plugin_style extends views_plugin { + /** + * Initialize a style plugin. + * + * @param $view + * @param $display + * @param $options + * The style options might come externally as the style can be sourced + * from at least two locations. If it's not included, look on the display. + */ + function init(&$view, &$display, $options = NULL) { + $this->view = &$view; + $this->display = &$display; + + // Overlay incoming options on top of defaults + $this->unpack_options($this->options, isset($options) ? $options : $display->handler->get_option('style_options')); + + if ($this->uses_row_plugin() && $display->handler->get_option('row_plugin')) { + $this->row_plugin = $display->handler->get_plugin('row'); + } + + $this->options += array( + 'grouping' => '', + ); + + $this->definition += array( + 'uses grouping' => TRUE, + ); + } + + function destroy() { + parent::destroy(); + + if (isset($this->row_plugin)) { + $this->row_plugin->destroy(); + } + } + + /** + * Return TRUE if this style also uses a row plugin. + */ + function uses_row_plugin() { + return !empty($this->definition['uses row plugin']); + } + + /** + * Return TRUE if this style also uses a row plugin. + */ + function uses_row_class() { + return !empty($this->definition['uses row class']); + } + + /** + * Return TRUE if this style also uses fields. + */ + function uses_fields() { + // If we use a row plugin, ask the row plugin. Chances are, we don't + // care, it does. + if ($this->uses_row_plugin() && !empty($this->row_plugin)) { + return $this->row_plugin->uses_fields(); + } + // Otherwise, maybe we do. + return !empty($this->definition['uses fields']); + } + + /** + * Return TRUE if this style uses tokens. + * + * Used to ensure we don't fetch tokens when not needed for performance. + */ + function uses_tokens() { + if ($this->uses_row_class()) { + $class = $this->options['row_class']; + if (strpos($class, '[') !== FALSE || strpos($class, '!') !== FALSE || strpos($class, '%') !== FALSE) { + return TRUE; + } + } + } + + /** + * Return the token replaced row class for the specified row. + */ + function get_row_class($row_index) { + $class = $this->options['row_class']; + if ($this->uses_fields() && $this->view->field) { + $class = $this->tokenize_value($class, $row_index); + } + + return drupal_clean_css_identifier($class); + } + + /** + * Take a value and apply token replacement logic to it. + */ + function tokenize_value($value, $row_index) { + if (strpos($value, '[') !== FALSE || strpos($value, '!') !== FALSE || strpos($value, '%') !== FALSE) { + $fake_item = array( + 'alter_text' => TRUE, + 'text' => $value, + ); + + $tokens = $this->row_tokens[$row_index]; + // Grab a random field handler to perform the render. + $field = end($this->view->field); + $value = strip_tags($field->render_altered($fake_item, $tokens)); + } + + return $value; + } + + function option_definition() { + $options = parent::option_definition(); + $options['grouping'] = array('default' => ''); + if ($this->uses_row_class()) { + $options['row_class'] = array('default' => ''); + } + + return $options; + } + + function options_form(&$form, &$form_state) { + // Only fields-based views can handle grouping. Style plugins can also exclude + // themselves from being groupable by setting their "use grouping" definiton + // key to FALSE. + // @TODO: Document "uses grouping" in docs.php when docs.php is written. + if ($this->uses_fields() && $this->definition['uses grouping']) { + $options = array('' => t('- None -')); + $options += $this->display->handler->get_field_labels(); + + // If there are no fields, we can't group on them. + if (count($options) > 1) { + $form['grouping'] = array( + '#type' => 'select', + '#title' => t('Grouping field'), + '#options' => $options, + '#default_value' => $this->options['grouping'], + '#description' => t('You may optionally specify a field by which to group the records. Leave blank to not group.'), + ); + } + } + + if ($this->uses_row_class()) { + $form['row_class'] = array( + '#title' => t('Row class'), + '#description' => t('The class to provide on each row.'), + '#type' => 'textfield', + '#default_value' => $this->options['row_class'], + ); + + if ($this->uses_fields()) { + $form['row_class']['#description'] .= ' ' . t('You may use field tokens from as per the "Replacement patterns" used in "Rewrite the output of this field" for all fields.'); + } + } + } + + /** + * Called by the view builder to see if this style handler wants to + * interfere with the sorts. If so it should build; if it returns + * any non-TRUE value, normal sorting will NOT be added to the query. + */ + function build_sort() { return TRUE; } + + /** + * Called by the view builder to let the style build a second set of + * sorts that will come after any other sorts in the view. + */ + function build_sort_post() { } + + /** + * Allow the style to do stuff before each row is rendered. + * + * @param $result + * The full array of results from the query. + */ + function pre_render($result) { + if (!empty($this->row_plugin)) { + $this->row_plugin->pre_render($result); + } + } + + /** + * Render the display in this style. + */ + function render() { + if ($this->uses_row_plugin() && empty($this->row_plugin)) { + debug('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) { + if ($this->uses_row_plugin()) { + $rows = array(); + foreach ($records as $row_index => $row) { + $this->view->row_index = $row_index; + $rows[$row_index] = $this->row_plugin->render($row); + } + } + else { + $rows = $records; + } + + $output .= theme($this->theme_functions(), + array( + 'view' => $this->view, + 'options' => $this->options, + 'rows' => $rows, + 'title' => $title) + ); + } + unset($this->view->row_index); + return $output; + } + + /** + * Group records as needed for rendering. + * + * @param $records + * An array of records from the view to group. + * @param $grouping_field + * The field id on which to group. If empty, the result set will be given + * a single group with an empty string as a label. + * @return + * The grouped record set. + */ + function render_grouping($records, $grouping_field = '') { + // Make sure fields are rendered + $this->render_fields($this->view->result); + $sets = array(); + if ($grouping_field) { + foreach ($records as $index => $row) { + $grouping = ''; + // Group on the rendered version of the field, not the raw. That way, + // we can control any special formatting of the grouping field through + // the admin or theme layer or anywhere else we'd like. + if (isset($this->view->field[$grouping_field])) { + $grouping = $this->get_field($index, $grouping_field); + if ($this->view->field[$grouping_field]->options['label']) { + $grouping = $this->view->field[$grouping_field]->options['label'] . ': ' . $grouping; + } + } + $sets[$grouping][$index] = $row; + } + } + else { + // Create a single group with an empty grouping field. + $sets[''] = $records; + } + return $sets; + } + + /** + * Render all of the fields for a given style and store them on the object. + * + * @param $result + * The result array from $view->result + */ + function render_fields($result) { + if (!$this->uses_fields()) { + return; + } + + if (isset($this->rendered_fields)) { + return $this->rendered_fields; + } + + $this->view->row_index = 0; + $keys = array_keys($this->view->field); + foreach ($result as $count => $row) { + $this->view->row_index = $count; + foreach ($keys as $id) { + $this->rendered_fields[$count][$id] = $this->view->field[$id]->theme($row); + } + + if ($this->uses_tokens()) { + $this->row_tokens[$count] = $this->view->field[$id]->get_render_tokens(array()); + } + } + unset($this->view->row_index); + } + + /** + * Get a rendered field. + * + * @param $index + * The index count of the row. + * @param $field + * The id of the field. + */ + function get_field($index, $field) { + if (!isset($this->rendered_fields)) { + $this->render_fields($this->view->result); + } + + if (isset($this->rendered_fields[$index][$field])) { + return $this->rendered_fields[$index][$field]; + } + } + + function validate() { + $errors = parent::validate(); + + if ($this->uses_row_plugin()) { + $plugin = $this->display->handler->get_plugin('row'); + if (empty($plugin)) { + $errors[] = t('Style @style requires a row style but the row plugin is invalid.', array('@style' => $this->definition['title'])); + } + else { + $result = $plugin->validate(); + if (!empty($result) && is_array($result)) { + $errors = array_merge($errors, $result); + } + } + } + return $errors; + } + + function query() { + parent::query(); + if (isset($this->row_plugin)) { + $this->row_plugin->query(); + } + } +} + +/** + * @} + */ + diff --git a/sites/all/modules/views/plugins/views_plugin_style_default.inc b/sites/all/modules/views/plugins/views_plugin_style_default.inc new file mode 100644 index 0000000000000000000000000000000000000000..0e2d83a64c8a56fe44d583b196d92a80cae25b60 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_style_default.inc @@ -0,0 +1,25 @@ +<?php +// $Id: views_plugin_style_default.inc,v 1.2 2008/09/30 19:47:11 merlinofchaos Exp $ +/** + * @file + * Contains the default style plugin. + */ + +/** + * Default style plugin to render rows one after another with no + * decorations. + * + * @ingroup views_style_plugins + */ +class views_plugin_style_default extends views_plugin_style { + /** + * Set default options + */ + function options(&$options) { + parent::options($options); + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_style_grid.inc b/sites/all/modules/views/plugins/views_plugin_style_grid.inc new file mode 100644 index 0000000000000000000000000000000000000000..08cebd8f7cfada06f486f5cd64b6e908652fe7f9 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_style_grid.inc @@ -0,0 +1,61 @@ +<?php +// $Id: views_plugin_style_grid.inc,v 1.1.6.2 2010/12/10 08:19:15 dereine Exp $ +/** + * @file + * Contains the grid style plugin. + */ + +/** + * Style plugin to render each item in a grid cell. + * + * @ingroup views_style_plugins + */ +class views_plugin_style_grid extends views_plugin_style { + /** + * Set default options + */ + function option_definition() { + $options = parent::option_definition(); + + $options['columns'] = array('default' => '4'); + $options['alignment'] = array('default' => 'horizontal'); + $options['fill_single_line'] = array('default' => TRUE); + $options['summary'] = array('default' => ''); + + return $options; + } + + /** + * Render the given style. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['columns'] = array( + '#type' => 'textfield', + '#title' => t('Number of columns'), + '#default_value' => $this->options['columns'], + ); + $form['alignment'] = array( + '#type' => 'radios', + '#title' => t('Alignment'), + '#options' => array('horizontal' => t('Horizontal'), 'vertical' => t('Vertical')), + '#default_value' => $this->options['alignment'], + '#description' => t('Horizontal alignment will place items starting in the upper left and moving right. Vertical alignment will place items starting in the upper left and moving down.'), + ); + + $form['fill_single_line'] = array( + '#type' => 'checkbox', + '#title' => t('Fill up single line'), + '#description' => t('If you disable this option a grid with only one row will have the amount of items as tds. If you disable it this can cause problems with your css.'), + '#default_value' => !empty($this->options['fill_single_line']), + ); + + $form['summary'] = array( + '#type' => 'textfield', + '#title' => t('Table summary'), + '#description' => t('This value will be displayed as table-summary attribute in the html. Set this for better accessiblity of your site.'), + '#default_value' => $this->options['summary'], + ); + } +} + diff --git a/sites/all/modules/views/plugins/views_plugin_style_jump_menu.inc b/sites/all/modules/views/plugins/views_plugin_style_jump_menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..19e1cd3397f44f7d94cf7170e1351b431d491c7d --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_style_jump_menu.inc @@ -0,0 +1,177 @@ +<?php +// $Id: views_plugin_style_jump_menu.inc,v 1.1.6.7 2010/12/14 00:47:26 merlinofchaos Exp $ +/** + * @file + * Contains the table style plugin. + */ + +/** + * Style plugin to render each item as a row in a table. + * + * @ingroup views_style_plugins + */ +class views_plugin_style_jump_menu extends views_plugin_style { + function option_definition() { + $options = parent::option_definition(); + + $options['hide'] = array('default' => FALSE); + $options['path'] = array('default' => ''); + $options['text'] = array('default' => 'Go', 'translatable' => TRUE); + $options['choose'] = array('default' => '- Choose -', 'translatable' => TRUE); + $options['default_value'] = array('default' => FALSE); + + return $options; + } + + /** + * Render the given style. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $handlers = $this->display->handler->get_handlers('field'); + if (empty($handlers)) { + $form['error_markup'] = array( + '#value' => t('You need at least one field before you can configure your jump menu settings'), + '#prefix' => '<div class="error form-item description">', + '#suffix' => '</div>', + ); + return; + } + + $form['markup'] = array( + '#value' => t('To properly configure a jump menu, you must select one field that will represent the path to utilize. You should then set that field to exclude. All other displayed fields will be part of the menu. Please note that all HTML will be stripped from this output as select boxes cannot show HTML.'), + '#prefix' => '<div class="form-item description">', + '#suffix' => '</div>', + ); + + foreach ($handlers as $id => $handler) { + $options[$id] = $handler->ui_name(); + } + + $form['path'] = array( + '#type' => 'select', + '#title' => t('Path field'), + '#options' => $options, + '#default_value' => $this->options['path'], + ); + + $form['hide'] = array( + '#type' => 'checkbox', + '#title' => t('Hide the "Go" button.'), + '#default_value' => !empty($this->options['hide']), + '#description' => t('If hidden, this button will only be hidden for users with javascript and the page will automatically jump when the select is changed.'), + ); + + $form['text'] = array( + '#type' => 'textfield', + '#title' => t('Button text'), + '#default_value' => $this->options['text'], + ); + + $form['choose'] = array( + '#type' => 'textfield', + '#title' => t('Choose text'), + '#default_value' => $this->options['choose'], + '#description' => t('The text that will appear as the selected option in the jump menu.'), + ); + + $form['default_value'] = array( + '#type' => 'checkbox', + '#title' => t('Select the current argument.'), + '#default_value' => !empty($this->options['default_value']), + '#description' => t('If checked, the current path will be displayed as the default option in the jump menu, if applicable.'), + ); + } + + /** + * Render the display in this style. + * + * This is overridden so that we can render our grouping specially. + */ + function render() { + $result = $this->view->result; + // Group the rows according to the grouping field, if specified. + $fields = $this->render_fields($result); + $sets = array(); + if ($this->options['grouping']) { + foreach ($result as $index => $row) { + $grouping = ''; + // Group on the rendered version of the field, not the raw. That way, + // we can control any special formatting of the grouping field through + // the admin or theme layer or anywhere else we'd like. + if (isset($this->view->field[$this->options['grouping']])) { + $grouping = strip_tags($this->get_field($index, $this->options['grouping'])); + if ($this->view->field[$this->options['grouping']]->options['label']) { + $grouping = $this->view->field[$this->options['grouping']]->options['label'] . ': ' . $grouping; + } + } + $sets[$grouping][] = $row; + } + } + else { + // Create a single group with an empty grouping field. + $sets[''] = $result; + } + + // Turn this all into an $options array for the jump menu. + $this->view->row_index = 0; + $options = array(); + $paths = array(); + + foreach ($sets as $title => $records) { + foreach ($records as $row) { + $path = strip_tags($this->get_field($this->view->row_index, $this->options['path'])); + // Putting a '/' in front messes up url() so let's take that out + // so users don't shoot themselves in the foot. + if (strpos($path, '/') === 0) { + $path = substr($path, 1); + } + + // use parse_url() to preserve query and fragment in case the user + // wants to do fun tricks. + $url = parse_url($path); + $url_options = array(); + if (isset($url['query'])) { + $path = strtr($path, array('?' . $url['query'] => '')); + $url_options['query'] = $url['query']; + } + if (isset($url['fragment'])) { + $path = strtr($path, array('#' . $url['fragment'] => '')); + $url_options['fragment'] = $url['fragment']; + } + + $path = url($path, $url_options); + $field = strip_tags($this->row_plugin->render($row)); + if ($title) { + $options[$title][$path] = $field; + } + else { + $options[$path] = $field; + } + $paths[$path] = $path; + $this->view->row_index++; + } + } + unset($this->view->row_index); + + $default_value = ''; + if ($this->options['default_value'] && !empty($paths[url($_GET['q'])])) { + $default_value = url($_GET['q']); + } + + ctools_include('jump-menu'); + $settings = array( + 'hide' => $this->options['hide'], + 'button' => $this->options['text'], + 'choose' => $this->options['choose'], + 'default_value' => $default_value, + ); + + return drupal_render(drupal_get_form('ctools_jump_menu', $options, $settings)); + } + + function render_set($title, $records) { + $options = array(); + $fields = $this->rendered_fields; + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_style_list.inc b/sites/all/modules/views/plugins/views_plugin_style_list.inc new file mode 100644 index 0000000000000000000000000000000000000000..eac331c5e221566619f80aef39198a7b8dc3a3a6 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_style_list.inc @@ -0,0 +1,54 @@ +<?php +// $Id: views_plugin_style_list.inc,v 1.1.6.1 2010/12/04 07:39:35 dereine Exp $ +/** + * @file + * Contains the list style plugin. + */ + +/** + * Style plugin to render each item in an ordered or unordered list. + * + * @ingroup views_style_plugins + */ +class views_plugin_style_list extends views_plugin_style { + /** + * Set default options + */ + function option_definition() { + $options = parent::option_definition(); + + $options['type'] = array('default' => 'ul'); + $options['class'] = array('default' => ''); + $options['wrapper_class'] = array('default' => 'item-list'); + + return $options; + } + + /** + * Render the given style. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['type'] = array( + '#type' => 'radios', + '#title' => t('List type'), + '#options' => array('ul' => t('Unordered list'), 'ol' => t('Ordered list')), + '#default_value' => $this->options['type'], + ); + $form['wrapper_class'] = array( + '#title' => t('Wrapper class'), + '#description' => t('The class to provide on the wrapper, outside the list.'), + '#type' => 'textfield', + '#size' => '30', + '#default_value' => $this->options['wrapper_class'], + ); + $form['class'] = array( + '#title' => t('List class'), + '#description' => t('The class to provide on the list element itself.'), + '#type' => 'textfield', + '#size' => '30', + '#default_value' => $this->options['class'], + ); + } +} + diff --git a/sites/all/modules/views/plugins/views_plugin_style_rss.inc b/sites/all/modules/views/plugins/views_plugin_style_rss.inc new file mode 100644 index 0000000000000000000000000000000000000000..7be2dedb040ae1a72ba45345934ac60afe275e70 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_style_rss.inc @@ -0,0 +1,106 @@ +<?php +// $Id: views_plugin_style_rss.inc,v 1.2.6.7 2010/12/18 08:02:38 dereine Exp $ +/** + * @file + * Contains the RSS style plugin. + */ + +/** + * Default style plugin to render an RSS feed. + * + * @ingroup views_style_plugins + */ +class views_plugin_style_rss extends views_plugin_style { + function attach_to($display_id, $path, $title) { + $display = $this->view->display[$display_id]->handler; + $url_options = array(); + $input = $this->view->get_exposed_input(); + if ($input) { + $url_options['query'] = $input; + } + $url_options['absolute'] = TRUE; + + $url = url($this->view->get_url(NULL, $path), $url_options); + if ($display->has_path()) { + if (empty($this->preview)) { + drupal_add_feed($url, $title); + } + } + else { + if (empty($this->view->feed_icon)) { + $this->view->feed_icon = ''; + } + + $this->view->feed_icon .= theme('feed_icon', array('url' => $url, 'title' => $title)); + drupal_add_html_head_link(array( + 'rel' => 'alternate', + 'type' => 'application/rss+xml', + 'title' => $title, + 'href' => $url + )); + } + } + + function option_definition() { + $options = parent::option_definition(); + + $options['description'] = array('default' => '', 'translatable' => TRUE); + + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + + $form['description'] = array( + '#type' => 'textfield', + '#title' => t('RSS description'), + '#default_value' => $this->options['description'], + '#description' => t('This will appear in the RSS feed itself.'), + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-style-options-override' => array(FALSE)), + ); + } + + /** + * Return an array of additional XHTML elements to add to the channel. + * + * @return + * An array that can be passed to format_xml_elements(). + */ + function get_channel_elements() { + return array(); + } + + function render() { + if (empty($this->row_plugin)) { + debug('views_plugin_style_default: Missing row plugin'); + return; + } + $rows = ''; + + // This will be filled in by the row plugin and is used later on in the + // theming output. + $this->namespaces = array(); + + // Fetch any additional elements for the channel and merge in their + // namespaces. + $this->channel_elements = $this->get_channel_elements(); + foreach ($this->channel_elements as $element) { + if (isset($element['namespace'])) { + $this->namespaces = array_merge($this->namespaces, $element['namespace']); + } + } + + foreach ($this->view->result as $row) { + $rows .= $this->row_plugin->render($row); + } + + return theme($this->theme_functions(), + array( + 'view' => $this->view, + 'options' => $this->options, + 'rows' => $rows + )); + } +} diff --git a/sites/all/modules/views/plugins/views_plugin_style_summary.inc b/sites/all/modules/views/plugins/views_plugin_style_summary.inc new file mode 100644 index 0000000000000000000000000000000000000000..3279bd4ebfb7c932816dfa69b292105e4793025f --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_style_summary.inc @@ -0,0 +1,75 @@ +<?php +// $Id: views_plugin_style_summary.inc,v 1.1.6.6 2010/11/05 07:20:54 dereine Exp $ +/** + * @file + * Contains the default summary style plugin, which displays items in an HTML list. + */ + +/** + * The default style plugin for summaries. + * + * @ingroup views_style_plugins + */ +class views_plugin_style_summary extends views_plugin_style { + function option_definition() { + $options = parent::option_definition(); + + $options['base_path'] = array('default' => ''); + $options['count'] = array('default' => TRUE, 'bool' => TRUE); + $options['override'] = array('default' => FALSE, 'bool' => TRUE); + $options['items_per_page'] = array('default' => 25); + + return $options; + } + + function query() { + if (!empty($this->options['override'])) { + $this->view->set_items_per_page(intval($this->options['items_per_page'])); + } + } + + function options_form(&$form, &$form_state) { + $form['base_path'] = array( + '#type' => 'textfield', + '#title' => t('Base path'), + '#default_value' => $this->options['base_path'], + '#description' => t('Define the base path for links in this summary + view, i.e. http://example.com/<strong>your_view_path/archive</strong>. + Do not include beginning and ending forward slash. If this value + is empty, views will use the first path found as the base path, + in page displays, or / if no path could be found.'), + ); + $form['count'] = array( + '#type' => 'checkbox', + '#default_value' => !empty($this->options['count']), + '#title' => t('Display record count with link'), + ); + $form['override'] = array( + '#type' => 'checkbox', + '#default_value' => !empty($this->options['override']), + '#title' => t('Override number of items to display'), + ); + $form['items_per_page'] = array( + '#type' => 'textfield', + '#title' => t('Items to display'), + '#default_value' => $this->options['items_per_page'], + '#process' => array('ctools_dependent_process'), + '#dependency' => array('edit-style-options-override' => array(TRUE)), + ); + } + + function render() { + $rows = array(); + foreach ($this->view->result as $row) { + // @todo: Include separator as an option. + $rows[] = $row; + } + + return theme($this->theme_functions(), array( + 'view' => $this->view, + 'options' => $this->options, + 'rows' => $rows + )); + } +} + diff --git a/sites/all/modules/views/plugins/views_plugin_style_summary_jump_menu.inc b/sites/all/modules/views/plugins/views_plugin_style_summary_jump_menu.inc new file mode 100644 index 0000000000000000000000000000000000000000..3dc06b4e7a056aefa21057d2816eab2370866774 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_style_summary_jump_menu.inc @@ -0,0 +1,121 @@ +<?php +// $Id: views_plugin_style_summary_jump_menu.inc,v 1.1.6.6 2010/12/14 00:47:26 merlinofchaos Exp $ +/** + * @file + * Contains the default summary style plugin, which displays items in an HTML list. + */ + +/** + * The default style plugin for summaries. + * + * @ingroup views_style_plugins + */ +class views_plugin_style_summary_jump_menu extends views_plugin_style { + function option_definition() { + $options = parent::option_definition(); + + $options['base_path'] = array('default' => ''); + $options['count'] = array('default' => TRUE); + $options['hide'] = array('default' => FALSE); + $options['text'] = array('default' => 'Go', 'translatable' => TRUE); + $options['choose'] = array('default' => '- Choose -', 'translatable' => TRUE); + $options['default_value'] = array('default' => FALSE); + + return $options; + } + + function query() { + $pager = array( + 'type' => 'none', + 'options' => array(), + ); + $this->display->handler->set_option('pager', $pager); + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['base_path'] = array( + '#type' => 'textfield', + '#title' => t('Base path'), + '#default_value' => $this->options['base_path'], + '#description' => t('Define the base path for links in this summary + view, i.e. http://example.com/<strong>your_view_path/archive</strong>. + Do not include beginning and ending forward slash. If this value + is empty, views will use the first path found as the base path, + in page displays, or / if no path could be found.'), + ); + $form['count'] = array( + '#type' => 'checkbox', + '#default_value' => !empty($this->options['count']), + '#title' => t('Display record count with link'), + ); + + $form['hide'] = array( + '#type' => 'checkbox', + '#title' => t('Hide the "Go" button.'), + '#default_value' => !empty($this->options['hide']), + '#description' => t('If hidden, this button will only be hidden for users with javascript and the page will automatically jump when the select is changed.'), + ); + + $form['text'] = array( + '#type' => 'textfield', + '#title' => t('Button text'), + '#default_value' => $this->options['text'], + ); + + $form['choose'] = array( + '#type' => 'textfield', + '#title' => t('Choose text'), + '#default_value' => $this->options['choose'], + '#description' => t('The text that will appear as the selected option in the jump menu.'), + ); + + $form['default_value'] = array( + '#type' => 'checkbox', + '#title' => t('Select the current argument.'), + '#default_value' => !empty($this->options['default_value']), + '#description' => t('If checked, the current argument setting will be displayed as the default option in the jump menu, if applicable.'), + ); + } + + function render() { + $argument = $this->view->argument[$this->view->build_info['summary_level']]; + + $url_options = array(); + + if (!empty($this->view->exposed_raw_input)) { + $url_options['query'] = $this->view->exposed_raw_input; + } + + $options = array(); + $default_value = ''; + foreach ($this->view->result as $id => $row) { + $args = $this->view->args; + $args[$argument->position] = $argument->summary_argument($row); + $base_path = NULL; + if (!empty($argument->options['style_options']['base_path'])) { + $base_path = $argument->options['style_options']['base_path']; + } + $path = url($this->view->get_url($args, $base_path), $url_options); + + $options[$path] = strip_tags($argument->summary_name($row)); + if (!empty($this->options['count'])) { + $options[$path] .= ' (' . intval($row->{$argument->count_alias}) . ')'; + } + if ($this->options['default_value'] && $_GET['q'] == $this->view->get_url($args)) { + $default_value = $path; + } + } + + ctools_include('jump-menu'); + $settings = array( + 'hide' => $this->options['hide'], + 'button' => $this->options['text'], + 'choose' => $this->options['choose'], + 'default_value' => $default_value, + ); + + return drupal_get_form('ctools_jump_menu', $options, $settings); + } +} + diff --git a/sites/all/modules/views/plugins/views_plugin_style_summary_unformatted.inc b/sites/all/modules/views/plugins/views_plugin_style_summary_unformatted.inc new file mode 100644 index 0000000000000000000000000000000000000000..00fb69933c0b5c1cfe83969ef8a9160272caa4ca --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_style_summary_unformatted.inc @@ -0,0 +1,35 @@ +<?php +// $Id: views_plugin_style_summary_unformatted.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos Exp $ +/** + * @file + * Contains the unformatted summary style plugin. + */ + +/** + * The default style plugin for summaries. + * + * @ingroup views_style_plugins + */ +class views_plugin_style_summary_unformatted extends views_plugin_style_summary { + function option_definition() { + $options = parent::option_definition(); + $options['inline'] = array('default' => FALSE); + $options['separator'] = array('default' => ''); + return $options; + } + + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $form['inline'] = array( + '#type' => 'checkbox', + '#default_value' => !empty($this->options['inline']), + '#title' => t('Display items inline'), + ); + $form['separator'] = array( + '#type' => 'textfield', + '#title' => t('Separator'), + '#default_value' => $this->options['separator'], + ); + } +} + diff --git a/sites/all/modules/views/plugins/views_plugin_style_table.inc b/sites/all/modules/views/plugins/views_plugin_style_table.inc new file mode 100644 index 0000000000000000000000000000000000000000..db3f8528d09a0e707c8853b1a87ee75787edb831 --- /dev/null +++ b/sites/all/modules/views/plugins/views_plugin_style_table.inc @@ -0,0 +1,271 @@ +<?php +// $Id: views_plugin_style_table.inc,v 1.7.4.12 2010/12/10 08:19:15 dereine Exp $ +/** + * @file + * Contains the table style plugin. + */ + +/** + * Style plugin to render each item as a row in a table. + * + * @ingroup views_style_plugins + */ +class views_plugin_style_table extends views_plugin_style { + function option_definition() { + $options = parent::option_definition(); + + $options['columns'] = array('default' => array()); + $options['default'] = array('default' => ''); + $options['info'] = array('default' => array()); + $options['override'] = array('default' => TRUE); + $options['sticky'] = array('default' => FALSE); + $options['order'] = array('default' => 'asc'); + $options['summary'] = array('default' => ''); + + return $options; + } + + /** + * Determine if we should provide sorting based upon $_GET inputs. + */ + function build_sort() { + if (!isset($_GET['order']) && ($this->options['default'] == -1 || empty($this->view->field[$this->options['default']]))) { + return TRUE; + } + + // If a sort we don't know anything about gets through, exit gracefully. + if (isset($_GET['order']) && empty($this->view->field[$_GET['order']])) { + return TRUE; + } + + // Let the builder know whether or not we're overriding the default sorts. + return empty($this->options['override']); + } + + /** + * Add our actual sort criteria + */ + function build_sort_post() { + if (!isset($_GET['order'])) { + // check for a 'default' clicksort. If there isn't one, exit gracefully. + if (empty($this->options['default'])) { + return; + } + $sort = $this->options['default']; + $this->order = !empty($this->options['order']) ? $this->options['order'] : 'asc'; + } + else { + $sort = $_GET['order']; + // Store the $order for later use. + $this->order = !empty($_GET['sort']) ? strtolower($_GET['sort']) : 'asc'; + } + + // If a sort we don't know anything about gets through, exit gracefully. + if (empty($this->view->field[$sort])) { + return; + } + + // Ensure $this->order is valid. + if ($this->order != 'asc' && $this->order != 'desc') { + $this->order = 'asc'; + } + + // Store the $sort for later use. + $this->active = $sort; + + // Tell the field to click sort. + $this->view->field[$sort]->click_sort($this->order); + } + + /** + * Normalize a list of columns based upon the fields that are + * available. This compares the fields stored in the style handler + * to the list of fields actually in the view, removing fields that + * have been removed and adding new fields in their own column. + * + * - Each field must be in a column. + * - Each column must be based upon a field, and that field + * is somewhere in the column. + * - Any fields not currently represented must be added. + * - Columns must be re-ordered to match the fields. + * + * @param $columns + * An array of all fields; the key is the id of the field and the + * value is the id of the column the field should be in. + * @param $fields + * The fields to use for the columns. If not provided, they will + * be requested from the current display. The running render should + * send the fields through, as they may be different than what the + * display has listed due to access control or other changes. + */ + function sanitize_columns($columns, $fields = NULL) { + $sanitized = array(); + if ($fields === NULL) { + $fields = $this->display->handler->get_option('fields'); + } + + // Preconfigure the sanitized array so that the order is retained. + foreach ($fields as $field => $info) { + // Set to itself so that if it isn't touched, it gets column + // status automatically. + $sanitized[$field] = $field; + } + + foreach ($columns as $field => $column) { + // first, make sure the field still exists. + if (!isset($sanitized[$field])) { + continue; + } + + // If the field is the column, mark it so, or the column + // it's set to is a column, that's ok + if ($field == $column || $columns[$column] == $column && !empty($sanitized[$column])) { + $sanitized[$field] = $column; + } + // Since we set the field to itself initially, ignoring + // the condition is ok; the field will get its column + // status back. + } + + return $sanitized; + } + + /** + * Render the given style. + */ + function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); + $handlers = $this->display->handler->get_handlers('field'); + if (empty($handlers)) { + $form['error_markup'] = array( + '#markup' => '<div class="error form-item description">' . t('You need at least one field before you can configure your table settings') . '</div>', + ); + return; + } + + $form['override'] = array( + '#type' => 'checkbox', + '#title' => t('Override normal sorting if click sorting is used'), + '#default_value' => !empty($this->options['override']), + ); + + $form['sticky'] = array( + '#type' => 'checkbox', + '#title' => t('Enable Drupal style "sticky" table headers (Javascript)'), + '#default_value' => !empty($this->options['sticky']), + '#description' => t('(Sticky header effects will not be active for preview below, only on live output.)'), + ); + + $form['order'] = array( + '#type' => 'select', + '#title' => t('Default sort order'), + '#options' => array('asc' => t('Ascending'), 'desc' => t('Descending')), + '#default_value' => $this->options['order'], + '#description' => t('If a default sort order is selected, what order should it use by default.'), + ); + + $form['summary'] = array( + '#type' => 'textfield', + '#title' => t('Table summary'), + '#description' => t('This value will be displayed as table-summary attribute in the html. Set this for better accessiblity of your site.'), + '#default_value' => $this->options['summary'], + ); + + // Note: views UI registers this theme handler on our behalf. Your module + // will have to register your theme handlers if you do stuff like this. + $form['#theme'] = 'views_ui_style_plugin_table'; + + $columns = $this->sanitize_columns($this->options['columns']); + + // Create an array of allowed columns from the data we know: + $field_names = $this->display->handler->get_field_labels(); + + if (isset($this->options['default'])) { + $default = $this->options['default']; + if (!isset($columns[$default])) { + $default = -1; + } + } + else { + $default = -1; + } + + foreach ($columns as $field => $column) { + $safe = str_replace(array('][', '_', ' '), '-', $field); + // the $id of the column for dependency checking. + $id = 'edit-style-options-columns-' . $safe; + + $form['columns'][$field] = array( + '#type' => 'select', + '#options' => $field_names, + '#default_value' => $column, + ); + if ($handlers[$field]->click_sortable()) { + $form['info'][$field]['sortable'] = array( + '#type' => 'checkbox', + '#default_value' => !empty($this->options['info'][$field]['sortable']), + '#process' => array('form_process_checkbox', 'ctools_dependent_process'), + '#dependency' => array($id => array($field)), + ); + $form['info'][$field]['default_sort_order'] = array( + '#type' => 'select', + '#options' => array('asc' => t('Ascending'), 'desc' => t('Descending')), + '#default_value' => !empty($this->options['info'][$field]['default_sort_order']) ? $this->options['info'][$field]['default_sort_order'] : 'asc', + '#process' => array('ctools_dependent_process'), + '#dependency_count' => 2, + '#dependency' => array($id => array($field), 'edit-style-options-info-' . $safe . '-sortable' => array(1)), + ); + // Provide an ID so we can have such things. + $radio_id = drupal_html_id('edit-default-' . $field); + $form['default'][$field] = array( + '#type' => 'radio', + '#return_value' => $field, + '#parents' => array('style_options', 'default'), + '#id' => $radio_id, + // because 'radio' doesn't fully support '#id' =( + '#attributes' => array('id' => $radio_id), + '#default_value' => $default, + '#process' => array('ctools_dependent_process'), + '#dependency' => array($id => array($field)), + ); + } + $form['info'][$field]['align'] = array( + '#type' => 'select', + '#default_value' => !empty($this->options['info'][$field]['align']) ? $this->options['info'][$field]['align'] : '', + '#options' => array( + '' => t('None'), + 'views-align-left' => t('Left'), + 'views-align-center' => t('Center'), + 'views-align-right' => t('Right'), + ), + '#process' => array('form_process_select', 'ctools_dependent_process'), + '#dependency' => array($id => array($field)), + ); + $form['info'][$field]['separator'] = array( + '#type' => 'textfield', + '#size' => 10, + '#default_value' => isset($this->options['info'][$field]['separator']) ? $this->options['info'][$field]['separator'] : '', + '#process' => array('ctools_dependent_process'), + '#dependency' => array($id => array($field)), + ); + + // markup for the field name + $form['info'][$field]['name'] = array( + '#markup' => $field_names[$field], + ); + } + + // Provide a radio for no default sort + $form['default'][-1] = array( + '#type' => 'radio', + '#return_value' => -1, + '#parents' => array('style_options', 'default'), + '#id' => 'edit-default-0', + '#default_value' => $default, + ); + + $form['description_markup'] = array( + '#markup' => '<div class="description form-item">' . t('Place fields into columns; you may combine multiple fields into the same column. If you do, the separator in the column specified will be used to separate the fields. Check the sortable box to make that column click sortable, and check the default sort radio to determine which column will be sorted by default, if any. You may control column order and field labels in the fields section.') . '</div>', + ); + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_area_text.test b/sites/all/modules/views/tests/handlers/views_handler_area_text.test new file mode 100644 index 0000000000000000000000000000000000000000..862144cd3373ec78969894516008417063a73fb4 --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_area_text.test @@ -0,0 +1,43 @@ +<?php +// $Id: views_handler_area_text.test,v 1.1.2.1 2010/11/07 11:32:25 dereine Exp $ + +class ViewsHandlerAreaTextTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Area: Text', + 'description' => 'Test the core views_handler_area_text handler.', + 'group' => 'Views Handlers', + ); + } + + public function testAreaText() { + $view = $this->getBasicView(); + + // add a text header + $string = $this->randomString(); + $view->display['default']->handler->override_option('header', array( + 'area' => array( + 'id' => 'area', + 'table' => 'views', + 'field' => 'area', + 'content' => $string, + ), + )); + + // Execute the view. + $this->executeView($view); + + $view->display_handler->handlers['header']['area']->options['format'] = $this->randomString(); + $this->assertEqual(NULL, $view->display_handler->handlers['header']['area']->render(), 'Non existant format should return nothing'); + + $view->display_handler->handlers['header']['area']->options['format'] = filter_default_format(); + $this->assertEqual(check_markup($string), $view->display_handler->handlers['header']['area']->render(), 'Existant format should return something'); + + // Empty results, and it shouldn't be displayed . + $this->assertEqual('', $view->display_handler->handlers['header']['area']->render(TRUE), 'No result should lead to no header'); + // Empty results, and it should be displayed. + $view->display_handler->handlers['header']['area']->options['empty'] = TRUE; + $this->assertEqual(check_markup($string), $view->display_handler->handlers['header']['area']->render(TRUE), 'No result, but empty enabled lead to a full header'); + } + +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_argument_null.test b/sites/all/modules/views/tests/handlers/views_handler_argument_null.test new file mode 100644 index 0000000000000000000000000000000000000000..73f87ae3444b553c0ddaa5a7fac42a201785532a --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_argument_null.test @@ -0,0 +1,65 @@ +<?php +// $Id: views_handler_argument_null.test,v 1.1.2.1 2010/11/07 11:32:25 dereine Exp $ + +class ViewsHandlerArgumentNullTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Argument: Null', + 'description' => 'Test the core views_handler_argument_null handler.', + 'group' => 'Views Handlers', + ); + } + + function viewsData() { + $data = parent::viewsData(); + $data['views_test']['id']['argument']['handler'] = 'views_handler_argument_null'; + + return $data; + } + + public function testAreaText() { + // Test validation + $view = $this->getBasicView(); + + // Add a null argument. + $string = $this->randomString(); + $view->display['default']->handler->override_option('arguments', array( + 'null' => array( + 'id' => 'null', + 'table' => 'views', + 'field' => 'null', + ), + )); + + $this->executeView($view); + + // Take sure that the argument is not validated yet. + unset($view->argument['null']->argument_validated); + $this->assertTrue($view->argument['null']->validate_arg(26)); + // test must_not_be option. + unset($view->argument['null']->argument_validated); + $view->argument['null']->options['must_not_be'] = TRUE; + $this->assertFalse($view->argument['null']->validate_arg(26), 'must_not_be returns FALSE, if there is an argument'); + unset($view->argument['null']->argument_validated); + $this->assertTrue($view->argument['null']->validate_arg(NULL), 'must_not_be returns TRUE, if there is no argument'); + + // Test execution. + $view = $this->getBasicView(); + + // Add a argument, which has null as handler. + $string = $this->randomString(); + $view->display['default']->handler->override_option('arguments', array( + 'id' => array( + 'id' => 'id', + 'table' => 'views_test', + 'field' => 'id', + ), + )); + + $this->executeView($view, array(26)); + + // The argument should be ignored, so every result should return. + $this->assertEqual(5, count($view->result)); + } + +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_field_boolean.test b/sites/all/modules/views/tests/handlers/views_handler_field_boolean.test new file mode 100644 index 0000000000000000000000000000000000000000..516edb0b40cb4ee6e9c6eb971252d072f7064e32 --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_field_boolean.test @@ -0,0 +1,64 @@ +<?php +// $Id: views_handler_field_boolean.test,v 1.1.2.1 2010/11/07 11:32:25 dereine Exp $ + +class ViewsHandlerFieldBooleanTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Field: Boolean', + 'description' => 'Test the core views_handler_field_boolean handler.', + 'group' => 'Views Handlers', + ); + } + + function dataSet() { + // Use default dataset but remove the age from john and paul + $data = parent::dataSet(); + $data[0]['age'] = 0; + $data[3]['age'] = 0; + return $data; + } + + function viewsData() { + $data = parent::viewsData(); + $data['views_test']['age']['field']['handler'] = 'views_handler_field_boolean'; + return $data; + } + + public function testFieldBoolean() { + $view = $this->getBasicView(); + + $view->display['default']->handler->override_option('fields', array( + 'age' => array( + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + 'relationship' => 'none', + ), + )); + + $this->executeView($view); + + // This is john, which has no age, there are no custom formats defined, yet. + $this->assertEqual(t('No'), $view->field['age']->advanced_render($view->result[0])); + $this->assertEqual(t('Yes'), $view->field['age']->advanced_render($view->result[1])); + + // Reverse the output. + $view->field['age']->options['not'] = TRUE; + $this->assertEqual(t('Yes'), $view->field['age']->advanced_render($view->result[0])); + $this->assertEqual(t('No'), $view->field['age']->advanced_render($view->result[1])); + + unset($view->field['age']->options['not']); + + // Use another output format. + $view->field['age']->options['type'] = 'true-false'; + $this->assertEqual(t('False'), $view->field['age']->advanced_render($view->result[0])); + $this->assertEqual(t('True'), $view->field['age']->advanced_render($view->result[1])); + + // Set a custom output format. + $view->field['age']->formats['test'] = array(t('Test-True'), t('Test-False')); + $view->field['age']->options['type'] = 'test'; + $this->assertEqual(t('Test-False'), $view->field['age']->advanced_render($view->result[0])); + $this->assertEqual(t('Test-True'), $view->field['age']->advanced_render($view->result[1])); + + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_field_counter.test b/sites/all/modules/views/tests/handlers/views_handler_field_counter.test new file mode 100644 index 0000000000000000000000000000000000000000..0cffb96c234d7341ecf998fca5115ae3a5ebfe5e --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_field_counter.test @@ -0,0 +1,63 @@ +<?php +// $Id: views_handler_field_counter.test,v 1.1.2.2 2010/12/27 08:43:31 dereine Exp $ + +class viewsHandlerFilterCounterTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Field: Counter', + 'description' => 'Tests the views_handler_field_counter handler', + 'group' => 'Views Handlers', + ); + } + + function testSimple() { + $view = $this->getBasicView(); + $view->display['default']->handler->override_option('fields', array( + 'counter' => array( + 'id' => 'counter', + 'table' => 'views', + 'field' => 'counter', + 'relationship' => 'none', + ), + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + ), + )); + $view->preview(); + + $this->assertEqual(1, $view->style_plugin->rendered_fields[0]['counter']); + $this->assertEqual(2, $view->style_plugin->rendered_fields[1]['counter']); + $this->assertEqual(3, $view->style_plugin->rendered_fields[2]['counter']); + $view->destroy(); + + $view = $this->getBasicView(); + $rand_start = rand(5, 10); + $view->display['default']->handler->override_option('fields', array( + 'counter' => array( + 'id' => 'counter', + 'table' => 'views', + 'field' => 'counter', + 'relationship' => 'none', + 'counter_start' => $rand_start + ), + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + ), + )); + $view->preview(); + + $this->assertEqual(0 + $rand_start, $view->style_plugin->rendered_fields[0]['counter']); + $this->assertEqual(1 + $rand_start, $view->style_plugin->rendered_fields[1]['counter']); + $this->assertEqual(2 + $rand_start, $view->style_plugin->rendered_fields[2]['counter']); + } + + // @TODO: Write tests for pager. + function testPager() { + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_field_custom.test b/sites/all/modules/views/tests/handlers/views_handler_field_custom.test new file mode 100644 index 0000000000000000000000000000000000000000..017efa56dd44e8d213c60c763032351be26b5174 --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_field_custom.test @@ -0,0 +1,40 @@ +<?php +// $Id: views_handler_field_custom.test,v 1.1.2.1 2010/11/07 11:32:25 dereine Exp $ + +class ViewsHandlerFieldCustomTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Field: Custom', + 'description' => 'Test the core views_handler_field_custom handler.', + 'group' => 'Views Handlers', + ); + } + + function viewsData() { + $data = parent::viewsData(); + $data['views_test']['name']['field']['handler'] = 'views_handler_field_custom'; + return $data; + } + + public function testFieldCustom() { + $view = $this->getBasicView(); + + // Alter the text of the field to a random string. + $random = $this->randomName(); + $view->display['default']->handler->override_option('fields', array( + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + 'alter' => array( + 'text' => $random, + ), + ), + )); + + $this->executeView($view); + + $this->assertEqual($random, $view->field['name']->advanced_render($view->result[0])); + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_field_date.test b/sites/all/modules/views/tests/handlers/views_handler_field_date.test new file mode 100644 index 0000000000000000000000000000000000000000..1f2dbe2780a67eb796de2500004d61991306042d --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_field_date.test @@ -0,0 +1,55 @@ +<?php +// $Id: views_handler_field_date.test,v 1.1.2.1 2010/11/07 11:32:25 dereine Exp $ + +class ViewsHandlerFieldDateTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Field: Date', + 'description' => 'Test the core views_handler_field_date handler.', + 'group' => 'Views Handlers', + ); + } + + function viewsData() { + $data = parent::viewsData(); + $data['views_test']['created']['field']['handler'] = 'views_handler_field_date'; + return $data; + } + + public function testFieldDate() { + $view = $this->getBasicView(); + + $view->display['default']->handler->override_option('fields', array( + 'created' => array( + 'id' => 'created', + 'table' => 'views_test', + 'field' => 'created', + 'relationship' => 'none', + // c is iso 8601 date format @see http://php.net/manual/en/function.date.php + 'custom_date_format' => 'c', + ), + )); + $time = gmmktime(0, 0, 0, 1, 1, 2000); + + $maps = array( + 'small' => format_date($time, 'small'), + 'medium' => format_date($time, 'medium'), + 'large' => format_date($time, 'large'), + 'custom' => format_date($time, 'custom', 'c'), + 'raw time ago' => format_interval(REQUEST_TIME - $time, 2), + 'time ago' => t('%time ago', array('%time' => format_interval(REQUEST_TIME - $time, 2))), + // TODO write tests for them +// 'raw time span' => format_interval(REQUEST_TIME - $time, 2), +// 'time span' => t('%time hence', array('%time' => format_interval(REQUEST_TIME - $time, 2))), + ); + + $this->executeView($view); + + foreach ($maps as $date_format => $expected_result) { + $view->field['created']->options['date_format'] = $date_format; + $this->assertEqual($expected_result, $view->field['created']->advanced_render($view->result[0])); + debug($view->field['created']->advanced_render($view->result[0])); + } + debug($view->result); + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_field_file_size.test b/sites/all/modules/views/tests/handlers/views_handler_field_file_size.test new file mode 100644 index 0000000000000000000000000000000000000000..7a3b030f76e33a6b5466f006c0dba99807091961 --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_field_file_size.test @@ -0,0 +1,58 @@ +<?php +// $Id: views_handler_field_file_size.test,v 1.1.2.1 2010/11/07 11:32:25 dereine Exp $ + +/** + * @see CommonXssUnitTest + */ +class ViewsHandlerTestFileSize extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Field: file_size', + 'description' => 'Test the core views_handler_field_file_size handler.', + 'group' => 'Views Handlers', + ); + } + + function dataSet() { + $data = parent::dataSet(); + $data[0]['age'] = 0; + $data[1]['age'] = 10; + $data[2]['age'] = 1000; + $data[3]['age'] = 10000; + + return $data; + } + + function viewsData() { + $data = parent::viewsData(); + $data['views_test']['age']['field']['handler'] = 'views_handler_field_file_size'; + + return $data; + } + + public function testFieldFileSize() { + $view = $this->getBasicView(); + + $view->display['default']->handler->override_option('fields', array( + 'age' => array( + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + ), + )); + + $this->executeView($view); + + // Test with the formatted option. + $this->assertEqual($view->field['age']->advanced_render($view->result[0]), ''); + $this->assertEqual($view->field['age']->advanced_render($view->result[1]), '10 bytes'); + $this->assertEqual($view->field['age']->advanced_render($view->result[2]), '1000 bytes'); + $this->assertEqual($view->field['age']->advanced_render($view->result[3]), '9.77 KB'); + // Test with the bytes option. + $view->field['age']->options['file_size_display'] = 'bytes'; + $this->assertEqual($view->field['age']->advanced_render($view->result[0]), ''); + $this->assertEqual($view->field['age']->advanced_render($view->result[1]), 10); + $this->assertEqual($view->field['age']->advanced_render($view->result[2]), 1000); + $this->assertEqual($view->field['age']->advanced_render($view->result[3]), 10000); + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_field_math.test b/sites/all/modules/views/tests/handlers/views_handler_field_math.test new file mode 100644 index 0000000000000000000000000000000000000000..839ab1289586ff2b63c8fa7bc6baa63e01143217 --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_field_math.test @@ -0,0 +1,38 @@ +<?php +// $Id: views_handler_field_math.test,v 1.1.2.1 2010/12/24 14:05:39 dereine Exp $ + +class ViewsHandlerFieldMath extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Field: Math', + 'description' => 'Test the core views_handler_field_math handler.', + 'group' => 'Views Handlers', + ); + } + + function viewsData() { + $data = parent::viewsData(); + return $data; + } + + public function testFieldCustom() { + $view = $this->getBasicView(); + + // Alter the text of the field to a random string. + $rand1 = rand(0, 100); + $rand2 = rand(0, 100); + $view->display['default']->handler->override_option('fields', array( + 'expression' => array( + 'id' => 'expression', + 'table' => 'views', + 'field' => 'expression', + 'relationship' => 'none', + 'expression' => $rand1 . ' + ' . $rand2, + ), + )); + + $this->executeView($view); + + $this->assertEqual($rand1 + $rand2, $view->field['expression']->render($view->result[0])); + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_field_url.test b/sites/all/modules/views/tests/handlers/views_handler_field_url.test new file mode 100644 index 0000000000000000000000000000000000000000..de2cce9ded27385d745ae19fbf8a30413e6f965e --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_field_url.test @@ -0,0 +1,53 @@ +<?php +// $Id: views_handler_field_url.test,v 1.1.2.1 2010/11/07 11:32:25 dereine Exp $ + +class ViewsHandlerFieldUrlTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Field: Url', + 'description' => 'Test the core views_handler_field_url handler.', + 'group' => 'Views Handlers', + ); + } + + function viewsData() { + $data = parent::viewsData(); + $data['views_test']['name']['field']['handler'] = 'views_handler_field_url'; + return $data; + } + + public function testFieldUrl() { + $view = $this->getBasicView(); + + $view->display['default']->handler->override_option('fields', array( + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + 'display_as_link' => FALSE, + ), + )); + + $this->executeView($view); + + $this->assertEqual('John', $view->field['name']->advanced_render($view->result[0])); + + // Make the url a link. + $view->delete(); + $view = $this->getBasicView(); + + $view->display['default']->handler->override_option('fields', array( + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + ), + )); + + $this->executeView($view); + + $this->assertEqual(l('John', 'John'), $view->field['name']->advanced_render($view->result[0])); + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_field_xss.test b/sites/all/modules/views/tests/handlers/views_handler_field_xss.test new file mode 100644 index 0000000000000000000000000000000000000000..0855f031cc8144464a50035f1c691a00e1f694d3 --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_field_xss.test @@ -0,0 +1,54 @@ +<?php +// $Id: views_handler_field_xss.test,v 1.1.2.1 2010/11/07 11:32:25 dereine Exp $ + +/** + * @see CommonXssUnitTest + */ +class ViewsHandlerTestXss extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Field: Xss', + 'description' => 'Test the core views_handler_field_css handler.', + 'group' => 'Views Handlers', + ); + } + + function dataHelper() { + $map = array( + 'John' => 'John', + "Foo\xC0barbaz" => '', + 'Fooÿñ' => 'Fooÿñ' + ); + + return $map; + } + + + function viewsData() { + $data = parent::viewsData(); + $data['views_test']['name']['field']['handler'] = 'views_handler_field_xss'; + + return $data; + } + + public function testFieldXss() { + $view = $this->getBasicView(); + + $view->display['default']->handler->override_option('fields', array( + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + ), + )); + + $this->executeView($view); + + $counter = 0; + foreach ($this->dataHelper() as $input => $expected_result) { + $view->result[$counter]->views_test_name = $input; + $this->assertEqual($view->field['name']->advanced_render($view->result[$counter]), $expected_result); + $counter++; + } + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_filter_date.test b/sites/all/modules/views/tests/handlers/views_handler_filter_date.test new file mode 100644 index 0000000000000000000000000000000000000000..7eaee58fa193a0f517a281811aa0cb34dd2eab33 --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_filter_date.test @@ -0,0 +1,186 @@ +<?php +// $Id: views_handler_filter_date.test,v 1.1.4.3 2010/11/25 20:07:44 dereine Exp $ + +/** + * Tests the handler filter_date. + * + * @TODO + * Convert to "beatles". + */ +class ViewsHandlerFilterDateTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Filter: Date', + 'description' => 'Test the core views_handler_filter_date handler.', + 'group' => 'Views Handlers', + ); + } + + function setUp() { + parent::setUp(); + // Add some basic test nodes. + $this->nodes = array(); + $this->nodes[] = $this->drupalCreateNode(array('created' => 100000)); + $this->nodes[] = $this->drupalCreateNode(array('created' => 200000)); + $this->nodes[] = $this->drupalCreateNode(array('created' => 300000)); + $this->nodes[] = $this->drupalCreateNode(array('created' => time() + 86400)); + + $this->map = array( + 'nid' => 'nid', + ); + $this->enableViewsUi(); + } + + /** + /* Test the general offset functionality. + */ + function testOffset() { + $view = $this->views_test_offset(); + // Test offset for simple operator. + $view->set_display('default'); + $view->init_handlers(); + $view->filter['created']->operator = '>'; + $view->filter['created']->value['type'] = 'offset'; + $view->filter['created']->value['value'] = '+1 hour'; + $view->execute_display('default'); + $expected_result = array( + array('nid' => $this->nodes[3]->nid), + ); + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->delete(); + + // Test offset for between operator. + $view->set_display('default'); + $view->init_handlers(); + $view->filter['created']->operator = 'between'; + $view->filter['created']->value['type'] = 'offset'; + $view->filter['created']->value['max'] = '+2 days'; + $view->filter['created']->value['min'] = '+1 hour'; + $view->execute_display('default'); + $expected_result = array( + array('nid' => $this->nodes[3]->nid), + ); + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->delete(); + } + + + /** + * Test the filter operator between/not between. + */ + function testBetween() { + // Test between with min and max. + $view = $this->views_test_between(); + $view->set_display('default'); + $view->init_handlers(); + $view->filter['created']->operator = 'between'; + $view->filter['created']->value['min'] = format_date(150000, 'custom', 'Y-m-d H:s'); + $view->filter['created']->value['max'] = format_date(250000, 'custom', 'Y-m-d H:s'); + $view->execute_display('default'); + $expected_result = array( + array('nid' => $this->nodes[1]->nid), + ); + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->delete(); + + // Test between with just min. + $view = $this->views_test_between(); + $view->set_display('default'); + $view->init_handlers(); + $view->filter['created']->operator = 'between'; + $view->filter['created']->value['max'] = format_date(250000, 'custom', 'Y-m-d H:s'); + $view->execute_display('default'); + $expected_result = array( + array('nid' => $this->nodes[0]->nid), + array('nid' => $this->nodes[1]->nid), + ); + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->delete(); + + // Test not between with min and max. + $view = $this->views_test_between(); + $view->set_display('default'); + $view->init_handlers(); + $view->filter['created']->operator = 'not between'; + $view->filter['created']->value['min'] = format_date(150000, 'custom', 'Y-m-d H:s'); + $view->filter['created']->value['max'] = format_date(250000, 'custom', 'Y-m-d H:s'); + $view->execute_display('default'); + $expected_result = array( + array('nid' => $this->nodes[0]->nid), + array('nid' => $this->nodes[2]->nid), + array('nid' => $this->nodes[3]->nid), + ); + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->delete(); + + // Test not between with min. + $view = $this->views_test_between(); + $view->set_display('default'); + $view->init_handlers(); + $view->filter['created']->operator = 'not between'; + $view->filter['created']->value['max'] = format_date(150000, 'custom', 'Y-m-d H:s'); + $view->execute_display('default'); + $expected_result = array( + array('nid' => $this->nodes[1]->nid), + array('nid' => $this->nodes[2]->nid), + array('nid' => $this->nodes[3]->nid), + ); + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->delete(); + } + + /** + * Take sure the validation callbacks works. + */ + function testUiValidation() { + $view = $this->views_test_between(); + $view->save(); + + $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); + $this->drupalLogin($admin_user); + menu_rebuild(); + $this->drupalGet('admin/structure/views/edit/test_filter_date_between'); + $this->drupalGet('admin/structure/views/nojs/config-item/test_filter_date_between/default/filter/created'); + + $edit = array(); + // Generate a definitive wrong value, which should be checked by validation. + $edit['options[value][value]'] = $this->randomString() . '-------'; + $this->drupalPost(NULL, $edit, t('Update')); + $this->assertText(t('Invalid date format.'), 'Take sure that validation is runned and the invalidate date format is identified.'); + } + + function views_test_between() { + $view = new view; + $view->name = 'test_filter_date_between'; + $view->description = ''; + $view->tag = ''; + $view->base_table = 'node'; + $view->api_version = '3.0-alpha1'; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['query']['type'] = 'views_query'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Node: Nid */ + $handler->display->display_options['fields']['nid']['id'] = 'nid'; + $handler->display->display_options['fields']['nid']['table'] = 'node'; + $handler->display->display_options['fields']['nid']['field'] = 'nid'; + /* Filter: Node: Updated date */ + $handler->display->display_options['filters']['created']['id'] = 'created'; + $handler->display->display_options['filters']['created']['table'] = 'node'; + $handler->display->display_options['filters']['created']['field'] = 'created'; + + return $view; + } + + function views_test_offset() { + $view = $this->views_test_between(); + return $view; + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_filter_equality.test b/sites/all/modules/views/tests/handlers/views_handler_filter_equality.test new file mode 100644 index 0000000000000000000000000000000000000000..769e091a70128d3b088c6b0ec4e79aa51b27dac9 --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_filter_equality.test @@ -0,0 +1,83 @@ +<?php +// $Id: views_handler_filter_equality.test,v 1.1.2.1 2010/12/26 22:41:40 dereine Exp $ + +class viewsHandlerFilterEqualityTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Filter: Equality', + 'description' => 'Test the core views_handler_filter_equality handler.', + 'group' => 'Views Handlers', + ); + } + + function setUp() { + parent::setUp(); + $this->column_map = array( + 'views_test_name' => 'name', + ); + } + + function viewsData() { + $data = parent::viewsData(); + $data['views_test']['name']['filter']['handler'] = 'views_handler_filter_equality'; + + return $data; + } + + function testEqual() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + 'operator' => '=', + 'value' => array('value' => 'Ringo'), + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'Ringo', + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + + function testNotEqual() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + 'operator' => '!=', + 'value' => array('value' => 'Ringo'), + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'John', + ), + array( + 'name' => 'George', + ), + array( + 'name' => 'Paul', + ), + array( + 'name' => 'Meredith', + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_filter_in_operator.test b/sites/all/modules/views/tests/handlers/views_handler_filter_in_operator.test new file mode 100644 index 0000000000000000000000000000000000000000..c78e031f2f10372329d6e7138dcb7f00eba91738 --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_filter_in_operator.test @@ -0,0 +1,90 @@ +<?php +// $Id: views_handler_filter_in_operator.test,v 1.1.2.1 2010/11/07 11:32:25 dereine Exp $ + +class ViewsHandlerFilterInOperator extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Filter: in_operator', + 'description' => 'Test the core views_handler_filter_in_operator handler.', + 'group' => 'Views Handlers', + ); + } + + function viewsData() { + $data = parent::viewsData(); + $data['views_test']['age']['filter']['handler'] = 'views_handler_filter_in_operator'; + + return $data; + } + + public function testFilterInOperatorSimple() { + $view = $this->getBasicView(); + + // Add a in_operator ordering. + $view->display['default']->handler->override_option('filters', array( + 'age' => array( + 'id' => 'age', + 'field' => 'age', + 'table' => 'views_test', + 'value' => array(26, 30), + 'operator' => 'in', + ), + )); + + $this->executeView($view); + + $expected_result = array( + array( + 'name' => 'Paul', + 'age' => 26, + ), + array( + 'name' => 'Meredith', + 'age' => 30, + ), + ); + + $this->assertEqual(2, count($view->result)); + $this->assertIdenticalResultset($view, $expected_result, array( + 'views_test_name' => 'name', + 'views_test_age' => 'age', + )); + + $view->delete(); + $view = $this->getBasicView(); + + // Add a in_operator ordering. + $view->display['default']->handler->override_option('filters', array( + 'age' => array( + 'id' => 'age', + 'field' => 'age', + 'table' => 'views_test', + 'value' => array(26, 30), + 'operator' => 'not in', + ), + )); + + $this->executeView($view); + + $expected_result = array( + array( + 'name' => 'John', + 'age' => 25, + ), + array( + 'name' => 'George', + 'age' => 27, + ), + array( + 'name' => 'Ringo', + 'age' => 28, + ), + ); + + $this->assertEqual(3, count($view->result)); + $this->assertIdenticalResultset($view, $expected_result, array( + 'views_test_name' => 'name', + 'views_test_age' => 'age', + )); + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_filter_numeric.test b/sites/all/modules/views/tests/handlers/views_handler_filter_numeric.test new file mode 100644 index 0000000000000000000000000000000000000000..05187d4e7fb204fa270c41309b30a79e9f1609e1 --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_filter_numeric.test @@ -0,0 +1,216 @@ +<?php +// $Id: views_handler_filter_numeric.test,v 1.1.2.1 2010/11/06 14:31:59 dereine Exp $ + +class viewsHandlerFilterNumericTest extends ViewsSqlTest { + var $column_map = array(); + + public static function getInfo() { + return array( + 'name' => 'Handlers: filter_numeric', + 'description' => 'Tests the numeric filter handler', + 'group' => 'Views Handlers', + ); + } + + function setUp() { + parent::setUp(); + $this->column_map = array( + 'views_test_name' => 'name', + 'views_test_age' => 'age', + ); + } + + function viewsData() { + $data = parent::viewsData(); + $data['views_test']['age']['filter']['allow empty'] = TRUE; + $data['views_test']['id']['filter']['allow empty'] = FALSE; + + return $data; + } + + public function testFilterNumericSimple() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'age' => array( + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + 'relationship' => 'none', + 'operator' => '=', + 'value' => array('value' => 28), + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'Ringo', + 'age' => 28, + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + + public function testFilterNumericBetween() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'age' => array( + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + 'relationship' => 'none', + 'operator' => 'between', + 'value' => array( + 'min' => 26, + 'max' => 29, + ), + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'George', + 'age' => 27, + ), + array( + 'name' => 'Ringo', + 'age' => 28, + ), + array( + 'name' => 'Paul', + 'age' => 26, + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + + // test not between + $view->delete(); + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'age' => array( + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + 'relationship' => 'none', + 'operator' => 'not between', + 'value' => array( + 'min' => 26, + 'max' => 29, + ), + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'John', + 'age' => 25, + ), + array( + 'name' => 'Paul', + 'age' => 26, + ), + array( + 'name' => 'Meredith', + 'age' => 30, + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + + public function testFilterNumericEmpty() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'age' => array( + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + 'relationship' => 'none', + 'operator' => 'empty', + ), + )); + + $this->executeView($view); + $resultset = array( + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + + $view->delete(); + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'age' => array( + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + 'relationship' => 'none', + 'operator' => 'not empty', + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'John', + 'age' => 25, + ), + array( + 'name' => 'George', + 'age' => 27, + ), + array( + 'name' => 'Ringo', + 'age' => 28, + ), + array( + 'name' => 'Paul', + 'age' => 26, + ), + array( + 'name' => 'Meredith', + 'age' => 30, + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + + public function testAllowEmpty() { + $view = $this->getBasicView(); + + $view->display['default']->handler->override_option('filters', array( + 'id' => array( + 'id' => 'id', + 'table' => 'views_test', + 'field' => 'id', + 'relationship' => 'none', + ), + 'age' => array( + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + 'relationship' => 'none', + ), + )); + + $view->set_display('default'); + $view->init_handlers(); + + $id_operators = $view->filter['id']->operators(); + $age_operators = $view->filter['age']->operators(); + + $this->assertFalse(isset($id_operators['empty'])); + $this->assertFalse(isset($id_operators['not empty'])); + $this->assertTrue(isset($age_operators['empty'])); + $this->assertTrue(isset($age_operators['not empty'])); + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_filter_string.test b/sites/all/modules/views/tests/handlers/views_handler_filter_string.test new file mode 100644 index 0000000000000000000000000000000000000000..b5491f1852745e61ef3d3dbc5aa1721fc63cdab9 --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_filter_string.test @@ -0,0 +1,406 @@ +<?php +// $Id: views_handler_filter_string.test,v 1.1.2.1 2010/12/27 22:06:04 dereine Exp $ + +class viewsHandlerFilterStringTest extends ViewsSqlTest { + var $column_map = array(); + + public static function getInfo() { + return array( + 'name' => 'Filter: String', + 'description' => 'Tests the core views_handler_filter_string handler.', + 'group' => 'Views Handlers', + ); + } + + function setUp() { + parent::setUp(); + $this->column_map = array( + 'views_test_name' => 'name', + ); + } + + function viewsData() { + $data = parent::viewsData(); + $data['views_test']['name']['filter']['allow empty'] = TRUE; + $data['views_test']['job']['filter']['allow empty'] = FALSE; + $data['views_test']['description'] = $data['views_test']['name']; + + return $data; + } + + protected function schemaDefinition() { + $schema = parent::schemaDefinition(); + $schema['views_test']['fields']['description'] = array( + 'description' => "A person's description", + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + ); + + return $schema; + } + + /** + * A extended test dataset. + */ + protected function dataSet() { + $dataset = parent::dataSet(); + $dataset[0]['description'] = 'John Winston Ono Lennon, MBE (9 October 1940 – 8 December 1980) was an English musician and singer-songwriter who rose to worldwide fame as one of the founding members of The Beatles, one of the most commercially successful and critically acclaimed acts in the history of popular music. Along with fellow Beatle Paul McCartney, he formed one of the most successful songwriting partnerships of the 20th century.'; + $dataset[1]['description'] = 'George Harrison,[1] MBE (25 February 1943 – 29 November 2001)[2] was an English rock guitarist, singer-songwriter, actor and film producer who achieved international fame as lead guitarist of The Beatles.'; + $dataset[2]['description'] = 'Richard Starkey, MBE (born 7 July 1940), better known by his stage name Ringo Starr, is an English musician, singer-songwriter, and actor who gained worldwide fame as the drummer for The Beatles.'; + $dataset[3]['description'] = 'Sir James Paul McCartney, MBE (born 18 June 1942) is an English musician, singer-songwriter and composer. Formerly of The Beatles (1960–1970) and Wings (1971–1981), McCartney is the most commercially successful songwriter in the history of popular music, according to Guinness World Records.[1]'; + $dataset[4]['description'] = NULL; + + return $dataset; + } + + protected function getBasicView() { + $view = parent::getBasicView(); + $view->display['default']->options['fields']['description'] = array( + 'id' => 'description', + 'table' => 'views_test', + 'field' => 'description', + 'relationship' => 'none', + ); + return $view; + } + + function testFilterStringEqual() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + 'operator' => '=', + 'value' => 'Ringo', + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'Ringo', + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + $view->destroy(); + + + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + 'operator' => '!=', + 'value' => array('value' => 'Ringo'), + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'John', + ), + array( + 'name' => 'George', + ), + array( + 'name' => 'Paul', + ), + array( + 'name' => 'Meredith', + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + + function testFilterStringContains() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + 'operator' => 'contains', + 'value' => 'ing', + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'Ringo', + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + + function testFilterStringWord() { + return; + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'description' => array( + 'id' => 'description', + 'table' => 'views_test', + 'field' => 'description', + 'relationship' => 'none', + 'operator' => 'word', + 'value' => 'musician producer', + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'Ringo', + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + $view->destroy(); + + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'description' => array( + 'id' => 'description', + 'table' => 'views_test', + 'field' => 'description', + 'relationship' => 'none', + 'operator' => 'allwords', + 'value' => 'Richard Starkey', + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'Ringo', + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + function testFilterStringStarts() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'description' => array( + 'id' => 'description', + 'table' => 'views_test', + 'field' => 'description', + 'relationship' => 'none', + 'operator' => 'starts', + 'value' => 'George', + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'George', + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + function testFilterStringNotStarts() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'description' => array( + 'id' => 'description', + 'table' => 'views_test', + 'field' => 'description', + 'relationship' => 'none', + 'operator' => 'not_starts', + 'value' => 'George', + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'John', + ), + array( + 'name' => 'Ringo', + ), + array( + 'name' => 'Paul', + ), + // There is no Meredith returned because his description is empty + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + + function testFilterStringEnds() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'description' => array( + 'id' => 'description', + 'table' => 'views_test', + 'field' => 'description', + 'relationship' => 'none', + 'operator' => 'ends', + 'value' => 'Beatles.', + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'George', + ), + array( + 'name' => 'Ringo', + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + + function testFilterStringNotEnds() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'description' => array( + 'id' => 'description', + 'table' => 'views_test', + 'field' => 'description', + 'relationship' => 'none', + 'operator' => 'not_ends', + 'value' => 'Beatles.', + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'John', + ), + array( + 'name' => 'Paul', + ), + // There is no Meredith returned because his description is empty + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + + function testFilterStringNot() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'description' => array( + 'id' => 'description', + 'table' => 'views_test', + 'field' => 'description', + 'relationship' => 'none', + 'operator' => 'not', + 'value' => 'Beatles.', + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'John', + ), + array( + 'name' => 'Paul', + ), + // There is no Meredith returned because his description is empty + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + + function testFilterStringShorter() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + 'operator' => 'shorterthan', + 'value' => 5, + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'John', + ), + array( + 'name' => 'Paul', + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + + function testFilterStringLonger() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + 'operator' => 'longerthan', + 'value' => 7, + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'Meredith', + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } + + function testFilterStringEmpty() { + $view = $this->getBasicView(); + + // Change the filtering + $view->display['default']->handler->override_option('filters', array( + 'description' => array( + 'id' => 'description', + 'table' => 'views_test', + 'field' => 'description', + 'relationship' => 'none', + 'operator' => 'empty', + ), + )); + + $this->executeView($view); + $resultset = array( + array( + 'name' => 'Meredith', + ), + ); + $this->assertIdenticalResultset($view, $resultset, $this->column_map); + } +} \ No newline at end of file diff --git a/sites/all/modules/views/tests/handlers/views_handler_sort.test b/sites/all/modules/views/tests/handlers/views_handler_sort.test new file mode 100644 index 0000000000000000000000000000000000000000..e7410000ae871c84ee1f4f4b4dfbef248f88cf6a --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_sort.test @@ -0,0 +1,117 @@ +<?php +// $Id: views_handler_sort.test,v 1.1.2.1 2010/11/07 11:32:25 dereine Exp $ + +/** + * Test for core views_handler_sort handler. + */ +class ViewsHandlerSortTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => t('Sort: generic'), + 'description' => t('Test the core views_handler_sort handler.'), + 'group' => t('Views Handlers'), + ); + } + + /** + * Test numeric ordering of the result set. + */ + public function testNumericOrdering() { + $view = $this->getBasicView(); + + // Change the ordering + $view->display['default']->handler->override_option('sorts', array( + 'age' => array( + 'order' => 'ASC', + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + 'relationship' => 'none', + ), + )); + + // Execute the view. + $this->executeView($view); + + // Verify the result. + $this->assertEqual(count($this->dataSet()), count($view->result), t('The number of returned rows match.')); + $this->assertIdenticalResultset($view, $this->orderResultSet($this->dataSet(), 'age'), array( + 'views_test_name' => 'name', + 'views_test_age' => 'age', + )); + + $view = $this->getBasicView(); + + // Reverse the ordering + $view->display['default']->handler->override_option('sorts', array( + 'age' => array( + 'order' => 'DESC', + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + 'relationship' => 'none', + ), + )); + + // Execute the view. + $this->executeView($view); + + // Verify the result. + $this->assertEqual(count($this->dataSet()), count($view->result), t('The number of returned rows match.')); + $this->assertIdenticalResultset($view, $this->orderResultSet($this->dataSet(), 'age', TRUE), array( + 'views_test_name' => 'name', + 'views_test_age' => 'age', + )); + } + + /** + * Test string ordering of the result set. + */ + public function testStringOrdering() { + $view = $this->getBasicView(); + + // Change the ordering + $view->display['default']->handler->override_option('sorts', array( + 'name' => array( + 'order' => 'ASC', + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + ), + )); + + // Execute the view. + $this->executeView($view); + + // Verify the result. + $this->assertEqual(count($this->dataSet()), count($view->result), t('The number of returned rows match.')); + $this->assertIdenticalResultset($view, $this->orderResultSet($this->dataSet(), 'name'), array( + 'views_test_name' => 'name', + 'views_test_age' => 'age', + )); + + $view = $this->getBasicView(); + + // Reverse the ordering + $view->display['default']->handler->override_option('sorts', array( + 'name' => array( + 'order' => 'DESC', + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + ), + )); + + // Execute the view. + $this->executeView($view); + + // Verify the result. + $this->assertEqual(count($this->dataSet()), count($view->result), t('The number of returned rows match.')); + $this->assertIdenticalResultset($view, $this->orderResultSet($this->dataSet(), 'name', TRUE), array( + 'views_test_name' => 'name', + 'views_test_age' => 'age', + )); + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_sort_date.test b/sites/all/modules/views/tests/handlers/views_handler_sort_date.test new file mode 100644 index 0000000000000000000000000000000000000000..7f341ac717c224cba5f57c3191da5ace7f26842c --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_sort_date.test @@ -0,0 +1,89 @@ +<?php +// $Id: views_handler_sort_date.test,v 1.1.2.1 2010/11/07 11:32:25 dereine Exp $ + +/** + * Test for core views_handler_sort_date handler. + */ +class ViewsHandlerSortDateTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => t('Sort: date'), + 'description' => t('Test the core views_handler_sort_date handler.'), + 'group' => t('Views Handlers'), + ); + } + + protected function orderResultSetDate($result_set, $column, $granularity, $reverse = TRUE) { + // Build a technical sort column. + foreach ($result_set as &$result) { + $result['_sort'] = $this->orderResultSetDateHelper($result[$column], $granularity); + } + return $this->orderResultSet($result_set, '_sort', $reverse); + } + + protected function orderResultSetDateHelper($date, $granularity) { + switch ('granularity') { + case 'second': + default: + return $date; + case 'minute': + return date('YmdHi', $date); + case 'hour': + return date('YmdH', $date); + case 'day': + return date('Ymd', $date); + case 'month': + return date('Ym', $date); + case 'year': + return date('Y', $date); + } + } + + /** + * Test numeric ordering of the result set. + */ + public function testDateOrdering() { + foreach (array('second', 'minute', 'hour', 'day', 'month', 'year') as $granularity) { + foreach (array(FALSE, TRUE) as $reverse) { + $view = $this->getBasicView(); + + // Change the fields. + $view->display['default']->handler->override_option('fields', array( + 'id' => array( + 'id' => 'id', + 'table' => 'views_test', + 'field' => 'id', + 'relationship' => 'none', + ), + 'created' => array( + 'id' => 'created', + 'table' => 'views_test', + 'field' => 'created', + 'relationship' => 'none', + ), + )); + + // Change the ordering + $view->display['default']->handler->override_option('sorts', array( + 'created' => array( + 'id' => 'created', + 'table' => 'views_test', + 'field' => 'created', + 'relationship' => 'none', + 'granularity' => 'second', + 'order' => $reverse ? 'DESC' : 'ASC', + ), + )); + + // Execute the view. + $this->executeView($view); + + // Verify the result. + $this->assertEqual(count($this->dataSet()), count($view->result), t('The number of returned rows match.')); + $this->assertIdenticalResultset($view, $this->orderResultSetDate($this->dataSet(), 'created', $granularity, $reverse), array( + 'views_test_created' => 'created', + ), t('Result is returned correctly when ordering by granularity @granularity, @reverse.', array('@granularity' => $granularity, '@reverse' => $reverse ? t('reverse') : t('forward')))); + } + } + } +} diff --git a/sites/all/modules/views/tests/handlers/views_handler_sort_random.test b/sites/all/modules/views/tests/handlers/views_handler_sort_random.test new file mode 100644 index 0000000000000000000000000000000000000000..a38a361a3129e5594cd7269eec55c8c40ccc894c --- /dev/null +++ b/sites/all/modules/views/tests/handlers/views_handler_sort_random.test @@ -0,0 +1,85 @@ +<?php +// $Id: views_handler_sort_random.test,v 1.1.2.1 2010/11/07 11:32:25 dereine Exp $ + +/** + * Test for core views_handler_sort_random handler. + */ +class ViewsHandlerSortRandomTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => t('Sort: random'), + 'description' => t('Test the core views_handler_sort_random handler.'), + 'group' => t('Views Handlers'), + ); + } + + /** + * Add more items to the test set, to make the order tests more robust. + */ + protected function dataSet() { + $data = parent::dataSet(); + for ($i = 0; $i < 50; $i++) { + $data[] = array( + 'name' => 'name_' . $i, + 'age' => $i, + 'job' => 'job_' . $i, + 'created' => rand(0, time()), + ); + } + return $data; + } + + /** + * Return a basic view with random ordering. + */ + protected function getBasicRandomView() { + $view = $this->getBasicView(); + + // Add a random ordering. + $view->display['default']->handler->override_option('sorts', array( + 'random' => array( + 'id' => 'random', + 'field' => 'random', + 'table' => 'views', + ), + )); + + return $view; + } + + /** + * Test random ordering of the result set. + * + * @see DatabaseSelectTestCase::testRandomOrder(). + */ + public function testRandomOrdering() { + // Execute a basic view first. + $view = $this->getBasicView(); + $this->executeView($view); + + // Verify the result. + $this->assertEqual(count($this->dataSet()), count($view->result), t('The number of returned rows match.')); + $this->assertIdenticalResultset($view, $this->dataSet(), array( + 'views_test_name' => 'name', + 'views_test_age' => 'age', + )); + + // Execute a random view, we expect the result set to be different. + $view_random = $this->getBasicRandomView(); + $this->executeView($view_random); + $this->assertEqual(count($this->dataSet()), count($view_random->result), t('The number of returned rows match.')); + $this->assertNotIdenticalResultset($view_random, $view->result, array( + 'views_test_name' => 'views_test_name', + 'views_test_age' => 'views_test_name', + )); + + // Execute a second random view, we expect the result set to be different again. + $view_random_2 = $this->getBasicRandomView(); + $this->executeView($view_random_2); + $this->assertEqual(count($this->dataSet()), count($view_random_2->result), t('The number of returned rows match.')); + $this->assertNotIdenticalResultset($view_random, $view->result, array( + 'views_test_name' => 'views_test_name', + 'views_test_age' => 'views_test_name', + )); + } +} diff --git a/sites/all/modules/views/tests/user/views_user_argument_default.test b/sites/all/modules/views/tests/user/views_user_argument_default.test new file mode 100644 index 0000000000000000000000000000000000000000..3a57a956d69b39648721da2eae9925aaecde95b0 --- /dev/null +++ b/sites/all/modules/views/tests/user/views_user_argument_default.test @@ -0,0 +1,87 @@ +<?php +// $Id: views_user_argument_default.test,v 1.1.4.4 2010/11/13 17:53:07 dereine Exp $ +/** + * @file + * Tests views user argument default plugin. + */ + +class viewsUserArgumentDefault extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Tests user argument default plugin', + 'description' => 'Tests user argument default plugin', + 'group' => 'Views Plugins', + ); + } + + public function test_plugin_argument_default_current_user() { + // Create a user to test. + $account = $this->drupalCreateUser(); + + // Switch the user, we have to check the global user too, because drupalLogin is only for the simpletest browser. + $this->drupalLogin($account); + global $user; + $admin = $user; + drupal_save_session(FALSE); + $user = $account; + + $view = $this->view_plugin_argument_default_current_user(); + + $view->set_display('default'); + $view->pre_execute(); + $view->init_handlers(); + + $this->assertEqual($view->argument['null']->get_default_argument(), $account->uid, 'Uid of the current user is used.'); + // Switch back. + $user = $admin; + drupal_save_session(TRUE); + } + + function view_plugin_argument_default_current_user() { + $view = new view; + $view->name = 'test_plugin_argument_default_current_user'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = '3.0-alpha1'; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['pager']['options']['items_per_page'] = '10'; + $handler->display->display_options['pager']['options']['offset'] = '0'; + $handler->display->display_options['pager']['options']['id'] = '0'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Node: Title */ + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['title']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['title']['alter']['trim'] = 0; + $handler->display->display_options['fields']['title']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['title']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['title']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['title']['alter']['html'] = 0; + $handler->display->display_options['fields']['title']['hide_empty'] = 0; + $handler->display->display_options['fields']['title']['empty_zero'] = 0; + $handler->display->display_options['fields']['title']['link_to_node'] = 0; + /* Argument: Global: Null */ + $handler->display->display_options['arguments']['null']['id'] = 'null'; + $handler->display->display_options['arguments']['null']['table'] = 'views'; + $handler->display->display_options['arguments']['null']['field'] = 'null'; + $handler->display->display_options['arguments']['null']['default_action'] = 'default'; + $handler->display->display_options['arguments']['null']['style_plugin'] = 'default_summary'; + $handler->display->display_options['arguments']['null']['default_argument_type'] = 'current_user'; + $handler->display->display_options['arguments']['null']['must_not_be'] = 0; + + return $view; + } +} diff --git a/sites/all/modules/views/tests/user/views_user_argument_validate.test b/sites/all/modules/views/tests/user/views_user_argument_validate.test new file mode 100644 index 0000000000000000000000000000000000000000..46fb81e9d35853b495ac30d4e0ce5e00fec6873e --- /dev/null +++ b/sites/all/modules/views/tests/user/views_user_argument_validate.test @@ -0,0 +1,114 @@ +<?php +// $Id +/** + * @file + * Tests views user argument argument handler. + */ + +module_load_include('test', 'views', 'tests/views_query'); + +class viewsUserArgumentValidate extends viewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Tests user argument validator', + 'description' => 'Tests user argument validator', + 'group' => 'Views Plugins', + ); + } + + function setUp() { + parent::setUp('views'); + $this->account = $this->drupalCreateUser(); + } + + function testArgumentValidateUserUid() { + $account = $this->account; + // test 'uid' case + $view = $this->view_argument_validate_user('uid'); + $view->set_display('default'); + $view->pre_execute(); + $view->init_handlers(); + $this->assertTrue($view->argument['null']->validate_arg($account->uid)); + // Reset safed argument validation. + $view->argument['null']->argument_validated = NULL; + // Fail for a string variable since type is 'uid' + $this->assertFalse($view->argument['null']->validate_arg($account->name)); + // Reset safed argument validation. + $view->argument['null']->argument_validated = NULL; + // Fail for a valid numeric, but for a user that doesn't exist + $this->assertFalse($view->argument['null']->validate_arg(32)); + } + + function testArgumentValidateUserName() { + $account = $this->account; + // test 'name' case + $view = $this->view_argument_validate_user('name'); + $view->set_display('default'); + $view->pre_execute(); + $view->init_handlers(); + $this->assertTrue($view->argument['null']->validate_arg($account->name)); + // Reset safed argument validation. + $view->argument['null']->argument_validated = NULL; + // Fail for a uid variable since type is 'name' + $this->assertFalse($view->argument['null']->validate_arg($account->uid)); + // Reset safed argument validation. + $view->argument['null']->argument_validated = NULL; + // Fail for a valid string, but for a user that doesn't exist + $this->assertFalse($view->argument['null']->validate_arg($this->randomName())); + } + + function testArgumentValidateUserEither() { + $account = $this->account; + // test 'either' case + $view = $this->view_argument_validate_user('either'); + $view->set_display('default'); + $view->pre_execute(); + $view->init_handlers(); + $this->assertTrue($view->argument['null']->validate_arg($account->name)); + // Reset safed argument validation. + $view->argument['null']->argument_validated = NULL; + // Fail for a uid variable since type is 'name' + $this->assertTrue($view->argument['null']->validate_arg($account->uid)); + // Reset safed argument validation. + $view->argument['null']->argument_validated = NULL; + // Fail for a valid string, but for a user that doesn't exist + $this->assertFalse($view->argument['null']->validate_arg($this->randomName())); + // Reset safed argument validation. + $view->argument['null']->argument_validated = NULL; + // Fail for a valid uid, but for a user that doesn't exist + $this->assertFalse($view->argument['null']->validate_arg(32)); + } + + function view_argument_validate_user($argtype) { + $view = new view; + $view->name = 'view_argument_validate_user'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Argument: Global: Null */ + $handler->display->display_options['arguments']['null']['id'] = 'null'; + $handler->display->display_options['arguments']['null']['table'] = 'views'; + $handler->display->display_options['arguments']['null']['field'] = 'null'; + $handler->display->display_options['arguments']['null']['style_plugin'] = 'default_summary'; + $handler->display->display_options['arguments']['null']['default_argument_type'] = 'fixed'; + $handler->display->display_options['arguments']['null']['validate_type'] = 'user'; + $handler->display->display_options['arguments']['null']['validate_options']['type'] = $argtype; + $handler->display->display_options['arguments']['null']['must_not_be'] = 0; + + return $view; + } + +} diff --git a/sites/all/modules/views/tests/views_access.test b/sites/all/modules/views/tests/views_access.test new file mode 100644 index 0000000000000000000000000000000000000000..27fcc33063eaf42d5489e7f3ba89aef930b5c23b --- /dev/null +++ b/sites/all/modules/views/tests/views_access.test @@ -0,0 +1,281 @@ +<?php +// $Id: views_access.test,v 1.1.4.6 2011/01/04 21:26:47 dereine Exp $ + +/** + * Basic test for pluggable access. + */ +class ViewsAccessTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => t('Access'), + 'description' => t('Tests pluggable access for views.'), + 'group' => t('Views Plugins') + ); + } + + public function setUp() { + parent::setUp(); + + $this->admin_user = $this->drupalCreateUser(array('access all views')); + $this->web_user = $this->drupalCreateUser(); + $this->web_role = current($this->web_user->roles); + + $this->normal_role = $this->drupalCreateRole(array()); + $this->normal_user = $this->drupalCreateUser(array('views_test test permission')); + $this->normal_user->roles[$this->normal_role] = $this->normal_role; + // Reset the plugin data. + views_fetch_plugin_data(NULL, NULL, TRUE); + } + + function viewsPlugins() { + $plugins = array( + 'access' => array( + 'test_static' => array( + 'title' => t('Static test access plugin'), + 'help' => t('Provides a static test access plugin.'), + 'handler' => 'views_test_plugin_access_test_static', + 'path' => drupal_get_path('module', 'views_test') . '/test_plugins', + ), + 'test_dynamic' => array( + 'title' => t('Dynamic test access plugin'), + 'help' => t('Provides a dynamic test access plugin.'), + 'handler' => 'views_test_plugin_access_test_dynamic', + 'path' => drupal_get_path('module', 'views_test') . '/test_plugins', + ), + ), + ); + + return $plugins; + } + + /** + * Test none access plugin. + */ + function testAccessNone() { + $view = $this->view_access_none(); + + $view->set_display('default'); + + $this->assertTrue($view->display_handler->access($this->admin_user), t('Admin-Account should be able to access the view everytime')); + $this->assertTrue($view->display_handler->access($this->web_user)); + $this->assertTrue($view->display_handler->access($this->normal_user)); + } + + /** + * Test perm access plugin. + */ + function testAccessPerm() { + $view = $this->view_access_perm(); + + $view->set_display('default'); + $access_plugin = $view->display_handler->get_plugin('access'); + + $this->assertTrue($view->display_handler->access($this->admin_user), t('Admin-Account should be able to access the view everytime')); + $this->assertFalse($view->display_handler->access($this->web_user)); + $this->assertTrue($view->display_handler->access($this->normal_user)); + } + + /** + * Test role access plugin. + */ + function testAccessRole() { + $view = $this->view_access_role(); + + $view->set_display('default'); + $access_plugin = $view->display_handler->get_plugin('access'); + + $this->assertTrue($view->display_handler->access($this->admin_user), t('Admin-Account should be able to access the view everytime')); + $this->assertFalse($view->display_handler->access($this->web_user)); + $this->assertTrue($view->display_handler->access($this->normal_user)); + } + + /** + * @todo Test abstract access plugin. + */ + + /** + * Test static access check. + */ + function testStaticAccessPlugin() { + $view = $this->view_access_static(); + + $view->set_display('default'); + $access_plugin = $view->display_handler->get_plugin('access'); + + $this->assertFalse($access_plugin->access($this->normal_user)); + + $access_plugin->options['access'] = TRUE; + $this->assertTrue($access_plugin->access($this->normal_user)); + + // FALSE comes from hook_menu caching. + $expected_hook_menu = array( + 'views_test_test_static_access_callback', array(FALSE) + ); + $hook_menu = $view->execute_hook_menu('page_1'); + $this->assertEqual($expected_hook_menu, $hook_menu['test_access_static']['access arguments'][0]); + + $expected_hook_menu = array( + 'views_test_test_static_access_callback', array(TRUE) + ); + $this->assertTrue(views_access($expected_hook_menu)); + } + + /** + * Test dynamic access plugin. + */ + function testDynamicAccessPlugin() { + $view = $this->view_access_dynamic(); + $argument1 = $this->randomName(); + $argument2 = $this->randomName(); + variable_set('test_dynamic_access_argument1', $argument1); + variable_set('test_dynamic_access_argument2', $argument2); + + $view->set_display('default'); + $access_plugin = $view->display_handler->get_plugin('access'); + + $this->assertFalse($access_plugin->access($this->normal_user)); + + $access_plugin->options['access'] = TRUE; + $this->assertFalse($access_plugin->access($this->normal_user)); + + $view->set_arguments(array($argument1, $argument2)); + $this->assertTrue($access_plugin->access($this->normal_user)); + + // FALSE comes from hook_menu caching. + $expected_hook_menu = array( + 'views_test_test_dynamic_access_callback', array(FALSE, 1, 2) + ); + $hook_menu = $view->execute_hook_menu('page_1'); + $this->assertEqual($expected_hook_menu, $hook_menu['test_access_dynamic']['access arguments'][0]); + + $expected_hook_menu = array( + 'views_test_test_dynamic_access_callback', array(TRUE, 1, 2) + ); + $this->assertTrue(views_access($expected_hook_menu, $argument1, $argument2)); + } + + function view_access_none() { + $view = new view; + $view->name = 'test_access_none'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + + return $view; + } + + function view_access_perm() { + $view = new view; + $view->name = 'test_access_perm'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'perm'; + $handler->display->display_options['access']['perm'] = 'views_test test permission'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + + return $view; + } + + function view_access_role() { + $view = new view; + $view->name = 'test_access_role'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'role'; + $handler->display->display_options['access']['role'] = array( + $this->normal_role => $this->normal_role, + ); + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + + return $view; + } + + function view_access_dynamic() { + $view = new view; + $view->name = 'test_access_dynamic'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'test_dynamic'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + + $handler = $view->new_display('page', 'Page', 'page_1'); + $handler->display->display_options['path'] = 'test_access_dynamic'; + + return $view; + } + + function view_access_static() { + $view = new view; + $view->name = 'test_access_static'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'test_static'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + + $handler = $view->new_display('page', 'Page', 'page_1'); + $handler->display->display_options['path'] = 'test_access_static'; + + return $view; + } +} \ No newline at end of file diff --git a/sites/all/modules/views/tests/views_analyze.test b/sites/all/modules/views/tests/views_analyze.test new file mode 100644 index 0000000000000000000000000000000000000000..31539a37b0fbd3436672cb7b04d7d587c35eb346 --- /dev/null +++ b/sites/all/modules/views/tests/views_analyze.test @@ -0,0 +1,48 @@ +<?php +// $Id: views_analyze.test,v 1.1.2.1 2010/11/20 21:40:58 dereine Exp $ +/** + * @file + * Tests the views analyse system. + */ + +class ViewsAnalyzeTest extends viewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Views Analyze', + 'description' => 'Test the views analyze system.', + 'group' => 'Views', + ); + } + + public function setUp() { + parent::setUp('views_ui'); + module_enable(array('views_ui')); + // @TODO Figure out why it's required to clear the cache here. + views_module_include('views_default.inc', TRUE); + views_get_all_views(TRUE); + menu_rebuild(); + + // Add an admin user will full rights; + $this->admin = $this->drupalCreateUser(array('administer views')); + } + + /** + * Tests that analyse works in general. + */ + function testAnalyseBasic() { + $this->drupalLogin($this->admin); + // Enable the frontpage view and click the analyse button. + $view = views_get_view('frontpage'); + $view->save(); + + $this->drupalGet('admin/structure/views/edit/frontpage'); + $this->helperButtonHasLabel('edit-submit', t('Analyze')); + + // This redirects the user to the form. + $this->drupalPost(NULL, array(), t('Analyze')); + $this->assertText(t('View analysis')); + + // This redirects the user back to the main views edit page. + $this->drupalPost(NULL, array(), t('Ok')); + } +} \ No newline at end of file diff --git a/sites/all/modules/views/tests/views_argument_default.test b/sites/all/modules/views/tests/views_argument_default.test new file mode 100644 index 0000000000000000000000000000000000000000..44f975b298126978f3de437b6482ac54adb6bc72 --- /dev/null +++ b/sites/all/modules/views/tests/views_argument_default.test @@ -0,0 +1,107 @@ +<?php +// $Id: views_argument_default.test,v 1.1.2.3 2010/05/24 19:58:36 dereine Exp $ + +/** +* Basic test for pluggable argument default. +*/ +class ViewsArgumentDefaultTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => t('Argument_default'), + 'description' => t('Tests pluggable argument_default for views.'), + 'group' => t('Views Plugins') + ); + } + + public function setUp() { + parent::setUp('views'); + + $this->random = $this->randomString(); + } + + /** + * Test fixed default argument. + */ + function testArgumentDefaultFixed() { + $view = $this->view_argument_default_fixed(); + + $view->set_display('default'); + $view->execute_display(); + $view->destroy(); + + $this->assertEqual($view->args[0], $this->random, t('Fixed argument should be used by default.')); + + // Take sure that a normal argument provided is used + $view = $this->view_argument_default_fixed(); + + $view->set_display('default'); + $random_string = $this->randomString(); + $view->execute_display('default', array($random_string)); + + $this->assertEqual($view->args[0], $random_string, t('Provided argumetn should be used.')); + } + + /** + * @todo Test php default argument. + */ + function testArgumentDefaultPhp() { + + } + + /** + * @todo Test node default argument. + */ + function testArgumentDefaultNode() { + + } + + function view_argument_default_fixed() { + $view = new view; + $view->name = 'test_argument_default_fixed'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['pager']['options']['items_per_page'] = '10'; + $handler->display->display_options['pager']['options']['offset'] = '0'; + $handler->display->display_options['pager']['options']['id'] = '0'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Node: Title */ + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['title']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['title']['alter']['trim'] = 0; + $handler->display->display_options['fields']['title']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['title']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['title']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['title']['alter']['html'] = 0; + $handler->display->display_options['fields']['title']['hide_empty'] = 0; + $handler->display->display_options['fields']['title']['empty_zero'] = 0; + $handler->display->display_options['fields']['title']['link_to_node'] = 0; + /* Argument: Global: Null */ + $handler->display->display_options['arguments']['null']['id'] = 'null'; + $handler->display->display_options['arguments']['null']['table'] = 'views'; + $handler->display->display_options['arguments']['null']['field'] = 'null'; + $handler->display->display_options['arguments']['null']['default_action'] = 'default'; + $handler->display->display_options['arguments']['null']['style_plugin'] = 'default_summary'; + $handler->display->display_options['arguments']['null']['default_argument_type'] = 'fixed'; + $handler->display->display_options['arguments']['null']['default_argument_options']['argument'] = $this->random; + $handler->display->display_options['arguments']['null']['must_not_be'] = 0; + + return $view; + } +} + diff --git a/sites/all/modules/views/tests/views_argument_validator.test b/sites/all/modules/views/tests/views_argument_validator.test new file mode 100644 index 0000000000000000000000000000000000000000..a046f9d9f8c95604f285be5482c85998bf620236 --- /dev/null +++ b/sites/all/modules/views/tests/views_argument_validator.test @@ -0,0 +1,99 @@ +<?php +// $Id: views_argument_validator.test,v 1.1.4.6 2010/05/24 19:58:36 dereine Exp $ + +class viewsArgumentValidatorTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => t('Argument validator'), + 'group' => t('Views Plugins'), + 'description' => t('Test argument validator tests.'), + ); + } + + function testArgumentValidatePhp() { + $string = $this->randomName(); + $view = $this->view_test_argument_validate_php($string); + $view->set_display('default'); + $view->pre_execute(); + $view->init_handlers(); + $this->assertTrue($view->argument['null']->validate_arg($string)); + // Reset safed argument validation. + $view->argument['null']->argument_validated = NULL; + $this->assertFalse($view->argument['null']->validate_arg($this->randomName())); + } + + function testArgumentValidateNumeric() { + $view = $this->view_argument_validate_numeric(); + $view->set_display('default'); + $view->pre_execute(); + $view->init_handlers(); + $this->assertFalse($view->argument['null']->validate_arg($this->randomString())); + // Reset safed argument validation. + $view->argument['null']->argument_validated = NULL; + $this->assertTrue($view->argument['null']->validate_arg(12)); + } + + function view_test_argument_validate_php($string) { + $code = 'return $argument == \''. $string .'\';'; + $view = new view; + $view->name = 'view_argument_validate_numeric'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Argument: Global: Null */ + $handler->display->display_options['arguments']['null']['id'] = 'null'; + $handler->display->display_options['arguments']['null']['table'] = 'views'; + $handler->display->display_options['arguments']['null']['field'] = 'null'; + $handler->display->display_options['arguments']['null']['style_plugin'] = 'default_summary'; + $handler->display->display_options['arguments']['null']['default_argument_type'] = 'fixed'; + $handler->display->display_options['arguments']['null']['validate_type'] = 'php'; + $handler->display->display_options['arguments']['null']['validate_options']['code'] = $code; + $handler->display->display_options['arguments']['null']['must_not_be'] = 0; + + return $view; + } + + function view_argument_validate_numeric() { + $view = new view; + $view->name = 'view_argument_validate_numeric'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Argument: Global: Null */ + $handler->display->display_options['arguments']['null']['id'] = 'null'; + $handler->display->display_options['arguments']['null']['table'] = 'views'; + $handler->display->display_options['arguments']['null']['field'] = 'null'; + $handler->display->display_options['arguments']['null']['style_plugin'] = 'default_summary'; + $handler->display->display_options['arguments']['null']['default_argument_type'] = 'fixed'; + $handler->display->display_options['arguments']['null']['validate_type'] = 'numeric'; + $handler->display->display_options['arguments']['null']['must_not_be'] = 0; + + return $view; + } +} diff --git a/sites/all/modules/views/tests/views_basic.test b/sites/all/modules/views/tests/views_basic.test new file mode 100644 index 0000000000000000000000000000000000000000..61187d6005aa4463874ddccb322f653014c51c52 --- /dev/null +++ b/sites/all/modules/views/tests/views_basic.test @@ -0,0 +1,174 @@ +<?php +// $Id: views_basic.test,v 1.1.4.4 2010/05/24 11:18:18 dereine Exp $ + +/** + * Basic test class for Views query builder tests. + */ +class ViewsBasicTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => t('Basic query test'), + 'description' => t('A basic query test for Views.'), + 'group' => t('Views') + ); + } + + /** + * Test a trivial result set. + */ + public function testSimpleResultSet() { + $view = $this->getBasicView(); + + // Execute the view. + $view->execute(); + + // Verify the result. + $this->assertEqual(5, count($view->result), t('The number of returned rows match.')); + $this->assertIdenticalResultset($view, $this->dataSet(), array( + 'views_test_name' => 'name', + 'views_test_age' => 'age', + )); + } + + /** + * Test filtering of the result set. + */ + public function testSimpleFiltering() { + $view = $this->getBasicView(); + + // Add a filter. + $view->display['default']->handler->override_option('filters', array( + 'age' => array( + 'operator' => '<', + 'value' => array( + 'value' => '28', + 'min' => '', + 'max' => '', + ), + 'group' => '0', + 'exposed' => FALSE, + 'expose' => array( + 'operator' => FALSE, + 'label' => '', + ), + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + 'relationship' => 'none', + ), + )); + + // Execute the view. + $view->execute(); + + // Build the expected result. + $dataset = array( + array( + 'id' => 1, + 'name' => 'John', + 'age' => 25, + ), + array( + 'id' => 2, + 'name' => 'George', + 'age' => 27, + ), + array( + 'id' => 4, + 'name' => 'Paul', + 'age' => 26, + ), + ); + + // Verify the result. + $this->assertEqual(3, count($view->result), t('The number of returned rows match.')); + $this->assertIdenticalResultSet($view, $dataset, array( + 'views_test_name' => 'name', + 'views_test_age' => 'age', + )); + } + + /** + * Test simple argument. + */ + public function testSimpleArgument() { + $view = $this->getBasicView(); + + // Add a argument. + $view->display['default']->handler->override_option('arguments', array( + 'age' => array( + 'default_action' => 'ignore', + 'style_plugin' => 'default_summary', + 'style_options' => array(), + 'wildcard' => 'all', + 'wildcard_substitution' => 'All', + 'title' => '', + 'breadcrumb' => '', + 'default_argument_type' => 'fixed', + 'default_argument' => '', + 'validate_type' => 'none', + 'validate_fail' => 'not found', + 'break_phrase' => 0, + 'not' => 0, + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + 'validate_user_argument_type' => 'uid', + 'validate_user_roles' => array( + '2' => 0, + ), + 'relationship' => 'none', + 'default_options_div_prefix' => '', + 'default_argument_user' => 0, + 'default_argument_fixed' => '', + 'default_argument_php' => '', + 'validate_argument_node_type' => array( + 'page' => 0, + 'story' => 0, + ), + 'validate_argument_node_access' => 0, + 'validate_argument_nid_type' => 'nid', + 'validate_argument_vocabulary' => array(), + 'validate_argument_type' => 'tid', + 'validate_argument_transform' => 0, + 'validate_user_restrict_roles' => 0, + 'validate_argument_php' => '', + ) + )); + + $saved_view = clone $view; + + // Execute with a view + $view->set_arguments(array(27)); + $view->execute(); + + // Build the expected result. + $dataset = array( + array( + 'id' => 2, + 'name' => 'George', + 'age' => 27, + ), + ); + + // Verify the result. + $this->assertEqual(1, count($view->result), t('The number of returned rows match.')); + $this->assertIdenticalResultSet($view, $dataset, array( + 'views_test_name' => 'name', + 'views_test_age' => 'age', + )); + + // Test "show all" if no argument is present. + $view = $saved_view; + $view->execute(); + + // Build the expected result. + $dataset = $this->dataSet(); + + $this->assertEqual(5, count($view->result), t('The number of returned rows match.')); + $this->assertIdenticalResultSet($view, $dataset, array( + 'views_test_name' => 'name', + 'views_test_age' => 'age', + )); + } +} diff --git a/sites/all/modules/views/tests/views_cache.test b/sites/all/modules/views/tests/views_cache.test new file mode 100644 index 0000000000000000000000000000000000000000..e5c9f2551a01fda9e1c43f1e2f79d99f683adb6e --- /dev/null +++ b/sites/all/modules/views/tests/views_cache.test @@ -0,0 +1,147 @@ +<?php +// $Id: views_cache.test,v 1.1.4.3 2010/05/24 19:58:36 dereine Exp $ +/** + * @file + * test cache system. + */ + +module_load_include('test', 'views', 'tests/views_query'); +/** + * Basic test for pluggable caching. + */ +class ViewsCacheTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => t('Cache'), + 'description' => t('Tests pluggable caching for views.'), + 'group' => t('Views Plugins') + ); + } + + /** + * Build and return a basic view of the views_test table. + */ + protected function getBasicView() { + views_include('view'); + + // Create the basic view. + $view = new view(); + $view->vid = 'test_view'; + $view->add_display('default'); + $view->base_table = 'views_test'; + + // Set up the fields we need. + $display = $view->new_display('default', 'Defaults', 'default'); + $display->override_option('fields', array( + 'id' => array( + 'id' => 'id', + 'table' => 'views_test', + 'field' => 'id', + 'relationship' => 'none', + ), + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + ), + 'age' => array( + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + 'relationship' => 'none', + ), + )); + + // Set up the sort order. + $display->override_option('sorts', array( + 'id' => array( + 'order' => 'ASC', + 'id' => 'id', + 'table' => 'views_test', + 'field' => 'id', + 'relationship' => 'none', + ), + )); + + return $view; + } + + /** + * Tests time based caching. + */ + function testTimeCaching() { + // Create a basic result which just 2 results. + $view = $this->getBasicView(); + $view->set_display(); + $view->display_handler->override_option('cache', array( + 'type' => 'time', + 'results_lifespan' => '3600', + 'output_lifespan' => '3600', + )); + + $view->execute(); + // Verify the result. + $this->assertEqual(5, count($view->result), t('The number of returned rows match.')); + + // Add another man to the beatles. + $record = array( + 'name' => 'Rod Davis', + 'age' => 29, + 'job' => 'Banjo', + ); + drupal_write_record('views_test', $record); + + // The Result should be the same as before, because of the caching. + $view = $this->getBasicView(); + $view->set_display(); + $view->display_handler->override_option('cache', array( + 'type' => 'time', + 'results_lifespan' => '3600', + 'output_lifespan' => '3600', + )); + + $view->execute(); + // Verify the result. + $this->assertEqual(5, count($view->result), t('The number of returned rows match.')); + } + + /** + * Tests no caching. + */ + function testNoneCaching() { + // Create a basic result which just 2 results. + $view = $this->getBasicView(); + $view->set_display(); + $view->display_handler->override_option('cache', array( + 'type' => 'none', + )); + + $view->execute(); + // Verify the result. + $this->assertEqual(5, count($view->result), t('The number of returned rows match.')); + + // Add another man to the beatles. + $record = array( + 'name' => 'Rod Davis', + 'age' => 29, + 'job' => 'Banjo', + ); + + drupal_write_record('views_test', $record); + + // The Result should be the same as before, because of the caching. + $view = $this->getBasicView(); + $view->set_display(); + $view->display_handler->override_option('cache', array( + 'type' => 'time', + 'results_lifespan' => '3600', + 'output_lifespan' => '3600', + )); + + $view->execute(); + // Verify the result. + $this->assertEqual(6, count($view->result), t('The number of returned rows match.')); + } +} + diff --git a/sites/all/modules/views/tests/views_exposed_form.test b/sites/all/modules/views/tests/views_exposed_form.test new file mode 100644 index 0000000000000000000000000000000000000000..b11cc1eab36972d4787319bc1bba9a96e9816f72 --- /dev/null +++ b/sites/all/modules/views/tests/views_exposed_form.test @@ -0,0 +1,97 @@ +<?php +// $Id: views_exposed_form.test,v 1.1.2.6 2010/11/25 20:07:44 dereine Exp $ +/** + * @file + * Test exposed forms. + */ +class ViewsExposedFormTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Exposed forms', + 'description' => 'Test exosed forms functionality.', + 'group' => 'Views Plugins', + ); + } + + public function setUp() { + parent::setUp('views_ui'); + module_enable(array('views_ui')); + // @TODO Figure out why it's required to clear the cache here. + views_module_include('views_default.inc', TRUE); + views_get_all_views(TRUE); + menu_rebuild(); + } + + /** + * Tests, whether and how the reset button can be renamed. + */ + public function testRenameResetButton() { + $account = $this->drupalCreateUser(); + $this->drupalLogin($account); + // Create some random nodes. + for ($i = 0; $i < 5; $i++) { + $this->drupalCreateNode(); + } + // Look at the page and check the label "reset". + $this->drupalGet('test_rename_reset_button'); + // Rename the label of the reset button. + $view = views_get_view('test_rename_reset_button'); + $view->set_display('default'); + + $exposed_form = $view->display_handler->get_option('exposed_form'); + $exposed_form['options']['reset_button_label'] = $expected_label = $this->randomName(); + $exposed_form['options']['reset_button'] = TRUE; + $view->display_handler->set_option('exposed_form', $exposed_form); + $view->save(); + + views_invalidate_cache(); + + // Look whether ther reset button label changed. + $this->drupalGet('test_rename_reset_button'); + + $this->helperButtonHasLabel('edit-reset', $expected_label); + } + + /** + * Test the admin interface of exposed filter and sort items. + */ + function testExposedAdminUi() { + $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); + $this->drupalLogin($admin_user); + menu_rebuild(); + $edit = array(); + + $this->drupalGet('admin/structure/views/nojs/config-item/test_exposed_admin_ui/default/filter/type'); + // Be sure that the button is called exposed + $this->helperButtonHasLabel('edit-options-expose-button-button', t('Expose')); + + // Click the Expose button. + $this->drupalPost('admin/structure/views/nojs/config-item/test_exposed_admin_ui/default/filter/type', $edit, t('Expose')); + // Check the label of the expose button + $this->helperButtonHasLabel('edit-options-expose-button-button', t('Hide')); + + // Check the validations of the filter handler. + $edit = array(); + $edit['options[expose][identifier]'] = ''; + $this->drupalPost(NULL, $edit, t('Update')); + $this->assertText(t('The identifier is required if the filter is exposed.')); + + $edit = array(); + $edit['options[expose][identifier]'] = 'value'; + $this->drupalPost(NULL, $edit, t('Update')); + $this->assertText(t('This identifier is not allowed.')); + + // Now check the sort criteria. + $this->drupalGet('admin/structure/views/nojs/config-item/test_exposed_admin_ui/default/sort/created'); + $this->helperButtonHasLabel('edit-options-expose-button-button', t('Expose')); + $this->assertNoFieldById('edit-options-expose-label', '', t('Take sure no label field is shown')); + + // Click the Expose button. + $edit = array(); + $this->drupalPost('admin/structure/views/nojs/config-item/test_exposed_admin_ui/default/sort/created', $edit, t('Expose')); + // Check the label of the expose button + $this->helperButtonHasLabel('edit-options-expose-button-button', t('Hide')); + $this->assertFieldById('edit-options-expose-label', '', t('Take sure a label field is shown')); + } +} + diff --git a/sites/all/modules/views/tests/views_glossary.test b/sites/all/modules/views/tests/views_glossary.test new file mode 100644 index 0000000000000000000000000000000000000000..981637bc7d5f4655705a7e51e70a039ceb6d18b0 --- /dev/null +++ b/sites/all/modules/views/tests/views_glossary.test @@ -0,0 +1,58 @@ +<?php +// $Id: views_glossary.test,v 1.1.4.4 2010/03/14 11:45:38 dereine Exp $ +/** + * @file + * Test glossary view ( summary of arguments ) + */ + +class ViewsGlossaryTestCase extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Glossary Test', + 'description' => 'Tests glossary functionality of views.', + 'group' => 'Views', + ); + } + + public function setUp() { + parent::setUp('views'); + } + + /** + * Test the default glossary view. + */ + public function testGlossaryView() { + // create a contentype and add some nodes, with a non random title. + $type = $this->drupalCreateContentType(); + $nodes_per_char = array( + 'd' => 1, + 'r' => 4, + 'u' => 10, + 'p' => 2, + 'a' => 3, + 'l' => 6, + ); + foreach ($nodes_per_char as $char => $count) { + $setting = array( + 'type' => $type->type + ); + for ($i = 0; $i < $count; $i++) { + $node = $setting; + $node['title'] = $char . $this->randomString(3); + $this->drupalCreateNode($node); + } + } + + // Execute glossary view + $view = views_get_view('glossary'); + $view->set_display('attachment'); + $view->execute_display('attachment'); + + // Check that the amount of nodes per char. + $result_nodes_per_char = array(); + foreach ($view->result as $item) { + $this->assertEqual($nodes_per_char[$item->title_truncated], $item->num_records); + } + } +} + diff --git a/sites/all/modules/views/tests/views_groupby.test b/sites/all/modules/views/tests/views_groupby.test new file mode 100644 index 0000000000000000000000000000000000000000..6b9f7df6087aadeb8abed3d4b9a9e0581f4004a5 --- /dev/null +++ b/sites/all/modules/views/tests/views_groupby.test @@ -0,0 +1,304 @@ +<?php +// $Id: views_groupby.test,v 1.1.4.4 2010/05/24 19:58:36 dereine Exp $ + +class ViewsQueryGroupByTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Tests groupby feature of views3', + 'description' => 'tests aggregate functionality of views3, for example count', + 'group' => 'Views', + ); + } + + public function setUp() { + parent::setUp('views', 'views_ui'); + module_enable(array('views_ui')); + } + + /** + * Test aggregatate count feature. + */ + public function testAggregateCount() { + // Create 2 nodes of type1 and 3 nodes of type2 + $type1 = $this->drupalCreateContentType(); + $type2 = $this->drupalCreateContentType(); + + $node_1 = array( + 'type' => $type1->type, + ); + $this->drupalCreateNode($node_1); + $this->drupalCreateNode($node_1); + $this->drupalCreateNode($node_1); + $this->drupalCreateNode($node_1); + + $node_2 = array( + 'type' => $type2->type, + ); + $this->drupalCreateNode($node_2); + $this->drupalCreateNode($node_2); + $this->drupalCreateNode($node_2); + + $view = $this->viewsAggregateCountView(); + $view->set_display('default'); + $output = $view->execute_display(); + + $this->assertEqual(count($view->result), 2, 'Make sure the count of items is right.'); + + $types = array(); + foreach ($view->result as $item) { + // num_records is a alias for nid. + $types[$item->node_type] = $item->num_records; + } + + $this->assertEqual($types[$type1->type], 4); + $this->assertEqual($types[$type2->type], 3); + } + + //public function testAggregateSum() { + //} + + public function viewsAggregateCountView() { + $view = new view; + $view->name = 'aggregate_count'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['group_by'] = TRUE; + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'some'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Node: Nid */ + $handler->display->display_options['fields']['nid']['id'] = 'nid'; + $handler->display->display_options['fields']['nid']['table'] = 'node'; + $handler->display->display_options['fields']['nid']['field'] = 'title'; + $handler->display->display_options['fields']['nid']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['nid']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['nid']['alter']['trim'] = 0; + $handler->display->display_options['fields']['nid']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['nid']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['nid']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['nid']['alter']['html'] = 0; + $handler->display->display_options['fields']['nid']['hide_empty'] = 0; + $handler->display->display_options['fields']['nid']['empty_zero'] = 0; + $handler->display->display_options['fields']['nid']['link_to_node'] = 0; + /* Argument: Node: Type */ + $handler->display->display_options['arguments']['type']['id'] = 'type'; + $handler->display->display_options['arguments']['type']['table'] = 'node'; + $handler->display->display_options['arguments']['type']['field'] = 'type'; + $handler->display->display_options['arguments']['type']['default_action'] = 'summary asc'; + $handler->display->display_options['arguments']['type']['style_plugin'] = 'default_summary'; + $handler->display->display_options['arguments']['type']['default_argument_type'] = 'fixed'; + + return $view; + } + + /** + * @param $group_by + * Which group_by function should be used, for example sum or count. + */ + function GroupByTestHelper($group_by, $values) { + // Create 2 nodes of type1 and 3 nodes of type2 + $type1 = $this->drupalCreateContentType(); + $type2 = $this->drupalCreateContentType(); + + $node_1 = array( + 'type' => $type1->type, + ); + // Nids from 1 to 4. + $this->drupalCreateNode($node_1); + $this->drupalCreateNode($node_1); + $this->drupalCreateNode($node_1); + $this->drupalCreateNode($node_1); + $node_2 = array( + 'type' => $type2->type, + ); + // Nids from 5 to 7. + $this->drupalCreateNode($node_2); + $this->drupalCreateNode($node_2); + $this->drupalCreateNode($node_2); + + $view = $this->viewsGroupByViewHelper($group_by); + $view->set_display('default'); + $output = $view->execute_display(); + + $this->assertEqual(count($view->result), 2, 'Make sure the count of items is right.'); + // Group by nodetype to identify the right count. + foreach ($view->result as $item) { + $results[$item->node_type] = $item->nid; + } + $this->assertEqual($results[$type1->type], $values[0]); + $this->assertEqual($results[$type2->type], $values[1]); + } + + function viewsGroupByViewHelper($group_by) { + $view = new view; + $view->name = 'group_by_count'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['group_by'] = TRUE; + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'some'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Node: Nid */ + $handler->display->display_options['fields']['nid']['id'] = 'nid'; + $handler->display->display_options['fields']['nid']['table'] = 'node'; + $handler->display->display_options['fields']['nid']['field'] = 'nid'; + $handler->display->display_options['fields']['nid']['group_type'] = $group_by; + $handler->display->display_options['fields']['nid']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['nid']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['nid']['alter']['trim'] = 0; + $handler->display->display_options['fields']['nid']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['nid']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['nid']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['nid']['alter']['html'] = 0; + $handler->display->display_options['fields']['nid']['hide_empty'] = 0; + $handler->display->display_options['fields']['nid']['empty_zero'] = 0; + $handler->display->display_options['fields']['nid']['link_to_node'] = 0; + /* Field: Node: Type */ + $handler->display->display_options['fields']['type']['id'] = 'type'; + $handler->display->display_options['fields']['type']['table'] = 'node'; + $handler->display->display_options['fields']['type']['field'] = 'type'; + $handler->display->display_options['fields']['type']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['type']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['type']['alter']['trim'] = 0; + $handler->display->display_options['fields']['type']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['type']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['type']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['type']['alter']['html'] = 0; + $handler->display->display_options['fields']['type']['hide_empty'] = 0; + $handler->display->display_options['fields']['type']['empty_zero'] = 0; + $handler->display->display_options['fields']['type']['link_to_node'] = 0; + + return $view; + } + + public function testGroupByCount() { + $this->GroupByTestHelper('count', array(4, 3)); + } + + function testGroupBySum() { + $this->GroupByTestHelper('sum', array(10, 18)); + } + + + function testGroupByAverage() { + $this->GroupByTestHelper('avg', array(2.5, 6)); + } + + function testGroupByMin() { + $this->GroupByTestHelper('min', array(1, 5)); + } + + function testGroupByMax() { + $this->GroupByTestHelper('max', array(4, 7)); + } + + function testGroupBySave() { + $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); + $this->drupalLogin($admin_user); + views_invalidate_cache(); + menu_rebuild(); + + $this->drupalGet('admin/structure/views'); + $this->drupalGet('admin/structure/views/edit/test_views_groupby_save'); + + $edit = array( + 'group_by' => TRUE, + ); + $this->drupalPost('admin/structure/views/nojs/display/test_views_groupby_save/default/group_by', $edit, t('Update')); + + $this->drupalGet('admin/structure/views/edit/test_views_groupby_save'); + $this->drupalPost('admin/structure/views/edit/test_views_groupby_save', array(), t('Save')); + + $this->drupalGet('admin/structure/views/nojs/display/test_views_groupby_save/default/group_by'); + } + + public function testGroupByCountOnlyFilters() { + // Check if GROUP BY and HAVING are included when a view + // Doesn't display SUM, COUNT, MAX... functions in SELECT statment + + $type1 = $this->drupalCreateContentType(); + + $node_1 = array( + 'type' => $type1->type, + ); + for ($x = 0; $x < 10; $x++) { + $this->drupalCreateNode($node_1); + } + + $view = $this->viewsGroupByCountViewOnlyFilters(); + $view->set_display('default'); + $output = $view->execute_display(); + + $this->assertTrue(strpos($view->build_info['query'], 'GROUP BY'), t('Make sure that GROUP BY is in the query')); + $this->assertTrue(strpos($view->build_info['query'], 'HAVING'), t('Make sure that HAVING is in the query')); + } + + function viewsGroupByCountViewOnlyFilters() { + $view = new view; + $view->name = 'group_by_in_filters'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['group_by'] = TRUE; + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'some'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Nodo: Tipo */ + $handler->display->display_options['fields']['type']['id'] = 'type'; + $handler->display->display_options['fields']['type']['table'] = 'node'; + $handler->display->display_options['fields']['type']['field'] = 'type'; + $handler->display->display_options['fields']['type']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['type']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['type']['alter']['trim'] = 0; + $handler->display->display_options['fields']['type']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['type']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['type']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['type']['alter']['html'] = 0; + $handler->display->display_options['fields']['type']['hide_empty'] = 0; + $handler->display->display_options['fields']['type']['empty_zero'] = 0; + $handler->display->display_options['fields']['type']['link_to_node'] = 0; + /* Filtrar: Nodo: Nid */ + $handler->display->display_options['filters']['nid']['id'] = 'nid'; + $handler->display->display_options['filters']['nid']['table'] = 'node'; + $handler->display->display_options['filters']['nid']['field'] = 'nid'; + $handler->display->display_options['filters']['nid']['group_type'] = 'count'; + $handler->display->display_options['filters']['nid']['operator'] = '>'; + $handler->display->display_options['filters']['nid']['value']['value'] = '3'; + + return $view; + } +} + + diff --git a/sites/all/modules/views/tests/views_handlers.test b/sites/all/modules/views/tests/views_handlers.test new file mode 100644 index 0000000000000000000000000000000000000000..20a78c986a98b8baac85960c8b3ea90df74e8659 --- /dev/null +++ b/sites/all/modules/views/tests/views_handlers.test @@ -0,0 +1,39 @@ +<?php +// $Id: views_handlers.test,v 1.1.4.4 2010/05/24 19:58:36 dereine Exp $ + +/** +* @file +* Test abstract handlers of views +*/ + +class ViewsHandlersTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => t('Handlers test'), + 'description' => t('test abstract handler definitions'), + 'group' => 'Views', + ); + } + + function setUp() { + parent::setUp('views', 'views_ui'); + module_enable(array('views_ui')); + } + + function testFilterInOperatorUi() { + $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); + $this->drupalLogin($admin_user); + menu_rebuild(); + + $path = 'admin/structure/views/nojs/config-item/test_filter_in_operator_ui/default/filter/type'; + $this->drupalGet($path); + $this->assertFieldByName('options[expose][reduce]', FALSE); + + $edit = array( + 'options[expose][reduce]' => TRUE, + ); + $this->drupalPost($path, $edit, t('Update')); + $this->drupalGet($path); + $this->assertFieldByName('options[expose][reduce]', TRUE); + } +} diff --git a/sites/all/modules/views/tests/views_module.test b/sites/all/modules/views/tests/views_module.test new file mode 100644 index 0000000000000000000000000000000000000000..8bfdca2e1d1f83fe756b62f8c23c7ee65468d30d --- /dev/null +++ b/sites/all/modules/views/tests/views_module.test @@ -0,0 +1,79 @@ +<?php +// $Id: views_module.test,v 1.1.2.3 2010/12/17 21:51:42 dereine Exp $ +module_load_include('test', 'views', 'tests/views_query'); +class viewsModuleTest extends ViewsSqlTest { + public static function getInfo() { + return array( + 'name' => 'Tests views.module', + 'description' => 'Tests some basic functions of views.module', + 'group' => 'Views', + ); + } + + public function setUp() { + parent::setUp(); + } + + public function test_views_trim_text() { + // Test unicode, @see http://drupal.org/node/513396#comment-2839416 + $text = array( + 'Tuy nhiên, những hi vọng', + 'Giả sử chúng tôi có 3 Apple', + 'siêu nhỏ này là bộ xử lý', + 'Di động của nhà sản xuất Phần Lan', + 'khoảng cách từ đại lí đến', + 'của hãng bao gồm ba dòng', + 'сд асд асд ас', + 'асд асд асд ас' + ); + // Just test maxlength without word boundry. + $alter = array( + 'max_length' => 10, + ); + $expect = array( + 'Tuy nhiên,', + 'Giả sử chú', + 'siêu nhỏ n', + 'Di động củ', + 'khoảng các', + 'của hãng b', + 'сд асд асд', + 'асд асд ас', + ); + + foreach ($text as $key => $line) { + $result_text = views_trim_text($alter, $line); + $this->assertEqual($result_text, $expect[$key]); + } + + // Test also word_boundary + $alter['word_boundary'] = TRUE; + $expect = array( + 'Tuy nhiên', + 'Giả sử', + 'siêu nhỏ', + 'Di động', + 'khoảng', + 'của hãng', + 'сд асд', + 'асд асд', + ); + + foreach ($text as $key => $line) { + $result_text = views_trim_text($alter, $line); + $this->assertEqual($result_text, $expect[$key]); + } + } + + /** + * Tests the dynamic includes of templates via module feature. + */ + function testModuleTemplates() { + $views_status = variable_get('views_defaults', array()); + $views_status['frontpage'] = FALSE; // false is enabled + variable_set('views_defaults', $views_status); + + $registry = theme_get_registry(); + $this->assertTrue(isset($registry['views_view__frontpage'])); + } +} diff --git a/sites/all/modules/views/tests/views_pager.test b/sites/all/modules/views/tests/views_pager.test new file mode 100644 index 0000000000000000000000000000000000000000..1b5360c764f643bf631622b3e82a415417788bc0 --- /dev/null +++ b/sites/all/modules/views/tests/views_pager.test @@ -0,0 +1,428 @@ +<?php +// $Id: views_pager.test,v 1.1.2.6 2010/10/12 20:59:02 merlinofchaos Exp $ +/** + * @file + * Tests the pluggable pager system + */ + +class ViewsPagerTest extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Pager', + 'description' => 'Test the pluggable pager system', + 'group' => 'Views Plugins', + ); + } + + public function setUp() { + parent::setUp('views', 'views_ui', 'views_test'); + } + + /** + * Pagers was sometimes not stored. + * + * See: http://drupal.org/node/652712. + */ + public function testStorePagerSettings() { + $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); + $this->drupalLogin($admin_user); + // Test behaviour described in http://drupal.org/node/652712#comment-2354918. + + $this->drupalGet('admin/structure/views/edit/frontpage'); + + + $edit = array( + 'pager_options[items_per_page]' => 20, + ); + $this->drupalPost('admin/structure/views/nojs/display/frontpage/default/pager_options', $edit, t('Update')); + $this->assertText('20 items'); + + // Change type and check whether the type is new type is stored. + $edit = array(); + $edit = array( + 'pager[type]' => 'mini', + ); + $this->drupalPost('admin/structure/views/nojs/display/frontpage/default/pager', $edit, t('Update')); + $this->drupalGet('admin/structure/views/edit/frontpage'); + $this->assertText('Mini pager', 'Changed pager plugin, should change some text'); + + // Test behaviour described in http://drupal.org/node/652712#comment-2354400 + $view = $this->viewsStorePagerSettings(); + // Make it editable in the admin interface. + $view->save(); + + $this->drupalGet('admin/structure/views/test_store_pager_settings'); + + $edit = array(); + $edit = array( + 'pager[type]' => 'full', + ); + $this->drupalPost('admin/structure/views/nojs/display/test_store_pager_settings/default/pager', $edit, t('Update')); + $this->drupalGet('admin/structure/views/edit/test_store_pager_settings'); + $this->assertText('Paged'); + + $edit = array( + 'pager_options[items_per_page]' => 20, + ); + $this->drupalPost('admin/structure/views/nojs/display/test_store_pager_settings/default/pager_options', $edit, t('Update')); + $this->assertText('20 items'); + + // add new display and test the settings again, by override it. + $edit = array( + 'display' => 'page', + ); + // Add a display and override the pager settings. + $this->drupalPost('admin/structure/views/edit/test_store_pager_settings', $edit, t('Add display')); + $this->drupalPost('admin/structure/views/nojs/display/test_store_pager_settings/page_1/pager', array(), t('Override')); + + $edit = array( + 'pager[type]' => 'mini', + ); + $this->drupalPost('admin/structure/views/nojs/display/test_store_pager_settings/page_1/pager', $edit, t('Update')); + $this->drupalGet('admin/structure/views/edit/test_store_pager_settings'); + $this->assertText('Mini pager', 'Changed pager plugin, should change some text'); + + $edit = array( + 'pager_options[items_per_page]' => 10, + ); + $this->drupalPost('admin/structure/views/nojs/display/test_store_pager_settings/default/pager_options', $edit, t('Update')); + $this->assertText('20 items'); + + } + + public function viewsStorePagerSettings() { + $view = new view; + $view->name = 'test_store_pager_settings'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'none'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'node'; + return $view; + } + + /** + * Test the none-pager-query. + */ + public function testNoLimit() { + // Create 11 nodes and take sure that everyone is returned. + // We create 11 nodes, because the default pager plugin had 10 items per page. + for ($i = 0; $i < 11; $i++) { + $this->drupalCreateNode(); + } + $view = $this->viewsPagerNoLimit(); + $view->set_display('default'); + $view->pre_execute(); + $view->execute(); + $this->assertEqual(count($view->result), 11, 'Take sure that every item is returned in the result'); + + $view->destroy(); + + // Setup and test a offset. + $view = $this->viewsPagerNoLimit(); + $view->set_display('default'); + + $pager = array( + 'type' => 'none', + 'options' => array( + 'offset' => 3, + ), + ); + $view->display_handler->set_option('pager', $pager); + $view->pre_execute(); + $view->execute(); + + $this->assertEqual(count($view->result), 8, 'Take sure that every item beside the first three is returned in the result'); + + // Check some public functions. + $this->assertFalse($view->query->pager->use_pager()); + $this->assertFalse($view->query->pager->use_count_query()); + $this->assertEqual($view->query->pager->get_items_per_page(), 0); + } + + public function viewsPagerNoLimit() { + $view = new view; + $view->name = 'test_pager_none'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'none'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'node'; + return $view; + } + + /** + * Test the some pager plugin. + */ + public function testLimit() { + // Create 11 nodes and take sure that everyone is returned. + // We create 11 nodes, because the default pager plugin had 10 items per page. + for ($i = 0; $i < 11; $i++) { + $this->drupalCreateNode(); + } + $view = $this->viewsPagerLimit(); + $view->set_display('default'); + $view->execute(); + $this->assertEqual(count($view->result), 5, 'Take sure that only a certain count of items is returned'); + $view->destroy(); + + // Setup and test a offset. + $view = $this->viewsPagerLimit(); + $view->set_display('default'); + + $pager = array( + 'type' => 'none', + 'options' => array( + 'offset' => 8, + 'items_per_page' => 5, + ), + ); + $view->display_handler->set_option('pager', $pager); + $view->pre_execute(); + $view->execute(); + $this->assertEqual(count($view->result), 3, 'Take sure that only a certain count of items is returned'); + + // Check some public functions. + $this->assertFalse($view->query->pager->use_pager()); + $this->assertFalse($view->query->pager->use_count_query()); + } + + public function viewsPagerLimit() { + $view = new view; + $view->name = 'test_pager_some'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'some'; + $handler->display->display_options['pager']['options']['offset'] = 0; + $handler->display->display_options['pager']['options']['items_per_page'] = 5; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'node'; + return $view; + } + + /** + * Test the normal pager. + */ + public function testNormalPager() { + // Create 11 nodes and take sure that everyone is returned. + // We create 11 nodes, because the default pager plugin had 10 items per page. + for ($i = 0; $i < 11; $i++) { + $this->drupalCreateNode(); + } + $view = $this->viewsPagerFull(); + $view->set_display('default'); + $view->pre_execute(); + $view->execute(); + $this->assertEqual(count($view->result), 5, 'Take sure that only a certain count of items is returned'); + $view->destroy(); + + // Setup and test a offset. + $view = $this->viewsPagerFull(); + $view->set_display('default'); + + $pager = array( + 'type' => 'full', + 'options' => array( + 'offset' => 8, + 'items_per_page' => 5, + ), + ); + $view->display_handler->set_option('pager', $pager); + $view->pre_execute(); + $view->execute(); + $this->assertEqual(count($view->result), 3, 'Take sure that only a certain count of items is returned'); + + // Test items per page = 0 + $view = $this->viewPagerFullZeroItemsPerPage(); + $view->set_display('default'); + $view->pre_execute(); + $view->execute(); + + $this->assertEqual(count($view->result), 11, 'All items are return'); + + // TODO test number of pages. + + // Test items per page = 0. + $view->destroy(); + + // Setup and test a offset. + $view = $this->viewsPagerFull(); + $view->set_display('default'); + + $pager = array( + 'type' => 'full', + 'options' => array( + 'offset' => 0, + 'items_per_page' => 0, + ), + ); + + $view->display_handler->set_option('pager', $pager); + $view->execute(); + $this->assertEqual($view->query->pager->get_items_per_page(), 0); + $this->assertEqual(count($view->result), 11); + } + + function viewPagerFullZeroItemsPerPage() { + $view = new view; + $view->name = 'view_pager_full_zero_items_per_page'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['pager']['options']['items_per_page'] = '0'; + $handler->display->display_options['pager']['options']['offset'] = '0'; + $handler->display->display_options['pager']['options']['id'] = '0'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Node: Title */ + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['title']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['title']['alter']['trim'] = 0; + $handler->display->display_options['fields']['title']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['title']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['title']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['title']['alter']['html'] = 0; + $handler->display->display_options['fields']['title']['hide_empty'] = 0; + $handler->display->display_options['fields']['title']['empty_zero'] = 0; + $handler->display->display_options['fields']['title']['link_to_node'] = 0; + + return $view; + } + + function viewsPagerFull() { + $view = new view; + $view->name = 'test_pager_full'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['pager']['options']['items_per_page'] = '5'; + $handler->display->display_options['pager']['options']['offset'] = '0'; + $handler->display->display_options['pager']['options']['id'] = '0'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'node'; + + return $view; + } + + function viewsPagerFullFields() { + $view = new view; + $view->name = 'test_pager_full'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['pager']['options']['items_per_page'] = '5'; + $handler->display->display_options['pager']['options']['offset'] = '0'; + $handler->display->display_options['pager']['options']['id'] = '0'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + $handler->display->display_options['fields']['title']['id'] = 'title'; + $handler->display->display_options['fields']['title']['table'] = 'node'; + $handler->display->display_options['fields']['title']['field'] = 'title'; + $handler->display->display_options['fields']['title']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['title']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['title']['alter']['trim'] = 0; + $handler->display->display_options['fields']['title']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['title']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['title']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['title']['alter']['html'] = 0; + $handler->display->display_options['fields']['title']['hide_empty'] = 0; + $handler->display->display_options['fields']['title']['empty_zero'] = 0; + $handler->display->display_options['fields']['title']['link_to_node'] = 0; + return $view; + } + + /** + * Test the minipager. + */ + public function testMiniPager() { + // the functionality is the same as the normal pager, so i don't know what to test here. + } + + /** + * Test rendering with NULL pager. + */ + public function testRenderNullPager() { + // Create 11 nodes and take sure that everyone is returned. + // We create 11 nodes, because the default pager plugin had 10 items per page. + for ($i = 0; $i < 11; $i++) { + $this->drupalCreateNode(); + } + $view = $this->viewsPagerFullFields(); + $view->set_display('default'); + $view->execute(); + $view->use_ajax = TRUE; // force the value again here + $view->query->pager = NULL; + $output = $view->render(); + $this->assertEqual(preg_match('/<ul class="pager">/', $output), 0, t('The pager is not rendered.')); + } +} + diff --git a/sites/all/modules/views/tests/views_plugin_localization_test.inc b/sites/all/modules/views/tests/views_plugin_localization_test.inc new file mode 100644 index 0000000000000000000000000000000000000000..b2ce829f7763b8f92324b7e5f6563db33f5e1a85 --- /dev/null +++ b/sites/all/modules/views/tests/views_plugin_localization_test.inc @@ -0,0 +1,36 @@ +<?php +// $Id: views_plugin_localization_test.inc,v 1.1.4.2 2010/12/01 20:05:06 dereine Exp $ + +/** + * A stump localisation plugin which has static variables to cache the input. + */ +class views_plugin_localization_test extends views_plugin_localization { + /** + * Store the strings which was translated. + */ + var $translated_strings; + /** + * Return the string and take sure that the test can find out whether the + * string got translated. + */ + function translate_string($string, $keys = array()) { + $this->translated_strings[] = $string; + return $string . "-translated"; + } + + /** + * Store the export strings. + */ + function export($source) { + if (!empty($source['value'])) { + $this->export_strings[] = $source['value']; + } + } + + /** + * Return the stored strings for the simpletest. + */ + function get_export_strings() { + return $this->export_strings; + } +} diff --git a/sites/all/modules/views/tests/views_query.test b/sites/all/modules/views/tests/views_query.test new file mode 100644 index 0000000000000000000000000000000000000000..d3d52c5712b9feac0de2b2389c2b03b56aa043f9 --- /dev/null +++ b/sites/all/modules/views/tests/views_query.test @@ -0,0 +1,412 @@ +<?php +// $Id: views_query.test,v 1.1.2.17 2011/01/04 21:26:47 dereine Exp $ + +/** + * @file + * Tests for Views query features. + */ + +/** + * Abstract class for views testing + */ +abstract class ViewsTestCase extends DrupalWebTestCase { + /** + * Helper function: verify a result set returned by view. + * + * The comparison is done on the string representation of the columns of the + * column map, taking the order of the rows into account, but not the order + * of the columns. + * + * @param $view + * An executed View. + * @param $expected_result + * An expected result set. + * @param $column_map + * An associative array mapping the columns of the result set from the view + * (as keys) and the expected result set (as values). + */ + protected function assertIdenticalResultset($view, $expected_result, $column_map = array(), $message = 'Identical result set') { + return $this->assertIdenticalResultsetHelper($view, $expected_result, $column_map, $message, 'assertIdentical'); + } + + /** + * Helper function: verify a result set returned by view. + * + * Inverse of ViewsTestCase::assertIdenticalResultset(). + * + * @param $view + * An executed View. + * @param $expected_result + * An expected result set. + * @param $column_map + * An associative array mapping the columns of the result set from the view + * (as keys) and the expected result set (as values). + */ + protected function assertNotIdenticalResultset($view, $expected_result, $column_map = array(), $message = 'Identical result set') { + return $this->assertIdenticalResultsetHelper($view, $expected_result, $column_map, $message, 'assertNotIdentical'); + } + + protected function assertIdenticalResultsetHelper($view, $expected_result, $column_map, $message, $assert_method) { + // Convert $view->result to an array of arrays. + $result = array(); + foreach ($view->result as $key => $value) { + $row = array(); + foreach ($column_map as $view_column => $expected_column) { + // The comparison will be done on the string representation of the value. + $row[$expected_column] = (string) $value->$view_column; + } + $result[$key] = $row; + } + + // Remove the columns we don't need from the expected result. + foreach ($expected_result as $key => $value) { + $row = array(); + foreach ($column_map as $expected_column) { + // The comparison will be done on the string representation of the value. + $row[$expected_column] = (string) (is_object($value) ? $value->$expected_column : $value[$expected_column]); + } + $expected_result[$key] = $row; + } + + // Reset the numbering of the arrays. + $result = array_values($result); + $expected_result = array_values($expected_result); + + $this->verbose('<pre>Returned data set: ' . print_r($result, TRUE) . "\n\nExpected: ". print_r($expected_result, TRUE)); + + // Do the actual comparison. + return $this->$assert_method($result, $expected_result, $message); + } + + /** + * Helper function: order an array of array based on a column. + */ + protected function orderResultSet($result_set, $column, $reverse = FALSE) { + $this->sort_column = $column; + $this->sort_order = $reverse ? -1 : 1; + usort($result_set, array($this, 'helperCompareFunction')); + return $result_set; + } + + protected $sort_column = NULL; + protected $sort_order = 1; + + /** + * Helper comparison function for orderResultSet(). + */ + protected function helperCompareFunction($a, $b) { + $value1 = $a[$this->sort_column]; + $value2 = $b[$this->sort_column]; + if ($value1 == $value2) { + return 0; + } + return $this->sort_order * (($value1 < $value2) ? -1 : 1); + } + + /** + * Helper function to check whether a button with a certain id exists and has a certain label. + */ + protected function helperButtonHasLabel($id, $expected_label, $message = 'Label has the expected value: %label.') { + return $this->assertFieldById($id, $expected_label, t($message, array('%label' => $expected_label))); + } + + /** + * Helper function to execute a view with debugging. + */ + protected function executeView($view, $args = array()) { + $view->set_display(); + $view->pre_execute($args); + $view->execute(); + $this->verbose('<pre>Executed view: ' . ((string) $view->build_info['query']) . '</pre>'); + } +} + +abstract class ViewsSqlTest extends ViewsTestCase { + + protected function setUp() { + parent::setUp('views', 'views_ui'); + + // Define the schema and views data variable before enabling the test module. + variable_set('views_test_schema', $this->schemaDefinition()); + variable_set('views_test_views_data', $this->viewsData()); + variable_set('views_test_views_plugins', $this->viewsPlugins()); + + module_enable(array('views_test')); + $this->resetAll(); + + // Load the test dataset. + $data_set = $this->dataSet(); + $query = db_insert('views_test') + ->fields(array_keys($data_set[0])); + foreach ($data_set as $record) { + $query->values($record); + } + $query->execute(); + $this->checkPermissions(array(), TRUE); + } + + /** + * This function allows to enable views ui from a higher class which can't change the setup function anymore. + * + * @TODO + * Convert existing setUp functions. + */ + function enableViewsUi() { + module_enable(array('views_ui')); + // @TODO Figure out why it's required to clear the cache here. + views_module_include('views_default.inc', TRUE); + views_get_all_views(TRUE); + menu_rebuild(); + } + + /** + * The schema definition. + */ + protected function schemaDefinition() { + $schema['views_test'] = array( + 'description' => 'Basic test table for Views tests.', + 'fields' => array( + 'id' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'name' => array( + 'description' => "A person's name", + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'age' => array( + 'description' => "The person's age", + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0), + 'job' => array( + 'description' => "The person's job", + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => 'Undefined', + ), + 'created' => array( + 'description' => "The creation date of this record", + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + ), + 'primary key' => array('id'), + 'unique keys' => array( + 'name' => array('name') + ), + 'indexes' => array( + 'ages' => array('age'), + ), + ); + return $schema; + } + + /** + * The views data definition. + */ + protected function viewsData() { + // Declaration of the base table. + $data['views_test']['table'] = array( + 'group' => t('Views test'), + 'base' => array( + 'field' => 'id', + 'title' => t('Views test'), + 'help' => t('Users who have created accounts on your site.'), + ), + ); + + // Declaration of fields. + $data['views_test']['id'] = array( + 'title' => t('ID'), + 'help' => t('The test data ID'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + $data['views_test']['name'] = array( + 'title' => t('Name'), + 'help' => t('The name of the person'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + $data['views_test']['age'] = array( + 'title' => t('Age'), + 'help' => t('The age of the person'), + 'field' => array( + 'handler' => 'views_handler_field_numeric', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_numeric', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_numeric', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + $data['views_test']['job'] = array( + 'title' => t('Job'), + 'help' => t('The job of the person'), + 'field' => array( + 'handler' => 'views_handler_field', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_string', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_string', + ), + 'sort' => array( + 'handler' => 'views_handler_sort', + ), + ); + $data['views_test']['created'] = array( + 'title' => t('Created'), + 'help' => t('The creation date of this record'), + 'field' => array( + 'handler' => 'views_handler_field_date', + 'click sortable' => TRUE, + ), + 'argument' => array( + 'handler' => 'views_handler_argument_date', + ), + 'filter' => array( + 'handler' => 'views_handler_filter_date', + ), + 'sort' => array( + 'handler' => 'views_handler_sort_date', + ), + ); + return $data; + } + + protected function viewsPlugins() { + return array(); + } + + /** + * A very simple test dataset. + */ + protected function dataSet() { + return array( + array( + 'name' => 'John', + 'age' => 25, + 'job' => 'Singer', + 'created' => gmmktime(0, 0, 0, 1, 1, 2000), + ), + array( + 'name' => 'George', + 'age' => 27, + 'job' => 'Singer', + 'created' => gmmktime(0, 0, 0, 1, 2, 2000), + ), + array( + 'name' => 'Ringo', + 'age' => 28, + 'job' => 'Drummer', + 'created' => gmmktime(6, 30, 30, 1, 1, 2000), + ), + array( + 'name' => 'Paul', + 'age' => 26, + 'job' => 'Songwriter', + 'created' => gmmktime(6, 0, 0, 1, 1, 2000), + ), + array( + 'name' => 'Meredith', + 'age' => 30, + 'job' => 'Speaker', + 'created' => gmmktime(6, 30, 10, 1, 1, 2000), + ), + ); + } + + /** + * Build and return a basic view of the views_test table. + */ + protected function getBasicView() { + views_include('view'); + + // Create the basic view. + $view = new view(); + $view->vid = 'test_view'; + $view->add_display('default'); + $view->base_table = 'views_test'; + + // Set up the fields we need. + $display = $view->new_display('default', 'Defaults', 'default'); + $display->override_option('fields', array( + 'id' => array( + 'id' => 'id', + 'table' => 'views_test', + 'field' => 'id', + 'relationship' => 'none', + ), + 'name' => array( + 'id' => 'name', + 'table' => 'views_test', + 'field' => 'name', + 'relationship' => 'none', + ), + 'age' => array( + 'id' => 'age', + 'table' => 'views_test', + 'field' => 'age', + 'relationship' => 'none', + ), + )); + + // Set up the sort order. + $display->override_option('sorts', array( + 'id' => array( + 'order' => 'ASC', + 'id' => 'id', + 'table' => 'views_test', + 'field' => 'id', + 'relationship' => 'none', + ), + )); + + // Set up the pager. + $display->override_option('pager', array( + 'type' => 'none', + 'options' => array('offset' => 0), + )); + + return $view; + } +} diff --git a/sites/all/modules/views/tests/views_test.info b/sites/all/modules/views/tests/views_test.info new file mode 100644 index 0000000000000000000000000000000000000000..2ed22abdd10170522ab13d2f73fb720d89c3bc5a --- /dev/null +++ b/sites/all/modules/views/tests/views_test.info @@ -0,0 +1,14 @@ +; $Id: views_test.info,v 1.1.2.3 2010/12/23 17:52:53 dereine Exp $ +name = Views Test +description = Test module for Views. +package = Views +core = 7.x +dependencies[] = views +hidden = TRUE + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-3.0-alpha1" +core = "7.x" +project = "views" +datestamp = "1294276880" + diff --git a/sites/all/modules/views/tests/views_test.install b/sites/all/modules/views/tests/views_test.install new file mode 100644 index 0000000000000000000000000000000000000000..348b4a83e5c1c23f53ae585418afaaf503d59bdc --- /dev/null +++ b/sites/all/modules/views/tests/views_test.install @@ -0,0 +1,6 @@ +<?php +// $Id: views_test.install,v 1.1.2.3 2010/05/24 09:13:58 dereine Exp $ + +function views_test_schema() { + return variable_get('views_test_schema', array()); +} diff --git a/sites/all/modules/views/tests/views_test.module b/sites/all/modules/views/tests/views_test.module new file mode 100644 index 0000000000000000000000000000000000000000..924a48948dc61c76facc42c34d9f16815c95cee0 --- /dev/null +++ b/sites/all/modules/views/tests/views_test.module @@ -0,0 +1,46 @@ +<?php +// $Id: views_test.module,v 1.1.2.9 2011/01/04 21:26:47 dereine Exp $ + +/** + * Implements hook_permission(). + */ +function views_test_permission() { + return array( + 'views_test test permission' => array( + 'title' => t('Test permission'), + 'description' => t('views_test test permission'), + ), + ); +} + +/** + * Implements hook_views_api(). + */ +function views_test_views_api() { + return array( + 'api' => '3.0-alpha1', + 'template path' => drupal_get_path('module', 'views_test') . '/templates', + ); +} + +/** + * Implements hook_views_data() + */ +function views_test_views_data() { + return variable_get('views_test_views_data', array()); +} + +/** + * Implements hook_views_plugins() + */ +function views_test_views_plugins() { + return variable_get('views_test_views_plugins', array()); +} + +function views_test_test_static_access_callback($access) { + return $access; +} + +function views_test_test_dynamic_access_callback($access, $argument1, $argument2) { + return $access && $argument1 == variable_get('test_dynamic_access_argument1', NULL) && $argument2 == variable_get('test_dynamic_access_argument2', NULL); +} \ No newline at end of file diff --git a/sites/all/modules/views/tests/views_test.views_default.inc b/sites/all/modules/views/tests/views_test.views_default.inc new file mode 100644 index 0000000000000000000000000000000000000000..cc57330b4d84cbd2121a8984b30f3c20d9e9009f --- /dev/null +++ b/sites/all/modules/views/tests/views_test.views_default.inc @@ -0,0 +1,144 @@ +<?php +// $Id: views_test.views_default.inc,v 1.1.2.5 2011/01/05 23:14:39 dereine Exp $ +/** + * @file + * Test views + */ + +/** + * Implements hook_views_default_views(). + */ +function views_test_views_default_views() { + $view = new view; + $view->name = 'test_views_groupby_save'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->version = 7; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'none'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + + $views[$view->name] = $view; + + $view = new view; + $view->name = 'test_rename_reset_button'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->version = 7; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['exposed_form']['options']['reset_button'] = TRUE; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'node'; + $handler->display->display_options['row_options']['links'] = 1; + $handler->display->display_options['row_options']['comments'] = 0; + /* Filter: Node: Type */ + $handler->display->display_options['filters']['type']['id'] = 'type'; + $handler->display->display_options['filters']['type']['table'] = 'node'; + $handler->display->display_options['filters']['type']['field'] = 'type'; + $handler->display->display_options['filters']['type']['exposed'] = TRUE; + $handler->display->display_options['filters']['type']['expose']['operator'] = 'type_op'; + $handler->display->display_options['filters']['type']['expose']['label'] = 'Node: Type'; + + /* Display: Page */ + $handler = $view->new_display('page', 'Page', 'page_1'); + $handler->display->display_options['path'] = 'test_rename_reset_button'; + + $views[$view->name] = $view; + + $view = new view; + $view->name = 'test_exposed_admin_ui'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->version = 7; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['exposed_form']['options']['reset_button'] = TRUE; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'node'; + $handler->display->display_options['row_options']['links'] = 1; + $handler->display->display_options['row_options']['comments'] = 0; + /* Sort criterion: Node: Post date */ + $handler->display->display_options['sorts']['created']['id'] = 'created'; + $handler->display->display_options['sorts']['created']['table'] = 'node'; + $handler->display->display_options['sorts']['created']['field'] = 'created'; + /* Filter: Node: Type */ + $handler->display->display_options['filters']['type']['id'] = 'type'; + $handler->display->display_options['filters']['type']['table'] = 'node'; + $handler->display->display_options['filters']['type']['field'] = 'type'; + $handler->display->display_options['filters']['type']['expose']['operator'] = 'type_op'; + $handler->display->display_options['filters']['type']['expose']['label'] = 'Node: Type'; + $handler->display->display_options['filters']['type']['expose']['use_operator'] = TRUE; + + /* Display: Page */ + $handler = $view->new_display('page', 'Page', 'page_1'); + $handler->display->display_options['path'] = 'test_exposed_admin_ui'; + + $views[$view->name] = $view; + + $view = new view; + $view->name = 'test_filter_in_operator_ui'; + $view->description = ''; + $view->tag = ''; + $view->view_php = ''; + $view->base_table = 'node'; + $view->is_cacheable = FALSE; + $view->api_version = 2; + $view->version = 7; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults', 'default'); + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Filter: Node: Type */ + $handler->display->display_options['filters']['type']['id'] = 'type'; + $handler->display->display_options['filters']['type']['table'] = 'node'; + $handler->display->display_options['filters']['type']['field'] = 'type'; + $handler->display->display_options['filters']['type']['exposed'] = TRUE; + $handler->display->display_options['filters']['type']['expose']['operator'] = 'type_op'; + $handler->display->display_options['filters']['type']['expose']['label'] = 'Node: Type'; + $handler->display->display_options['filters']['type']['expose']['use_operator'] = 0; + $handler->display->display_options['filters']['type']['expose']['identifier'] = 'type'; + $handler->display->display_options['filters']['type']['expose']['reduce'] = 0; + + $views[$view->name] = $view; + + return $views; +} + diff --git a/sites/all/modules/views/tests/views_translatable.test b/sites/all/modules/views/tests/views_translatable.test new file mode 100644 index 0000000000000000000000000000000000000000..2b7c85fd5571b489c618b72756625fac27b05dbb --- /dev/null +++ b/sites/all/modules/views/tests/views_translatable.test @@ -0,0 +1,151 @@ +<?php +// $Id: views_translatable.test,v 1.1.4.2 2010/12/01 20:05:06 dereine Exp $ + +module_load_include('test', 'views', 'tests/views_query'); + +class viewsTranslatableTest extends ViewsSqlTest { + var $strings; + + public static function getInfo() { + return array( + 'name' => 'Views Translatable Test', + 'description' => 'Tests the pluggable translations', + 'group' => 'Views', + ); + } + + /* + * The views plugin definition. Override it if you test provides a plugin. + */ + public function viewsPlugins() { + return array( + 'localization' => array( + 'test' => array( + 'no ui' => TRUE, + 'title' => t('Test'), + 'help' => t('This is a test description.'), + 'handler' => 'views_plugin_localization_test', + 'parent' => 'parent', + 'path' => drupal_get_path('module', 'views') .'/tests', + ), + ), + ); + } + + public function setUp() { + parent::setUp(); + + variable_set('views_localization_plugin', 'test'); + // Reset the plugin data. + views_fetch_plugin_data(NULL, NULL, TRUE); + $this->strings = array('Defaults1', 'Apply1', 'Sort By1', 'Asc1', 'Desc1', 'more1', 'Reset1', 'Offset1', 'Defaults1', 'title1', 'Items per page1', 'fieldlabel1', 'filterlabel1'); + $this->enableViewsUi(); + } + + /** + * Test the unpack translation funtionality. + */ + public function testUnpackTranslatable() { + $view = $this->view_unpack_translatable(); + $view->init_localization(); + + $this->assertEqual('views_plugin_localization_test', get_class($view->localization_plugin), 'Take sure that init_localization initiales the right translation plugin'); + + $view->export_locale_strings(); + + $expected_strings = $this->strings; + $result_strings = $view->localization_plugin->get_export_strings(); + $this->assertEqual(sort($expected_strings), sort($result_strings), 'Take sure that the localisation plugin got every translatable string.'); + } + + public function testUi() { + // Take sure that the string is not translated on the ui. + $view = $this->view_unpack_translatable(); + $view->save(); + views_invalidate_cache(); + + $admin_user = $this->drupalCreateUser(array('administer views', 'administer site configuration')); + $this->drupalLogin($admin_user); + + $this->drupalGet("admin/structure/views/edit/$view->name"); + $this->assertNoText('-translated', 'Take sure that no strings get\'s translated in the ui.'); + } + + /** + * Take sure that the translations get's into the loaded view. + */ + public function testTranslation() { + $view = $this->view_unpack_translatable(); + $view->set_display('default'); + $view->pre_execute(); + $view->execute(); + + $expected_strings = array(); + foreach ($this->strings as $string) { + $expected_strings[] = $string .= '-translated'; + } + $this->assertEqual(sort($expected_strings), sort($view->localization_plugin->translated_strings), 'Take sure that every string got loaded translated'); + } + + public function view_unpack_translatable() { + $view = new view; + $view->name = 'view_unpack_translatable'; + $view->description = ''; + $view->tag = ''; + $view->base_table = 'node'; + $view->api_version = '3.0-alpha1'; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Defaults */ + $handler = $view->new_display('default', 'Defaults1', 'default'); + $handler->display->display_options['title'] = 'title1'; + $handler->display->display_options['use_more_text'] = 'more1'; + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['query']['type'] = 'views_query'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['exposed_form']['options']['submit_button'] = 'Apply1'; + $handler->display->display_options['exposed_form']['options']['reset_button'] = TRUE; + $handler->display->display_options['exposed_form']['options']['reset_button_label'] = 'Reset1'; + $handler->display->display_options['exposed_form']['options']['exposed_sorts_label'] = 'Sort By1'; + $handler->display->display_options['exposed_form']['options']['sort_asc_label'] = 'Asc1'; + $handler->display->display_options['exposed_form']['options']['sort_desc_label'] = 'Desc1'; + $handler->display->display_options['pager']['type'] = 'full'; + $handler->display->display_options['pager']['options']['items_per_page'] = '10'; + $handler->display->display_options['pager']['options']['offset'] = '0'; + $handler->display->display_options['pager']['options']['id'] = '0'; + $handler->display->display_options['pager']['options']['expose']['items_per_page'] = TRUE; + $handler->display->display_options['pager']['options']['expose']['items_per_page_label'] = 'Items per page1'; + $handler->display->display_options['pager']['options']['expose']['offset'] = TRUE; + $handler->display->display_options['pager']['options']['expose']['offset_label'] = 'Offset1'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* Field: Node: Nid */ + $handler->display->display_options['fields']['nid']['id'] = 'nid'; + $handler->display->display_options['fields']['nid']['table'] = 'node'; + $handler->display->display_options['fields']['nid']['field'] = 'nid'; + $handler->display->display_options['fields']['nid']['label'] = 'fieldlabel1'; + $handler->display->display_options['fields']['nid']['alter']['alter_text'] = 0; + $handler->display->display_options['fields']['nid']['alter']['make_link'] = 0; + $handler->display->display_options['fields']['nid']['alter']['trim'] = 0; + $handler->display->display_options['fields']['nid']['alter']['word_boundary'] = 1; + $handler->display->display_options['fields']['nid']['alter']['ellipsis'] = 1; + $handler->display->display_options['fields']['nid']['alter']['strip_tags'] = 0; + $handler->display->display_options['fields']['nid']['alter']['html'] = 0; + $handler->display->display_options['fields']['nid']['hide_empty'] = 0; + $handler->display->display_options['fields']['nid']['empty_zero'] = 0; + $handler->display->display_options['fields']['nid']['link_to_node'] = 0; + /* Filter: Node: Nid */ + $handler->display->display_options['filters']['nid']['id'] = 'nid'; + $handler->display->display_options['filters']['nid']['table'] = 'node'; + $handler->display->display_options['filters']['nid']['field'] = 'nid'; + $handler->display->display_options['filters']['nid']['exposed'] = TRUE; + $handler->display->display_options['filters']['nid']['expose']['operator'] = 'nid_op'; + $handler->display->display_options['filters']['nid']['expose']['label'] = 'filterlabel1'; + $handler->display->display_options['filters']['nid']['expose']['identifier'] = 'nid'; + $handler->display->display_options['filters']['nid']['expose']['single'] = 0; + $handler->display->display_options['filters']['nid']['expose']['reduce'] = 0; + + return $view; + } +} diff --git a/sites/all/modules/views/theme/theme.inc b/sites/all/modules/views/theme/theme.inc new file mode 100644 index 0000000000000000000000000000000000000000..a005c96d9f7f8ff7d9a2e94d30fe2a1b87508bfc --- /dev/null +++ b/sites/all/modules/views/theme/theme.inc @@ -0,0 +1,938 @@ +<?php +// $Id: theme.inc,v 1.84.4.43 2011/01/04 00:00:20 dereine Exp $ + +/** + * @file theme.inc + * + * An array of preprocessors to fill variables for templates and helper + * functions to make theming easier. + */ + +/** + * Provide a full array of possible themes to try for a given hook. + * + * @param $hook + * The hook to use. This is the base theme/template name. + * @param $view + * The view being rendered. + * @param $display + * The display being rendered, if applicable. + */ +function _views_theme_functions($hook, $view, $display = NULL) { + $themes = array(); + + if ($display) { + $themes[] = $hook . '__' . $view->name . '__' . $display->id; + $themes[] = $hook . '__' . $display->id; + $themes[] = $hook . '__' . preg_replace('/[^a-z0-9]/', '_', strtolower($view->tag)); + if ($display->id != $display->display_plugin) { + $themes[] = $hook . '__' . $view->name . '__' . $display->display_plugin; + $themes[] = $hook . '__' . $display->display_plugin; + } + } + $themes[] = $hook . '__' . $view->name; + $themes[] = $hook; + return $themes; +} + +/** + * Preprocess the primary theme implementation for a view. + */ +function template_preprocess_views_view(&$vars) { + global $base_path; + + $view = $vars['view']; + + $vars['rows'] = !empty($view->result) || !empty($view->style_plugin->definition['even empty']) ? $view->style_plugin->render($view->result) : ''; + + $vars['css_name'] = drupal_clean_css_identifier($view->name); + $vars['name'] = $view->name; + $vars['display_id'] = $view->current_display; + + // Basic classes + $vars['classes_array'] = array(); + $vars['classes_array'][] = 'view'; + $vars['classes_array'][] = 'view-' . drupal_clean_css_identifier($vars['name']); + $vars['classes_array'][] = 'view-id-' . $vars['name']; + $vars['classes_array'][] = 'view-display-id-' . $vars['display_id']; + + $css_class = $view->display_handler->get_option('css_class'); + if (!empty($css_class)) { + $vars['css_class'] = preg_replace('/[^a-zA-Z0-9- ]/', '-', $css_class); + $vars['classes_array'][] = $vars['css_class']; + } + + $empty = empty($vars['rows']); + + $vars['header'] = $view->display_handler->render_area('header', $empty); + $vars['footer'] = $view->display_handler->render_area('footer', $empty); + if ($empty) { + $vars['empty'] = $view->display_handler->render_area('empty'); + } + + $vars['exposed'] = !empty($view->exposed_widgets) ? $view->exposed_widgets : ''; + $vars['more'] = $view->display_handler->render_more_link(); + $vars['feed_icon'] = !empty($view->feed_icon) ? $view->feed_icon : ''; + $vars['pager'] = $view->query->render_pager(); + + $vars['attachment_before'] = !empty($view->attachment_before) ? $view->attachment_before : ''; + $vars['attachment_after'] = !empty($view->attachment_after) ? $view->attachment_after : ''; + + // if administrator, add some links. These used to be tabs, but this is better. + if (user_access('administer views') && module_exists('views_ui') && module_exists('contextual') && empty($view->hide_admin_links) && !variable_get('views_no_hover_links', FALSE)) { + $links = array( + 'views-edit' => array( + 'title' => t('Edit view'), + 'attributes' => array('title' => t("Edit this view")), + 'href' => "admin/structure/views/edit/$view->name", + 'fragment' => 'views-tab-' . $view->current_display, + 'query' => drupal_get_destination(), + ), + ); + drupal_alter('views_admin_links', $links, $view); + + $build = array( + '#prefix' => '<div class="contextual-links-wrapper">', + '#suffix' => '</div>', + '#theme' => 'links__contextual', + '#links' => $links, + '#attributes' => array('class' => array('contextual-links')), + '#attached' => array( + 'library' => array(array('contextual', 'contextual-links')), + ), + ); + $vars['classes_array'][] = 'contextual-links-region'; + $vars['admin_links'] = drupal_render($build); + } + else { + $vars['admin_links'] = ''; + $vars['admin_links_raw'] = array(); + } + + // Attachments are always updated with the outer view, never by themselves, + // so they do not have dom ids. + if (empty($view->is_attachment)) { + // Our JavaScript needs to have some means to find the HTML belonging to this + // view. + // + // It is true that the DIV wrapper has classes denoting the name of the view + // and its display ID, but this is not enough to unequivocally match a view + // with its HTML, because one view may appear several times on the page. So + // we set up a running counter, $dom_id, to issue a "unique" identifier for + // each view. This identifier is written to both Drupal.settings and the DIV + // wrapper. + static $dom_id = 1; + $vars['dom_id'] = !empty($view->dom_id) ? $view->dom_id : $dom_id++; + $vars['classes_array'][] = 'view-dom-id-' . $vars['dom_id']; + } + + // If using AJAX, send identifying data about this view. + if ($view->use_ajax && empty($view->is_attachment)) { + $settings = array( + 'views' => array( + 'ajax_path' => url('views/ajax'), + 'ajaxViews' => array( + array( + 'view_name' => $view->name, + 'view_display_id' => $view->current_display, + 'view_args' => check_plain(implode('/', $view->args)), + 'view_path' => check_plain($_GET['q']), + // Pass through URL to ensure we get e.g. language prefixes. +// 'view_base_path' => isset($view->display['page']) ? substr(url($view->display['page']->display_options['path']), strlen($base_path)) : '', + 'view_base_path' => $view->get_path(), + 'view_dom_id' => $vars['dom_id'], + // To fit multiple views on a page, the programmer may have + // overridden the display's pager_element. + 'pager_element' => isset($view->query->pager) ? $view->query->pager->get_pager_id() : 0, + ), + ), + ), + ); + + drupal_add_js($settings, 'setting'); + views_add_js('ajax_view'); + } + // Flatten the classes to a string for the template file. + $vars['classes'] = implode(' ', $vars['classes_array']); +} + +/** + * Preprocess theme function to print a single record from a row, with fields + */ +function template_preprocess_views_view_fields(&$vars) { + $view = $vars['view']; + + // Loop through the fields for this view. + $inline = FALSE; + $vars['fields'] = array(); // ensure it's at least an empty array. + foreach ($view->field as $id => $field) { + // render this even if set to exclude so it can be used elsewhere. + $field_output = $view->style_plugin->get_field($view->row_index, $id); + $empty = $field_output !== 0 && empty($field_output); + if (empty($field->options['exclude']) && (!$empty || (empty($field->options['hide_empty']) && empty($vars['options']['hide_empty'])))) { + $object = new stdClass(); + $object->handler = &$view->field[$id]; + + $object->element_type = $object->handler->element_type(TRUE); + if ($object->element_type) { + $class = ''; + if ($object->handler->options['element_default_classes']) { + $class = 'field-content'; + } + + if ($classes = $object->handler->element_classes()) { + if ($class) { + $class .= ' '; + } + $class .= $classes; + } + + $field_output = '<' . $object->element_type . ' class="' . $class . '">' . $field_output . '</' . $object->element_type . '>'; + } + + // Protect ourself somewhat for backward compatibility. This will prevent + // old templates from producing invalid HTML when no element type is selected. + if (empty($object->element_type)) { + $object->element_type = 'span'; + } + + $object->content = $field_output; + if (isset($view->field[$id]->field_alias) && isset($vars['row']->{$view->field[$id]->field_alias})) { + $object->raw = $vars['row']->{$view->field[$id]->field_alias}; + } + else { + $object->raw = NULL; // make sure it exists to reduce NOTICE + } + + if (!empty($vars['options']['separator']) && $inline && $object->inline && $object->content) { + $object->separator = filter_xss_admin($vars['options']['separator']); + } + + $object->class = drupal_clean_css_identifier($id); + $object->inline = !empty($vars['options']['inline'][$id]); + $inline = $object->inline; + $object->inline_html = $object->handler->element_wrapper_type(TRUE, TRUE); + + if ($object->inline_html === '') { + $object->inline_html = $object->inline ? 'span' : 'div'; + } + + // Set up the wrapper HTML. + $object->wrapper_prefix = ''; + $object->wrapper_suffix = ''; + + if ($object->inline_html) { + $class = ''; + if ($object->handler->options['element_default_classes']) { + $class = "views-field views-field-" . $object->class; + } + + if ($classes = $object->handler->element_wrapper_classes()) { + if ($class) { + $class .= ' '; + } + $class .= ' ' . $classes; + } + + $object->wrapper_prefix = '<' . $object->inline_html; + if ($class) { + $object->wrapper_prefix .= ' class="' . $class . '"'; + } + $object->wrapper_prefix .= '>'; + $object->wrapper_suffix = '</' . $object->inline_html . '>'; + } + + // Set up the label for the value and the HTML to make it easier + // on the template. + $object->label = check_plain($view->field[$id]->label()); + $object->label_html = ''; + $object->element_label_type = $object->handler->element_label_type(TRUE); + if ($object->element_label_type && $object->label) { + $class = ''; + if ($object->handler->options['element_default_classes']) { + $class = 'views-label-' . $object->class; + } + + $element_label_class = $object->handler->element_label_classes(); + if ($element_label_class) { + if ($class) { + $class .= ' '; + } + + $class .= $element_label_class; + } + + $object->label_html = '<' . $object->element_label_type . ' class="' . $class . '">'; + $object->label_html .= $object->label; + if ($object->handler->options['element_label_colon']) { + $object->label_html .= ': '; + } + $object->label_html .= '</' . $object->element_label_type . '>'; + } + + $vars['fields'][$id] = $object; + } + } + +} + +/** + * Display a single views field. + * + * Interesting bits of info: + * $field->field_alias says what the raw value in $row will be. Reach it like + * this: @code { $row->{$field->field_alias} @endcode + */ +function theme_views_view_field($vars) { + $view = $vars['view']; + $field = $vars['field']; + $row = $vars['row']; + return $vars['output']; +} + +/** + * Process a single field within a view. + * + * This preprocess function isn't normally run, as a function is used by + * default, for performance. However, by creating a template, this + * preprocess should get picked up. + */ +function template_preprocess_views_view_field(&$vars) { + $vars['output'] = $vars['field']->advanced_render($vars['row']); +} + +/** + * Preprocess theme function to print a single record from a row, with fields + */ +function template_preprocess_views_view_summary(&$vars) { + $view = $vars['view']; + $argument = $view->argument[$view->build_info['summary_level']]; + + $url_options = array(); + + if (!empty($view->exposed_raw_input)) { + $url_options['query'] = $view->exposed_raw_input; + } + $vars['classes'] = array(); + foreach ($vars['rows'] as $id => $row) { + $vars['rows'][$id]->link = $argument->summary_name($row); + $args = $view->args; + $args[$argument->position] = $argument->summary_argument($row); + + $base_path = NULL; + if (!empty($argument->options['style_options']['base_path'])) { + $base_path = $argument->options['style_options']['base_path']; + } + $vars['rows'][$id]->url = url($view->get_url($args, $base_path), $url_options); + $vars['rows'][$id]->count = intval($row->{$argument->count_alias}); + if ($vars['rows'][$id]->url == base_path() . $_GET['q'] || $vars['rows'][$id]->url == base_path() . drupal_get_path_alias($_GET['q'])) { + $vars['classes'][$id] = 'active'; + } + } +} + +/** + * Template preprocess theme function to print summary basically + * unformatted. + */ +function template_preprocess_views_view_summary_unformatted(&$vars) { + $view = $vars['view']; + $argument = $view->argument[$view->build_info['summary_level']]; + $vars['classes'] = array(); + + $url_options = array(); + + if (!empty($view->exposed_raw_input)) { + $url_options['query'] = $view->exposed_raw_input; + } + + $count = 0; + foreach ($vars['rows'] as $id => $row) { + // only false on first time: + if ($count++) { + $vars['rows'][$id]->separator = filter_xss_admin($vars['options']['separator']); + } + $vars['rows'][$id]->link = $argument->summary_name($row); + $args = $view->args; + $args[$argument->position] = $argument->summary_argument($row); + + $base_path = NULL; + if (!empty($argument->options['style_options']['base_path'])) { + $base_path = $argument->options['style_options']['base_path']; + } + $vars['rows'][$id]->url = url($view->get_url($args, $base_path), $url_options); + $vars['rows'][$id]->count = intval($row->{$argument->count_alias}); + if ($vars['rows'][$id]->url == base_path() . $_GET['q'] || $vars['rows'][$id]->url == base_path() . drupal_get_path_alias($_GET['q'])) { + $vars['classes'][$id] = 'active'; + } + } +} + +/** + * Display a view as a table style. + */ +function template_preprocess_views_view_table(&$vars) { + $view = $vars['view']; + + // We need the raw data for this grouping, which is passed in as $vars['rows']. + // However, the template also needs to use for the rendered fields. We + // therefore swap the raw data out to a new variable and reset $vars['rows'] + // so that it can get rebuilt. + // Store rows so that they may be used by further preprocess functions. + $result = $vars['result'] = $vars['rows']; + $vars['rows'] = array(); + $vars['field_classes'] = array(); + + $options = $view->style_plugin->options; + $handler = $view->style_plugin; + + $fields = &$view->field; + $columns = $handler->sanitize_columns($options['columns'], $fields); + + $active = !empty($handler->active) ? $handler->active : ''; + $order = !empty($handler->order) ? $handler->order : 'asc'; + + $query = tablesort_get_query_parameters(); + + $header = array(); + + // Fields must be rendered in order as of Views 2.3, so we will pre-render + // everything. + $renders = $handler->render_fields($result); + + foreach ($columns as $field => $column) { + // Create a second variable so we can easily find what fields we have and what the + // CSS classes should be. + $vars['fields'][$field] = drupal_clean_css_identifier($field); + if ($active == $field) { + $vars['fields'][$field] .= ' active'; + } + + // render the header labels + if ($field == $column && empty($fields[$field]->options['exclude'])) { + $label = check_plain(!empty($fields[$field]) ? $fields[$field]->label() : ''); + if (empty($options['info'][$field]['sortable']) || !$fields[$field]->click_sortable()) { + $vars['header'][$field] = $label; + } + else { + $initial = !empty($options['info'][$field]['default_sort_order']) ? $options['info'][$field]['default_sort_order'] : 'asc'; + + if ($active == $field) { + $initial = ($order == 'asc') ? 'desc' : 'asc'; + } + + $title = t('sort by @s', array('@s' => $label)); + if ($active == $field) { + $label .= theme('tablesort_indicator', array('style' => $initial)); + } + + $query['order'] = $field; + $query['sort'] = $initial; + $link_options = array( + 'html' => TRUE, + 'attributes' => array('title' => $title), + 'query' => $query, + ); + $vars['header'][$field] = l($label, $_GET['q'], $link_options); + } + + $vars['header_classes'][$field] = ''; + // Set up the header label class. + if ($fields[$field]->options['element_default_classes']) { + $vars['header_classes'][$field] .= "views-field views-field-" . $vars['fields'][$field]; + } + $class = $fields[$field]->element_label_classes(); + if ($class) { + if ($vars['header_classes'][$field]) { + $vars['header_classes'][$field] .= ' '; + } + $vars['header_classes'][$field] .= $class; + } + + // Add a header label wrapper if one was selected. + if ($vars['header'][$field]) { + $element_label_type = $fields[$field]->element_label_type(TRUE, TRUE); + if ($element_label_type) { + $vars['header'][$field] = '<' . $element_label_type . '>' . $vars['header'][$field] . '</' . $element_label_type . '>'; + } + } + + } + + // Add a CSS align class to each field if one was set + if (!empty($options['info'][$field]['align'])) { + $vars['fields'][$field] .= ' ' . drupal_clean_css_identifier($options['info'][$field]['align']); + } + + // Render each field into its appropriate column. + foreach ($result as $num => $row) { + // Add field classes + $vars['field_classes'][$field][$num] = ''; + if ($fields[$field]->options['element_default_classes']) { + $vars['field_classes'][$field][$num] = "views-field views-field-" . $vars['fields'][$field]; + } + if ($classes = $fields[$field]->element_classes()) { + if ($vars['field_classes'][$field][$num]) { + $vars['field_classes'][$field][$num] .= ' '; + } + + $vars['field_classes'][$field][$num] .= $classes; + } + + if (!empty($fields[$field]) && empty($fields[$field]->options['exclude'])) { + $field_output = $renders[$num][$field]; + $element_type = $fields[$field]->element_type(TRUE, TRUE); + if ($element_type) { + $field_output = '<' . $element_type . '>' . $field_output . '</' . $element_type . '>'; + } + + // Don't bother with separators and stuff if the field does not show up. + if (empty($field_output) && !empty($vars['rows'][$num][$column])) { + continue; + } + + // Place the field into the column, along with an optional separator. + if (!empty($vars['rows'][$num][$column])) { + if (!empty($options['info'][$column]['separator'])) { + $vars['rows'][$num][$column] .= filter_xss_admin($options['info'][$column]['separator']); + } + } + else { + $vars['rows'][$num][$column] = ''; + } + + $vars['rows'][$num][$column] .= $field_output; + } + } + } + + $count = 0; + foreach ($vars['rows'] as $num => $row) { + $vars['row_classes'][$num][] = ($count++ % 2 == 0) ? 'odd' : 'even'; + if ($row_class = $handler->get_row_class($num)) { + $vars['row_classes'][$num][] = $row_class; + } + } + + $vars['row_classes'][0][] = 'views-row-first'; + $vars['row_classes'][count($vars['row_classes']) - 1][] = 'views-row-last'; + + $vars['classes_array'] = array('views-table'); + if (!empty($options['sticky'])) { + drupal_add_js('misc/tableheader.js'); + $vars['classes_array'][] = "sticky-enabled"; + } + $vars['classes_array'][] = 'cols-'. count($vars['rows']); + + if (!empty($handler->options['summary'])) { + $vars['attributes_array'] = array('summary' => $handler->options['summary']); + } +} + +/** + * Display a view as a grid style. + */ +function template_preprocess_views_view_grid(&$vars) { + $view = $vars['view']; + $result = $view->result; + $options = $view->style_plugin->options; + $handler = $view->style_plugin; + + $columns = $options['columns']; + + $rows = array(); + $row_indexes = array(); + + if ($options['alignment'] == 'horizontal') { + $row = array(); + $col_count = 0; + $row_count = 0; + $count = 0; + foreach ($vars['rows'] as $row_index => $item) { + $count++; + $row[] = $item; + $row_indexes[$row_count][$col_count] = $row_index; + $col_count++; + if ($count % $columns == 0) { + $rows[] = $row; + $row = array(); + $col_count = 0; + $row_count++; + } + } + if ($row) { + // Fill up the last line only if it's configured, but this is default. + if (!empty($handler->options['fill_single_line']) || count($rows)) { + for ($i = 0; $i < ($columns - $col_count); $i++) { + $row[] = ''; + } + } + $rows[] = $row; + } + } + else { + $num_rows = floor(count($vars['rows']) / $columns); + // The remainders are the 'odd' columns that are slightly longer. + $remainders = count($vars['rows']) % $columns; + $row = 0; + $col = 0; + foreach ($vars['rows'] as $count => $item) { + $rows[$row][$col] = $item; + $row_indexes[$row][$col] = $count; + $row++; + + if (!$remainders && $row == $num_rows) { + $row = 0; + $col++; + } + elseif ($remainders && $row == $num_rows + 1) { + $row = 0; + $col++; + $remainders--; + } + } + for ($i = 0; $i < count($rows[0]); $i++) { + // This should be string so that's okay :) + if (!isset($rows[count($rows) - 1][$i])) { + $rows[count($rows) - 1][$i] = ''; + } + } + } + + // Apply the row classes + foreach ($rows as $row_number => $row) { + $row_classes = array(); + $row_classes[] = 'row-' . ($row_number + 1); + if ($row_number == 0) { + $row_classes[] = 'row-first'; + } + if (count($rows) == ($row_number + 1)) { + $row_classes[] = 'row-last'; + } + $vars['row_classes'][$row_number] = implode(' ', $row_classes); + foreach ($rows[$row_number] as $column_number => $item) { + $column_classes = array(); + $column_classes[] = 'col-'. ($column_number + 1); + if ($column_number == 0) { + $column_classes[] = 'col-first'; + } + elseif (count($rows[$row_number]) == ($column_number + 1)) { + $column_classes[] = 'col-last'; + } + if (isset($row_indexes[$row_number][$column_number]) && $column_class = $view->style_plugin->get_row_class($row_indexes[$row_number][$column_number])) { + $column_classes[] = $column_class; + } + $vars['column_classes'][$row_number][$column_number] = implode(' ', $column_classes); + } + } + $vars['rows'] = $rows; + + if (!empty($handler->options['summary'])) { + $vars['attributes_array'] = array('summary' => $handler->options['summary']); + } +} + +/** + * Display the simple view of rows one after another + */ +function template_preprocess_views_view_unformatted(&$vars) { + $view = $vars['view']; + $rows = $vars['rows']; + + $vars['classes_array'] = array(); + $vars['classes'] = array(); + // Set up striping values. + $count = 0; + $max = count($rows); + foreach ($rows as $id => $row) { + $count++; + $vars['classes'][$id][] = 'views-row'; + $vars['classes'][$id][] = 'views-row-' . $count; + $vars['classes'][$id][] = 'views-row-' . ($count % 2 ? 'odd' : 'even'); + if ($count == 1) { + $vars['classes'][$id][] = 'views-row-first'; + } + if ($count == $max) { + $vars['classes'][$id][] = 'views-row-last'; + } + + if ($row_class = $view->style_plugin->get_row_class($id)) { + $vars['classes'][$id][] = $row_class; + } + + // Flatten the classes to a string for each row for the template file. + $vars['classes_array'][$id] = implode(' ', $vars['classes'][$id]); + } +} + +/** + * Display the view as an HTML list element + */ +function template_preprocess_views_view_list(&$vars) { + $handler = $vars['view']->style_plugin; + + $vars['class'] = drupal_clean_css_identifier($handler->options['class']); + $vars['wrapper_class'] = drupal_clean_css_identifier($handler->options['wrapper_class']); + $vars['wrapper_prefix'] = ''; + $vars['wrapper_suffix'] = ''; + $vars['list_type_prefix'] = '<' . $handler->options['type'] . '>'; + $vars['list_type_suffix'] = '</' . $handler->options['type'] . '>'; + if ($vars['wrapper_class']) { + $vars['wrapper_prefix'] = '<div class="' . $vars['wrapper_class'] . '">'; + $vars['wrapper_suffix'] = '</div>'; + } + + if ($vars['class']) { + $vars['list_type_prefix'] = '<' . $handler->options['type'] . ' class="' . $vars['class'] . '">'; + } + template_preprocess_views_view_unformatted($vars); +} + +/** + * Preprocess an RSS feed + */ +function template_preprocess_views_view_rss(&$vars) { + global $base_url; + global $language; + + $view = &$vars['view']; + $options = &$vars['options']; + $items = &$vars['rows']; + + $style = &$view->style_plugin; + + // The RSS 2.0 "spec" doesn't indicate HTML can be used in the description. + // We strip all HTML tags, but need to prevent double encoding from properly + // escaped source data (such as & becoming &amp;). + $vars['description'] = check_plain(decode_entities(strip_tags($options['description']))); + + if ($view->display_handler->get_option('sitename_title')) { + $title = variable_get('site_name', 'Drupal'); + if ($slogan = variable_get('site_slogan', '')) { + $title .= ' - ' . $slogan; + } + } + else { + $title = $view->get_title(); + } + $vars['title'] = check_plain($title); + + // Figure out which display which has a path we're using for this feed. If there isn't + // one, use the global $base_url + $link_display_id = $view->display_handler->get_link_display(); + if ($link_display_id && !empty($view->display[$link_display_id])) { + $path = $view->display[$link_display_id]->handler->get_path(); + } + + if ($path) { + $path = $view->get_url(NULL, $path); + $url_options = array('absolute' => TRUE); + if (!empty($view->exposed_raw_input)) { + $url_options['query'] = $view->exposed_raw_input; + } + + // Compare the link to the default home page; if it's the default home page, just use $base_url. + if ($path == variable_get('site_frontpage', 'node')) { + $path = ''; + } + + $vars['link'] = check_url(url($path, $url_options)); + } + + $vars['langcode'] = check_plain($language->language); + $vars['namespaces'] = drupal_attributes($style->namespaces); + $vars['items'] = $items; + $vars['channel_elements'] = format_xml_elements($style->channel_elements); + + drupal_add_http_header('Content-Type', 'application/rss+xml; charset=utf-8'); +} + +/** + * Default theme function for all RSS rows. + */ +function template_preprocess_views_view_row_rss(&$vars) { + $view = &$vars['view']; + $options = &$vars['options']; + $item = &$vars['row']; + + $vars['title'] = check_plain($item->title); + $vars['link'] = check_url($item->link); + $vars['description'] = check_plain($item->description); + $vars['item_elements'] = empty($item->elements) ? '' : format_xml_elements($item->elements); +} + +/** + * Default theme function for all filter forms. + */ +function template_preprocess_views_exposed_form(&$vars) { + $form = &$vars['form']; + + // Put all single checkboxes together in the last spot. + $checkboxes = ''; + + if (!empty($form['q'])) { + $vars['q'] = drupal_render($form['q']); + } + + $vars['widgets'] = array(); + foreach ($form['#info'] as $id => $info) { + // Set aside checkboxes. + if (isset($form[$info['value']]['#type']) && $form[$info['value']]['#type'] == 'checkbox') { + $checkboxes .= drupal_render($form[$info['value']]); + continue; + } + $widget = new stdClass; + // set up defaults so that there's always something there. + $widget->label = $widget->operator = $widget->widget = NULL; + + $widget->id = $form[$info['value']]['#id']; + if (!empty($info['label'])) { + $widget->label = $info['label']; + } + if (!empty($info['operator'])) { + $widget->operator = drupal_render($form[$info['operator']]); + } + $widget->widget = drupal_render($form[$info['value']]); + $vars['widgets'][$id] = $widget; + } + + // Wrap up all the checkboxes we set aside into a widget. + if ($checkboxes) { + $widget = new stdClass; + // set up defaults so that there's always something there. + $widget->label = $widget->operator = $widget->widget = NULL; + $widget->widget = $checkboxes; + $vars['widgets']['checkboxes'] = $widget; + } + + if (isset($form['sort_by'])) { + $vars['sort_by'] = drupal_render($form['sort_by']); + $vars['sort_order'] = drupal_render($form['sort_order']); + } + if (isset($form['items_per_page'])) { + $vars['items_per_page'] = drupal_render($form['items_per_page']); + } + if (isset($form['offset'])) { + $vars['offset'] = drupal_render($form['offset']); + } + if (isset($form['reset'])) { + $vars['reset_button'] = drupal_render($form['reset']); + } + // This includes the submit button. + $vars['button'] = drupal_render_children($form); +} + +function theme_views_mini_pager($vars) { + global $pager_page_array, $pager_total; + + $tags = $vars['tags']; + $element = $vars['element']; + $parameters = $vars['parameters']; + $quantity = $vars['quantity']; + + // Calculate various markers within this pager piece: + // Middle is used to "center" pages around the current page. + $pager_middle = ceil($quantity / 2); + // current is the page we are currently paged to + $pager_current = $pager_page_array[$element] + 1; + // max is the maximum page number + $pager_max = $pager_total[$element]; + // End of marker calculations. + + + $li_previous = theme('pager_previous', + array( + 'text' => (isset($tags[1]) ? $tags[1] : t('‹‹')), + 'element' => $element, + 'interval' => 1, + 'parameters' => $parameters, + ) + ); + if (empty($li_previous)) { + $li_previous = " "; + } + + $li_next = theme('pager_next', + array( + 'text' => (isset($tags[3]) ? $tags[3] : t('››')), + 'element' => $element, + 'interval' => 1, + 'parameters' => $parameters, + ) + ); + if (empty($li_next)) { + $li_next = " "; + } + + if ($pager_total[$element] > 1) { + $items[] = array( + 'class' => array('pager-previous'), + 'data' => $li_previous, + ); + + $items[] = array( + 'class' => array('pager-current'), + 'data' => t('@current of @max', array('@current' => $pager_current, '@max' => $pager_max)), + ); + + $items[] = array( + 'class' => array('pager-next'), + 'data' => $li_next, + ); + return theme('item_list', + array( + 'items' => $items, + 'title' => NULL, + 'type' => 'ul', + 'attributes' => array('class' => array('pager')), + ) + ); + } +} + +/** + * @defgroup views_templates Views' template files + * @{ + * All views templates can be overridden with a variety of names, using + * the view, the display ID of the view, the display type of the view, + * or some combination thereof. + * + * For each view, there will be a minimum of two templates used. The first + * is used for all views: views-view.tpl.php. + * + * The second template is determined by the style selected for the view. Note + * that certain aspects of the view can also change which style is used; for + * example, arguments which provide a summary view might change the style to + * one of the special summary styles. + * + * The default style for all views is views-view-unformatted.tpl.php + * + * Many styles will then farm out the actual display of each row to a row + * style; the default row style is views-view-fields.tpl.php. + * + * Here is an example of all the templates that will be tried in the following + * case: + * + * View, named foobar. Style: unformatted. Row style: Fields. Display: Page. + * + * - views-view--foobar--page.tpl.php + * - views-view--page.tpl.php + * - views-view--foobar.tpl.php + * - views-view.tpl.php + * + * - views-view-unformatted--foobar--page.tpl.php + * - views-view-unformatted--page.tpl.php + * - views-view-unformatted--foobar.tpl.php + * - views-view-unformatted.tpl.php + * + * - views-view-fields--foobar--page.tpl.php + * - views-view-fields--page.tpl.php + * - views-view-fields--foobar.tpl.php + * - views-view-fields.tpl.php + * + * Important! When adding a new template to your theme, be sure to flush the + * theme registry cache! + * + * @see _views_theme_functions + * @} + */ diff --git a/sites/all/modules/views/theme/views-exposed-form.tpl.php b/sites/all/modules/views/theme/views-exposed-form.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..52f50c2e7856a3875c7470c1f81b6ff23cec4238 --- /dev/null +++ b/sites/all/modules/views/theme/views-exposed-form.tpl.php @@ -0,0 +1,76 @@ +<?php +// $Id: views-exposed-form.tpl.php,v 1.4.6.6 2010/08/13 21:45:25 merlinofchaos Exp $ +/** + * @file views-exposed-form.tpl.php + * + * This template handles the layout of the views exposed filter form. + * + * Variables available: + * - $widgets: An array of exposed form widgets. Each widget contains: + * - $widget->label: The visible label to print. May be optional. + * - $widget->operator: The operator for the widget. May be optional. + * - $widget->widget: The widget itself. + * - $sort_by: The select box to sort the view using an exposed form. + * - $sort_order: The select box with the ASC, DESC options to define order. May be optional. + * - $items_per_page: The select box with the available items per page. May be optional. + * - $offset: A textfield to define the offset of the view. May be optional. + * - $reset_button: A button to reset the exposed filter applied. May be optional. + * - $button: The submit button for the form. + * + * @ingroup views_templates + */ +?> +<?php if (!empty($q)): ?> + <?php + // This ensures that, if clean URLs are off, the 'q' is added first so that + // it shows up first in the URL. + print $q; + ?> +<?php endif; ?> +<div class="views-exposed-form"> + <div class="views-exposed-widgets clearfix"> + <?php foreach($widgets as $id => $widget): ?> + <div class="views-exposed-widget views-widget-<?php print $id ?>"> + <?php if (!empty($widget->label)): ?> + <label for="<?php print $widget->id; ?>"> + <?php print $widget->label; ?> + </label> + <?php endif; ?> + <?php if (!empty($widget->operator)): ?> + <div class="views-operator"> + <?php print $widget->operator; ?> + </div> + <?php endif; ?> + <div class="views-widget"> + <?php print $widget->widget; ?> + </div> + </div> + <?php endforeach; ?> + <?php if (!empty($sort_by)): ?> + <div class="views-exposed-widget"> + <?php print $sort_by; ?> + </div> + <div class="views-exposed-widget"> + <?php print $sort_order; ?> + </div> + <?php endif; ?> + <?php if (!empty($items_per_page)): ?> + <div class="views-exposed-widget"> + <?php print $items_per_page; ?> + </div> + <?php endif; ?> + <?php if (!empty($offset)): ?> + <div class="views-exposed-widget"> + <?php print $offset; ?> + </div> + <?php endif; ?> + <div class="views-exposed-widget views-submit-button"> + <?php print $button ?> + </div> + <?php if (!empty($reset_button)): ?> + <div class="views-exposed-widget views-reset-button"> + <?php print $reset_button; ?> + </div> + <?php endif; ?> + </div> +</div> diff --git a/sites/all/modules/views/theme/views-more.tpl.php b/sites/all/modules/views/theme/views-more.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..d56ae178d6f84c4fb611ed2b48a33deeac9265b0 --- /dev/null +++ b/sites/all/modules/views/theme/views-more.tpl.php @@ -0,0 +1,17 @@ +<?php +// $Id: views-more.tpl.php,v 1.3.4.1 2009/11/02 22:01:27 merlinofchaos Exp $ +/** + * @file views-more.tpl.php + * Theme the more link + * + * - $more_url: the url for the more link + * + * @ingroup views_templates + */ +?> + +<div class="more-link"> + <a href="<?php print $more_url ?>"> + <?php print $link_text; ?> + </a> +</div> diff --git a/sites/all/modules/views/theme/views-ui-edit-item.tpl.php b/sites/all/modules/views/theme/views-ui-edit-item.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..e5ebcd675e75a69e02ea8a2a103c9240ab5cecfd --- /dev/null +++ b/sites/all/modules/views/theme/views-ui-edit-item.tpl.php @@ -0,0 +1,46 @@ +<?php +// $Id: views-ui-edit-item.tpl.php,v 1.9 2008/08/08 16:57:44 merlinofchaos Exp $ +/** + * @file views-ui-edit-item.tpl.php + * + * This template handles the printing of fields/filters/sort criteria/arguments or relationships. + */ +?> +<?php print $rearrange; ?> +<?php print $add; ?> +<div class="views-category-title<?php + if ($overridden) { + print ' overridden'; + } + if ($defaulted) { + print ' defaulted'; + } + ?>"> + <?php print $item_help_icon; ?> + <?php print $title; ?> +</div> + +<div class="views-category-content<?php + if ($overridden) { + print ' overridden'; + } + if ($defaulted) { + print ' defaulted'; + } + ?>"> + <?php if (!empty($no_fields)): ?> + <div><?php print t('The style selected does not utilize fields.'); ?></div> + <?php elseif (empty($fields)): ?> + <div><?php print t('None defined'); ?></div> + <?php else: ?> + <?php foreach ($fields as $pid => $field): ?> + <?php if (!empty($field['links'])): ?> + <?php print $field['links']; ?> + <?php endif; ?> + <div class="<?php print $field['class']; if (!empty($field['changed'])) { print ' changed'; } ?>"> + <?php print $field['title']; ?> + <?php print $field['info']; ?> + </div> + <?php endforeach; ?> + <?php endif; ?> +</div> diff --git a/sites/all/modules/views/theme/views-ui-edit-tab.tpl.php b/sites/all/modules/views/theme/views-ui-edit-tab.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..c0e423c4048d8aeec652ca232c6dac2b84dcf205 --- /dev/null +++ b/sites/all/modules/views/theme/views-ui-edit-tab.tpl.php @@ -0,0 +1,106 @@ +<?php +// $Id: views-ui-edit-tab.tpl.php,v 1.11.6.4 2010/12/24 08:25:02 dereine Exp $ +/** + * @file views-ui-edit-tab.tpl.php + * Template for the primary view editing window. + */ +?> +<div class="clearfix views-display views-display-<?php print $display->id; if (!empty($display->deleted)) { print ' views-display-deleted'; }; ?>"> + <?php // top section ?> + <?php if ($remove): ?> + <div class="remove-display"><?php print $remove ?></div> + <?php endif; ?> + <?php if ($clone): ?> + <div class="clone-display"><?php print $clone ?></div> + <?php endif; ?> + <div class="top"> + <div class="inside"> + <?php print $display_help_icon; ?> + <span class="display-title"> + <?php print $title; ?> + </span> + <span class="display-description"> + <?php print $description; ?> + </span> + </div> + </div> + + <?php // left section ?> + <div class="left tab-section"> + <div class="inside"> + <?php // If this is the default display, add some basic stuff here. ?> + <?php if ($default): ?> + <div class="views-category"> + <div class="views-category-title"><?php print t('View settings'); ?></div> + <div class="views-category-content"> + <?php foreach ($details as $name => $detail): ?> + <div class="<?php $details_class[$name]; if (!empty($details_changed[$name])) { print ' changed'; }?>"> + <?php print $detail ?> + </div> + <?php endforeach; ?> + </div> + </div> + <?php endif; ?> + + <?php foreach ($categories as $category_id => $category): ?> + <div class="views-category"> + <div class="views-category-title views-category-<?php print $category_id; ?>"> + <?php print $category['title']; ?> + </div> + <div class="views-category-content"> + <?php foreach ($category['data'] as $data): ?> + <div class="<?php + print $data['class']; + if (!empty($data['overridden'])) { + print ' overridden'; + } + if (!empty($data['defaulted'])) { + print ' defaulted'; + } + if (!empty($data['changed'])) { + print ' changed'; + }?>"> + <?php print $data['links'] . $data['content'] ?> + </div> + <?php endforeach; ?> + </div> + </div> + <?php endforeach; ?> + </div> + </div> + + <?php // middle section ?> + <div class="middle tab-section"> + <div class="inside"> + <?php foreach ($areas as $area): ?> + <div class="views-category"> + <?php print $area; ?> + </div> + <?php endforeach;?> + <?php if (!empty($fields)): ?> + <div class="views-category"> + <?php print $fields; ?> + </div> + <?php endif; ?> + </div> + </div> + + <?php // right section ?> + <div class="right tab-section"> + <div class="inside"> + <div class="views-category"> + <?php print $relationships; ?> + </div> + <div class="views-category"> + <?php print $arguments; ?> + </div> + <div class="views-category"> + <?php print $sorts; ?> + </div> + <div class="views-category"> + <?php print $filters; ?> + </div> + </div> + </div> + +</div> diff --git a/sites/all/modules/views/theme/views-ui-edit-view.tpl.php b/sites/all/modules/views/theme/views-ui-edit-view.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..5c515ab0ba5c2d85ab37ec3d887403172bdc10bb --- /dev/null +++ b/sites/all/modules/views/theme/views-ui-edit-view.tpl.php @@ -0,0 +1,46 @@ +<?php +// $Id: views-ui-edit-view.tpl.php,v 1.10.6.2 2010/10/16 14:55:13 dereine Exp $ +/** + * @file views-ui-edit-view.tpl.php + * Template for the primary view editing window. + */ +?> +<div class="views-edit-view"> + <?php if ($locked): ?> + <div class="view-locked"> + <?php print t('This view 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' => $locked, '!age' => $lock_age, '!break' => $break)); ?> + </div> + <?php endif; ?> + <div class="views-basic-info contextual-links-region clearfix<?php if (!empty($view->changed)) { print " changed"; }?>"> + <?php if (!is_numeric($view->vid)): ?> + <div class="view-changed view-new"><?php print t('New view'); ?></div> + <?php else: ?> + <div class="view-changed"><?php print t('Changed view'); ?></div> + <?php endif; ?> + <div class="views-quick-links"> + <?php print $quick_links ?> + </div> + <?php print t('View %name, displaying items of type <strong>@base</strong>.', + array('%name' => $view->name, '@base' => $base_table)); ?> + </div> + + <?php print $tabs; ?> + + <div id="views-ajax-form"> + <div id="views-ajax-title"> + <?php // This is initially empty ?> + </div> + <div id="views-ajax-pad"> + <?php /* This is sent in because it is also sent out through settings and + needs to be consistent. */ ?> + <?php print $message; ?> + </div> + </div> + + <?php print $save_button ?> + + <h2><?php print t('Live preview'); ?></h2> + <div id='views-live-preview'> + <?php print $preview ?> + </div> +</div> diff --git a/sites/all/modules/views/theme/views-ui-list-views.tpl.php b/sites/all/modules/views/theme/views-ui-list-views.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..76701e25432878afe840c6bdd1add3b877ca59f9 --- /dev/null +++ b/sites/all/modules/views/theme/views-ui-list-views.tpl.php @@ -0,0 +1,42 @@ +<?php +// $Id: views-ui-list-views.tpl.php,v 1.6.6.1 2010/01/20 23:24:24 dereine Exp $ +/** + * @file + * + * Displays the list of views on the administration screen. + */ +?> +<p><?php print $help; ?></p> +<?php print $widgets; ?> +<?php foreach ($views as $view): ?> + <table class="views-entry <?php print $view->classes; ?>"> + <tbody> + <tr> + <td class="view-name"> + <?php print $help_type_icon; ?> + <?php print t('<em>@type</em> @base view: <strong>@view</strong>', array('@type' => $view->type, '@view' => $view->name, '@base' => $view->base)); ?> + <?php if (!empty($view->tag)): ?> + (<?php print $view->tag; ?>) + <?php endif; ?> + </td> + <td class="view-ops"><?php print $view->ops ?></td> + </tr> + <tr> + <td> + <?php if ($view->title): ?> + <?php print t('Title: @title', array('@title' => $view->title)); ?> <br /> + <?php endif; ?> + <?php if (isset($view->path)): ?> + <?php print t('Path: !path', array('!path' => $view->path)); ?> <br /> + <?php endif; ?> + <?php if ($view->displays): ?> + <em><?php print $view->displays; ?> </em><br /> + <?php endif; ?> + </td> + <td colspan="2" class="description"> + <?php print $view->description; ?> + </td> + </tr> + </tbody> + </table> +<?php endforeach; ?> diff --git a/sites/all/modules/views/theme/views-view-field.tpl.php b/sites/all/modules/views/theme/views-view-field.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..6053d1d645f5655b3129c57fcf2477d15cea1847 --- /dev/null +++ b/sites/all/modules/views/theme/views-view-field.tpl.php @@ -0,0 +1,23 @@ +<?php +// $Id: views-view-field.tpl.php,v 1.1 2008/05/16 22:22:32 merlinofchaos Exp $ + /** + * This template is used to print a single field in a view. It is not + * actually used in default Views, as this is registered as a theme + * function which has better performance. For single overrides, the + * template is perfectly okay. + * + * Variables available: + * - $view: The view object + * - $field: The field handler object that can process the input + * - $row: The raw SQL result that can be used + * - $output: The processed output that will normally be used. + * + * When fetching output from the $row, this construct should be used: + * $data = $row->{$field->field_alias} + * + * The above will guarantee that you'll always get the correct data, + * regardless of any changes in the aliasing that might happen if + * the view is modified. + */ +?> +<?php print $output; ?> \ No newline at end of file diff --git a/sites/all/modules/views/theme/views-view-fields.tpl.php b/sites/all/modules/views/theme/views-view-fields.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..22d8c7e97f40dee5682daade40c89401c1f09058 --- /dev/null +++ b/sites/all/modules/views/theme/views-view-fields.tpl.php @@ -0,0 +1,36 @@ +<?php +// $Id: views-view-fields.tpl.php,v 1.6.6.1 2010/12/04 07:39:35 dereine Exp $ +/** + * @file views-view-fields.tpl.php + * Default simple view template to all the fields as a row. + * + * - $view: The view in use. + * - $fields: an array of $field objects. Each one contains: + * - $field->content: The output of the field. + * - $field->raw: The raw data for the field, if it exists. This is NOT output safe. + * - $field->class: The safe class id to use. + * - $field->handler: The Views field handler object controlling this field. Do not use + * var_export to dump this object, as it can't handle the recursion. + * - $field->inline: Whether or not the field should be inline. + * - $field->inline_html: either div or span based on the above flag. + * - $field->wrapper_prefix: A complete wrapper containing the inline_html to use. + * - $field->wrapper_suffix: The closing tag for the wrapper. + * - $field->separator: an optional separator that may appear before a field. + * - $field->label: The wrap label text to use. + * - $field->label_html: The full HTML of the label to use including + * configured element type. + * - $row: The raw result object from the query, with all data it fetched. + * + * @ingroup views_templates + */ +?> +<?php foreach ($fields as $id => $field): ?> + <?php if (!empty($field->separator)): ?> + <?php print $field->separator; ?> + <?php endif; ?> + + <?php print $field->wrapper_prefix; ?> + <?php print $field->label_html; ?> + <?php print $field->content; ?> + <?php print $field->wrapper_suffix; ?> +<?php endforeach; ?> diff --git a/sites/all/modules/views/theme/views-view-grid.tpl.php b/sites/all/modules/views/theme/views-view-grid.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..4c831e4ba5ef0e1a85c3fcb131e45b6f5610de32 --- /dev/null +++ b/sites/all/modules/views/theme/views-view-grid.tpl.php @@ -0,0 +1,28 @@ +<?php +// $Id: views-view-grid.tpl.php,v 1.3.6.3 2010/12/10 08:19:15 dereine Exp $ +/** + * @file views-view-grid.tpl.php + * Default simple view template to display a rows in a grid. + * + * - $rows contains a nested array of rows. Each row contains an array of + * columns. + * + * @ingroup views_templates + */ +?> +<?php if (!empty($title)) : ?> + <h3><?php print $title; ?></h3> +<?php endif; ?> +<table class="views-view-grid"<?php print $attributes; ?>> + <tbody> + <?php foreach ($rows as $row_number => $columns): ?> + <tr class="<?php print $row_classes[$row_number]; ?>"> + <?php foreach ($columns as $column_number => $item): ?> + <td class="<?php print $column_classes[$row_number][$column_number]; ?>"> + <?php print $item; ?> + </td> + <?php endforeach; ?> + </tr> + <?php endforeach; ?> + </tbody> +</table> diff --git a/sites/all/modules/views/theme/views-view-list.tpl.php b/sites/all/modules/views/theme/views-view-list.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..167f728d844670afb58225dc3b665f5266810478 --- /dev/null +++ b/sites/all/modules/views/theme/views-view-list.tpl.php @@ -0,0 +1,21 @@ +<?php +// $Id: views-view-list.tpl.php,v 1.3.6.3 2010/12/07 17:19:09 dereine Exp $ +/** + * @file views-view-list.tpl.php + * Default simple view template to display a list of rows. + * + * - $title : The title of this group of rows. May be empty. + * - $options['type'] will either be ul or ol. + * @ingroup views_templates + */ +?> +<?php print $wrapper_prefix; ?> + <?php if (!empty($title)) : ?> + <h3><?php print $title; ?></h3> + <?php endif; ?> + <?php print $list_type_prefix; ?> + <?php foreach ($rows as $id => $row): ?> + <li class="<?php print $classes_array[$id]; ?>"><?php print $row; ?></li> + <?php endforeach; ?> + <?php print $list_type_suffix; ?> +<?php print $wrapper_suffix; ?> diff --git a/sites/all/modules/views/theme/views-view-row-comment.tpl.php b/sites/all/modules/views/theme/views-view-row-comment.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..44b1b4360cf34552177b1a33b79934a0b5d4c464 --- /dev/null +++ b/sites/all/modules/views/theme/views-view-row-comment.tpl.php @@ -0,0 +1,18 @@ +<?php +// $Id: views-view-row-comment.tpl.php,v 1.1 2008/05/15 22:55:18 merlinofchaos Exp $ +/** + * @file views-view-row-comment.tpl.php + * Default simple view template to display a single comment. + * + * Rather than doing anything with this particular template, it is more + * efficient to use a variant of the comment.tpl.php based upon the view, + * which will be named comment-view-VIEWNAME.tpl.php. This isn't actually + * a views template, which is why it's not used here, but is a template + * 'suggestion' given to the comment template, and is used exactly + * the same as any other variant of the comment template file, such as + * node-nodeTYPE.tpl.php + * + * @ingroup views_templates + */ +?> +<?php print $comment; ?> \ No newline at end of file diff --git a/sites/all/modules/views/theme/views-view-row-node.tpl.php b/sites/all/modules/views/theme/views-view-row-node.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..c0a35d3c58a3272cfc5aa4ee16317aea007c5aef --- /dev/null +++ b/sites/all/modules/views/theme/views-view-row-node.tpl.php @@ -0,0 +1,21 @@ +<?php +// $Id: views-view-row-node.tpl.php,v 1.3.6.1 2010/09/15 09:01:01 dereine Exp $ +/** + * @file views-view-row-node.tpl.php + * Default simple view template to display a single node. + * + * Rather than doing anything with this particular template, it is more + * efficient to use a variant of the node.tpl.php based upon the view, + * which will be named node--view--VIEWNAME.tpl.php. This isn't actually + * a views template, which is why it's not used here, but is a template + * 'suggestion' given to the node template, and is used exactly + * the same as any other variant of the node template file, such as + * node-NODETYPE.tpl.php + * + * @ingroup views_templates + */ +?> +<?php print $node; ?> +<?php if ($comments): ?> + <?php print $comments; ?> +<?php endif; ?> diff --git a/sites/all/modules/views/theme/views-view-row-rss.tpl.php b/sites/all/modules/views/theme/views-view-row-rss.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..0a975018ba2315657eef3e7ac8641b6280ae63f1 --- /dev/null +++ b/sites/all/modules/views/theme/views-view-row-rss.tpl.php @@ -0,0 +1,15 @@ +<?php +// $Id: views-view-row-rss.tpl.php,v 1.1 2008/12/02 22:17:42 merlinofchaos Exp $ +/** + * @file views-view-row-rss.tpl.php + * Default view template to display a item in an RSS feed. + * + * @ingroup views_templates + */ +?> + <item> + <title><?php print $title; ?></title> + <link><?php print $link; ?></link> + <description><?php print $description; ?></description> + <?php print $item_elements; ?> + </item> diff --git a/sites/all/modules/views/theme/views-view-rss.tpl.php b/sites/all/modules/views/theme/views-view-rss.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..36e6ab95146853b17840292eb5fd06dcc1f0e71d --- /dev/null +++ b/sites/all/modules/views/theme/views-view-rss.tpl.php @@ -0,0 +1,20 @@ +<?php +// $Id: views-view-rss.tpl.php,v 1.3 2008/12/02 00:02:06 merlinofchaos Exp $ +/** + * @file views-view-rss.tpl.php + * Default template for feed displays that use the RSS style. + * + * @ingroup views_templates + */ +?> +<?php print "<?xml"; ?> version="1.0" encoding="utf-8" <?php print "?>"; ?> +<rss version="2.0" xml:base="<?php print $link; ?>"<?php print $namespaces; ?>> + <channel> + <title><?php print $title; ?></title> + <link><?php print $link; ?></link> + <description><?php print $description; ?></description> + <language><?php print $langcode; ?></language> + <?php print $channel_elements; ?> + <?php print $items; ?> + </channel> +</rss> \ No newline at end of file diff --git a/sites/all/modules/views/theme/views-view-summary-unformatted.tpl.php b/sites/all/modules/views/theme/views-view-summary-unformatted.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..9498feb5822155631a6188b4951263361fbb8d60 --- /dev/null +++ b/sites/all/modules/views/theme/views-view-summary-unformatted.tpl.php @@ -0,0 +1,20 @@ +<?php +// $Id: views-view-summary-unformatted.tpl.php,v 1.2.6.1 2010/03/16 23:12:25 merlinofchaos Exp $ +/** + * @file views-view-summary-unformatted.tpl.php + * Default simple view template to display a group of summary lines + * + * This wraps items in a span if set to inline, or a div if not. + * + * @ingroup views_templates + */ +?> +<?php foreach ($rows as $id => $row): ?> + <?php print (!empty($options['inline']) ? '<span' : '<div') . ' class="views-summary views-summary-unformatted">'; ?> + <?php if (!empty($row->separator)) { print $row->separator; } ?> + <a href="<?php print $row->url; ?>"<?php print !empty($classes[$id]) ? ' class="'. $classes[$id] .'"' : ''; ?>><?php print $row->link; ?></a> + <?php if (!empty($options['count'])): ?> + (<?php print $row->count; ?>) + <?php endif; ?> + <?php print !empty($options['inline']) ? '</span>' : '</div>'; ?> +<?php endforeach; ?> diff --git a/sites/all/modules/views/theme/views-view-summary.tpl.php b/sites/all/modules/views/theme/views-view-summary.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..c07d7382d2712badcd4b2b292fc9f21192a95ab3 --- /dev/null +++ b/sites/all/modules/views/theme/views-view-summary.tpl.php @@ -0,0 +1,20 @@ +<?php +// $Id: views-view-summary.tpl.php,v 1.6.6.1 2010/03/16 23:12:25 merlinofchaos Exp $ +/** + * @file views-view-summary.tpl.php + * Default simple view template to display a list of summary lines + * + * @ingroup views_templates + */ +?> +<div class="item-list"> + <ul class="views-summary"> + <?php foreach ($rows as $id => $row): ?> + <li><a href="<?php print $row->url; ?>"<?php print !empty($classes[$id]) ? ' class="'. $classes[$id] .'"' : ''; ?>><?php print $row->link; ?></a> + <?php if (!empty($options['count'])): ?> + (<?php print $row->count?>) + <?php endif; ?> + </li> + <?php endforeach; ?> + </ul> +</div> diff --git a/sites/all/modules/views/theme/views-view-table.tpl.php b/sites/all/modules/views/theme/views-view-table.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..89866f0ae602d4f4bb5fd45f2d1abc20ee3be5e1 --- /dev/null +++ b/sites/all/modules/views/theme/views-view-table.tpl.php @@ -0,0 +1,45 @@ +<?php +// $Id: views-view-table.tpl.php,v 1.8.6.3 2010/12/10 08:19:15 dereine Exp $ +/** + * @file views-view-table.tpl.php + * Template to display a view as a table. + * + * - $title : The title of this group of rows. May be empty. + * - $header: An array of header labels keyed by field id. + * - $header_classes: An array of header classes keyed by field id. + * - $fields: An array of CSS IDs to use for each field id. + * - $class: A class or classes to apply to the table, based on settings. + * - $row_classes: An array of classes to apply to each row, indexed by row + * number. This matches the index in $rows. + * - $rows: An array of row items. Each row is an array of content. + * $rows are keyed by row number, fields within rows are keyed by field ID. + * - $field_classes: An array of classes to apply to each field, indexed by + * field id, then row number. This matches the index in $rows. + * @ingroup views_templates + */ +?> +<table class="<?php print $classes; ?>"<?php print $attributes; ?>> + <?php if (!empty($title)) : ?> + <caption><?php print $title; ?></caption> + <?php endif; ?> + <thead> + <tr> + <?php foreach ($header as $field => $label): ?> + <th class="<?php print $header_classes[$field]; ?>"> + <?php print $label; ?> + </th> + <?php endforeach; ?> + </tr> + </thead> + <tbody> + <?php foreach ($rows as $count => $row): ?> + <tr class="<?php print implode(' ', $row_classes[$count]); ?>"> + <?php foreach ($row as $field => $content): ?> + <td class="<?php print $field_classes[$field][$count]; ?>"> + <?php print $content; ?> + </td> + <?php endforeach; ?> + </tr> + <?php endforeach; ?> + </tbody> +</table> diff --git a/sites/all/modules/views/theme/views-view-unformatted.tpl.php b/sites/all/modules/views/theme/views-view-unformatted.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..6bf5a336df90c172d71f7125833fc246e500d94f --- /dev/null +++ b/sites/all/modules/views/theme/views-view-unformatted.tpl.php @@ -0,0 +1,17 @@ +<?php +// $Id: views-view-unformatted.tpl.php,v 1.6.6.1 2010/03/29 20:05:38 dereine Exp $ +/** + * @file views-view-unformatted.tpl.php + * Default simple view template to display a list of rows. + * + * @ingroup views_templates + */ +?> +<?php if (!empty($title)): ?> + <h3><?php print $title; ?></h3> +<?php endif; ?> +<?php foreach ($rows as $id => $row): ?> + <div class="<?php print $classes_array[$id]; ?>"> + <?php print $row; ?> + </div> +<?php endforeach; ?> diff --git a/sites/all/modules/views/theme/views-view.tpl.php b/sites/all/modules/views/theme/views-view.tpl.php new file mode 100644 index 0000000000000000000000000000000000000000..a202ec961083cc2e217d8d4318383c5f5026ebc6 --- /dev/null +++ b/sites/all/modules/views/theme/views-view.tpl.php @@ -0,0 +1,90 @@ +<?php +// $Id: views-view.tpl.php,v 1.13.4.4 2010/07/04 10:04:51 dereine Exp $ +/** + * @file views-view.tpl.php + * Main view template + * + * Variables available: + * - $classes_array: An array of classes determined in + * template_preprocess_views_view(). Default classes are: + * .view + * .view-[css_name] + * .view-id-[view_name] + * .view-display-id-[display_name] + * .view-dom-id-[dom_id] + * - $classes: A string version of $classes_array for use in the class attribute + * - $css_name: A css-safe version of the view name. + * - $css_class: The user-specified classes names, if any + * - $header: The view header + * - $footer: The view footer + * - $rows: The results of the view query, if any + * - $empty: The empty text to display if the view is empty + * - $pager: The pager next/prev links to display, if any + * - $exposed: Exposed widget form/info to display + * - $feed_icon: Feed icon to display, if any + * - $more: A link to view more, if any + * - $admin_links: A rendered list of administrative links + * - $admin_links_raw: A list of administrative links suitable for theme('links') + * + * @ingroup views_templates + */ +?> +<div class="<?php print $classes; ?>"> + <?php if ($admin_links): ?> + <?php print $admin_links; ?> + <?php endif; ?> + <?php if ($header): ?> + <div class="view-header"> + <?php print $header; ?> + </div> + <?php endif; ?> + + <?php if ($exposed): ?> + <div class="view-filters"> + <?php print $exposed; ?> + </div> + <?php endif; ?> + + <?php if ($attachment_before): ?> + <div class="attachment attachment-before"> + <?php print $attachment_before; ?> + </div> + <?php endif; ?> + + <?php if ($rows): ?> + <div class="view-content"> + <?php print $rows; ?> + </div> + <?php elseif ($empty): ?> + <div class="view-empty"> + <?php print $empty; ?> + </div> + <?php endif; ?> + + <?php if ($pager): ?> + <?php print $pager; ?> + <?php endif; ?> + + <?php if ($attachment_after): ?> + <div class="attachment attachment-after"> + <?php print $attachment_after; ?> + </div> + <?php endif; ?> + + <?php if ($more): ?> + <?php print $more; ?> + <?php endif; ?> + + <?php if ($footer): ?> + <div class="view-footer"> + <?php print $footer; ?> + </div> + <?php endif; ?> + + <?php if ($feed_icon): ?> + <div class="feed-icon"> + <?php print $feed_icon; ?> + </div> + <?php endif; ?> + +</div> <?php /* class view */ ?> diff --git a/sites/all/modules/views/translations/de.po b/sites/all/modules/views/translations/de.po new file mode 100644 index 0000000000000000000000000000000000000000..e878db831bfe9dae10a8c67652c5c16a6b1847ea --- /dev/null +++ b/sites/all/modules/views/translations/de.po @@ -0,0 +1,4439 @@ +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# views.module,v 1.141 2006/06/25 18:24:56 merlinofchaos +# views_ui.module,v 1.28 2006/06/25 18:24:56 merlinofchaos +# views_user.inc,v 1.7 2006/06/25 18:24:56 merlinofchaos +# views_comment.inc,v 1.3 2006/06/23 22:12:23 merlinofchaos +# views_node.inc,v 1.16 2006/06/25 18:24:56 merlinofchaos +# views_upload.inc,v 1.1 2006/06/24 01:41:53 merlinofchaos +# views_rss.module,v 1.3 2006/06/25 01:57:28 merlinofchaos +# views_theme_wizard.module,v 1.2 2006/07/12 23:21:04 merlinofchaos +# views.install,v 1.21 2006/07/24 22:44:27 merlinofchaos +# +msgid "" +msgstr "" +"Project-Id-Version: German translation for views module\n" +"POT-Creation-Date: 2008-11-06 21:18+0100\n" +"PO-Revision-Date: 2008-12-01 01:16+0100\n" +"Last-Translator: Alexander Haß\n" +"Language-Team: Alexander Hass\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" + +#: views.module:629 +msgid "Broken handler @table.@field" +msgstr "Beschädigte Behandlungsroutine @table.@field" + +#: views.module:747 +msgid "Skipping broken view @view" +msgstr "Beschädigte Ansicht @view wurde übersprungen" + +#: views.module:794;834 +#: includes/admin.inc:98;216;216;621 +msgid "Overridden" +msgstr "Übersteuert" + +#: views.module:797;830 +#: views_ui.module:289 +#: includes/admin.inc:97;215;215;588;766 +msgid "Default" +msgstr "Standard" + +#: views.module:935 +#: includes/admin.inc:295 +#: views_export/views_export.module:116 +msgid "Apply" +msgstr "Anwenden" + +#: views.module:151 +#: views_ui.module:26 +#: views.info:0;0 +#: views_ui.info:0 +#: views_export/views_export.info:0 +msgid "Views" +msgstr "Ansichten" + +#: views.module:155 +msgid "Ajax callback for view loading." +msgstr "Ajax-Rückfrage für das Laden der Ansicht." + +#: views.module:0 +msgid "views" +msgstr "Ansichten" + +#: views_ui.module:159 +msgid "The converter will make a best-effort attempt to convert a Views 1 view to Views 2. This conversion is not reliable; you will very likely have to make adjustments to your view to get it to match. You can import Views 1 views through the normal Import tab." +msgstr "Der Konverter wird mit größter Mühe versuchen einen „View 1“ nach „View 2“ zu konvertieren. Diese Konvertierung ist nicht zuverlässig und es müssen sicherlich Anpassungen an der Ansicht vorgenommen werden, um den alten Stand wiederherzustellen. „View 1“-Ansichten können über den normalen Import-Reiter importiert werden." + +#: views_ui.module:265 +msgid "Changes cannot be made to a locked view." +msgstr "An einer gesperrten Ansicht können keine Änderungen vorgenommen werden." + +#: views_ui.module:28 +msgid "Views are customized lists of content on your system; they are highly configurable and give you control over how lists of content are presented." +msgstr "Ansichten sind benutzerdefinierte Listen von Inhalt in dem System. Diese sind hochgradig Konfigurierbar und ermöglichen die Kontrolle, wie Listen von Inhalten präsentiert werden." + +#: views_ui.module:32 +#: includes/plugins.inc:135 +msgid "List" +msgstr "Alle anzeigen" + +#: views_ui.module:38 +#: includes/admin.inc:1178;1178;2165 +msgid "Add" +msgstr "Hinzufügen" + +#: views_ui.module:43 +#: includes/admin.inc:724 +msgid "Import" +msgstr "Importieren" + +#: views_ui.module:49 +msgid "Tools" +msgstr "Werkzeuge" + +#: views_ui.module:55 +msgid "Basic" +msgstr "Basis" + +#: views_ui.module:63 +#: includes/convert.inc:30 +msgid "Convert" +msgstr "Konvertieren" + +#: views_ui.module:64 +msgid "Convert stored Views 1 views." +msgstr "Konvertiere gespeicherte Views 1 Ansichten." + +#: views_ui.module:70;83;88 +msgid "Delete view" +msgstr "Ansicht löschen" + +#: views_ui.module:76 +msgid "Convert view" +msgstr "Ansicht konvertieren" + +#: views_ui.module:113 +#: includes/admin.inc:93 +#: theme/theme.inc:89 +msgid "Edit" +msgstr "Bearbeiten" + +#: views_ui.module:0 +msgid "views_ui" +msgstr "views_ui" + +#: views.install:31 +msgid "Stores the general data for a view." +msgstr "Speichert die allgemeinen Daten für eine Ansicht." + +#: views.install:37 +msgid "The view ID of the field, defined by the database." +msgstr "Die von der Datenbank festgelegte Ansichts-ID für das Feld." + +#: views.install:45 +msgid "The unique name of the view. This is the primary field views are loaded from, and is used so that views may be internal and not necessarily in the database. May only be alphanumeric characters plus underscores." +msgstr "Der eindeutige Name der Ansicht. Dies ist das primäre Feld aus dem Ansichten geladen werden und wird verwendet, damit Ansichten intern sind und sich nicht notwendigerweise in der Datenbank befinden müssen." + +#: views.install:51 +msgid "A description of the view for the admin interface." +msgstr "Eine Beschreibung der Ansicht für die Verwaltungsoberfläche." + +#: views.install:57 +msgid "A tag used to group/sort views in the admin interface" +msgstr "Eine Kennzeichnung die verwendet wird, um Ansichten in der Verwaltungsoberfläche zu gruppieren/sortieren." + +#: views.install:61 +msgid "A chunk of PHP code that can be used to provide modifications to the view prior to building." +msgstr "Ein Stück von PHP-Code das verwendet werden kann, um Änderungen an einer Ansicht vor dem Aufbau vorzunehmen." + +#: views.install:68 +msgid "What table this view is based on, such as node, user, comment, or term." +msgstr "Auf welcher Tabelle diese Ansicht basiert, wie etwa Beitrag, Benutzer, Kommentar oder Begriff." + +#: views.install:74 +msgid "A boolean to indicate whether or not this view may have its query cached." +msgstr "Ein boolscher Wert der angibt, ob die Abfrage dieser Ansicht gecached wird oder nicht." + +#: views.install:82 +msgid "Stores information about each display attached to a view." +msgstr "Speichert Informationen über jede Anzeige, die mit einer Ansicht verbunden ist." + +#: views.install:89 +msgid "The view this display is attached to." +msgstr "Die Ansicht mit der diese Anzeige verbunden ist." + +#: views.install:97 +msgid "An identifier for this display; usually generated from the display_plugin, so should be something like page or page_1 or block_2, etc." +msgstr "Ein Bezeichner für die Anzeige. Normalerweise wird dieser vom display_plugin generiert und sollte so ähnlich wie page, page_1 oder page_2, usw. lauten." + +#: views.install:104 +msgid "The title of the display, viewable by the administrator." +msgstr "Der für einen Administrator sichtbare Titel der Anzeige." + +#: views.install:111 +msgid "The type of the display. Usually page, block or embed, but is pluggable so may be other things." +msgstr "Der Typ der Anzeige. Normalerweise eine Seite, Block oder Einbettung aber auch um andere Dinge erweiterbar." + +#: views.install:116 +msgid "The order in which this display is loaded." +msgstr "Die Reihenfolge in der die Anzeige geladen wird." + +#: views.install:120 +msgid "A serialized array of options for this display; it contains options that are generally only pertinent to that display plugin type." +msgstr "Ein serialisiertes Array von Optionen für diese Anzeige. Dies enthält Optionen die generell nur zu diesem Anzeige-Plugin-Typ gehören." + +# TODO +#: views.install:131 +msgid "A special cache used to store objects that are being edited; it serves to save state in an ordinarily stateless environment." +msgstr "Ein spezieller Cache der zum Speichern von Objekten verwendet wird, die gerade bearbeitet werden. Dieser stellt den Status " + +#: views.install:136 +msgid "The session ID this cache object belongs to." +msgstr "Die Session-ID zu der dieses Cacheobjekt gehört." + +#: views.install:141 +msgid "The name of the view this cache is attached to." +msgstr "Der Name der Ansicht mit dem dieser Cache verbunden ist." + +#: views.install:146 +msgid "The name of the object this cache is attached to; this essentially represents the owner so that several sub-systems can use this cache." +msgstr "Der Name des Objekts an den dieser Cache angehängt ist. Dies repräsentiert hauptsächlich den Eigentümer, damit verschiedene andere Subsysteme diesen Cache nutzen können." + +#: views.install:153 +msgid "The time this cache was created or updated." +msgstr "Der Zeitpunkt zu dem der Cache erstellt oder aktualisiert wurde." + +#: views.install:157 +msgid "Serialized data being stored." +msgstr "Die gespeicherten serialisierten Daten." + +#: views.info:0 +msgid "Create customized lists and queries from your database." +msgstr "Benutzerdefinierte Listen und Abfragen aus der Datenbank erstellen." + +#: views_ui.info:0 +msgid "Views UI" +msgstr "Ansichten UI" + +#: views_ui.info:0 +msgid "Administrative interface to views. Without this module, you cannot create or edit your views." +msgstr "Verwaltungsoberfläche für Ansichten. Ohne dieses Modul können Ansichten weder erstellt noch bearbeitet werden." + +#: docs/docs.php:127 +msgid "Emulates the default Drupal front page; you may set the default home page path to this view to make it your front page." +msgstr "Emuliert die standardmäßige Drupal-Startseite. Der standardmäßige Pfad der Startseite kann auf diese Ansicht eingestellt werden, um diese zur Startseite zu machen." + +#: docs/docs.php:128 +msgid "default" +msgstr "Standard" + +#: docs/docs.php:137 +#: includes/plugins.inc:25 +msgid "Defaults" +msgstr "Standards" + +#: docs/docs.php:226 +#: includes/plugins.inc:39;47 +msgid "Page" +msgstr "Seite" + +#: docs/docs.php:281 +#: includes/plugins.inc:72;80 +msgid "Feed" +msgstr "Newsfeed" + +#: docs/docs.php:349 +msgid "Front page feed" +msgstr "Newsfeed der Startseite" + +#: handlers/views_handler_argument.inc:102 +#: modules/translation/views_handler_relationship_translation.inc:23 +msgid "All" +msgstr "Alle" + +#: handlers/views_handler_argument.inc:119 +#: includes/admin.inc:272;383 +#: modules/comment.views.inc:44 +#: modules/node.views.inc:85;413 +#: plugins/views_plugin_display.inc:592 +#: plugins/views_plugin_display_page.inc:285;348 +msgid "Title" +msgstr "Titel" + +#: handlers/views_handler_argument.inc:121 +msgid "The title to use when this argument is present. It will override the title of the view and titles from previous arguments. You can use percent substitution here to replace with argument titles. Use \"%1\" for the first argument, \"%2\" for the second, etc." +msgstr "Der bei diesem vorhandenen Argument zu verwendende Titel. Dies wird den Titel der Ansicht und die Titel von vorhergehenden Argumenten übersteuern. Um Titel mit Argumenten zu ersetzen, kann die prozentuale Ersetzung verwendet werden. Dabei kann für das erste Argument „%1“, für das zweite „%2“, etc. verwendet werden." + +#: handlers/views_handler_argument.inc:134 +msgid "Action to take if argument is not present" +msgstr "Die auszuführende Aktion, wenn das Argument nicht vorhanden ist" + +#: handlers/views_handler_argument.inc:146 +msgid "Wildcard" +msgstr "Platzhalter" + +#: handlers/views_handler_argument.inc:149 +msgid "If this value is received as an argument, the argument will be ignored; i.e, \"all values\"" +msgstr "Sollte dieser Wert als Argument übergeben werden, wird das Argument ignoriert z.B. „alle Werte“" + +#: handlers/views_handler_argument.inc:155 +#, fuzzy +msgid "Wildcard title" +msgstr "Platzhaltertitel" + +#: handlers/views_handler_argument.inc:158 +msgid "The title to use for the wildcard in substitutions elsewhere." +msgstr "" + +#: handlers/views_handler_argument.inc:181 +msgid "Validator options" +msgstr "Validatoroptionen" + +#: handlers/views_handler_argument.inc:186 +#, fuzzy +msgid "Validator" +msgstr "Validator" + +#: handlers/views_handler_argument.inc:190 +msgid "<Basic validation>" +msgstr "<Basisvalidierung>" + +#: handlers/views_handler_argument.inc:229 +msgid "Action to take if argument does not validate" +msgstr "Die auszuführende Aktion, wenn das Argument nicht valide ist" + +#: handlers/views_handler_argument.inc:248 +msgid "Display all values" +msgstr "Alle Werte anzeigen" + +#: handlers/views_handler_argument.inc:253 +msgid "Hide view / Page not found (404)" +msgstr "Ansicht ausblenden / Seite wurde nicht gefunden (404)" + +#: handlers/views_handler_argument.inc:258 +msgid "Display empty text" +msgstr "Leerer Text anzeigen" + +#: handlers/views_handler_argument.inc:263 +msgid "Summary, sorted ascending" +msgstr "Zusammenfassung, aufsteigend sortiert" + +#: handlers/views_handler_argument.inc:270 +msgid "Summary, sorted descending" +msgstr "Zusammenfassung, absteigend sortiert" + +#: handlers/views_handler_argument.inc:277 +msgid "Provide default argument" +msgstr "Standardargument zu Verfügung stellen" + +#: handlers/views_handler_argument.inc:310 +msgid "Provide default argument options" +msgstr "Standardmäßige Argumentoptionen zur Verfügung stellen" + +#: handlers/views_handler_argument.inc:320 +msgid "Default argument type" +msgstr "Standardtyp für Argumente" + +#: handlers/views_handler_argument.inc:708 +#: handlers/views_handler_field.inc:227 +#: handlers/views_handler_filter.inc:592 +#: handlers/views_handler_relationship.inc:133 +#: handlers/views_handler_sort.inc:66 +msgid "Broken/missing handler" +msgstr "Beschädigte/fehlende Behandlungsroutine" + +#: handlers/views_handler_argument.inc:716 +#: handlers/views_handler_field.inc:235 +#: handlers/views_handler_filter.inc:600 +#: handlers/views_handler_relationship.inc:141 +#: handlers/views_handler_sort.inc:74 +msgid "The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item." +msgstr "Die Behandlungsroutine für diesen Eintrag ist beschädigt oder fehlt und kann nicht verwendet werden. Sollte ein Modul diese Behandlungsroutine zu Verfügung gestellt haben und deaktiviert worden sein, kann die Wiederaktivierung des Moduls dies korrigieren. Ansonsten sollte der Eintrag wohl gelöscht werden." + +#: handlers/views_handler_argument_date.inc:29 +msgid "Current date" +msgstr "Aktuelles Datum" + +#: handlers/views_handler_argument_date.inc:30 +msgid "Current node's creation time" +msgstr "Aktuelles Beitragserstellungsdatum" + +#: handlers/views_handler_argument_date.inc:31 +msgid "Current node's update time" +msgstr "Aktuelles Beitragsaktualisierungsdatum" + +#: handlers/views_handler_argument_many_to_one.inc:45 +#: handlers/views_handler_argument_numeric.inc:30 +msgid "Allow multiple terms per argument." +msgstr "Ermöglicht mehrere Begriffe pro Argument." + +# English string needs work "ODER-Verknüpfung" +#: handlers/views_handler_argument_many_to_one.inc:46 +#, fuzzy +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 (for OR) or 1,2,3 (for AND)." +msgstr "Sobald ausgewählt, können Benutzer mehrere Argumente in Form von 1+2+3 (für ODER-Verknüpfungen) oder 1,2,3 (für UND-Verknüpfungen) angeben." + +#: handlers/views_handler_argument_many_to_one.inc:53 +#: handlers/views_handler_argument_string.inc:95 +msgid "Allow multiple arguments to work together." +msgstr "Ermöglicht die Zusammenarbeit mehrerer Argumente." + +#: handlers/views_handler_argument_many_to_one.inc:54 +#: handlers/views_handler_argument_string.inc:96 +msgid "If selected, multiple instances of this argument can work together, as though multiple terms were supplied to the same argument. This setting is not compatible with the \"Reduce duplicates\" setting." +msgstr "" + +#: handlers/views_handler_argument_many_to_one.inc:60 +#: handlers/views_handler_argument_string.inc:102 +msgid "Do not display items with no value in summary" +msgstr "Einträge ohne Wert in der Zusammenfassung nicht anzeigen" + +#: handlers/views_handler_argument_many_to_one.inc:95;109 +#: handlers/views_handler_argument_numeric.inc:45;57 +#: modules/taxonomy.views.inc:129;208;292 +msgid "Uncategorized" +msgstr "Nicht kategorisiert" + +#: handlers/views_handler_argument_many_to_one.inc:113 +#: handlers/views_handler_argument_numeric.inc:61 +msgid "Invalid input" +msgstr "Ungültige Eingabe" + +#: handlers/views_handler_argument_null.inc:21 +msgid "Fail basic validation if any argument is given" +msgstr "Die Basisvalidierung soll fehlschlagen, wenn irgendein Argument übergeben wird" + +#: handlers/views_handler_argument_null.inc:23 +msgid "By checking this field, you can use this to make sure views with more arguments than necessary fail validation." +msgstr "" + +#: handlers/views_handler_argument_numeric.inc:31 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 or 1,2,3." +msgstr "If selected, users can enter multiple arguments in the form of 1+2+3 or 1,2,3." + +#: handlers/views_handler_argument_numeric.inc:37 +msgid "Exclude the argument" +msgstr "Argument ausschließen" + +#: handlers/views_handler_argument_numeric.inc:38 +msgid "If selected, the numbers entered in the argument will be excluded rather than limiting the view." +msgstr "Sobald ausgewählt, werden die im Argument angegebenen Zahlen ausgeschlossen und nicht zur Begrenzung der Ansicht verwendet." + +#: handlers/views_handler_argument_string.inc:44 +msgid "Glossary mode" +msgstr "" + +#: handlers/views_handler_argument_string.inc:45 +msgid "Glossary mode applies a limit to the number of characters used in the argument, which allows the summary view to act as a glossary." +msgstr "" + +#: handlers/views_handler_argument_string.inc:51 +msgid "Character limit" +msgstr "Zeichenbegrenzung" + +#: handlers/views_handler_argument_string.inc:52 +msgid "How many characters of the argument to filter against. If set to 1, all fields starting with the letter in the argument would be matched." +msgstr "" + +#: handlers/views_handler_argument_string.inc:60 +msgid "Case" +msgstr "Groß-/Kleinschreibung" + +#: handlers/views_handler_argument_string.inc:61 +msgid "When printing the argument result, how to transform the case." +msgstr "" + +#: handlers/views_handler_argument_string.inc:63;77 +msgid "No transform" +msgstr "Keine Umwandlung" + +#: handlers/views_handler_argument_string.inc:64;78 +msgid "Upper case" +msgstr "Großschreibung" + +#: handlers/views_handler_argument_string.inc:65;79 +msgid "Lower case" +msgstr "Kleinschreibung" + +#: handlers/views_handler_argument_string.inc:66;80 +msgid "Capitalize first letter" +msgstr "Ersten Buchstaben groß schreiben" + +#: handlers/views_handler_argument_string.inc:67;81 +msgid "Capitalize each word" +msgstr "Jedes Wort groß schreiben" + +#: handlers/views_handler_argument_string.inc:74 +msgid "Case in path" +msgstr "Groß-/Kleinschreibung im Pfad" + +#: handlers/views_handler_argument_string.inc:75 +msgid "When printing url paths, how to transform the of the argument. Do not use this unless with Postgres as it uses case sensitive comparisons." +msgstr "" + +#: handlers/views_handler_argument_string.inc:88 +msgid "Transform spaces to dashes in URL" +msgstr "Leerzeichen in der URL in Striche umwandeln" + +#: handlers/views_handler_field.inc:146 +#: handlers/views_handler_filter.inc:322 +#: handlers/views_handler_relationship.inc:78 +msgid "Label" +msgstr "Bezeichnung" + +#: handlers/views_handler_field.inc:148 +msgid "The label for this field that will be displayed to end users if the style requires it." +msgstr "" + +#: handlers/views_handler_field.inc:152 +msgid "Exclude from display" +msgstr "Von der Anzeige ausschließen" + +#: handlers/views_handler_field.inc:154 +msgid "Check this box to not display this field, but still load it in the view. Use this option to not show a grouping field in each record, or when doing advanced theming." +msgstr "" + +#: handlers/views_handler_field_boolean.inc:24 +msgid "Output format" +msgstr "Ausgabeformat" + +#: handlers/views_handler_field_boolean.inc:26 +msgid "Yes/No" +msgstr "Ja/Nein" + +#: handlers/views_handler_field_boolean.inc:27 +msgid "True/False" +msgstr "Wahr/Unwahr" + +#: handlers/views_handler_field_boolean.inc:28 +msgid "On/Off" +msgstr "An/Aus" + +#: handlers/views_handler_field_boolean.inc:34 +msgid "Reverse" +msgstr "Umgekehrt" + +#: handlers/views_handler_field_boolean.inc:35 +msgid "If checked, true will be displayed as false." +msgstr "Sobald aktiviert, wird „wahr“ als „unwahr“ angezeigt." + +#: handlers/views_handler_field_boolean.inc:49 +#: handlers/views_handler_filter_boolean_operator.inc:47 +#: handlers/views_handler_filter_in_operator.inc:25 +#: plugins/views_plugin_display.inc:633;642;659;667;717;803;1207 +#: plugins/views_plugin_display_attachment.inc:63;69 +msgid "Yes" +msgstr "Ja" + +#: handlers/views_handler_field_boolean.inc:49 +#: handlers/views_handler_filter_boolean_operator.inc:47 +#: handlers/views_handler_filter_in_operator.inc:25 +#: plugins/views_plugin_display.inc:633;642;659;667;717;803;811;1207 +#: plugins/views_plugin_display_attachment.inc:63;69 +msgid "No" +msgstr "Nein" + +#: handlers/views_handler_field_boolean.inc:51 +#: handlers/views_handler_filter_boolean_operator.inc:16;61 +msgid "True" +msgstr "Wahr" + +#: handlers/views_handler_field_boolean.inc:51 +#: handlers/views_handler_filter_boolean_operator.inc:61 +msgid "False" +msgstr "Unwahr" + +#: handlers/views_handler_field_boolean.inc:53 +msgid "On" +msgstr "An" + +#: handlers/views_handler_field_boolean.inc:53 +msgid "Off" +msgstr "Aus" + +#: handlers/views_handler_field_date.inc:24 +msgid "Date format" +msgstr "Datumsformat" + +#: handlers/views_handler_field_date.inc:29 +msgid "Custom" +msgstr "Benutzerdefiniert" + +#: handlers/views_handler_field_date.inc:30 +#, fuzzy +msgid "Time ago" +msgstr "Zeit vergangen" + +#: handlers/views_handler_field_date.inc:36 +msgid "Custom date format" +msgstr "Benutzerdefiniertes Datumsformat" + +# not literally +#: handlers/views_handler_field_date.inc:37 +msgid "If \"Custom\", see <a href=\"http://us.php.net/manual/en/function.date.php\" target=\"_blank\">the PHP docs</a> for date formats. If \"Time ago\" this is the the number of different units to display, which defaults to two." +msgstr "Für „Benutzerdefiniert“ gibt es nähere Information über Datumsformate in der <a href=\"http://www.php.net/manual/de/function.date.php\" target=\"_blank\">PHP-Dokumentation</a>. Bei „Zeit vergangen“ ist dies die Anzahl der unterschiedlichen Einheiten die angezeigt werden sollen, welche standardmäßig 2-stellig sind." + +#: handlers/views_handler_field_date.inc:53 +msgid "%time ago" +msgstr "vor %time" + +#: handlers/views_handler_field_numeric.inc:32 +msgid "Round" +msgstr "Runden" + +#: handlers/views_handler_field_numeric.inc:33 +msgid "If checked, the number will be rounded." +msgstr "Sobald aktiviert, wird die Zahl gerundet." + +#: handlers/views_handler_field_numeric.inc:38 +msgid "Precision" +msgstr "Genauigkeit" + +#: handlers/views_handler_field_numeric.inc:40 +msgid "Specify how many digits to print after the decimal point." +msgstr "Festlegen, wie viele Stellen nach dem Dezimalpunkt erscheinen sollen." + +#: handlers/views_handler_field_numeric.inc:47 +msgid "Decimal point" +msgstr "Dezimalpunkt" + +#: handlers/views_handler_field_numeric.inc:49 +msgid "What single character to use as a decimal point." +msgstr "Welches Symbol als Dezimalpunkt verwendet werden soll." + +#: handlers/views_handler_field_numeric.inc:55 +msgid "Thousands separator" +msgstr "Tausender-Trennzeichen" + +#: handlers/views_handler_field_numeric.inc:57 +msgid "What single character to use as the thousands separator." +msgstr "Welches Symbol als tausender Trennzeichen verwendet werden soll." + +#: handlers/views_handler_field_numeric.inc:62 +msgid "Prefix" +msgstr "Präfix" + +#: handlers/views_handler_field_numeric.inc:64 +msgid "Text to put before the number, such as currency symbol." +msgstr "Text der vor die Zahl gestellt werden soll, wie etwa ein Währungszeichen." + +#: handlers/views_handler_field_numeric.inc:68 +msgid "Suffix" +msgstr "Suffix" + +#: handlers/views_handler_field_numeric.inc:70 +msgid "Text to put after the number, such as currency symbol." +msgstr "Text der an die Zahl angehängt werden soll, wie etwa ein Währungszeichen." + +#: handlers/views_handler_field_prerender_list.inc:29 +#: modules/node/views_plugin_row_node_rss.inc:24 +msgid "Display type" +msgstr "Anzeigetyp" + +#: handlers/views_handler_field_prerender_list.inc:31 +#: plugins/views_plugin_style_list.inc:33 +msgid "Unordered list" +msgstr "Ungeordnete Liste" + +#: handlers/views_handler_field_prerender_list.inc:32 +#: plugins/views_plugin_style_list.inc:33 +msgid "Ordered list" +msgstr "Geordnete Liste" + +#: handlers/views_handler_field_prerender_list.inc:33 +msgid "Simple separator" +msgstr "Einfacher Separator" + +#: handlers/views_handler_field_prerender_list.inc:40 +#: includes/admin.inc:2974 +#: plugins/views_plugin_row_fields.inc:47 +#: plugins/views_plugin_style_summary_unformatted.inc:30 +msgid "Separator" +msgstr "Separator" + +#: handlers/views_handler_field_prerender_list.inc:48 +msgid "Empty list text" +msgstr "Leerer Listentext" + +#: handlers/views_handler_field_prerender_list.inc:50 +msgid "If the list is empty, you may enter text here that will be displayed." +msgstr "Hier kann ein Text eingegeben werden, der bei einer leeren Liste angezeigt wird." + +#: handlers/views_handler_field_url.inc:24 +#: modules/statistics/views_handler_field_accesslog_path.inc:31 +msgid "Display as link" +msgstr "Als Link anzeigen" + +#: handlers/views_handler_filter.inc:136 +msgid "Operator" +msgstr "Operator" + +#: handlers/views_handler_filter.inc:201 +msgid "Expose" +msgstr "Hervorheben" + +# TODO as they view it. +#: handlers/views_handler_filter.inc:206 +#, fuzzy +msgid "This item is currently not exposed. If you <strong>expose</strong> it, users will be able to change the filter as they view it." +msgstr "Der Eintrag ist derzeit nicht hervorgehoben. Sollte dieser <strong>hervorgehoben</strong> werden, können Benutzer den Filter ändern." + +#: handlers/views_handler_filter.inc:213 +msgid "Hide" +msgstr "Ausblenden" + +# TODO as they view it. +#: handlers/views_handler_filter.inc:218 +#, fuzzy +msgid "This item is currently exposed. If you <strong>hide</strong> it, users will not be able to change the filter as they view it." +msgstr "Dieser Eintrag ist derzeit hervorgehoben. Sollte dieser <strong>ausgeblendet</strong> werden, können Benutzer den Filter nicht ändern." + +#: handlers/views_handler_filter.inc:289 +msgid "Unlock operator" +msgstr "Operator entsperren" + +#: handlers/views_handler_filter.inc:290 +msgid "When checked, the operator will be exposed to the user" +msgstr "Sobald aktiviert, wird der Operator für den Benutzer hervorgehoben" + +#: handlers/views_handler_filter.inc:296 +msgid "Operator identifier" +msgstr "Bezeichner für Operator" + +#: handlers/views_handler_filter.inc:298 +msgid "This will appear in the URL after the ? to identify this operator." +msgstr "Dies wird in der URL nach dem ? erscheinen, um diesen Operator zu identifizieren." + +#: handlers/views_handler_filter.inc:315 +msgid "Filter identifier" +msgstr "Bezeichner für Filter" + +#: handlers/views_handler_filter.inc:317 +msgid "This will appear in the URL after the ? to identify this filter. Cannot be blank." +msgstr "Dieser wird in der URL nach dem ? erscheinen, um den Filter zu identifizieren. Darf nicht unausgefüllt bleiben." + +#: handlers/views_handler_filter.inc:333 +msgid "Optional" +msgstr "Optional" + +#: handlers/views_handler_filter.inc:334 +msgid "This exposed filter is optional and will have added options to allow it not to be set." +msgstr "Dieser hervorgehobene Filter ist optional und wird Optionen enthalten, damit dieser nicht eingestellt werden muss." + +#: handlers/views_handler_filter.inc:340 +msgid "Force single" +msgstr "Eine Option erzwingen" + +#: handlers/views_handler_filter.inc:341 +msgid "Force this exposed filter to accept only one option." +msgstr "Diesen hervorgehobenen Filter zwingen, nur eine Option zu akzeptieren." + +#: handlers/views_handler_filter.inc:347 +msgid "Remember" +msgstr "Erinnern" + +#: handlers/views_handler_filter.inc:348 +msgid "Remember the last setting the user gave this filter." +msgstr "Die letzte Filtereinstellung des Benutzers merken." + +#: handlers/views_handler_filter.inc:359 +msgid "The identifier is required if the filter is exposed." +msgstr "Der Bezeichner ist erforderlich, wenn der Filter hervorgehoben ist." + +#: handlers/views_handler_filter.inc:364 +msgid "This identifier is not allowed." +msgstr "Dieser Bezeichner ist unzulässig." + +# Beliebig, etc ? +#: handlers/views_handler_filter.inc:465 +#, fuzzy +msgid "<Any>" +msgstr "<Jeder>" + +# TODO: English should be uppercase +#: handlers/views_handler_filter_boolean_operator.inc:58 +#: handlers/views_handler_filter_in_operator.inc:175 +#: handlers/views_handler_filter_numeric.inc:247 +#: handlers/views_handler_filter_string.inc:111 +#, fuzzy +msgid "exposed" +msgstr "Hervorgehoben" + +#: handlers/views_handler_filter_date.inc:24 +msgid "Value type" +msgstr "Werttyp" + +#: handlers/views_handler_filter_date.inc:26 +msgid "A date in any machine readable format. CCYY-MM-DD HH:MM:SS is preferred." +msgstr "Ein Datum in einem maschinenlesbaren Format. JJJJ-MM-TT HH:MM:SS ist bevorzugt." + +#: handlers/views_handler_filter_date.inc:27 +msgid "An offset from the current time such as \"+1 day\" or \"-2 hours -30 minutes\"" +msgstr "Ein Zeitversatz bezogen auf die aktuellen Uhrzeit, wie etwa „+1 Tag“ oder „-2 Stunden -30 Minuten“" + +#: handlers/views_handler_filter_date.inc:77;83;87 +msgid "Invalid date format." +msgstr "Ungültiges Datumsformat." + +#: handlers/views_handler_filter_equality.inc:15 +#: handlers/views_handler_filter_numeric.inc:38 +#: handlers/views_handler_filter_string.inc:28 +msgid "Is equal to" +msgstr "Ist gleich mit" + +#: handlers/views_handler_filter_equality.inc:16 +#: handlers/views_handler_filter_numeric.inc:44 +#: handlers/views_handler_filter_string.inc:34 +msgid "Is not equal to" +msgstr "Ist ungleich zu" + +#: handlers/views_handler_filter_equality.inc:26 +#: handlers/views_handler_filter_numeric.inc:148;163 +#: handlers/views_handler_filter_string.inc:170 +msgid "Value" +msgstr "Wert" + +#: handlers/views_handler_filter_in_operator.inc:15 +msgid "Options" +msgstr "Optionen" + +#: handlers/views_handler_filter_in_operator.inc:37 +msgid "Limit list to selected items" +msgstr "Liste auf ausgewählte Einträge begrenzen" + +#: handlers/views_handler_filter_in_operator.inc:38 +msgid "If checked, the selected items presented to the user will be the only ones selected here." +msgstr "Sobald aktiviert, werden nur die hier ausgewählten Einträge dem Benutzer präsentiert." + +#: handlers/views_handler_filter_in_operator.inc:57 +#: handlers/views_handler_filter_many_to_one.inc:32 +msgid "Is one of" +msgstr "Ist eines von" + +#: handlers/views_handler_filter_in_operator.inc:58 +msgid "Is not one of" +msgstr "Ist keines von" + +#: handlers/views_handler_filter_in_operator.inc:193 +#: modules/system.views.inc:209 +#: plugins/views_plugin_access.inc:55 +msgid "Unknown" +msgstr "Unbekannt" + +#: handlers/views_handler_filter_many_to_one.inc:33 +msgid "Is all of" +msgstr "Ist alles von" + +#: handlers/views_handler_filter_many_to_one.inc:34 +msgid "Is none of" +msgstr "Ist keines von" + +#: handlers/views_handler_filter_numeric.inc:26 +msgid "Is less than" +msgstr "Ist weniger als" + +#: handlers/views_handler_filter_numeric.inc:28 +msgid "<" +msgstr "<" + +#: handlers/views_handler_filter_numeric.inc:32 +msgid "Is less than or equal to" +msgstr "Ist weniger als oder gleich" + +#: handlers/views_handler_filter_numeric.inc:34 +msgid "<=" +msgstr "<=" + +#: handlers/views_handler_filter_numeric.inc:40 +#: handlers/views_handler_filter_string.inc:29 +msgid "=" +msgstr "=" + +#: handlers/views_handler_filter_numeric.inc:46 +#: handlers/views_handler_filter_string.inc:35 +msgid "!=" +msgstr "!=" + +#: handlers/views_handler_filter_numeric.inc:50 +msgid "Is greater than or equal to" +msgstr "Ist größer als oder gleich" + +#: handlers/views_handler_filter_numeric.inc:52 +msgid ">=" +msgstr ">=" + +#: handlers/views_handler_filter_numeric.inc:56 +msgid "Is greater than" +msgstr "Ist größer als" + +#: handlers/views_handler_filter_numeric.inc:58 +msgid ">" +msgstr ">" + +#: handlers/views_handler_filter_numeric.inc:62 +msgid "Is between" +msgstr "Ist zwischen" + +#: handlers/views_handler_filter_numeric.inc:64 +msgid "between" +msgstr "zwischen" + +#: handlers/views_handler_filter_numeric.inc:68 +msgid "Is not between" +msgstr "Ist nicht zwischen" + +#: handlers/views_handler_filter_numeric.inc:70 +msgid "not between" +msgstr "nicht zwischen" + +#: handlers/views_handler_filter_numeric.inc:79 +#: handlers/views_handler_filter_string.inc:80 +msgid "Is empty (NULL)" +msgstr "Ist leer (NULL)" + +#: handlers/views_handler_filter_numeric.inc:81 +#: handlers/views_handler_filter_string.inc:82 +msgid "empty" +msgstr "leer" + +#: handlers/views_handler_filter_numeric.inc:85 +#: handlers/views_handler_filter_string.inc:86 +msgid "Is not empty (NULL)" +msgstr "Ist nicht leer (NULL)" + +#: handlers/views_handler_filter_numeric.inc:87 +#: handlers/views_handler_filter_string.inc:88 +msgid "not empty" +msgstr "nicht leer" + +#: handlers/views_handler_filter_numeric.inc:175 +msgid "Min" +msgstr "Min" + +#: handlers/views_handler_filter_numeric.inc:181 +msgid "And max" +msgstr "Und höchstens" + +#: handlers/views_handler_filter_numeric.inc:181 +msgid "And" +msgstr "und" + +#: handlers/views_handler_filter_numeric.inc:253 +msgid "@min and @max" +msgstr "@min und @max" + +#: handlers/views_handler_filter_string.inc:40 +msgid "Contains" +msgstr "Enthält" + +#: handlers/views_handler_filter_string.inc:41 +msgid "contains" +msgstr "enthält" + +#: handlers/views_handler_filter_string.inc:46 +msgid "Contains any word" +msgstr "Enthält ein beliebiges Wort" + +#: handlers/views_handler_filter_string.inc:47 +msgid "has word" +msgstr "enthält das Wort" + +#: handlers/views_handler_filter_string.inc:52 +msgid "Contains all words" +msgstr "Enthält alle Wörter" + +#: handlers/views_handler_filter_string.inc:53 +msgid "has all" +msgstr "enthält alle" + +#: handlers/views_handler_filter_string.inc:58 +msgid "Starts with" +msgstr "Beginnt mit" + +#: handlers/views_handler_filter_string.inc:59 +msgid "begins" +msgstr "beginnt" + +#: handlers/views_handler_filter_string.inc:64 +msgid "Ends with" +msgstr "Endet mit" + +#: handlers/views_handler_filter_string.inc:65 +msgid "ends" +msgstr "endet" + +#: handlers/views_handler_filter_string.inc:70 +msgid "Does not contain" +msgstr "Enthält nicht" + +#: handlers/views_handler_filter_string.inc:71 +msgid "!has" +msgstr "!has" + +#: handlers/views_handler_filter_string.inc:126 +msgid "Case sensitive" +msgstr "Groß- und Kleinschreibung berücksichtigen" + +#: handlers/views_handler_filter_string.inc:128 +msgid "Case sensitive filters may be faster. MySQL might ignore case sensitivity." +msgstr "Filter die Groß-/Kleinschreibung beachten, können schneller sein. MySQL könnte die Groß-/Kleinschreibung ignorieren." + +#: handlers/views_handler_relationship.inc:80 +msgid "The label for this relationship that will be displayed only administratively." +msgstr "Die Bezeichnung für diese Beziehung wird nur innerhalb der Verwaltung angezeigt." + +# Relationship is required +#: handlers/views_handler_relationship.inc:85 +msgid "Require this relationship" +msgstr "Beziehung ist erforderlich" + +#: handlers/views_handler_relationship.inc:86 +msgid "If required, items that do not contain this relationship will not appear." +msgstr "" + +#: handlers/views_handler_sort.inc:38 +msgid "asc" +msgstr "aufsteigend" + +#: handlers/views_handler_sort.inc:42 +msgid "desc" +msgstr "absteigend" + +#: handlers/views_handler_sort.inc:54 +msgid "Sort order" +msgstr "Sortierreihenfolge" + +#: handlers/views_handler_sort.inc:55 +#: plugins/views_plugin_style_table.inc:149 +msgid "Ascending" +msgstr "Aufsteigend" + +#: handlers/views_handler_sort.inc:55 +#: plugins/views_plugin_style_table.inc:149 +msgid "Descending" +msgstr "Absteigend" + +#: handlers/views_handler_sort_date.inc:26 +msgid "Granularity" +msgstr "Granularität" + +#: handlers/views_handler_sort_date.inc:28 +msgid "Second" +msgstr "Sekunde" + +#: handlers/views_handler_sort_date.inc:29 +msgid "Minute" +msgstr "Minute" + +#: handlers/views_handler_sort_date.inc:30 +msgid "Hour" +msgstr "Stunde" + +#: handlers/views_handler_sort_date.inc:31 +msgid "Day" +msgstr "Tag" + +#: handlers/views_handler_sort_date.inc:32 +msgid "Month" +msgstr "Monat" + +#: handlers/views_handler_sort_date.inc:33 +msgid "Year" +msgstr "Jahr" + +#: handlers/views_handler_sort_date.inc:35 +msgid "The granularity is the smallest unit to use when determining whether two dates are the same; for example, if the granularity is \"Year\" then all dates in 1999, regardless of when they fall in 1999, will be considered the same date." +msgstr "Die Granularität ist die Kleinste zu verwendende Einheit, wenn die Gleichheit zweiter Datumsangaben ermittelt werden soll. Sollte beispielsweise die Granularität das „Jahr“ sein, wird jedes Datum in 1999 ungeachtet dem Tag in 1999, als das gleiche Datum betrachtet." + +#: handlers/views_handler_sort_formula.inc:24 +msgid "views_handler_sort_formula missing default: @formula" +msgstr "Standard für views_handler_sort_formula ist nicht vorhanden: @formula" + +#: includes/admin.inc:36 +msgid "If you <a href=\"@modules\">enable the advanced help module</a>, Views will provide more and better help. <a href=\"@hide\">Hide this message.</a>" +msgstr "Das Ansichten-Modul stellt durch nach <a href=\"@modules\">Aktivieren des erweiterten Hilfemoduls</a> eine bessere und ausführlichere Hilfe zu Verfügung. <a href=\"@hide\">Diese Meldung ausblenden.</a>" + +#: includes/admin.inc:39 +msgid "If you install the advanced help module from !href, Views will provide more and better help. <a href=\"@hide\">Hide this message.</a>" +msgstr "Ansichten stellt durch die Installation des erweiterten Hilfemoduls von !href eine bessere und ausführlichere Hilfe zu Verfügung. <a href=\"@hide\">Diese Meldung ausblenden.</a>" + +#: includes/admin.inc:94;978 +#: theme/theme.inc:96 +#: views_export/views_export.module:128 +msgid "Export" +msgstr "Exportieren" + +#: includes/admin.inc:95;983 +#: theme/theme.inc:101 +msgid "Clone" +msgstr "Duplizieren" + +#: includes/admin.inc:98 +msgid "Revert" +msgstr "Zurücksetzen" + +#: includes/admin.inc:98;634;847 +#: includes/convert.inc:35;108 +msgid "Delete" +msgstr "Löschen" + +#: includes/admin.inc:103 +msgid "Disable" +msgstr "Deaktivieren" + +#: includes/admin.inc:106 +msgid "Enable" +msgstr "Aktivieren" + +#: includes/admin.inc:112 +msgid "Warning! Broken view!" +msgstr "Warnung! Beschädigte Ansicht!" + +#: includes/admin.inc:127 +#: includes/view.inc:1666 +msgid "Broken" +msgstr "Beschädigt" + +#: includes/admin.inc:189 +msgid "Install the advanced help module for the getting started" +msgstr "Für die ersten Schritte sollte das erweiterte Hilfemodul installiert werden" + +#: includes/admin.inc:192 +msgid "Not sure what to do? Try the \"!getting-started\" page." +msgstr "Nicht sicher was Sie machen sollen? Versuchen Sie die „!getting-started“-Seite aufzurufen." + +#: includes/admin.inc:206;213;2131 +msgid "<All>" +msgstr "<Alle>" + +#: includes/admin.inc:207 +#: plugins/views_plugin_style.inc:76 +msgid "<None>" +msgstr "<Keine>" + +#: includes/admin.inc:211 +msgid "Storage" +msgstr "Speicher" + +#: includes/admin.inc:214;214 +#: includes/view.inc:1165;1215 +msgid "Normal" +msgstr "Normal" + +#: includes/admin.inc:228;275 +#: modules/node.views.inc:140 +#: plugins/views_plugin_display_page.inc:273 +msgid "Type" +msgstr "Typ" + +#: includes/admin.inc:246;273;1063 +#: views_export/views_export.module:146 +#, fuzzy +msgid "Tag" +msgstr "Kennzeichnung" + +#: includes/admin.inc:262 +msgid "Displays" +msgstr "Anzeigen" + +#: includes/admin.inc:269 +msgid "Sort by" +msgstr "Sortieren nach" + +#: includes/admin.inc:271 +#: modules/system.views.inc:69 +#: modules/user.views.inc:59;79 +#: plugins/views_plugin_display.inc:580 +msgid "Name" +msgstr "Name" + +#: includes/admin.inc:274;391 +#: modules/statistics.views.inc:149 +#: modules/system.views.inc:88 +#: plugins/views_plugin_display_page.inc:202 +msgid "Path" +msgstr "Pfad" + +#: includes/admin.inc:276 +#: includes/convert.inc:21 +#: modules/upload.views.inc:56 +#: views_export/views_export.module:146 +msgid "Description" +msgstr "Beschreibung" + +#: includes/admin.inc:283 +msgid "Order" +msgstr "Reihenfolge" + +#: includes/admin.inc:285 +msgid "Up" +msgstr "nach oben" + +#: includes/admin.inc:286 +msgid "Down" +msgstr "nach unten" + +#: includes/admin.inc:370;401 +msgid "Query" +msgstr "Abfrage" + +#: includes/admin.inc:372 +msgid "These queries were run during view rendering:" +msgstr "Diese Abfragen werden während dem Rendering der Ansicht ausgeführt:" + +#: includes/admin.inc:377 +msgid "[@time ms]" +msgstr "[@time ms] " + +#: includes/admin.inc:380 +msgid "Other queries" +msgstr "Andere Abfragen" + +#: includes/admin.inc:388 +msgid "This display has no path." +msgstr "Diese Anzeige hat keinen Pfad." + +#: includes/admin.inc:393 +msgid "Query build time" +msgstr "Aufbauzeit der Abfrage" + +#: includes/admin.inc:393;394;395 +msgid "@time ms" +msgstr "@time ms" + +#: includes/admin.inc:394 +msgid "Query execute time" +msgstr "Ausführungszeit der Abfrage" + +#: includes/admin.inc:395 +msgid "View render time" +msgstr "Renderingzeit der Ansicht" + +#: includes/admin.inc:401 +#, fuzzy +msgid "No query was run" +msgstr "Es wurde keine Abfrage ausgeführt" + +#: includes/admin.inc:408 +#, fuzzy +msgid "Unable to preview due to validation errors." +msgstr "Die Vorschau kann wegen Validierungsfehlern nicht angezeigt werden." + +#: includes/admin.inc:459 +msgid "Display" +msgstr "Anzeige" + +#: includes/admin.inc:467 +#: includes/view.inc:1870 +msgid "Arguments" +msgstr "Argumente" + +#: includes/admin.inc:469 +msgid "Separate arguments with a / as though they were a URL path." +msgstr "Argumente mit einem „/“ voneinander abtrennen, als ob diese ein URL-Pfad wären." + +#: includes/admin.inc:475 +msgid "Preview" +msgstr "Vorschau" + +#: includes/admin.inc:513 +msgid "Clone view %view" +msgstr "Ansicht %view duplizieren" + +#: includes/admin.inc:526;713 +#: includes/convert.inc:20 +msgid "View name" +msgstr "Ansichtsname" + +#: includes/admin.inc:527 +msgid "This is the unique name of the view. It must contain only alphanumeric characters and underscores; it is used to identify the view internally and to generate unique theming template names for this view. If overriding a module provided view, the name must not be changed or instead a new view will be created." +msgstr "" + +#: includes/admin.inc:535;1826 +msgid "View description" +msgstr "Beschreibung anzeigen" + +#: includes/admin.inc:536;1827 +msgid "This description will appear on the Views administrative UI to tell you what the view is about." +msgstr "Diese Beschreibung erscheint auf der Verwaltungsoberfläche der Ansichten, um darüber Aufzuklären, worum es sich bei der Ansicht handelt." + +#: includes/admin.inc:542;1833 +#, fuzzy +msgid "View tag" +msgstr "Ansichten-Kennzeichnung" + +#: includes/admin.inc:543;1834 +msgid "Enter an optional tag for this view; it is used only to help sort views on the administrative page." +msgstr "Eine optionale Kennzeichnung für diese Ansicht eingeben. Diese wird auf der Verwaltungsseite nur als Sortierhilfe für Ansichten verwendet." + +#: includes/admin.inc:555 +msgid "View type" +msgstr "Ansichtstyp" + +# Können die Argumente, Felder, Sortierkriterien und Filter *oder* der Ansichtentyp nicht mehr geändert werden? +#: includes/admin.inc:556 +#, fuzzy +msgid "The view type is the primary table for which information is being retrieved. The view type controls what arguments, fields, sort criteria and filters are available, so once this is set it <strong>cannot be changed</strong>." +msgstr "Der Ansichtentyp ist die primäre Tabelle für die Information abgefragt werden. Da der Ansichtentyp die zu Verfügung stehenden Argumente, Felder, Sortierkriterien und Filter kontrolliert, können diese <strong>nicht mehr geändert werden</strong>, nachdem diese einmal eingestellt wurden." + +#: includes/admin.inc:567 +msgid "Next" +msgstr "nächste Seite" + +#: includes/admin.inc:583;758 +msgid "View name must be alphanumeric or underscores only." +msgstr "Der Name einer Ansicht darf nur aus Buchstaben und Unterstrichen bestehen." + +#: includes/admin.inc:589 +msgid "You must use a unique name for this view." +msgstr "Für die Ansicht muss ein eindeutiger Name verwendet werden." + +#: includes/admin.inc:622 +msgid "Are you sure you want to revert the view %name?" +msgstr "Soll die Ansicht %name wirklich zurückgesetzt werden?" + +#: includes/admin.inc:623 +msgid "Reverting the view will delete the view that is in the database, reverting it to the original default view. Any changes you have made will be lost and cannot be recovered." +msgstr "Eine Ansicht zurückzusetzten wird die Ansicht in der Datenbank löschen und auf die Orginalansicht zurücksetzten. Alle vorgenommenen Änderungen gehen verloren und können nicht wiederhergestellt werden." + +#: includes/admin.inc:626 +#: includes/convert.inc:105 +msgid "Are you sure you want to delete the view %name?" +msgstr "Soll die Ansicht %name wirklich gelöscht werden?" + +#: includes/admin.inc:627 +msgid "Deleting a view cannot be undone." +msgstr "Das Löschen einer Ansicht kann nicht rückgängig gemacht werden." + +#: includes/admin.inc:635;671;840;1329 +#: includes/convert.inc:109 +msgid "Cancel" +msgstr "Abbrechen" + +#: includes/admin.inc:644 +msgid "The view has been deleted." +msgstr "Die Ansicht wurde gelöscht." + +#: includes/admin.inc:656 +msgid "There is no lock on view %view to break." +msgstr "Auf der Ansicht %view gibt es keine aufzuhebende Sperre." + +#: includes/admin.inc:666 +msgid "Are you sure you want to break the lock on view %name?" +msgstr "Soll die Sperre auf der Ansicht %name wirklich aufgehoben werden?" + +#: includes/admin.inc:669 +msgid "By breaking this lock, any unsaved changes made by !user will be lost!" +msgstr "Durch Aufheben der Sperre, gehen alle ungespeicherten Änderungen von !user verloren!" + +#: includes/admin.inc:670 +msgid "Break lock" +msgstr "Sperre aufheben" + +#: includes/admin.inc:680 +msgid "The lock has been broken and you may now edit this view." +msgstr "Die Sperre wurde aufgehoben und die Ansicht kann jetzt bearbeitet werden." + +#: includes/admin.inc:687 +msgid "Edit view %view" +msgstr "Ansicht %view bearbeiten" + +#: includes/admin.inc:714 +msgid "Enter the name to use for this view if it is different from the source view. Leave blank to use the name of the view." +msgstr "Einen Namen für die Ansicht eingeben, wenn dieser anders als die ursprüngliche Ansicht ist. Freilassen, um den Namen der Ansicht zu verwenden." + +#: includes/admin.inc:719 +msgid "Paste view code here" +msgstr "Code für die Ansicht hier einfügen" + +#: includes/admin.inc:741 +msgid "Unable to interpret view code." +msgstr "Code der Ansicht konnte nicht Interpretiert werden." + +#: includes/admin.inc:749 +msgid "You are importing a view created in Views version 1. You may need to adjust some parameters to work correctly in version 2." +msgstr "Es wird eine Ansicht aus Views-Version 1 importiert. Hier müssen möglicherweise einige Parameter angepasst werden, damit diese mit Version 2 richtig zusammenarbeitet." + +#: includes/admin.inc:752 +msgid "That view is not compatible with this version of Views." +msgstr "Diese Ansicht ist inkompatibel mit dieser Ansichtenversion." + +#: includes/admin.inc:767 +msgid "A view by that name already exists; please choose a different name" +msgstr "Eine Ansicht mit diesem Namen ist schon vorhanden. Bitte einen anderen Namen wählen." + +#: includes/admin.inc:776 +msgid "Display plugin @plugin is not available." +msgstr "Das Anzeige-Plugin @plugin ist nicht verfügbar." + +#: includes/admin.inc:783 +msgid "Style plugin @plugin is not available." +msgstr "Das Design-Plugin @plugin ist nicht verfügbar." + +#: includes/admin.inc:789 +msgid "Row plugin @plugin is not available." +msgstr "Das Zeilen-Plugin @plugin ist nicht verfügbar." + +#: includes/admin.inc:799 +msgid "@type handler @table.@field is not available." +msgstr "Die @type-Behandlungsroutine @table.@field ist nicht verfügbar." + +#: includes/admin.inc:812 +msgid "Unable to import view." +msgstr "Die Ansicht konnte nicht importiert werden." + +#: includes/admin.inc:833;861 +msgid "Save" +msgstr "Speichern" + +#: includes/admin.inc:885 +msgid "The view has been saved." +msgstr "Die Ansicht wurde gespeichert." + +#: includes/admin.inc:929 +msgid "Unknown or missing table name" +msgstr "Unbekannter oder fehlender Tabellenname" + +#: includes/admin.inc:934 +msgid "Click on an item to edit that item's details." +msgstr "Einen Eintrag anklicken, um die Details zu bearbeiten." + +#: includes/admin.inc:937 +msgid "This view has a broken default display and cannot be used." +msgstr "Diese Ansicht enthält eine beschädigte Standardanzeige und kann nicht verwendet werden." + +#: includes/admin.inc:979 +#: theme/theme.inc:97 +msgid "Export this view" +msgstr "Diese Ansicht exportieren" + +#: includes/admin.inc:984 +#: theme/theme.inc:102 +msgid "Create a copy of this view" +msgstr "Eine Kopie der Ansicht erstellen" + +#: includes/admin.inc:995 +msgid "View \"!display\"" +msgstr "Ansicht „!display“" + +#: includes/admin.inc:996 +msgid "Go to the real page for this display" +msgstr "Auf die reale Seite dieser Anzeige wechseln" + +#: includes/admin.inc:1062;3008 +#: includes/plugins.inc:218 +#: plugins/views_plugin_display.inc:587;704;723 +#: plugins/views_plugin_display_attachment.inc:90 +#: plugins/views_plugin_display_block.inc:73 +#: plugins/views_plugin_display_feed.inc:108 +#: plugins/views_plugin_display_page.inc:193 +msgid "None" +msgstr "Keines" + +#: includes/admin.inc:1140 +msgid "Invalid" +msgstr "Ungültig" + +#: includes/admin.inc:1141 +msgid "Error: Display @display refers to a plugin named '@plugin', but that plugin doesn't exist!" +msgstr "Fehler: Die Anzeige @display bezieht sich auf das nicht vorhandene Plugin ‚@plugin‘!" + +#: includes/admin.inc:1176;1176 +msgid "Rearrange" +msgstr "Umsortieren" + +#: includes/admin.inc:1216;2216;2391;2459;2544 +msgid "Error: handler for @table > @field doesn't exist!" +msgstr "Fehler: Die Behandlungsroutine für @table > @field ist nicht vorhanden!" + +#: includes/admin.inc:1235;1235;1244 +msgid "Settings" +msgstr "Einstellungen" + +#: includes/admin.inc:1240 +#: plugins/views_plugin_display.inc:598;616 +msgid "Missing style plugin" +msgstr "Fehlendes Design-Plugin" + +#: includes/admin.inc:1244 +#: plugins/views_plugin_display.inc:611;626 +msgid "Change settings for this style" +msgstr "Einstellungen für dieses Design ändern" + +#: includes/admin.inc:1247 +msgid " Style: !style" +msgstr " Design: !style" + +# not literally +#: includes/admin.inc:1278 +msgid "Invalid display id found while regenerating tabs" +msgstr "Eine ungültige Anzeige-ID wurde bei der Neuerstellung von Reitern gefunden" + +#: includes/admin.inc:1311 +msgid "Update" +msgstr "Aktualisieren" + +#: includes/admin.inc:1329 +msgid "Ok" +msgstr "Ok" + +#: includes/admin.inc:1600 +msgid "Unable to initialize default display" +msgstr "Die Standardanzeige konnte nicht initialisiert werden." + +#: includes/admin.inc:1632 +msgid "Add display" +msgstr "Anzeige hinzufügen" + +#: includes/admin.inc:1672 +msgid "Remove display" +msgstr "Anzeige entfernen" + +#: includes/admin.inc:1683 +msgid "Restore display" +msgstr "Anzeige wiederherstellen" + +#: includes/admin.inc:1755 +msgid "Analyze" +msgstr "Analysieren" + +#: includes/admin.inc:1767 +msgid "View analysis" +msgstr "Analyse anzeigen" + +#: includes/admin.inc:1821 +msgid "View details" +msgstr "Ansichtdetails" + +#: includes/admin.inc:1862;1916;1971;2117;2209;2384;2452;2537 +msgid "Invalid display id @display" +msgstr "Ungültige Anzeige-ID @display" + +#: includes/admin.inc:1920 +msgid "Configure @type" +msgstr "@type konfigurieren" + +#: includes/admin.inc:1975 +msgid "Rearrange @type" +msgstr "@type neu anordnen" + +#: includes/admin.inc:2018 +msgid "Broken field @id" +msgstr "Beschädigtes Feld @id" + +#: includes/admin.inc:2058;2067;2300 +msgid "Remove" +msgstr "Entfernen" + +#: includes/admin.inc:2058;2058 +msgid "Remove this item" +msgstr "Dieses Element entfernen" + +#: includes/admin.inc:2064 +msgid "No fields available." +msgstr "Keine Felder verfügbar." + +#: includes/admin.inc:2067 +#: modules/book.views.inc:57 +#: modules/taxonomy.views.inc:135 +#: modules/upload.views.inc:90 +#: plugins/views_plugin_display_page.inc:312 +msgid "Weight" +msgstr "Reihenfolge" + +#: includes/admin.inc:2123 +msgid "Add @type" +msgstr "@type hinzufügen" + +#: includes/admin.inc:2134 +msgid "Groups" +msgstr "Gruppen" + +#: includes/admin.inc:2153 +msgid "!group: !field" +msgstr "!group: !field" + +#: includes/admin.inc:2162 +#, fuzzy +msgid "There are no @types available to add." +msgstr "Es stehen keine @types zum Hinzufügen zu Verfügung." + +#: includes/admin.inc:2259 +msgid "Do not use a relationship" +msgstr "Keine Beziehung verwenden" + +#: includes/admin.inc:2273 +#: includes/view.inc:1894;1895 +msgid "Relationship" +msgstr "Beziehung" + +#: includes/admin.inc:2286 +msgid "Configure @type %item" +msgstr "@type %item konfigurieren" + +#: includes/admin.inc:2399 +msgid "Configure extra settings for @type %item" +msgstr "Besondere Einstellungen für @type %item konfigurieren" + +#: includes/admin.inc:2464 +msgid "Change summary style for @type %item" +msgstr "Zusammenfassungsdesign für @type %item ändern" + +#: includes/admin.inc:2487;2501 +msgid "Internal error: broken plugin." +msgstr "Interner Fehler: beschädigtes Plugin." + +#: includes/admin.inc:2551 +msgid "Configure summary style for @type %item" +msgstr "Zusammenfassungsdesign für @type %item konfigurieren" + +#: includes/admin.inc:2643 +msgid "Clear Views' cache" +msgstr "Ansichten-Cache leeren" + +#: includes/admin.inc:2649 +msgid "Add Views signature to all SQL queries" +msgstr "Eine View-Signatur zu allen SQL-Abfragen hinzufügen" + +# TODO troubleshooting +#: includes/admin.inc:2650 +msgid "All Views-generated queries will include a special 'VIEWS' = 'VIEWS' string in the WHERE clause. This makes identifying Views queries in database server logs simpler, but should only be used when troubleshooting." +msgstr "Alle von Ansichten generierten Abfragen werden eine spezielle Zeichenkette 'VIEWS' = 'VIEWS' in der WHERE Bedingung enthalten. Dies erlaubt die einfachere Identifikation der Abfragen von Ansichten in den Datenbankprotokollen, sollte aber nur zur Fehlersuche genutzt werden." + +#: includes/admin.inc:2656 +msgid "Disable views data caching" +msgstr "Datencaching von Ansichten deaktivieren" + +#: includes/admin.inc:2657 +msgid "Views caches data about tables, modules and views available, to increase performance. By checking this box, Views will skip this cache and always rebuild this data when needed. This can have a serious performance impact on your site." +msgstr "Ansichten cached Daten über die Tabellen, Module und verfügbaren Ansichten, um die Leistung zu steigern. Durch aktivieren dieses Ankreuzfeldes wird Ansichten den Cache übergehen und die Daten bei Bedarf neu aufbauen. Dies kann erhebliche Auswirkungen auf die Leistung der Website haben." + +#: includes/admin.inc:2663 +msgid "Ignore missing advanced help module" +msgstr "Das fehlende Erweiterte-Hilfe-Modul ignorieren" + +#: includes/admin.inc:2664 +msgid "Views uses the advanced help module to provide help text; if this module is not present Views will complain, unless this setting is checked." +msgstr "Das Ansichten-Modul verwendet das Erweiterte Hilfe-Modul, um Hilfetexte zu Verfügung zu stellen. Sollte das Modul nicht vorhanden sein, wird das Ansichten-Modul solange darauf hinweisen, bis diese Einstellung aktiviert wurde. " + +#: includes/admin.inc:2670 +msgid "Show query above live preview" +msgstr "Abfrage oberhalb der Live-Vorschau anzeigen" + +#: includes/admin.inc:2671 +msgid "The live preview feature will show you the output of the view you're creating, as well as the view. Check here to show the query and other information above the view; leave this unchecked to show that information below the view." +msgstr "Die Live-Vorschau-Funktion wird die Ausgabe der erstellten Ansicht und auch die Ansicht anzeigen. Aktivieren, um die Abfrage und andere Information oberhalb der Ansicht anzuzeigen. Deaktivieren, um diese Information unterhalb der Ansicht anzuzeigen." + +#: includes/admin.inc:2677 +msgid "Show other queries run during render during live preview" +msgstr "" + +#: includes/admin.inc:2678 +msgid "Drupal has the potential to run many queries while a view is being rendered. Checking this box will display every query run during view render as part of the live preview." +msgstr "" + +# not literally +#: includes/admin.inc:2684 +msgid "Do not show hover links over views" +msgstr "Administrationslinks in den Ansichten nicht anzeigen" + +# not literally +#: includes/admin.inc:2685 +msgid "To make it easier to administrate your views, Views provides 'hover' links to take you to the edit and export screen of a view whenever the view is used. This can be distracting on some themes, though; if it is problematic, you can turn it off here." +msgstr "Um die Verwaltung der Ansichten zu erleichtern, werden Administrationslinks in den Ansichten angezeigt, mit denen man zur Bearbeiten- und Exportieren-Seite einer Ansicht gelangt. Diese können in einigen Themes stören und bei Problemen hiermit abgeschaltet werden." + +#: includes/admin.inc:2691 +msgid "Enable views performance statistics via the Devel module" +msgstr "Performancestatistiken für Ansichten mittels Devel-Modul aktivieren" + +#: includes/admin.inc:2692 +msgid "Check this to enable some Views query and performance statistics <em>if Devel is installed</em>." +msgstr "Aktivieren, damit Abfragen und Leistungsstatistiken der Ansicht bei <em>installiertem Devel-Modul</em> angezeigt werden." + +#: includes/admin.inc:2698 +msgid "Disable javascript with Views" +msgstr "JavaScript mit Ansichten deaktivieren" + +#: includes/admin.inc:2699 +msgid "If you are having problems with the javascript, you can disable it here; the Views UI should degrade and still be usable without javascript, it just not as good." +msgstr "" + +# not literally +#: includes/admin.inc:2707 +msgid "Page region to output performance statistics" +msgstr "Performancestatistiken in folgender Seitenregion ausgegeben" + +#: includes/admin.inc:2720 +msgid "The cache has been cleared." +msgstr "Der Cache wurde geleert." + +#: includes/admin.inc:2886 +msgid "Error: missing @component" +msgstr "Fehler: @component fehlt" + +#: includes/admin.inc:2972 +#: includes/view.inc:1865 +msgid "Field" +msgstr "Feld" + +#: includes/admin.inc:2973 +msgid "Column" +msgstr "Spalte" + +#: includes/admin.inc:2976 +msgid "Sortable" +msgstr "Sortierbar" + +#: includes/admin.inc:2980 +msgid "Default sort" +msgstr "Standardsortierung" + +# not literally +#: includes/ajax.inc:82 +msgid "Server reports invalid input error." +msgstr "Der Server hat eine ungültige Eingabe festgestellt." + +#: includes/ajax.inc:83 +msgid "Error" +msgstr "Fehler" + +# http://drupal.org/node/279073#comment-909822 +#: includes/analyze.inc:38 +msgid "View analysis can find nothing to report." +msgstr "Die Analyse der Ansicht kann nichts berichtenswertes finden." + +#: includes/analyze.inc:104 +msgid "This view has only a default display and therefore will not be placed anywhere on your site; perhaps you want to add a page or a block display." +msgstr "" + +#: includes/convert.inc:14 +msgid "There are no Views 1 views stored in the database to convert." +msgstr "In der Datenbank sind keine Views-1-Ansichten zum konvertieren vorhanden." + +#: includes/convert.inc:22 +msgid "Operations" +msgstr "Operationen" + +#: includes/convert.inc:33 +msgid "Converted" +msgstr "Konvertiert" + +#: includes/convert.inc:68 +msgid "The table below lists Views version 1 views that are stored in the database. You can either convert them to work in Views version 2, or delete them. The views are convertible only if there is no Views 2 view with the same name." +msgstr "" + +#: includes/convert.inc:79 +msgid "Unable to find view." +msgstr "Ansicht konnte nicht gefunden werden." + +#: includes/convert.inc:89 +msgid "Unable to convert view." +msgstr "Ansicht konnte nicht konvertiert werden." + +#: includes/convert.inc:107 +msgid "This action cannot be undone." +msgstr "Dieser Vorgang kann nicht rückgängig gemacht werden." + +#: includes/convert.inc:117 +msgid "The view has been deleted" +msgstr "Die Ansicht wurde gelöscht." + +#: includes/form.inc:249 +msgid "Validation error, please try again. If this error persists, please contact the site administrator." +msgstr "Bei der Gültigkeitsüberprüfung ist ein Fehler aufgetreten, bitte erneut versuchen. Falls der Fehler fortbesteht, wenden Sie sich bitte an den Administrator der Website." + +#: includes/handlers.inc:43 +msgid "Handler @handler include tried to loop infinitely!" +msgstr "Die Behandlungsroutine @handler ist eine Endlosschleife!" + +#: includes/handlers.inc:269 +msgid "!group: !title" +msgstr "!group: !title" + +#: includes/handlers.inc:507 +msgid "Reduce duplicates" +msgstr "Duplikate reduzieren" + +#: includes/handlers.inc:508 +msgid "This filter can cause items that have more than one of the selected options to appear as duplicate results. If this filter causes duplicate results to occur, this checkbox can reduce those duplicates; however, the more terms it has to search for, the less performant the query will be, so use this with caution." +msgstr "" + +#: includes/plugins.inc:26 +msgid "Default settings for this view." +msgstr "Standardeinstellungen für diese Ansicht." + +# not literally +#: includes/plugins.inc:40 +msgid "Display the view as a page, with a URL and menu links." +msgstr "Die Ansicht als Seite mit einer URL und Menüeinträgen anzeigen." + +#: includes/plugins.inc:51;60 +msgid "Block" +msgstr "Block" + +#: includes/plugins.inc:52 +msgid "Display the view as a block." +msgstr "Eine Ansicht als Block anzeigen." + +#: includes/plugins.inc:64 +msgid "Attachment" +msgstr "Anhang" + +#: includes/plugins.inc:65 +msgid "Attachments added to other displays to achieve multiple views in the same view." +msgstr "" + +#: includes/plugins.inc:73 +msgid "Display the view as a feed, such as an RSS feed." +msgstr "Die Ansicht als Newsfeed anzeigen, wie einen RSS-Newsfeed." + +#: includes/plugins.inc:93;144 +msgid "Unformatted" +msgstr "Unformatiert" + +#: includes/plugins.inc:94 +msgid "Displays rows one after another." +msgstr "Zeigt die Zeilen aufeinander folgend an." + +#: includes/plugins.inc:104 +msgid "HTML List" +msgstr "HTML-Liste" + +#: includes/plugins.inc:105 +msgid "Displays rows as an HTML list." +msgstr "Zeigt die Zeilen als HTML-Liste an." + +#: includes/plugins.inc:114 +msgid "Grid" +msgstr "Raster" + +#: includes/plugins.inc:115 +msgid "Displays rows in a grid." +msgstr "Zeilen in einem Gitter anzeigen." + +#: includes/plugins.inc:124 +msgid "Table" +msgstr "Tabelle" + +#: includes/plugins.inc:125 +msgid "Displays rows in a table." +msgstr "Zeilen in einer Tabelle anzeigen." + +#: includes/plugins.inc:136 +msgid "Displays the default summary as a list." +msgstr "Zeigt die standardmäßige Zusammenfassung als Liste an." + +#: includes/plugins.inc:145 +#, fuzzy +msgid "Displays the summary unformatted, with option for one after another or inline." +msgstr "Zeigt die Zusammenfassung unformatiert an, mit der Option eine nach der anderen oder inline." + +#: includes/plugins.inc:154 +msgid "RSS Feed" +msgstr "RSS-Feed" + +#: includes/plugins.inc:155 +msgid "Generates an RSS feed from a view." +msgstr "Generiert einen RSS-Newsfeed aus einer Ansicht." + +#: includes/plugins.inc:173 +#: includes/view.inc:1863 +msgid "Fields" +msgstr "Felder" + +#: includes/plugins.inc:174 +msgid "Displays the fields with an optional template." +msgstr "Die Felder mit einer optionalen Vorlage anzeigen." + +#: includes/plugins.inc:187 +msgid "Fixed entry" +msgstr "Fester Eintrag" + +#: includes/plugins.inc:191;203 +msgid "PHP Code" +msgstr "PHP-Code" + +#: includes/plugins.inc:207 +msgid "Numeric" +msgstr "Numerisch" + +#: includes/plugins.inc:219 +msgid "Will be available to all users." +msgstr "Wird allen Benutzern zu Verfügung stehen." + +#: includes/plugins.inc:224 +#: plugins/views_plugin_access_role.inc:40 +msgid "Role" +msgstr "Rolle" + +#: includes/plugins.inc:225 +msgid "Access will be granted to users with any of the specified roles." +msgstr "" + +#: includes/plugins.inc:231 +#: plugins/views_plugin_access_perm.inc:35 +msgid "Permission" +msgstr "Berechtigung" + +#: includes/plugins.inc:232 +msgid "Access will be granted to users with the specified permission string." +msgstr "" + +#: includes/view.inc:261 +msgid "set_display() called with invalid display id @display." +msgstr "set_display() wurde mit ungültiger Anzeige-ID @display aufgerufen." + +#: includes/view.inc:1063 +msgid "Home" +msgstr "Startseite" + +#: includes/view.inc:1864 +msgid "fields" +msgstr "Felder" + +#: includes/view.inc:1866 +msgid "field" +msgstr "Feld" + +#: includes/view.inc:1871 +msgid "arguments" +msgstr "Argumente" + +#: includes/view.inc:1872;1873 +msgid "Argument" +msgstr "Argument" + +#: includes/view.inc:1877 +msgid "Sort criteria" +msgstr "Sortierkriterium" + +#: includes/view.inc:1878 +msgid "sort criteria" +msgstr "Sortierkriterium" + +#: includes/view.inc:1879 +msgid "Sort criterion" +msgstr "Sortierkriterien" + +#: includes/view.inc:1880 +msgid "sort criterion" +msgstr "Sortierkriterien" + +#: includes/view.inc:1884 +msgid "Filters" +msgstr "Filter" + +#: includes/view.inc:1885 +msgid "filters" +msgstr "Filter" + +#: includes/view.inc:1886 +msgid "Filter" +msgstr "Filter" + +#: includes/view.inc:1887 +msgid "filter" +msgstr "Filter" + +#: includes/view.inc:1892 +msgid "Relationships" +msgstr "Beziehungen" + +#: includes/view.inc:1893 +msgid "relationships" +msgstr "Beziehungen" + +# auf/bei/unter? +#: js/ajax.js:0;0;0;0;0;0;0 +#: js/ajax_view.js:0;0;0 +#, fuzzy +msgid "An error occurred at @path." +msgstr "Ein Fehler ist auf @path aufgetreten." + +#: js/tabs.js:0 +msgid "jQuery UI Tabs: Mismatching fragment identifier." +msgstr "" + +#: js/tabs.js:0 +msgid "jQuery UI Tabs: Not enough arguments to add tab." +msgstr "jQuery UI-Reiter: Nicht genug Argumente, um einen Reiter hinzuzufügen." + +#: modules/book.views.inc:21;36;46;99 +msgid "Book" +msgstr "Buch" + +#: modules/book.views.inc:30 +msgid "Top level book" +msgstr "In Moderation" + +#: modules/book.views.inc:31 +msgid "The book the node is in." +msgstr "Das Buch, indem der Beitrag enthalten ist." + +#: modules/book.views.inc:58 +msgid "The weight of the book page." +msgstr "Die Reihenfolge der Buchseite." + +#: modules/book.views.inc:69 +#: modules/comment.views.inc:202 +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:24 +msgid "Depth" +msgstr "Tiefe" + +#: modules/book.views.inc:70 +msgid "The depth of the book page in the hierarchy; top level books have a depth of 1." +msgstr "Die Tiefe der Buchseite in der Hierarchie. Bücher der obersten Ebene haben eine Tiefe von 1." + +#: modules/book.views.inc:87 +msgid "Hierarchy" +msgstr "Hierarchie" + +#: modules/book.views.inc:88 +msgid "The order of pages in the book hierarchy. Remember to sort by weight too if you want exactly the right order." +msgstr "" + +#: modules/book.views.inc:110 +#: modules/taxonomy.views.inc:259 +msgid "Parent" +msgstr "Übergeordnet" + +#: modules/book.views.inc:111 +msgid "The parent book node." +msgstr "Der übergeordnete Buchbeitrag." + +#: modules/book.views.inc:116 +msgid "Book parent" +msgstr "Übergeordnetes Buch" + +#: modules/comment.views.inc:22;26;384;395 +msgid "Comment" +msgstr "Kommentar" + +#: modules/comment.views.inc:27 +msgid "Comments are responses to node content." +msgstr "Kommentare sind Antworten auf Inhalte von Beiträgen." + +#: modules/comment.views.inc:45 +msgid "The title of the comment." +msgstr "Der Titel des Kommentars." + +#: modules/comment.views.inc:63 +#: modules/node.views.inc:358 +msgid "Body" +msgstr "Textkörper" + +#: modules/comment.views.inc:64 +msgid "The text of the comment." +msgstr "Der Text des Kommentars." + +#: modules/comment.views.inc:76 +msgid "ID" +msgstr "ID" + +#: modules/comment.views.inc:77 +msgid "The comment ID of the field" +msgstr "Die Kommentar-ID des Feldes" + +#: modules/comment.views.inc:95 +msgid "Author" +msgstr "Autor" + +#: modules/comment.views.inc:96 +msgid "The name of the poster." +msgstr "Der Name des Beitragenden." + +#: modules/comment.views.inc:114 +msgid "Author's website" +msgstr "Website des Autors" + +#: modules/comment.views.inc:115 +msgid "The website address of the comment's author. Can be a link. The homepage can also be linked with the Name field. Will be empty if posted by a registered user." +msgstr "" + +#: modules/comment.views.inc:133 +#: modules/node.views.inc:108 +msgid "Post date" +msgstr "Beitragsdatum" + +#: modules/comment.views.inc:134 +msgid "Date and time of when the comment was posted." +msgstr "Zeitpunkt zu dem der Kommentar gespeichert wurde." + +#: modules/comment.views.inc:149 +msgid "In moderation" +msgstr "In Moderation" + +#: modules/comment.views.inc:150 +msgid "Whether or not the comment is currently in moderation." +msgstr "Ob sich der Kommentar derzeit in Moderation befindet oder nicht." + +#: modules/comment.views.inc:157 +#: modules/node.views.inc:204;213 +msgid "Moderated" +msgstr "Moderiert" + +#: modules/comment.views.inc:167 +msgid "View link" +msgstr "‚Anzeigen‘-Link" + +#: modules/comment.views.inc:168 +msgid "Provide a simple link to view the comment." +msgstr "Stellt einen einfachen Link zur Ansicht des Kommentars bereit." + +#: modules/comment.views.inc:176 +#: modules/node.views.inc:250 +#: modules/user.views.inc:202 +msgid "Edit link" +msgstr "‚Bearbeiten‘-Link" + +#: modules/comment.views.inc:177 +msgid "Provide a simple link to edit the comment." +msgstr "Stellt einen einfachen Link zum Bearbeiten des Kommentars bereit." + +#: modules/comment.views.inc:185 +#: modules/node.views.inc:258;472 +#: modules/user.views.inc:210 +msgid "Delete link" +msgstr "‚Löschen‘-Link" + +#: modules/comment.views.inc:186 +msgid "Provide a simple link to delete the comment." +msgstr "Stellt einen einfachen Link zum Löschen des Kommentars bereit." + +#: modules/comment.views.inc:194 +msgid "Reply-to link" +msgstr "‚Antworten‘-Link" + +#: modules/comment.views.inc:195 +msgid "Provide a simple link to reply to the comment." +msgstr "Stellt einen einfachen Link zum Antworten auf den Kommentars bereit." + +#: modules/comment.views.inc:203 +msgid "Display the depth of the comment if it is threaded." +msgstr "Bei gruppierter Ansicht die Verschachtelungstiefe des Kommentars anzeigen." + +#: modules/comment.views.inc:207 +msgid "Thread" +msgstr "Thread" + +#: modules/comment.views.inc:208 +msgid "Sort by the threaded order. This will keep child comments together with their parents." +msgstr "Nach der gruppierten Reihenfolge sortieren. Dies wird die Unterkommentare mit ihren Eltern zusammenlassen." + +#: modules/comment.views.inc:214;220;255 +#: modules/node.views.inc:24;29;90;357;372;484;616;627;639 +#: modules/upload.views.inc:43 +msgid "Node" +msgstr "Beitrag" + +#: modules/comment.views.inc:215 +msgid "The node the comment is a reply to." +msgstr "Der Beitrag auf den sich diese Antwort bezieht." + +#: modules/comment.views.inc:225;231 +#: modules/node.views.inc:345 +#: modules/statistics.views.inc:204 +#: modules/user.views.inc:23;27;219 +msgid "User" +msgstr "Benutzer" + +#: modules/comment.views.inc:226 +msgid "The user who wrote the comment." +msgstr "Der Benutzer, der den Kommentar geschrieben hat." + +#: modules/comment.views.inc:236 +msgid "Parent CID" +msgstr "Übergeordnete Kommentar-ID" + +#: modules/comment.views.inc:237 +msgid "The Comment ID of the parent comment." +msgstr "Die Kommentar-ID dies übergeordneten Kommentars." + +#: modules/comment.views.inc:242;247 +msgid "Parent comment" +msgstr "Übergeordneter Kommentar" + +#: modules/comment.views.inc:243 +msgid "The parent comment." +msgstr "Der übergeordnete Kommentar." + +#: modules/comment.views.inc:268 +msgid "Last comment time" +msgstr "Letzter Kommentarzeitpunkt" + +#: modules/comment.views.inc:269 +msgid "Date and time of when the last comment was posted." +msgstr "Zeitpunkt zu dem der letzte Kommentar gespeichert wurde." + +#: modules/comment.views.inc:284 +msgid "Last comment author" +msgstr "Letzter Kommentarautor" + +#: modules/comment.views.inc:285 +msgid "The name of the author of the last posted comment." +msgstr "Der Name des Autors von dem letzten Kommentar." + +#: modules/comment.views.inc:297 +msgid "Comment count" +msgstr "Anzahl an Kommentaren" + +#: modules/comment.views.inc:298 +msgid "The number of comments a node has." +msgstr "Die Anzahl der Kommentare zu einem Beitrag." + +#: modules/comment.views.inc:316 +msgid "Updated/commented date" +msgstr "Aktualisierungs-/Kommentarzeitpunkt" + +#: modules/comment.views.inc:317 +msgid "The most recent of last comment posted or node updated time." +msgstr "" + +#: modules/comment.views.inc:340 +msgid "New comments" +msgstr "Neue Kommentare" + +#: modules/comment.views.inc:341 +msgid "The number of new comments on the node." +msgstr "Die Anzahl der neuen Kommentare zu dem Beitrag." + +#: modules/comment.views.inc:349 +msgid "Comment status" +msgstr "Kommentarstatus" + +#: modules/comment.views.inc:350 +msgid "Whether comments are enabled or disabled on the node." +msgstr "Ob Kommentare zu dem Beitrag aktiviert oder deaktiviert sind." + +#: modules/comment.views.inc:364 +msgid "User posted or commented" +msgstr "" + +#: modules/comment.views.inc:365 +msgid "Display comments only if a user posted the node or commented on the node." +msgstr "Kommentare nur anzeigen, wenn ein Benutzer den Beitrag gespeichert oder kommentiert hat." + +#: modules/comment.views.inc:385 +msgid "Display the comment with standard comment view." +msgstr "Den Kommentar mit der Standardkommentaransicht anzeigen." + +#: modules/comment.views.inc:396 +msgid "Display the comment as RSS." +msgstr "Zeigt den Kommentar als RSS-Newsfeed an." + +#: modules/node.views.inc:30 +msgid "Nodes are a Drupal site's primary content." +msgstr "Beiträge sind der primäre Inhalt einer Drupal-Website." + +#: modules/node.views.inc:57 +msgid "Nid" +msgstr "Beitrags-ID" + +#: modules/node.views.inc:58 +msgid "The node ID of the node." +msgstr "Die Beitrags-ID des Beitrags." + +#: modules/node.views.inc:86;414 +msgid "The title of the node." +msgstr "Der Titel des Beitrags." + +# ? +#: modules/node.views.inc:109 +msgid "The date the node was posted." +msgstr "Der Zeitpunkt zu dem der Beitrag gespeichert wurde." + +#: modules/node.views.inc:124 +msgid "Updated date" +msgstr "Aktualisierungszeitpunkt" + +#: modules/node.views.inc:125 +msgid "The date the node was last updated." +msgstr "Der Zeitpunkt zu dem der Beitrag das letzte mal aktualisiert wurde." + +#: modules/node.views.inc:141 +msgid "The type of a node (for example, \"blog entry\", \"forum post\", \"story\", etc)." +msgstr "Der Beitragstyp (zum Beispiel: „Blogbeitrag“, „Forumsbeitrag“, „Artikel“, usw)." + +#: modules/node.views.inc:159;167;181 +#: modules/translation.views.inc:106 +#: modules/upload.views.inc:82 +msgid "Published" +msgstr "Veröffentlicht" + +#: modules/node.views.inc:160 +msgid "The published status of the node." +msgstr "Den Veröffentlichungsstatus des Beitrags." + +#: modules/node.views.inc:176 +#, fuzzy +msgid "Published or admin" +msgstr "Veröffentlicht oder Verwalter" + +#: modules/node.views.inc:177 +msgid "Filters out unpublished nodes if the current user cannot view them." +msgstr "Filtert unveröffentlichte Beiträge aus, wenn der aktuelle Benutzer diese nicht sehen kann." + +#: modules/node.views.inc:187;195 +msgid "Promoted to front page" +msgstr "Auf der Startseite" + +#: modules/node.views.inc:188 +msgid "The front page of the node." +msgstr "Die Startseite dieses Beitrags." + +#: modules/node.views.inc:205 +msgid "Whether or not the node is moderated." +msgstr "Ob ein Beitrag moderiert ist oder nicht." + +#: modules/node.views.inc:222;231 +msgid "Sticky" +msgstr "am Anfang von Listen" + +#: modules/node.views.inc:223 +msgid "Whether or not the node is sticky." +msgstr "Ob ein Beitrag am Anfang von Listen angezeigt wird oder nicht." + +#: modules/node.views.inc:242 +msgid "Link" +msgstr "Link" + +#: modules/node.views.inc:243 +msgid "Provide a simple link to the node." +msgstr "Stellt einen einfachen Link zu dem Beitrag bereit." + +#: modules/node.views.inc:251 +msgid "Provide a simple link to edit the node." +msgstr "Stellt einen einfachen Link zum Bearbeiten des Beitrags bereit." + +#: modules/node.views.inc:259 +msgid "Provide a simple link to delete the node." +msgstr "Stellt einen einfachen Link zum Löschen des Beitrags bereit." + +#: modules/node.views.inc:267;448 +#: modules/user.views.inc:123 +msgid "Created date" +msgstr "Erstellungsdatum" + +#: modules/node.views.inc:268 +msgid "In the form of CCYYMMDD." +msgstr "In der Form von JJJJMMTT." + +#: modules/node.views.inc:276 +msgid "Created year + month" +msgstr "Jahr + Monat wurde erstellt" + +#: modules/node.views.inc:277 +msgid "In the form of YYYYMM." +msgstr "In der Form von JJJJMM." + +#: modules/node.views.inc:285 +msgid "Created year" +msgstr "Erstellungsjahr" + +#: modules/node.views.inc:286 +msgid "In the form of YYYY." +msgstr "In der Form von JJJJ." + +#: modules/node.views.inc:294 +msgid "Created month" +msgstr "Erstellungsmonat" + +#: modules/node.views.inc:295 +msgid "In the form of MM (01 - 12)." +msgstr "In der Form von MM (01 - 12)." + +#: modules/node.views.inc:303 +msgid "Created day" +msgstr "Erstellungstag" + +#: modules/node.views.inc:304 +msgid "In the form of DD (01 - 31)." +msgstr "In der Form von TT (01 - 31)." + +#: modules/node.views.inc:312 +msgid "Created week" +msgstr "Erstellungswoche" + +#: modules/node.views.inc:313 +msgid "In the form of WW (01 - 53)." +msgstr "In der Form von WW (01 - 53)." + +#: modules/node.views.inc:325;330 +msgid "Node revision" +msgstr "Beitragsversion" + +#: modules/node.views.inc:331 +msgid "Node revisions are a history of changes to nodes." +msgstr "Beitragsversionen sind eine Historie von Änderungen an Beiträgen." + +#: modules/node.views.inc:346 +msgid "Relate a node revision to the user who created the revision." +msgstr "" + +#: modules/node.views.inc:351 +msgid "user" +msgstr "Benutzer" + +#: modules/node.views.inc:359 +msgid "The actual, full data in the body field; this may not be valid data on all node types." +msgstr "" + +#: modules/node.views.inc:373 +msgid "Teaser" +msgstr "Anrisstext" + +#: modules/node.views.inc:374 +msgid "The stored teaser field. This may not be valid or useful data on all node types." +msgstr "" + +#: modules/node.views.inc:387 +msgid "Vid" +msgstr "Vid" + +#: modules/node.views.inc:388 +msgid "The revision ID of the node revision." +msgstr "Die Versions-ID der Beitragsversion." + +#: modules/node.views.inc:434 +msgid "Log message" +msgstr "Protokollnachricht" + +#: modules/node.views.inc:435 +msgid "The log message entered when the revision was created." +msgstr "Die eingegebene Protokollnachricht, als die Version erstellt wurde." + +#: modules/node.views.inc:449 +msgid "The date the node revision was created." +msgstr "Der Zeitpunkt zu dem die Beitragsversion erstellt wurde." + +#: modules/node.views.inc:464 +msgid "Revert link" +msgstr "‚Zurück‘-Link" + +#: modules/node.views.inc:465 +msgid "Provide a simple link to revert to the revision." +msgstr "Stellt einen einfachen Link bereit, um zu der Version zurückzukehren." + +#: modules/node.views.inc:473 +msgid "Provide a simple link to delete the node revision." +msgstr "Stellt einen einfachen Link zum Löschen der Beitragsversion bereit." + +#: modules/node.views.inc:500 +msgid "Has new content" +msgstr "Neuer Inhalt vorhanden" + +#: modules/node.views.inc:503 +msgid "Show a marker if the node has new or updated content." +msgstr "Eine Markierung anzeigen, wenn der Beitrag neuen oder aktualisierten Inhalt enthält." + +#: modules/node.views.inc:506 +msgid "Show only nodes that have new content." +msgstr "Nur Beiträge mit neuem Inhalt anzeigen." + +#: modules/node.views.inc:617;628 +msgid "Display the node with standard node view." +msgstr "Den Beitrag mit der Standardbeitragsansicht anzeigen." + +#: modules/node.views.inc:646 +msgid "Node ID from URL" +msgstr "Beitrags-ID aus der URL" + +#: modules/node.views.inc:708 +msgid "Display %display has no access control but does not contain a filter for published nodes." +msgstr "Die Anzeige %display hat keine Zugriffskontrolle und enthält keinen Filter für veröffentlichte Beiträge." + +#: modules/poll.views.inc:23 +msgid "Poll" +msgstr "Umfrage" + +#: modules/poll.views.inc:38;47 +#: modules/user.views.inc:171;180 +msgid "Active" +msgstr "Aktiv" + +#: modules/poll.views.inc:39 +msgid "Whether the poll is open for voting." +msgstr "Ob die Umfrage offen für die Stimmabgabe ist." + +#: modules/profile.views.inc:20;40 +msgid "Profile" +msgstr "Profil" + +#: modules/profile.views.inc:100 +msgid "@field-name" +msgstr "@field-name" + +#: modules/profile.views.inc:107 +msgid "Profile textfield" +msgstr "Profiltextfeld" + +#: modules/profile.views.inc:126 +msgid "Profile textarea" +msgstr "Profil-Textfeld" + +#: modules/profile.views.inc:142 +msgid "Profile checkbox" +msgstr "Profil-Ankreuzfeld" + +#: modules/profile.views.inc:159 +msgid "Profile URL" +msgstr "Profil-URL" + +#: modules/profile.views.inc:175 +msgid "Profile selection" +msgstr "Profileauswahl" + +#: modules/profile.views.inc:195 +msgid "Profile freeform list %field-name." +msgstr "" + +#: modules/profile.views.inc:207 +msgid "Profile date %field-name." +msgstr "Profildatum %field-name." + +#: modules/search.views.inc:23;77;88;106;163 +msgid "Search" +msgstr "Suchen" + +#: modules/search.views.inc:72 +msgid "Score" +msgstr "Punktzahl" + +#: modules/search.views.inc:73 +msgid "The score of the search item." +msgstr "Die Punktzahl der Suchebegriffes." + +#: modules/search.views.inc:95 +msgid "Links from" +msgstr "Links von" + +#: modules/search.views.inc:96 +msgid "Nodes that link from the node." +msgstr "Beiträge die von dem Beitrag verlinken." + +#: modules/search.views.inc:113 +msgid "Links to" +msgstr "Links zu" + +#: modules/search.views.inc:114 +msgid "Nodes that link to the node." +msgstr "Beiträge die auf den Beitrag verlinken." + +#: modules/search.views.inc:125 +msgid "Search Terms" +msgstr "Suchbegriffe" + +#: modules/search.views.inc:126 +msgid "The terms to search for." +msgstr "Die Begriffe nach denen gesucht werden soll." + +#: modules/search.views.inc:164 +msgid "Display the results with standard search view." +msgstr "Die Ergebnisse mit der Standard-Suchansicht anzeigen." + +#: modules/statistics.views.inc:24 +msgid "Node statistics" +msgstr "Beitragsstatistiken" + +#: modules/statistics.views.inc:36 +msgid "Total views" +msgstr "Seitenansichten gesamt" + +#: modules/statistics.views.inc:37 +msgid "The total number of times the node has been viewed." +msgstr "Dies zeigt die Anzahl an, wie oft ein Beitrag insgesamt gelesen wurde." + +#: modules/statistics.views.inc:53 +msgid "Views today" +msgstr "Heutige Seitenansichten" + +#: modules/statistics.views.inc:54 +msgid "The total number of times the node has been viewed today." +msgstr "Dies zeigt die Anzahl an, wie oft ein Beitrag heute gelesen wurde." + +#: modules/statistics.views.inc:70 +msgid "Most recent view" +msgstr "Die neuste Seitenansicht" + +#: modules/statistics.views.inc:71 +msgid "The most recent time the node has been viewed." +msgstr "Der letzte Zeitpunkt zu dem der Beitrag gelesen wurde." + +#: modules/statistics.views.inc:89;94 +msgid "Access log" +msgstr "Zugriffsprotokoll" + +#: modules/statistics.views.inc:95 +msgid "Stores site access information." +msgstr "Speichert die Zugriffsinformation auf die Website." + +#: modules/statistics.views.inc:109 +msgid "Session ID" +msgstr "Session-ID" + +#: modules/statistics.views.inc:110 +msgid "Browser session ID of user that visited page." +msgstr "Die Browser-Session-ID des Benutzers, der diese Seite besucht hat." + +#: modules/statistics.views.inc:129 +msgid "Page title" +msgstr "Seitentitel" + +#: modules/statistics.views.inc:130 +msgid "Title of page visited." +msgstr "Titel der besuchten Seite." + +#: modules/statistics.views.inc:150 +msgid "Internal path to page visited (relative to Drupal root.)" +msgstr "Interner Pfad zur besuchten Seite (relativ zum Drupal-Hauptverzeichnis)." + +#: modules/statistics.views.inc:169 +msgid "Referrer" +msgstr "Referrer" + +#: modules/statistics.views.inc:170 +msgid "Referrer URI." +msgstr "Referrer-URI." + +#: modules/statistics.views.inc:185 +msgid "Hostname" +msgstr "Hostadresse" + +#: modules/statistics.views.inc:186 +msgid "Hostname of user that visited the page." +msgstr "Der Hostname des Benutzers, der die Seite besucht hat." + +#: modules/statistics.views.inc:205 +msgid "The user who visited the site." +msgstr "Der Benutzer, der die Website besucht hat." + +#: modules/statistics.views.inc:215 +msgid "Timer" +msgstr "Timer" + +#: modules/statistics.views.inc:216 +msgid "Time in milliseconds that the page took to load." +msgstr "Die benötigte Ladezeit der Seite in Millisekunden." + +#: modules/statistics.views.inc:231 +msgid "Timestamp" +msgstr "Zeitstempel" + +#: modules/statistics.views.inc:232 +msgid "Timestamp of when the page was visited." +msgstr "Zeitstempel zu dem die Seite besucht wurde." + +#: modules/system.views.inc:25;30 +msgid "File" +msgstr "Datei" + +#: modules/system.views.inc:31 +msgid "Files maintained by Drupal and various modules." +msgstr "Dateien werden von Drupal und unterschiedlichen Modulen verwaltet." + +#: modules/system.views.inc:49 +msgid "File ID" +msgstr "Datei-ID" + +#: modules/system.views.inc:50 +msgid "The ID of the file." +msgstr "Die ID der Datei." + +#: modules/system.views.inc:70 +msgid "The name of the file." +msgstr "Der Name der Datei." + +#: modules/system.views.inc:89 +msgid "The path of the file." +msgstr "Der Pfad der Datei." + +#: modules/system.views.inc:107 +msgid "Mime type" +msgstr "MIME-Typ" + +#: modules/system.views.inc:108 +msgid "The mime type of the file." +msgstr "Der MIME-Typ der Datei." + +#: modules/system.views.inc:126 +msgid "Size" +msgstr "Größe" + +#: modules/system.views.inc:127 +msgid "The size of the file." +msgstr "Die Größe der Datei." + +#: modules/system.views.inc:142 +msgid "Status" +msgstr "Status" + +#: modules/system.views.inc:143 +msgid "The status of the file." +msgstr "Der Status der Datei." + +#: modules/system.views.inc:158 +msgid "Upload date" +msgstr "Profilauswahl" + +# ? +#: modules/system.views.inc:159 +msgid "The date the file was uploaded." +msgstr "Der Zeitpunkt zu dem die Datei hochgeladen wurde." + +#: modules/system.views.inc:204 +msgid "Temporary" +msgstr "Temporär" + +#: modules/system.views.inc:205 +msgid "Permanent" +msgstr "Dauerhaft" + +#: modules/taxonomy.views.inc:24;67;152;170;226;266;303;314 +msgid "Taxonomy" +msgstr "Taxonomie" + +#: modules/taxonomy.views.inc:48 +msgid "Vocabulary name" +msgstr "Vokabularname" + +#: modules/taxonomy.views.inc:50 +msgid "Name of the vocabulary a term is a member of. This will be the vocabulary that whichever term the \"Taxonomy: Term\" field is; and can similarly cause duplicates." +msgstr "" + +#: modules/taxonomy.views.inc:56 +msgid "Vocabulary ID" +msgstr "Vokabular-ID" + +#: modules/taxonomy.views.inc:57 +msgid "The taxonomy vocabulary ID" +msgstr "Die Vokabular-ID der Taxonomie" + +#: modules/taxonomy.views.inc:70;116;213 +msgid "Term" +msgstr "Begriff" + +#: modules/taxonomy.views.inc:71 +msgid "Taxonomy terms are attached to nodes." +msgstr "" + +#: modules/taxonomy.views.inc:96;196 +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:35 +msgid "Term ID" +msgstr "Begriff-ID" + +#: modules/taxonomy.views.inc:97;197 +msgid "The taxonomy term ID" +msgstr "Die Taxonomiebegriff-ID" + +#: modules/taxonomy.views.inc:117 +msgid "Taxonomy terms. Note that using this can cause duplicate nodes to appear in views; you must add filters to reduce the result set." +msgstr "" + +#: modules/taxonomy.views.inc:127 +msgid "Taxonomy term name." +msgstr "Name des Taxonomie-Begriffes." + +#: modules/taxonomy.views.inc:136 +msgid "The term weight field" +msgstr "Das Feld für die Begriffsreihenfolge" + +#: modules/taxonomy.views.inc:148 +msgid "Term description" +msgstr "Begriffsbeschreibung" + +#: modules/taxonomy.views.inc:149 +msgid "The description associated with a taxonomy term." +msgstr "Die einem Taxonomiebegriff zugeordnete Beschreibung." + +#: modules/taxonomy.views.inc:160 +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:37 +msgid "Vocabulary" +msgstr "Vokabular" + +#: modules/taxonomy.views.inc:161 +msgid "Filter the results of \"Taxonomy: Term\" to a particular vocabulary." +msgstr "" + +#: modules/taxonomy.views.inc:199 +msgid "All terms" +msgstr "Alle Begriffe" + +#: modules/taxonomy.views.inc:200 +msgid "Display all taxonomy terms associated with a node from specified vocabularies." +msgstr "Alle einem Beitrag zugeordneten Taxonomiebegriffe eines angegebenes Vokabulars anzeigen." + +#: modules/taxonomy.views.inc:254 +msgid "Parent term" +msgstr "Übergeordneter Begriff" + +#: modules/taxonomy.views.inc:255 +msgid "The parent term of the term. This can produce duplicate entries if you are using a vocabulary that allows multiple parents." +msgstr "" + +#: modules/taxonomy.views.inc:287 +msgid "Term synonym" +msgstr "Begriffssynonym" + +#: modules/taxonomy.views.inc:288 +msgid "Term synonyms may be used to find terms by alternate names." +msgstr "" + +#: modules/taxonomy.views.inc:304 +msgid "Term ID (with depth)" +msgstr "Begriffs-ID (mit Verschachtelungstiefe)" + +#: modules/taxonomy.views.inc:305 +msgid "The depth filter is more complex, so provides fewer options." +msgstr "Der Verschachtelungstiefenfilter ist wesentlich komplexer und stellt deshalb weniger Optionen zu Verfügung." + +#: modules/taxonomy.views.inc:315 +msgid "Term ID depth modifier" +msgstr "" + +#: modules/taxonomy.views.inc:316 +msgid "Allows the \"depth\" for Taxonomy: Term ID (with depth) to be modified via an additional argument." +msgstr "Ermöglicht über ein zusätzliches Argument die Anpassung der „Verschachtelungstiefe“ einer Taxonomie-Begriffs-ID (mit Verschachtelungstiefe)." + +#: modules/taxonomy.views.inc:372 +msgid "Taxonomy term" +msgstr "Taxonomie-Begriff" + +#: modules/translation.views.inc:31;48;80;97 +msgid "Node translation" +msgstr "Beitragsübersetzung" + +#: modules/translation.views.inc:32 +#: modules/node/views_handler_filter_node_language.inc:9 +#: modules/translation/views_handler_filter_node_language.inc:9 +msgid "Language" +msgstr "Sprache" + +#: modules/translation.views.inc:33 +msgid "The language the content is in." +msgstr "Die Sprache des Inhalts." + +#: modules/translation.views.inc:49 +msgid "Translation set node ID" +msgstr "Beitrags-ID des Übersetzungssatzes" + +#: modules/translation.views.inc:50 +msgid "The ID of the translation set the content belongs to." +msgstr "Die ID des Übersetzungssatzes, zu dem der Inhalt gehört." + +#: modules/translation.views.inc:69;74 +msgid "Source translation" +msgstr "Quellübersetzung" + +#: modules/translation.views.inc:70 +msgid "The source that this content was translated from." +msgstr "Die Quelle aus der dieser Inhalt übersetzt wird." + +#: modules/translation.views.inc:81;84;91 +msgid "Translations" +msgstr "Übersetzungen" + +#: modules/translation.views.inc:82;85 +msgid "Versions of content in different languages." +msgstr "Versionen von Inhalt in unterschiedlichen Sprachen." + +#: modules/translation.views.inc:98 +msgid "Translation status" +msgstr "Übersetzungsstatus" + +#: modules/translation.views.inc:99 +msgid "The translation status of the node--whether or not the translation needs to be updated." +msgstr "Der Übersetzungsstatus des Beitrags - ob die Übersetzung aktualisiert werden muss oder nicht." + +#: modules/upload.views.inc:25;112 +msgid "Upload" +msgstr "Upload" + +#: modules/upload.views.inc:44 +msgid "The node the uploaded file is attached to" +msgstr "Der Beitrag an dem die hochgeladene Datei angehängt ist." + +#: modules/upload.views.inc:46 +msgid "upload" +msgstr "Upload" + +#: modules/upload.views.inc:57 +msgid "The description of the uploaded file." +msgstr "Die Beschreibung der hochgeladen Datei." + +#: modules/upload.views.inc:74 +msgid "Listed" +msgstr "Aufgelistet" + +#: modules/upload.views.inc:75 +msgid "Whether or not the file is marked to be listed." +msgstr "Ob die Datei zur Auflistung markiert ist oder nicht." + +#: modules/upload.views.inc:91 +msgid "The weight, used for sorting." +msgstr "Die für die Sortierung verwendete Reihenfolge." + +#: modules/upload.views.inc:113;125 +msgid "Attached files" +msgstr "Angehängte Dateien" + +#: modules/upload.views.inc:114 +msgid "All files attached to a node with upload.module." +msgstr "Alle mit dem Upload-Modul an einen Beitrag angehängten Dateien." + +#: modules/upload.views.inc:121 +#: modules/upload/views_handler_filter_upload_fid.inc:10 +msgid "Has attached files" +msgstr "Angehängte Dateien vorhanden" + +#: modules/upload.views.inc:122 +msgid "Only display items with attached files. This can cause duplicates if there are multiple attached files." +msgstr "Nur Einträge mit angehängten Dateien anzeigen. Sollten mehrere angehängte Dateien vorhanden sein, kann dies zu Duplikaten führen." + +#: modules/upload.views.inc:126 +msgid "Add a relationship to gain access to more file data for files uploaded by upload.module. Note that this relationship will cause duplicate nodes if there are multiple files attached to the node." +msgstr "" + +#: modules/upload.views.inc:132 +msgid "Files" +msgstr "Dateien" + +#: modules/user.views.inc:28 +msgid "Users who have created accounts on your site." +msgstr "Benutzer, die Konten auf der Website erstellt haben." + +#: modules/user.views.inc:48 +msgid "Uid" +msgstr "Uid" + +#: modules/user.views.inc:49 +msgid "The user ID" +msgstr "Benutzer-ID" + +#: modules/user.views.inc:70 +msgid "Current" +msgstr "Aktuell" + +#: modules/user.views.inc:71 +msgid "Filter the view to the currently logged in user." +msgstr "Die Ansicht des aktuell angemeldeten Benuters filtern." + +#: modules/user.views.inc:80 +msgid "The user or author name." +msgstr "Der Benutzer oder Name des Autors." + +#: modules/user.views.inc:96 +msgid "E-mail" +msgstr "E-Mail-Adresse" + +#: modules/user.views.inc:97 +msgid "Email address for a given user. This field is not normally shown to users, so be cautious when using it." +msgstr "Die E-Mail-Adresse für einen bestimmten Benutzer. Dieses Feld wird Benutzern normalerweise nicht angezeigt und sollte nur unter Vorsicht verwendet werden." + +#: modules/user.views.inc:112 +msgid "Picture" +msgstr "Bild" + +#: modules/user.views.inc:113 +msgid "The user's picture, if allowed." +msgstr "Das Bild des Benutzers, soweit zulässig." + +#: modules/user.views.inc:124 +msgid "The date the user was created." +msgstr "Der Zeitpunkt zu dem der Benutzer erstellt wurde." + +#: modules/user.views.inc:139 +msgid "Last access" +msgstr "Letzter Zugriff" + +#: modules/user.views.inc:140 +msgid "The user's last access date." +msgstr "Letztes Zugriffsdatum des Benutzers." + +#: modules/user.views.inc:155 +msgid "Last login" +msgstr "Letzte Anmeldung" + +#: modules/user.views.inc:156 +msgid "The user's last login date." +msgstr "Letztes Anmeldedatum des Benutzers." + +#: modules/user.views.inc:172 +msgid "Whether a user is active or blocked." +msgstr "Ob ein Benutzer aktiv oder blockiert ist." + +#: modules/user.views.inc:189 +msgid "Signature" +msgstr "Signatur" + +#: modules/user.views.inc:190 +msgid "The user's signature." +msgstr "Die Signatur des Benutzers." + +#: modules/user.views.inc:203 +msgid "Provide a simple link to edit the user." +msgstr "Stellt einen einfachen Link zum Bearbeiten des Benutzers bereit." + +#: modules/user.views.inc:211 +msgid "Provide a simple link to delete the user." +msgstr "Stellt einen einfachen Link zum Löschen des Benutzers bereit." + +#: modules/user.views.inc:240 +msgid "Roles" +msgstr "Rollen" + +#: modules/user.views.inc:241 +msgid "Roles that a user belongs to." +msgstr "Die Rollen denen ein Benutzer angehört." + +#: modules/user.views.inc:253 +msgid "No role" +msgstr "Keine Rolle" + +#: modules/user.views.inc:296 +msgid "User ID from URL" +msgstr "Benutzer-ID aus der URL" + +#: modules/user.views.inc:302 +msgid "User ID from logged in user" +msgstr "Benutzer-ID des angemeldeten Benutzers" + +#: modules/views.views.inc:18 +msgid "Global" +msgstr "Global" + +#: modules/views.views.inc:23 +msgid "Random" +msgstr "Zufall" + +#: modules/views.views.inc:24 +msgid "Randomize the display order." +msgstr "Die Anzeigereihenfolge zufällig anordnen." + +#: modules/views.views.inc:31 +msgid "Null" +msgstr "Null" + +#: modules/views.views.inc:32 +msgid "Allow an argument to be ignored. The query will not be altered by this argument." +msgstr "Ermöglicht es, dass ein Argument ignoriert wird. Die Abfrage wird durch dieses Argument nicht verändert." + +#: modules/comment/views_handler_argument_comment_user_uid.inc:11 +#: modules/user/views_handler_argument_user_uid.inc:17 +msgid "Anonymous" +msgstr "Gast" + +#: modules/comment/views_handler_argument_comment_user_uid.inc:17 +msgid "No user" +msgstr "Keine Benutzer" + +#: modules/comment/views_handler_field_comment.inc:30 +msgid "Link this field to its comment" +msgstr "Dieses Feld auf seinen Kommentar verlinken" + +#: modules/comment/views_handler_field_comment_link.inc:23 +#: modules/node/views_handler_field_node_link.inc:24 +#: modules/user/views_handler_field_user_link.inc:22 +msgid "Text to display" +msgstr "Anzuzeigender Text" + +#: modules/comment/views_handler_field_comment_link.inc:34 +#: modules/node/views_handler_field_node_link.inc:35 +#: modules/user/views_handler_field_user_link.inc:38 +msgid "view" +msgstr "Anzeigen" + +#: modules/comment/views_handler_field_comment_link_delete.inc:12 +#: modules/node/views_handler_field_node_link_delete.inc:26 +#: modules/node/views_handler_field_node_revision_link_delete.inc:35 +#: modules/user/views_handler_field_user_link_delete.inc:13 +msgid "delete" +msgstr "Löschen" + +#: modules/comment/views_handler_field_comment_link_edit.inc:21 +#: modules/node/views_handler_field_node_link_edit.inc:26 +#: modules/user/views_handler_field_user_link_edit.inc:13 +msgid "edit" +msgstr "Bearbeiten" + +#: modules/comment/views_handler_field_comment_link_reply.inc:13 +msgid "reply" +msgstr "Antwort" + +#: modules/comment/views_handler_field_comment_username.inc:25 +msgid "Link this field to its user or an author's homepage" +msgstr "Mit diesem Feld auf den Benutzer oder die Startseite des Autors verlinken" + +#: modules/comment/views_handler_field_node_comment.inc:12 +#: modules/comment/views_handler_filter_node_comment.inc:10 +msgid "Disabled" +msgstr "Deaktiviert" + +#: modules/comment/views_handler_field_node_comment.inc:14 +#: modules/comment/views_handler_filter_node_comment.inc:11 +msgid "Read only" +msgstr "Nur Leseberechtigung" + +# Translation is context sensitive for comments and may cause incompatibilities. +#: modules/comment/views_handler_field_node_comment.inc:16 +#: modules/comment/views_handler_filter_node_comment.inc:12 +msgid "Read/Write" +msgstr "Kommentare lesen und schreiben" + +#: modules/comment/views_handler_field_node_new_comments.inc:25 +msgid "Link this field to new comments" +msgstr "Dieses Feld mit neuen Kommentaren verknüpfen" + +#: modules/comment/views_handler_field_node_new_comments.inc:30 +msgid "Display nothing if no new comments" +msgstr "Nichts anzeigen, wenn keine neuen Kommentare vorhanden sind" + +#: modules/comment/views_plugin_row_comment_view.inc:21 +#: modules/node/views_plugin_row_node_view.inc:32 +msgid "Display links" +msgstr "Links anzeigen" + +#: modules/node/views_handler_argument_dates_various.inc:167 +#, fuzzy +msgid "Week @week" +msgstr "@week Woche" + +#: modules/node/views_handler_argument_node_language.inc:29 +#: modules/translation/views_handler_argument_node_language.inc:29 +msgid "Unknown language" +msgstr "Unbekannte Sprache" + +#: modules/node/views_handler_argument_node_type.inc:30 +msgid "Unknown node type" +msgstr "Unbekannter Beitragstyp" + +#: modules/node/views_handler_field_history_user_timestamp.inc:32 +msgid "Check for new comments as well" +msgstr "Auch auf neue Kommentare überprüfen." + +#: modules/node/views_handler_field_node.inc:32 +msgid "Link this field to its node" +msgstr "Dieses Feld auf seinen Beitrag verlinken" + +#: modules/node/views_handler_field_node_revision_link_revert.inc:36 +msgid "revert" +msgstr "zurücksetzen" + +#: modules/node/views_handler_filter_node_language.inc:10 +#: modules/translation/views_handler_filter_node_language.inc:10 +msgid "Current user's language" +msgstr "Aktuelle Sprache des Benutzers" + +#: modules/node/views_handler_filter_node_language.inc:10 +#: modules/translation/views_handler_filter_node_language.inc:10 +msgid "No language" +msgstr "Keine Sprache" + +#: modules/node/views_handler_filter_node_type.inc:9 +msgid "Node type" +msgstr "Beitragstyp" + +#: modules/node/views_plugin_argument_validate_node.inc:29 +msgid "Types" +msgstr "Typen" + +#: modules/node/views_plugin_argument_validate_node.inc:32 +msgid "If you wish to validate for specific node types, check them; if none are checked, all nodes will pass." +msgstr "" + +#: modules/node/views_plugin_argument_validate_node.inc:39 +msgid "Validate user has access to the node" +msgstr "Überprüfen, ob der Benutzer Zugriff auf den Beitrag hat" + +#: modules/node/views_plugin_argument_validate_node.inc:47 +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:33 +msgid "Argument type" +msgstr "Argumenttyp" + +#: modules/node/views_plugin_argument_validate_node.inc:49 +msgid "Node ID" +msgstr "Beitrags-ID" + +#: modules/node/views_plugin_argument_validate_node.inc:50 +msgid "Node IDs separated by , or +" +msgstr "Beitrag-IDs getrennt nach , oder +" + +#: modules/node/views_plugin_row_node_rss.inc:26 +msgid "Full text" +msgstr "Vollständiger Text" + +#: modules/node/views_plugin_row_node_rss.inc:27 +msgid "Title plus teaser" +msgstr "Titel mit Anrißtext" + +#: modules/node/views_plugin_row_node_rss.inc:28 +msgid "Title only" +msgstr "Nur Titel" + +#: modules/node/views_plugin_row_node_rss.inc:29 +msgid "Use default RSS settings" +msgstr "Die Standard-RSS-Einstellungen verwenden" + +#: modules/node/views_plugin_row_node_rss.inc:95 +msgid "read more" +msgstr "Weiterlesen" + +#: modules/node/views_plugin_row_node_view.inc:27 +msgid "Display only teaser" +msgstr "Nur den Anrißtext anzeigen" + +#: modules/node/views_plugin_row_node_view.inc:37 +msgid "Display node comments" +msgstr "Beitragskommentare anzeigen" + +#: modules/search/views_handler_filter_search.inc:23 +msgid "On empty input" +msgstr "Bei leerer Eingabe" + +#: modules/search/views_handler_filter_search.inc:26 +msgid "Show All" +msgstr "Alle anzeigen" + +#: modules/search/views_handler_filter_search.inc:27 +msgid "Show None" +msgstr "Keine anzeigen" + +#: modules/search/views_handler_filter_search.inc:42 +msgid "Enter the terms you wish to search for." +msgstr "Die Begriffe eingeben nach denen gesucht werden soll." + +#: modules/search/views_handler_filter_search.inc:62 +msgid "You must include at least one positive keyword with @count characters or more." +msgstr "Es muss mindestens ein gültiges Stichwort in der Suchanfrage verwendet werden, das mindestens @count oder mehr Zeichen enthält." + +#: modules/search/views_handler_filter_search.inc:66 +msgid "Search for either of the two terms with uppercase <strong>OR</strong>. For example, <strong>cats OR dogs</strong>." +msgstr "Mit großgeschriebenem <strong>OR</strong> nach einem von beiden Begriffen suchen. Beispielsweise <strong>Katzen OR Hunde</strong>." + +#: modules/search/views_plugin_row_search_view.inc:23 +msgid "Display score" +msgstr "Anzeigepunktzahl" + +#: modules/system/views_handler_argument_file_fid.inc:13 +msgid "No title" +msgstr "Kein Titel" + +#: modules/system/views_handler_field_file.inc:29 +#: modules/upload/views_handler_field_upload_description.inc:24 +#: modules/upload/views_handler_field_upload_fid.inc:21 +msgid "Link this field to download the file" +msgstr "" + +#: modules/taxonomy/views_handler_argument_taxonomy.inc:18 +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:125 +msgid "No name" +msgstr "Kein Name" + +# festlegen? +#: modules/taxonomy/views_handler_argument_term_node_tid.inc:17 +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:38 +msgid "Set the breadcrumb for the term parents" +msgstr "Die Pfadnavigation für die übergeordneten Begriffe festlegen" + +#: modules/taxonomy/views_handler_argument_term_node_tid.inc:18 +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:39 +msgid "If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received." +msgstr "" + +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:26 +msgid "The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term \"fruit\" and a child term \"apple\", with a depth of 1 (or higher) then filtering for the term \"fruit\" will get nodes that are tagged with \"apple\" as well as \"fruit\". If negative, the reverse is true; searching for \"apple\" will also pick up nodes tagged with \"fruit\" if depth is -1 (or lower)." +msgstr "" + +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:31 +msgid "Allow multiple terms per argument" +msgstr "Ermöglicht mehrere Begriffe pro Argument." + +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:32 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3. Due to the number of JOINs it would require, AND will be treated as OR with this argument." +msgstr "Sobald aktiviert, können Benutzer mehrere Argumente in der Form von 1+2+3 eingeben. Aufgrund der Anzahl der erforderlichen JOINs wird AND mit diesem Argument als OR betrachtet." + +#: modules/taxonomy/views_handler_argument_vocabulary_vid.inc:15 +msgid "No vocabulary" +msgstr "Kein Vokabular" + +# TODO: See: Link this field to its term page +#: modules/taxonomy/views_handler_field_taxonomy.inc:33 +msgid "Link this field to its taxonomy term page" +msgstr "Dieses Feld mit seiner Taxonomie-Begriffseite verlinken" + +# TODO: See: Link this field to its taxonomy term page +#: modules/taxonomy/views_handler_field_term_node_tid.inc:34 +msgid "Link this field to its term page" +msgstr "Dieses Feld mit seiner Begriffseite verlinken" + +#: modules/taxonomy/views_handler_field_term_node_tid.inc:41 +msgid "Limit terms by vocabulary" +msgstr "Begriffe nach Vokabular begrenzen" + +#: modules/taxonomy/views_handler_field_term_node_tid.inc:55 +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:23 +msgid "Vocabularies" +msgstr "Vokabulare" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:39 +msgid "Select which vocabulary to show terms for in the regular options." +msgstr "" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:49 +msgid "Selection type" +msgstr "Auswahltyp" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:50 +msgid "Dropdown" +msgstr "Auswahlliste" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:50 +msgid "Autocomplete" +msgstr "Autovervollständigung" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:56 +msgid "Show hierarchy in dropdown" +msgstr "Hierarchie in Auswahlliste anzeigen" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:73 +msgid "An invalid vocabulary is selected. Please change it in the options." +msgstr "Ein ungültiges Vokabular wurde ausgewählt. Bitte in den Optionen ändern." + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:91;147 +msgid "Select terms from vocabulary @voc" +msgstr "Begriffe aus dem Vokabular @voc wählen." + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:255 +msgid "Unable to find term: @terms" +msgid_plural "Unable to find terms: @terms" +msgstr[0] "Begriff konnte nicht gefunden werden: @terms" +msgstr[1] "Begriffe konnten nicht gefunden werden: @terms" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:26 +msgid "If you wish to validate for specific vocabularies, check them; if none are checked, all terms will pass." +msgstr "" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:36 +msgid "Term IDs separated by , or +" +msgstr "Begriff-IDs getrennt nach , oder +" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:37 +msgid "Term name or synonym" +msgstr "Begriffsname oder Synonym" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:38 +msgid "Term name/synonym converted to Term ID" +msgstr "Begriffname/Synonym wurde zur Begriff-ID konvertiert." + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:41 +msgid "Select the form of this argument; if using term name, it is generally more efficient to convert it to a term ID and use Taxonomy: Term ID rather than Taxonomy: Term Name\" as an argument." +msgstr "" + +#: modules/translation/views_handler_filter_node_language.inc:10 +msgid "Default site language" +msgstr "Standardmäßige Websitesprache" + +#: modules/translation/views_handler_relationship_translation.inc:24 +msgid "Current language" +msgstr "Aktuelle Sprache" + +#: modules/translation/views_handler_relationship_translation.inc:25 +msgid "Default language" +msgstr "Standardsprache" + +#: modules/translation/views_handler_relationship_translation.inc:32 +msgid "Translation option" +msgstr "Übersetzungsoption" + +#: modules/translation/views_handler_relationship_translation.inc:33 +msgid "The translation options allows you to select which translation or translations in a translation set join on. Select \"Current language\" or \"Default language\" to join on the translation in the current or default language respectively. Select a specific language to join on a translation in that language. If you select \"All\", each translation will create a new row, which may appear to cause duplicates." +msgstr "" + +#: modules/upload/views_handler_field_upload_fid.inc:27 +msgid "Only show \"listed\" file attachments" +msgstr "Nur „aufgelistete“ Dateianhänge anzeigen" + +#: modules/user/views_handler_field_user.inc:30 +msgid "Link this field to its user" +msgstr "Dieses Feld mit seinem Benutzer verlinken" + +#: modules/user/views_handler_field_user_mail.inc:16 +msgid "Link this field" +msgstr "Dieses Feld verlinken" + +#: modules/user/views_handler_field_user_mail.inc:19 +msgid "No link" +msgstr "Keine Verlinkung" + +#: modules/user/views_handler_field_user_mail.inc:20 +msgid "To the user" +msgstr "Zu dem Benutzer" + +#: modules/user/views_handler_field_user_mail.inc:21 +msgid "With a mailto:" +msgstr "Mit einem mailto:" + +# TODO: English is not context sensitive +#: modules/user/views_handler_filter_user_current.inc:10 +msgid "Is the logged in user" +msgstr "Ist der angemeldete Benutzer" + +#: modules/user/views_handler_filter_user_name.inc:28 +msgid "Usernames" +msgstr "Benutzernamen" + +#: modules/user/views_handler_filter_user_name.inc:29 +msgid "Enter a comma separated list of user names." +msgstr "Eine kommagetrennte Liste von Benutzernamen." + +#: modules/user/views_handler_filter_user_name.inc:112 +msgid "Unable to find user: @users" +msgid_plural "Unable to find users: @users" +msgstr[0] "Benutzer konnte nicht gefunden werden: @users" +msgstr[1] "Benutzer konnten nicht gefunden werden: @users" + +#: modules/user/views_plugin_argument_default_user.inc:17 +msgid "Also look for a node and use the node author" +msgstr "" + +#: plugins/views_plugin_access_none.inc:9 +msgid "Unrestricted" +msgstr "Unbeschränkt" + +#: plugins/views_plugin_access_perm.inc:37 +msgid "Only users with the selected permission flag will be able to access this display. Note that users with \"access all views\" can see any view, regardless of other permissions." +msgstr "" + +#: plugins/views_plugin_access_role.inc:21 +msgid "No role(s) selected" +msgstr "Keine Rolle(n) ausgewählt" + +#: plugins/views_plugin_access_role.inc:24 +msgid "Multiple roles" +msgstr "Mehrere Rollen" + +#: plugins/views_plugin_access_role.inc:43 +msgid "Only the checked roles will be able to access this display. Note that users with \"access all views\" can see any view, regardless of role." +msgstr "Nur die aktivierten Rollen werden auf diese Anzeige zugreifen können. Beachten, dass Benutzer mit dem „Zugriff auf alle Ansichten“ alle Ansichten unabhängig von ihrer Rolle sehen können." + +#: plugins/views_plugin_access_role.inc:49 +msgid "You must select at least one role if type is \"by role\"" +msgstr "Beim Typ „nach Rolle“ muss mindestens eine Rolle ausgewählt sein." + +#: plugins/views_plugin_argument_default.inc:32 +msgid "Default argument" +msgstr "Standard-Argument" + +#: plugins/views_plugin_argument_default.inc:54 +msgid "Note: you do not have permission to modify this. If you change the default argument type, this setting will be lost and you will NOT be able to get it back." +msgstr "" + +#: plugins/views_plugin_argument_default_php.inc:17 +msgid "PHP argument code" +msgstr "PHP-Argumentcode" + +#: plugins/views_plugin_argument_default_php.inc:20 +msgid "Enter PHP code that returns a value to use for this argument. Do not use <?php ?>. You must return only a single value for just this argument." +msgstr "" + +#: plugins/views_plugin_argument_validate.inc:43 +msgid "Note: you do not have permission to modify this. If you change the validator, this setting will be lost and you will NOT be able to get it back." +msgstr "" + +#: plugins/views_plugin_argument_validate_php.inc:19 +msgid "PHP validate code" +msgstr "" + +#: plugins/views_plugin_argument_validate_php.inc:21 +msgid "Enter PHP code that returns TRUE or FALSE. No return is the same as FALSE, so be SURE to return something if you do not want to declare the argument invalid. Do not use <?php ?>. The argument to validate will be \"$argument\" and the view will be \"$view\". You may change the argument by setting \"$handler->argument\"." +msgstr "" + +#: plugins/views_plugin_display.inc:558 +msgid "Broken field" +msgstr "Beschädigtes Feld" + +#: plugins/views_plugin_display.inc:575 +msgid "Basic settings" +msgstr "Basiseinstellungen" + +#: plugins/views_plugin_display.inc:582 +msgid "Change the name of this display." +msgstr "Den Namen dieser Anzeige ändern." + +#: plugins/views_plugin_display.inc:594 +msgid "Change the title that this display will use." +msgstr "Den von dieser Anzeige verwendeten Titel ändern." + +#: plugins/views_plugin_display.inc:604 +msgid "Style" +msgstr "Design" + +#: plugins/views_plugin_display.inc:606 +msgid "Change the style plugin." +msgstr "Das Design-Plugin ändern." + +#: plugins/views_plugin_display.inc:620 +msgid "Row style" +msgstr "Zeilendesign" + +#: plugins/views_plugin_display.inc:622 +msgid "Change the row plugin." +msgstr "Das Zeilen-Plugin ändern." + +#: plugins/views_plugin_display.inc:632 +msgid "Use AJAX" +msgstr "AJAX verwenden" + +#: plugins/views_plugin_display.inc:634 +msgid "Change whether or not this display will use AJAX." +msgstr "Ändern, ob diese Anzeige AJAX verwenden soll oder nicht." + +#: plugins/views_plugin_display.inc:641 +msgid "Use pager" +msgstr "Seitennavigation verwenden" + +#: plugins/views_plugin_display.inc:642 +msgid "Mini" +msgstr "Mini" + +#: plugins/views_plugin_display.inc:643 +msgid "Change this display's pager setting." +msgstr "Die Seitennavigations-Einstellung dieser Anzeige ändern." + +#: plugins/views_plugin_display.inc:650;822 +msgid "Items per page" +msgstr "Beträge pro Seite" + +#: plugins/views_plugin_display.inc:650;822 +#: plugins/views_plugin_style_summary.inc:43 +msgid "Items to display" +msgstr "Anzuzeigende Einträge" + +#: plugins/views_plugin_display.inc:651 +msgid "Unlimited" +msgstr "Unbegrenzt" + +#: plugins/views_plugin_display.inc:652 +msgid "Change how many items to display." +msgstr "Die Anzahl der anzuzeigenden Beiträge ändern." + +#: plugins/views_plugin_display.inc:658 +msgid "More link" +msgstr "‚Weiter‘-Link" + +#: plugins/views_plugin_display.inc:660 +msgid "Specify whether this display will provide a \"more\" link." +msgstr "Festlegen, ob diese Anzeige einen „Weiter“-Link bereitstellt." + +#: plugins/views_plugin_display.inc:666;849 +msgid "Distinct" +msgstr "Eindeutig" + +#: plugins/views_plugin_display.inc:668;846 +msgid "Display only distinct items, without duplicates." +msgstr "Nur unterschiedliche Einträge ohne Duplikate anzeigen." + +#: plugins/views_plugin_display.inc:681 +msgid "Access" +msgstr "Zugriff" + +#: plugins/views_plugin_display.inc:683 +msgid "Specify access control type for this display." +msgstr "Den Zugriffskontrolltyp für diese Anzeige festlegen." + +#: plugins/views_plugin_display.inc:687 +msgid "Change settings for this access type." +msgstr "Einstellungen für diesen Zugriffstyp ändern." + +#: plugins/views_plugin_display.inc:707 +msgid "Link display" +msgstr "Anzeige verlinken" + +#: plugins/views_plugin_display.inc:709 +msgid "Specify which display this display will link to." +msgstr "Angeben, zu welcher Anzeige diese Anzeige verlinken soll." + +#: plugins/views_plugin_display.inc:716 +msgid "Exposed form in block" +msgstr "Hervorgehobenes Formular in Block" + +#: plugins/views_plugin_display.inc:718 +msgid "Allow the exposed form to appear in a block instead of the view." +msgstr "Ermöglicht das Erscheinen des hervorgehobenen Formulars in einem Block anstatt der Ansicht." + +#: plugins/views_plugin_display.inc:721;897 +msgid "Header" +msgstr "Kopfbereich" + +#: plugins/views_plugin_display.inc:721;913 +msgid "Footer" +msgstr "Fußbereich" + +#: plugins/views_plugin_display.inc:721;929 +msgid "Empty text" +msgstr "Leerer Text" + +#: plugins/views_plugin_display.inc:737 +msgid "Unknown/missing format" +msgstr "Unbekannt/fehlendes Format" + +# May not context sensitive +#: plugins/views_plugin_display.inc:745 +#, fuzzy +msgid "Change this display's !name." +msgstr "Den !name dieser Anzeige ändern." + +#: plugins/views_plugin_display.inc:751 +msgid "Theme" +msgstr "Theme" + +#: plugins/views_plugin_display.inc:752 +msgid "Information" +msgstr "Information" + +# not literally +#: plugins/views_plugin_display.inc:753 +msgid "Get information on how to theme this display" +msgstr "Information abrufen, wie diese Anzeige dargestellt werden soll." + +#: plugins/views_plugin_display.inc:779 +msgid "The name of this display" +msgstr "Der Name dieser Anzeige" + +#: plugins/views_plugin_display.inc:782 +msgid "This title will appear only in the administrative interface for the View." +msgstr "Dieser Titel wird nur in die Verwaltungsoberfläche für die Ansicht angezeigt." + +#: plugins/views_plugin_display.inc:787 +msgid "The title of this view" +msgstr "Der Titel dieser Ansicht." + +#: plugins/views_plugin_display.inc:790 +msgid "This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc." +msgstr "Dieser Titel wird mit der Ansicht angezeigt, wo in der Regel die Titel angezeigt werden. Beispielsweise als Seitentitel, Blocktitel, etc." + +# not literally +#: plugins/views_plugin_display.inc:795 +msgid "Use AJAX when available to load this view" +msgstr "Soweit möglich, soll diese Ansicht mit AJAX geladen werden." + +#: plugins/views_plugin_display.inc:799 +msgid "If set, this view will use an AJAX mechanism for paging, table sorting and exposed filters. This means the entire page will not refresh. It is not recommended that you use this if this view is the main content of the page as it will prevent deep linking to specific pages, but it is very useful for side content." +msgstr "" + +#: plugins/views_plugin_display.inc:808 +msgid "Use a pager for this view" +msgstr "Eine Seitennavigation für diese Ansicht verwenden" + +#: plugins/views_plugin_display.inc:811 +msgid "Full pager" +msgstr "Vollständige Seitennavigation" + +#: plugins/views_plugin_display.inc:811 +msgid "Mini pager" +msgstr "Kleine Seitennavigation" + +#: plugins/views_plugin_display.inc:816 +msgid "Pager element" +msgstr "Seitennavigationselement" + +#: plugins/views_plugin_display.inc:817 +msgid "Unless you're experiencing problems with pagers related to this view, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible." +msgstr "" + +#: plugins/views_plugin_display.inc:826 +msgid "The number of items to display per page. Enter 0 for no limit." +msgstr "Die Anzahl der anzuzeigenden Einträge pro Seite. 0 für keine Begrenzung." + +#: plugins/views_plugin_display.inc:831 +msgid "Offset" +msgstr "Offset" + +#: plugins/views_plugin_display.inc:832 +msgid "The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed. Offset can not be used if items to display is 0; instead use a very large number there." +msgstr "Die Anzahl der zu überspringenden Einträge. Sollte das Feld beispielsweise den Wert 3 enthalten, werden die ersten 3 Einträge übersprungen und nicht angezeigt. Der Offset kann nicht verwendet, wenn die anzuzeigenden Einträge 0 betragen. Stattdessen muss eine sehr großen Zahl verwendet werden." + +#: plugins/views_plugin_display.inc:837 +msgid "Add a more link to the bottom of the display." +msgstr "Am unteren Rand der Anzeige einen ‚mehr‘-Link einfügen." + +# TODO: Add more link +#: plugins/views_plugin_display.inc:840 +msgid "Create more link" +msgstr "‚Weiter‘-Link erstellen" + +#: plugins/views_plugin_display.inc:841 +msgid "This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' above." +msgstr "Dies wird am unteren Rand dieser Ansicht einen ‚mehr‘-Link einfügen, der auf die Seitenansicht verlinkt. Sollte mehr wie eine Seitenansicht vorhanden sein, wird der Link auf die unter ‚Link-Anzeige‘ angegebene Anzeige zeigen." + +#: plugins/views_plugin_display.inc:850 +msgid "This will make the view display only distinct items. If there are multiple identical items, each will be displayed only once. You can use this to try and remove duplicates from a view, though it does not always work. Note that this can slow queries down, so use it with caution." +msgstr "" + +#: plugins/views_plugin_display.inc:855 +msgid "Access restrictions" +msgstr "Zugriffsberechtigungen" + +# TODO: not context sensitive +#: plugins/views_plugin_display.inc:874;954 +msgid "You may also adjust the !settings for the currently selected style by clicking on the icon." +msgstr "" + +#: plugins/views_plugin_display.inc:874;954;999 +msgid "settings" +msgstr "Einstellungen" + +#: plugins/views_plugin_display.inc:882 +msgid "Access options" +msgstr "Zugriffsoptionen" + +#: plugins/views_plugin_display.inc:900;916 +msgid "Display even if view has no result" +msgstr "Auch anzeigen, wenn die Ansicht keine Ergebnisse zurückliefert" + +#: plugins/views_plugin_display.inc:907 +msgid "Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional." +msgstr "Am Anfang der Ansicht anzuzeigender Text. Dieser kann eine Erklärung, Links oder beliebige andere Inhalte enthalten. (Optional)" + +#: plugins/views_plugin_display.inc:923 +msgid "Text to display beneath the view. May contain an explanation or links or whatever you like. Optional." +msgstr "Unterhalb der Ansicht anzuzeigender Text. Dieser kann eine Erklärung, Links oder beliebige andere Inhalte enthalten. (Optional)" + +#: plugins/views_plugin_display.inc:934 +msgid "Text to display if the view has no results. Optional." +msgstr "Der anzuzeigende Text, wenn die Ansicht keine Ergebnisse zurückliefert. (Optional)" + +#: plugins/views_plugin_display.inc:940 +msgid "How should this view be styled" +msgstr "Wie soll diese Ansicht designed werden" + +#: plugins/views_plugin_display.inc:946 +msgid "If the style you choose has settings, be sure to click the settings button that will appear next to it in the View summary." +msgstr "" + +#: plugins/views_plugin_display.inc:960 +msgid "Style options" +msgstr "Darstellungsoptionen" + +#: plugins/views_plugin_display.inc:971 +msgid "Row style options" +msgstr "Darstellungsoptionen für Zeilen" + +#: plugins/views_plugin_display.inc:986 +msgid "How should each row in this view be styled" +msgstr "Wie soll jede Zeile in dieser Ansicht designed werden" + +#: plugins/views_plugin_display.inc:999 +msgid "You may also adjust the !settings for the currently selected row style by clicking on the icon." +msgstr "" + +#: plugins/views_plugin_display.inc:1005 +msgid "Which display to use for path" +msgstr "Welche Anzeige für den Pfad verwendet werden soll" + +#: plugins/views_plugin_display.inc:1014 +msgid "Which display to use to get this display's path for things like summary links, rss feed links, more links, etc." +msgstr "" + +#: plugins/views_plugin_display.inc:1019 +msgid "Theming information" +msgstr "Theming-Information" + +#: plugins/views_plugin_display.inc:1027 +msgid "Display output" +msgstr "Anzeigeausgabe" + +#: plugins/views_plugin_display.inc:1031 +msgid "Alternative display output" +msgstr "Alternative Anzeigeausgabe" + +#: plugins/views_plugin_display.inc:1038 +msgid "Style output" +msgstr "Designausgabe" + +#: plugins/views_plugin_display.inc:1042 +msgid "Alternative style" +msgstr "Alternatives Design" + +#: plugins/views_plugin_display.inc:1049 +msgid "Row style output" +msgstr "Ausgabe des Zeilendesign" + +#: plugins/views_plugin_display.inc:1053 +msgid "Alternative row style" +msgstr "Alternatives Zeilendesign" + +#: plugins/views_plugin_display.inc:1061 +msgid "Field @field (ID: @id)" +msgstr "Feld @field (ID: @id)" + +#: plugins/views_plugin_display.inc:1069 +msgid "This section lists all possible templates for the display plugin and for the style plugins, ordered roughly from the least specific to the most specific. The active template for each plugin -- which is the most specific template found on the system -- is highlighted in bold." +msgstr "" + +#: plugins/views_plugin_display.inc:1084 +msgid "Rescan template files" +msgstr "Vorlagendateien erneut einlesen" + +#: plugins/views_plugin_display.inc:1090 +#, fuzzy +msgid "<strong>Important!</strong> When adding, removing, or renaming template files, it is necessary to make Drupal aware of the changes by making it rescan the files on your system. By clicking this button you clear Drupal's theme registry and thereby trigger this rescanning process. The highlighted templates above will then reflect the new state of your system." +msgstr "<strong>Wichtig!</strong> Beim Hinzufügen, Entfernen oder Umbennennen von Template-Dateien ist es erforderlich Drupal über die Änderung durch neu Einlesen der Dateien auf dem System in Kenntnis zu setzen. Durch Anklicken dieses Schaltknopfs wird die Drupal-Theme-Registierung gelöscht und damit dieser Neueinleseprozess angestoßen. Die oberhalb hervorgehobenen Templates werden dann den neuen Stand des Systems wiedergeben." + +#: plugins/views_plugin_display.inc:1096 +msgid "Theming information (display)" +msgstr "Theming-Information (Anzeige)" + +#: plugins/views_plugin_display.inc:1097;1124;1153;1182 +msgid "Back to !info." +msgstr "Zurück zu !info." + +#: plugins/views_plugin_display.inc:1097;1124;1153;1182 +msgid "theming information" +msgstr "Theming-Information" + +# theming ? +#: plugins/views_plugin_display.inc:1100 +msgid "This display has no theming information" +msgstr "Für diese Anzeige gibt es keine Theming-Information" + +#: plugins/views_plugin_display.inc:1103 +msgid "This is the default theme template used for this display." +msgstr "Dies ist das standardmäßig verwendete Theme-Template für diese Anzeige." + +#: plugins/views_plugin_display.inc:1109 +msgid "This is an alternative template for this display." +msgstr "Dies ist eine alternative Vorlage für diese Anzeige." + +#: plugins/views_plugin_display.inc:1123 +msgid "Theming information (style)" +msgstr "Theming-Information (Design)" + +#: plugins/views_plugin_display.inc:1129 +msgid "This display has no style theming information" +msgstr "Diese Anzeige enthält keine Theming-Information für das Design" + +#: plugins/views_plugin_display.inc:1132 +msgid "This is the default theme template used for this style." +msgstr "Dies ist das standardmäßig verwendete Theme-Template für dieses Design." + +#: plugins/views_plugin_display.inc:1138 +msgid "This is an alternative template for this style." +msgstr "Dies ist ein alternatives Template für dieses Design." + +#: plugins/views_plugin_display.inc:1152;1181 +msgid "Theming information (row style)" +msgstr "Theming-Information (Zeilendesign)" + +#: plugins/views_plugin_display.inc:1158 +msgid "This display has no row style theming information" +msgstr "Diese Anzeige enthält keine Theming-Information für das Zeilendesign" + +#: plugins/views_plugin_display.inc:1161;1184 +msgid "This is the default theme template used for this row style." +msgstr "Dies ist das standardmäßig verwendete Theme-Template für dieses Zeilendesign." + +#: plugins/views_plugin_display.inc:1167 +msgid "This is an alternative template for this row style." +msgstr "Dies ist ein alternatives Template für dieses Zeilendesign." + +#: plugins/views_plugin_display.inc:1199 +msgid "Put the exposed form in a block" +msgstr "Das hervorgehobene Formular in einen Block legen" + +# not literally +#: plugins/views_plugin_display.inc:1203 +msgid "If set, any exposed widgets will not appear with this view. Instead, a block will be made available to the Drupal block administration system, and the exposed form will appear there. Note that this block must be enabled manually, Views will not enable it for you." +msgstr "Sobald aktiviert, wird jedes hervorgehobenes Steuerelement nicht mit der Ansicht erscheinen. Stattdessen wird dem Drupal-Blockverwaltungssystem ein Block zu Verfügung gestellt, der das hervorgehobene Formular enthält. Hierbei ist zu beachten, dass dieser Block manuell aktiviert werden muss und nicht durch das Ansichten-Modul aktiviert wird." + +#: plugins/views_plugin_display.inc:1238 +msgid "File found in folder @template-path" +msgstr "Datei wurde im Verzeichnis @template-path gefunden" + +#: plugins/views_plugin_display.inc:1242 +msgid "(File not found, in folder @template-path)" +msgstr "(Datei wurde im Verzeichnis @template-path nicht gefunden)" + +#: plugins/views_plugin_display.inc:1399 +msgid "Override" +msgstr "Übersteuern" + +#: plugins/views_plugin_display.inc:1404 +msgid "Status: using default values." +msgstr "Status: Standardwerte werden verwendet." + +#: plugins/views_plugin_display.inc:1408 +msgid "Update default display" +msgstr "Standardanzeige aktualisieren" + +#: plugins/views_plugin_display.inc:1413 +msgid "Use default" +msgstr "Standard verwenden" + +#: plugins/views_plugin_display.inc:1418 +msgid "Status: using overridden values." +msgstr "Status: Übersteuerte Werte werden verwendet." + +#: plugins/views_plugin_display.inc:1633 +msgid "Display \"@display\" uses fields but there are none defined for it or all are excluded." +msgstr "Die Anzeige „@display“ verwendet Felder, aber es sind keine dafür angegeben oder alle ausgeschlossen." + +#: plugins/views_plugin_display.inc:1638 +msgid "Display \"@display\" uses a path but the path is undefined." +msgstr "Die Anzeige „@display“ verwendet einen Pfad, aber der Pfad ist nicht angegeben." + +#: plugins/views_plugin_display.inc:1643 +msgid "Display \"@display\" has an invalid style plugin." +msgstr "Die Anzeige „@display“ verwendet ein ungültiges Design-Plugin." + +#: plugins/views_plugin_display.inc:1659 +msgid "Exposed form: @view-@display_id" +msgstr "Hervorgehobenes Formular: @view-@display_id" + +#: plugins/views_plugin_display_attachment.inc:35 +msgid "Before" +msgstr "Vorher" + +#: plugins/views_plugin_display_attachment.inc:36 +msgid "After" +msgstr "Nachdem" + +#: plugins/views_plugin_display_attachment.inc:37 +msgid "Both" +msgstr "Beide" + +#: plugins/views_plugin_display_attachment.inc:57 +msgid "Attachment settings" +msgstr "Einstellungen für Anhänge" + +#: plugins/views_plugin_display_attachment.inc:62;109 +msgid "Inherit arguments" +msgstr "Vererbte Argumente" + +# übernehmen/vererben? +#: plugins/views_plugin_display_attachment.inc:68;118 +msgid "Inherit exposed filters" +msgstr "Hervorgehobene Filter übernehmen" + +#: plugins/views_plugin_display_attachment.inc:74;127 +msgid "Position" +msgstr "Position" + +#: plugins/views_plugin_display_attachment.inc:80 +#: plugins/views_plugin_display_feed.inc:98 +msgid "Multiple displays" +msgstr "Mehrere Anzeigen" + +#: plugins/views_plugin_display_attachment.inc:95;136 +#: plugins/views_plugin_display_feed.inc:113;140 +msgid "Attach to" +msgstr "Anhängen an" + +#: plugins/views_plugin_display_attachment.inc:112;121 +msgid "Inherit" +msgstr "Vererben" + +#: plugins/views_plugin_display_attachment.inc:113 +msgid "Should this display inherit its arguments from the parent display to which it is attached?" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:122 +msgid "Should this display inherit its exposed filter values from the parent display to which it is attached?" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:130 +msgid "Attach before or after the parent display?" +msgstr "Bevor oder nach der übergeordneten Anzeige anhängen?" + +#: plugins/views_plugin_display_attachment.inc:145 +msgid "Select which display or displays this should attach to." +msgstr "" + +#: plugins/views_plugin_display_block.inc:68 +msgid "Block settings" +msgstr "Blockeinstellungen" + +#: plugins/views_plugin_display_block.inc:82 +msgid "Admin" +msgstr "Admin" + +#: plugins/views_plugin_display_block.inc:106 +msgid "Do not cache" +msgstr "Nicht cachen" + +#: plugins/views_plugin_display_block.inc:107 +msgid "Cache once for everything (global)" +msgstr "Einmalig für alles (global) cachen." + +#: plugins/views_plugin_display_block.inc:108 +msgid "Per page" +msgstr "Nach Seite" + +#: plugins/views_plugin_display_block.inc:109 +msgid "Per role" +msgstr "Nach Rolle" + +# ? +#: plugins/views_plugin_display_block.inc:110 +msgid "Per role per page" +msgstr "Nach Rolle und Seite" + +#: plugins/views_plugin_display_block.inc:111 +msgid "Per user" +msgstr "Nach Benutzer" + +# ? +#: plugins/views_plugin_display_block.inc:112 +msgid "Per user per page" +msgstr "Nach Benutzer und Seite" + +#: plugins/views_plugin_display_block.inc:137 +msgid "Block admin description" +msgstr "" + +#: plugins/views_plugin_display_block.inc:140 +msgid "This will appear as the name of this block in administer >> site building >> blocks." +msgstr "Dies wird als der Name dieses Blocks in Verwalten >> Strukturierung >> Blöcke erscheinen." + +#: plugins/views_plugin_display_block.inc:145 +msgid "Block caching type" +msgstr "Cachetyp für Blöcke" + +#: plugins/views_plugin_display_block.inc:149 +msgid "This sets the default status for Drupal's built-in block caching method; this requires that caching be turned on in block administration, and be careful because you have little control over when this cache is flushed." +msgstr "" + +#: plugins/views_plugin_display_feed.inc:86 +msgid "Feed settings" +msgstr "Newsfeed-Einstellungen" + +#: plugins/views_plugin_display_feed.inc:90 +msgid "Using the site name" +msgstr "Der Name der Website wird verwendet" + +#: plugins/views_plugin_display_feed.inc:132 +msgid "Use the site name for the title" +msgstr "Den Namen der Website für den Titel verwenden." + +#: plugins/views_plugin_display_feed.inc:149 +msgid "The feed icon will be available only to the selected displays." +msgstr "Das Feed-Symbol wird nur in den ausgewählten Anzeigen zur Verfügung stehen." + +#: plugins/views_plugin_display_feed.inc:155 +msgid "This view will be displayed by visiting this path on your site. It is recommended that the path be something like \"path/%/%/feed\" or \"path/%/%/rss.xml\", putting one % in the path for each argument you have defined in the view." +msgstr "Diese Ansicht wird durch den Besuch des Pfades auf der Website angezeigt. Es werden Pfade wie „pfad/%/%/feed“ oder „pfad/%/%/rss.xml“ empfohlen, bei dem für jedes in der Ansicht festgelegte Argument ein % in den Pfad eingefügt wird." + +#: plugins/views_plugin_display_page.inc:188 +msgid "Page settings" +msgstr "Seiteneinstellungen" + +#: plugins/views_plugin_display_page.inc:213 +msgid "No menu" +msgstr "Kein Menü" + +#: plugins/views_plugin_display_page.inc:216 +msgid "Normal: @title" +msgstr "Normal: @title" + +#: plugins/views_plugin_display_page.inc:220 +msgid "Tab: @title" +msgstr "Reiter: @title" + +#: plugins/views_plugin_display_page.inc:230;302 +msgid "Menu" +msgstr "Menü" + +#: plugins/views_plugin_display_page.inc:236 +msgid "Change settings for the parent menu" +msgstr "Einstellungen für das übergeordnete Menü ändern" + +#: plugins/views_plugin_display_page.inc:249 +msgid "The menu path or URL of this view" +msgstr "Der Menüpfad oder URL von dieser Ansicht" + +#: plugins/views_plugin_display_page.inc:253 +msgid "This view will be displayed by visiting this path on your site. You may use \"%\" in your URL to represent values that will be used for arguments: For example, \"node/%/feed\"." +msgstr "" + +#: plugins/views_plugin_display_page.inc:259 +msgid "Menu item entry" +msgstr "Menüpunkt" + +#: plugins/views_plugin_display_page.inc:276 +msgid "No menu entry" +msgstr "Kein Menüpunkt" + +#: plugins/views_plugin_display_page.inc:277 +msgid "Normal menu entry" +msgstr "Normaler Menüpunkt" + +#: plugins/views_plugin_display_page.inc:278;343 +msgid "Menu tab" +msgstr "Menü-Reiter" + +#: plugins/views_plugin_display_page.inc:279 +msgid "Default menu tab" +msgstr "Standardmäßiger Menü-Reiter" + +#: plugins/views_plugin_display_page.inc:288 +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "Den zu verwendenden Text für den Menüpunkt eingeben, wenn dieser auf Normal oder Reiter eingestellt wird." + +#: plugins/views_plugin_display_page.inc:295 +msgid "Warning: Changing this item's menu will not work reliably in Drupal 6.4 or earlier. Please upgrade your copy of Drupal at !url." +msgstr "" + +#: plugins/views_plugin_display_page.inc:306 +msgid "Insert item into an available menu." +msgstr "Menüeintrag in ein vorhandenes Menü eintragen." + +#: plugins/views_plugin_display_page.inc:315 +msgid "The lower the weight the higher/further left it will appear." +msgstr "Je niedriger die Reihenfolge, umso höher bzw. weiter links wird es erscheinen." + +#: plugins/views_plugin_display_page.inc:321 +msgid "Default tab options" +msgstr "Standardmäßige Reiteroptionen" + +#: plugins/views_plugin_display_page.inc:330 +msgid "When providing a menu item as a 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>." +msgstr "" + +#: plugins/views_plugin_display_page.inc:341 +msgid "Parent menu item" +msgstr "Übergeordneter Menüpunkt" + +#: plugins/views_plugin_display_page.inc:343 +msgid "Already exists" +msgstr "Schon vorhanden" + +#: plugins/views_plugin_display_page.inc:343 +msgid "Normal menu item" +msgstr "Normaler Menüpunkt" + +#: plugins/views_plugin_display_page.inc:351 +msgid "If creating a parent menu item, enter the title of the item." +msgstr "Einen Titel für den Menüpunkt eingeben, wenn ein übergeordneter Menüpunkt erstellt wird." + +#: plugins/views_plugin_display_page.inc:357 +msgid "Tab weight" +msgstr "Reiterreihenfolge" + +#: plugins/views_plugin_display_page.inc:361 +msgid "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." +msgstr "Die Reihenfolge des Reiters eingeben, wenn der übergeordnete Menüpunkt ein Reiter ist. Umso niedriger die Zahl ist, desto weiter links wird er angezeigt." + +#: plugins/views_plugin_display_page.inc:375 +msgid "\"$arg\" is no longer supported. Use % instead." +msgstr "„$arg“ wird nicht mehr unterstützt. Stattdessen kann % verwendet werden." + +#: plugins/views_plugin_display_page.inc:379 +msgid "\"%\" may not be used for the first segment of a path." +msgstr "„%“ darf nicht als erstes Segment eines Pfades verwendet werden." + +#: plugins/views_plugin_display_page.inc:389 +msgid "Views cannot create normal menu items for paths with a % in them." +msgstr "Ansichten können keine normalen Menüpunkt für Pfade mit einem % erstellen." + +#: plugins/views_plugin_display_page.inc:396 +msgid "A display whose path ends with a % cannot be a tab." +msgstr "Eine Anzeige deren Pfad mit einem % abschließt kann kein Reiter sein." + +#: plugins/views_plugin_display_page.inc:401 +msgid "Title is required for this menu type." +msgstr "Ein Titel ist für diesen Menütyp erforderlich." + +#: plugins/views_plugin_display_page.inc:432 +msgid "Display @display is set to use a menu but the menu title is not set." +msgstr "Die Anzeige @display ist konfiguriert ein Menü zu verwenden, aber der Menütitel ist nicht vorhanden." + +#: plugins/views_plugin_display_page.inc:438 +msgid "Display @display is set to use a parent menu but the parent menu title is not set." +msgstr "Die Anzeige @display ist konfiguriert ein übergeordnetes Menü zu verwenden, aber der übergeordnete Menütitel ist nicht vorhanden." + +#: plugins/views_plugin_row_fields.inc:40 +msgid "Inline fields" +msgstr "Inline-Felder" + +#: plugins/views_plugin_row_fields.inc:43 +msgid "Inline fields will be displayed next to each other rather than one after another." +msgstr "" + +#: plugins/views_plugin_row_fields.inc:51 +msgid "The separator may be placed between inline fields to keep them from squishing up next to each other. You can use HTML in this field." +msgstr "" + +#: plugins/views_plugin_style.inc:91 +msgid "Grouping field" +msgstr "Gruppierungsfeld" + +#: plugins/views_plugin_style.inc:94 +msgid "You may optionally specify a field by which to group the records. Leave blank to not group." +msgstr "" + +#: plugins/views_plugin_style.inc:191 +msgid "Style @style requires a row style but the row plugin is invalid." +msgstr "Das Design @style erfordert ein Zeilendesign, aber das Zeilen-Plugin ist ungültig." + +#: plugins/views_plugin_style_grid.inc:33 +msgid "Number of columns" +msgstr "Anzahl der Spalten" + +#: plugins/views_plugin_style_grid.inc:38 +msgid "Alignment" +msgstr "Ausrichtung" + +#: plugins/views_plugin_style_grid.inc:39 +msgid "Horizontal" +msgstr "Horizontal" + +#: plugins/views_plugin_style_grid.inc:39 +msgid "Vertical" +msgstr "Vertikal" + +#: plugins/views_plugin_style_grid.inc:41 +msgid "Horizontal alignment will place items starting in the upper left and moving right. Vertical alignment will place items starting in the upper left and moving down." +msgstr "" + +#: plugins/views_plugin_style_list.inc:32 +msgid "List type" +msgstr "Listentyp" + +#: plugins/views_plugin_style_rss.inc:56 +msgid "Use the site mission for the description" +msgstr "Die Websitebeschreibung für die Beschreibung verwenden." + +#: plugins/views_plugin_style_rss.inc:60 +msgid "RSS description" +msgstr "RSS-Beschreibung" + +# not literally +#: plugins/views_plugin_style_rss.inc:62 +#, fuzzy +msgid "This will appear in the RSS feed itself." +msgstr "Dies wird in dem RSS-Newsfeed erscheinen." + +#: plugins/views_plugin_style_summary.inc:34 +#, fuzzy +msgid "Display record count with link" +msgstr "Anzahl der Ergebnisse mit dem Link anzeigen" + +#: plugins/views_plugin_style_summary.inc:39 +msgid "Override number of items to display" +msgstr "Die Anzahl der anzuzeigenden Einträge übersteuern" + +#: plugins/views_plugin_style_summary_unformatted.inc:26 +#, fuzzy +msgid "Display items inline" +msgstr "Einträge inline anzeigen" + +#: plugins/views_plugin_style_table.inc:126 +msgid "You need at least one field before you can configure your table settings" +msgstr "Mindestens ein Feld ist erforderlich, bevor die Tabelleneinstellungen konfiguriert werden können" + +#: plugins/views_plugin_style_table.inc:135 +msgid "Override normal sorting if click sorting is used" +msgstr "Normale Sortierung übersteuern, wenn die Klick-Sortierung verwendet wird." + +#: plugins/views_plugin_style_table.inc:141 +msgid "Enable Drupal style \"sticky\" table headers (Javascript)" +msgstr "" + +#: plugins/views_plugin_style_table.inc:143 +msgid "(Sticky header effects will not be active for preview below, only on live output.)" +msgstr "" + +#: plugins/views_plugin_style_table.inc:148 +msgid "Default sort order" +msgstr "Standardsortierung" + +#: plugins/views_plugin_style_table.inc:151 +#, fuzzy +msgid "If a default sort order is selected, what order should it use by default." +msgstr "Welche standardmäßige Sortierung bei der standardmäßigen Sortierreihenfolge verwendet werden soll." + +#: plugins/views_plugin_style_table.inc:237 +msgid "Place fields into columns; you may combine multiple fields into the same column. If you do, the separator in the column specified will be used to separate the fields. Check the sortable box to make that column click sortable, and check the default sort radio to determine which column will be sorted by default, if any. You may control column order and field labels in the fields section." +msgstr "" + +#: theme/views-more.tpl.php:15 +msgid "more" +msgstr "Weiter" + +#: theme/views-ui-edit-item.tpl.php:32 +msgid "The style selected does not utilize fields." +msgstr "Das ausgewählte Design verwendet keine Felder." + +#: theme/views-ui-edit-item.tpl.php:34 +msgid "None defined" +msgstr "Nicht definiert" + +#: theme/views-ui-edit-tab.tpl.php:31 +msgid "View settings" +msgstr "Einstellungen der Ansicht" + +#: theme/views-ui-edit-view.tpl.php:11 +msgid "This view 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>." +msgstr "Diese Ansicht wird gerade vom Benutzer !user bearbeitet und ist deshalb für die Bearbeitung durch andere gesperrt. Diese Sperre ist !age alt. Hier klicken um <a href=\"!break\">die Sperre aufzuheben</a>." + +#: theme/views-ui-edit-view.tpl.php:16 +msgid "New view" +msgstr "Neue Ansicht" + +#: theme/views-ui-edit-view.tpl.php:18 +msgid "Changed view" +msgstr "Ansicht wurde geändert" + +#: theme/views-ui-edit-view.tpl.php:23 +msgid "View %name, displaying items of type <strong>@base</strong>." +msgstr "Die Ansicht %name zeigt Einträge vom Typ <strong>@base</strong> an." + +#: theme/views-ui-edit-view.tpl.php:42 +msgid "Live preview" +msgstr "Live-Vorschau" + +#: theme/views-ui-list-views.tpl.php:17 +msgid "<em>@type</em> @base view: <strong>@view</strong>" +msgstr "<em>@type</em> @base-Ansicht: <strong>@view</strong>" + +#: theme/views-ui-list-views.tpl.php:27 +msgid "Title: @title" +msgstr "Titel: @title" + +#: theme/views-ui-list-views.tpl.php:30 +msgid "Path: !path" +msgstr "Pfad: !path" + +#: theme/theme.inc:90 +msgid "Edit this view" +msgstr "Diese Ansicht bearbeiten" + +#: theme/theme.inc:307 +msgid "sort by @s" +msgstr "Nach @s sortieren" + +#: theme/theme.inc:559 +msgid "‹‹" +msgstr "‹‹" + +#: theme/theme.inc:560 +msgid "››" +msgstr "››" + +#: theme/theme.inc:570 +msgid "@current of @max" +msgstr "@current von @max" + +#: views_export/views_export.module:76 +msgid "There are no views to be exported at this time." +msgstr "Derzeit gibt es keine zu exportierenden Ansichten." + +# "Tags" als "Tags" belassen? +#: views_export/views_export.module:108 +msgid "Show only these tags" +msgstr "Nur diese Kennzeichnungen anzeigen" + +#: views_export/views_export.module:122 +msgid "Module name" +msgstr "Modulname" + +#: views_export/views_export.module:123 +msgid "Enter the module name to export code to." +msgstr "Den Modulnamen angebenen zu dem Code exportiert wird." + +# TODO: English needs work +#: views_export/views_export.module:190 +msgid "Put this in @module.views_default.inc in your modules/@module directory or modules/@module/includes directory" +msgstr "Diesen Code im Verzeichnis modules/@module oder modules/@module/includes in eine Datei mit dem Namen @module.views_default.inc eingefügen." + +#: views_export/views_export.module:44 +msgid "use views exporter" +msgstr "Ansichten-Export verwenden" + +#: views_export/views_export.module:17 +msgid "Bulk export" +msgstr "Massenexport" + +#: views_export/views_export.module:0 +msgid "views_export" +msgstr "views_export" + +# Name of the views export module +#: views_export/views_export.info:0 +msgid "Views exporter" +msgstr "Ansichten-Export" + +#: views_export/views_export.info:0 +msgid "Allows exporting multiple views at once." +msgstr "Ermöglicht den Export mehrerer Ansichten auf einmal." + +#~ msgid "break this lock" +#~ msgstr "Sperre aufheben" + +#, fuzzy +#~ msgid "exposed>" +#~ msgstr "hervorgehoben" +#~ msgid "By role" +#~ msgstr "Nach Rolle" +#~ msgid "By permission" +#~ msgstr "Nach Berechtigung" +#~ msgid "" +#~ "Email address for a given user. Only accessible to users with " +#~ "<em>administer users</em> permission" +#~ msgstr "" +#~ "E-Mail-Adresse eines angegebenen Benutzers. Nur Benutzer mit der " +#~ "<em>Benutzer verwalten</em>-Berechtigung können darauf zugreifen." +#~ msgid "If by role" +#~ msgstr "Wenn nach Rolle" +#~ msgid "If by permission" +#~ msgstr "Wenn nach Berechtigung" +#~ msgid "Caching" +#~ msgstr "Caching" +#~ msgid "User ID" +#~ msgstr "Benutzer-ID" +#~ msgid "administer views" +#~ msgstr "Ansichten verwalten" +#~ msgid "Shows all new activity on system." +#~ msgstr "Alle neuen Aktivitäten auf dem System anzeigen." +#~ msgid "Replies" +#~ msgstr "Antworten" +#~ msgid "Last Post" +#~ msgstr "Letzter Beitrag" + +#, fuzzy +#~ msgid " new" +#~ msgstr " neu" +#~ msgid "Recent posts for %1" +#~ msgstr "Neueste Beiträge für %1" +#~ msgid "Recent posts" +#~ msgstr "Neue Beiträge" +#~ msgid "Recent comments" +#~ msgstr "Neueste Kommentare" +#~ msgid "Reply to" +#~ msgstr "Antwort an" +#~ msgid "Pages that link to %1" +#~ msgstr "Seiten die zu %1 verweisen" + +# core? +#, fuzzy +#~ msgid "Popular content" +#~ msgstr "Beliebter Inhalt" +#~ msgid "Popular (page)" +#~ msgstr "Beliebt (Seite)" +#~ msgid "Today (page)" +#~ msgstr "Heute (Seite)" +#~ msgid "Today's popular content" +#~ msgstr "Heutiger beliebtester Inhalt" +#~ msgid "Popular (block)" +#~ msgstr "Beliebt (Block)" +#~ msgid "Today (block)" +#~ msgstr "Heute (Block)" +#~ msgid "Core feed" +#~ msgstr "Kern-Newsfeed" + diff --git a/sites/all/modules/views/translations/eo.po b/sites/all/modules/views/translations/eo.po new file mode 100644 index 0000000000000000000000000000000000000000..5de86ce4b0b319b8f19209181a2c6f502129b228 --- /dev/null +++ b/sites/all/modules/views/translations/eo.po @@ -0,0 +1,4100 @@ +# Esperanto translation of Drupal (general) +# Copyright 2008 Chuck Smith <chuck@chucksmith.de> +# Generated from files: +# views.module,v 1.300 2008/06/25 21:10:10 merlinofchaos +# admin.inc,v 1.123 2008/07/02 18:43:08 merlinofchaos +# views_ui.module,v 1.99 2008/06/04 00:09:53 merlinofchaos +# views_export.module,v 1.2 2008/06/25 21:42:20 merlinofchaos +# views.info,v 1.7 2007/08/12 06:52:14 merlinofchaos +# views_ui.info,v 1.10 2008/01/09 00:05:08 merlinofchaos +# views_export.info,v 1.1 2008/06/12 16:17:25 merlinofchaos +# plugins.inc,v 1.134 2008/07/04 16:47:20 merlinofchaos +# convert.inc,v 1.11 2008/06/26 16:41:01 merlinofchaos +# theme.inc,v 1.53 2008/07/03 15:54:08 merlinofchaos +# views.install,v 1.41 2008/06/03 23:50:44 merlinofchaos +# docs.php,v 1.8 2008/06/18 15:25:46 merlinofchaos +# node.views.inc,v 1.76 2008/07/02 18:14:03 merlinofchaos +# view.inc,v 1.116 2008/07/03 18:01:44 merlinofchaos +# system.views.inc,v 1.6 2008/06/26 00:58:29 merlinofchaos +# user.views.inc,v 1.47 2008/06/26 00:58:29 merlinofchaos +# argument.handlers.inc,v 1.40 2008/07/04 20:43:33 merlinofchaos +# comment.views.inc,v 1.20 2008/07/02 17:42:57 merlinofchaos +# statistics.views.inc,v 1.7 2008/06/26 00:58:29 merlinofchaos +# upload.views.inc,v 1.12 2008/06/30 16:37:14 merlinofchaos +# book.views.inc,v 1.4 2008/07/02 17:42:57 merlinofchaos +# taxonomy.views.inc,v 1.37 2008/07/02 18:53:40 merlinofchaos +# ajax.inc,v 1.15 2008/06/14 17:42:42 merlinofchaos +# field.handlers.inc,v 1.13 2008/06/18 15:25:46 merlinofchaos +# filter.handlers.inc,v 1.25 2008/07/03 05:05:12 merlinofchaos +# relationship.handlers.inc,v 1.7 2008/06/30 16:37:14 merlinofchaos +# sort.handlers.inc,v 1.6 2008/06/18 15:25:46 merlinofchaos +# form.inc,v 1.10 2008/06/25 21:10:10 merlinofchaos +# handlers.inc,v 1.88 2008/06/25 22:20:01 merlinofchaos +# ajax.js,v 1.21 2008/05/27 22:31:59 merlinofchaos +# ajax_view.js,v 1.5 2008/05/27 22:31:59 merlinofchaos +# tabs.js,v 1.3 2008/03/30 15:58:26 merlinofchaos +# poll.views.inc,v 1.2 2008/03/12 04:32:07 merlinofchaos +# profile.views.inc,v 1.7 2008/06/26 00:58:29 merlinofchaos +# search.views.inc,v 1.11 2008/06/27 00:39:07 merlinofchaos +# views.views.inc,v 1.4 2008/06/26 00:58:29 merlinofchaos +# views-more.tpl.php,v 1.2 2008/04/11 08:46:26 merlinofchaos +# views-ui-edit-item.tpl.php,v 1.7 2008/05/09 19:32:12 merlinofchaos +# views-ui-edit-tab.tpl.php,v 1.10 2008/05/14 00:30:25 merlinofchaos +# views-ui-edit-view.tpl.php,v 1.8 2008/05/14 00:52:10 merlinofchaos +# views-ui-list-views.tpl.php,v 1.5 2008/05/08 05:29:30 merlinofchaos +# +#, fuzzy +msgid "" +"" +msgstr "Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2008-07-06 13:10+0200\n" +"PO-Revision-Date: 2008-08-12 HH:MM+ZZZZ\n" +"Last-Translator: Chuck Smith <chuck@chucksmith.de>\n" +"Language-Team: Esperanto <chuck@chucksmith.de>\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" + +#: views.module:640 +msgid "Skipping broken view @view" +msgstr "Preterpasi rompitan aspekton @view" + +#: views.module:687 +#: includes/admin.inc:92 +msgid "Overridden" +msgstr "Anstataŭigita" + +#: views.module:690 +#: views_ui.module:284 +#: includes/admin.inc:91 +msgid "Default" +msgstr "Defaŭlta" + +#: views.module:828 +#: includes/admin.inc:286 +#: views_export/views_export.module:116 +msgid "Apply" +msgstr "Apliki" + +#: views.module:109 +#: views_ui.module:23 +#: views.info:0 +#: views_ui.info:0 +#: views_export/views_export.info:0 +msgid "Views" +msgstr "Aspektoj" + +#: views.module:114 +msgid "Ajax callback for view loading." +msgstr "Ajax-revoko por ŝarĝi aspekton." + +#: views.module:0 +msgid "views" +msgstr "aspektoj" + +#: views_ui.module:158 +msgid "The converter will make a best-effort attempt to convert a Views 1 view to Views 2. This conversion is not reliable; you will very likely have to make adjustments to your view to get it to match. You can import Views 1 views through the normal Import tab." +msgstr "La konvertilo klopodos kiel eble plej bone konverti aspekton de Aspektoj 1 al Aspektoj 2. Tiu konvertado ne fidindas; vi plej verŝajne devos ĝustigi vian aspekton por ke ĝi kongruu. Vi povas importi aspektojn de Aspektoj 1 per la normala importa langeto." + +#: views_ui.module:25 +msgid "Views are customized lists of content on your system; they are highly configurable and give you control over how lists of content are presented." +msgstr "Aspektoj estas adapteblaj listoj de enhavo en via sistemo; ili estas tre adapteblaj kaj donos al vi regon super kiel listoj de enhavo prezentiĝos." + +#: views_ui.module:29 +#: includes/plugins.inc:88 +msgid "List" +msgstr "Listo" + +#: views_ui.module:35 +#: includes/admin.inc:1105 +msgid "Add" +msgstr "Aldoni" + +#: views_ui.module:40 +#: includes/admin.inc:715 +msgid "Import" +msgstr "Importi" + +#: views_ui.module:46 +msgid "Tools" +msgstr "Iloj" + +#: views_ui.module:52 +msgid "Basic" +msgstr "Baza" + +#: views_ui.module:60 +#: includes/convert.inc:30 +msgid "Convert" +msgstr "Konverti" + +#: views_ui.module:61 +msgid "Convert stored Views 1 views." +msgstr "Konverti konservitajn aspektojn de Aspektoj 1." + +#: views_ui.module:67 +msgid "Delete view" +msgstr "Forigi aspekton" + +#: views_ui.module:73 +msgid "Convert view" +msgstr "Konverti aspekton" + +#: views_ui.module:110 +#: includes/admin.inc:87 +#: theme/theme.inc:89 +msgid "Edit" +msgstr "Redakti" + +#: views_ui.module:0 +msgid "views_ui" +msgstr "views_ui" + +#: views.install:31 +msgid "Stores the general data for a view." +msgstr "Konservas la ĝeneralajn datumojn por aspekto." + +#: views.install:37 +msgid "The view ID of the field, defined by the database." +msgstr "La aspekta ID de la kampo, difinita de la datumbazo." + +#: views.install:45 +msgid "The unique name of the view. This is the primary field views are loaded from, and is used so that views may be internal and not necessarily in the database. May only be alphanumeric characters plus underscores." +msgstr "La unika nomo de la aspekto. Tio estas la ĉefa kampo de kiu aspektoj estas ŝarĝitaj, kaj estas uzata por ke aspektoj povu esti internaj kaj ne necese en la datumbazo. Povas nur esti alfanumeraj signoj kaj substrekoj." + +#: views.install:51 +msgid "A description of the view for the admin interface." +msgstr "Priskribo de la aspekto por la administra interfaco." + +#: views.install:57 +msgid "A tag used to group/sort views in the admin interface" +msgstr "Etikedo uzata por grupigi/ordigi aspektojn en la administra interfaco" + +#: views.install:61 +msgid "A chunk of PHP code that can be used to provide modifications to the view prior to building." +msgstr "Peco de PHP-kodo kiu povas esti uzata por modifi la aspekton antaŭ ĝia konstruado." + +#: views.install:68 +msgid "What table this view is based on, such as node, user, comment, or term." +msgstr "Sur kiu tabelo ĉi tiu aspekto estas bazita, kiel nodo, uzanto, komento aŭ termino." + +#: views.install:74 +msgid "A boolean to indicate whether or not this view may have its query cached." +msgstr "Buleo por indiki ĉu aŭ ne ĉi tiu aspekto povas kaŝmemorigi sian informpeton." + +#: views.install:82 +msgid "Stores information about each display attached to a view." +msgstr "Konservas informojn pri ĉiu aspekto alkroĉita al aspekto." + +#: views.install:89 +msgid "The view this display is attached to." +msgstr "La aspekto al kiu ĝi estas alkroĉita." + +#: views.install:97 +msgid "An identifier for this display; usually generated from the display_plugin, so should be something like page or page_1 or block_2, etc." +msgstr "Identigilo por ĉi tiu aspekto; kutime generita de la display_plugin, do devas esti io kiel page aŭ page_1 aŭ block_2 ktp." + +#: views.install:104 +msgid "The title of the display, viewable by the administrator." +msgstr "La titolo de la aspekto, videbla de la administranto." + +#: views.install:111 +msgid "The type of the display. Usually page, block or embed, but is pluggable so may be other things." +msgstr "La speco de la aspekto. Kutime paĝo, bloko aŭ enteksta, sed estas kromprogramebla, do povas esti aliaj aferoj." + +#: views.install:116 +msgid "The order in which this display is loaded." +msgstr "La sinsekvo en kiu ĉi tiu aspekto ŝarĝiĝas." + +#: views.install:120 +msgid "A serialized array of options for this display; it contains options that are generally only pertinent to that display plugin type." +msgstr "Serialigita matrico de opcioj por ĉi tiu aspekto; ĝi enhavas opciojn kiuj ĝenerale rilatas al tiu aspekta kromprograma speco. " + +#: views.install:131 +msgid "A special cache used to store objects that are being edited; it serves to save state in an ordinarily stateless environment." +msgstr "Speciala kaŝmemoro uzata por konservi objektojn kiuj estas redaktataj; ĝi servas por konservi staton en ordinare senstata ĉirkaŭaĵo." + +#: views.install:136 +msgid "The session ID this cache object belongs to." +msgstr "La seanca ID al kiu ĉi tiu kaŝmemora objekto apartenas." + +#: views.install:141 +msgid "The name of the view this cache is attached to." +msgstr "La nomo de la aspekto al kiu ĉi tiu kaŝmemoro estas alkroĉita." + +#: views.install:146 +msgid "The name of the object this cache is attached to; this essentially represents the owner so that several sub-systems can use this cache." +msgstr "La nomo de la objekto al kiu ĉi tiu kaŝmemoro estas alkroĉita; tio esence reprezentas la havanto por ke kelkaj subsistemoj povas uzi ĉi tiun kaŝmemoron." + +#: views.install:153 +msgid "The time this cache was created or updated." +msgstr "La tempo kiam ĉi tiu kaŝmemoro estis kreita aŭ ĝisdatigita." + +#: views.install:157 +msgid "Serialized data being stored." +msgstr "Serialigitaj datumoj konserviĝas." + +#: views.info:0 +msgid "Create customized lists and queries from your database." +msgstr "Krei proprajn listojn kaj vicojn el via datumbazo." + +#: views_ui.info:0 +msgid "Views UI" +msgstr "Aspektoj UI" + +#: views_ui.info:0 +msgid "Administrative interface to views. Without this module, you cannot create or edit your views." +msgstr "Administranta interfaco al aspektoj. Sen ĉi tiu modulo, vi ne povas krei aŭ redakti viajn aspektojn." + +#: docs/docs.php:106 +msgid "Emulates the default Drupal front page; you may set the default home page path to this view to make it your front page." +msgstr "Imitas la defaŭltan frontpaĝon de Drupalo; oni povas fiksi la defaŭltan hejmpaĝan vojon al ĉi tiu aspekto por ke ĝi ĉefpaĝiĝu." + +#: docs/docs.php:107 +msgid "default" +msgstr "defaŭlta" + +#: docs/docs.php:116 +#: includes/plugins.inc:18 +msgid "Defaults" +msgstr "Defaŭltoj" + +#: docs/docs.php:205 +#: includes/plugins.inc:32 +msgid "Page" +msgstr "Paĝo" + +#: docs/docs.php:260 +#: includes/plugins.inc:65 +msgid "Feed" +msgstr "Fluo" + +#: docs/docs.php:328 +msgid "Front page feed" +msgstr "Ĉefpaĝa fluo" + +#: includes/admin.inc:34 +msgid "If you install the advanced help module from !href, Views will provide more and better help. <a href=\"@hide\">Hide this message.</a>" +msgstr "Se vi instalas la help-modulo por spertuloj de !href, Aspektoj provizos pli bonan helpon. <a href=\"@hide\">Kaŝi ĉi tiun mesaĝon.</a>" + +#: includes/admin.inc:88 +#: theme/theme.inc:96 +#: views_export/views_export.module:128 +msgid "Export" +msgstr "Eksporti" + +#: includes/admin.inc:89 +#: theme/theme.inc:101 +msgid "Clone" +msgstr "Kloni" + +#: includes/admin.inc:92 +msgid "Revert" +msgstr "Malfari ŝanĝojn" + +#: includes/admin.inc:92 +#: includes/convert.inc:35 +msgid "Delete" +msgstr "Forigi" + +#: includes/admin.inc:97 +msgid "Disable" +msgstr "Malŝalti" + +#: includes/admin.inc:100 +msgid "Enable" +msgstr "Ŝalti" + +#: includes/admin.inc:106 +msgid "Warning! Broken view!" +msgstr "Atentu! Rompita aspekto!" + +#: includes/admin.inc:121 +msgid "Broken" +msgstr "Rompita" + +#: includes/admin.inc:180 +msgid "Install the advanced help module for the getting started" +msgstr "Instalu la help-modulon por spertuloj por komenci" + +#: includes/admin.inc:183 +msgid "Not sure what to do? Try the \"!getting-started\" page." +msgstr "Ne certas kion fari? Provu la paĝon de \"Komenci\"." + +#: includes/admin.inc:197 +msgid "<All>" +msgstr "<All>" + +#: includes/admin.inc:198 +#: includes/plugins.inc:2975 +msgid "<None>" +msgstr "<None>" + +#: includes/admin.inc:213 +#: views_export/views_export.module:146 +msgid "Tag" +msgstr "Etikedo" + +#: includes/admin.inc:229 +msgid "Displays" +msgstr "Aspektoj" + +#: includes/admin.inc:241 +#: includes/plugins.inc:1128 +#: modules/node.views.inc:139 +msgid "Type" +msgstr "Speco" + +#: includes/admin.inc:248 +msgid "Storage" +msgstr "Konservado" + +#: includes/admin.inc:251 +#: includes/view.inc:1097 +msgid "Normal" +msgstr "Normala" + +#: includes/admin.inc:260 +msgid "Sort by" +msgstr "Ordigi laŭ" + +#: includes/admin.inc:262 +#: includes/plugins.inc:831 +#: modules/system.views.inc:69 +#: modules/user.views.inc:59 +msgid "Name" +msgstr "Nomo" + +#: includes/admin.inc:263 +#: includes/argument.handlers.inc:127 +#: includes/plugins.inc:843 +#: modules/comment.views.inc:44 +#: modules/node.views.inc:84 +msgid "Title" +msgstr "Titolo" + +#: includes/admin.inc:265 +#: includes/plugins.inc:2098 +#: modules/statistics.views.inc:146 +#: modules/system.views.inc:88 +msgid "Path" +msgstr "Vojo" + +#: includes/admin.inc:267 +#: includes/convert.inc:21 +#: modules/upload.views.inc:56 +#: views_export/views_export.module:146 +msgid "Description" +msgstr "Priskribo" + +#: includes/admin.inc:274 +msgid "Order" +msgstr "Sinsekvo" + +#: includes/admin.inc:276 +msgid "Up" +msgstr "Supren" + +#: includes/admin.inc:277 +msgid "Down" +msgstr "Malsupren" + +#: includes/admin.inc:361 +msgid "Query" +msgstr "Informpeto" + +#: includes/admin.inc:363 +msgid "These queries were run during view rendering:" +msgstr "Ĉi tiuj informpetoj funkciis dum kreado de aspekto:" + +#: includes/admin.inc:368 +msgid "[@time ms] " +msgstr "[@time ms]" + +#: includes/admin.inc:371 +msgid "Other queries" +msgstr "Aliaj informpetoj" + +#: includes/admin.inc:379 +msgid "This display has no path." +msgstr "Ĉi tiu aspekto ne havas vojon." + +#: includes/admin.inc:384 +msgid "Query build time" +msgstr "Tempo por konstrui informpeton" + +#: includes/admin.inc:384 +msgid "@time ms" +msgstr "@time ms" + +#: includes/admin.inc:385 +msgid "Query execute time" +msgstr "Tempo por plenumi informpeton" + +#: includes/admin.inc:386 +msgid "View render time" +msgstr "Tempo por montri aspekton" + +#: includes/admin.inc:392 +msgid "No query was run" +msgstr "Neniu informpeto funkciis" + +#: includes/admin.inc:399 +msgid "Unable to preview due to validation errors." +msgstr "Ne eblas antaŭvidi pro validigaj eraroj." + +#: includes/admin.inc:450 +msgid "Display" +msgstr "Montri" + +#: includes/admin.inc:458 +#: includes/view.inc:1774 +msgid "Arguments" +msgstr "Argumentoj" + +#: includes/admin.inc:460 +msgid "Separate arguments with a / as though they were a URL path." +msgstr "Disigi argumentojn per / kvazaŭ ili estis URL-vojo." + +#: includes/admin.inc:466 +msgid "Preview" +msgstr "Antaŭvidi" + +#: includes/admin.inc:504 +msgid "Clone view @view" +msgstr "Klona aspekto @view" + +#: includes/admin.inc:517 +#: includes/convert.inc:20 +msgid "View name" +msgstr "Nomo de aspekto" + +#: includes/admin.inc:518 +msgid "This is the unique name of the view. It must contain only alphanumeric characters and underscores; it is used to identify the view internally and to generate unique theming template names for this view. If overriding a module provided view, the name must not be changed or instead a new view will be created." +msgstr "Ĉi tio estas unika nomo de la aspekto. Ĝi devas enhavi nur alfanumerajn signojn kaj substrekojn; ĝi estas uzata por identigi la aspekton interne kaj por generi unikajn haŭtajn ŝablonajn nomojn por ĉi tiu aspekto. Se oni anstataŭigas modulprovitan aspekton, la nomo ne povas esti ŝanĝita aŭ anstataŭe nova aspekto kreiĝos." + +#: includes/admin.inc:526 +msgid "View description" +msgstr "Priskribo de aspekto" + +#: includes/admin.inc:527 +msgid "This description will appear on the Views administrative UI to tell you what the view is about." +msgstr "Ĉi tiu priskribo aperos en la administra UI por Aspektoj por montri al vi pri kio temas la aspekto." + +#: includes/admin.inc:533 +msgid "View tag" +msgstr "Etikedo de aspekto" + +#: includes/admin.inc:534 +msgid "Enter an optional tag for this view; it is used only to help sort views on the administrative page." +msgstr "Enmetu nedevigan etikedon por ĉi tiu aspekto; ĝi estas uzata nur por helpi ordigi aspektojn en la administra paĝo." + +#: includes/admin.inc:546 +msgid "View type" +msgstr "Aspekta speco" + +#: includes/admin.inc:547 +msgid "The view type is the primary table for which information is being retrieved. The view type controls what arguments, fields, sort criteria and filters are available, so once this is set it <strong>cannot be changed</strong>." +msgstr "La aspekta speco estas la ĉefa tabelo por kiu informoj estas ricevita. La aspekta speco regas kiuj argumentoj, kampoj, ordigaj kriterioj kaj filtriloj alireblas, do kiam tio estas fiksita, <strong>ĝi estas neŝanĝebla</strong>." + +#: includes/admin.inc:558 +msgid "Next" +msgstr "Sekva" + +#: includes/admin.inc:574 +msgid "View name must be alphanumeric or underscores only." +msgstr "Aspekta nomo devas enhavi nur alfanumerojn aŭ substrekojn." + +#: includes/admin.inc:580 +msgid "You must use a unique name for this view." +msgstr "Vi devas uzi unikan nomon por ĉi tiu aspekto." + +#: includes/admin.inc:613 +msgid "Are you sure you want to revert the view %name?" +msgstr "Ĉu vi certas ke vi volas refari la ŝanĝojn al la aspekto %name?" + +#: includes/admin.inc:614 +msgid "Reverting the view will delete the view that is in the database, reverting it to the original default view. Any changes you have made will be lost and cannot be recovered." +msgstr "Refari la ŝanĝojn de la aspekto forigos la aspekton kiu estas en la datumbazo, revenante al ĝia originala defaŭlta aspekto. Ŝanĝojn kiujn vi faris estos plene perditaj." + +#: includes/admin.inc:617 +#: includes/convert.inc:105 +msgid "Are you sure you want to delete the view %name?" +msgstr "Ĉu vi certas ke vi volas forigi la aspekton %name?" + +#: includes/admin.inc:618 +msgid "Deleting a view cannot be undone." +msgstr "Forigi aspekton ne povas esti malfarata." + +#: includes/admin.inc:626 +#: includes/convert.inc:110 +msgid "Cancel" +msgstr "Nuligi" + +#: includes/admin.inc:635 +msgid "The view has been deleted." +msgstr "La aspekto estis forigita." + +#: includes/admin.inc:647 +msgid "There is no lock on view %view to break." +msgstr "Ne estas ŝlosilo por rompi de aspekto %view." + +#: includes/admin.inc:657 +msgid "Are you sure you want to break the lock on view %name?" +msgstr "Ĉu vi certas ke vi volas rompi la ŝlosilon de aspekto %name?" + +#: includes/admin.inc:660 +msgid "By breaking this lock, any unsaved changes made by !user will be lost!" +msgstr "Rompante ĉi tiun ŝlosilon, nekonservitaj ŝanĝoj de !user estos perdita!" + +#: includes/admin.inc:661 +msgid "Break lock" +msgstr "Rompi ŝlosilon" + +#: includes/admin.inc:678 +msgid "Edit view \"%view\"" +msgstr "Redakti aspekton \"%view\"" + +#: includes/admin.inc:705 +msgid "Enter the name to use for this view if it is different from the source view. Leave blank to use the name of the view." +msgstr "Enmeti la nomon por uzi por ĉi tiu aspekto se ĝi malsamas de la fonta aspekto. Lasu malplena por uzi la nomon de la aspekto." + +#: includes/admin.inc:710 +msgid "Paste view code here" +msgstr "Glui aspektan kodon ĉi tie" + +#: includes/admin.inc:732 +msgid "Unable to interpret view code." +msgstr "Ne eblas interpreti kodon de aspekto." + +#: includes/admin.inc:740 +msgid "You are importing a view created in Views version 1. You may need to adjust some parameters to work correctly in version 2." +msgstr "Vi importas aspekton kreita en versio 1 de Aspektoj. Vi eble devas ĝustigi kelkajn parametrojn por funkcii ĝuste en versio 2." + +#: includes/admin.inc:743 +msgid "That view is not compatible with this version of Views." +msgstr "Tiu aspekto ne kongruas kun ĉi tiu versio de Aspektoj." + +#: includes/admin.inc:758 +msgid "A view by that name already exists; please choose a different name" +msgstr "Aspekto de tiu nomo jam ekzistas; bonvolu elekti alian nomon" + +#: includes/admin.inc:779 +msgid "Save" +msgstr "Konservi" + +#: includes/admin.inc:831 +msgid "The view has been saved." +msgstr "La aspekto estas konservita." + +#: includes/admin.inc:875 +msgid "Unknown or missing table name" +msgstr "Nekonata aŭ mankata tabela nomo" + +#: includes/admin.inc:880 +msgid "Click on an item to edit that item's details." +msgstr "Klaku sur ero por redakti ties detalojn." + +#: includes/admin.inc:883 +msgid "This view has a broken default display and cannot be used." +msgstr "Ĉi tiu aspekto havas rompitan defaŭltan montradon kaj ne povas esti uzata." + +#: includes/admin.inc:919 +msgid "break this lock" +msgstr "rompi ĉi tiun ŝlosilon" + +#: includes/admin.inc:925 +#: theme/theme.inc:97 +msgid "Export this view" +msgstr "Eksporti ĉi tiun aspekton" + +#: includes/admin.inc:930 +#: theme/theme.inc:102 +msgid "Create a copy of this view" +msgstr "Krei kopion de ĉi tiu aspekto" + +#: includes/admin.inc:941 +msgid "View \"!display\"" +msgstr "Vidi \"!display\"" + +#: includes/admin.inc:942 +msgid "Go to the real page for this display" +msgstr "Iri al la vera paĝo por ĉi tiu montro" + +#: includes/admin.inc:1008 +#: includes/plugins.inc:838 +msgid "None" +msgstr "Neniu" + +#: includes/admin.inc:1082 +msgid "Invalid" +msgstr "Nevalida" + +#: includes/admin.inc:1082 +msgid "Error: Display @display refers to a plugin named '@plugin', but that plugin doesn't exist!" +msgstr "Eraro: Montro @display referencas al kromprogramo nomata '@plugin', sed tiu kromprogramo ne ekzistas!" + +#: includes/admin.inc:1103 +msgid "Rearrange" +msgstr "Rearanĝi" + +#: includes/admin.inc:1136 +msgid "Error: handler for @table > @field doesn't exist!" +msgstr "Eraro: traktilo por @table > @field ne ekzistas!" + +#: includes/admin.inc:1155 +msgid "Settings" +msgstr "Agordoj" + +#: includes/admin.inc:1160 +#: includes/plugins.inc:849 +msgid "Missing style plugin" +msgstr "Mankata stila kromprogramo" + +#: includes/admin.inc:1164 +#: includes/plugins.inc:862 +msgid "Change settings for this style" +msgstr "Ŝanĝi agordojn por ĉi tiu stilo" + +#: includes/admin.inc:1167 +msgid " Style: !style" +msgstr " Stilo: !style" + +#: includes/admin.inc:1198 +msgid "Invalid display id while regenerating tabs" +msgstr "Nevalida montra id regenerante langetojn" + +#: includes/admin.inc:1231 +msgid "Update" +msgstr "Ĝisdatigo" + +#: includes/admin.inc:1249 +msgid "Ok" +msgstr "Ok" + +#: includes/admin.inc:1518 +msgid "Unable to initialize default display" +msgstr "Ne eblas pravalorizi defaŭltan montron" + +#: includes/admin.inc:1550 +msgid "Add display" +msgstr "Aldoni montron" + +#: includes/admin.inc:1590 +msgid "Remove display" +msgstr "Forigi montron" + +#: includes/admin.inc:1601 +msgid "Restore display" +msgstr "Restarigi montron" + +#: includes/admin.inc:1673 +msgid "Analyze" +msgstr "Analizi" + +#: includes/admin.inc:1693 +msgid "This view has only a default display and therefore will not be placed anywhere on your site; perhaps you want to add a page or a block display." +msgstr "Ĉi tiu aspekto havas nur defaŭltan montron kaj tiel ne povas lokiĝi ie en via retejo; eble vi volas aldoni paĝon aŭ blokan montron." + +#: includes/admin.inc:1705 +msgid "View analysis" +msgstr "Analizo de aspekto" + +#: includes/admin.inc:1714 +msgid "View analysis can find nothing to report." +msgstr "Analizo de aspekto ne povas trovi ion por raporti." + +#: includes/admin.inc:1788 +msgid "View details" +msgstr "Detaloj de aspekto" + +#: includes/admin.inc:1829 +msgid "Invalid display id @display" +msgstr "Nevalida montra id @display" + +#: includes/admin.inc:1887 +msgid "Configure @type" +msgstr "Agordi @type" + +#: includes/admin.inc:1942 +msgid "Rearrange @type" +msgstr "Rearanĝi @type" + +#: includes/admin.inc:1985 +msgid "Broken field @id" +msgstr "Rompita kampo @id" + +#: includes/admin.inc:2025 +msgid "Remove" +msgstr "Forigi" + +#: includes/admin.inc:2025 +msgid "Remove this item" +msgstr "Forigi ĉi tiun eron" + +#: includes/admin.inc:2031 +msgid "No fields available." +msgstr "Neniuj kampoj alireblaj." + +#: includes/admin.inc:2034 +#: includes/plugins.inc:2190 +#: modules/book.views.inc:57 +#: modules/taxonomy.views.inc:115 +#: modules/upload.views.inc:90 +msgid "Weight" +msgstr "Pezo" + +#: includes/admin.inc:2090 +msgid "Add @type" +msgstr "Aldoni @type" + +#: includes/admin.inc:2101 +msgid "Groups" +msgstr "Grupoj" + +#: includes/admin.inc:2120 +msgid "!group: !field" +msgstr "!group: !field" + +#: includes/admin.inc:2129 +msgid "There are no @types available to add." +msgstr "Ne estas @types alireblaj por aldoni." + +#: includes/admin.inc:2226 +msgid "Do not use a relationship" +msgstr "Ne uzu en rilato" + +#: includes/admin.inc:2235 +#: includes/view.inc:1798 +msgid "Relationship" +msgstr "Rilato" + +#: includes/admin.inc:2248 +msgid "Configure @type \"@item\"" +msgstr "Agordi @type \"@item\"" + +#: includes/admin.inc:2361 +msgid "Configure extra settings for @type \"@item\"" +msgstr "Agordi ekstrajn agordojn por @type \"@item\"" + +#: includes/admin.inc:2426 +msgid "Change summary style for @type \"@item\"" +msgstr "Ŝanĝi resuman stilon por @type \"@item\"" + +#: includes/admin.inc:2449 +msgid "Internal error: broken plugin." +msgstr "Interna eraro: rompita kromprogramo." + +#: includes/admin.inc:2513 +msgid "Configure summary style for @type \"@item\"" +msgstr "Agordi resuman stilon por @type \"@item\"" + +#: includes/admin.inc:2605 +msgid "Clear Views' cache" +msgstr "Malplenigi kaŝmemoron de Aspekto" + +#: includes/admin.inc:2611 +msgid "Add Views signature to all SQL queries" +msgstr "Aldoni subskribon de Aspekto al ĉiuj SQL-informpetoj" + +#: includes/admin.inc:2612 +msgid "All Views-generated queries will include a special 'VIEWS' = 'VIEWS' string in the WHERE clause. This makes identifying Views queries in database server logs simpler, but should only be used when troubleshooting." +msgstr "Ĉiuj Aspekto-generitaj informpetoj inkluzivos specialan 'VIEWS' = 'VIEWS' teksto en la WHERE sekcio. Tio simpligas identigi informpetojn de Aspektoj en datumbazaj servilaj protokoloj, sed devas esti uzata nur dum problemsolvado." + +#: includes/admin.inc:2618 +msgid "Disable views data caching" +msgstr "Malŝalti datum-kaŝmemoradon de aspektoj" + +#: includes/admin.inc:2619 +msgid "Views caches data about tables, modules and views available, to increase performance. By checking this box, Views will skip this cache and always rebuild this data when needed. This can have a serious performance impact on your site." +msgstr "Aspektoj kaŝmemorigas datumojn pri alireblaj tabeloj, moduloj kaj aspektoj, por plibonigi rendimenton. Se ŝaltita, Aspektoj preterpasos ĉi tiun kaŝmemoron kaj ĉiam rekonstruas ĉi tiujn datumojn kiam bezonata. Tio povas serioze influi la rendimenton de via retejo." + +#: includes/admin.inc:2625 +msgid "Ignore missing advanced help module" +msgstr "Ignori mankantan help-modulo por spertuloj" + +#: includes/admin.inc:2626 +msgid "Views uses the advanced help module to provide help text; if this module is not present Views will complain, unless this setting is checked." +msgstr "Aspektoj uzas la help-modulon de spertoj por provizi helpan tekston; se tiu modulo ne ekzistas, Aspektoj eble plendos, krom se ĉi tiu agordo estas ŝaltita." + +#: includes/admin.inc:2632 +msgid "Show query above live preview" +msgstr "Montri informpeton super viva antaŭvido" + +#: includes/admin.inc:2633 +msgid "The live preview feature will show you the output of the view you're creating, as well as the view. Check here to show the query and other information above the view; leave this unchecked to show that information below the view." +msgstr "La viva antaŭvida funkcio montros al vi la eligo de la aspekto kiun vi kreas, kune kun la aspekto. Ŝaltu ĝin por montri la informpeton kaj aliajn informojn super la aspekto; lasu ĝin malŝaltita por montri tiujn informojn sub la aspekto." + +#: includes/admin.inc:2639 +msgid "Show other queries run during render during live preview" +msgstr "Montri aliajn informpetojn kiuj funkcias dum montrado de viva antaŭvido" + +#: includes/admin.inc:2640 +msgid "Drupal has the potential to run many queries while a view is being rendered. Checking this box will display every query run during view render as part of the live preview." +msgstr "Drupalo havas potencialon por funkciigi multajn informpetojn dum aspekto montriĝas. Kiam ŝaltita, oni vidos ĉiun informpeton dum la montriĝo kiel parto de la viva antaŭvido." + +#: includes/admin.inc:2646 +msgid "Do not show hover links over views" +msgstr "Ne montri superligilojn super aspektoj" + +#: includes/admin.inc:2647 +msgid "To make it easier to administrate your views, Views provides 'hover' links to take you to the edit and export screen of a view whenever the view is used. This can be distracting on some themes, though; if it is problematic, you can turn it off here." +msgstr "Por faciligi administradon de viaj aspektoj, Aspektoj provizas 'superligilojn' al la redakta kaj eksporta ekrano de aspekto kiam la aspekto estas uzata. Tio povas distri en kelkaj haŭtoj, tamen, se estas problema, vi povas malŝalti ĝin ĉi tie." + +#: includes/admin.inc:2653 +msgid "Enable views performance statistics via the Devel module" +msgstr "Ŝalti rendimentajn statistikon de aspektoj per la Devel-modulo." + +#: includes/admin.inc:2654 +msgid "Check this to enable some Views query and performance statistics <em>if Devel is installed</em>." +msgstr "Ĉi tio ŝaltas kelkajn informpetan kaj rendimentajn statistikojn de Aspektoj <em>se Devel estas instalita</em>. " + +#: includes/admin.inc:2660 +msgid "Disable javascript with Views" +msgstr "Malŝalti JavaSkripton kun Aspektoj" + +#: includes/admin.inc:2661 +msgid "If you are having problems with the javascript, you can disable it here; the Views UI should degrade and still be usable without javascript, it just not as good." +msgstr "Se vi havas problemojn kun la JavaSkripto, vi povas malŝalti ĝin ĉi tie; la Aspektoj UI devas daŭre funkcii kaj uzeblas sen JavaSkripto, ĝi simple ne estas tiel bona." + +#: includes/admin.inc:2669 +msgid "Page region to output performance statistics" +msgstr "Paĝa regiono por eligi rendimentan statistikon" + +#: includes/admin.inc:2682 +msgid "The cache has been cleared." +msgstr "La kaŝmemoro estas malplenigita." + +#: includes/admin.inc:2872 +msgid "Error: missing @component" +msgstr "Eraro: mankas @component" + +#: includes/ajax.inc:73 +msgid "Server reports invalid input error." +msgstr "Servilo raportas nevalidan enmetan eraron." + +#: includes/ajax.inc:74 +msgid "Error" +msgstr "Eraro" + +#: includes/argument.handlers.inc:110 +msgid "All" +msgstr "Ĉiuj" + +#: includes/argument.handlers.inc:129 +msgid "The title to use when this argument is present; it will override the title of the view and titles from previous arguments. You can use percent substitution here to replace with argument titles. Use \"%1\" for the first argument, \"%2\" for the second, etc." +msgstr "La titolo por uzi kiam ĉi tiu argumento ekzistas; ĝi anstataŭigos la titolon de la aspekto kaj titoloj de antaŭaj argumentoj. Vi povas uzi procentan anstataŭigon por anstataŭigi kun argumentaj titoloj. Uzu \"%1\" por la unua argumento, \"%2\" por la dua ktp." + +#: includes/argument.handlers.inc:142 +msgid "Action to take if argument is not present" +msgstr "Ago por fari se argumento ne ekzistas" + +#: includes/argument.handlers.inc:154 +msgid "Wildcard" +msgstr "Ĵokero" + +#: includes/argument.handlers.inc:157 +msgid "If this value is received as an argument, the argument will be ignored; i.e, \"all values\"" +msgstr "Se tiu valoro ne estas ricevita kiel argumento, la argumento estos ignorita; alivorte \"ĉiuj valoroj\"" + +#: includes/argument.handlers.inc:163 +msgid "Wildcard title" +msgstr "Ĵokera titolo" + +#: includes/argument.handlers.inc:166 +msgid "The title to use for the wildcard in substitutions elsewhere." +msgstr "La titolo por uzi por la ĵokero en anstataŭigoj aliloke." + +#: includes/argument.handlers.inc:189 +msgid "Validator options" +msgstr "Validilaj opcioj" + +#: includes/argument.handlers.inc:194 +msgid "Validator" +msgstr "Validilo" + +#: includes/argument.handlers.inc:198 +msgid "<Basic validation>" +msgstr "<Basic validation>" + +#: includes/argument.handlers.inc:233 +msgid "Action to take if argument does not validate" +msgstr "Ago por fari se argumento ne validiĝas" + +#: includes/argument.handlers.inc:252 +msgid "Display all values" +msgstr "Montri ĉiujn valorojn" + +#: includes/argument.handlers.inc:257 +msgid "Hide view / Page not found (404)" +msgstr "Kaŝi aspekton / Paĝo ne trovita (404)" + +#: includes/argument.handlers.inc:262 +msgid "Display empty text" +msgstr "Montri malplenan tekston" + +#: includes/argument.handlers.inc:267 +msgid "Summary, sorted ascending" +msgstr "Resumo, ordigita kreskante" + +#: includes/argument.handlers.inc:274 +msgid "Summary, sorted descending" +msgstr "Resumo, ordigita malkreskante" + +#: includes/argument.handlers.inc:281 +msgid "Provide default argument" +msgstr "Provizi defaŭltan argumenton" + +#: includes/argument.handlers.inc:314 +msgid "Provide default argument options" +msgstr "Provizi defaŭltan argumentajn opciojn" + +#: includes/argument.handlers.inc:324 +msgid "Default argument type" +msgstr "Defaŭlta argumenta speco" + +#: includes/argument.handlers.inc:710 +#: includes/field.handlers.inc:217 +#: includes/filter.handlers.inc:577 +#: includes/relationship.handlers.inc:132 +#: includes/sort.handlers.inc:71 +msgid "Broken/missing handler" +msgstr "Rompita/mankata traktilo" + +#: includes/argument.handlers.inc:718 +#: includes/field.handlers.inc:225 +#: includes/filter.handlers.inc:585 +#: includes/relationship.handlers.inc:140 +#: includes/sort.handlers.inc:79 +msgid "The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item." +msgstr "La traktilo por ĉi tiu ero estas rompita aŭ mankata kaj ne povas esti uzata. Se modulo provizis la traktilon kaj estis malŝaltita, reŝalti la modulon eble restarigos ĝin. Alikaze, vi verŝajne devas forigi la eron." + +#: includes/argument.handlers.inc:804 +msgid "Current date" +msgstr "Aktuala dato" + +#: includes/argument.handlers.inc:859 +msgid "Glossary mode" +msgstr "Glosara reĝimo" + +#: includes/argument.handlers.inc:860 +msgid "Glossary mode applies a limit to the number of characters used in the argument, which allows the summary view to act as a glossary." +msgstr "Glosara reĝimo aplikas limon al nombro da signoj uzitaj en la argumento, kiu ebligas ke la resuma aspekto povu agi kiel glosaro." + +#: includes/argument.handlers.inc:866 +msgid "Character limit" +msgstr "Signa limo" + +#: includes/argument.handlers.inc:867 +msgid "How many characters of the argument to filter against. If set to 1, all fields starting with the letter in the argument would be matched." +msgstr "Kiom da signoj por filtri de la argumento. Se agordita al 1, ĉiuj kampoj komencante kun la litero en la argumento kongruus. " + +#: includes/argument.handlers.inc:875 +msgid "Case" +msgstr "Uskleco" + +#: includes/argument.handlers.inc:876 +msgid "When printing the argument result, how to transform the case." +msgstr "Montrante la argumentan rezulton, kiel transformi la usklecon." + +#: includes/argument.handlers.inc:878 +msgid "No transform" +msgstr "Neniu transformo" + +#: includes/argument.handlers.inc:879 +msgid "Upper case" +msgstr "Majuskla" + +#: includes/argument.handlers.inc:880 +msgid "Lower case" +msgstr "Minuskla" + +#: includes/argument.handlers.inc:881 +msgid "Capitalize first letter" +msgstr "Majuskligi unuan literon" + +#: includes/argument.handlers.inc:882 +msgid "Capitalize each word" +msgstr "Majuskligi ĉiun vorton" + +#: includes/argument.handlers.inc:889 +msgid "Case in path" +msgstr "Uskleco en vojo" + +#: includes/argument.handlers.inc:890 +msgid "When printing url paths, how to transform the of the argument. Do not use this unless with Postgres as it uses case sensitive comparisons." +msgstr "Kiam montrante url-vojojn, kiel transformi la de la argumento. Ne uzu tion krom kun Postgres ĉar ĝi uzas usklecodistingajn komparojn." + +#: includes/argument.handlers.inc:903 +msgid "Transform spaces to dashes in URL" +msgstr "Transformi spacetojn al streketojn en URL" + +#: includes/argument.handlers.inc:910 +msgid "Allow multiple arguments to work together." +msgstr "Ebligi multajn argumentojn por kunfunkcii." + +#: includes/argument.handlers.inc:911 +msgid "If selected, multiple instances of this argument can work together, as though multiple terms were supplied to the same argument. This setting is not compatible with the \"Reduce duplicates\" setting." +msgstr "Se elektita, multaj ekzemploj de ĉi tiu argumento povas kunfunkcii, kvazaŭ multaj terminoj estis donitaj al la sama argumento. Tiu agordo ne kongruas kun la agordo de \"Redukti kopiojn\"." + +#: includes/argument.handlers.inc:917 +msgid "Do not display items with no value in summary" +msgstr "Ne montru erojn kun neniu valoro en resumo." + +#: includes/argument.handlers.inc:1043 +msgid "Allow multiple terms per argument." +msgstr "Ebligi multajn terminojn por argumento." + +#: includes/argument.handlers.inc:1044 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 or 1,2,3." +msgstr "Se elektita, uzantoj povas enmeti multajn argumentojn en la formo de 1+2+3 aŭ 1,2,3." + +#: includes/argument.handlers.inc:1050 +msgid "Exclude the argument" +msgstr "Ekskludi la argumenton" + +#: includes/argument.handlers.inc:1051 +msgid "If selected, the numbers entered in the argument will be excluded rather than limiting the view." +msgstr "Se elektita, la nombroj enmetitaj en la argumento ekskludiĝos anstataŭ limigi la aspekton." + +#: includes/argument.handlers.inc:1058 +#: modules/taxonomy.views.inc:109 +msgid "Uncategorized" +msgstr "Nekategoriigita" + +#: includes/argument.handlers.inc:1074 +msgid "Invalid input" +msgstr "Nevalida enmeto" + +#: includes/argument.handlers.inc:1150 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 (for OR) or 1,2,3 (for AND)." +msgstr "Se elektita, uzantoj povas enmeti multajn argumentojn en la formo de 1+2+3 (por OR) aŭ 1,2,3 (por AND)." + +#: includes/convert.inc:14 +msgid "There are no Views 1 views stored in the database to convert." +msgstr "Ne estas aspektoj de Aspektoj 1 en la datumbazo por konverti." + +#: includes/convert.inc:22 +msgid "Operations" +msgstr "Operacioj" + +#: includes/convert.inc:33 +msgid "Converted" +msgstr "Konvertita" + +#: includes/convert.inc:68 +msgid "The table below lists Views version 1 views that are stored in the database. You can either convert them to work in Views version 2, or delete them. The views are convertible only if there is no Views 2 view with the same name." +msgstr "La tabelo sube listigas aspektoj de Aspektoj versio 1 kiuj estas konservitaj en la datumbazo. Vi povas aŭ konverti ilin por funkcii en Aspektoj versio 2, aŭ forigi ilin. La aspektoj estas konverteblaj nur se ne estas aspektoj de Aspektoj 2 kun la sama nomo." + +#: includes/convert.inc:79 +msgid "Unable to find view." +msgstr "Ne eblas trovi aspekton." + +#: includes/convert.inc:89 +msgid "Unable to convert view." +msgstr "Ne eblas konverti aspekton." + +#: includes/convert.inc:108 +msgid "This action cannot be undone." +msgstr "Tiu ago ne povas esti malfarata." + +#: includes/convert.inc:118 +msgid "The view has been deleted" +msgstr "Tiu aspekto estis forigita." + +#: includes/field.handlers.inc:138 +#: includes/filter.handlers.inc:309 +#: includes/relationship.handlers.inc:78 +msgid "Label" +msgstr "Etikedo" + +#: includes/field.handlers.inc:140 +msgid "The label for this field that will be displayed to end users if the style requires it." +msgstr "La etikedo por ĉi tiu kampo montriĝos al uzantoj se la stilo bezonas ĝin." + +#: includes/field.handlers.inc:144 +msgid "Exclude from display" +msgstr "Ekskludu de montrado" + +#: includes/field.handlers.inc:146 +msgid "Check this box to not display this field, but still load it in the view. Use this option to not show a grouping field in each record, or when doing advanced theming." +msgstr "Ŝaltu por ne montri ĉi tiun kampon, sed tamen ŝarĝi ĝin en la montro. Uzu ĉi tiun opcion por ne montri grupigan kampon en ĉiu rikardo, aŭ kiam vi faras haŭtadon por spertuloj." + +#: includes/field.handlers.inc:255 +msgid "Date format" +msgstr "Datoformato" + +#: includes/field.handlers.inc:260 +msgid "Custom" +msgstr "Propra" + +#: includes/field.handlers.inc:261 +msgid "Time ago" +msgstr "Tempo antaŭe" + +#: includes/field.handlers.inc:267 +msgid "Custom date format" +msgstr "Propra datoformato" + +#: includes/field.handlers.inc:268 +msgid "If \"Custom\", see <a href=\"http://us.php.net/manual/en/function.date.php\">the PHP docs</a> for date formats. If \"Time ago\" this is the the number of different units to display, which defaults to two." +msgstr "Se \"Propra\" vidu <a href=\"http://us.php.net/manual/en/function.date.php\">la PHP-dokumentojn</a> por datoformatoj. Se \"Tempo antaŭe\", tio estas la nombro da malsamaj unuoj por montri, kiu defaŭltas al du." + +#: includes/field.handlers.inc:284 +msgid "%time ago" +msgstr "%time antaŭe" + +#: includes/field.handlers.inc:312 +msgid "Output format" +msgstr "Eliga formato" + +#: includes/field.handlers.inc:314 +msgid "Yes/No" +msgstr "Jes/Ne" + +#: includes/field.handlers.inc:315 +msgid "True/False" +msgstr "Vera/Malvera" + +#: includes/field.handlers.inc:316 +msgid "On/Off" +msgstr "Ŝaltita/Malŝaltita" + +#: includes/field.handlers.inc:322 +msgid "Reverse" +msgstr "Inversa" + +#: includes/field.handlers.inc:323 +msgid "If checked, true will be displayed as false." +msgstr "Se ŝaltita, vera montriĝos kiel malvera." + +#: includes/field.handlers.inc:337 +#: includes/filter.handlers.inc:929 +#: includes/plugins.inc:884 +msgid "Yes" +msgstr "Jes" + +#: includes/field.handlers.inc:337 +#: includes/filter.handlers.inc:929 +#: includes/plugins.inc:884 +msgid "No" +msgstr "Ne" + +#: includes/field.handlers.inc:339 +#: includes/filter.handlers.inc:898 +msgid "True" +msgstr "Vera" + +#: includes/field.handlers.inc:339 +#: includes/filter.handlers.inc:939 +msgid "False" +msgstr "Malvera" + +#: includes/field.handlers.inc:341 +msgid "On" +msgstr "Ŝaltita" + +#: includes/field.handlers.inc:341 +msgid "Off" +msgstr "Malŝaltita" + +#: includes/field.handlers.inc:404 +#: modules/statistics.views.inc:274 +msgid "Display as link" +msgstr "Montri kiel ligilo" + +#: includes/field.handlers.inc:446 +#: modules/node.views.inc:1259 +msgid "Display type" +msgstr "Montra speco" + +#: includes/field.handlers.inc:448 +#: includes/plugins.inc:3129 +msgid "Unordered list" +msgstr "Neordigita listo" + +#: includes/field.handlers.inc:449 +#: includes/plugins.inc:3129 +msgid "Ordered list" +msgstr "Ordigita listo" + +#: includes/field.handlers.inc:450 +msgid "Simple separator" +msgstr "Simpla disigilo" + +#: includes/field.handlers.inc:457 +#: includes/plugins.inc:3423 +msgid "Separator" +msgstr "Disigilo" + +#: includes/field.handlers.inc:465 +msgid "Empty list text" +msgstr "Malplena lista teksto" + +#: includes/field.handlers.inc:467 +msgid "If the list is empty, you may enter text here that will be displayed." +msgstr "Se la listo estas malplena, vi povas enmeti tekston ĉi tie kiu montriĝos." + +#: includes/field.handlers.inc:524 +msgid "Round" +msgstr "Rondigo" + +#: includes/field.handlers.inc:525 +msgid "If checked, the number will be rounded." +msgstr "Se ŝaltita, la numero rondiĝos." + +#: includes/field.handlers.inc:530 +msgid "Precision" +msgstr "Precizo" + +#: includes/field.handlers.inc:532 +msgid "Specify how many digits to print after the decimal point." +msgstr "Indiki kiom da ciferoj por montri post la dekuma punkto." + +#: includes/field.handlers.inc:539 +msgid "Decimal point" +msgstr "Dekuma punkto" + +#: includes/field.handlers.inc:541 +msgid "What single character to use as a decimal point." +msgstr "Kiu signo por uzi kiel dekuma punkto." + +#: includes/field.handlers.inc:547 +msgid "Thousands separator" +msgstr "Disigilo de miloj" + +#: includes/field.handlers.inc:549 +msgid "What single character to use as the thousands separator." +msgstr "Kiu signo por uzi kiel la disigilo de miloj." + +#: includes/field.handlers.inc:554 +msgid "Prefix" +msgstr "Prefikso" + +#: includes/field.handlers.inc:556 +msgid "Text to put before the number, such as currency symbol." +msgstr "Teksto por meti antaŭ la numero, kiel mona simbolo." + +#: includes/field.handlers.inc:560 +msgid "Suffix" +msgstr "Sufikso" + +#: includes/field.handlers.inc:562 +msgid "Text to put after the number, such as currency symbol." +msgstr "Teksto por meti post la numero, kiel mona simbolo." + +#: includes/filter.handlers.inc:124 +msgid "Operator" +msgstr "Operacio" + +#: includes/filter.handlers.inc:188 +msgid "Expose" +msgstr "Montri" + +#: includes/filter.handlers.inc:193 +msgid "This item is currently not exposed. If you <strong>expose</strong> it, users will be able to change the filter as they view it." +msgstr "Ĉi tiu ero nun estas kaŝita. Se vi <strong>montras</strong> ĝin, uzantoj povos ŝanĝi la filtrilon dum ili vidas ĝin." + +#: includes/filter.handlers.inc:200 +msgid "Hide" +msgstr "Kaŝi" + +#: includes/filter.handlers.inc:205 +msgid "This item is currently exposed. If you <strong>hide</strong> it, users will not able to change the filter as they view it." +msgstr "Ĉi tiu ero estas nun montrata. Se vi <strong>kaŝas</strong> ĝin, uzantoj ne povos ŝanĝi la filtrilon dum ili vidas ĝin. " + +#: includes/filter.handlers.inc:276 +msgid "Unlock operator" +msgstr "Malŝlosi operatoron" + +#: includes/filter.handlers.inc:277 +msgid "When checked, the operator will be exposed to the user" +msgstr "Kiam ŝaltita, la operatoro montriĝas al la uzanto" + +#: includes/filter.handlers.inc:283 +msgid "Operator identifier" +msgstr "Operatora identigilo" + +#: includes/filter.handlers.inc:285 +msgid "This will appear in the URL after the ? to identify this operator." +msgstr "Ĉi tio aperos en la URL post la ? por identigi ĉi tiun operatoron." + +#: includes/filter.handlers.inc:302 +msgid "Filter identifier" +msgstr "Filtrila identigilo" + +#: includes/filter.handlers.inc:304 +msgid "This will appear in the URL after the ? to identify this filter. Cannot be blank." +msgstr "Ĉi tio aperos en la URL post la ? por identigi ĉi tiun filtrilon. Ne povas esti malplena." + +#: includes/filter.handlers.inc:320 +msgid "Optional" +msgstr "Nedeviga" + +#: includes/filter.handlers.inc:321 +msgid "This exposed filter is optional and will have added options to allow it not to be set." +msgstr "Ĉi tiu montrata filtrilo estas nedeviga kaj havos aldonajn opciojn por ebligi ke ĝi ne estu ŝaltita." + +#: includes/filter.handlers.inc:327 +msgid "Force single" +msgstr "Devigi unuopan" + +#: includes/filter.handlers.inc:328 +msgid "Force this exposed filter to accept only one option." +msgstr "Devigi ke ĉi tiu montrata filtrilo akceptu nur unu opcion." + +#: includes/filter.handlers.inc:334 +msgid "Remember" +msgstr "Memori" + +#: includes/filter.handlers.inc:335 +msgid "Remember the last setting the user gave this filter." +msgstr "Memori la lastan agordon kiun la uzanto donis al ĉi tiu filtrilo." + +#: includes/filter.handlers.inc:346 +msgid "The identifier is required if the filter is\n exposed." +msgstr "La identigilo estas bezonata se la filtrilo estas\n montrata." + +#: includes/filter.handlers.inc:352 +msgid "This identifier is not allowed." +msgstr "Ĉi tiu identigilo ne estas permesata." + +#: includes/filter.handlers.inc:453 +msgid "<Any>" +msgstr "<Any>" + +#: includes/filter.handlers.inc:607 +msgid "Is equal to" +msgstr "Egalas al" + +#: includes/filter.handlers.inc:608 +msgid "Is not equal to" +msgstr "Ne egalas al" + +#: includes/filter.handlers.inc:618 +msgid "Value" +msgstr "Valoro" + +#: includes/filter.handlers.inc:650 +msgid "=" +msgstr "=" + +#: includes/filter.handlers.inc:661 +msgid "Contains" +msgstr "Enhavas" + +#: includes/filter.handlers.inc:662 +msgid "contains" +msgstr "enhavas" + +#: includes/filter.handlers.inc:667 +msgid "Contains any word" +msgstr "Enhavas iun vorton" + +#: includes/filter.handlers.inc:668 +msgid "has word" +msgstr "havas vorton" + +#: includes/filter.handlers.inc:673 +msgid "Contains all words" +msgstr "Enhavas ĉiujn vortojn" + +#: includes/filter.handlers.inc:674 +msgid "has all" +msgstr "havas ĉiujn" + +#: includes/filter.handlers.inc:679 +msgid "Starts with" +msgstr "Komenciĝas per" + +#: includes/filter.handlers.inc:680 +msgid "begins" +msgstr "komenciĝas" + +#: includes/filter.handlers.inc:685 +msgid "Ends with" +msgstr "Finiĝas per" + +#: includes/filter.handlers.inc:686 +msgid "ends" +msgstr "finiĝas" + +#: includes/filter.handlers.inc:691 +msgid "Does not contain" +msgstr "Ne enhavas" + +#: includes/filter.handlers.inc:692 +msgid "!has" +msgstr "!has" + +#: includes/filter.handlers.inc:701 +msgid "Is empty (NULL)" +msgstr "Malplenas (NULL)" + +#: includes/filter.handlers.inc:703 +msgid "empty" +msgstr "malplena" + +#: includes/filter.handlers.inc:707 +msgid "Is not empty (NULL)" +msgstr "Ne malplenas (NULL)" + +#: includes/filter.handlers.inc:709 +msgid "not empty" +msgstr "ne malplena" + +#: includes/filter.handlers.inc:732 +msgid "exposed>" +msgstr "montrata>" + +#: includes/filter.handlers.inc:739 +msgid "Case sensitive" +msgstr "Usklecodistinga" + +#: includes/filter.handlers.inc:741 +msgid "Case sensitive filters may be faster; MySQL might ignore case sensitivity." +msgstr "Usklecodistingaj filtriloj povas esti pli rapidaj; MySQL eble ignoras usklecodistingeco." + +#: includes/filter.handlers.inc:936 +msgid "exposed" +msgstr "montrita" + +#: includes/filter.handlers.inc:968 +msgid "Options" +msgstr "Opcioj" + +#: includes/filter.handlers.inc:990 +msgid "Limit list to selected items" +msgstr "Limigi liston al elektitaj eroj" + +#: includes/filter.handlers.inc:991 +msgid "If checked, the selected items presented to the user will be the only ones selected here." +msgstr "Se ŝaltita, la elektitaj eroj prezentitaj al la uzanto estos la solaj kiuj estas elektitaj ĉi tie. " + +#: includes/filter.handlers.inc:1010 +msgid "Is one of" +msgstr "Estas unu el" + +#: includes/filter.handlers.inc:1011 +msgid "Is not one of" +msgstr "Ne estas unu el" + +#: includes/filter.handlers.inc:1102 +#: modules/system.views.inc:234 +msgid "Unknown" +msgstr "Nekonata" + +#: includes/filter.handlers.inc:1157 +msgid "Is less than" +msgstr "Estas malpli ol" + +#: includes/filter.handlers.inc:1159 +msgid "<" +msgstr "<" + +#: includes/filter.handlers.inc:1163 +msgid "Is less than or equal to" +msgstr "Estas malpli ol aŭ egala al" + +#: includes/filter.handlers.inc:1165 +msgid "<=" +msgstr "<=" + +#: includes/filter.handlers.inc:1177 +msgid "!=" +msgstr "!=" + +#: includes/filter.handlers.inc:1181 +msgid "Is greater than or equal to" +msgstr "Estas pli granda aŭ egala al" + +#: includes/filter.handlers.inc:1183 +msgid ">=" +msgstr ">=" + +#: includes/filter.handlers.inc:1187 +msgid "Is greater than" +msgstr "Estas pli granda ol" + +#: includes/filter.handlers.inc:1189 +msgid ">" +msgstr ">" + +#: includes/filter.handlers.inc:1193 +msgid "Is between" +msgstr "Estas inter" + +#: includes/filter.handlers.inc:1195 +msgid "between" +msgstr "inter" + +#: includes/filter.handlers.inc:1199 +msgid "Is not between" +msgstr "Ne estas inter" + +#: includes/filter.handlers.inc:1201 +msgid "not between" +msgstr "ne inter" + +#: includes/filter.handlers.inc:1292 +msgid "Min" +msgstr "Min" + +#: includes/filter.handlers.inc:1298 +msgid "And max" +msgstr "Kaj maks" + +#: includes/filter.handlers.inc:1298 +msgid "And" +msgstr "Kaj" + +#: includes/filter.handlers.inc:1355 +msgid "@min and @max" +msgstr "@min kaj @max" + +#: includes/filter.handlers.inc:1381 +msgid "Value type" +msgstr "Valora speco" + +#: includes/filter.handlers.inc:1383 +msgid "A date in any machine readable format. CCYY-MM-DD HH:MM:SS is preferred." +msgstr "Dato en maŝinlegebla formato. CCYY-MM-DD HH:MM:SS estas preferata." + +#: includes/filter.handlers.inc:1384 +msgid "An offset from the current time such as \"+1 day\" or \"-2 hours -30 minutes\"" +msgstr "Deŝovo de la nuna tempo kiel \"+1 tago\" aŭ \"-2 horoj -30 minutoj\"" + +#: includes/filter.handlers.inc:1434 +msgid "Invalid date format." +msgstr "Nevalida datoformato." + +#: includes/filter.handlers.inc:1540 +msgid "Is all of" +msgstr "Estas ĉio el" + +#: includes/filter.handlers.inc:1541 +msgid "Is none of" +msgstr "Estas nenio el" + +#: includes/form.inc:249 +msgid "Validation error, please try again. If this error persists, please contact the site administrator." +msgstr "Validiga eraro, bonvolu reprovi. Se ĉi tiu eraro daŭras, bonvolu kontakti la retejan administranton." + +#: includes/handlers.inc:154 +msgid "!group: !title" +msgstr "!group: !title" + +#: includes/handlers.inc:380 +msgid "Reduce duplicates" +msgstr "Redukti kopiojn" + +#: includes/handlers.inc:381 +msgid "This filter can cause items that have more than one of the selected options to appear as duplicate results. If this filter causes duplicate results to occur, this checkbox can reduce those duplicates; however, the more terms it has to search for, the less performant the query will be, so use this with caution." +msgstr "Ĉi tiu filtrilo povas kaŭzi ke eroj havu pli ol unu el la elektitaj opcioj por aperi kiel kopiaj rezultoj. Se tiu filtrilo kaŭzas ke kopiaj rezultoj okazu, tiu markobutono povas redukti tiujn kopiojn; tamen, ju pli da terminoj ĝi devas serĉi, des malpli rendimenta la informpeto estos, do uzu tion atente. " + +#: includes/plugins.inc:19 +msgid "Default settings for this view." +msgstr "Defaŭltaj agordoj por ĉi tiu aspekto." + +#: includes/plugins.inc:33 +msgid "Display the view as a page, with a URL and menu links." +msgstr "Montri la aspekton kiel paĝo, kun URL kaj menuligiloj." + +#: includes/plugins.inc:44 +msgid "Block" +msgstr "Bloko" + +#: includes/plugins.inc:45 +msgid "Display the view as a block." +msgstr "Montri la aspekton kiel blokon." + +#: includes/plugins.inc:57 +msgid "Attachment" +msgstr "Alkroĉaĵo" + +#: includes/plugins.inc:58 +msgid "Attachments added to other displays to achieve multiple views in the same view." +msgstr "Alkroĉaĵoj aldonitaj al aliaj montroj por atingi multajn aspektojn en la sama aspekto." + +#: includes/plugins.inc:66 +msgid "Display the view as a feed, such as an RSS feed." +msgstr "Montri la aspekton kiel fluo, ekzemple kiel RSS-fluo." + +#: includes/plugins.inc:78 +msgid "Unformatted" +msgstr "Neformatita" + +#: includes/plugins.inc:79 +msgid "Displays rows one after another." +msgstr "Montras vicojn unu post la alia." + +#: includes/plugins.inc:89 +msgid "Displays rows as an HTML list." +msgstr "Montras vicojn kiel HTML-liston." + +#: includes/plugins.inc:97 +msgid "Grid" +msgstr "Krado" + +#: includes/plugins.inc:98 +msgid "Displays rows in a grid." +msgstr "Montras vicojn en krado." + +#: includes/plugins.inc:106 +msgid "Table" +msgstr "Tabelo" + +#: includes/plugins.inc:107 +msgid "Displays rows in a table." +msgstr "Montras vicojn en tabelo." + +#: includes/plugins.inc:117 +msgid "Displays the default summary summary as a list." +msgstr "Montras la defaŭltan resumon kiel liston." + +#: includes/plugins.inc:125 +msgid "Displays the summary unformatted, with option for one after another or inline." +msgstr "Montras la resumon neformatitan, kun opcio por unu post la alia aŭ enteksta." + +#: includes/plugins.inc:132 +msgid "RSS Feed" +msgstr "RSS-Fluo" + +#: includes/plugins.inc:133 +msgid "Generates an RSS feed from a view." +msgstr "Generas RSS-fluon de aspekto." + +#: includes/plugins.inc:143 +#: includes/view.inc:1767 +msgid "Fields" +msgstr "Kampoj" + +#: includes/plugins.inc:144 +msgid "Displays the fields with an optional template." +msgstr "Montras la kampojn kun nedeviga ŝablono." + +#: includes/plugins.inc:154 +msgid "Fixed entry" +msgstr "Fiksita ero" + +#: includes/plugins.inc:158 +msgid "PHP Code" +msgstr "PHP-Kodo" + +#: includes/plugins.inc:168 +msgid "Numeric" +msgstr "Numera" + +#: includes/plugins.inc:809 +msgid "Broken field" +msgstr "Rompita kampo" + +#: includes/plugins.inc:826 +msgid "Basic settings" +msgstr "Bazaj agordoj" + +#: includes/plugins.inc:833 +msgid "Change the name of this display." +msgstr "Ŝanĝi la nomon de ĉi tiu montro." + +#: includes/plugins.inc:845 +msgid "Change the title that this display will use." +msgstr "Ŝanĝu la titolon kiun ĉi tiu montro uzos." + +#: includes/plugins.inc:855 +msgid "Style" +msgstr "Stilo" + +#: includes/plugins.inc:857 +msgid "Change the style plugin." +msgstr "Ŝanĝi la stilan kromprogramon." + +#: includes/plugins.inc:871 +msgid "Row style" +msgstr "Vica stilo" + +#: includes/plugins.inc:873 +msgid "Change the row plugin." +msgstr "Ŝanĝi la vican kromprogramon." + +#: includes/plugins.inc:883 +msgid "Use AJAX" +msgstr "Uzi AJAX-n" + +#: includes/plugins.inc:885 +msgid "Change whether or not this display will use AJAX." +msgstr "Ŝanĝi ĉu aŭ ne ĉi tiu montro uzos AJAX-n." + +#: includes/plugins.inc:892 +msgid "Use pager" +msgstr "Uzi paĝilon" + +#: includes/plugins.inc:893 +msgid "Mini" +msgstr "Mini" + +#: includes/plugins.inc:894 +msgid "Change this display's pager setting." +msgstr "Ŝanĝi la agordon de ĉi tiu montra paĝilo" + +#: includes/plugins.inc:901 +msgid "Items per page" +msgstr "Eroj de paĝo" + +#: includes/plugins.inc:901 +msgid "Items to display" +msgstr "Eroj por montri" + +#: includes/plugins.inc:902 +msgid "Unlimited" +msgstr "Senlima" + +#: includes/plugins.inc:903 +msgid "Change how many items to display." +msgstr "Ŝanĝi kiom da eroj por montri" + +#: includes/plugins.inc:909 +msgid "More link" +msgstr "Plia ligilo" + +#: includes/plugins.inc:911 +msgid "Specify whether this display will provide a \"more\" link." +msgstr "Elekti ĉu ĉi tiu montro provizos \"plian\" ligilon." + +#: includes/plugins.inc:917 +msgid "Distinct" +msgstr "Distinga" + +#: includes/plugins.inc:919 +msgid "Display only distinct items, without duplicates." +msgstr "Montri nur distinktajn erojn, sen kopioj." + +#: includes/plugins.inc:930 +msgid "Unrestricted" +msgstr "Nelimigita" + +#: includes/plugins.inc:938 +msgid "Multiple roles" +msgstr "Multaj roloj" + +#: includes/plugins.inc:950 +msgid "Access" +msgstr "Aliro" + +#: includes/plugins.inc:952 +msgid "Specify access control settings for this display." +msgstr "Indiki alirajn agordojn por ĉi tiu montro." + +#: includes/plugins.inc:972 +msgid "Link display" +msgstr "Ligila montro" + +#: includes/plugins.inc:974 +msgid "Specify which display this display will link to." +msgstr "Indiki al kiu montro ĉi tiu montro ligos." + +#: includes/plugins.inc:979 +msgid "Header" +msgstr "Kaplinio" + +#: includes/plugins.inc:979 +msgid "Footer" +msgstr "Piedlinio" + +#: includes/plugins.inc:979 +msgid "Empty text" +msgstr "Malplena teksto" + +#: includes/plugins.inc:995 +msgid "Unknown/missing filter" +msgstr "Nekonata/mankata filtrilo" + +#: includes/plugins.inc:1003 +msgid "Change this display's !name." +msgstr "Ŝanĝi la !name de la montro." + +#: includes/plugins.inc:1009 +msgid "Theme" +msgstr "Haŭto" + +#: includes/plugins.inc:1010 +msgid "Information" +msgstr "Informoj" + +#: includes/plugins.inc:1011 +msgid "Get information on how to theme this display" +msgstr "Akiri informojn pri kiel haŭtigi ĉi tiun montron" + +#: includes/plugins.inc:1037 +msgid "The name of this display" +msgstr "La nomo de ĉi tiu montro" + +#: includes/plugins.inc:1040 +msgid "This title will appear only in the administrative interface for the View." +msgstr "Ĉi tiu titolo aperos nur en la administra interfaco por la Aspekto." + +#: includes/plugins.inc:1045 +msgid "The title of this view" +msgstr "La titolo de ĉi tiu aspekto" + +#: includes/plugins.inc:1048 +msgid "This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc." +msgstr "Ĉi tiu titolo montros kun la aspekto, kie ajn titoloj normale montriĝas; ekzemple, kiel la paĝa titolo, bloka titolo ktp." + +#: includes/plugins.inc:1053 +msgid "Use AJAX when available to load this view" +msgstr "Uzi AJAX-n kiam eblas por ŝarĝi ĉi tiun aspekton" + +#: includes/plugins.inc:1057 +msgid "If set, this view will use an AJAX mechanism for paging, table sorting and exposed filters. This means the entire page will not refresh. It is not recommended that you use this if this view is the main content of the page as it will prevent deep linking to specific pages, but it is very useful for side content." +msgstr "Se ŝaltita, ĉi tiu aspekto uzos AJAX-n mekanismon por paĝado, tabelordigo kaj montrataj filtriloj. Tio signifas ke la tuta paĝo ne refreŝiĝos. Ne estas rekomendita uzi tion se ĉi tiu aspekto estas la ĉefa enhavo de la paĝo ĉar tio malebligos profundajn ligilojn al specifaj paĝoj, sed tre utilas por flanka enhavo." + +#: includes/plugins.inc:1066 +msgid "Use a pager for this view" +msgstr "Uzi paĝilon por ĉi tiu aspekto" + +#: includes/plugins.inc:1069 +msgid "Full pager" +msgstr "Plena paĝilo" + +#: includes/plugins.inc:1069 +msgid "Mini pager" +msgstr "Mini-paĝilo" + +#: includes/plugins.inc:1074 +msgid "Pager element" +msgstr "Paĝila elemento" + +#: includes/plugins.inc:1075 +msgid "Unless you're experiencing problems with pagers related to this view, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible." +msgstr "Krom se vi spertas problemojn kun paĝiloj rilate al ĉi tiu aspekto, indas lasi ĉe 0. Se vi uzas multajn paĝilojn en unu paĝo, vi eble bezonas ke tiu numero estu pli alta valoro por ke ĝi ne konfliktu kun la ?page=array. Grandaj valoroj aldonos multe da komoj al viaj URL-oj, do evitu se eblas." + +#: includes/plugins.inc:1084 +msgid "The number of items to display per page. Enter 0 for no limit." +msgstr "La nombro da eroj por montri en ĉiu paĝo. Enmetu 0 por neniu limo." + +#: includes/plugins.inc:1089 +msgid "Offset" +msgstr "Deŝovo" + +#: includes/plugins.inc:1090 +msgid "The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed. Offset can not be used if items to display is 0; instead use a very large number there." +msgstr "La nombro da eroj por preterpasi. Ekzemple, se ĉi tiu kampo estas 3, la unuaj 3 eroj preterpasiĝos kaj ne montriĝos. Deŝovo ne povas esti uzata se la montro estas 0; anstataŭe uzu tre grandan numeron tie." + +#: includes/plugins.inc:1095 +msgid "Add a more link to the bottom of the display." +msgstr "Aldonu "pli" ligilon sube de la montro. " + +#: includes/plugins.inc:1098 +msgid "Create more link" +msgstr "Kreu "pli" ligilon" + +#: includes/plugins.inc:1099 +msgid "This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' above." +msgstr "Tio aldonos "pli" ligilon sube de ĉi tiu montro, kiu ligos al la paĝa aspekto. Se vi havas pli ol unu paĝa aspekto, la ligilo iros al la montro indikita en 'Ligila montro' supre." + +#: includes/plugins.inc:1108 +msgid "This will make the view display only distinct items. If there are multiple identical items, each will be displayed only once. You can use this to try and remove duplicates from a view, though it does not always work. Note that this can slow queries down, so use it with caution." +msgstr "Tio kaŭzos ke la aspekto montros nur malsamajn erojn. Se estas multaj samaj eroj, ĉiu montriĝos nur unufoje. Vi povas uzi ĉi tion por provi forigi kopiojn de aspekto, kvankam tio ne ĉiam funkcias. Rimarku ke tio povas malrapidigi informpetojn, do uzu ĝin zorgeme." + +#: includes/plugins.inc:1113 +msgid "Access restrictions" +msgstr "Aliraj limigoj" + +#: includes/plugins.inc:1130 +msgid "By role" +msgstr "De rolo" + +#: includes/plugins.inc:1130 +msgid "By permission" +msgstr "De permeso" + +#: includes/plugins.inc:1139 +msgid "Role" +msgstr "Rolo" + +#: includes/plugins.inc:1142 +msgid "Only the checked roles will be able to access this display. Note that users with \"access all views\" can see any view, regardless of role." +msgstr "Nur la elektitaj roloj eblos aliri ĉi tiun montron. Rimarku ke uzantoj kun \"aliri ĉiujn aspektojn\" povas vidi ĉiujn aspektojn, egale de la rolo." + +#: includes/plugins.inc:1159 +msgid "Permission" +msgstr "Permeso" + +#: includes/plugins.inc:1161 +msgid "Only users with the selected permission flag will be able to access this display. Note that users with \"access all views\" can see any view, regardless of other permissions." +msgstr "Nur uzantoj kun la elektita permeso povos aliri ĉi tiun montron. Rimarku ke uzantoj kun la permeso \"aliri ĉiujn aspektojn\" povas vidi ĉiujn aspektojn, egale de aliaj permesoj." + +#: includes/plugins.inc:1172 +msgid "Display even if view has no result" +msgstr "Montru eĉ se la aspekto ne havas rezulton" + +#: includes/plugins.inc:1179 +msgid "Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional." +msgstr "Teksto por montri supre de la aspekto. Eble enhavas klarigon aŭ ligilojn aŭ kion ajn vi volas. Nedeviga." + +#: includes/plugins.inc:1195 +msgid "Text to display beneath the view. May contain an explanation or links or whatever you like. Optional." +msgstr "Teksto por montri sub la aspekto. Eblas enhavas klarigon aŭ ligiloj aŭ kion ajn vi volas. Nedeviga." + +#: includes/plugins.inc:1206 +msgid "Text to display if the view has no results. Optional." +msgstr "Teksto por montri se la aspekto ne havas rezultojn. Nedeviga." + +#: includes/plugins.inc:1212 +msgid "How should this view be styled" +msgstr "Kiel ĉi tiu aspekto devas esti stilita." + +#: includes/plugins.inc:1218 +msgid "If the style you choose has settings, be sure to click the settings button that will appear next to it in the View summary." +msgstr "Se la stilo vi elektis havas agordojn, certe klaku la butonon de agordoj kiu aperos apud ĝi en la resumo de la Aspekto." + +#: includes/plugins.inc:1226 +msgid "You may also adjust the !settings for the currently selected style by clicking on the icon." +msgstr "Vi ankaŭ povas ŝanĝi la !settings por la nune elektita stilo klakante sur la bildsimbolo." + +#: includes/plugins.inc:1226 +msgid "settings" +msgstr "agordoj" + +#: includes/plugins.inc:1232 +msgid "Style options" +msgstr "Stilaj opcioj" + +#: includes/plugins.inc:1244 +msgid "Row style options" +msgstr "Stilaj opcioj de vico" + +#: includes/plugins.inc:1256 +msgid "How should each row in this view be styled" +msgstr "Kiel ĉiu vico en ĉi tiu aspekto devas esti stilita" + +#: includes/plugins.inc:1269 +msgid "You may also adjust the !settings for the currently selected row style by clicking on the icon." +msgstr "Vi ankaŭ povas ŝanĝi la agordojn por la nune elektita vica stilo klakante la ikonon." + +#: includes/plugins.inc:1275 +msgid "Which display to use for path" +msgstr "Kiun montron por uzi kiel vojo" + +#: includes/plugins.inc:1284 +msgid "Which display to use to get this display's path for things like summary links, rss feed links, more links, etc." +msgstr "Kiun montron por uzi por preni la vojon de la montro por aferoj kiel resumaj ligiloj, rss-fluaj ligiloj, pliaj ligiloj ktp." + +#: includes/plugins.inc:1289 +msgid "Theming information" +msgstr "Haŭtaj informoj" + +#: includes/plugins.inc:1297 +msgid "Display output" +msgstr "Eligo de montro" + +#: includes/plugins.inc:1301 +msgid "Alternative display output" +msgstr "Alternativa eligo de montro" + +#: includes/plugins.inc:1308 +msgid "Style output" +msgstr "Eligo de stilo" + +#: includes/plugins.inc:1312 +msgid "Alternative style" +msgstr "Alternative stilo" + +#: includes/plugins.inc:1319 +msgid "Row style output" +msgstr "Eligo de vica stilo" + +#: includes/plugins.inc:1323 +msgid "Alternative row style" +msgstr "Alternativa vica stilo" + +#: includes/plugins.inc:1331 +msgid "Field @field (ID: @id)" +msgstr "Kampo @field (ID: @id)" + +#: includes/plugins.inc:1339 +msgid "This section lists all possible templates for the display plugin and for the style plugins, ordered roughly from the least specific to the most specific. The active template for each plugin -- which is the most specific template found on the system -- is highlighted in bold." +msgstr "Ĉi tiu sekcio listigas ĉiujn eblajn ŝablonojn por la montra kromprogramo kaj por la stilaj kromprogramoj, ordigitaj pli malpli de la malplej specifaj ĝis la plej specifaj. La aktiva ŝablono por ĉiu kromprogramo -- kiu estas la plej specifa ŝablonon trovita en la sistemo -- estas markita grase." + +#: includes/plugins.inc:1354 +msgid "Rescan template files" +msgstr "Reskani ŝablonajn dosierojn" + +#: includes/plugins.inc:1360 +msgid "<strong>Important!</strong> When adding, removing, or renaming template files, it is necessary to make Drupal aware of the changes by making it rescan the files on your system. By clicking this button you clear Drupal's theme registry and thereby trigger this rescanning process. The highlighted templates above will then reflect the new state of your system." +msgstr "<strong>Grave!</strong> Kiam aldonante, forigante, aŭ renomante ŝablonajn dosierojn, necesas atentigi Drupalon de la ŝanĝoj per reskanado de la dosieroj en via sistemo. Klakante ĉi tiun butonon, vi malplenigas la registrejon de la Drupala haŭto kaj tiel ekigas la reskanan procezon. La markitaj ŝablonoj supre tiam reflektos la novan staton de via sistemo." + +#: includes/plugins.inc:1366 +msgid "Theming information (display)" +msgstr "Haŭtaj informoj (montro)" + +#: includes/plugins.inc:1367 +msgid "Back to !info." +msgstr "Reen al !info." + +#: includes/plugins.inc:1367 +msgid "theming information" +msgstr "haŭtaj informoj" + +#: includes/plugins.inc:1370 +msgid "This display has no theming information" +msgstr "Ĉi tiu ŝablono ne havas haŭtajn informojn" + +#: includes/plugins.inc:1373 +msgid "This is the default theme template used for this display." +msgstr "Tio estas la defaŭlta haŭta ŝablono uzata por ĉi tiu montro." + +#: includes/plugins.inc:1379 +msgid "This is an alternative template for this display." +msgstr "Tio estas alternativa ŝablono por ĉi tiu montro." + +#: includes/plugins.inc:1393 +msgid "Theming information (style)" +msgstr "Haŭtaj informoj (stilo)" + +#: includes/plugins.inc:1399 +msgid "This display has no style theming information" +msgstr "Ĉi tiu montro ne havas informojn de stila haŭtado" + +#: includes/plugins.inc:1402 +msgid "This is the default theme template used for this style." +msgstr "Tio estas la defaŭlta haŭta ŝablono uzata por ĉi tiu stilo." + +#: includes/plugins.inc:1408 +msgid "This is an alternative template for this style." +msgstr "Tio estas alternative ŝablono por ĉi tiu stilo." + +#: includes/plugins.inc:1422 +msgid "Theming information (row style)" +msgstr "Haŭtaj informoj (vica stilo)" + +#: includes/plugins.inc:1428 +msgid "This display has no row style theming information" +msgstr "Ĉi tiu montro ne havas informojn de vica stila haŭtado" + +#: includes/plugins.inc:1431 +msgid "This is the default theme template used for this row style." +msgstr "Tio estas la defaŭlta haŭta ŝablono uzata por ĉi tiu vica stilo." + +#: includes/plugins.inc:1437 +msgid "This is an alternative template for this row style." +msgstr "Tio estas alternativa ŝablono por ĉi tiu vica stilo." + +#: includes/plugins.inc:1494 +msgid "File found in folder @template-path" +msgstr "Dosiero trovita en dosierujo @template-path" + +#: includes/plugins.inc:1498 +msgid "(File not found, in folder @template-path)" +msgstr "(Dosiero ne trovita, en dosierujo @template-path)" + +#: includes/plugins.inc:1525 +msgid "You must select at least one role if type is \"by role\"" +msgstr "Vi devas elektia almenaŭ unu rolon se speco estas \"de rolo\"" + +#: includes/plugins.inc:1633 +msgid "Override" +msgstr "Anstataŭigi" + +#: includes/plugins.inc:1638 +msgid "Status: using default values." +msgstr "Stato: uzante defaŭltajn valorojn." + +#: includes/plugins.inc:1642 +msgid "Update default display" +msgstr "Ĝisdatigi defaŭltan montron" + +#: includes/plugins.inc:1647 +msgid "Use default" +msgstr "Uzu defaŭltan" + +#: includes/plugins.inc:1652 +msgid "Status: using overridden values." +msgstr "Stato: uzante anstataŭigitajn valorojn." + +#: includes/plugins.inc:1842 +msgid "Display @display uses fields but there are none defined for it." +msgstr "Montro @display uzas kampojn, sed ne estas iuj difinitaj por ĝi." + +#: includes/plugins.inc:1846 +msgid "Display @display uses path but path is undefined." +msgstr "Montro @display uzas vojon, sed vojo estas nedifinita." + +#: includes/plugins.inc:1851 +msgid "Display @display has an invalid style plugin." +msgstr "Montro @display havas nevalidan stilan kromprogramon." + +#: includes/plugins.inc:2084 +msgid "Page settings" +msgstr "Paĝaj agordoj" + +#: includes/plugins.inc:2109 +msgid "No menu" +msgstr "Neniu menuo" + +#: includes/plugins.inc:2112 +msgid "Normal: @title" +msgstr "Normala: @title" + +#: includes/plugins.inc:2116 +msgid "Tab: @title" +msgstr "Langeto: @title" + +#: includes/plugins.inc:2126 +msgid "Menu" +msgstr "Menuo" + +#: includes/plugins.inc:2132 +msgid "Change settings for the parent menu" +msgstr "Ŝanĝi agordojn por la patra menuo" + +#: includes/plugins.inc:2145 +msgid "The menu path or URL of this view" +msgstr "La menua vojo aŭ URL de ĉi tiu aspekto" + +#: includes/plugins.inc:2149 +msgid "This view will be displayed by visiting this path on your site. You may use \"%\" in your URL to represent values that will be used for arguments: For example, \"node/%/feed\"." +msgstr "Ĉi tiu aspekto montriĝos vizitante ĉi tiun vojon en via retejo. Vi povas uzi \"%\" en via URL por reprezenti valorojn kiuj estos uzataj por argumentoj: Ekzemple, \"node/%f/feed\"." + +#: includes/plugins.inc:2155 +msgid "Menu item entry" +msgstr "Menuera enskribo" + +#: includes/plugins.inc:2172 +msgid "No menu entry" +msgstr "Neniu menua enskribo" + +#: includes/plugins.inc:2173 +msgid "Normal menu entry" +msgstr "Normala menua enskribo" + +#: includes/plugins.inc:2174 +msgid "Menu tab" +msgstr "Menua langeto" + +#: includes/plugins.inc:2175 +msgid "Default menu tab" +msgstr "Defaŭlta menua langeto" + +#: includes/plugins.inc:2184 +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "Se agordita al normala aŭ langeto, enmetu la tekston por uzi por la menuero." + +#: includes/plugins.inc:2193 +msgid "If set to tab, enter the weight of the item. The lower the weight the higher/further left it will appear." +msgstr "Se agordita al langeto, enmetu la pezon de la ero. Ju pli malalta la pezo, des pli alta/pli dekstre ĝi aperos." + +#: includes/plugins.inc:2199 +msgid "Default tab options" +msgstr "Defaŭltaj langetaj opcioj" + +#: includes/plugins.inc:2208 +msgid "When providing a menu item as a 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>." +msgstr "Kiam provizante menueron kiel langeto, Drupalo devas scii kio estos la gepatra menuero de tiu langeto. Kelkfoje la gepatro jam ekzistos, sed alifoje vi devos krei ĝin. La vojo de gepatra ero ĉiam estos la sama vojo kun la lasta parto for. Ekz, se la vojo de ĉi tiu vojo estas <em>foo/bar/baz</em>, la patra vojo estos <em>foo/bar</em>" + +#: includes/plugins.inc:2219 +msgid "Parent menu item" +msgstr "Patra menuero" + +#: includes/plugins.inc:2221 +msgid "Already exists" +msgstr "Jam ekzistas" + +#: includes/plugins.inc:2221 +msgid "Normal menu item" +msgstr "Normala menuero" + +#: includes/plugins.inc:2229 +msgid "If creating a parent menu item, enter the title of the item." +msgstr "Se kreante patran menueron, enmetu la titolon de la ero." + +#: includes/plugins.inc:2235 +msgid "Tab weight" +msgstr "Langeta pezo" + +#: includes/plugins.inc:2239 +msgid "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." +msgstr "Se la patra menuero estas langeto, enmetu la pezon de la langeto. Ju pli malalta la numero, des pli dekstre ĝi estos." + +#: includes/plugins.inc:2253 +msgid "\"$arg\" is no longer supported. Use % instead." +msgstr "\"$arg\" ne plu estas subtenata. Anstataŭe uzu %." + +#: includes/plugins.inc:2263 +msgid "Views cannot create normal menu items for paths with a % in them." +msgstr "Aspektoj ne povas krei normalajn menuerojn por vojoj kun % en ili." + +#: includes/plugins.inc:2270 +msgid "A display whose path ends with a % cannot be a tab." +msgstr "Montro kies vojo finiĝas per % ne povas esti langeto." + +#: includes/plugins.inc:2275 +msgid "Title is required for this menu type." +msgstr "Titolo estas bezonata por ĉi tiu speco de menuo." + +#: includes/plugins.inc:2306 +msgid "Display @display is set to use a menu but the menu title is not set." +msgstr "Montro @display estas agordita por uzi menuon, sed ne ekzistas titolo de la menuo." + +#: includes/plugins.inc:2312 +msgid "Display @display is set to use a parent menu but the parent menu title is not set." +msgstr "Montro @display estas agordi por uzi gepatran menuon, sed ne ekzistas gepatra titolo de la menuo." + +#: includes/plugins.inc:2378 +msgid "Block settings" +msgstr "Agordoj de bloko" + +#: includes/plugins.inc:2392 +msgid "Admin" +msgstr "Admin" + +#: includes/plugins.inc:2416 +msgid "Do not cache" +msgstr "Ne kaŝmemorigu" + +#: includes/plugins.inc:2417 +msgid "Cache once for everything (global)" +msgstr "Kaŝmemorigu unufoje por ĉio (globala)" + +#: includes/plugins.inc:2418 +msgid "Per page" +msgstr "Por paĝo" + +#: includes/plugins.inc:2419 +msgid "Per role" +msgstr "Por rolo" + +#: includes/plugins.inc:2420 +msgid "Per role per page" +msgstr "Por rolo por paĝo" + +#: includes/plugins.inc:2421 +msgid "Per user" +msgstr "Por uzanto" + +#: includes/plugins.inc:2422 +msgid "Per user per page" +msgstr "Por uzanto por paĝo" + +#: includes/plugins.inc:2447 +msgid "Block admin description" +msgstr "Priskribo de bloka administranto" + +#: includes/plugins.inc:2450 +msgid "This will appear as the name of this block in administer >> site building >> blocks." +msgstr "Tio aperos kiel la nomo de ĉi tiu bloko en administri >> reteja konstruado >> blokoj." + +#: includes/plugins.inc:2455 +msgid "Block caching type" +msgstr "Bloka speco de kaŝmemorado" + +#: includes/plugins.inc:2459 +msgid "This sets the default status for Drupal's built-in block caching method; this requires that caching be turned on in block administration, and be careful because you have little control over when this cache is flushed." +msgstr "Tio agordas la defaŭltan staton por la enkonstruita blokokaŝada metodo de Drupalo; tio bezonatas ke kaŝmemorado estu ŝaltita en bloka administrado, kaj zorgi ĉar vi havas malmulte da rego super kiam tiu kaŝmemoro estas malplenigita." + +#: includes/plugins.inc:2511 +msgid "Before" +msgstr "Antaŭ" + +#: includes/plugins.inc:2512 +msgid "After" +msgstr "Post" + +#: includes/plugins.inc:2513 +msgid "Both" +msgstr "Ambaŭ" + +#: includes/plugins.inc:2533 +msgid "Attachment settings" +msgstr "Alkroĉaj agordoj" + +#: includes/plugins.inc:2538 +msgid "Inherit arguments" +msgstr "Heredaj argumentoj" + +#: includes/plugins.inc:2544 +msgid "Inherit exposed filters" +msgstr "Heredi montratajn filtrilojn" + +#: includes/plugins.inc:2550 +msgid "Position" +msgstr "Pozicio" + +#: includes/plugins.inc:2556 +msgid "Multiple displays" +msgstr "Multajn montrojn" + +#: includes/plugins.inc:2571 +msgid "Attach to" +msgstr "Alkroĉi al" + +#: includes/plugins.inc:2588 +msgid "Inherit" +msgstr "Heredi" + +#: includes/plugins.inc:2589 +msgid "Should this display inherit its arguments from the parent display to which it is attached?" +msgstr "Ĉu ĉi tiu montro heredu ĝiajn argumentojn de la patra montro al kiu ĝi estas alkroĉita?" + +#: includes/plugins.inc:2598 +msgid "Should this display inherit its exposed filter values from the parent display to which it is attached?" +msgstr "Ĉu ĉi tiu montro heredu ĝiajn montratajn filtrajn valorojn de la patra montro al kiu ĝi estas alkroĉita?" + +#: includes/plugins.inc:2606 +msgid "Attach before or after the parent display?" +msgstr "Alkroĉi antaŭ aŭ post la patra montro?" + +#: includes/plugins.inc:2621 +msgid "Select which display or displays this should attach to." +msgstr "Elektu kiun montron aŭ montrojn al kiu ĝi devas alkroĉi." + +#: includes/plugins.inc:2776 +msgid "Feed settings" +msgstr "Fluaj agordoj" + +#: includes/plugins.inc:2780 +msgid "Using the site name" +msgstr "Uzante la retejan nomon" + +#: includes/plugins.inc:2822 +msgid "Use the site name for the title" +msgstr "Uzi la retejan nomon por la titolo" + +#: includes/plugins.inc:2845 +msgid "This view will be displayed by visiting this path on your site. It is recommended that the path be something like \"path/%/%/feed\" or \"path/%/%/rss.xml\", putting one % in the path for each argument you have defined in the view." +msgstr "Ĉi tiu aspekto montriĝos per vizito de ĉi tiu vojo en via retejo. Estas rekomentia ke la vojo estu kiel \"vojo/%/%/fluo\" aŭ "\vojo/%/%/rss.xml\", metante unu % en la vojo por ĉiu argumento kiun vi difinis en la aspekto. " + +#: includes/plugins.inc:2990 +msgid "Grouping field" +msgstr "Grupigi kampon" + +#: includes/plugins.inc:2993 +msgid "You may optionally specify a field by which to group the records. Leave blank to not group." +msgstr "Vi povas nedevige indiki kampon per kiu grupigi la rikordojn. Lasu malplena por ne grupigi." + +#: includes/plugins.inc:3081 +msgid "Style @style requires a row style but the row plugin is invalid." +msgstr "Stilo @style bezonas vican stilon, sed la vica kromprogramo estas nevalida." + +#: includes/plugins.inc:3128 +msgid "List type" +msgstr "Lista speco" + +#: includes/plugins.inc:3158 +msgid "Number of columns" +msgstr "Nombro da kolumnoj" + +#: includes/plugins.inc:3163 +msgid "Alignment" +msgstr "Ĝisrandigo" + +#: includes/plugins.inc:3164 +msgid "Horizontal" +msgstr "Horizontale" + +#: includes/plugins.inc:3164 +msgid "Vertical" +msgstr "Vertikale" + +#: includes/plugins.inc:3166 +msgid "Horizontal alignment will place items starting in the upper left and moving right. Vertical alignment will place items starting in the upper left and moving down." +msgstr "Horizontala ĝisrandigo lokigos erojn komencante en la supra maldesktra angulo kaj iras dekstren. Vertikala ĝisrandigo lokigos erojn en la supra maldekstra angulo kaj subiras." + +#: includes/plugins.inc:3285 +msgid "You need at least one field before you can configure your table settings" +msgstr "Vi bezonas almenaŭ unu kampon antaŭ ol vi povas agordi vian tabelon." + +#: includes/plugins.inc:3294 +msgid "Override normal sorting if click sorting is used" +msgstr "Anstataŭigi normalan ordigon se klaka ordigo estas uzata" + +#: includes/plugins.inc:3300 +msgid "Enable Drupal style \"sticky\" table headers (Javascript)" +msgstr "Ŝalti Drupal-stilan \"fiksa\" tabelaj kaplinioj (JavaSkripto)" + +#: includes/plugins.inc:3302 +msgid "(Sticky header effects will not be active for preview below, only on live output.)" +msgstr "(Fiksita kapliniaj efikoj ne aktivos por la antaŭvido sube, nur en viva eligo.)" + +#: includes/plugins.inc:3307 +msgid "Default sort order" +msgstr "Defaŭlta ordiga sinsekvo" + +#: includes/plugins.inc:3308 +#: includes/sort.handlers.inc:60 +msgid "Ascending" +msgstr "Kreskante" + +#: includes/plugins.inc:3308 +#: includes/sort.handlers.inc:60 +msgid "Descending" +msgstr "Malkreskante" + +#: includes/plugins.inc:3310 +msgid "If a default sort order is selected, what order should it use by default." +msgstr "Se defaŭlta ordiga sinsekvo estas elektita, kiun ordigon ĝi uzu defaŭlte." + +#: includes/plugins.inc:3396 +msgid "Place fields into columns; you may combine multiple fields into the same column. If you do, the separator in the column specified will be used to separate the fields. Check the sortable box to make that column click sortable, and check the default sort radio to determine which column will be sorted by default, if any. You may control column order and field labels in the fields section." +msgstr "Lokigi kampojn en kolumnojn; vi povas kombini multajn kampojn en la saman kolumnon. Se vi faras, la disigilo en la kolumno indikita estos uzata por disigi la kampojn. Kontrolu la ordigeblan skatolon por certigi ke tiu kolumo ordigeblos, kaj ŝaltu la defaŭltan ordigan radion por determini kiun kolumnon ordiĝos defaŭlte, se iun. Vi povas regi kolumnan sinsekvon kaj kampajn enketojn en la kampa sekcio." + +#: includes/plugins.inc:3421 +#: includes/view.inc:1769 +msgid "Field" +msgstr "Kampo" + +#: includes/plugins.inc:3422 +msgid "Column" +msgstr "Propra" + +#: includes/plugins.inc:3425 +msgid "Sortable" +msgstr "Ordigebla" + +#: includes/plugins.inc:3429 +msgid "Default sort" +msgstr "Defaŭlta ordigo" + +#: includes/plugins.inc:3488 +msgid "Display record count with link" +msgstr "Montri rikordan kalkulon kun ligilo" + +#: includes/plugins.inc:3493 +msgid "Override number of items to display" +msgstr "Anstataŭigi nombron da eroj por montri" + +#: includes/plugins.inc:3530 +msgid "Display items inline" +msgstr "Montri erojn entekste" + +#: includes/plugins.inc:3580 +msgid "Use the site mission for the description" +msgstr "Uzu la retejan mision por la priskribo" + +#: includes/plugins.inc:3584 +msgid "RSS description" +msgstr "RSS-priskribo" + +#: includes/plugins.inc:3586 +msgid "This will appear in the RSS feed itself." +msgstr "Ĉi tio aperos en la RSS-fluo mem." + +#: includes/plugins.inc:3709 +msgid "Inline fields" +msgstr "Entekstaj kampoj" + +#: includes/plugins.inc:3712 +msgid "Inline fields will be displayed next to each other rather than one after another." +msgstr "Entekstaj kampoj montriĝos apud unu la alia anstataŭ unu post la alia." + +#: includes/plugins.inc:3720 +msgid "The separator may be placed between inline fields to keep them from squishing up next to each other. You can use HTML in this field." +msgstr "La disigilo povas lokiĝi inter entekstaj kampoj por certigi ke ili ne aperas tuj apud unu la alia. Vi povas uzi HTML-n en ĉi tiu kampo." + +#: includes/plugins.inc:3770 +msgid "Default argument" +msgstr "Defaŭlta argumento" + +#: includes/plugins.inc:3792 +msgid "Note: you do not have permission to modify this. If you change the default argument type, this setting will be lost and you will NOT be able to get it back." +msgstr "Notu: vi ne havas permeson modifi ĉi tion. Se vi ŝanĝas la defaŭltan argumentan specon, ĉi tiu agordo estos perdita kaj vi NE povos rehavi ĝin." + +#: includes/plugins.inc:3813 +msgid "PHP argument code" +msgstr "Argumenta kodo de PHP" + +#: includes/plugins.inc:3816 +msgid "Enter PHP code that returns a value to use for this argument. Do not use <?php ?>. You must return only a single value for just this argument." +msgstr "Enmetu PHP-kodon kiu revenigas valoron por uzi por ĉi tiu argumento. Ne uzu <?php ?> Vi devas revenigi nur unu valoron por precize ĉi tiu argumento." + +#: includes/plugins.inc:3896 +msgid "Note: you do not have permission to modify this. If you change the validator, this setting will be lost and you will NOT be able to get it back." +msgstr "Rimarku: vi ne havas permeson modifi ĉi tion. Se vi ŝanĝas la validigilon, ĉi tiu agordo estos perdita kaj vi NE povos rehavi ĝin." + +#: includes/plugins.inc:3921 +msgid "PHP validate code" +msgstr "Validigi kodon de PHP" + +#: includes/plugins.inc:3923 +msgid "Enter PHP code that returns TRUE or FALSE. No return is the same as FALSE, so be SURE to return something if you do not want to declare the argument invalid. Do not use <?php ?>. The argument to validate will be \"$argument\" and the view will be \"$view\". You may change the argument by setting \"$handler->argument\"." +msgstr "Enmetu PHP-kodon kiu revenas TRUE aŭ FALSE. Neniu reveno estas la sama kiel FALSE, do CERTE revenigu ion se vi volas volas deklari la argumenton nevalida. Ne uzu <?php ?>. La argumento por validigi estos \"$argument\" kaj la montro estos \"$view\". Vi rajtas ŝanĝi la argumenton agordante \"$handler->argument\"." + +#: includes/relationship.handlers.inc:80 +msgid "The label for this relationship that will be displayed only administratively." +msgstr "La enketo por ĉi tiu rilato kiu montriĝos nur administre." + +#: includes/relationship.handlers.inc:85 +msgid "Require this relationship" +msgstr "Bezoni ĉi tiun rilaton" + +#: includes/relationship.handlers.inc:86 +msgid "If required, items that do not contain this relationship will not appear." +msgstr "Se bezonata, eroj kiuj ne enhavas ĉi tiun rilaton ne aperos." + +#: includes/sort.handlers.inc:43 +msgid "asc" +msgstr "kresk" + +#: includes/sort.handlers.inc:47 +msgid "desc" +msgstr "malkresk" + +#: includes/sort.handlers.inc:59 +msgid "Sort order" +msgstr "Ordiga sinsekvo" + +#: includes/sort.handlers.inc:108 +msgid "views_handler_sort_formula missing default: @formula" +msgstr "views_handler_sort_formula mankante defaŭlto: @formula" + +#: includes/sort.handlers.inc:148 +msgid "Granularity" +msgstr "Granuleco" + +#: includes/sort.handlers.inc:150 +msgid "Second" +msgstr "Sekundo" + +#: includes/sort.handlers.inc:151 +msgid "Minute" +msgstr "Minuto" + +#: includes/sort.handlers.inc:152 +msgid "Hour" +msgstr "Horo" + +#: includes/sort.handlers.inc:153 +msgid "Day" +msgstr "Tago" + +#: includes/sort.handlers.inc:154 +msgid "Month" +msgstr "Monato" + +#: includes/sort.handlers.inc:155 +msgid "Year" +msgstr "Jaro" + +#: includes/sort.handlers.inc:157 +msgid "The granularity is the smallest unit to use when determining whether two dates are the same; for example, if the granularity is \"Year\" then all dates in 1999, regardless of when they fall in 1999, will be considered the same date." +msgstr "La granuleco estas la plej malgranda unuo por uzi kiam determinante ĉu du datoj estas la samaj; ekzemple, se la granuleco estas \"Jaro\" tiam ĉiuj datoj en 1999, egale de kiam ili estas en 1999, estos konsiderataj la sama dato." + +#: includes/view.inc:255 +msgid "set_display called with invalid display id @display" +msgstr "set_display vokita kun nevalida montra id @display" + +#: includes/view.inc:995 +msgid "Home" +msgstr "Hejmo" + +#: includes/view.inc:1768 +msgid "fields" +msgstr "kampoj" + +#: includes/view.inc:1770 +msgid "field" +msgstr "kampo" + +#: includes/view.inc:1775 +msgid "arguments" +msgstr "argumentoj" + +#: includes/view.inc:1776 +msgid "Argument" +msgstr "Argumento" + +#: includes/view.inc:1781 +msgid "Sort criteria" +msgstr "Ordiga kriterioj" + +#: includes/view.inc:1782 +msgid "sort criteria" +msgstr "ordiga kriterioj" + +#: includes/view.inc:1783 +msgid "Sort criterion" +msgstr "Ordiga kriterio" + +#: includes/view.inc:1784 +msgid "sort criterion" +msgstr "ordiga kriterio" + +#: includes/view.inc:1788 +msgid "Filters" +msgstr "Filtriloj" + +#: includes/view.inc:1789 +msgid "filters" +msgstr "filtriloj" + +#: includes/view.inc:1790 +msgid "Filter" +msgstr "Filtrilo" + +#: includes/view.inc:1791 +msgid "filter" +msgstr "filtrilo" + +#: includes/view.inc:1796 +msgid "Relationships" +msgstr "Rilatoj" + +#: includes/view.inc:1797 +msgid "relationships" +msgstr "rilatoj" + +#: js/ajax.js:0 +#: js/ajax_view.js:0 +msgid "An error occurred at " +msgstr "Eraro okazis ĉe" + +#: js/tabs.js:0 +msgid "jQuery UI Tabs: Mismatching fragment identifier." +msgstr "jQuery UI Langetoj: Miskongrua fragmenta identigilo." + +#: js/tabs.js:0 +msgid "jQuery UI Tabs: Not enough arguments to add tab." +msgstr "jQuery UI Langetoj: Ne sufiĉe da argumentoj por aldoni langeton." + +#: modules/book.views.inc:21 +msgid "Book" +msgstr "Libro" + +#: modules/book.views.inc:30 +msgid "Top level book" +msgstr "Plej altnivela libro" + +#: modules/book.views.inc:31 +msgid "The book the node is in." +msgstr "La libro en kiu la nodo estas." + +#: modules/book.views.inc:58 +msgid "The weight of the book page." +msgstr "La pezo de la libra paĝo." + +#: modules/book.views.inc:69 +#: modules/comment.views.inc:202 +#: modules/taxonomy.views.inc:310 +msgid "Depth" +msgstr "Profundeco" + +#: modules/book.views.inc:70 +msgid "The depth of the book page in the hierarchy; top level books have a depth of 1." +msgstr "La profundeco de la libra paĝo en la hierarkio; plej altnivelaj libroj havas profundecon de 1." + +#: modules/book.views.inc:87 +msgid "Hierarchy" +msgstr "Hierarkio" + +#: modules/book.views.inc:88 +msgid "The order of pages in the book hierarchy. Remember to sort by weight too if you want exactly the right order." +msgstr "La sinsekvo de paĝoj en la libra hierarkio. Memoru ordigi ankaŭ laŭ pezo se vi volas precize la ĝustan sinsekvon." + +#: modules/book.views.inc:110 +msgid "Parent" +msgstr "Gepatra" + +#: modules/book.views.inc:111 +msgid "The parent book node." +msgstr "La gepatra libra nodo." + +#: modules/book.views.inc:116 +msgid "Book parent" +msgstr "Libra gepatro" + +#: modules/comment.views.inc:22 +msgid "Comment" +msgstr "Komento" + +#: modules/comment.views.inc:27 +msgid "Comments are responses to node content." +msgstr "Komentoj estas respondoj al noda enhavo." + +#: modules/comment.views.inc:45 +msgid "The title of the comment." +msgstr "La titolo de la komento." + +#: modules/comment.views.inc:63 +#: modules/node.views.inc:366 +msgid "Body" +msgstr "Korpo" + +#: modules/comment.views.inc:64 +msgid "The text of the comment." +msgstr "La teksto de la komento." + +#: modules/comment.views.inc:76 +msgid "ID" +msgstr "ID" + +#: modules/comment.views.inc:77 +msgid "The comment ID of the field" +msgstr "La komenta ID de la kampo" + +#: modules/comment.views.inc:95 +msgid "Author" +msgstr "Aŭtoro" + +#: modules/comment.views.inc:96 +msgid "The name of the poster." +msgstr "La nomo de la afiŝinto." + +#: modules/comment.views.inc:114 +msgid "Author's website" +msgstr "Aŭtora retejo" + +#: modules/comment.views.inc:115 +msgid "The website address of the comment's author. Can be a link. The homepage can also be linked with the Name field. Will be empty if posted by a registered user." +msgstr "La reteja adreso de la komenta aŭtoro. Povas esti ligilo. La hejmpaĝo ankaŭ povas esti ligita kun la Noma kampo. Malplenos se afiŝita de registrita uzanto." + +#: modules/comment.views.inc:133 +#: modules/node.views.inc:107 +msgid "Post date" +msgstr "Afiŝa dato" + +#: modules/comment.views.inc:134 +msgid "Date and time of when the comment was posted." +msgstr "Dato kaj tempo kiam la komento estis afiŝita." + +#: modules/comment.views.inc:149 +msgid "In moderation" +msgstr "Prizorgata" + +#: modules/comment.views.inc:150 +msgid "Whether or not the comment is currently in moderation." +msgstr "Ĉu aŭ ne la komento estas nun en moderado." + +#: modules/comment.views.inc:157 +#: modules/node.views.inc:203 +msgid "Moderated" +msgstr "Prizorgita" + +#: modules/comment.views.inc:167 +msgid "View link" +msgstr "Vidi ligilon" + +#: modules/comment.views.inc:168 +msgid "Provide a simple link to view the comment." +msgstr "Provizi simplan ligilon por vidi la komenton." + +#: modules/comment.views.inc:176 +#: modules/node.views.inc:249 +#: modules/user.views.inc:204 +msgid "Edit link" +msgstr "Redakti ligilon" + +#: modules/comment.views.inc:177 +msgid "Provide a simple link to edit the comment." +msgstr "Provizi simplan ligilon por redakti la komenton." + +#: modules/comment.views.inc:185 +#: modules/node.views.inc:257 +#: modules/user.views.inc:212 +msgid "Delete link" +msgstr "Forigi ligilon" + +#: modules/comment.views.inc:186 +msgid "Provide a simple link to delete the comment." +msgstr "Provizi simplan ligilon por forigi la komenton." + +#: modules/comment.views.inc:194 +msgid "Reply-to link" +msgstr "Respondi-al ligilo" + +#: modules/comment.views.inc:195 +msgid "Provide a simple link to reply to the comment." +msgstr "Provizi simplan ligilon por respondi al la komento." + +#: modules/comment.views.inc:203 +msgid "Display the depth of the comment if it is threaded." +msgstr "Montri la profundecon de la komento se ĝi estas fadenita." + +#: modules/comment.views.inc:207 +msgid "Thread" +msgstr "Fadeno" + +#: modules/comment.views.inc:208 +msgid "Sort by the threaded order. This will keep child comments together with their parents." +msgstr "Ordigi laŭ la fadena sinsekvo. Tio tenos idajn komentojn kune kun siaj patroj." + +#: modules/comment.views.inc:214 +#: modules/node.views.inc:24 +#: modules/upload.views.inc:43 +msgid "Node" +msgstr "Nodo" + +#: modules/comment.views.inc:215 +msgid "The node the comment is a reply to." +msgstr "La nodo al kiu komento estas respondo." + +#: modules/comment.views.inc:225 +#: modules/node.views.inc:353 +#: modules/statistics.views.inc:201 +#: modules/user.views.inc:23 +msgid "User" +msgstr "Uzanto" + +#: modules/comment.views.inc:226 +msgid "The user who wrote the comment." +msgstr "La uzanto kiu skribis la komenton." + +#: modules/comment.views.inc:236 +msgid "Parent CID" +msgstr "Patra CID" + +#: modules/comment.views.inc:237 +msgid "The Comment ID of the parent comment." +msgstr "La komenta ID de la patra komento." + +#: modules/comment.views.inc:242 +msgid "Parent comment" +msgstr "Patra komento" + +#: modules/comment.views.inc:243 +msgid "The parent comment." +msgstr "La gepatra komento." + +#: modules/comment.views.inc:268 +msgid "Last comment time" +msgstr "Lasta komenta tempo" + +#: modules/comment.views.inc:269 +msgid "Date and time of when the last comment was posted." +msgstr "Dato kaj tempo de kiam la lasta komento estis afiŝita." + +#: modules/comment.views.inc:284 +msgid "Last comment author" +msgstr "Lasta komento de aŭtoro" + +#: modules/comment.views.inc:285 +msgid "The name of the author of the last posted comment." +msgstr "La nomo de la aŭtoro de la laste afiŝita komento." + +#: modules/comment.views.inc:297 +msgid "Comment count" +msgstr "Kvanto da komentoj" + +#: modules/comment.views.inc:298 +msgid "The number of comments a node has." +msgstr "La nombro da komentoj kiun nodo havas." + +#: modules/comment.views.inc:316 +msgid "Updated/commented date" +msgstr "Ĝisdatigita/komentita dato" + +#: modules/comment.views.inc:317 +msgid "The most recent of last comment posted or node updated time." +msgstr "La plej lasta de lasta komento afiŝita aŭ nodo ĝisdatigita tempo." + +#: modules/comment.views.inc:340 +msgid "New comments" +msgstr "Novaj komentoj" + +#: modules/comment.views.inc:341 +msgid "The number of new comments on the node." +msgstr "La nombro da novaj komentoj en la nodo." + +#: modules/comment.views.inc:349 +msgid "Comment status" +msgstr "Komenta stato" + +#: modules/comment.views.inc:350 +msgid "Whether comments are enabled or disabled on the node." +msgstr "Ĉu komentoj estas ŝaltitaj aŭ malŝaltitaj en la nodo." + +#: modules/comment.views.inc:364 +msgid "User posted or commented" +msgstr "Uzanto afiŝis aŭ komentis" + +#: modules/comment.views.inc:365 +msgid "Display comments only if a user posted the node or commented on the node." +msgstr "Montri komentojn nur se uzanto afiŝis la nodon aŭ komentis en la nodo." + +#: modules/comment.views.inc:385 +msgid "Display the comment with standard comment view." +msgstr "Montri la komenton kun norma komenta montro." + +#: modules/comment.views.inc:394 +msgid "Display the comment as RSS." +msgstr "Montri la komenton kiel RSS." + +#: modules/comment.views.inc:462 +msgid "Link this field to its comment" +msgstr "Ligi ĉi tiun kampon al ĝia komento" + +#: modules/comment.views.inc:504 +msgid "Link this field to its user or an author's homepage" +msgstr "Ligi ĉi tiun kampon al ĝia uzanto aŭ aŭtora hejmpaĝo" + +#: modules/comment.views.inc:549 +#: modules/node.views.inc:611 +#: modules/user.views.inc:452 +msgid "Text to display" +msgstr "Teksto por montri" + +#: modules/comment.views.inc:560 +#: modules/node.views.inc:622 +#: modules/user.views.inc:468 +msgid "view" +msgstr "vidi" + +#: modules/comment.views.inc:583 +#: modules/node.views.inc:651 +#: modules/user.views.inc:484 +msgid "edit" +msgstr "redakti" + +#: modules/comment.views.inc:597 +#: modules/node.views.inc:679 +#: modules/user.views.inc:500 +msgid "delete" +msgstr "forigi" + +#: modules/comment.views.inc:611 +msgid "reply" +msgstr "respondi" + +#: modules/comment.views.inc:742 +msgid "Link this field to new comments" +msgstr "Ligi ĉi tiun kampon al novaj komentoj" + +#: modules/comment.views.inc:747 +msgid "Display nothing if no new comments" +msgstr "Montri nenion se neniuj novaj komentoj" + +#: modules/comment.views.inc:812 +#: modules/user.views.inc:599 +msgid "Anonymous" +msgstr "Anonima" + +#: modules/comment.views.inc:818 +msgid "No user" +msgstr "Neniu uzanto" + +#: modules/comment.views.inc:852 +msgid "Disabled" +msgstr "Malŝaltita" + +#: modules/comment.views.inc:854 +msgid "Read only" +msgstr "Nur-legi" + +#: modules/comment.views.inc:856 +msgid "Read/Write" +msgstr "Legi/Modifi" + +#: modules/comment.views.inc:887 +#: modules/node.views.inc:1207 +msgid "Display links" +msgstr "Montri ligilojn" + +#: modules/node.views.inc:30 +msgid "Nodes are a Drupal site's primary content." +msgstr "Nodoj estas ĉefa enhavo de Drupala retejo." + +#: modules/node.views.inc:57 +msgid "Nid" +msgstr "Nid" + +#: modules/node.views.inc:58 +msgid "The node ID of the node." +msgstr "La noda ID de la nodo." + +#: modules/node.views.inc:85 +msgid "The title of the node." +msgstr "La titolo de la nodo." + +#: modules/node.views.inc:108 +msgid "The date the node was posted." +msgstr "La dato kiam la nodo estis afiŝita." + +#: modules/node.views.inc:123 +msgid "Updated date" +msgstr "Ĝisdatigita dato" + +#: modules/node.views.inc:124 +msgid "The date the node was last updated." +msgstr "La dato kiam la nodo estis laste ĝisdatigita." + +#: modules/node.views.inc:140 +msgid "The type of a node (for example, \"blog entry\", \"forum post\", \"story\", etc)." +msgstr "La speco de nodo (ekzemple, \"blog-enskribo\", \"forum-afiŝo\", \"rakonto\", ktp)" + +#: modules/node.views.inc:158 +#: modules/upload.views.inc:82 +msgid "Published" +msgstr "Publikigita" + +#: modules/node.views.inc:159 +msgid "The published status of the node." +msgstr "La eldona stato de la nodo." + +#: modules/node.views.inc:175 +msgid "Published or admin" +msgstr "Eldonita aŭ admin" + +#: modules/node.views.inc:176 +msgid "Filters out unpublished nodes if the current user cannot view them." +msgstr "Elfiltras neeldonitajn nodojn se la nuna uzanto ne povas vidi ilin." + +#: modules/node.views.inc:186 +msgid "Promoted to front page" +msgstr "Promociita al ĉefpaĝo" + +#: modules/node.views.inc:187 +msgid "The front page of the node." +msgstr "La ĉefpaĝo de la nodo." + +#: modules/node.views.inc:204 +msgid "Whether or not the node is moderated." +msgstr "Ĉu aŭ ne la nodo estas moderata." + +#: modules/node.views.inc:221 +msgid "Sticky" +msgstr "Fiksita" + +#: modules/node.views.inc:222 +msgid "Whether or not the node is sticky." +msgstr "Ĉu aŭ ne la nodo estas fiksita." + +#: modules/node.views.inc:241 +msgid "Link" +msgstr "Ligilo" + +#: modules/node.views.inc:242 +msgid "Provide a simple link to the node." +msgstr "Provizi simplan ligilon al la nodo." + +#: modules/node.views.inc:250 +msgid "Provide a simple link to edit the node." +msgstr "Provizi simplan ligilon por redakti la nodon." + +#: modules/node.views.inc:258 +msgid "Provide a simple link to delete the node." +msgstr "Provizi simplan ligilon por forigi la nodon." + +#: modules/node.views.inc:266 +msgid "Language" +msgstr "Lingvo" + +#: modules/node.views.inc:267 +msgid "The language the content is in." +msgstr "La lingvo de la enhavo." + +#: modules/node.views.inc:284 +#: modules/user.views.inc:125 +msgid "Created date" +msgstr "Kreita dato" + +#: modules/node.views.inc:285 +msgid "In the form of CCYYMMDD." +msgstr "en la formo de CCYYMMDD." + +#: modules/node.views.inc:293 +msgid "Created year + month" +msgstr "Kreita jaro + monato" + +#: modules/node.views.inc:294 +msgid "In the form of YYYYMM." +msgstr "En la formo de YYYYMM." + +#: modules/node.views.inc:302 +msgid "Created year" +msgstr "Kreita jaro" + +#: modules/node.views.inc:303 +msgid "In the form of YYYY." +msgstr "En la formo de YYYY." + +#: modules/node.views.inc:311 +msgid "Created month" +msgstr "Kreita monato" + +#: modules/node.views.inc:312 +msgid "In the form of MM (01 - 12)." +msgstr "En la formo de MM (01 - 12)." + +#: modules/node.views.inc:320 +msgid "Created week" +msgstr "Kreita semajno" + +#: modules/node.views.inc:321 +msgid "In the form of WW (01 - 53)." +msgstr "En la formo de WW (01 - 53)." + +#: modules/node.views.inc:333 +msgid "Node revision" +msgstr "Noda revizio" + +#: modules/node.views.inc:339 +msgid "Node revisions are a history of changes to nodes." +msgstr "Nodaj revizioj estas historio de ŝanĝoj al nodoj." + +#: modules/node.views.inc:354 +msgid "Relate a node revision to the user who created the revision." +msgstr "Rilatu nodan rivizion al la uzanto kiu kreis la revizion." + +#: modules/node.views.inc:359 +msgid "user" +msgstr "uzanto" + +#: modules/node.views.inc:367 +msgid "The actual, full data in the body field; this may not be valid data on all node types." +msgstr "La veraj, plenaj datumoj en la korpa kampo; tio eble ne estas validaj datumoj por ĉiuj nodaj specoj." + +#: modules/node.views.inc:381 +msgid "Teaser" +msgstr "Resumo" + +#: modules/node.views.inc:382 +msgid "The stored teaser field. This may not be valid or useful data on all node types." +msgstr "La konservita resuma kampo. Tio eble ne estas validaj aŭ utilaj datumoj por ĉiuj nodaj specoj. " + +#: modules/node.views.inc:395 +msgid "Vid" +msgstr "Vid" + +#: modules/node.views.inc:396 +msgid "The revision ID of the node revision." +msgstr "La revizia ID de la noda revizio." + +#: modules/node.views.inc:441 +msgid "Log message" +msgstr "Protokola mesaĝo" + +#: modules/node.views.inc:442 +msgid "The log message entered when the revision was created." +msgstr "La protokola mesaĝo enmetita kiam la revizio estis kreita." + +#: modules/node.views.inc:456 +msgid "The date the node revision was created." +msgstr "La dato kiam la noda revizio estis kreita." + +#: modules/node.views.inc:471 +msgid "Revert link" +msgstr "Ligilo por malfari ŝanĝojn" + +#: modules/node.views.inc:472 +msgid "Provide a simple link to revert to the revision." +msgstr "Provizi simplan ligilon por malfari ŝanĝojn al la revizio." + +#: modules/node.views.inc:480 +msgid "Provide a simple link to delete the node revision." +msgstr "Provizi simplan ligilon por forigi la nodan revizion." + +#: modules/node.views.inc:507 +msgid "Has new content" +msgstr "Havas novan enhavon" + +#: modules/node.views.inc:510 +msgid "Show a marker if the node has new or updated content." +msgstr "Montri markilon se la nodo havas novan aŭ ĝisdatigitan enhavon." + +#: modules/node.views.inc:513 +msgid "Show only nodes that have new content." +msgstr "Montri nur nodojn kiuj havas novan enhavon." + +#: modules/node.views.inc:544 +msgid "Link this field to its node" +msgstr "Ligi ĉi tiun kampon al ĝia nodo" + +#: modules/node.views.inc:717 +msgid "revert" +msgstr "malfari ŝanĝojn" + +#: modules/node.views.inc:788 +msgid "Check for new comments as well" +msgstr "Kontrolu ankaŭ por novaj komentoj" + +#: modules/node.views.inc:858 +msgid "Unknown node type" +msgstr "Nekonata noda speco" + +#: modules/node.views.inc:1027 +msgid "Week @week" +msgstr "Semajno @week" + +#: modules/node.views.inc:1037 +msgid "Node type" +msgstr "Noda speco" + +#: modules/node.views.inc:1094 +msgid "Current user's language" +msgstr "Lingvo de nuna uzanto" + +#: modules/node.views.inc:1094 +msgid "No language" +msgstr "Neniu lingvo" + +#: modules/node.views.inc:1140 +msgid "Unknown language" +msgstr "Nekonata lingvo" + +#: modules/node.views.inc:1153 +msgid "Display the node with standard node view." +msgstr "Montri la nodon kun norma noda montro." + +#: modules/node.views.inc:1177 +msgid "Node ID from URL" +msgstr "Noda ID de URL" + +#: modules/node.views.inc:1202 +msgid "Display only teaser" +msgstr "Montri nur resumon" + +#: modules/node.views.inc:1261 +msgid "Full text" +msgstr "Plena teksto" + +#: modules/node.views.inc:1262 +msgid "Title plus teaser" +msgstr "Titolo plus resumo" + +#: modules/node.views.inc:1263 +msgid "Title only" +msgstr "Nur titolo" + +#: modules/node.views.inc:1264 +msgid "Use default RSS settings" +msgstr "Uzi defaŭltajn RSS-agordojn" + +#: modules/node.views.inc:1330 +msgid "read more" +msgstr "legi pli" + +#: modules/node.views.inc:1363 +msgid "Types" +msgstr "Specoj" + +#: modules/node.views.inc:1366 +msgid "If you wish to validate for specific node types, check them; if none are checked, all nodes will pass." +msgstr "Se vi deziras validigi specifajn nodajn specojn, kontrolu ilin; se neniu estas ŝaltita, ĉiuj nodoj sukcesos." + +#: modules/node.views.inc:1373 +msgid "Validate user has access to the node" +msgstr "Validiga uzanto povas aliri la nodon" + +#: modules/node.views.inc:1381 +#: modules/taxonomy.views.inc:1015 +msgid "Argument type" +msgstr "Argumenta speco" + +#: modules/node.views.inc:1383 +msgid "Node ID" +msgstr "Noda ID" + +#: modules/node.views.inc:1384 +msgid "Node IDs separated by , or +" +msgstr "Nodaj ID-oj disigitaj per , aŭ +" + +#: modules/node.views.inc:1507 +msgid "Display %display has no access control but does not contain a filter for published nodes." +msgstr "Montro %display ne havas aliran regadon, sed ne enhavas filtrilon por eldonitaj nodoj." + +#: modules/poll.views.inc:23 +msgid "Poll" +msgstr "Enketo" + +#: modules/poll.views.inc:38 +#: modules/user.views.inc:173 +msgid "Active" +msgstr "Aktiva" + +#: modules/poll.views.inc:39 +msgid "Whether the poll is open for voting." +msgstr "Ĉu la enketo estas malfermita por voĉdonado." + +#: modules/profile.views.inc:20 +msgid "Profile" +msgstr "Profilo" + +#: modules/profile.views.inc:100 +msgid "@field-name" +msgstr "@field-name" + +#: modules/profile.views.inc:107 +msgid "Profile textfield" +msgstr "Profila tekstkampo" + +#: modules/profile.views.inc:126 +msgid "Profile textarea" +msgstr "Profila tekstareo" + +#: modules/profile.views.inc:142 +msgid "Profile checkbox" +msgstr "Profila markobutono" + +#: modules/profile.views.inc:159 +msgid "Profile URL" +msgstr "Profila URL" + +#: modules/profile.views.inc:175 +msgid "Profile selection" +msgstr "Profila elektado" + +#: modules/profile.views.inc:195 +msgid "Profile freeform list %field-name." +msgstr "Profila liberforma listo %field-name." + +#: modules/profile.views.inc:207 +msgid "Profile date %field-name." +msgstr "Profila dato %field-name." + +#: modules/search.views.inc:23 +msgid "Search" +msgstr "Serĉi" + +#: modules/search.views.inc:72 +msgid "Score" +msgstr "Poentaro" + +#: modules/search.views.inc:73 +msgid "The score of the search item." +msgstr "La poentaro de la serĉero." + +#: modules/search.views.inc:95 +msgid "Links from" +msgstr "Ligiloj de" + +#: modules/search.views.inc:96 +msgid "Nodes that link from the node." +msgstr "Nodoj kiuj ligas de la nodo." + +#: modules/search.views.inc:113 +msgid "Links to" +msgstr "Ligiloj al" + +#: modules/search.views.inc:114 +msgid "Nodes that link to the node." +msgstr "Nodoj kiuj ligas al la nodo." + +#: modules/search.views.inc:125 +msgid "Search Terms" +msgstr "Serĉaj Terminoj" + +#: modules/search.views.inc:126 +msgid "The terms to search for." +msgstr "La terminoj por serĉi." + +#: modules/search.views.inc:155 +msgid "On empty input" +msgstr "Per malplena enmeto" + +#: modules/search.views.inc:158 +msgid "Show All" +msgstr "Montri ĉiujn" + +#: modules/search.views.inc:159 +msgid "Show None" +msgstr "Montri nenion" + +#: modules/search.views.inc:173 +msgid "Enter the terms you wish to search for." +msgstr "Enmetu la terminojn kiujn vi deziras serĉi." + +#: modules/search.views.inc:188 +msgid "You must include at least one positive keyword with @count characters or more." +msgstr "Vi devas inkluzivi almenaŭ unu pozitivan ŝlosilvorton kun @count signoj aŭ pli." + +#: modules/search.views.inc:192 +msgid "Search for either of the two terms with uppercase <strong>OR</strong>. For example, <strong>cats OR dogs</strong>." +msgstr "Serĉi por unu el la du terminoj kun majuskla <strong>OR</strong>. Ekzemple, <strong>katoj OR hundoj</strong>." + +#: modules/search.views.inc:245 +msgid "Display the results with standard search view." +msgstr "Montri la rezultojn per norma serĉa montro." + +#: modules/search.views.inc:269 +msgid "Display score" +msgstr "Montri poentaron" + +#: modules/statistics.views.inc:24 +msgid "Node statistics" +msgstr "Noda statistiko" + +#: modules/statistics.views.inc:36 +msgid "Total views" +msgstr "Ĉiuj vidoj" + +#: modules/statistics.views.inc:37 +msgid "The total number of times the node has been viewed." +msgstr "La tuta nombro da fojoj la nodo estas vidita." + +#: modules/statistics.views.inc:53 +msgid "Views today" +msgstr "Vidoj hodiaŭ" + +#: modules/statistics.views.inc:54 +msgid "The total number of times the node has been viewed today." +msgstr "La tuta nombro da fojoj la nodo estas vidita hodiaŭ." + +#: modules/statistics.views.inc:70 +msgid "Most recent view" +msgstr "Plej lasta vido" + +#: modules/statistics.views.inc:71 +msgid "The most recent time the node has been viewed." +msgstr "La plej lasta fojo kiam la nodo estas vidita." + +#: modules/statistics.views.inc:86 +msgid "Access log" +msgstr "Alira protokolo" + +#: modules/statistics.views.inc:92 +msgid "Stores site access information." +msgstr "Konservas alirajn informojn de la retejo." + +#: modules/statistics.views.inc:106 +msgid "Session ID" +msgstr "Seanca ID" + +#: modules/statistics.views.inc:107 +msgid "Browser session ID of user that visited page." +msgstr "Retumila seanca ID de uzanto kiu vizitis paĝon." + +#: modules/statistics.views.inc:126 +msgid "Page title" +msgstr "Paĝa titolo" + +#: modules/statistics.views.inc:127 +msgid "Title of page visited." +msgstr "Titolo de paĝo vizitita." + +#: modules/statistics.views.inc:147 +msgid "Internal path to page visited (relative to Drupal root.)" +msgstr "Interna vojo al paĝo vizitita (relativa al Drupala radiko.)" + +#: modules/statistics.views.inc:166 +msgid "Referrer" +msgstr "Referanto" + +#: modules/statistics.views.inc:167 +msgid "Referrer URI." +msgstr "Referanta URI." + +#: modules/statistics.views.inc:182 +msgid "Hostname" +msgstr "Gastiga nomo" + +#: modules/statistics.views.inc:183 +msgid "Hostname of user that visited the page." +msgstr "Gastiga nomo de uzanto kiu vizitis la paĝon." + +#: modules/statistics.views.inc:202 +msgid "The user who visited the site." +msgstr "La uzanto kiu vizitis la retejon." + +#: modules/statistics.views.inc:212 +msgid "Timer" +msgstr "Horloĝo" + +#: modules/statistics.views.inc:213 +msgid "Time in milliseconds that the page took to load." +msgstr "Tempo en milisekundoj dum kiam la paĝo ŝargiĝis." + +#: modules/statistics.views.inc:228 +msgid "Timestamp" +msgstr "Tempindiko" + +#: modules/statistics.views.inc:229 +msgid "Timestamp of when the page was visited." +msgstr "Tempindiko kiam la paĝo estis vizitita." + +#: modules/system.views.inc:25 +msgid "File" +msgstr "Dosiero" + +#: modules/system.views.inc:31 +msgid "Files maintained by Drupal and various modules." +msgstr "Dosieroj administrataj de Drupalo kaj diversaj moduloj." + +#: modules/system.views.inc:49 +msgid "File ID" +msgstr "Dosiera ID" + +#: modules/system.views.inc:50 +msgid "The ID of the file." +msgstr "La ID de la dosiero." + +#: modules/system.views.inc:70 +msgid "The name of the file." +msgstr "La nomo de la dosiero." + +#: modules/system.views.inc:89 +msgid "The path of the file." +msgstr "La vojo de la dosiero." + +#: modules/system.views.inc:107 +msgid "Mime type" +msgstr "MIME-speco" + +#: modules/system.views.inc:108 +msgid "The mime type of the file." +msgstr "La MIME-speco de la dosiero." + +#: modules/system.views.inc:126 +msgid "Size" +msgstr "Grandeco" + +#: modules/system.views.inc:127 +msgid "The size of the file." +msgstr "La grandeco de la dosiero." + +#: modules/system.views.inc:142 +msgid "Status" +msgstr "Stato" + +#: modules/system.views.inc:143 +msgid "The status of the file." +msgstr "La stato de la dosiero." + +#: modules/system.views.inc:158 +msgid "Upload date" +msgstr "Alŝutita dato" + +#: modules/system.views.inc:159 +msgid "The date the file was uploaded." +msgstr "La dato kiam la dosiero estis alŝutita." + +#: modules/system.views.inc:202 +#: modules/upload.views.inc:152 +msgid "Link this field to download the file" +msgstr "Ligu ĉi tiun kampon por elŝuti la dosieron." + +#: modules/system.views.inc:229 +msgid "Temporary" +msgstr "Provizora" + +#: modules/system.views.inc:230 +msgid "Permanent" +msgstr "Daŭra" + +#: modules/system.views.inc:270 +msgid "No title" +msgstr "Neniu titolo" + +#: modules/taxonomy.views.inc:24 +msgid "Taxonomy" +msgstr "Taksonomio" + +#: modules/taxonomy.views.inc:48 +msgid "Vocabulary name" +msgstr "Vortproviza nomo" + +#: modules/taxonomy.views.inc:50 +msgid "Name of the vocabulary a term is a member of. This will be the vocabulary that whichever term the \"Taxonomy: Term\" field is; and can similarly cause duplicates." +msgstr "Nomo de la vortprovizo kiun termino estas membro. Tio estos la vortprovizo kiu ajn termino la \"Taksonomio: Termino\" kampo estas; kaj povas simile kaŭzi kopiojn." + +#: modules/taxonomy.views.inc:56 +msgid "Vocabulary ID" +msgstr "Vortproviza ID" + +#: modules/taxonomy.views.inc:57 +msgid "The taxonomy vocabulary ID" +msgstr "La taksonomia vortproviza ID" + +#: modules/taxonomy.views.inc:70 +msgid "Term" +msgstr "Termino" + +#: modules/taxonomy.views.inc:71 +msgid "Taxonomy terms are attached to nodes." +msgstr "Taksonomiaj terminoj estas alkroĉitaj al nodoj." + +#: modules/taxonomy.views.inc:97 +msgid "Taxonomy terms. Note that using this can cause duplicate nodes to appear in views; you must add filters to reduce the result set." +msgstr "Taksonomiaj terminoj. Rimarku ke uzante ĉi tion povas kaŭzi ke kopiaj nodoj aperu en montroj; vi devas aldoni filtrilojn por redukti la rezultaron. " + +#: modules/taxonomy.views.inc:107 +msgid "Taxonomy term name" +msgstr "Nomo de taksonomia termino" + +#: modules/taxonomy.views.inc:116 +msgid "The term weight field" +msgstr "Peza kampo de la termino" + +#: modules/taxonomy.views.inc:128 +msgid "Term description" +msgstr "Priskribo de la termino" + +#: modules/taxonomy.views.inc:129 +msgid "The description associated with a taxonomy term." +msgstr "La priskribo asociita kun taksonomia termino." + +#: modules/taxonomy.views.inc:140 +msgid "Vocabulary" +msgstr "Vortprovizo" + +#: modules/taxonomy.views.inc:141 +msgid "Filter the results of \"Taxonomy: Term\" to a particular vocabulary." +msgstr "Filtri la rezultojn de \"Taksonomio: Termino\" al specifa vortprovizo." + +#: modules/taxonomy.views.inc:176 +msgid "Term ID" +msgstr "Termina ID" + +#: modules/taxonomy.views.inc:177 +msgid "The taxonomy term ID" +msgstr "La taksonomia termina ID" + +#: modules/taxonomy.views.inc:179 +msgid "All terms" +msgstr "Ĉiuj terminoj" + +#: modules/taxonomy.views.inc:180 +msgid "Display all taxonomy terms associated with a node." +msgstr "Montri ĉiujn taksonomiajn terminojn asociitaj kun nodo." + +#: modules/taxonomy.views.inc:253 +msgid "Term synonym" +msgstr "Sinonimo de termino" + +#: modules/taxonomy.views.inc:254 +msgid "Term synonyms may be used to find terms by alternate names." +msgstr "Sinonimoj de termino povas esti uzata por trovi terminojn per alternativaj nomoj." + +#: modules/taxonomy.views.inc:270 +msgid "Term ID (with depth)" +msgstr "Termina ID (kun profundeco)" + +#: modules/taxonomy.views.inc:271 +msgid "The depth filter is more complex, so provides fewer options." +msgstr "La profunda filtrilo estas pli kompleksa, do provizas malpli da opcioj." + +#: modules/taxonomy.views.inc:281 +msgid "Term ID depth modifier" +msgstr "Profunda modifilo de termina ID" + +#: modules/taxonomy.views.inc:282 +msgid "Allows the \"depth\" for Taxonomy: Term ID (with depth) to be modified via an additional argument." +msgstr "Ebligas ke la \"profundeco\" por Taksonomio: Termina ID (kun profundeco) estu modifebla per aldona argumento." + +#: modules/taxonomy.views.inc:312 +msgid "The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term \"fruit\" and a child term \"apple\", with a depth of 1 (or higher) then filtering for the term \"fruit\" will get nodes that are tagged with \"apple\" as well as \"fruit\". If negative, the reverse is true; searching for \"apple\" will also pick up nodes tagged with \"fruit\" if depth is -1 (or lower)." +msgstr "La profundeco kongruos kun nodoj etikeditaj kun terminoj en la hierarkio. Ekzemple, se oni havas la terminon \"frukto\" kaj ida termino \"pomo\", kun profundeco de 1 (aŭ pli) tiam filtrado por la termino \"frukto\" kongruos kun nodoj kiuj estas etiketitaj kun \"pomo\" kaj \"frukto\". Se negativa, la inverso veras, serĉante por \"pomo\" ankaŭ kongruos kun nodoj etiketitaj kun \"frukto\" se profundeco estas -1 (aŭ malpli)." + +#: modules/taxonomy.views.inc:317 +msgid "Allow multiple terms per argument" +msgstr "Ebligi multajn erojn por ĉiu argumento" + +#: modules/taxonomy.views.inc:318 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3. Due to the number of JOINs it would require, AND will be treated as OR with this argument." +msgstr "Se elektita, uzantoj povas enmeti multajn argumentojn en la formo de 1+2+3. Pro la nombro da JOIN-oj kiujn tiu bezonatus, AND estos traktata kiel OR kun tiu argumento." + +#: modules/taxonomy.views.inc:324 +msgid "Set the breadcrumb for the term parents" +msgstr "Agordu la paĝnivelan navigo por la gepatra termino" + +#: modules/taxonomy.views.inc:325 +msgid "If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received." +msgstr "Se elektita, la paĝnivela navigo inkluzivos ĉiujn patrajn terminojn, ĉiu ligante al ĉi tiu montro. Rimarku ke tio funkcias nur se nur unu termino estis ricevita." + +#: modules/taxonomy.views.inc:411 +msgid "No name" +msgstr "Neniu nomo" + +#: modules/taxonomy.views.inc:520 +msgid "Link this field to its term page" +msgstr "Ligi ĉi tiun kampon al ĝia termina paĝo" + +#: modules/taxonomy.views.inc:527 +msgid "Limit terms by vocabulary" +msgstr "Limigi terminojn per vortprovizo" + +#: modules/taxonomy.views.inc:541 +msgid "Vocabularies" +msgstr "Vortprovizoj" + +#: modules/taxonomy.views.inc:612 +msgid "Link this field to its taxonomy term page" +msgstr "Ligi ĉi tiun kampon al ĝia taksonomia termina paĝo" + +#: modules/taxonomy.views.inc:684 +msgid "No vocabulary" +msgstr "Neniu vortprovizo" + +#: modules/taxonomy.views.inc:726 +msgid "Select which vocabulary to show terms for in the regular options." +msgstr "Elekti kiun vortprovizon por montri terminojn en la regulaj opcioj." + +#: modules/taxonomy.views.inc:736 +msgid "Selection type" +msgstr "Elekta speco" + +#: modules/taxonomy.views.inc:737 +msgid "Dropdown" +msgstr "Falmenuo" + +#: modules/taxonomy.views.inc:737 +msgid "Autocomplete" +msgstr "Aŭtokompletigi" + +#: modules/taxonomy.views.inc:743 +msgid "Show hierarchy in dropdown" +msgstr "Montri hierarkion en falmenuo" + +#: modules/taxonomy.views.inc:760 +msgid "An invalid vocabulary is selected. Please change it in the options." +msgstr "Nevalida vortprovizo estis elektita. Bonvolu ŝanĝi ĝin en la opcioj." + +#: modules/taxonomy.views.inc:778 +msgid "Select terms from vocabulary @voc" +msgstr "Elekti terminojn el vortprovizo @voc" + +#: modules/taxonomy.views.inc:983 +msgid "Taxonomy term" +msgstr "Taksonomia termino" + +#: modules/taxonomy.views.inc:1008 +msgid "If you wish to validate for specific vocabularies, check them; if none are checked, all nodes will pass." +msgstr "Se vi deziras validigi speciajn vortprovizojn, kontrolu ilin; se neniu estas ŝaltita, ĉiuj nodoj sukcesos." + +#: modules/taxonomy.views.inc:1018 +msgid "Term IDs separated by , or +" +msgstr "Terminaj ID-oj disigita per , aŭ +" + +#: modules/taxonomy.views.inc:1019 +msgid "Term name or synonym" +msgstr "Termina nomo aŭ sinonimo" + +#: modules/taxonomy.views.inc:1020 +msgid "Term name/synonym converted to Term ID" +msgstr "Termina nomo/sinonimo konvertita al Termina ID" + +#: modules/taxonomy.views.inc:1023 +msgid "Select the form of this argument; if using term name, it is generally more efficient to convert it to a term ID and use Taxonomy: Term ID rather than Taxonomy: Term Name\" as an argument." +msgstr "Elekti la formon de ĉi tiu argumento; se uzante la terminan nomon, estas ĝenerale pli efika konverti ĝin al termina ID kaj uzi Taksonomion; Termina ID anstataŭ ol Taksonomio; Termina Nomo\" kiel argumento." + +#: modules/taxonomy.views.inc:910 +msgid "Unable to find term: @terms" +msgid_plural "Unable to find terms: @terms" +msgstr[0] "Ne eblas trovi terminon: @terms" +msgstr[1] "Ne eblas trovi terminojn: @terms" + +#: modules/upload.views.inc:25 +msgid "Upload" +msgstr "Alŝuti" + +#: modules/upload.views.inc:44 +msgid "The node the uploaded file is attached to" +msgstr "La nodo al kiu la alŝutita dosiero estas alkroĉita" + +#: modules/upload.views.inc:46 +msgid "upload" +msgstr "alŝuti" + +#: modules/upload.views.inc:57 +msgid "The description of the uploaded file." +msgstr "La priskribo de la alŝutita dosiero" + +#: modules/upload.views.inc:74 +msgid "Listed" +msgstr "Listita" + +#: modules/upload.views.inc:75 +msgid "Whether or not the file is marked to be listed." +msgstr "Ĉu aŭ ne la dosiero estas markita kiel listita." + +#: modules/upload.views.inc:91 +msgid "The weight, used for sorting." +msgstr "La pezo, uzita por ordigi." + +#: modules/upload.views.inc:110 +msgid "Attached files" +msgstr "Alkroĉitaj dosieroj" + +#: modules/upload.views.inc:111 +msgid "All files attached to a node with upload.module." +msgstr "Ĉiuj dosieroj alkroĉitaj al nodo kun alŝuta modulo." + +#: modules/upload.views.inc:118 +msgid "Has attached files" +msgstr "Havas alkroĉitajn dosierojn" + +#: modules/upload.views.inc:119 +msgid "Only display items with attached files. This can cause duplicates if there are multiple attached files." +msgstr "Nur montri erojn kun alkroĉitaj dosieroj. Tio povas kaŭzi kopiojn se estas multaj alkroĉitaj dosieroj." + +#: modules/upload.views.inc:123 +msgid "Add a relationship to gain access to more file data for files uploaded by upload.module. Note that this relationship will cause duplicate nodes if there are multiple files attached to the node." +msgstr "Aldoni rilaton por ekaliron pli da dosieraj datumoj por dosieroj alŝutitaj de upload.module. Rimarku ke ĉi tiu rilato kaŭzos kopiitajn nodojn se estas multaj dosieroj alkroĉitaj al la nodo." + +#: modules/upload.views.inc:129 +msgid "Files" +msgstr "Dosieroj" + +#: modules/upload.views.inc:158 +msgid "Only show \"listed\" file attachments" +msgstr "Nur montri \"listitaj\" dosier-alkroĉaĵoj" + +#: modules/user.views.inc:28 +msgid "Users who have created accounts on your site." +msgstr "Uzantoj kiuj kreis konton en via retejo." + +#: modules/user.views.inc:48 +msgid "Uid" +msgstr "Uid" + +#: modules/user.views.inc:49 +msgid "The user ID" +msgstr "La ID de uzanto" + +#: modules/user.views.inc:70 +msgid "Current" +msgstr "Aktuala" + +#: modules/user.views.inc:71 +msgid "Filter the view to the currently logged in user." +msgstr "Filtri la montron al la nune ensalutinta uzanto." + +#: modules/user.views.inc:80 +msgid "The user or author name." +msgstr "La uzanto aŭ aŭtora nomo." + +#: modules/user.views.inc:96 +msgid "E-mail" +msgstr "Retpoŝto" + +#: modules/user.views.inc:97 +msgid "Email address for a given user. Only accessible to users with <em>administer users</em> permission" +msgstr "Retpoŝtadreso por uzanto. Nur alirebla al uzantoj kun permeso de <em>administri uzantoj</em>" + +#: modules/user.views.inc:114 +msgid "Picture" +msgstr "Bildo" + +#: modules/user.views.inc:115 +msgid "The user's picture, if allowed." +msgstr "La bildo de uzanto, se permesata." + +#: modules/user.views.inc:126 +msgid "The date the user was created." +msgstr "La dato kiam la uzanto estis kreita." + +#: modules/user.views.inc:141 +msgid "Last access" +msgstr "Lasta aliro" + +#: modules/user.views.inc:142 +msgid "The user's last access date." +msgstr "Lasta alira dato de la uzanto." + +#: modules/user.views.inc:157 +msgid "Last login" +msgstr "Lasta ensaluto" + +#: modules/user.views.inc:158 +msgid "The user's last login date." +msgstr "Lasta ensaluta dato de la uzanto." + +#: modules/user.views.inc:174 +msgid "Whether a user is active or blocked." +msgstr "Ĉu uzanto estas aktiva aŭ blokita." + +#: modules/user.views.inc:191 +msgid "Signature" +msgstr "Subskribo" + +#: modules/user.views.inc:192 +msgid "The user's signature." +msgstr "Subskribo de la uzanto." + +#: modules/user.views.inc:205 +msgid "Provide a simple link to edit the user." +msgstr "Provizi simplan ligilon por redakti la uzanton." + +#: modules/user.views.inc:213 +msgid "Provide a simple link to delete the user." +msgstr "Provizi simplan ligilon por forigi la uzanton." + +#: modules/user.views.inc:242 +msgid "Roles" +msgstr "Roloj" + +#: modules/user.views.inc:243 +msgid "Roles that a user belongs to." +msgstr "Roloj kiuj apertenas al uzanto." + +#: modules/user.views.inc:255 +msgid "No role" +msgstr "Neniu rolo" + +#: modules/user.views.inc:306 +msgid "User ID from URL" +msgstr "ID de uzanto de URL" + +#: modules/user.views.inc:322 +msgid "Also look for a node and use the node author" +msgstr "Ankaŭ serĉu por nodo kaj uzu la nodan aŭtoron" + +#: modules/user.views.inc:396 +msgid "Link this field to its user" +msgstr "Ligi ĉi tiun kampon al ĝia uzanto" + +#: modules/user.views.inc:519 +msgid "Link this field" +msgstr "Ligi ĉi tiun kampon" + +#: modules/user.views.inc:522 +msgid "No link" +msgstr "Neniu ligilo" + +#: modules/user.views.inc:523 +msgid "To the user" +msgstr "Al la uzanto" + +#: modules/user.views.inc:524 +msgid "With a mailto:" +msgstr "Kun mailto:" + +#: modules/user.views.inc:634 +msgid "Usernames" +msgstr "Uzantnomoj" + +#: modules/user.views.inc:635 +msgid "Enter a comma separated list of user names." +msgstr "Enmetu koman disigitan liston de uzantnomoj." + +#: modules/user.views.inc:754 +msgid "Is the logged in user" +msgstr "Estas la ensalutinta uzanto" + +#: modules/user.views.inc:714 +msgid "Unable to find user: @users" +msgid_plural "Unable to find users: @users" +msgstr[0] "Ne eblas trovi uzanton: @users" +msgstr[1] "Ne eblas trovi uzantojn: @users" + +#: modules/views.views.inc:18 +msgid "Global" +msgstr "Globala" + +#: modules/views.views.inc:23 +msgid "Random" +msgstr "Hazarda" + +#: modules/views.views.inc:24 +msgid "Randomize the display order." +msgstr "Hazardigu la montran sinsekvon." + +#: modules/views.views.inc:31 +msgid "Null" +msgstr "Nulo" + +#: modules/views.views.inc:32 +msgid "Allow an argument to be ignored. The query will not be altered by this argument." +msgstr "Ebligas ke argumento estu ignorata. La informpeto ne ŝanĝiĝos pro ĉi tiu argumento." + +#: modules/views.views.inc:84 +msgid "Fail basic validation if any argument is given" +msgstr "Malsukcesigu bazan validigon se argumento estas donita." + +#: modules/views.views.inc:86 +msgid "By checking this field, you can use this to make sure views with more arguments than necessary fail validation." +msgstr "Ŝaltante ĉi tiun kampon, vi povas uzi ĝin por certigi ke montroj kun pliaj argumentoj ol necese malsukcesas validigon." + +#: theme/views-more.tpl.php:15 +msgid "more" +msgstr "pli" + +#: theme/views-ui-edit-item.tpl.php:18 +msgid "None defined" +msgstr "Neniuj difinitaj" + +#: theme/views-ui-edit-tab.tpl.php:31 +msgid "View settings" +msgstr "Montraj agordoj" + +#: theme/views-ui-edit-view.tpl.php:11 +msgid "This view is being edited by user !user, and is therefore locked from editing by others. This lock is !age old. Click here to !break." +msgstr "Ĉi tiu montro estas redaktata de uzanto !uzanto kaj tiel ŝlosita de redaktado de aliaj. Tiu ŝloso estas !age malnova. Alklaku ĉi tie por !break." + +#: theme/views-ui-edit-view.tpl.php:16 +msgid "New view" +msgstr "Nova montro" + +#: theme/views-ui-edit-view.tpl.php:18 +msgid "Changed view" +msgstr "Ŝanĝita montro" + +#: theme/views-ui-edit-view.tpl.php:23 +msgid "View %name, displaying items of type <strong>@base</strong>." +msgstr "Montro %name, montrante erojn de speco <strong>@base</strong>." + +#: theme/views-ui-edit-view.tpl.php:42 +msgid "Live preview" +msgstr "Viva antaŭvido" + +#: theme/views-ui-list-views.tpl.php:17 +msgid "<em>@type</em> @base view: <strong>@view</strong>" +msgstr "<em>@type</em> @base montro: <strong>@view</strong>" + +#: theme/views-ui-list-views.tpl.php:27 +msgid "Title: @title" +msgstr "Titolo: @title" + +#: theme/views-ui-list-views.tpl.php:30 +msgid "Path: !path" +msgstr "Vojo: !path" + +#: theme/theme.inc:90 +msgid "Edit this view" +msgstr "Redakti ĉi tiun montron" + +#: theme/theme.inc:290 +msgid "sort by @s" +msgstr "ordigi laŭ @s" + +#: theme/theme.inc:500 +msgid "‹‹" +msgstr "‹‹" + +#: theme/theme.inc:501 +msgid "››" +msgstr "››" + +#: theme/theme.inc:511 +msgid "@current of @max" +msgstr "@current de @max" + +#: views_export/views_export.module:76 +msgid "There are no views to be exported at this time." +msgstr "Estas neniuj montroj por eksporti momente." + +#: views_export/views_export.module:108 +msgid "Show only these tags" +msgstr "Montri nur ĉi tiujn etikedojn" + +#: views_export/views_export.module:122 +msgid "Module name" +msgstr "Modula nomo" + +#: views_export/views_export.module:123 +msgid "Enter the module name to export code to." +msgstr "Enmeti la modulan nomon al kiu vi volas eksporti kodon." + +#: views_export/views_export.module:190 +msgid "Put this in @module.views_default.inc in your modules/@module directory or modules/@module/includes directory" +msgstr "Meti ĉi tion en @module.views_default.inc en via dosierujo de modules/@module aŭ modules/@module/includes." + +#: views_export/views_export.module:44 +msgid "use views exporter" +msgstr "uzi montro-eksportilon" + +#: views_export/views_export.module:17 +msgid "Bulk export" +msgstr "Amas-eksporti" + +#: views_export/views_export.module:0 +msgid "views_export" +msgstr "views_export" + +#: views_export/views_export.info:0 +msgid "Views exporter" +msgstr "Montro-eksportilo" + +#: views_export/views_export.info:0 +msgid "Allows exporting multiple views at once." +msgstr "Ebligas eksportadon de multaj montroj samtempe." diff --git a/sites/all/modules/views/translations/fr.po b/sites/all/modules/views/translations/fr.po new file mode 100644 index 0000000000000000000000000000000000000000..7417dfe3dc2ab51e6f8ca48e77d8d72c8bcd6403 --- /dev/null +++ b/sites/all/modules/views/translations/fr.po @@ -0,0 +1,3951 @@ +# translation of SB-views-6.x-2.x-dev.po to +# translation of views-6.x-2.x-dev.po to +msgid "" +msgstr "" +"Project-Id-Version: SB-views-6.x-2.x-dev\n" +"POT-Creation-Date: 2008-07-01 05:39+0200\n" +"PO-Revision-Date: 2008-07-07 02:33+0200\n" +"Last-Translator: sandrine\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" + +#: views.module:625 +msgid "Skipping broken view @view" +msgstr "Vue brisée @view sautée" + +#: views.module:672;712 +#: includes/admin.inc:92;253;253;599 +msgid "Overridden" +msgstr "Supplantée" + +#: views.module:675;708 +#: views_ui.module:284 +#: includes/admin.inc:91;252;252;566;738 +msgid "Default" +msgstr "Par défaut" + +#: views.module:824 +#: includes/admin.inc:286 +#: views_export/views_export.module:116 +msgid "Apply" +msgstr "Appliquer" + +#: views.module:109 +#: views_ui.module:23 +#: views.info:0;0 +#: views_ui.info:0 +#: views_export/views_export.info:0 +msgid "Views" +msgstr "Views" + +#: views.module:114 +msgid "Ajax callback for view loading." +msgstr "Procédure de rappel Ajax pour le chargement de la vue." + +#: views.module:0 +msgid "views" +msgstr "vues" + +#: views_ui.module:158 +msgid "The converter will make a best-effort attempt to convert a Views 1 view to Views 2. This conversion is not reliable; you will very likely have to make adjustments to your view to get it to match. You can import Views 1 views through the normal Import tab." +msgstr "Le convertisseur tente au mieux de convertir une vue Views 1 vers Views 2. Cette conversion n'est pas fiable et vous devrez très probablement ajuster votre vue pour la faire correspondre exactement. Vous pouvez importer les vues Views 1 par le biais de l'onglet habituel Importer." + +#: views_ui.module:25 +msgid "Views are customized lists of content on your system; they are highly configurable and give you control over how lists of content are presented." +msgstr "Les vues sont des listes personnalisées de contenus présents sur votre système. Elles sont hautement configurables et vous donnent le contrôle sur la présentation des listes de contenus." + +#: views_ui.module:29 +#: includes/plugins.inc:88;116 +msgid "List" +msgstr "Liste" + +#: views_ui.module:35 +#: includes/admin.inc:1081;1081;2093 +msgid "Add" +msgstr "Ajouter" + +#: views_ui.module:40 +#: includes/admin.inc:702 +msgid "Import" +msgstr "Importer" + +#: views_ui.module:46 +msgid "Tools" +msgstr "Outils" + +#: views_ui.module:52 +msgid "Basic" +msgstr "Basique" + +#: views_ui.module:60 +#: includes/convert.inc:30 +msgid "Convert" +msgstr "Convertir" + +#: views_ui.module:61 +msgid "Convert stored Views 1 views." +msgstr "Convertir les vues Views 1 enregistrées." + +#: views_ui.module:67;80;85 +msgid "Delete view" +msgstr "Supprimer la vue" + +#: views_ui.module:73 +msgid "Convert view" +msgstr "Convertir la vue" + +#: views_ui.module:110 +#: includes/admin.inc:87 +#: theme/theme.inc:89 +msgid "Edit" +msgstr "Éditer" + +#: views_ui.module:0 +msgid "views_ui" +msgstr "views_ui" + +#: views.install:31 +msgid "Stores the general data for a view." +msgstr "Enregistre les données générales d'une vue." + +#: views.install:37 +msgid "The view ID of the field, defined by the database." +msgstr "Identifiant de vue du champ, défini par la base de données." + +#: views.install:45 +msgid "The unique name of the view. This is the primary field views are loaded from, and is used so that views may be internal and not necessarily in the database. May only be alphanumeric characters plus underscores." +msgstr "Nom unique de la vue. Il s'agit du champ primaire à partir duquel les vues sont chargées et il est utilisé de manière à ce que les vues puissent être internes et non nécessairement dans la base de données. Ne peut contenir que des caractères alphanumériques et des espaces soulignés." + +#: views.install:51 +msgid "A description of the view for the admin interface." +msgstr "Description de la vue pour l'interface d'administration." + +#: views.install:57 +msgid "A tag used to group/sort views in the admin interface" +msgstr "Étiquette utilisée pour grouper/trier les vues dans l'interface d'administration" + +#: views.install:61 +msgid "A chunk of PHP code that can be used to provide modifications to the view prior to building." +msgstr "Extrait de code PHP pouvant être utilisé pour modifier la vue avant sa construction." + +#: views.install:68 +msgid "What table this view is based on, such as node, user, comment, or term." +msgstr "Table sur laquelle est basée la vue, par exemple nœud, utilisateur, commentaire ou terme." + +#: views.install:74 +msgid "A boolean to indicate whether or not this view may have its query cached." +msgstr "Valeur booléenne indiquant si la requête de la vue peut être mise en cache ou non." + +#: views.install:82 +msgid "Stores information about each display attached to a view." +msgstr "Enregistre des informations sur chaque affichage attaché à la vue." + +#: views.install:89 +msgid "The view this display is attached to." +msgstr "La vue à laquelle est attaché cet affichage." + +#: views.install:97 +msgid "An identifier for this display; usually generated from the display_plugin, so should be something like page or page_1 or block_2, etc." +msgstr "Un identifiant pour cet affichage ; habituellement généré par le display_plugin, il devrait donc ressembler à page, page_1, block_2, etc." + +#: views.install:104 +msgid "The title of the display, viewable by the administrator." +msgstr "Le titre de l'affichage, visible par l'administrateur." + +#: views.install:111 +msgid "The type of the display. Usually page, block or embed, but is pluggable so may be other things." +msgstr "Le type d'affichage. Généralement, page, bloc ou embed, mais il peut être greffé et donc prendre d'autres valeurs." + +#: views.install:116 +msgid "The order in which this display is loaded." +msgstr "L'ordre de chargement de cet affichage." + +#: views.install:120 +msgid "A serialized array of options for this display; it contains options that are generally only pertinent to that display plugin type." +msgstr "Tableau sérialisé d'options pour cet affichage ; il contient des options qui ne sont généralement pertinentes que pour le type de plugin de cet affichage." + +#: views.install:131 +msgid "A special cache used to store objects that are being edited; it serves to save state in an ordinarily stateless environment." +msgstr "Cache spécial utilisé pour enregistrer les objets en cours d'édition ; il sert à enregistrer l'état dans un environnement normalement sans état." + +#: views.install:136 +msgid "The session ID this cache object belongs to." +msgstr "L'identifiant de session auquel cet objet de cache appartient." + +#: views.install:141 +msgid "The name of the view this cache is attached to." +msgstr "Le nom de la vue à laquelle ce cache est rattaché." + +#: views.install:146 +msgid "The name of the object this cache is attached to; this essentially represents the owner so that several sub-systems can use this cache." +msgstr "Le nom de l'objet auquel ce cache est rattaché ; il représente essentiellement le propritéaire, de sorte que plusieurs sous-systèmes peuvent utiliser ce cache." + +#: views.install:153 +msgid "The time this cache was created or updated." +msgstr "Date de création ou de mise à jour de ce cache." + +#: views.install:157 +msgid "Serialized data being stored." +msgstr "Données sérialisées en cours d'enregistrement." + +#: views.info:0 +msgid "Create customized lists and queries from your database." +msgstr "Créez des listes et requêtes personnalisées à partir de votre base de données." + +#: views_ui.info:0 +msgid "Views UI" +msgstr "Views UI" + +#: views_ui.info:0 +msgid "Administrative interface to views. Without this module, you cannot create or edit your views." +msgstr "Interface d'administration des vues. Sans ce module, vous ne pouvez pas créer ou éditer de vue." + +#: docs/docs.php:106 +msgid "Emulates the default Drupal front page; you may set the default home page path to this view to make it your front page." +msgstr "Émule la page d'accueil par défaut de Drupal ; vous pouvez faire pointer le chemin de votre page d'accueil par défaut vers cette vue pour en faire votre page d'accueil." + +#: docs/docs.php:107 +msgid "default" +msgstr "par défaut" + +#: docs/docs.php:116 +#: includes/plugins.inc:18 +msgid "Defaults" +msgstr "Paramètres par défaut" + +#: docs/docs.php:205 +#: includes/plugins.inc:32;40 +msgid "Page" +msgstr "Page" + +#: docs/docs.php:260 +#: includes/plugins.inc:65;72 +msgid "Feed" +msgstr "Flux" + +#: docs/docs.php:328 +msgid "Front page feed" +msgstr "Flux de la page d'accueil" + +#: includes/admin.inc:34 +msgid "If you install the advanced help module from !href, Views will provide more and better help. <a href=\"@hide\">Hide this message.</a>" +msgstr "Si vous installez le module d'aide avancé de !href, Views vous proposera une aide plus conséquente et plus détaillée. <a href=\"@hide\">Cacher ce message.</a>" + +#: includes/admin.inc:88;900 +#: theme/theme.inc:96 +#: views_export/views_export.module:128 +msgid "Export" +msgstr "Exporter" + +#: includes/admin.inc:89;905 +#: theme/theme.inc:101 +msgid "Clone" +msgstr "Dupliquer" + +#: includes/admin.inc:92 +msgid "Revert" +msgstr "Revenir" + +#: includes/admin.inc:92;612;774 +#: includes/convert.inc:35;109 +msgid "Delete" +msgstr "Supprimer" + +#: includes/admin.inc:97 +msgid "Disable" +msgstr "Désactiver" + +#: includes/admin.inc:100 +msgid "Enable" +msgstr "Activer" + +#: includes/admin.inc:106 +msgid "Warning! Broken view!" +msgstr "Attention ! Vue brisée !" + +#: includes/admin.inc:121 +msgid "Broken" +msgstr "Brisé" + +#: includes/admin.inc:180 +msgid "Install the advanced help module for the getting started" +msgstr "Installez le module d'aide avancée pour démarrer" + +#: includes/admin.inc:183 +msgid "Not sure what to do? Try the \"!getting-started\" page." +msgstr "Vous n'êtes pas sûr de ce que vous devez faire ? Essayez de commencer par la page \"!getting-started\"." + +#: includes/admin.inc:197;250;2059 +msgid "<All>" +msgstr "<Tous>" + +#: includes/admin.inc:198 +#: includes/plugins.inc:2820 +msgid "<None>" +msgstr "<Aucun>" + +#: includes/admin.inc:213;264;985 +#: views_export/views_export.module:146 +msgid "Tag" +msgstr "Étiquette" + +#: includes/admin.inc:229 +msgid "Displays" +msgstr "Affichage" + +#: includes/admin.inc:241;266 +#: includes/plugins.inc:1102;2079 +#: modules/node.views.inc:139 +msgid "Type" +msgstr "Type" + +#: includes/admin.inc:248 +msgid "Storage" +msgstr "Enregistrement" + +#: includes/admin.inc:251;251 +#: includes/view.inc:993;1043 +msgid "Normal" +msgstr "Normal" + +#: includes/admin.inc:260 +msgid "Sort by" +msgstr "Trier par" + +#: includes/admin.inc:262 +#: includes/plugins.inc:805 +#: modules/system.views.inc:69 +#: modules/user.views.inc:59;79 +msgid "Name" +msgstr "Nom" + +#: includes/admin.inc:263;361 +#: includes/argument.handlers.inc:111 +#: includes/plugins.inc:817;2091;2136 +#: modules/comment.views.inc:44 +#: modules/node.views.inc:84;402 +msgid "Title" +msgstr "Titre" + +#: includes/admin.inc:265;369 +#: includes/plugins.inc:2008 +#: modules/statistics.views.inc:146 +#: modules/system.views.inc:88 +msgid "Path" +msgstr "Chemin" + +#: includes/admin.inc:267 +#: includes/convert.inc:21 +#: modules/upload.views.inc:48 +#: views_export/views_export.module:146 +msgid "Description" +msgstr "Description" + +#: includes/admin.inc:274 +msgid "Order" +msgstr "Ordre" + +#: includes/admin.inc:276 +msgid "Up" +msgstr "Haut" + +#: includes/admin.inc:277 +msgid "Down" +msgstr "Bas" + +#: includes/admin.inc:360;379 +msgid "Query" +msgstr "Requête" + +#: includes/admin.inc:366 +msgid "This display has no path." +msgstr "Cet affichage n'a pas de chemin" + +#: includes/admin.inc:371 +msgid "Query build time" +msgstr "Durée de construction de la requête" + +#: includes/admin.inc:371;372;373 +msgid "@time ms" +msgstr "@time ms" + +#: includes/admin.inc:372 +msgid "Query execute time" +msgstr "Durée d'exécution de la requête" + +#: includes/admin.inc:373 +msgid "View render time" +msgstr "Durée de rendu de la vue" + +#: includes/admin.inc:379 +msgid "No query was run" +msgstr "Aucune requête n'a été exécutée" + +#: includes/admin.inc:386 +msgid "Unable to preview due to validation errors." +msgstr "Impossible de prévisualiser à cause d'erreurs de validation." + +#: includes/admin.inc:437 +msgid "Display" +msgstr "Affichage" + +#: includes/admin.inc:445 +#: includes/view.inc:1670 +msgid "Arguments" +msgstr "Arguments" + +#: includes/admin.inc:447 +msgid "Separate arguments with a / as though they were a URL path." +msgstr "Séparez les arguments par un / comme s'il s'agissait d'URL." + +#: includes/admin.inc:453 +msgid "Preview" +msgstr "Aperçu" + +#: includes/admin.inc:491 +msgid "Clone view @view" +msgstr "Dupliquer la vue @view" + +#: includes/admin.inc:504;691 +#: includes/convert.inc:20 +msgid "View name" +msgstr "Nom de la vue" + +#: includes/admin.inc:505 +msgid "This is the unique name of the view. It must contain only alphanumeric characters and underscores; it is used to identify the view internally and to generate unique theming template names for this view. If overriding a module provided view, the name must not be changed or instead a new view will be created." +msgstr "Il s'agit du nom unique de la vue. Il ne doit comporter que des caractères alphanumériques et des espaces soulignés. Il sert à identifier la vue en interne et à générer des noms uniques pour les templates de thèmes pour cette vue. Si la vue supplante une vue fournie par un module, le nom ne doit pas être modifié sous peine de créer une nouvelle vue." + +#: includes/admin.inc:513;1769 +msgid "View description" +msgstr "Description de la vue" + +#: includes/admin.inc:514;1770 +msgid "This description will appear on the Views administrative UI to tell you what the view is about." +msgstr "Cette description apparaîtra dans l'interface utilisateur d'administration de Views pour vous indiquer l'objet de cette vue." + +#: includes/admin.inc:520;1776 +msgid "View tag" +msgstr "Étiquette de la vue" + +#: includes/admin.inc:521;1777 +msgid "Enter an optional tag for this view; it is used only to help sort views on the administrative page." +msgstr "Saisissez une étiquette optionnelle pour cette vue ; elle sert uniquement à faciliter le tri des vues sur la page d'administration." + +#: includes/admin.inc:533 +msgid "View type" +msgstr "Type de vue" + +#: includes/admin.inc:534 +msgid "The view type is the primary table for which information is being retrieved. The view type controls what arguments, fields, sort criteria and filters are available, so once this is set it <strong>cannot be changed</strong>." +msgstr "Le type de vue est la table primaire pour laquelle les informations sont récupérées. Le type de vue contrôle quels arguments, champs, critères de tri et filtres sont disponibles ; par conséquent, une fois qu'il est fixé, il ne <strong>peut plus être modifié</strong>." + +#: includes/admin.inc:545 +msgid "Next" +msgstr "Suivant" + +#: includes/admin.inc:561 +msgid "View name must be alphanumeric or underscores only." +msgstr "Le nom de la vue n peut contenir que des caractères alphanumériques et des espaces soulignés." + +#: includes/admin.inc:567 +msgid "You must use a unique name for this view." +msgstr "Vous devez utiliser un nom unique pour cette vue." + +#: includes/admin.inc:600 +msgid "Are you sure you want to revert the view %name?" +msgstr "Êtes-vous sûr(e) de vouloir revenir en arrière pour la vue %name ?" + +#: includes/admin.inc:601 +msgid "Reverting the view will delete the view that is in the database, reverting it to the original default view. Any changes you have made will be lost and cannot be recovered." +msgstr "Revenir en arrière pour une vue supprime la vue enregistrée dans la base de données pour revenir à la vue par défaut d'origine. Toutes les modifications que vous aviez apportées seront perdues et ne pourront être récupérées." + +#: includes/admin.inc:604 +#: includes/convert.inc:105 +msgid "Are you sure you want to delete the view %name?" +msgstr "Êtes-vous sûr(e) de vouloir supprimer la vue %name ?" + +#: includes/admin.inc:605 +msgid "Deleting a view cannot be undone." +msgstr "Supprimer une vue est irréversible." + +#: includes/admin.inc:613;649;767;1225 +#: includes/convert.inc:110 +msgid "Cancel" +msgstr "Annuler" + +#: includes/admin.inc:622 +msgid "The view has been deleted." +msgstr "La vue a été supprimée." + +#: includes/admin.inc:634 +msgid "There is no lock on view %view to break." +msgstr "Il n'y a aucun verrou à faire sauter sur la vue %view." + +#: includes/admin.inc:644 +msgid "Are you sure you want to break the lock on view %name?" +msgstr "Êtes-vous sûr(e) de vouloir faire sauter le verrou sur la vue %name ?" + +#: includes/admin.inc:647 +msgid "By breaking this lock, any unsaved changes made by !user will be lost!" +msgstr "En faisant sauter ce verrou, toutes les modifications réalisées par !user et non encore enregistrées seront perdues !" + +#: includes/admin.inc:648 +msgid "Break lock" +msgstr "Faire sauter le verrou" + +#: includes/admin.inc:665 +msgid "Edit view \"%view\"" +msgstr "Éditer la vue \"%view\"" + +#: includes/admin.inc:692 +msgid "Enter the name to use for this view if it is different from the source view. Leave blank to use the name of the view." +msgstr "Saisissez le nom à utiliser pour cette vue s'il diffère de la vue source. Laissez la valeur à blanc pour utiliser le nom de la vue." + +#: includes/admin.inc:697 +msgid "Paste view code here" +msgstr "Copiez le code de la vue ici" + +#: includes/admin.inc:719 +msgid "Unable to interpret view code." +msgstr "Impossible d'interpréter le code de la vue." + +#: includes/admin.inc:726 +msgid "You are importing a view created in Views version 1. You may need to adjust some parameters to work correctly in version 2." +msgstr "Vous importez une vue créée dans Views version 1. Vous pourrez être amené à ajuster certains paramètres pour que la vue fonctionne correctement dans Views version 2." + +#: includes/admin.inc:729 +msgid "That view is not compatible with this version of Views." +msgstr "Cette vue n'est pas compatible avec cette version de Views." + +#: includes/admin.inc:739 +msgid "A view by that name already exists; please choose a different name" +msgstr "Une vue portant ce nom existe déjà ; merci de choisir un nom différent." + +#: includes/admin.inc:760;788 +msgid "Save" +msgstr "Enregistrer" + +#: includes/admin.inc:812 +msgid "The view has been saved." +msgstr "La vue a été enregistrée." + +#: includes/admin.inc:851 +msgid "Unknown or missing table name" +msgstr "Nom de table inconnu ou manquant" + +#: includes/admin.inc:856 +msgid "Click on an item to edit that item's details." +msgstr "Cliquez sur un élément pour modifier ses détails." + +#: includes/admin.inc:859 +msgid "This view has a broken default display and cannot be used." +msgstr "Cette vue possède un affichage par défaut défectueux et ne peut donc être utilisée." + +#: includes/admin.inc:895 +msgid "break this lock" +msgstr "faire sauter ce verrou" + +#: includes/admin.inc:901 +#: theme/theme.inc:97 +msgid "Export this view" +msgstr "Exporter cette vue" + +#: includes/admin.inc:906 +#: theme/theme.inc:102 +msgid "Create a copy of this view" +msgstr "Créer une copie de cette vue" + +#: includes/admin.inc:917 +msgid "View \"!display\"" +msgstr "Voir \"!display\"" + +#: includes/admin.inc:918 +msgid "Go to the real page for this display" +msgstr "Aller à la vraie page de cet affichage" + +#: includes/admin.inc:984 +#: includes/plugins.inc:812;943;955;1999;2293;2467;2659;3299 +msgid "None" +msgstr "Aucun" + +#: includes/admin.inc:1058 +msgid "Invalid" +msgstr "Invalide" + +#: includes/admin.inc:1058 +msgid "Error: Display @display refers to a plugin named '@plugin', but that plugin doesn't exist!" +msgstr "Erreur : l'affichage @display se réfère à un plugin nommé '@plugin', mais ce plugin n'existe pas !" + +#: includes/admin.inc:1079;1079 +msgid "Rearrange" +msgstr "Réordonner" + +#: includes/admin.inc:1112;2144;2323;2391;2476 +msgid "Error: handler for @table > @field doesn't exist!" +msgstr "Erreur : le gestionnaire pour @table > @field n'existe pas !" + +#: includes/admin.inc:1131;1131;1140 +msgid "Settings" +msgstr "Paramètres" + +#: includes/admin.inc:1136 +#: includes/plugins.inc:823;841 +msgid "Missing style plugin" +msgstr "Plugin de style manquant" + +#: includes/admin.inc:1140 +#: includes/plugins.inc:836;851 +msgid "Change settings for this style" +msgstr "Modifier les paramètres pour ce style" + +#: includes/admin.inc:1143 +msgid " Style: !style" +msgstr " Style : !style" + +#: includes/admin.inc:1174 +msgid "Invalid display id while regenerating tabs" +msgstr "Identifiant d'affichage invalide à la regénération des onglets" + +#: includes/admin.inc:1207 +msgid "Update" +msgstr "Mise à jour" + +#: includes/admin.inc:1225 +msgid "Ok" +msgstr "Ok" + +#: includes/admin.inc:1494 +msgid "Unable to initialize default display" +msgstr "Impossible d'initialiser l'affichage par défaut" + +#: includes/admin.inc:1526 +msgid "Add display" +msgstr "Nouvel affichage" + +#: includes/admin.inc:1566 +msgid "Remove display" +msgstr "Supprimer un affichage" + +#: includes/admin.inc:1577 +msgid "Restore display" +msgstr "Restaurer un affichage" + +#: includes/admin.inc:1649 +msgid "Analyze" +msgstr "Analyser" + +#: includes/admin.inc:1669 +msgid "This view has only a default display and therefore will not be placed anywhere on your site; perhaps you want to add a page or a block display." +msgstr "Cette vue ne possède qu'un affichage par défaut et, par conséquent, n'apparaîtra nulle part sur votre site ; peut-être devrez-vous ajouter un affichage de page ou de bloc." + +#: includes/admin.inc:1681 +msgid "View analysis" +msgstr "Analyse de la vue" + +#: includes/admin.inc:1690 +msgid "View analysis can find nothing to report." +msgstr "L'analyse de la vue n'a rien trouvé à signaler." + +#: includes/admin.inc:1764 +msgid "View details" +msgstr "Détails de la vue" + +#: includes/admin.inc:1805;1854;1904;2045;2137;2316;2384;2469 +msgid "Invalid display id @display" +msgstr "Identifiant d'affichage @display invalide" + +#: includes/admin.inc:1858 +msgid "Configure @type" +msgstr "Configurer @type" + +#: includes/admin.inc:1908 +msgid "Rearrange @type" +msgstr "Réarranger @type" + +#: includes/admin.inc:1951 +msgid "Broken field @id" +msgstr "Champ brisé @id" + +#: includes/admin.inc:1986;1995;2232;2341 +msgid "Remove" +msgstr "Supprimer" + +#: includes/admin.inc:1986;1986 +msgid "Remove this item" +msgstr "Supprimer cet élément" + +#: includes/admin.inc:1992 +msgid "No fields available." +msgstr "Aucun champ disponible." + +#: includes/admin.inc:1995 +#: includes/plugins.inc:2100 +#: modules/book.views.inc:57 +#: modules/taxonomy.views.inc:126 +#: modules/upload.views.inc:82 +msgid "Weight" +msgstr "Poids" + +#: includes/admin.inc:2051 +msgid "Add @type" +msgstr "Ajouter @type" + +#: includes/admin.inc:2062 +msgid "Groups" +msgstr "Groupes" + +#: includes/admin.inc:2081 +msgid "!group: !field" +msgstr "!group : !field" + +#: includes/admin.inc:2090 +msgid "There are no @types available to add." +msgstr "Il n'y a aucun @types disponible à ajouter." + +#: includes/admin.inc:2155 +#: includes/plugins.inc:1556 +msgid "Status: using default values." +msgstr "Statut : utilisation des valeurs par défaut." + +#: includes/admin.inc:2162 +#: includes/plugins.inc:1568 +msgid "Status: using overridden values." +msgstr "Statut : utilisation des valeurs supplantées." + +#: includes/admin.inc:2200 +msgid "Do not use a relationship" +msgstr "Ne pas utiliser de relation" + +#: includes/admin.inc:2209 +#: includes/view.inc:1694;1695 +msgid "Relationship" +msgstr "Relation" + +#: includes/admin.inc:2222 +msgid "Configure @type \"@item\"" +msgstr "Configurer @type \"@item\"" + +#: includes/admin.inc:2331 +msgid "Configure extra settings for @type \"@item\"" +msgstr "Configurer les paramètres supplémentaires pour @type \"@item\"" + +#: includes/admin.inc:2396 +msgid "Change summary style for @type \"@item\"" +msgstr "Changer le style de résumé pour @type \"@item\"" + +#: includes/admin.inc:2419;2433 +msgid "Internal error: broken plugin." +msgstr "Erreur interne : plugin défectueux." + +#: includes/admin.inc:2483 +msgid "Configure summary style for @type \"@item\"" +msgstr "Configurer le style de résumé pour @type \"@item\"" + +#: includes/admin.inc:2575 +msgid "Clear Views' cache" +msgstr "Vider le cache de Views" + +#: includes/admin.inc:2581 +msgid "Add Views signature to all SQL queries" +msgstr "Ajouter la signature Views à toutes les requêtes SQL" + +#: includes/admin.inc:2582 +msgid "All Views-generated queries will include a special 'VIEWS' = 'VIEWS' string in the WHERE clause. This makes identifying Views queries in database server logs simpler, but should only be used when troubleshooting." +msgstr "Toutes les requêtes générées par Views incluront une chaîne spéciale 'VIEWS' = 'VIEWS' dans la clause WHERE. Ceci facilite grandement l'identification des requêtes Views dans les fichier journaux du serveur de base de données, mais ne devrait être utilisé que pour le dépannage." + +#: includes/admin.inc:2588 +msgid "Disable views data caching" +msgstr "Désactiver la mise en cache des données Views" + +#: includes/admin.inc:2589 +msgid "Views caches data about tables, modules and views available, to increase performance. By checking this box, Views will skip this cache and always rebuild this data when needed. This can have a serious performance impact on your site." +msgstr "Views met en cache des données relatives aux tables, aux modules et aux vues disponibles afin d'améliorer les performances. En cochant cette case, vous obligez Views à sauter cette mise en cache et à reconstruire systématiquement la base de données dès que nécessaire. Cela peut avoir un impact important sur les performances de votre site." + +#: includes/admin.inc:2595 +msgid "Ignore missing advanced help module" +msgstr "Ignorer le module d'aide avancée manquant" + +#: includes/admin.inc:2596 +msgid "Views uses the advanced help module to provide help text; if this module is not present Views will complain, unless this setting is checked." +msgstr "Views utilise le module d'aide avancée pour proposer des textes d'aide ; si ce module est absent, Views le signalera sauf si ce paramètre est coché." + +#: includes/admin.inc:2602 +msgid "Show query above live preview" +msgstr "Afficher la requête au dessus de la prévisualisation en direct" + +#: includes/admin.inc:2603 +msgid "The live preview feature will show you the output of the view you're creating, as well as the view. Check here to show the query and other information above the view; leave this unchecked to show that information below the view." +msgstr "La prévisualisation en direct vous montrera le résultat de la vue que vous êtes en train de créer, ainsi que la vue. Cochez cette case pour voir apparaître la requête et les autres informations au dessus de la vue ; laissez la case non cochée pour conserver ces informations sous la vue." + +#: includes/admin.inc:2609 +msgid "Do not show hover links over views" +msgstr "Ne pas montrer les liens flottants sur les vues" + +#: includes/admin.inc:2610 +msgid "To make it easier to administrate your views, Views provides 'hover' links to take you to the edit and export screen of a view whenever the view is used. This can be distracting on some themes, though; if it is problematic, you can turn it off here." +msgstr "Pour faciliter l'administration de vos vues, Views propose des liens 'flottants' pour vous conduire aux écrans d'édition et d'export d'une vue, lorsque celle-ci est utilisée. Cela peut toutefois se révéler gênant sur certains thèmes ; si ces liens posent des problèmes, vous pouvez les désactiver ici." + +#: includes/admin.inc:2616 +msgid "Enable views performance statistics via the Devel module" +msgstr "Activer les statistiques de performances de Views via le module Devel" + +#: includes/admin.inc:2617 +msgid "Check this to enable some Views query and performance statistics <em>if Devel is installed</em>." +msgstr "Cochez cette case pour activer certaines statistiques sur les performances et requêtes de Views, <em>à condition que Devel soit installé</em>." + +#: includes/admin.inc:2623 +msgid "Disable javascript with Views" +msgstr "Désactiver le JavaScript avec Views" + +#: includes/admin.inc:2624 +msgid "If you are having problems with the javascript, you can disable it here; the Views UI should degrade and still be usable without javascript, it just not as good." +msgstr "Si vous rencontrez des problèmes avec JavaScript, vous pouvez le désactiver ici ; l'interface graphique de Views devrait s'adapter mais rester utilisable sans JavaScript, simplement sa qualité s'en ressentira." + +#: includes/admin.inc:2632 +msgid "Page region to output performance statistics" +msgstr "Région de la page où afficher les statistiques de performance" + +#: includes/admin.inc:2645 +msgid "The cache has been cleared." +msgstr "Le cache a été vidé." + +#: includes/admin.inc:2809 +msgid "Error: missing @component" +msgstr "Erreur : @component manquant" + +#: includes/ajax.inc:73 +msgid "Server reports invalid input error." +msgstr "Le serveur signale une erreur de saisie invalide." + +#: includes/ajax.inc:74 +msgid "Error" +msgstr "Erreur" + +#: includes/argument.handlers.inc:91 +msgid "All" +msgstr "Tous / Toutes" + +#: includes/argument.handlers.inc:113 +msgid "The title to use when this argument is present; it will override the title of the view and titles from previous arguments. You can use percent substitution here to replace with argument titles. Use \"%1\" for the first argument, \"%2\" for the second, etc." +msgstr "Titre à utiliser lorsque cet argument est présent ; il supplante le titre de la vue et les titres des arguments précédents. Vous pouvez utiliser le caractère pourcent pour réaliser des substitutions ici et remplacer par les titres des arguments. Utilisez \"%1\" pour le premier argument, \"%2\" pour le deuxième, etc." + +#: includes/argument.handlers.inc:126 +msgid "Action to take if argument is not present" +msgstr "Action à mener si l'argument est absent" + +# ~fuzzy +#: includes/argument.handlers.inc:138 +msgid "Wildcard" +msgstr "Joker" + +#: includes/argument.handlers.inc:141 +msgid "If this value is received as an argument, the argument will be ignored; i.e, \"all values\"" +msgstr "Si cette valeur est reçue comme argument, l'argument sera ignoré ; correspond à \"toutes les valeurs\"" + +#: includes/argument.handlers.inc:147 +msgid "Wildcard title" +msgstr "Titre joker" + +#: includes/argument.handlers.inc:150 +msgid "The title to use for the wildcard in substitutions elsewhere." +msgstr "Titre à utiliser pour le joker dans les substitutions réalisées ailleurs." + +#: includes/argument.handlers.inc:173 +msgid "Validator" +msgstr "Validateur" + +#: includes/argument.handlers.inc:177 +msgid "<Basic validation>" +msgstr "<Validation de base>" + +#: includes/argument.handlers.inc:213 +msgid "Action to take if argument does not validate" +msgstr "Actions à mener sur l'argument ne passe pas la validation" + +#: includes/argument.handlers.inc:228 +msgid "Display all values" +msgstr "Afficher toutes les valeurs" + +#: includes/argument.handlers.inc:233 +msgid "Hide view / Page not found (404)" +msgstr "Cacher la vue / Page non trouvée (404)" + +#: includes/argument.handlers.inc:237 +msgid "Display empty text" +msgstr "Afficher le texte vide" + +#: includes/argument.handlers.inc:242 +msgid "Summary, sorted ascending" +msgstr "Sommaire, classement ascendant" + +#: includes/argument.handlers.inc:249 +msgid "Summary, sorted descending" +msgstr "Sommaire, classement descendant" + +#: includes/argument.handlers.inc:256 +msgid "Provide default argument" +msgstr "Fournir l'argument par défaut" + +#: includes/argument.handlers.inc:287 +msgid "Default argument type" +msgstr "Type d'argument par défaut" + +#: includes/argument.handlers.inc:702 +msgid "Current date" +msgstr "Date actuelle" + +#: includes/argument.handlers.inc:757 +msgid "Glossary mode" +msgstr "Mode glossaire" + +#: includes/argument.handlers.inc:758 +msgid "Glossary mode applies a limit to the number of characters used in the argument, which allows the summary view to act as a glossary." +msgstr "Le mode glossaire applique une limite au nombre de caractères utilisés dans l'argument, ce qui permet à la vue sommaire de se comporter comme un glossaire." + +#: includes/argument.handlers.inc:764 +msgid "Character limit" +msgstr "Limite de caractères" + +#: includes/argument.handlers.inc:765 +msgid "How many characters of the argument to filter against. If set to 1, all fields starting with the letter in the argument would be matched." +msgstr "Nombre de caractères de l'argument à utiliser pour le filtrage. Si la valeur est fixée à 1, tous les champs commençant par la lettre saisie en argument correspondront." + +#: includes/argument.handlers.inc:773 +msgid "Case" +msgstr "Casse" + +#: includes/argument.handlers.inc:774 +msgid "When printing the argument result, how to transform the case." +msgstr "À l'affichage du résultat de l'argument, définit la transformation à appliquer à la casse." + +#: includes/argument.handlers.inc:776;790 +msgid "No transform" +msgstr "Aucune transformation" + +#: includes/argument.handlers.inc:777;791 +msgid "Upper case" +msgstr "Majuscules" + +#: includes/argument.handlers.inc:778;792 +msgid "Lower case" +msgstr "Minuscules" + +#: includes/argument.handlers.inc:779;793 +msgid "Capitalize first letter" +msgstr "Mettre la première lettre en majuscule" + +#: includes/argument.handlers.inc:780;794 +msgid "Capitalize each word" +msgstr "Mettre chaque mot en majuscules" + +#: includes/argument.handlers.inc:787 +msgid "Case in path" +msgstr "Casse dans les chemins" + +#: includes/argument.handlers.inc:788 +msgid "When printing url paths, how to transform the of the argument. Do not use this unless with Postgres as it uses case sensitive comparisons." +msgstr "À l'affichage d'URL, indique comment transformer la casse de l'argument. À ne pas utiliser sauf avec Postgres car il y a utilisation de comparaisons sensibles à la casse." + +#: includes/argument.handlers.inc:801 +msgid "Transform spaces to dashes in URL" +msgstr "Dans les URL, transforme les espaces en tirets" + +#: includes/argument.handlers.inc:808;1046 +msgid "Allow multiple arguments to work together." +msgstr "Permettre à plusieurs arguments de collaborer." + +#: includes/argument.handlers.inc:809;1047 +msgid "If selected, multiple instances of this argument can work together, as though multiple terms were supplied to the same argument. This setting is not compatible with the \"Reduce duplicates\" setting." +msgstr "Si cette option est sélectionnée, plusieurs instances de cet argument peuvent collaborer comme si l'on avait fourni plusieurs termes pour le même argument. Ce paramétrage n'est pas compatible avec le paramètre \"Supprimer les doublons\"." + +#: includes/argument.handlers.inc:815;1053 +msgid "Do not display items with no value in summary" +msgstr "Ne pas afficher les éléments sans valeur dans le sommaire" + +#: includes/argument.handlers.inc:936;1038 +msgid "Allow multiple terms per argument." +msgstr "Autoriser plusieurs termes par argument." + +#: includes/argument.handlers.inc:937 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 or 1,2,3." +msgstr "Si cette option est sélectionnée, les utilisateurs peuvent saisir plusieurs arguments sous la forme 1+2+3 ou 1,2,3." + +#: includes/argument.handlers.inc:943 +msgid "Exclude the argument" +msgstr "Exclure l'argument" + +#: includes/argument.handlers.inc:944 +msgid "If selected, the numbers entered in the argument will be excluded rather than limiting the view." +msgstr "Si cette option est sélectionnée, les nombres saisis dans l'argument seront exclus plutôt que de limiter la vue." + +#: includes/argument.handlers.inc:951;963;1088;1102 +#: modules/taxonomy.views.inc:120;204;287 +msgid "Uncategorized" +msgstr "Sans catégorie" + +#: includes/argument.handlers.inc:967;1106 +msgid "Invalid input" +msgstr "Saisie invalide" + +#: includes/argument.handlers.inc:1039 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 (for OR) or 1,2,3 (for AND)." +msgstr "Si cette option est sélectionnée, les utilisateurs peuvent saisir plusieurs arguments sous la forme 1+2+3 (pour OU) ou 1,2,3 (pour ET)." + +#: includes/convert.inc:14 +msgid "There are no Views 1 views stored in the database to convert." +msgstr "Il n'y a aucune vue Views 1 enregistrée dans la base de données à convertir." + +#: includes/convert.inc:22 +msgid "Operations" +msgstr "Opérations" + +#: includes/convert.inc:33 +msgid "Converted" +msgstr "Converti" + +#: includes/convert.inc:68 +msgid "The table below lists Views version 1 views that are stored in the database. You can either convert them to work in Views version 2, or delete them. The views are convertible only if there is no Views 2 view with the same name." +msgstr "Le tableau ci-dessous dresse la liste des vues Views version 1 enregistrées dans la base de données. Vous pouvez, soit les convertir pour fonctionner avec Views version 2, soit les supprimer. Les vues ne peuvent être converties que s'il n'existe pas de vue Views 2 possédant le même nom." + +#: includes/convert.inc:79 +msgid "Unable to find view." +msgstr "Impossible de trouver la vue." + +#: includes/convert.inc:89 +msgid "Unable to convert view." +msgstr "Impossible de convertir la vue." + +#: includes/convert.inc:108 +msgid "This action cannot be undone." +msgstr "Cette action est irréversible." + +#: includes/convert.inc:118 +msgid "The view has been deleted" +msgstr "La vue a été supprimée" + +#: includes/field.handlers.inc:130 +#: includes/filter.handlers.inc:304 +#: includes/relationship.handlers.inc:60 +msgid "Label" +msgstr "Étiquette" + +#: includes/field.handlers.inc:132 +msgid "The label for this field that will be displayed to end users if the style requires it." +msgstr "L'étiquette de ce champ, qui sera affichée aux utilisateurs finaux si le style l'exige." + +#: includes/field.handlers.inc:136 +msgid "Exclude from display" +msgstr "Exclure de l'affichage" + +#: includes/field.handlers.inc:138 +msgid "Check this box to not display this field, but still load it in the view. Use this option to not show a grouping field in each record, or when doing advanced theming." +msgstr "Cochez cette case pour ne pas afficher ce champ mais le charger néanmoins dans la vue. Utilisez cette option pour ne pas montrer un champ de groupement dans chaque enregistrement ou lorsque vous travaillez sur des thèmes avancés." + +#: includes/field.handlers.inc:223 +msgid "Date format" +msgstr "Format de date" + +#: includes/field.handlers.inc:228 +msgid "Custom" +msgstr "Personnalisé" + +#: includes/field.handlers.inc:229 +msgid "Time ago" +msgstr "Il y a" + +#: includes/field.handlers.inc:235 +msgid "Custom date format" +msgstr "Format de date personnalisé" + +#: includes/field.handlers.inc:236 +msgid "If \"Custom\", see <a href=\"http://us.php.net/manual/en/function.date.php\">the PHP docs</a> for date formats. If \"Time ago\" this is the the number of different units to display, which defaults to two." +msgstr "Si \"Personnalisé\", référez-vous à <a href=\"http://fr.php.net/manual/fr/function.date.php\">la documentation PHP</a> relative aux formats de dates. Si \"Il y a\", il s'agit du nombre d'unités différentes à afficher, fixé par défaut à deux." + +#: includes/field.handlers.inc:252 +msgid "%time ago" +msgstr "Il y a %time" + +#: includes/field.handlers.inc:280 +msgid "Output format" +msgstr "Format de sortie" + +#: includes/field.handlers.inc:282 +msgid "Yes/No" +msgstr "Oui/Non" + +#: includes/field.handlers.inc:283 +msgid "True/False" +msgstr "Vrai/Faux" + +#: includes/field.handlers.inc:284 +msgid "On/Off" +msgstr "Activé/Désactivé" + +#: includes/field.handlers.inc:290 +msgid "Reverse" +msgstr "Inversé" + +#: includes/field.handlers.inc:291 +msgid "If checked, true will be displayed as false." +msgstr "Si cette option est cochée, Vrai apparaîtra comme Faux." + +#: includes/field.handlers.inc:305 +#: includes/filter.handlers.inc:853;898 +#: includes/plugins.inc:858;867;884;892;1035;2446 +msgid "Yes" +msgstr "Oui" + +#: includes/field.handlers.inc:305 +#: includes/filter.handlers.inc:853;898 +#: includes/plugins.inc:858;867;884;892;1035;1043;2446 +msgid "No" +msgstr "Non" + +#: includes/field.handlers.inc:307 +#: includes/filter.handlers.inc:822;863 +msgid "True" +msgstr "Vrai" + +#: includes/field.handlers.inc:307 +#: includes/filter.handlers.inc:863 +msgid "False" +msgstr "Faux" + +#: includes/field.handlers.inc:309 +msgid "On" +msgstr "Activé" + +#: includes/field.handlers.inc:309 +msgid "Off" +msgstr "Désactivé" + +#: includes/field.handlers.inc:368 +#: modules/statistics.views.inc:276 +msgid "Display as link" +msgstr "Afficher comme lien" + +#: includes/field.handlers.inc:410 +#: modules/node.views.inc:1289 +msgid "Display type" +msgstr "Type d'affichage" + +#: includes/field.handlers.inc:412 +#: includes/plugins.inc:2971 +msgid "Unordered list" +msgstr "Liste non ordonnée" + +#: includes/field.handlers.inc:413 +#: includes/plugins.inc:2971 +msgid "Ordered list" +msgstr "Liste ordonnée" + +#: includes/field.handlers.inc:414 +msgid "Simple separator" +msgstr "Séparateur simple" + +#: includes/field.handlers.inc:421 +#: includes/plugins.inc:3265;3376;3557 +msgid "Separator" +msgstr "Séparateur" + +#: includes/field.handlers.inc:429 +msgid "Empty list text" +msgstr "Texte de liste vide" + +#: includes/field.handlers.inc:431 +msgid "If the list is empty, you may enter text here that will be displayed." +msgstr "Si la liste est vide, vous pouvez saisir ici le texte qui devra être affiché." + +#: includes/field.handlers.inc:480 +msgid "Round" +msgstr "Arrondi" + +#: includes/field.handlers.inc:481 +msgid "If checked, the number will be rounded." +msgstr "Si cette option est coché, le nombre sera arrondi." + +#: includes/field.handlers.inc:486 +msgid "Precision" +msgstr "Précision" + +#: includes/field.handlers.inc:488 +msgid "Specify how many digits to print after the decimal point." +msgstr "Précisez le nombre de chiffres à afficher après le marqueur décimal." + +#: includes/field.handlers.inc:495 +msgid "Decimal point" +msgstr "Marqueur décimal" + +#: includes/field.handlers.inc:497 +msgid "What single character to use as a decimal point." +msgstr "Caractère à utiliser comme marqueur décimal" + +#: includes/field.handlers.inc:503 +msgid "Thousands separator" +msgstr "Séparateur de milliers" + +#: includes/field.handlers.inc:505 +msgid "What single character to use as the thousands separator." +msgstr "Caractère à utiliser pour séparer les milliers." + +#: includes/field.handlers.inc:510 +msgid "Prefix" +msgstr "Préfixe" + +#: includes/field.handlers.inc:512 +msgid "Text to put before the number, such as currency symbol." +msgstr "Texte à faire figurer avant le nombre, par exemple une unité monétaire." + +#: includes/field.handlers.inc:516 +msgid "Suffix" +msgstr "Suffixe" + +#: includes/field.handlers.inc:518 +msgid "Text to put after the number, such as currency symbol." +msgstr "Texte à faire figurer après le nombre, par exemple une unité monétaire." + +#: includes/filter.handlers.inc:119 +msgid "Operator" +msgstr "Opérateur" + +#: includes/filter.handlers.inc:183 +msgid "Expose" +msgstr "Exposer" + +#: includes/filter.handlers.inc:188 +msgid "This item is currently not exposed. If you <strong>expose</strong> it, users will be able to change the filter as they view it." +msgstr "Cet élément n'est pour le moment pas exposé. Si vous l'<strong>exposez</strong>, les utilisateurs pourront changer le filtre lorsqu'ils l'affichent." + +#: includes/filter.handlers.inc:195 +msgid "Hide" +msgstr "Cacher" + +#: includes/filter.handlers.inc:200 +msgid "This item is currently exposed. If you <strong>hide</strong> it, users will not able to change the filter as they view it." +msgstr "Cet élément est actuellement exposé. Si vous le <strong>cachez</strong>, les utilisateurs ne pourront pas changer le filtre lorsqu'ils l'affichent." + +#: includes/filter.handlers.inc:271 +msgid "Unlock operator" +msgstr "Déverrouiller l'opérateur" + +#: includes/filter.handlers.inc:272 +msgid "When checked, the operator will be exposed to the user" +msgstr "Si cette option est cochée, l'opérateur apparaîtra à l'utilisateur." + +#: includes/filter.handlers.inc:278 +msgid "Operator identifier" +msgstr "Identifiant de l'opérateur" + +#: includes/filter.handlers.inc:280 +msgid "This will appear in the URL after the ? to identify this operator." +msgstr "Ceci apparaîtra dans l'URL après le point d'interrogation ? pour identifier cet opérateur." + +#: includes/filter.handlers.inc:297 +msgid "Filter identifier" +msgstr "Identifiant du filtre" + +#: includes/filter.handlers.inc:299 +msgid "This will appear in the URL after the ? to identify this filter. Cannot be blank." +msgstr "Ceci apparaîtra dans l'URL après le point d'interrogation ? pour identifier ce filtre. Ne peut être laissé à blanc." + +#: includes/filter.handlers.inc:315 +msgid "Optional" +msgstr "Facultatif" + +#: includes/filter.handlers.inc:316 +msgid "This exposed filter is optional and will have added options to allow it not to be set." +msgstr "Ce filtre exposé est facultatif et proposera des options supplémentaires pour permettre de ne pas le paramétrer." + +#: includes/filter.handlers.inc:322 +msgid "Force single" +msgstr "Forcer l'unicité" + +#: includes/filter.handlers.inc:323 +msgid "Force this exposed filter to accept only one option." +msgstr "Forcer ce filtre exposé à n'accepter qu'une seule option." + +#: includes/filter.handlers.inc:329 +msgid "Remember" +msgstr "Mémoriser" + +#: includes/filter.handlers.inc:330 +msgid "Remember the last setting the user gave this filter." +msgstr "Mémoriser le dernier paramétrage utilisé par l'utilisateur pour ce filtre." + +#: includes/filter.handlers.inc:341 +msgid "" +"The identifier is required if the filter is\n" +" exposed." +msgstr "" +"L'identifiant est obligatoire si le filtre est\n" +" exposé." + +#: includes/filter.handlers.inc:347 +msgid "This identifier is not allowed." +msgstr "Cet identifiant n'est pas autorisé." + +#: includes/filter.handlers.inc:448 +msgid "<Any>" +msgstr "<N'importe lequel>" + +#: includes/filter.handlers.inc:540;582;1089 +msgid "Is equal to" +msgstr "Est égal à " + +#: includes/filter.handlers.inc:541;588;1095 +msgid "Is not equal to" +msgstr "N'est pas égal à" + +#: includes/filter.handlers.inc:551;714;1197 +msgid "Value" +msgstr "Valeur" + +#: includes/filter.handlers.inc:583;589;1091 +msgid "=" +msgstr "=" + +#: includes/filter.handlers.inc:594 +msgid "Contains" +msgstr "Contient" + +#: includes/filter.handlers.inc:595 +msgid "contains" +msgstr "contient" + +#: includes/filter.handlers.inc:600 +msgid "Contains any word" +msgstr "Contient n'importe quel mot" + +#: includes/filter.handlers.inc:601 +msgid "has word" +msgstr "contient le mot" + +#: includes/filter.handlers.inc:606 +msgid "Contains all words" +msgstr "Contient tous les mots" + +#: includes/filter.handlers.inc:607 +msgid "has all" +msgstr "contient tous" + +#: includes/filter.handlers.inc:612 +msgid "Starts with" +msgstr "Commence par" + +#: includes/filter.handlers.inc:613 +msgid "begins" +msgstr "commence" + +#: includes/filter.handlers.inc:618 +msgid "Ends with" +msgstr "Finit par" + +#: includes/filter.handlers.inc:619 +msgid "ends" +msgstr "finit" + +#: includes/filter.handlers.inc:624 +msgid "Does not contain" +msgstr "Ne contient pas" + +#: includes/filter.handlers.inc:625 +msgid "!has" +msgstr "!has" + +#: includes/filter.handlers.inc:634;1130 +msgid "Is empty (NULL)" +msgstr "Est vide (NULL)" + +#: includes/filter.handlers.inc:636;1132 +msgid "empty" +msgstr "vide" + +#: includes/filter.handlers.inc:640;1136 +msgid "Is not empty (NULL)" +msgstr "N'est pas vide (NULL)" + +#: includes/filter.handlers.inc:642;1138 +msgid "not empty" +msgstr "non vide" + +#: includes/filter.handlers.inc:665 +msgid "exposed>" +msgstr "exposé>" + +#: includes/filter.handlers.inc:672 +msgid "Case sensitive" +msgstr "Sensible à la casse" + +#: includes/filter.handlers.inc:674 +msgid "Case sensitive filters may be faster; MySQL might ignore case sensitivity." +msgstr "Les filtres sensibles à la casse peuvent être plus rapides ; MySQL peut ignorer la sensibilité à la casse." + +#: includes/filter.handlers.inc:860;1009 +msgid "exposed" +msgstr "exposé" + +#: includes/filter.handlers.inc:888 +msgid "Options" +msgstr "Options" + +#: includes/filter.handlers.inc:910 +msgid "Limit list to selected items" +msgstr "Limiter la liste aux éléments sélectionnés" + +#: includes/filter.handlers.inc:911 +msgid "If checked, the selected items presented to the user will be the only ones selected here." +msgstr "Si cette option est cochée, les éléments sélectionnés présentés à l'utilisateur seront uniquement ceux sélectionnés ici." + +#: includes/filter.handlers.inc:930;1459 +msgid "Is one of" +msgstr "Fait partie de" + +#: includes/filter.handlers.inc:931 +msgid "Is not one of" +msgstr "Ne fait pas partie de " + +#: includes/filter.handlers.inc:1022 +#: modules/system.views.inc:236 +msgid "Unknown" +msgstr "Inconnu" + +#: includes/filter.handlers.inc:1077 +msgid "Is less than" +msgstr "Est inférieur à" + +#: includes/filter.handlers.inc:1079 +msgid "<" +msgstr "<" + +#: includes/filter.handlers.inc:1083 +msgid "Is less than or equal to" +msgstr "Est inférieur ou égal à" + +#: includes/filter.handlers.inc:1085 +msgid "<=" +msgstr "<=" + +#: includes/filter.handlers.inc:1097 +msgid "!=" +msgstr "!=" + +#: includes/filter.handlers.inc:1101 +msgid "Is greater than or equal to" +msgstr "Est supérieur ou égal à" + +#: includes/filter.handlers.inc:1103 +msgid ">=" +msgstr ">=" + +#: includes/filter.handlers.inc:1107 +msgid "Is greater than" +msgstr "Est supérieur à" + +#: includes/filter.handlers.inc:1109 +msgid ">" +msgstr ">" + +#: includes/filter.handlers.inc:1113 +msgid "Is between" +msgstr "Est compris entre" + +#: includes/filter.handlers.inc:1115 +msgid "between" +msgstr "entre" + +#: includes/filter.handlers.inc:1119 +msgid "Is not between" +msgstr "N'est pas compris entre" + +#: includes/filter.handlers.inc:1121 +msgid "not between" +msgstr "pas entre" + +#: includes/filter.handlers.inc:1212 +msgid "Min" +msgstr "Min" + +#: includes/filter.handlers.inc:1218 +msgid "And max" +msgstr "Et max" + +#: includes/filter.handlers.inc:1218 +msgid "And" +msgstr "Et" + +#: includes/filter.handlers.inc:1275 +msgid "@min and @max" +msgstr "@min et @max" + +#: includes/filter.handlers.inc:1301 +msgid "Value type" +msgstr "Type de valeur" + +#: includes/filter.handlers.inc:1303 +msgid "A date in any machine readable format. CCYY-MM-DD HH:MM:SS is preferred." +msgstr "Date dans n'importe quel format machine. AAAA-MM-JJ HH:MM:SS est préférable" + +#: includes/filter.handlers.inc:1304 +msgid "An offset from the current time such as \"+1 day\" or \"-2 hours -30 minutes\"" +msgstr "Décalage à partir de l'heure courante, par exemple \"+1 jour\" ou \"-2 heures -30 minutes\"" + +#: includes/filter.handlers.inc:1354;1360;1364 +msgid "Invalid date format." +msgstr "Format de date invalide." + +#: includes/filter.handlers.inc:1460 +msgid "Is all of" +msgstr "Tout parmi" + +#: includes/filter.handlers.inc:1461 +msgid "Is none of" +msgstr "Aucun parmi" + +#: includes/handlers.inc:136 +msgid "!group: !title" +msgstr "!group : !title" + +#: includes/handlers.inc:336 +msgid "Broken/missing handler" +msgstr "Gestionnaire défectueux/manquant" + +#: includes/handlers.inc:344 +msgid "The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item." +msgstr "Le gestionnaire de cet élément est défectueux ou absent, et ne peut donc être utilisé. Si un module a fourni le gestionnaire puis a été désactivé, réactiver le module peut permettre de le restaurer. Sinon, vous devriez probablement supprimer cet élément." + +#: includes/handlers.inc:380 +msgid "Reduce duplicates" +msgstr "Supprimer les doublons" + +#: includes/handlers.inc:381 +msgid "This filter can cause items that have more than one of the selected options to appear as duplicate results. If this filter causes duplicate results to occur, this checkbox can reduce those duplicates; however, the more terms it has to search for, the less performant the query will be, so use this with caution." +msgstr "Ce filtre peut causer l'apparition de doublons pour les éléments possédant plusieurs des options sélectionnées. Si ce filtre provoque l'apparition de doublons, cette case peut supprimer les doublons en question. Toutefois, plus il y a de termes à rechercher, plus les performances de la requête diminueront : utilisez-la donc avec précautions." + +#: includes/plugins.inc:19 +msgid "Default settings for this view." +msgstr "Paramètres par défaut pour cette vue." + +#: includes/plugins.inc:33 +msgid "Display the view as a page, with a URL and menu links." +msgstr "Afficher la vue en tant que page, avec une URL et des liens de menu." + +#: includes/plugins.inc:44;53 +msgid "Block" +msgstr "Bloc" + +#: includes/plugins.inc:45 +msgid "Display the view as a block." +msgstr "Afficher la vue en tant que bloc." + +#: includes/plugins.inc:57 +msgid "Attachment" +msgstr "Fichier attaché" + +#: includes/plugins.inc:58 +msgid "Attachments added to other displays to achieve multiple views in the same view." +msgstr "Fichiers attachés à d'autres affichages pour parvenir à plusieurs vues à l'intérieur de la même vue." + +#: includes/plugins.inc:66 +msgid "Display the view as a feed, such as an RSS feed." +msgstr "Afficher la vue en tant que flux, par exemple un flux RSS." + +#: includes/plugins.inc:78;124 +msgid "Unformatted" +msgstr "Non mis en forme" + +#: includes/plugins.inc:79 +msgid "Displays rows one after another." +msgstr "Afficher les lignes les unes après les autres." + +#: includes/plugins.inc:89 +msgid "Displays rows as an HTML list." +msgstr "Afficher les lignes dans une liste HTML." + +#: includes/plugins.inc:97 +msgid "Grid" +msgstr "Grille" + +#: includes/plugins.inc:98 +msgid "Displays rows in a grid." +msgstr "Afficher les lignes dans une grille." + +#: includes/plugins.inc:106 +msgid "Table" +msgstr "Tableau" + +#: includes/plugins.inc:107 +msgid "Displays rows in a table." +msgstr "Afficher les lignes dans un tableau." + +#: includes/plugins.inc:117 +msgid "Displays the default summary summary as a list." +msgstr "Afficher le sommaire du sommaire par défaut en tant que liste." + +#: includes/plugins.inc:125 +msgid "Displays the summary unformatted, with option for one after another or inline." +msgstr "Affiche le sommaire sans mise en forme, les informations apparaissant, soit les unes après les autres, soit en ligne." + +#: includes/plugins.inc:132 +msgid "RSS Feed" +msgstr "Flux RSS" + +#: includes/plugins.inc:133 +msgid "Generates an RSS feed from a view." +msgstr "Génère un flux RSS à partir d'une vue." + +#: includes/plugins.inc:143 +#: includes/view.inc:1663 +msgid "Fields" +msgstr "Champs" + +#: includes/plugins.inc:144 +msgid "Displays the fields with an optional template." +msgstr "Affiche les champs avec un template facultatif." + +#: includes/plugins.inc:154 +msgid "Fixed entry" +msgstr "Entrée fixe" + +#: includes/plugins.inc:158;164 +msgid "PHP Code" +msgstr "Code PHP" + +#: includes/plugins.inc:168 +msgid "Numeric" +msgstr "Numérique" + +#: includes/plugins.inc:783 +msgid "Broken field" +msgstr "Champ brisé" + +#: includes/plugins.inc:800 +msgid "Basic settings" +msgstr "Paramètres de base" + +#: includes/plugins.inc:807 +msgid "Change the name of this display." +msgstr "Changer le nom de l'affichage." + +#: includes/plugins.inc:819 +msgid "Change the title that this display will use." +msgstr "Changer le titre que cet affichage utilisera." + +#: includes/plugins.inc:829 +msgid "Style" +msgstr "Style" + +#: includes/plugins.inc:831 +msgid "Change the style plugin." +msgstr "Changer le plugin de style." + +#: includes/plugins.inc:845 +msgid "Row style" +msgstr "Style de ligne" + +#: includes/plugins.inc:847 +msgid "Change the row plugin." +msgstr "Changer le plugin de ligne." + +#: includes/plugins.inc:857 +msgid "Use AJAX" +msgstr "Utiliser AJAX" + +#: includes/plugins.inc:859 +msgid "Change whether or not this display will use AJAX." +msgstr "Modifier si cet affichage utilisera ou non AJAX." + +#: includes/plugins.inc:866 +msgid "Use pager" +msgstr "Utiliser la pagination" + +#: includes/plugins.inc:867 +msgid "Mini" +msgstr "Mini" + +#: includes/plugins.inc:868 +msgid "Change this display's pager setting." +msgstr "Modifier les paramètres de pagination de cet affichage." + +#: includes/plugins.inc:875;1054 +msgid "Items per page" +msgstr "Éléments par page" + +#: includes/plugins.inc:875;1054;3339 +msgid "Items to display" +msgstr "Éléments à afficher" + +#: includes/plugins.inc:876 +msgid "Unlimited" +msgstr "Illimité" + +#: includes/plugins.inc:877 +msgid "Change how many items to display." +msgstr "Changer le nombre d'éléments à afficher." + +#: includes/plugins.inc:883 +msgid "More link" +msgstr "Lien \"plus\"" + +#: includes/plugins.inc:885 +msgid "Specify whether this display will provide a \"more\" link." +msgstr "Spécifie si cet affichage proposera un lien \"plus\"." + +#: includes/plugins.inc:891;1081 +msgid "Distinct" +msgstr "Distinct" + +#: includes/plugins.inc:893;1078 +msgid "Display only distinct items, without duplicates." +msgstr "Afficher uniquement les éléments distincts, sans doublon." + +#: includes/plugins.inc:904;1104 +msgid "Unrestricted" +msgstr "Illimité" + +#: includes/plugins.inc:912 +msgid "Multiple roles" +msgstr "Rôles multiples" + +#: includes/plugins.inc:924 +msgid "Access" +msgstr "Accès" + +#: includes/plugins.inc:926 +msgid "Specify access control settings for this display." +msgstr "Précise les paramètres de contrôle d'accès pour cet affichage." + +#: includes/plugins.inc:946 +msgid "Link display" +msgstr "Affichage de lien" + +#: includes/plugins.inc:948 +msgid "Specify which display this display will link to." +msgstr "Indique vers quel affichage conduit le lien de cet affichage." + +#: includes/plugins.inc:953;1143 +msgid "Header" +msgstr "Entête" + +#: includes/plugins.inc:953;1159 +msgid "Footer" +msgstr "Pied de page" + +#: includes/plugins.inc:953;1175 +msgid "Empty text" +msgstr "Texte de page vide" + +#: includes/plugins.inc:969 +msgid "Unknown/missing filter" +msgstr "Filtre inconnu/manquant" + +#: includes/plugins.inc:977 +msgid "Change this display's !name." +msgstr "Changer le !name de cet affichage." + +#: includes/plugins.inc:983 +msgid "Theme" +msgstr "Thème" + +#: includes/plugins.inc:984 +msgid "Information" +msgstr "Informations" + +#: includes/plugins.inc:985 +msgid "Get information on how to theme this display" +msgstr "Obtenir des informations sur comment créer un thème pour cet affichage" + +#: includes/plugins.inc:1011 +msgid "The name of this display" +msgstr "Nom de cet affichage" + +#: includes/plugins.inc:1014 +msgid "This title will appear only in the administrative interface for the View." +msgstr "Ce titre apparaîtra uniquement dans l'interface d'administration de la vue." + +#: includes/plugins.inc:1019 +msgid "The title of this view" +msgstr "Titre de cette vue" + +#: includes/plugins.inc:1022 +msgid "This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc." +msgstr "Ce titre sera affiché avec la vue, partout où des titres sont normalement affichés (par exemple titre de page, titre de bloc, etc.)." + +#: includes/plugins.inc:1027 +msgid "Use AJAX when available to load this view" +msgstr "Utiliser AJAX lorsque c'est possible pour charger cette vue" + +#: includes/plugins.inc:1031 +msgid "If set, this view will use an AJAX mechanism for paging, table sorting and exposed filters. This means the entire page will not refresh. It is not recommended that you use this if this view is the main content of the page as it will prevent deep linking to specific pages, but it is very useful for side content." +msgstr "Si cette option est sélectionnée, cette vue utilisera un mécanisme Ajax pour la pagination, le tri des tables et les filtres exposés. Cela signifie que la page n'aura pas à se rafraîchir entièrement. Il n'est pas recommandé d'utiliser cette option si cette vue constitue le contenu principal de la page, car elle empêche les liens profonds vers des pages spécifiques ; c'est toutefois très utile pour les contenus accessoires." + +#: includes/plugins.inc:1040 +msgid "Use a pager for this view" +msgstr "Utiliser une pagination pour cette vue" + +#: includes/plugins.inc:1043 +msgid "Full pager" +msgstr "Pagination complète" + +#: includes/plugins.inc:1043 +msgid "Mini pager" +msgstr "Mini-pagination" + +#: includes/plugins.inc:1048 +msgid "Pager element" +msgstr "Élément de pagination" + +#: includes/plugins.inc:1049 +msgid "Unless you're experiencing problems with pagers related to this view, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible." +msgstr "À moins que vous ne rencontriez des difficultés avec la pagination associée à cette vue, vous devriez laisser cette option à 0. Si vous utilisez plusieurs une pagination sur plusieurs pages, vous pouvez être amené à choisir une valeur plus élevée pour ce nombre afin d'éviter tout conflit avec ?page=array. Les valeurs importantes ajouteront un grand nombre de virgules à vos URL, c'est donc à éviter autant que possible." + +#: includes/plugins.inc:1058 +msgid "The number of items to display per page. Enter 0 for no limit." +msgstr "Nombre d'éléments à afficher par page. Choisissez 0 pour un nombre illimité." + +#: includes/plugins.inc:1063 +msgid "Offset" +msgstr "Décalage" + +#: includes/plugins.inc:1064 +msgid "The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed. Offset can not be used if items to display is 0; instead use a very large number there." +msgstr "Nombre d'éléments à sauter. Si, par exemple, ce champ vaut 3, les trois premiers éléments seront sautés et non affichés. Le décalage ne peut pas être utilisé si le nombre d'éléments à afficher vaut 0 ; vous devez au contraire utiliser un très grand nombre pour cette dernière valeur." + +#: includes/plugins.inc:1069 +msgid "Add a more link to the bottom of the display." +msgstr "Ajouter un lien \"plus\" en bas de l'affichage." + +#: includes/plugins.inc:1072 +msgid "Create more link" +msgstr "Créer un lien \"plus\"" + +#: includes/plugins.inc:1073 +msgid "This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' above." +msgstr "Ceci ajoute un lien \"plus\" en bas de la vue, qui conduit à la vue de la page. SI vous avez plusieurs vues de la page, le lien pointe vers l'affichage spécifié dans l'option 'Affichage de lien' ci-dessus." + +#: includes/plugins.inc:1082 +msgid "This will make the view display only distinct items. If there are multiple identical items, each will be displayed only once. You can use this to try and remove duplicates from a view, though it does not always work. Note that this can slow queries down, so use it with caution." +msgstr "Ceci contraint la vue à ne présenter que des éléments distincts. S'il existe plusieurs éléments identiques, chacun n'apparaîtra qu'une seule fois. Vous pouvez utiliser cette option pour essayer de supprimer les doublons d'une vue, bien que cela ne fonctionne pas toujours. Notez que cela peut ralentir les requêtes, c'est donc une option à utiliser avec précautions." + +#: includes/plugins.inc:1087 +msgid "Access restrictions" +msgstr "Restrictions d'accès" + +#: includes/plugins.inc:1104 +msgid "By role" +msgstr "Par rôle" + +#: includes/plugins.inc:1104 +msgid "By permission" +msgstr "Par droits d'accès" + +#: includes/plugins.inc:1113 +msgid "If by role" +msgstr "Si par rôle" + +#: includes/plugins.inc:1116 +msgid "Only the checked roles will be able to access this display. Note that users with \"access all views\" can see any view, regardless of role." +msgstr "Seuls les rôles cochés seront en mesure d'accéder à cet affichage. Notez que les utilisateurs disposant des droits \"accéder à toutes les vues\" pourront consulter toutes les vues, quel que soit leur rôle." + +#: includes/plugins.inc:1133 +msgid "If by permission" +msgstr "Si par droits d'accès" + +#: includes/plugins.inc:1135 +msgid "Only users with the selected permission flag will be able to access this display. Note that users with \"access all views\" can see any view, regardless of other permissions." +msgstr "Seuls les utilisateurs disposant du droit d'accès approprié pourront accéder à cet affichage. Notez que les utilisateurs disposant des droits \"accéder à toutes les vues\" pourront consulter toutes les vues, indépendamment des autres droits." + +#: includes/plugins.inc:1146;1162 +msgid "Display even if view has no result" +msgstr "Afficher même si la vue n'a pas de résultat" + +#: includes/plugins.inc:1153 +msgid "Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional." +msgstr "Texte à montrer en haut de la vue. Ceci peut contenir des explications, des liens ou tout ce que vous désirez. Optionnel." + +#: includes/plugins.inc:1169 +msgid "Text to display beneath the view. May contain an explanation or links or whatever you like. Optional." +msgstr "Texte à montrer sous la vue. Ceci peut contenir des explications, des liens ou tout ce que vous désirez. Optionnel." + +#: includes/plugins.inc:1180 +msgid "Text to display if the view has no results. Optional." +msgstr "Texte à afficher si la vue n'a pas de résultat. Optionnel." + +#: includes/plugins.inc:1186 +msgid "How should this view be styled" +msgstr "Style à appliquer à cette vue" + +#: includes/plugins.inc:1192 +msgid "If the style you choose has settings, be sure to click the settings button that will appear next to it in the View summary." +msgstr "Si le style de votre choix possède des paramètres, veillez à cliquer sur le bouton de paramétrage qui apparaîtra à son côté dans le résumé de la vue." + +#: includes/plugins.inc:1200 +msgid "You may also adjust the !settings for the currently selected style by clicking on the icon." +msgstr "Vous pouvez également adapter les !settings pour le style en cours en cliquant sur l'icône." + +#: includes/plugins.inc:1200;1242 +msgid "settings" +msgstr "paramètres" + +#: includes/plugins.inc:1206 +msgid "Style options" +msgstr "Options de style" + +#: includes/plugins.inc:1218 +msgid "Row style options" +msgstr "Options de style de ligne" + +#: includes/plugins.inc:1230 +msgid "How should each row in this view be styled" +msgstr "Comment les lignes de cette vue doivent être stylées" + +#: includes/plugins.inc:1242 +msgid "You may also adjust the !settings for the currently selected row style by clicking on the icon." +msgstr "Vous pouvez également adapter les !settings pour le style de la ligne en cours en cliquant sur l'icône." + +#: includes/plugins.inc:1248 +msgid "Which display to use for path" +msgstr "Affichage à utiliser pour le chemin" + +#: includes/plugins.inc:1257 +msgid "Which display to use to get this display's path for things like summary links, rss feed links, more links, etc." +msgstr "Quel affichage utiliser pour obtenir le chemin de cet affichage pour des éléments du type liens de résumé, liens de flux RSS, liens \"plus\", etc." + +#: includes/plugins.inc:1262 +msgid "Theming information" +msgstr "Informations de thème" + +#: includes/plugins.inc:1270 +msgid "Display output" +msgstr "Sortie de l'affichage" + +#: includes/plugins.inc:1275 +msgid "Style output" +msgstr "Sortie du style" + +#: includes/plugins.inc:1280 +msgid "Row style output" +msgstr "Sortie du style de ligne" + +#: includes/plugins.inc:1286 +msgid "Field @field" +msgstr "Champ @field" + +#: includes/plugins.inc:1294 +msgid "<strong>Important!</strong> When you add a new template to your theme, be sure to clear the theme registry cache. You can do this by visiting administer >> site building >> themes -- just loading the page should clear the cache." +msgstr "<strong>Important !</strong> Lorsque vous ajoutez un nouveau template à votre thème, veillez à bien vider le cache de registre du thème. Vous pouvez procéder en consultant la page administrer >> construction du site >> thèmes : le simple fait de charger la page devrait vider le cache." + +#: includes/plugins.inc:1306 +msgid "Theming information (display)" +msgstr "Informations de thème (affichage)" + +#: includes/plugins.inc:1307;1326;1347;1368 +msgid "Back to !info." +msgstr "Revenir à !info." + +#: includes/plugins.inc:1307;1326;1347;1368 +msgid "theming information" +msgstr "informations de thème" + +#: includes/plugins.inc:1310 +msgid "This display has no theming information" +msgstr "Cet affichage n'a aucune information de thème" + +#: includes/plugins.inc:1313 +msgid "This is the default theme template used for this display." +msgstr "Ceci est le template de thème par défaut utilisé pour cet affichage." + +#: includes/plugins.inc:1325 +msgid "Theming information (style)" +msgstr "Informations de thème (style)" + +#: includes/plugins.inc:1331 +msgid "This display has no style theming information" +msgstr "Cet affichage n'a aucune information de thème de style" + +#: includes/plugins.inc:1334 +msgid "This is the default theme template used for this style." +msgstr "Ceci est le template de thème par défaut utilisé pour ce style." + +#: includes/plugins.inc:1346;1367 +msgid "Theming information (row style)" +msgstr "Informations de thème (style de ligne)" + +#: includes/plugins.inc:1352 +msgid "This display has no row style theming information" +msgstr "Cet affichage n'a aucune information de thème de style de ligne" + +#: includes/plugins.inc:1355;1370 +msgid "This is the default theme template used for this row style." +msgstr "Ceci est le template de thème par défaut utilisé pour ce style de ligne." + +#: includes/plugins.inc:1434 +msgid "You must select at least one role if type is \"by role\"" +msgstr "Vous devez sélectionner au moins un rôle si le type est \"par rôle\"" + +#: includes/plugins.inc:1551 +msgid "Override" +msgstr "Supplanter" + +#: includes/plugins.inc:1563 +msgid "Use default" +msgstr "Utiliser la valeur par défaut" + +#: includes/plugins.inc:1756 +msgid "Display @display uses fields but there are none defined for it." +msgstr "L'affichage @display utilise des champs mais aucun champ n'est défini pour cet affichage." + +#: includes/plugins.inc:1760 +msgid "Display @display uses path but path is undefined." +msgstr "L'affichage @display utilise un chemin mais le chemin n'est pas défini." + +#: includes/plugins.inc:1765 +msgid "Display @display has an invalid style plugin." +msgstr "L'affichage @display présente un plugin de style invalide." + +#: includes/plugins.inc:1994 +msgid "Page settings" +msgstr "Paramètres de la page" + +#: includes/plugins.inc:2019 +msgid "No menu" +msgstr "Pas de menu" + +#: includes/plugins.inc:2022 +msgid "Normal: @title" +msgstr "Normal : @title" + +#: includes/plugins.inc:2026 +msgid "Tab: @title" +msgstr "Onglet : @title" + +#: includes/plugins.inc:2036 +msgid "Menu" +msgstr "Menu" + +#: includes/plugins.inc:2042 +msgid "Change settings for the parent menu" +msgstr "Changer les paramètres pour le menu parent" + +#: includes/plugins.inc:2055 +msgid "The menu path or URL of this view" +msgstr "Le chemin ou l'URL de menu pour cette vue" + +#: includes/plugins.inc:2059 +msgid "This view will be displayed by visiting this path on your site. You may use \"%\" in your URL to represent values that will be used for arguments: For example, \"node/%/feed\"." +msgstr "Cette vue sera affichée en visitant ce chemin sur votre site. Vous pouvez utiliser \"%\" dans votre URL pour représenter les valeurs qui seront utilisées comme arguments : par exemple \"node/%/feed\"." + +#: includes/plugins.inc:2065 +msgid "Menu item entry" +msgstr "Entrée d'élément de menu" + +#: includes/plugins.inc:2082 +msgid "No menu entry" +msgstr "Aucune entrée de menu" + +#: includes/plugins.inc:2083 +msgid "Normal menu entry" +msgstr "Entrée de menu normale" + +#: includes/plugins.inc:2084;2131 +msgid "Menu tab" +msgstr "Onglet de menu" + +#: includes/plugins.inc:2085 +msgid "Default menu tab" +msgstr "Onglet de menu par défaut" + +#: includes/plugins.inc:2094 +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "Si positionné à normal ou onglet, saisissez le texte à utiliser pour l'élément de menu." + +#: includes/plugins.inc:2103 +msgid "If set to tab, enter the weight of the item. The lower th weight the higher/further left it will appear." +msgstr "Si positionné à onglet, saisissez le poids de l'élément. Plus le poids est faible, plus il apparaîtra haut ou à gauche." + +#: includes/plugins.inc:2109 +msgid "Default tab options" +msgstr "Options d'onglet par défaut" + +#: includes/plugins.inc:2118 +msgid "When providing a menu item as a 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>." +msgstr "Lorsque l'on fournit un élément de menu en tant qu'onglet, Drupal a besoin de savoir quel sera l'élément de menu parent de cet onglet. Parfois le parent existe déjà, mais vous pouvez également être amené à en créer un. Le chemin d'un élément parent sera toujours le même chemin, dont la dernière partie est supprimée. Par exemple, si le chemin vers cette vue est <em>foo/bar/baz</em>, le chemin parent sera alors <em>foo/bar</em>." + +#: includes/plugins.inc:2129 +msgid "Parent menu item" +msgstr "Élément de menu parent" + +#: includes/plugins.inc:2131 +msgid "Already exists" +msgstr "Existe déjà" + +#: includes/plugins.inc:2131 +msgid "Normal menu item" +msgstr "Élément de menu normal" + +#: includes/plugins.inc:2139 +msgid "If creating a parent menu item, enter the title of the item." +msgstr "Si vous créez un élément de menu parent, saisissez le titre de l'élément." + +#: includes/plugins.inc:2145 +msgid "Tab weight" +msgstr "Poids de l'onglet" + +#: includes/plugins.inc:2149 +msgid "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." +msgstr "Si l'élément de menu parent est un onglet, saisissez le poids de l'onglet. Plus le nombre est faible, plus l'élément apparaîtra à gauche." + +#: includes/plugins.inc:2163 +msgid "\"$arg\" is no longer supported. Use % instead." +msgstr "\"$arg\" n'est plus pris en charge. Utilisez plutôt %." + +#: includes/plugins.inc:2173 +msgid "Views cannot create normal menu items for paths with a % in them." +msgstr "Views ne peut pas créer d'élément de menu normal pour les chemins comportant un %." + +#: includes/plugins.inc:2180 +msgid "A display whose path ends with a % cannot be a tab." +msgstr "Un affichage dont le chemin se termine par un % ne peut être un onglet." + +#: includes/plugins.inc:2185 +msgid "Title is required for this menu type." +msgstr "Le titre est obligatoire pour ce type de menu." + +#: includes/plugins.inc:2216 +msgid "Display @display is set to use a menu but the menu title is not set." +msgstr "L'affichage @display est configuré pour utiliser un menu mais le titre du menu n'est pas renseigné." + +#: includes/plugins.inc:2222 +msgid "Display @display is set to use a parent menu but the parent menu title is not set." +msgstr "L'affichage @display est configuré pour utiliser un menu parent mais le titre du menu parent n'est pas renseigné." + +#: includes/plugins.inc:2288 +msgid "Block settings" +msgstr "Paramètres des blocs" + +#: includes/plugins.inc:2302 +msgid "Admin" +msgstr "Admin" + +#: includes/plugins.inc:2314 +msgid "Caching" +msgstr "Mise en cache" + +#: includes/plugins.inc:2324 +msgid "Do not cache" +msgstr "Ne pas mettre en cache" + +#: includes/plugins.inc:2325 +msgid "Cache once for everything (global)" +msgstr "Mettre en cache une fois pour tout (global)" + +#: includes/plugins.inc:2326 +msgid "Per page" +msgstr "Par page" + +#: includes/plugins.inc:2327 +msgid "Per role" +msgstr "Par rôle" + +#: includes/plugins.inc:2328 +msgid "Per role per page" +msgstr "Par rôle par page" + +#: includes/plugins.inc:2329 +msgid "Per user" +msgstr "Par utilisateur" + +#: includes/plugins.inc:2330 +msgid "Per user per page" +msgstr "Par utilisateur par page" + +#: includes/plugins.inc:2355 +msgid "Block admin description" +msgstr "Description pour l'administration des blocs" + +#: includes/plugins.inc:2358 +msgid "This will appear as the name of this block in administer >> site building >> blocks." +msgstr "Ceci apparaîtra comme le nom de ce bloc dans administrer >> construction du site >> blocs." + +#: includes/plugins.inc:2363 +msgid "Block caching type" +msgstr "Type de mise en cache des blocs" + +#: includes/plugins.inc:2367 +msgid "This sets the default status for Drupal's built-in block caching method; this requires that caching be turned on in block administration, and be careful because you have little control over when this cache is flushed." +msgstr "Ceci positionne l'état par défaut pour la méthode de mise en cache de blocs intégrée à Drupal. Ceci nécessite d'activer la mise en cache dans l'administration des blocs. Attention car vous n'avez que très peu de contrôle sur la fréquence de vidage du cache." + +#: includes/plugins.inc:2418 +msgid "Before" +msgstr "Avant" + +#: includes/plugins.inc:2419 +msgid "After" +msgstr "Après" + +#: includes/plugins.inc:2420 +msgid "Both" +msgstr "Les deux" + +#: includes/plugins.inc:2440 +msgid "Attachment settings" +msgstr "Paramètres de fichiers attachés" + +#: includes/plugins.inc:2445;2486 +msgid "Inherit arguments" +msgstr "Hériter les arguments" + +#: includes/plugins.inc:2451;2495 +msgid "Position" +msgstr "Position" + +#: includes/plugins.inc:2457;2649 +msgid "Multiple displays" +msgstr "Affichages multiples" + +#: includes/plugins.inc:2472;2504;2664;2678 +msgid "Attach to" +msgstr "Attacher à" + +#: includes/plugins.inc:2489 +msgid "Inherit" +msgstr "Hériter" + +#: includes/plugins.inc:2490 +msgid "Should this display inherit its arguments from the parent display to which it is attached?" +msgstr "Cet affichage doit-il hériter ses arguments de l'affichage parent auquel il est attaché ?" + +#: includes/plugins.inc:2498;2687 +msgid "Attach before or after the parent display?" +msgstr "Attacher avant ou après l'affichage parent ?" + +#: includes/plugins.inc:2513 +msgid "Select which display or displays this should attach to." +msgstr "Sélectionnez à quel(s) affichage(s) ceci doit s'attacher." + +#: includes/plugins.inc:2641 +msgid "Feed settings" +msgstr "Paramètres de flux" + +#: includes/plugins.inc:2693 +msgid "This view will be displayed by visiting this path on your site. It is recommended that the path be something like \"path/%/%/feed\" or \"path/%/%/rss.xml\", putting one % in the path for each argument you have defined in the view." +msgstr "Cette vue sera affichée en visitant ce chemin sur votre site. Il est recommandé que le chemin soit du type \"path/%/%/feed\" ou \"path/%/%/rss.xml\" et de placer un caractère % dans le chemin pour chaque argument que vous avez défini dans la vue." + +#: includes/plugins.inc:2835 +msgid "Grouping field" +msgstr "Champ de regroupement" + +#: includes/plugins.inc:2838 +msgid "You may optionally specify a field by which to group the records. Leave blank to not group." +msgstr "Vous pouvez optionnellement spécifier un champ grâce au quel regrouper les enregistrements. Laisser à blanc pour ne rien regrouper." + +#: includes/plugins.inc:2923 +msgid "Style @style requires a row style but the row plugin is invalid." +msgstr "Le style @style nécessite un style de ligne mais le plugin de ligne est invalide." + +#: includes/plugins.inc:2970 +msgid "List type" +msgstr "Type de liste" + +#: includes/plugins.inc:3000 +msgid "Number of columns" +msgstr "Nombre de colonnes" + +#: includes/plugins.inc:3005 +msgid "Alignment" +msgstr "Alignement" + +#: includes/plugins.inc:3006 +msgid "Horizontal" +msgstr "Horizontal" + +#: includes/plugins.inc:3006 +msgid "Vertical" +msgstr "Vertical" + +#: includes/plugins.inc:3008 +msgid "Horizontal alignment will place items starting in the upper left and moving right. Vertical alignment will place items starting in the upper left and moving down." +msgstr "L'alighement horizontal place les éléments depuis le coin supérieur gauche et en allant vers la droite. L'alignement vertical positionne les éléments depuis le coin supérieur gauche et en allant vers le bas." + +#: includes/plugins.inc:3127 +msgid "You need at least one field before you can configure your table settings" +msgstr "Vous avez besoin d'au moins un champ avant de pouvoir configurer vos paramètres de tableau" + +#: includes/plugins.inc:3136 +msgid "Override normal sorting if click sorting is used" +msgstr "Supplanter le tri normal si le tri par clic est utilisé" + +#: includes/plugins.inc:3142 +msgid "Enable Drupal style \"sticky\" table headers (Javascript)" +msgstr "Activer les entêtes de tableau \"collants\" de Drupal (JavaScript)" + +#: includes/plugins.inc:3144 +msgid "(Sticky header effects will not be active for preview below, only on live output.)" +msgstr "(Les effets d'entêtes collants ne seront pas actifs pour la prévisualisation ci-dessous, uniquement pour une sortie réelle)." + +#: includes/plugins.inc:3149 +msgid "Default sort order" +msgstr "Ordre de tri par défaut" + +#: includes/plugins.inc:3150 +#: includes/sort.handlers.inc:60 +msgid "Ascending" +msgstr "Ascendant" + +#: includes/plugins.inc:3150 +#: includes/sort.handlers.inc:60 +msgid "Descending" +msgstr "Descendant" + +#: includes/plugins.inc:3152 +msgid "If a default sort order is selected, what order should it use by default." +msgstr "Si un ordre de tri par défaut est sélectionné, quel ordre celui-ci doit-il utiliser par défaut." + +#: includes/plugins.inc:3238 +msgid "Place fields into columns; you may combine multiple fields into the same column. If you do, the separator in the column specified will be used to separate the fields. Check the sortable box to make that column clicksortable, and check the default sort radio to determine which column will be sorted by default, if any. You may control column order and field labels in the fields section." +msgstr "Placez les champs dans des colonnes. Vous pouvez combiner plusieurs champs dans une même colonne. Si c'est le cas, le séparateur de la colonne spécifiée sera utilisé pour séparer les champs. Cochez la case classable pour rendre cette colonne classable par clic et cochez le bouton radio tri par défaut pour déterminer quelle colonne sera triée par défaut (s'il doit y en avoir une). Vous pouvez contrôler l'ordre des colonnes et les libellés des champs dans la section champs." + +#: includes/plugins.inc:3263 +#: includes/view.inc:1665 +msgid "Field" +msgstr "Champ" + +#: includes/plugins.inc:3264 +msgid "Column" +msgstr "Colonne" + +#: includes/plugins.inc:3267 +msgid "Sortable" +msgstr "Classable" + +#: includes/plugins.inc:3271 +msgid "Default sort" +msgstr "Tri par défaut" + +#: includes/plugins.inc:3330 +msgid "Display record count with link" +msgstr "Afficher le décompte d'enregistrements avec lien" + +#: includes/plugins.inc:3335 +msgid "Override number of items to display" +msgstr "Supplanter le nombre d'éléments à afficher" + +#: includes/plugins.inc:3372 +msgid "Display items inline" +msgstr "Afficher les éléments en ligne" + +#: includes/plugins.inc:3421 +msgid "Use the site mission for the description" +msgstr "Utiliser l'énoncé de mission du site pour la description" + +#: includes/plugins.inc:3425 +msgid "RSS description" +msgstr "Description RSS" + +#: includes/plugins.inc:3427 +msgid "This will appear in the RSS feed itself." +msgstr "Ceci apparaîtra dans le flux RSS lui-même." + +#: includes/plugins.inc:3550 +msgid "Inline fields" +msgstr "Champs en ligne" + +#: includes/plugins.inc:3553 +msgid "Inline fields will be displayed next to each other rather than one after another." +msgstr "Les champs en ligne seront affichés l'un à côté de l'autre plutôt que l'un après l'autre." + +#: includes/plugins.inc:3561 +msgid "The separator may be placed between inline fields to keep them from squishing up next to each other. You can use HTML in this field." +msgstr "Le séparateur peut être placé entre les champs en ligne pour éviter qu'ils ne s'entassent les uns sur les autres. Vous pouvez utiliser du HTML pour ce champ." + +#: includes/plugins.inc:3611 +msgid "Default argument" +msgstr "Argument par défaut" + +#: includes/plugins.inc:3653 +msgid "PHP argument code" +msgstr "Code d'argument PHP" + +#: includes/plugins.inc:3656 +msgid "Enter PHP code that returns a value to use for this argument. Do not use <?php ?>. You must return only a single value for just this argument." +msgstr "Saisissez un code PHP renvoyant la valeur à utiliser pour cet argument. N'utilisez pas <?php ?>. vous ne devez renvoyer qu'une seule valeur pour cet argument seul." + +#: includes/plugins.inc:3760 +msgid "PHP validate code" +msgstr "Code de validation PHP" + +#: includes/plugins.inc:3762 +msgid "Enter PHP code that returns TRUE or FALSE. No return is the same as FALSE, so be SURE to return something if you do not want to declare the argument invalid. Do not use <?php ?>. The argument to validate will be \"$argument\" and the view will be \"$view\". You may change the argument by setting \"$handler->argument\"." +msgstr "Saisissez un code PHP renvoyant TRUE ou FALSE. Si le code ne renvoie aucune valeur, c'est équivalent à FALSE : vous DEVEZ donc vous assurer que le code renvoie quelque chose si vous ne voulez pas déclarer un argument invalide. N'utilisez pas <?php ?>. L'argument à valider sera \"$argument\" et la vue \"$view\". Vous pouvez changer l'argument en positionnant \"$handler->argument\"." + +#: includes/relationship.handlers.inc:62 +msgid "The label for this relationship that will be displayed only administratively." +msgstr "Intitulé pour cette relation, qui ne sera affiché qu'à des fins d'administration." + +#: includes/relationship.handlers.inc:67 +msgid "Require this relationship" +msgstr "Exiger cette relation" + +#: includes/relationship.handlers.inc:68 +msgid "If required, items that do not contain this relationship will not appear." +msgstr "Si la relation est exigée, les éléments qui ne présentent pas cette relation n'apparaîtront pas." + +#: includes/sort.handlers.inc:43 +msgid "asc" +msgstr "asc" + +#: includes/sort.handlers.inc:47 +msgid "desc" +msgstr "desc" + +#: includes/sort.handlers.inc:59 +msgid "Sort order" +msgstr "Ordre de tri" + +#: includes/sort.handlers.inc:76 +msgid "views_handler_sort_formula missing default: @formula" +msgstr "Manque la valeur par défaut pour views_handler_sort_formula : @formula" + +#: includes/sort.handlers.inc:116 +msgid "Granularity" +msgstr "Granularité" + +#: includes/sort.handlers.inc:118 +msgid "Second" +msgstr "Seconde" + +#: includes/sort.handlers.inc:119 +msgid "Minute" +msgstr "Minute" + +#: includes/sort.handlers.inc:120 +msgid "Hour" +msgstr "Heure" + +#: includes/sort.handlers.inc:121 +msgid "Day" +msgstr "Jour" + +#: includes/sort.handlers.inc:122 +msgid "Month" +msgstr "Mois" + +#: includes/sort.handlers.inc:123 +msgid "Year" +msgstr "Année" + +#: includes/sort.handlers.inc:125 +msgid "The granularity is the smallest unit to use when determining whether two dates are the same; for example, if the granularity is \"Year\" then all dates in 1999, regardless of when they fall in 1999, will be considered the same date." +msgstr "La granularité est la plus petite unité à utiliser pour déterminer si deux dates sont identiques ; par exemple, si la granularité est \"Année\", toutes les dates de l'année 1999, indépendamment du mois et du jour, seront considérées comme identiques." + +#: includes/view.inc:224 +msgid "set_display called with invalid display id @display" +msgstr "set_display appelé avec un identifiant d'affichage @display invalide" + +#: includes/view.inc:946 +msgid "Home" +msgstr "Accueil" + +#: includes/view.inc:1664 +msgid "fields" +msgstr "champs" + +#: includes/view.inc:1666 +msgid "field" +msgstr "champ" + +#: includes/view.inc:1671 +msgid "arguments" +msgstr "arguments" + +#: includes/view.inc:1672;1673 +msgid "Argument" +msgstr "Argument" + +#: includes/view.inc:1677 +msgid "Sort criteria" +msgstr "Critères de tri" + +#: includes/view.inc:1678 +msgid "sort criteria" +msgstr "critères de tri" + +#: includes/view.inc:1679 +msgid "Sort criterion" +msgstr "Critère de tri" + +#: includes/view.inc:1680 +msgid "sort criterion" +msgstr "critère de tri" + +#: includes/view.inc:1684 +msgid "Filters" +msgstr "Filtres" + +#: includes/view.inc:1685 +msgid "filters" +msgstr "filtres" + +#: includes/view.inc:1686 +msgid "Filter" +msgstr "Filtre" + +#: includes/view.inc:1687 +msgid "filter" +msgstr "filtre" + +#: includes/view.inc:1692 +msgid "Relationships" +msgstr "Relations" + +#: includes/view.inc:1693 +msgid "relationships" +msgstr "relations" + +#: js/ajax.js:0;0;0;0;0;0;0 +#: js/ajax_view.js:0;0;0 +msgid "An error occurred at " +msgstr "Une erreur s'est produite à" + +#: js/tabs.js:0 +msgid "jQuery UI Tabs: Mismatching fragment identifier." +msgstr "Onglets d'interface jQuery : identifiant de fragment ne correspondant pas." + +#: js/tabs.js:0 +msgid "jQuery UI Tabs: Not enough arguments to add tab." +msgstr "Onglets d'interface jQuery : pas assez d'arguments pour ajouter l'onglet." + +#: modules/book.views.inc:21;36;46;99 +msgid "Book" +msgstr "Livre" + +#: modules/book.views.inc:30 +msgid "Top level book" +msgstr "Livre de plus haut niveau" + +#: modules/book.views.inc:31 +msgid "The book the node is in" +msgstr "Le livre dans lequel se trouve le nœud" + +#: modules/book.views.inc:58 +msgid "The weight of the book page." +msgstr "Le poids de la page de livre." + +#: modules/book.views.inc:69 +#: modules/comment.views.inc:202 +#: modules/taxonomy.views.inc:339 +msgid "Depth" +msgstr "Profondeur" + +#: modules/book.views.inc:70 +msgid "The depth of the book page in the hierarchy; top level books have a depth of 1." +msgstr "La profondeur de la page de livre dans la hiérarchie ; les livres de plus haut niveau ont une profondeur de 1." + +#: modules/book.views.inc:87 +msgid "Hierarchy" +msgstr "Hiérarchie" + +#: modules/book.views.inc:88 +msgid "The order of pages in the book hierarchy. Remember to sort by weight too if you want exactly the right order." +msgstr "L'ordre des pages dans la hiérarchie du livre. N'oubliez pas de trier aussi par poids si vous souhaitez exactement le bon ordre." + +#: modules/book.views.inc:110 +msgid "Parent" +msgstr "Parent" + +#: modules/book.views.inc:111 +msgid "The parent book node" +msgstr "Le nœud de livre parent" + +#: modules/book.views.inc:116 +msgid "Book parent" +msgstr "Parent de livre" + +#: modules/comment.views.inc:22;26;382;391 +msgid "Comment" +msgstr "Commentaire" + +#: modules/comment.views.inc:27 +msgid "Comments are responses to node content." +msgstr "Les commentaires sont des réponses au contenu des nœuds." + +#: modules/comment.views.inc:45 +msgid "The title of the comment." +msgstr "Le titre du commentaire." + +#: modules/comment.views.inc:63 +#: modules/node.views.inc:348 +msgid "Body" +msgstr "Corps" + +#: modules/comment.views.inc:64 +msgid "The text of the comment." +msgstr "Le texte du commentaire." + +#: modules/comment.views.inc:76 +msgid "ID" +msgstr "Identifiant" + +#: modules/comment.views.inc:77 +msgid "The commment ID of the field" +msgstr "L'identifiant de commentaire du champ" + +#: modules/comment.views.inc:95 +msgid "Author" +msgstr "Auteur" + +#: modules/comment.views.inc:96 +msgid "The name of the poster." +msgstr "Le nom du rédacteur." + +#: modules/comment.views.inc:114 +msgid "Author's website" +msgstr "Site web de l'auteur" + +#: modules/comment.views.inc:115 +msgid "The website address of the comment's author. Can be a link. The homepage can also be linked with the Name field. Will be empty if posted by a registered user." +msgstr "L'adresse du site web de l'auteur du commentaire. Peut être un lien. Le champ Name peut également servir à créer le lien vers la page d'accueil. Sera vide si le commentaire est publié par un utilisateur enregistré." + +#: modules/comment.views.inc:133 +#: modules/node.views.inc:107 +msgid "Post date" +msgstr "Date de publication" + +#: modules/comment.views.inc:134 +msgid "Date and time of when the comment was posted." +msgstr "Date et heure de publication du commentaire." + +#: modules/comment.views.inc:149 +msgid "In moderation" +msgstr "En cours de modération" + +#: modules/comment.views.inc:150 +msgid "Whether or not the comment is currently in moderation." +msgstr "Indique si le commentaire est en cours de modération ou non." + +#: modules/comment.views.inc:157 +msgid "Moderated" +msgstr "Modéré" + +#: modules/comment.views.inc:167 +msgid "View link" +msgstr "Lien d'affichage" + +#: modules/comment.views.inc:168 +msgid "Provide a simple link to view the comment." +msgstr "Fournit un lien simple pour afficher le commentaire." + +#: modules/comment.views.inc:176 +#: modules/node.views.inc:231 +#: modules/user.views.inc:204 +msgid "Edit link" +msgstr "Lien d'édition" + +#: modules/comment.views.inc:177 +msgid "Provide a simple link to edit the comment." +msgstr "Fournit un lien simple pour modifier le commentaire." + +#: modules/comment.views.inc:185 +#: modules/node.views.inc:239;461 +#: modules/user.views.inc:212 +msgid "Delete link" +msgstr "Lien de suppression" + +#: modules/comment.views.inc:186 +msgid "Provide a simple link to delete the comment." +msgstr "Fournit un lien simple pour supprimer le commentaire." + +#: modules/comment.views.inc:194 +msgid "Reply-to link" +msgstr "Lien de réponse" + +#: modules/comment.views.inc:195 +msgid "Provide a simple link to reply to the comment." +msgstr "Fournit un lien simple pour répondre au commentaire." + +#: modules/comment.views.inc:203 +msgid "Display the depth of the comment if it is threaded." +msgstr "Afficher la profondeur du commentaire s'il apparaît dans un fil." + +#: modules/comment.views.inc:207 +msgid "Thread" +msgstr "Fil" + +#: modules/comment.views.inc:208 +msgid "Sort by the threaded order. This will keep child comments together with their parents." +msgstr "Trier suivant l'ordre du fil. Ceci maintient les commentaires enfants avec leurs parents." + +#: modules/comment.views.inc:214 +#: modules/node.views.inc:1413 +msgid "Node ID" +msgstr "Identifiant de nœud" + +#: modules/comment.views.inc:215 +msgid "The node the comment is a reply to." +msgstr "Le nœud auquel répond le commentaire." + +#: modules/comment.views.inc:220;253 +#: modules/node.views.inc:24;29;89;347;362;473;1178;1187;1197 +msgid "Node" +msgstr "Node" + +#: modules/comment.views.inc:225 +msgid "User ID" +msgstr "Identifiant utilisateur" + +#: modules/comment.views.inc:226 +msgid "The user who wrote the comment." +msgstr "L'utilisateur ayant rédigé le commentaire." + +#: modules/comment.views.inc:231 +#: modules/node.views.inc:335 +#: modules/statistics.views.inc:201 +#: modules/user.views.inc:23;27;221 +msgid "User" +msgstr "Utilisateur" + +#: modules/comment.views.inc:236 +msgid "Parent CID" +msgstr "Identifiant du commentaire parent" + +#: modules/comment.views.inc:237 +msgid "The Comment ID of the parent comment." +msgstr "L'identifiant du commentaire parent." + +#: modules/comment.views.inc:245 +msgid "Parent comment" +msgstr "Commentaire parent" + +#: modules/comment.views.inc:266 +msgid "Last comment time" +msgstr "Heure du dernier commentaire" + +#: modules/comment.views.inc:267 +msgid "Date and time of when the last comment was posted." +msgstr "Date et heure de publication du dernier commentaire." + +#: modules/comment.views.inc:282 +msgid "Last comment author" +msgstr "Auteur du dernier commentaire" + +#: modules/comment.views.inc:283 +msgid "The name of the author of the last posted comment." +msgstr "Le nom de l'auteur ayant rédigé le dernier commentaire." + +#: modules/comment.views.inc:295 +msgid "Comment count" +msgstr "Décompte de commentaires" + +#: modules/comment.views.inc:296 +msgid "The number of comments a node has." +msgstr "Le nombre de commentaires que présente un nœud." + +#: modules/comment.views.inc:314 +msgid "Updated/commented date" +msgstr "Date de mise à jour/commentaire" + +#: modules/comment.views.inc:315 +msgid "The most recent of last comment posted or node updated time." +msgstr "L'information la plus récente entre le dernier commentaire publié et la date de dernière mise à jour du nœud." + +#: modules/comment.views.inc:338 +msgid "New comments" +msgstr "Nouveau commentaires" + +#: modules/comment.views.inc:339 +msgid "The number of new comments on the node." +msgstr "Le nombre de nouveaux commentaires au sein du nœud." + +#: modules/comment.views.inc:347 +msgid "Comment status" +msgstr "Statut des commentaires" + +#: modules/comment.views.inc:348 +msgid "Whether comments are enabled or disabled on the node." +msgstr "Indique si les commentaires sont activés ou désactivés sur le nœud." + +#: modules/comment.views.inc:362 +msgid "User posted or commented" +msgstr "Publié ou commenté par l'utilisateur" + +#: modules/comment.views.inc:363 +msgid "Display comments only if a user posted the node or commented on the node." +msgstr "Afficher les commentaires uniquement si un utilisateur a publié le nœud ou rédigé des commentaires à son sujet" + +#: modules/comment.views.inc:383 +msgid "Display the comment with standard comment view." +msgstr "Afficher le commentaire avec la vue de commentaire standard." + +#: modules/comment.views.inc:392 +msgid "Display the comment as RSS." +msgstr "Afficher le commentaire en tant que RSS." + +#: modules/comment.views.inc:462 +msgid "Link this field to its comment" +msgstr "Lier ce champ à son commentaire" + +#: modules/comment.views.inc:506 +msgid "Link this field to its user or an author's homepage" +msgstr "Lier ce champ à son utilisateur ou à la page d'accueil d'un auteur" + +#: modules/comment.views.inc:553 +#: modules/node.views.inc:601 +#: modules/user.views.inc:447 +msgid "Text to display" +msgstr "Texte à afficher" + +#: modules/comment.views.inc:564 +#: modules/node.views.inc:612 +#: modules/user.views.inc:463 +msgid "view" +msgstr "voir" + +#: modules/comment.views.inc:589 +#: modules/node.views.inc:643 +#: modules/user.views.inc:481 +msgid "edit" +msgstr "éditer" + +#: modules/comment.views.inc:605 +#: modules/node.views.inc:673;752 +#: modules/user.views.inc:499 +msgid "delete" +msgstr "supprimer" + +#: modules/comment.views.inc:621 +msgid "reply" +msgstr "répondre" + +#: modules/comment.views.inc:764 +msgid "Link this field to new comments" +msgstr "Lier ce champ aux nouveaux commentaires" + +#: modules/comment.views.inc:769 +msgid "Display nothing if no new comments" +msgstr "Ne rien afficher s'il n'y a pas de nouveau commentaire" + +#: modules/comment.views.inc:836 +#: modules/user.views.inc:606 +msgid "Anonymous" +msgstr "Anonyme" + +#: modules/comment.views.inc:842 +msgid "No user" +msgstr "Aucun utilisateur" + +#: modules/comment.views.inc:878;895 +msgid "Disabled" +msgstr "Désactivé" + +#: modules/comment.views.inc:880;896 +msgid "Read only" +msgstr "Lecture uniquement" + +#: modules/comment.views.inc:882;897 +msgid "Read/Write" +msgstr "Lecture/Écriture" + +#: modules/comment.views.inc:917 +#: modules/node.views.inc:1235 +msgid "Display links" +msgstr "Afficher les liens" + +#: modules/node.views.inc:30 +msgid "Nodes are a Drupal site's primary content." +msgstr "Les nœuds constituent le contenu primaire d'un site Drupal." + +#: modules/node.views.inc:57 +msgid "Nid" +msgstr "Nid" + +#: modules/node.views.inc:58 +msgid "The node ID of the node." +msgstr "Identifiant du nœud." + +#: modules/node.views.inc:85;403 +msgid "The title of the node." +msgstr "Titre du nœud." + +#: modules/node.views.inc:108 +msgid "The date the node was posted." +msgstr "Date de publication du nœud." + +#: modules/node.views.inc:123 +msgid "Updated date" +msgstr "Date de mise à jour" + +#: modules/node.views.inc:124 +msgid "The date the node was last updated." +msgstr "Date de dernière mise à jour du nœud." + +#: modules/node.views.inc:140 +msgid "The type of a node (for example, \"blog entry\", \"forum post\", \"story\", etc)." +msgstr "Type d'un nœud (par exemple, \"billet de blog\", \"discussion de forum\", \"article\", etc.)." + +#: modules/node.views.inc:158;166;180 +#: modules/upload.views.inc:74 +msgid "Published" +msgstr "Publié" + +#: modules/node.views.inc:159 +msgid "The published status of the node." +msgstr "Statut de publication du nœud." + +#: modules/node.views.inc:175 +msgid "Published or admin" +msgstr "Publié ou admin" + +#: modules/node.views.inc:176 +msgid "Filters out unpublished nodes if the current user cannot view them." +msgstr "Filtre et exclut les nœuds non publiés si l'utilisateur courant ne peut pas les voir." + +#: modules/node.views.inc:186;194 +msgid "Promoted to front page" +msgstr "Promu en page d'accueil" + +#: modules/node.views.inc:187 +msgid "The front page of the node." +msgstr "Page d'accueil du nœud." + +#: modules/node.views.inc:203;212 +msgid "Sticky" +msgstr "Collant" + +#: modules/node.views.inc:204 +msgid "Whether or not the node is sticky." +msgstr "Indique si le nœud est collant ou non." + +#: modules/node.views.inc:223 +msgid "Link" +msgstr "Lien" + +#: modules/node.views.inc:224 +msgid "Provide a simple link to the node." +msgstr "Fournit un lien simple vers le nœud." + +#: modules/node.views.inc:232 +msgid "Provide a simple link to edit the node." +msgstr "Fournit un lien simple pour éditer le nœud." + +#: modules/node.views.inc:240 +msgid "Provide a simple link to delete the node." +msgstr "Fournit un lien simple pour supprimer le nœud." + +#: modules/node.views.inc:248;1115 +msgid "Language" +msgstr "Langue" + +#: modules/node.views.inc:249 +msgid "The language the content is in." +msgstr "Langue de rédaction du contenu." + +#: modules/node.views.inc:266;437 +#: modules/user.views.inc:125 +msgid "Created date" +msgstr "Date de création" + +#: modules/node.views.inc:267 +msgid "In the form of CCYYMMDD." +msgstr "Sous la forme AAAAMMJJ." + +#: modules/node.views.inc:275 +msgid "Created year + month" +msgstr "Année + mois de création" + +#: modules/node.views.inc:276 +msgid "In the form of YYYYMM." +msgstr "Sous la forme AAAAMM." + +#: modules/node.views.inc:284 +msgid "Created year" +msgstr "Année de création" + +#: modules/node.views.inc:285 +msgid "In the form of YYYY." +msgstr "Sous la forme AAAA." + +#: modules/node.views.inc:293 +msgid "Created month" +msgstr "Mois de création" + +#: modules/node.views.inc:294 +msgid "In the form of MM (01 - 12)." +msgstr "Sous la forme MM (01 - 12)." + +#: modules/node.views.inc:302 +msgid "Created week" +msgstr "Semaine de création" + +#: modules/node.views.inc:303 +msgid "In the form of WW (01 - 53)." +msgstr "Sous la forme SS (01 - 53)." + +#: modules/node.views.inc:315;320 +msgid "Node revision" +msgstr "Révision du nœud" + +#: modules/node.views.inc:321 +msgid "Node revisions are a history of changes to nodes." +msgstr "Les révisions du nœud représente l'historique des modifications de ce nœud." + +#: modules/node.views.inc:336 +msgid "Relate a node revision to the user who created the revision." +msgstr "Associer une révision à l'utilisateur qui en est l'auteur." + +#: modules/node.views.inc:341 +msgid "user" +msgstr "utilisateur" + +#: modules/node.views.inc:349 +msgid "The actual, full data in the body field; this may not be valid data on all node types." +msgstr "Les données effectives et complètes du champ corps ; ces données peuvent n'être pas valides sur tous les types de nœuds." + +#: modules/node.views.inc:363 +msgid "Teaser" +msgstr "Résumé" + +#: modules/node.views.inc:364 +msgid "The stored teaser field. This may not be valid or useful data on all node types." +msgstr "Le champ du résumé enregistré. Ceci peut ne pas être valide ou utile pour tous les types de nœuds." + +#: modules/node.views.inc:377 +msgid "Vid" +msgstr "Vid" + +#: modules/node.views.inc:378 +msgid "The revision ID of the node revision." +msgstr "Identifiant de révision du nœud." + +#: modules/node.views.inc:423 +msgid "Log message" +msgstr "Message de journal" + +#: modules/node.views.inc:424 +msgid "The log message entered when the revision was created." +msgstr "Le message enregistré dans le journal à la création de la révision." + +#: modules/node.views.inc:438 +msgid "The date the node revision was created." +msgstr "La date de création de la révision du nœud." + +#: modules/node.views.inc:453 +msgid "Revert link" +msgstr "Lien de retour arrière" + +#: modules/node.views.inc:454 +msgid "Provide a simple link to revert to the revision." +msgstr "Fournit un lien simple pour revenir à une révision antérieure." + +#: modules/node.views.inc:462 +msgid "Provide a simple link to delete the node revision." +msgstr "Fournit un lien simple pour supprimer la révision du nœud." + +#: modules/node.views.inc:489 +msgid "Has new content" +msgstr "Présente des contenus nouveaux" + +#: modules/node.views.inc:492 +msgid "Show a marker if the node has new or updated content." +msgstr "Affiche un marqueur si le nœud présente des contenus nouveaux ou mis à jour." + +#: modules/node.views.inc:495 +msgid "Show only nodes that have new content." +msgstr "Afficher uniquement les nœuds présentant des contenus nouveaux" + +#: modules/node.views.inc:528 +msgid "Link this field to its node" +msgstr "Lier ce champ à son nœud" + +#: modules/node.views.inc:713 +msgid "revert" +msgstr "revenir" + +#: modules/node.views.inc:788 +msgid "Check for new comments as well" +msgstr "Vérifier aussi la présence de nouveaux commentaires" + +#: modules/node.views.inc:860 +msgid "Unknown node type" +msgstr "Type de nœud inconnu" + +#: modules/node.views.inc:1043 +msgid "Week @week" +msgstr "Semaine @week" + +#: modules/node.views.inc:1055 +msgid "Node type" +msgstr "Type de nœud" + +#: modules/node.views.inc:1116 +msgid "Current user's language" +msgstr "Langue de l'utilisateur courant" + +#: modules/node.views.inc:1116 +msgid "No language" +msgstr "Pas de langue" + +#: modules/node.views.inc:1166 +msgid "Unknown language" +msgstr "Langue inconnue" + +#: modules/node.views.inc:1179;1188 +msgid "Display the node with standard node view." +msgstr "Afficher le nœud avec une vue de nœud standard." + +#: modules/node.views.inc:1203 +msgid "Node ID from URL" +msgstr "Identifiant du nœud à partir de l'URL" + +#: modules/node.views.inc:1230 +msgid "Display only teaser" +msgstr "Afficher uniquement le résumé" + +#: modules/node.views.inc:1291 +msgid "Full text" +msgstr "Texte entier" + +#: modules/node.views.inc:1292 +msgid "Title plus teaser" +msgstr "Titre et résumé" + +#: modules/node.views.inc:1293 +msgid "Title only" +msgstr "Titre seulement" + +#: modules/node.views.inc:1294 +msgid "Use default RSS settings" +msgstr "Utiliser le paramétrage RSS par défaut" + +#: modules/node.views.inc:1360 +msgid "read more" +msgstr "en lire plus" + +#: modules/node.views.inc:1393 +msgid "Types" +msgstr "Types" + +#: modules/node.views.inc:1396 +msgid "If you wish to validate for specific node types, check them; if none are checked, all nodes will pass." +msgstr "Si vous souhaitez une validation pour certains types de nœuds spécifiques, cochez-les ; si aucun nœud n'est coché, tous les nœuds seront acceptés." + +#: modules/node.views.inc:1403 +msgid "Validate user has access to the node" +msgstr "L'utilisateur de validation a accès au nœud" + +#: modules/node.views.inc:1411 +#: modules/taxonomy.views.inc:1044 +msgid "Argument type" +msgstr "Type d'argument" + +#: modules/node.views.inc:1414 +msgid "Node IDs separated by , or +" +msgstr "Identifiants des nœuds séparés par des virgules ou des +" + +#: modules/node.views.inc:1533 +msgid "Display %display has no access control but does not contain a filter for published nodes." +msgstr "L'affichage @display ne présente aucun contrôle d'accès mais il ne contient pas de filtre pour les nœuds publiés." + +#: modules/poll.views.inc:23 +msgid "Poll" +msgstr "Sondage" + +#: modules/poll.views.inc:38;47 +#: modules/user.views.inc:173;182 +msgid "Active" +msgstr "Actif" + +#: modules/poll.views.inc:39 +msgid "Whether the poll is open for voting." +msgstr "Indique si le sondage enregistre toujours les votes." + +#: modules/profile.views.inc:20;40 +msgid "Profile" +msgstr "Profil" + +#: modules/profile.views.inc:100 +msgid "@field-name" +msgstr "@field-name" + +#: modules/profile.views.inc:107 +msgid "Profile textfield" +msgstr "Champ de texte de profil" + +#: modules/profile.views.inc:126 +msgid "Profile textarea" +msgstr "Zone de texte de profil" + +#: modules/profile.views.inc:142 +msgid "Profile checkbox" +msgstr "Case à cocher de profil" + +#: modules/profile.views.inc:159 +msgid "Profile URL" +msgstr "URL de profil" + +#: modules/profile.views.inc:175 +msgid "Profile selection" +msgstr "Sélection de profil" + +#: modules/profile.views.inc:195 +msgid "Profile freeform list %field-name." +msgstr "Liste libre de profil %field-name." + +#: modules/profile.views.inc:207 +msgid "Profile date %field-name." +msgstr "Date de profil %field-name." + +#: modules/search.views.inc:23;77;88;106;172;247 +msgid "Search" +msgstr "Recherche" + +#: modules/search.views.inc:72 +msgid "Score" +msgstr "Score" + +#: modules/search.views.inc:73 +msgid "The score of the search item." +msgstr "Score de l'élément de recherche." + +#: modules/search.views.inc:95 +msgid "Links from" +msgstr "Liens en provenance de" + +#: modules/search.views.inc:96 +msgid "Nodes that link from the node." +msgstr "Nœuds vers lesquels pointe le nœud." + +#: modules/search.views.inc:113 +msgid "Links to" +msgstr "Liens vers" + +#: modules/search.views.inc:114 +msgid "Nodes that link to the node." +msgstr "Nœuds pointant vers le nœud." + +#: modules/search.views.inc:125 +msgid "Search Terms" +msgstr "Termes de recherche" + +#: modules/search.views.inc:126 +msgid "The terms to search for." +msgstr "Termes à rechercher." + +#: modules/search.views.inc:156 +msgid "On empty input" +msgstr "En cas de saisie vide" + +#: modules/search.views.inc:159 +msgid "Show All" +msgstr "Montrer tous" + +#: modules/search.views.inc:160 +msgid "Show None" +msgstr "Montrer aucun" + +#: modules/search.views.inc:175 +msgid "Enter the terms you wish to search for." +msgstr "Entrez les termes que vous voulez rechercher." + +#: modules/search.views.inc:190 +msgid "You must include at least one positive keyword with @count characters or more." +msgstr "Vous devez inclure au moins un mot-clé positif de @count caractères ou plus." + +#: modules/search.views.inc:194 +msgid "Search for either of the two terms with uppercase <strong>OR</strong>. For example, <strong>cats OR dogs</strong>." +msgstr "Cherche l'un ou l'autre termes avec <strong>OR</strong> en majuscule. Par exemple : <strong>chats OR chiens</strong>." + +#: modules/search.views.inc:248 +msgid "Display the results with standard search view." +msgstr "Afficher les résultats avec la vue de recherche standard." + +#: modules/search.views.inc:274 +msgid "Display score" +msgstr "Afficher le score" + +#: modules/statistics.views.inc:24 +msgid "Node statistics" +msgstr "Statistiques du nœud" + +#: modules/statistics.views.inc:36 +msgid "Total views" +msgstr "Nombre total d'affichages" + +#: modules/statistics.views.inc:37 +msgid "The total number of times the node has been viewed." +msgstr "Le nombre total d'affichages du nœud." + +#: modules/statistics.views.inc:53 +msgid "Views today" +msgstr "Affichages aujourd'hui" + +#: modules/statistics.views.inc:54 +msgid "The total number of times the node has been viewed today." +msgstr "Le nombre total d'affichage du nœud aujourd'hui." + +#: modules/statistics.views.inc:70 +msgid "Most recent view" +msgstr "Dernier affichage" + +#: modules/statistics.views.inc:71 +msgid "The most recent time the node has been viewed." +msgstr "Date de dernier affichage du nœud." + +#: modules/statistics.views.inc:86;91 +msgid "Access log" +msgstr "Journal d'accès" + +#: modules/statistics.views.inc:92 +msgid "Stores site access information." +msgstr "Enregistre les informations relatives à l'accès au site." + +#: modules/statistics.views.inc:106 +msgid "Session ID" +msgstr "Identifiant de session" + +#: modules/statistics.views.inc:107 +msgid "Browser session ID of user that visited page." +msgstr "Identifiant de session du navigateur pour l'utilisateur ayant consulté cette page." + +#: modules/statistics.views.inc:126 +msgid "Page title" +msgstr "Titre de la page" + +#: modules/statistics.views.inc:127 +msgid "Title of page visited." +msgstr "Titre de la page consultée." + +#: modules/statistics.views.inc:147 +msgid "Internal path to page visited (relative to Drupal root.)" +msgstr "Chemin interne vers la page visitée (relatif à la racine de Drupal)." + +#: modules/statistics.views.inc:166 +msgid "Referrer" +msgstr "Référent" + +#: modules/statistics.views.inc:167 +msgid "Referrer URI." +msgstr "URI référent." + +#: modules/statistics.views.inc:182 +msgid "Hostname" +msgstr "Nom d'hôte" + +#: modules/statistics.views.inc:183 +msgid "Hostname of user that visited the page." +msgstr "Nom d'hôte de l'utilisateur ayant consulté la page." + +#: modules/statistics.views.inc:202 +msgid "The user who visited the site." +msgstr "L'utilisateur ayant visité le site." + +#: modules/statistics.views.inc:212 +msgid "Timer" +msgstr "Chronomètre" + +#: modules/statistics.views.inc:213 +msgid "Time in milliseconds that the page took to load." +msgstr "Temps de chargement de la page en millisecondes." + +#: modules/statistics.views.inc:228 +msgid "Timestamp" +msgstr "Horodatage" + +#: modules/statistics.views.inc:229 +msgid "Timestamp of when the page was visited." +msgstr "Tampon d'horodatage de la dernière visite de la page." + +#: modules/system.views.inc:25;30 +msgid "File" +msgstr "Fichier" + +#: modules/system.views.inc:31 +msgid "Files maintained by Drupal and various modules." +msgstr "Fichiers maintenus par Drupal et différents modules." + +#: modules/system.views.inc:49 +msgid "File ID" +msgstr "Identifiant de fichier" + +#: modules/system.views.inc:50 +msgid "The ID of the file." +msgstr "Identifiant du fichier." + +#: modules/system.views.inc:70 +msgid "The name of the file." +msgstr "Nom du fichier." + +#: modules/system.views.inc:89 +msgid "The path of the file." +msgstr "Chemin du fichier." + +#: modules/system.views.inc:107 +msgid "Mime type" +msgstr "Type MIME" + +#: modules/system.views.inc:108 +msgid "The mime type of the file." +msgstr "Le type MIME du fichier." + +#: modules/system.views.inc:126 +msgid "Size" +msgstr "Taille" + +#: modules/system.views.inc:127 +msgid "The size of the file." +msgstr "La taille du fichier." + +#: modules/system.views.inc:142 +msgid "Status" +msgstr "Statut" + +#: modules/system.views.inc:143 +msgid "The status of the file." +msgstr "Le statut du fichier." + +#: modules/system.views.inc:158 +msgid "Upload date" +msgstr "Date de transfert" + +#: modules/system.views.inc:159 +msgid "The date the file was uploaded." +msgstr "La date de transfert du fichier." + +#: modules/system.views.inc:204 +#: modules/upload.views.inc:145;216 +msgid "Link this field to download the file" +msgstr "Liez ce champ pour télécharger le fichier" + +#: modules/system.views.inc:231 +msgid "Temporary" +msgstr "Temporaire" + +#: modules/system.views.inc:232 +msgid "Permanent" +msgstr "Permanent" + +#: modules/system.views.inc:278 +msgid "No title" +msgstr "Sans titre" + +#: modules/taxonomy.views.inc:24;73;143;161;219;255;298;309 +msgid "Taxonomy" +msgstr "Taxonomie" + +#: modules/taxonomy.views.inc:54 +msgid "Vocabulary name" +msgstr "Nom du vocabulaire" + +#: modules/taxonomy.views.inc:56 +msgid "Name of the vocabulary a term is a member of. This will be the vocabulary that whichever term the \"Taxonomy: Term\" field is; and can similarly cause duplicates." +msgstr "Nom du vocabulaire dont le terme fait partie. C'est le vocabulaire correspondant au terme du champ \"Taxonomie : Terme\" et peut, de façon similaire, générer des doublons." + +#: modules/taxonomy.views.inc:62 +msgid "Vocabulary ID" +msgstr "Identifiant de vocabulaire" + +#: modules/taxonomy.views.inc:63 +msgid "The taxonomy vocabulary ID" +msgstr "L'identifiant du vocabulaire taxonomique" + +#: modules/taxonomy.views.inc:76;107 +msgid "Term" +msgstr "Terme" + +#: modules/taxonomy.views.inc:77 +msgid "Taxonomy terms are attached to nodes." +msgstr "Les termes de taxonomie sont rattachés aux nœuds." + +#: modules/taxonomy.views.inc:108 +msgid "Taxonomy terms. Note that using this can cause duplicate nodes to appear in views; you must add filters to reduce the resultset." +msgstr "Termes de taxonomie. Notez que leur utilisation peut causer l'apparition de doublons parmi les nœuds dans les vues, vous devez donc ajouter des filtres pour limiter l'ensemble des résultats." + +#: modules/taxonomy.views.inc:118 +msgid "Taxonomy term name" +msgstr "Nom du terme de classification" + +#: modules/taxonomy.views.inc:127 +msgid "The term weight field" +msgstr "Champ du poids du terme" + +#: modules/taxonomy.views.inc:139 +msgid "Term description" +msgstr "Description du terme" + +#: modules/taxonomy.views.inc:140 +msgid "The description associated with a taxonomy term." +msgstr "La description associée à un terme de classification." + +#: modules/taxonomy.views.inc:151;763 +msgid "Vocabulary" +msgstr "Vocabulaire" + +#: modules/taxonomy.views.inc:152 +msgid "Filter the results of \"Taxonomy: Term\" to a particular vocabulary." +msgstr "Filtrer les résultats de \"Taxonomie : Terme\" dans un vocabulaire spécifique." + +#: modules/taxonomy.views.inc:193;1046 +msgid "Term ID" +msgstr "Identifiant de terme" + +#: modules/taxonomy.views.inc:194 +msgid "The taxonomy term ID" +msgstr "L'identifiant du terme de classification." + +#: modules/taxonomy.views.inc:196 +msgid "All terms" +msgstr "Tous les termes" + +#: modules/taxonomy.views.inc:197 +msgid "Display all taxonomy terms associated with a node." +msgstr "Afficher tous les termes de taxonomie associés à un nœud." + +#: modules/taxonomy.views.inc:282 +msgid "Term synonym" +msgstr "Synonome du terme" + +#: modules/taxonomy.views.inc:283 +msgid "Term synonyms may be used to find terms by alternate names." +msgstr "Les synonymes de termes peuvent être utilisés pour trouver des termes par d'autres appellations." + +#: modules/taxonomy.views.inc:299 +msgid "Term ID (with depth)" +msgstr "Identifiant de terme (avec profondeur)" + +#: modules/taxonomy.views.inc:300 +msgid "The depth filter is more complex, so provides fewer options." +msgstr "Le filtre de profondeur est plus complexe et propose donc moins d'options." + +#: modules/taxonomy.views.inc:310 +msgid "Term ID depth modifier" +msgstr "Modificateur de la profondeur de l'identifiant de terme" + +#: modules/taxonomy.views.inc:311 +msgid "Allows the \"depth\" for Taxonomy: Term ID (with depth) to be modified via an additional argument." +msgstr "Permet de modifier à l'aide d'un argument supplémentaire la \"profondeur\" pour Taxonomie : Identifiant de terme (avec profondeur)." + +#: modules/taxonomy.views.inc:341 +msgid "The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term \"fruit\" and a child term \"apple\", with a depth of 1 (or higher) then filtering for the term \"fruit\" will get nodes that are tagged with \"apple\" as well as \"fruit\". If negative, the reverse is true; searching for \"apple\" will also pick up nodes tagged with \"fruit\" if depth is -1 (or lower)." +msgstr "La profondeur assurera la correspondance avec les nœuds étiquetés par des termes de la hiérarchie. Si, par exemple, vous avez le terme \"fruit\" et le terme enfant \"pomme\", avec une profondeur de 1 ou plus, alors un filtrage sur le terme \"fruit\" renverra des nœuds étiquetés par \"pomme\" aussi bien que par \"fruit\". Si la profondeur est négative, l'inverse est également vrai : rechercher \"pomme\" avec une profondeur de -1 (ou moins) renverra également les nœuds étiquetés par \"fruit\"." + +#: modules/taxonomy.views.inc:346 +msgid "Allow multiple terms per argument" +msgstr "Autoriser plusieurs termes par argument" + +#: modules/taxonomy.views.inc:347 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3. Due to the number of JOINs it would require, AND will be treated as OR with this argument." +msgstr "Si cette option est sélectionnée, les utilisateurs peuvent saisir plusieurs arguments sous la forme 1+2+3. Du fait du nombre de JOIN que cela représenterait, les requêtes AND seront traitées comme des OR avec cet argument." + +#: modules/taxonomy.views.inc:353;978 +msgid "Set the breadcrumb for the term parents" +msgstr "Faire apparaître les parents du terme dans le fil d'Ariane" + +#: modules/taxonomy.views.inc:354;979 +msgid "If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received." +msgstr "Si cette option est sélectionnée, le fil d'Ariane inclura tous les termes parents, chacun comportant un lien vers cette vue. Notez que cela fonctionne uniquement si un seul terme a été reçu." + +#: modules/taxonomy.views.inc:440;685 +msgid "No name" +msgstr "Aucun nom" + +#: modules/taxonomy.views.inc:551 +msgid "Link this field to its term page" +msgstr "Lier ce champ vers la page de terme correspondante" + +#: modules/taxonomy.views.inc:558 +msgid "Limit terms by vocabulary" +msgstr "Limiter les termes par vocabulaire" + +#: modules/taxonomy.views.inc:572;1034 +msgid "Vocabularies" +msgstr "Vocabulaires" + +#: modules/taxonomy.views.inc:645 +msgid "Link this field to its taxonomy term page" +msgstr "Lier ce champ vers la page de terme de classification correspondante" + +#: modules/taxonomy.views.inc:721 +msgid "No vocabulary" +msgstr "Aucun vocabulaire" + +#: modules/taxonomy.views.inc:765 +msgid "Select which vocabulary to show terms for in the regular options." +msgstr "Sélectionnez le vocabulaire pour lequel montrer les termes dans les options normales." + +#: modules/taxonomy.views.inc:775 +msgid "Selection type" +msgstr "Type de sélection" + +#: modules/taxonomy.views.inc:776 +msgid "Dropdown" +msgstr "Liste déroulante" + +#: modules/taxonomy.views.inc:776 +msgid "Autocomplete" +msgstr "Auto-complètement" + +#: modules/taxonomy.views.inc:782 +msgid "Show hierarchy in dropdown" +msgstr "Montrer la hiérarchie dans la liste déroulante" + +#: modules/taxonomy.views.inc:799 +msgid "An invalid vocabulary is selected. Please change it in the options." +msgstr "Un vocabulaire invalide a été sélectionné. Merci de le modifier dans les options." + +#: modules/taxonomy.views.inc:817;851 +msgid "Select terms from vocabulary @voc" +msgstr "Sélectionner les termes dans le vocabulaire @voc" + +#: modules/taxonomy.views.inc:1012 +msgid "Taxonomy term" +msgstr "Terme de classification" + +#: modules/taxonomy.views.inc:1037 +msgid "If you wish to validate for specific vocabularies, check them; if none are checked, all nodes will pass." +msgstr "Si vous souhaitez une validation pour certains vocabulaires spécifiques, cochez-les. Si aucun n'est coché, tous les nœuds seront acceptés." + +#: modules/taxonomy.views.inc:1047 +msgid "Term IDs separated by , or +" +msgstr "Identifiants de termes, séparés par des virgules ou des +" + +#: modules/taxonomy.views.inc:1048 +msgid "Term name or synonym" +msgstr "Nom ou synonyme de terme" + +#: modules/taxonomy.views.inc:1049 +msgid "Term name/synonym converted to Term ID" +msgstr "Nom/synonyme du terme converti en identifiant de terme" + +#: modules/taxonomy.views.inc:1052 +msgid "Select the form of this argument; if using term name, it is generally more efficient to convert it to a term ID and use Taxonomy: Term ID rather than Taxonomy: Term Name\" as an argument." +msgstr "Sélectionnez la forme de cet argument ; si l'on utilise le nom du terme, il est généralement plus efficace de le convertir vers un identifiant de terme et d'utiliser \"Taxonomie : Identifiant de terme\" plutôt que \"Taxonomie : Nom du terme\" en tant qu'argument." + +#: modules/taxonomy.views.inc:937 +msgid "Unable to find term: @terms" +msgid_plural "Unable to find terms: @terms" +msgstr[0] "Impossible de trouver le terme @terms" +msgstr[1] "Impossible de trouver les termes @terms" + +#: modules/upload.views.inc:25 +msgid "Upload" +msgstr "Transfert de fichiers" + +#: modules/upload.views.inc:49 +msgid "The description of the uploaded file." +msgstr "La description du fichier transféré." + +#: modules/upload.views.inc:66 +msgid "Listed" +msgstr "Listé" + +#: modules/upload.views.inc:67 +msgid "Whether or not the file is marked to be listed." +msgstr "Indique si le fichier est marqué pour être listé." + +#: modules/upload.views.inc:83 +msgid "The weight, used for sorting." +msgstr "Le poids, utilisé pour le tri." + +#: modules/upload.views.inc:101;113 +msgid "Attached files" +msgstr "Fichiers attachés" + +#: modules/upload.views.inc:102 +msgid "All files attached to a node with upload.module." +msgstr "Tous les fichiers attachés à un nœud avec upload.module." + +#: modules/upload.views.inc:109;274 +msgid "Has attached files" +msgstr "Possède des fichiers attachés" + +#: modules/upload.views.inc:110 +msgid "Only display items with attached files. This can cause duplicates if there are multiple attached files." +msgstr "Affiche uniquement les éléments présentant des fichiers attachés. Ceci peut causer des doublons s'il y a plusieurs fichiers attachés." + +#: modules/upload.views.inc:114 +msgid "Add a relationship to gain access to more file data for files uploaded by upload.module. Note that this relationship will cause duplicate nodes if there are multiple files attached to the node." +msgstr "Ajouter une relation pour accéder à davantage de données fichiers pour les fichiers transférés par upload.module. Notez que cette relation provoquera l'apparition de doublons s'il y a plusieurs fichiers attachés à un nœud." + +#: modules/upload.views.inc:120 +msgid "Files" +msgstr "Fichiers" + +#: modules/upload.views.inc:151 +msgid "Only show \"listed\" file attachments" +msgstr "Montrer uniquement les fichiers attachés \"listés\"" + +#: modules/user.views.inc:28 +msgid "Users who have created accounts on your site." +msgstr "Utilisateurs ayant créé un compte sur votre site." + +#: modules/user.views.inc:48 +msgid "Uid" +msgstr "Uid" + +#: modules/user.views.inc:49 +msgid "The user ID" +msgstr "Identifiant de l'utilisateur" + +#: modules/user.views.inc:70 +msgid "Current" +msgstr "Courant" + +#: modules/user.views.inc:71 +msgid "Filter the view to the currently logged in user." +msgstr "Filtre la vue pour montrer les utilisateurs actuellement connectés." + +#: modules/user.views.inc:80 +msgid "The user or author name." +msgstr "Le nom de l'utilisateur ou de l'auteur." + +#: modules/user.views.inc:96 +msgid "E-mail" +msgstr "E-mail" + +#: modules/user.views.inc:97 +msgid "Email address for a given user. Only accessible to users with <em>administer users</em> permission" +msgstr "Adresse e-mail d'un utilisateur donné. N'est accessible qu'aux utilisateurs ayant le droit d'<em>administrer les utilisateurs</em>" + +#: modules/user.views.inc:114 +msgid "Picture" +msgstr "Portrait" + +#: modules/user.views.inc:115 +msgid "The user's picture, if allowed." +msgstr "Portrait de l'utilisateur, si autorisé." + +#: modules/user.views.inc:126 +msgid "The date the user was created." +msgstr "Date de création de l'utilisateur." + +#: modules/user.views.inc:141 +msgid "Last access" +msgstr "Dernier accès" + +#: modules/user.views.inc:142 +msgid "The user's last access date." +msgstr "La date de dernier accès de l'utilisateur." + +#: modules/user.views.inc:157 +msgid "Last login" +msgstr "Dernière connexion" + +#: modules/user.views.inc:158 +msgid "The user's last login date." +msgstr "La date de dernière connexion de l'utilisateur." + +#: modules/user.views.inc:174 +msgid "Whether a user is active or blocked." +msgstr "Indique si un utilisateur est actif ou bloqué." + +#: modules/user.views.inc:191 +msgid "Signature" +msgstr "Signature" + +#: modules/user.views.inc:192 +msgid "The user's signature." +msgstr "La signature de l'utilisateur." + +#: modules/user.views.inc:205 +msgid "Provide a simple link to edit the user." +msgstr "Fournit un lien simple pour éditer l'utilisateur." + +#: modules/user.views.inc:213 +msgid "Provide a simple link to delete the user." +msgstr "Fournit un lien simple pour supprimer l'utilisateur." + +#: modules/user.views.inc:242 +msgid "Roles" +msgstr "Rôles" + +#: modules/user.views.inc:243 +msgid "Roles that a user belongs to." +msgstr "Rôles auxquels appartient un utilisateur." + +#: modules/user.views.inc:255 +msgid "No role" +msgstr "Aucun rôle" + +#: modules/user.views.inc:306 +msgid "User ID from URL" +msgstr "Identifiant utilisateur dans l'URL" + +#: modules/user.views.inc:322 +msgid "Also look for a node and use the node author" +msgstr "Rechercher aussi un nœud et utiliser l'auteur du nœud" + +#: modules/user.views.inc:387 +msgid "Link this field to its user" +msgstr "Lier ce champ à l'utilisateur correspondant" + +#: modules/user.views.inc:520 +msgid "Link this field" +msgstr "Lier ce champ" + +#: modules/user.views.inc:523 +msgid "No link" +msgstr "Aucun lien" + +#: modules/user.views.inc:524 +msgid "To the user" +msgstr "Vers l'utilisateur" + +#: modules/user.views.inc:525 +msgid "With a mailto:" +msgstr "Avec un mailto:" + +#: modules/user.views.inc:643 +msgid "Usernames" +msgstr "Noms d'utilisateurs" + +#: modules/user.views.inc:644 +msgid "Enter a comma separated list of user names." +msgstr "Saisissez une liste de noms d'utilisateurs séparés par des virgules." + +#: modules/user.views.inc:752 +msgid "Is the logged in user" +msgstr "Est l'utilisateur connecté" + +#: modules/user.views.inc:710 +msgid "Unable to find user: @users" +msgid_plural "Unable to find users: @users" +msgstr[0] "Impossible de trouver l'utilisateur @users" +msgstr[1] "Impossible de trouver les utilisateurs @users" + +#: modules/views.views.inc:18 +msgid "Global" +msgstr "Global" + +#: modules/views.views.inc:23 +msgid "Random" +msgstr "Au hasard" + +#: modules/views.views.inc:24 +msgid "Randomize the display order." +msgstr "Rendre l'ordre d'affichage aléatoire." + +#: modules/views.views.inc:31 +msgid "Null" +msgstr "Vide" + +#: modules/views.views.inc:32 +msgid "Allow an argument to be ignored. The query will not be altered by this argument." +msgstr "Autoriser un argument à être ignoré. La requête ne sera pas modifiée par cet argument." + +#: modules/views.views.inc:88 +msgid "Fail basic validation if any argument is given" +msgstr "Faire échouer la validation de base si un argument est fourni" + +#: modules/views.views.inc:90 +msgid "By checking this field, you can use this to make sure views with more arguments than necessary fail validation." +msgstr "En cochant cette case, vous pouvez utiliser ceci pour vérifier que la validation des vues présentant plus d'arguments que nécessaire échoue." + +#: theme/views-more.tpl.php:15 +msgid "more" +msgstr "plus" + +#: theme/views-ui-edit-item.tpl.php:18 +msgid "None defined" +msgstr "Aucun défini" + +#: theme/views-ui-edit-tab.tpl.php:31 +msgid "View settings" +msgstr "Paramétrage de la vue" + +#: theme/views-ui-edit-view.tpl.php:11 +msgid "This view is being edited by user !user, and is therefore locked from editing by others. This lock is !age old. Click here to !break." +msgstr "Cette vue est en cours de modification par l'utilisateur !user et elle est par conséquent verrouillée en modification pour tout autre utilisateur. Ce verrou dure depuis !age. Cliquez ici pour le !break." + +#: theme/views-ui-edit-view.tpl.php:16 +msgid "New view" +msgstr "Nouvelle vue" + +#: theme/views-ui-edit-view.tpl.php:18 +msgid "Changed view" +msgstr "Vue changée" + +#: theme/views-ui-edit-view.tpl.php:23 +msgid "View %name, displaying items of type <strong>@base</strong>." +msgstr "Voir %name en affichant les éléments de type <strong>@base</strong>." + +#: theme/views-ui-edit-view.tpl.php:42 +msgid "Live preview" +msgstr "Prévisualisation en direct" + +#: theme/views-ui-list-views.tpl.php:17 +msgid "<em>@type</em> @base view: <strong>@view</strong>" +msgstr "Vue <em>@type</em> @base : <strong>@view</strong>" + +#: theme/views-ui-list-views.tpl.php:27 +msgid "Title: @title" +msgstr "Titre : @title" + +#: theme/views-ui-list-views.tpl.php:30 +msgid "Path: !path" +msgstr "Chemin : !path" + +#: theme/theme.inc:90 +msgid "Edit this view" +msgstr "Éditer cette vue" + +#: theme/theme.inc:289 +msgid "sort by @s" +msgstr "trier par @s" + +#: theme/theme.inc:490 +msgid "‹‹" +msgstr "‹‹" + +#: theme/theme.inc:491 +msgid "››" +msgstr "››" + +#: theme/theme.inc:501 +msgid "@current of @max" +msgstr "@current de @max" + +#: views_export/views_export.module:17 +msgid "Bulk export" +msgstr "Export par lot" + +#: views_export/views_export.module:76 +msgid "There are no views to be exported at this time." +msgstr "Il n'y a pas de vue à exporter pour le moment." + +#: views_export/views_export.module:108 +msgid "Show only these tags" +msgstr "Montrer uniquement ces étiquettes" + +#: views_export/views_export.module:122 +msgid "Module name" +msgstr "Nom du module" + +#: views_export/views_export.module:123 +msgid "Enter the module name to export code to." +msgstr "Saisissez le nom du module vers lequel exporter le code." + +#: views_export/views_export.module:190 +msgid "Put this in @module.views_default.inc in your modules/@module directory or modules/@module/includes directory" +msgstr "Placez ceci dans @module.views_default.inc dans votre répertoire modules/@module ou modules/@module/includes" + +#: views_export/views_export.module:44 +msgid "use views exporter" +msgstr "utiliser l'exportateur de vues" + +#: views_export/views_export.module:0 +msgid "views_export" +msgstr "views_export" + +#: views_export/views_export.info:0 +msgid "Views exporter" +msgstr "Exportateur de vues" + +#: views_export/views_export.info:0 +msgid "Allows exporting multiple views at once." +msgstr "Permet d'exporter plusieurs vues à la fois" + diff --git a/sites/all/modules/views/translations/it.po b/sites/all/modules/views/translations/it.po new file mode 100644 index 0000000000000000000000000000000000000000..bf598988d55992685f5920c500e618992ca2c893 --- /dev/null +++ b/sites/all/modules/views/translations/it.po @@ -0,0 +1,4233 @@ +msgid "" +msgstr "" +"Suggerimento: \n" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: Drupalitalia <infoATTAPdrupalitalia.org>\n" +"Language-Team: Italian\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/upload.views.inc:56; +#: includes/convert.inc:21; +#: includes/admin.inc:273; +#: views_export/views_export.module:146 +msgid "Description" +msgstr "Descrizione" + +#: includes/admin.inc:2346,2113,2104 +msgid "Remove" +msgstr "Elimina" + +#: handlers/views_handler_filter_in_operator.inc:25; +#: handlers/views_handler_filter_boolean_operator.inc:47; +#: handlers/views_handler_field_boolean.inc:49; +#: plugins/views_plugin_display.inc:1207,803,717,667,659,642,633; +#: plugins/views_plugin_display_attachment.inc:69,63 +msgid "Yes" +msgstr "Si" + +#: handlers/views_handler_filter_in_operator.inc:25; +#: handlers/views_handler_filter_boolean_operator.inc:47; +#: handlers/views_handler_field_boolean.inc:49; +#: plugins/views_plugin_display.inc:1207,811,803,717,667,659,642,633; +#: plugins/views_plugin_display_attachment.inc:69,63 +msgid "No" +msgstr "No" + +#: modules/node/views_handler_field_node_link_edit.inc:26; +#: modules/comment/views_handler_field_comment_link_edit.inc:21; +#: modules/user/views_handler_field_user_link_edit.inc:13 +msgid "edit" +msgstr "modifica" + +#: modules/node/views_handler_field_node_revision_link_delete.inc:35; +#: modules/node/views_handler_field_node_link_delete.inc:26; +#: modules/comment/views_handler_field_comment_link_delete.inc:12; +#: modules/user/views_handler_field_user_link_delete.inc:13 +msgid "delete" +msgstr "elimina" + +#: includes/admin.inc:1308 +msgid "Update" +msgstr "Aggiorna" + +#: includes/admin.inc:564 +msgid "Next" +msgstr "Avanti" + +#: modules/user.views.inc:219,27,23; +#: modules/statistics.views.inc:201; +#: modules/node.views.inc:345; +#: modules/comment.views.inc:231,225 +msgid "User" +msgstr "Utente" + +#: includes/view.inc:1212,1162; +#: includes/admin.inc:211 +msgid "Normal" +msgstr "Normale" + +#: modules/comment/views_handler_filter_node_comment.inc:10; +#: modules/comment/views_handler_field_node_comment.inc:12 +msgid "Disabled" +msgstr "Disattivato" + +#: includes/convert.inc:108,35; +#: includes/admin.inc:844,631,98 +msgid "Delete" +msgstr "Elimina" + +#: includes/admin.inc:2211,1175 +msgid "Add" +msgstr "Aggiungi" + +#: handlers/views_handler_filter_in_operator.inc:15 +msgid "Options" +msgstr "Opzioni" + +#: includes/plugins.inc:135,104 +msgid "List" +msgstr "Elenco" + +#: includes/admin.inc:93; +#: theme/theme.inc:89 +msgid "Edit" +msgstr "Modifica" + +#: handlers/views_handler_filter.inc:136 +msgid "Operator" +msgstr "Operatore" + +#: modules/user.views.inc:240 +msgid "Roles" +msgstr "Ruoli" + +#: modules/system.views.inc:142 +msgid "Status" +msgstr "Status" + +#: modules/user.views.inc:79,59; +#: modules/system.views.inc:69; +#: includes/admin.inc:268; +#: plugins/views_plugin_display.inc:580 +msgid "Name" +msgstr "Nome" + +#: includes/convert.inc:22 +msgid "Operations" +msgstr "Operazioni" + +#: modules/node/views_handler_field_node_link.inc:35; +#: modules/comment/views_handler_field_comment_link.inc:34; +#: modules/user/views_handler_field_user_link.inc:38 +msgid "view" +msgstr "mostra" + +#: modules/comment/views_handler_argument_comment_user_uid.inc:11; +#: modules/user/views_handler_argument_user_uid.inc:17 +msgid "Anonymous" +msgstr "Anonimo" + +#: plugins/views_plugin_display.inc:651 +msgid "Unlimited" +msgstr "Nessun limite" + +#: includes/admin.inc:763,585,212,97; +#: views.module:830,797; +#: views_ui.module:289 +msgid "Default" +msgstr "Predefinito" + +#: includes/convert.inc:109; +#: includes/admin.inc:1326,837,668,632 +msgid "Cancel" +msgstr "Annulla" + +#: modules/node.views.inc:351 +msgid "user" +msgstr "utente" + +#: includes/plugins.inc:224; +#: plugins/views_plugin_access_role.inc:40 +msgid "Role" +msgstr "Ruolo" + +#: includes/admin.inc:1241,1232 +msgid "Settings" +msgstr "Impostazioni" + +#: modules/node.views.inc:140; +#: includes/admin.inc:272,225; +#: plugins/views_plugin_display_page.inc:273 +msgid "Type" +msgstr "Tipo" + +#: modules/upload.views.inc:90; +#: modules/taxonomy.views.inc:135; +#: modules/book.views.inc:57; +#: includes/admin.inc:2113; +#: plugins/views_plugin_display_page.inc:312 +msgid "Weight" +msgstr "Peso" + +#: includes/convert.inc:107 +msgid "This action cannot be undone." +msgstr "Questa azione non può essere annullata." + +#: modules/node.views.inc:358; +#: modules/comment.views.inc:63 +msgid "Body" +msgstr "Corpo" + +#: includes/admin.inc:472 +msgid "Preview" +msgstr "Anteprima" + +#: handlers/views_handler_filter.inc:333 +msgid "Optional" +msgstr "Opzionale" + +#: includes/admin.inc:858,830 +msgid "Save" +msgstr "Salva" + +#: handlers/views_handler_field_numeric.inc:55 +msgid "Thousands separator" +msgstr "Separatore delle migliaia" + +#: modules/search.views.inc:163,106,88,77,23 +msgid "Search" +msgstr "Cerca" + +#: modules/node.views.inc:413,85; +#: modules/comment.views.inc:44; +#: includes/admin.inc:380,269; +#: handlers/views_handler_argument.inc:119; +#: plugins/views_plugin_display.inc:592; +#: plugins/views_plugin_display_page.inc:348,285 +msgid "Title" +msgstr "Titolo" + +#: modules/comment.views.inc:76 +msgid "ID" +msgstr "ID" + +#: plugins/views_plugin_style_list.inc:32 +msgid "List type" +msgstr "Tipo di elenco" + +#: modules/system.views.inc:209; +#: handlers/views_handler_filter_in_operator.inc:193; +#: plugins/views_plugin_access.inc:55 +msgid "Unknown" +msgstr "Sconosciuto" + +#: modules/comment.views.inc:395,384,26,22 +msgid "Comment" +msgstr "Commento" + +#: includes/admin.inc:280 +msgid "Order" +msgstr "Ordine" + +#: plugins/views_plugin_display_block.inc:82 +msgid "Admin" +msgstr "Amministrazione" + +#: modules/user.views.inc:189 +msgid "Signature" +msgstr "Firma" + +#: modules/statistics.views.inc:126 +msgid "Page title" +msgstr "Titolo della pagina" + +#: includes/admin.inc:106 +msgid "Enable" +msgstr "Attiva" + +#: modules/user.views.inc:96 +msgid "E-mail" +msgstr "E-mail" + +#: includes/view.inc:1060 +msgid "Home" +msgstr "Home" + +#: includes/view.inc:1870,1869 +msgid "Argument" +msgstr "Argomento" + +#: modules/upload.views.inc:132 +msgid "Files" +msgstr "Files" + +#: modules/system.views.inc:30,25 +msgid "File" +msgstr "File" + +#: modules/upload.views.inc:112,25 +msgid "Upload" +msgstr "Upload" + +#: includes/admin.inc:721 +msgid "Import" +msgstr "Importa" + +#: includes/admin.inc:975,94; +#: theme/theme.inc:96; +#: views_export/views_export.module:128 +msgid "Export" +msgstr "Esporta" + +#: includes/admin.inc:292; +#: views.module:935; +#: views_export/views_export.module:116 +msgid "Apply" +msgstr "Applica" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:37; +#: modules/taxonomy.views.inc:160 +msgid "Vocabulary" +msgstr "Vocabolario" + +#: includes/plugins.inc:218; +#: includes/admin.inc:3054,1059; +#: plugins/views_plugin_display.inc:723,704,587; +#: plugins/views_plugin_display_attachment.inc:90; +#: plugins/views_plugin_display_block.inc:73; +#: plugins/views_plugin_display_feed.inc:108; +#: plugins/views_plugin_display_page.inc:193 +msgid "None" +msgstr "Nessuno" + +#: plugins/views_plugin_display.inc:897,721 +msgid "Header" +msgstr "Intestazione" + +#: handlers/views_handler_field_date.inc:24 +msgid "Date format" +msgstr "Formato data" + +#: includes/view.inc:1862; +#: includes/admin.inc:3018 +msgid "Field" +msgstr "Campo" + +#: handlers/views_handler_sort_date.inc:31 +msgid "Day" +msgstr "Giorno" + +#: handlers/views_handler_sort_date.inc:32 +msgid "Month" +msgstr "Mese" + +#: handlers/views_handler_sort_date.inc:33 +msgid "Year" +msgstr "Anno" + +#: handlers/views_handler_relationship.inc:78; +#: handlers/views_handler_filter.inc:322; +#: handlers/views_handler_field.inc:146 +msgid "Label" +msgstr "Etichetta" + +#: modules/node.views.inc:373 +msgid "Teaser" +msgstr "Anteprima" + +#: includes/view.inc:1860; +#: includes/plugins.inc:173 +msgid "Fields" +msgstr "Campi" + +#: modules/node/views_plugin_argument_validate_node.inc:29 +msgid "Types" +msgstr "Tipi" + +#: includes/admin.inc:2180 +msgid "Groups" +msgstr "Gruppi" + +#: plugins/views_plugin_display.inc:604 +msgid "Style" +msgstr "Stile" + +#: handlers/views_handler_field_numeric.inc:62 +msgid "Prefix" +msgstr "Prefisso" + +#: handlers/views_handler_field_numeric.inc:68 +msgid "Suffix" +msgstr "Suffisso" + +#: modules/translation/views_handler_filter_node_language.inc:9; +#: modules/node/views_handler_filter_node_language.inc:9; +#: modules/translation.views.inc:32 +msgid "Language" +msgstr "Lingua" + +#: includes/ajax.inc:83 +msgid "Error" +msgstr "Errore" + +#: theme/views-more.tpl.php:15 +msgid "more" +msgstr "leggi tutto" + +#: modules/node/views_plugin_row_node_rss.inc:95 +msgid "read more" +msgstr "leggi tutto" + +#: includes/plugins.inc:60,51 +msgid "Block" +msgstr "Blocco" + +#: modules/taxonomy.views.inc:259; +#: modules/book.views.inc:110 +msgid "Parent" +msgstr "Genitore" + +#: modules/node.views.inc:434 +msgid "Log message" +msgstr "Messaggio di log" + +#: modules/book.views.inc:99,46,36,21 +msgid "Book" +msgstr "Book" + +#: handlers/views_handler_field_date.inc:29 +msgid "Custom" +msgstr "Personalizzato" + +#: modules/comment/views_handler_filter_node_comment.inc:11; +#: modules/comment/views_handler_field_node_comment.inc:14 +msgid "Read only" +msgstr "Sola lettura" + +#: modules/comment/views_handler_filter_node_comment.inc:12; +#: modules/comment/views_handler_field_node_comment.inc:16 +msgid "Read/Write" +msgstr "Lettura/Scrittura" + +#: modules/comment/views_handler_field_comment_link_reply.inc:13 +msgid "reply" +msgstr "rispondi" + +#: modules/comment.views.inc:95 +msgid "Author" +msgstr "Autore" + +#: modules/translation.views.inc:106; +#: modules/upload.views.inc:82; +#: modules/node.views.inc:181,167,159 +msgid "Published" +msgstr "Pubblicato" + +#: includes/admin.inc:1173 +msgid "Rearrange" +msgstr "Riorganizza" + +#: includes/plugins.inc:124 +msgid "Table" +msgstr "Tabella" + +#: includes/view.inc:1881 +msgid "Filters" +msgstr "Filtri" + +#: includes/view.inc:1884 +msgid "filter" +msgstr "filtro" + +#: modules/taxonomy.views.inc:314,303,266,226,170,152,67,24 +msgid "Taxonomy" +msgstr "Tassonomia" + +#: modules/system.views.inc:88; +#: modules/statistics.views.inc:146; +#: includes/admin.inc:388,271; +#: plugins/views_plugin_display_page.inc:202 +msgid "Path" +msgstr "Path" + +#: includes/admin.inc:103 +msgid "Disable" +msgstr "Disabilita" + +#: modules/node.views.inc:195,187 +msgid "Promoted to front page" +msgstr "Promosso in prima pagina" + +#: includes/view.inc:1883 +msgid "Filter" +msgstr "Filtra" + +#: modules/node/views_handler_field_node_revision_link_revert.inc:36 +msgid "revert" +msgstr "ripristina" + +#: includes/admin.inc:98 +msgid "Revert" +msgstr "Ripristina" + +#: modules/poll.views.inc:23 +msgid "Poll" +msgstr "Poll" + +#: modules/user.views.inc:180,171; +#: modules/poll.views.inc:47,38 +msgid "Active" +msgstr "Attivo" + +#: modules/search/views_handler_filter_search.inc:62 +msgid "You must include at least one positive keyword with @count characters or more." +msgstr "Devi inserire almeno una parola-chiave con @count caratteri o più." + +#: modules/search/views_handler_filter_search.inc:42 +msgid "Enter the terms you wish to search for." +msgstr "Inserisci i termini da cercare." + +#: modules/statistics.views.inc:166 +msgid "Referrer" +msgstr "Referrer" + +#: modules/statistics.views.inc:182 +msgid "Hostname" +msgstr "Nome host" + +#: modules/statistics.views.inc:228 +msgid "Timestamp" +msgstr "Data e ora" + +#: includes/plugins.inc:47,39; +#: docs/docs.php:226 +msgid "Page" +msgstr "Pagina" + +#: modules/node/views_plugin_row_node_rss.inc:26 +msgid "Full text" +msgstr "Testo completo" + +#: handlers/views_handler_filter_string.inc:170; +#: handlers/views_handler_filter_numeric.inc:163,148; +#: handlers/views_handler_filter_equality.inc:26 +msgid "Value" +msgstr "Valore" + +#: modules/taxonomy.views.inc:372 +msgid "Taxonomy term" +msgstr "Termine della tassonomia" + +#: modules/taxonomy.views.inc:48 +msgid "Vocabulary name" +msgstr "Nome del vocabolario" + +#: modules/book.views.inc:87 +msgid "Hierarchy" +msgstr "Gerarchia" + +#: modules/taxonomy.views.inc:254 +msgid "Parent term" +msgstr "Termine padre" + +#: docs/docs.php:128 +msgid "default" +msgstr "predefinito" + +#: includes/plugins.inc:64 +msgid "Attachment" +msgstr "Allegato" + +#: modules/system.views.inc:126 +msgid "Size" +msgstr "Dimensione" + +#: modules/upload.views.inc:46 +msgid "upload" +msgstr "caricamento" + +#: modules/user.views.inc:112 +msgid "Picture" +msgstr "Ritratto" + +#: includes/plugins.inc:231; +#: plugins/views_plugin_access_perm.inc:35 +msgid "Permission" +msgstr "Permesso" + +#: modules/user.views.inc:139 +msgid "Last access" +msgstr "Ultimo accesso" + +#: includes/admin.inc:2177,210,203 +msgid "<All>" +msgstr "<Tutto>" + +#: handlers/views_handler_field_date.inc:53 +msgid "%time ago" +msgstr "%time fa" + +#: handlers/views_handler_filter_string.inc:40 +msgid "Contains" +msgstr "Contiene" + +#: views_ui.info:0; +#: views.info:0; +#: views_export/views_export.info:0 +msgid "Views" +msgstr "Viste" + +#: plugins/views_plugin_display.inc:1399 +msgid "Override" +msgstr "Sovrascrivi" + +#: includes/admin.inc:980,95; +#: theme/theme.inc:101 +msgid "Clone" +msgstr "Clona" + +#: includes/admin.inc:618,213,98; +#: views.module:834,794 +msgid "Overridden" +msgstr "Modificato (overridden)" + +#: plugins/views_plugin_display_page.inc:302,230 +msgid "Menu" +msgstr "Menu" + +#: handlers/views_handler_argument.inc:263 +msgid "Summary, sorted ascending" +msgstr "Sommario, ordinato in modo crescente" + +#: handlers/views_handler_argument.inc:270 +msgid "Summary, sorted descending" +msgstr "Sommario, ordinato in modo decrescente" + +#: handlers/views_handler_sort.inc:55; +#: plugins/views_plugin_style_table.inc:149 +msgid "Ascending" +msgstr "Crescente" + +#: handlers/views_handler_sort.inc:55; +#: plugins/views_plugin_style_table.inc:149 +msgid "Descending" +msgstr "Decrescente" + +#: plugins/views_plugin_display.inc:681 +msgid "Access" +msgstr "Accesso" + +#: plugins/views_plugin_display.inc:907 +msgid "Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional." +msgstr "Testo da visualizzare in cima alla vista. Può contenere maggiori informazioni, links o altro a tua discrezione. Questo campo è opzionale." + +#: plugins/views_plugin_display.inc:913,721 +msgid "Footer" +msgstr "Piè di pagina" + +#: plugins/views_plugin_display_page.inc:343 +msgid "Normal menu item" +msgstr "Voce del menu (Normal menu item)" + +#: plugins/views_plugin_display.inc:929,721 +msgid "Empty text" +msgstr "Testo vuoto" + +#: handlers/views_handler_filter.inc:201 +msgid "Expose" +msgstr "Visualizza all'utente" + +#: includes/admin.inc:282 +msgid "Up" +msgstr "Su" + +#: includes/admin.inc:283 +msgid "Down" +msgstr "Giù" + +#: includes/admin.inc:3022 +msgid "Sortable" +msgstr "Ordinabile" + +#: handlers/views_handler_argument.inc:146 +msgid "Wildcard" +msgstr "Caratteri jolly" + +#: includes/view.inc:1867; +#: includes/admin.inc:464 +msgid "Arguments" +msgstr "Argomenti" + +#: includes/admin.inc:755,580 +msgid "View name must be alphanumeric or underscores only." +msgstr "Il nome della vista deve contenere caratteri alfabetici o il simbolo \"_\"" + +#: modules/views.views.inc:23 +msgid "Random" +msgstr "Casuale" + +#: modules/taxonomy.views.inc:292,208,129; +#: handlers/views_handler_argument_numeric.inc:57,45; +#: handlers/views_handler_argument_many_to_one.inc:109,95 +msgid "Uncategorized" +msgstr "Non categorizzato" + +#: modules/translation/views_handler_relationship_translation.inc:23; +#: handlers/views_handler_argument.inc:102 +msgid "All" +msgstr "Tutti" + +#: includes/view.inc:1882 +msgid "filters" +msgstr "filtri" + +#: plugins/views_plugin_display.inc:575 +msgid "Basic settings" +msgstr "Impostazioni di base" + +#: modules/profile.views.inc:40,20 +msgid "Profile" +msgstr "Profilo" + +#: handlers/views_handler_filter.inc:213 +msgid "Hide" +msgstr "Nascondi" + +#: modules/node/views_plugin_argument_validate_node.inc:49 +msgid "Node ID" +msgstr "ID nodo" + +#: handlers/views_handler_filter_boolean_operator.inc:61,16; +#: handlers/views_handler_field_boolean.inc:51 +msgid "True" +msgstr "Vero" + +#: handlers/views_handler_filter_boolean_operator.inc:61; +#: handlers/views_handler_field_boolean.inc:51 +msgid "False" +msgstr "Falso" + +#: plugins/views_plugin_style_grid.inc:33 +msgid "Number of columns" +msgstr "Numero di colonne" + +#: modules/node.views.inc:242 +msgid "Link" +msgstr "Link" + +#: includes/admin.inc:204; +#: plugins/views_plugin_style.inc:76 +msgid "<None>" +msgstr "<Nessuno>" + +#: includes/admin.inc:3020; +#: handlers/views_handler_field_prerender_list.inc:40; +#: plugins/views_plugin_row_fields.inc:47; +#: plugins/views_plugin_style_summary_unformatted.inc:30 +msgid "Separator" +msgstr "Separatore" + +#: modules/upload.views.inc:43; +#: modules/node.views.inc:639,627,616,484,372,357,90,29,24; +#: modules/comment.views.inc:255,220,214 +msgid "Node" +msgstr "Node" + +#: modules/node.views.inc:213,204; +#: modules/comment.views.inc:157 +msgid "Moderated" +msgstr "Moderato" + +#: plugins/views_plugin_style_grid.inc:38 +msgid "Alignment" +msgstr "Allineamento" + +#: includes/convert.inc:30 +msgid "Convert" +msgstr "Conversione" + +#: includes/admin.inc:456 +msgid "Display" +msgstr "Mostra" + +#: handlers/views_handler_filter_string.inc:35,29; +#: handlers/views_handler_filter_numeric.inc:40 +msgid "=" +msgstr "=" + +#: plugins/views_plugin_display.inc:751 +msgid "Theme" +msgstr "Tema" + +#: modules/node/views_plugin_row_node_rss.inc:28 +msgid "Title only" +msgstr "Solo il titolo" + +#: includes/plugins.inc:114 +msgid "Grid" +msgstr "Griglia" + +#: modules/node.views.inc:231,222 +msgid "Sticky" +msgstr "In rilievo" + +#: plugins/views_plugin_display_attachment.inc:37 +msgid "Both" +msgstr "Entrambi" + +#: includes/plugins.inc:25; +#: docs/docs.php:137 +msgid "Defaults" +msgstr "Predefinite" + +#: includes/plugins.inc:80,72; +#: docs/docs.php:281 +msgid "Feed" +msgstr "Feed" + +#: handlers/views_handler_sort_date.inc:30 +msgid "Hour" +msgstr "Ora" + +#: handlers/views_handler_sort_date.inc:29 +msgid "Minute" +msgstr "Minuto" + +#: handlers/views_handler_sort_date.inc:28 +msgid "Second" +msgstr "Secondo" + +#: handlers/views_handler_sort_date.inc:26 +msgid "Granularity" +msgstr "Granularità" + +#: includes/form.inc:249 +msgid "Validation error, please try again. If this error persists, please contact the site administrator." +msgstr "Errore di validazione, riprovare. Se l'errore persiste, contattare l'amministratore del sito." + +#: theme/theme.inc:307 +msgid "sort by @s" +msgstr "ordina per @s" + +#: views_ui.info:0 +msgid "Views UI" +msgstr "Viste UI" + +#: handlers/views_handler_argument_string.inc:60 +msgid "Case" +msgstr "Maiuscole/minuscole" + +#: modules/comment.views.inc:207 +msgid "Thread" +msgstr "Thread" + +#: plugins/views_plugin_display.inc:999,954,874 +msgid "settings" +msgstr "impostazioni" + +#: modules/translation.views.inc:91,84,81 +msgid "Translations" +msgstr "Traduzioni" + +#: modules/translation.views.inc:98 +msgid "Translation status" +msgstr "Stato della traduzione" + +#: modules/node/views_plugin_row_node_view.inc:32; +#: modules/comment/views_plugin_row_comment_view.inc:21 +msgid "Display links" +msgstr "Link della visualizzazione" + +#: includes/admin.inc:552 +msgid "View type" +msgstr "Tipo di vista" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:33; +#: modules/node/views_plugin_argument_validate_node.inc:47 +msgid "Argument type" +msgstr "Tipo di argomento" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:35; +#: modules/taxonomy.views.inc:196,96 +msgid "Term ID" +msgstr "ID Termine" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:23; +#: modules/taxonomy/views_handler_field_term_node_tid.inc:55 +msgid "Vocabularies" +msgstr "Vocabolari" + +#: modules/taxonomy.views.inc:56 +msgid "Vocabulary ID" +msgstr "ID vocabolario" + +#: plugins/views_plugin_display_block.inc:68 +msgid "Block settings" +msgstr "Impostazioni blocco" + +#: modules/upload.views.inc:125,113 +msgid "Attached files" +msgstr "File allegati" + +#: modules/taxonomy.views.inc:148 +msgid "Term description" +msgstr "Descrizione del termine" + +#: modules/taxonomy.views.inc:213,116,70 +msgid "Term" +msgstr "Termine" + +#: plugins/views_plugin_display.inc:641 +msgid "Use pager" +msgstr "Usa paginatore" + +#: plugins/views_plugin_display.inc:831 +msgid "Offset" +msgstr "Slittamento" + +#: modules/node/views_handler_filter_node_type.inc:9 +msgid "Node type" +msgstr "Tipo di nodo" + +#: includes/view.inc:1889 +msgid "Relationships" +msgstr "Relazioni" + +#: includes/admin.inc:2104 +msgid "Remove this item" +msgstr "Rimuovi questa voce" + +#: modules/system/views_handler_argument_file_fid.inc:13 +msgid "No title" +msgstr "Nessun titolo" + +#: plugins/views_plugin_display_page.inc:188 +msgid "Page settings" +msgstr "Impostazioni pagina" + +#: modules/book.views.inc:116 +msgid "Book parent" +msgstr "Libro genitore" + +#: modules/book.views.inc:30 +msgid "Top level book" +msgstr "Libro top level" + +#: includes/admin.inc:1060,270,243; +#: views_export/views_export.module:146 +msgid "Tag" +msgstr "Etichetta" + +#: handlers/views_handler_filter_string.inc:70 +msgid "Does not contain" +msgstr "Non contiene" + +#: handlers/views_handler_filter_numeric.inc:26 +msgid "Is less than" +msgstr "È meno di" + +#: handlers/views_handler_filter_numeric.inc:32 +msgid "Is less than or equal to" +msgstr "È minore o uguale a" + +#: handlers/views_handler_filter_string.inc:28; +#: handlers/views_handler_filter_numeric.inc:38; +#: handlers/views_handler_filter_equality.inc:15 +msgid "Is equal to" +msgstr "È uguale a" + +#: handlers/views_handler_filter_numeric.inc:50 +msgid "Is greater than or equal to" +msgstr "È maggiore o uguale a" + +#: handlers/views_handler_filter_numeric.inc:56 +msgid "Is greater than" +msgstr "È maggiore di" + +#: handlers/views_handler_filter_string.inc:34; +#: handlers/views_handler_filter_numeric.inc:44; +#: handlers/views_handler_filter_equality.inc:16 +msgid "Is not equal to" +msgstr "Non è uguale a" + +#: includes/view.inc:1892,1891; +#: includes/admin.inc:2319 +msgid "Relationship" +msgstr "Relazione" + +#: modules/search.views.inc:72 +msgid "Score" +msgstr "Punteggio" + +#: includes/admin.inc:398,367 +msgid "Query" +msgstr "Query" + +#: includes/admin.inc:2110 +msgid "No fields available." +msgstr "Nessun campo disponibile." + +#: modules/search/views_handler_filter_search.inc:66 +msgid "Search for either of the two terms with uppercase <strong>OR</strong>. For example, <strong>cats OR dogs</strong>." +msgstr "Cerca ognuno dei due termini con <strong>OR</strong> maiuscolo. Per esempio, <strong>gatti OR cani</strong>." + +#: modules/statistics.views.inc:107 +msgid "Browser session ID of user that visited page." +msgstr "Sfoglia la sessione ID dell'utente che ha visitato la pagina." + +#: modules/statistics.views.inc:127 +msgid "Title of page visited." +msgstr "Titolo della pagina visitata" + +#: modules/statistics.views.inc:147 +msgid "Internal path to page visited (relative to Drupal root.)" +msgstr "Percorso interno della pagina visitata (relativo al percorso principale di Drupal)." + +#: modules/statistics.views.inc:167 +msgid "Referrer URI." +msgstr "Referrer URI." + +#: modules/statistics.views.inc:183 +msgid "Hostname of user that visited the page." +msgstr "Nome host dell'utente che ha visitato la pagina." + +#: modules/statistics.views.inc:213 +msgid "Time in milliseconds that the page took to load." +msgstr "Tempo (in millisecondi) di caricamento della pagina." + +#: modules/statistics.views.inc:229 +msgid "Timestamp of when the page was visited." +msgstr "Data e ora (timestamp) di quando la pagina è stata visitata." + +#: views.install:31 +msgid "Stores the general data for a view." +msgstr "Memorizza i dati generali di una vista." + +#: views.install:37 +msgid "The view ID of the field, defined by the database." +msgstr "L'ID vista del campo, definito dal database." + +#: views.install:45 +msgid "The unique name of the view. This is the primary field views are loaded from, and is used so that views may be internal and not necessarily in the database. May only be alphanumeric characters plus underscores." +msgstr "Il nome univoco di una vista. Questo è il campo primario dal quale sono caricate le viste e viene usato in modo che le viste possano essere interne e non necessariamente nel database. Può contenere solo caratteri alfanumerici e underscore (_)." + +#: views.install:51 +msgid "A description of the view for the admin interface." +msgstr "Una descrizione della vista nell'interfaccia di amministrazione." + +#: views.install:61 +msgid "A chunk of PHP code that can be used to provide modifications to the view prior to building." +msgstr "Un pezzo di codice PHP che può essere usato per fornire modifiche alla vista prima della costruzione." + +#: views.install:68 +msgid "What table this view is based on, such as node, user, comment, or term." +msgstr "Su quale tabella si basa questa vista, tipo nodo, utente, commento o termine." + +#: views.install:74 +msgid "A boolean to indicate whether or not this view may have its query cached." +msgstr "Un booleano per indicare se questa vista può avere la sua query memorizzata in cache o no." + +#: views.install:82 +msgid "Stores information about each display attached to a view." +msgstr "Memorizza informazioni su ogni visualizzazione allegata a una vista." + +#: views.install:89 +msgid "The view this display is attached to." +msgstr "La vista alla quale è allegata questa visualizzazione." + +#: views.install:111 +msgid "The type of the display. Usually page, block or embed, but is pluggable so may be other things." +msgstr "Il tipo di visualizzazione. In genere pagina, blocco o integrato, ma è inseribile per cui può essere oltre cose." + +#: views.install:97 +msgid "An identifier for this display; usually generated from the display_plugin, so should be something like page or page_1 or block_2, etc." +msgstr "Un identificatore per questa visualizzazione; di solito generato dal display_plugin, quindi dovrebbe essere qualcosa tipo pagina o page_1 o block_2, ecc." + +#: views.install:116 +msgid "The order in which this display is loaded." +msgstr "L'ordine in cui viene caricata questa visualizzazione." + +#: views.install:120 +msgid "A serialized array of options for this display; it contains options that are generally only pertinent to that display plugin type." +msgstr "Un array serializzato di opzioni per questa visualizzazione; contiene opzioni che in genere sono pertinenti solo a quel tipo di visualizzazione." + +#: views.info:0 +msgid "Create customized lists and queries from your database." +msgstr "Crea elenchi personalizzati di query dal tuo database." + +#: handlers/views_handler_field_date.inc:30 +msgid "Time ago" +msgstr "Tempo fa" + +#: handlers/views_handler_field_date.inc:36 +msgid "Custom date format" +msgstr "Formato della data paersonalizzato" + +#: handlers/views_handler_sort_formula.inc:24 +msgid "views_handler_sort_formula missing default: @formula" +msgstr "views_handler_sort_formula manca predefinito: @formula" + +#: handlers/views_handler_argument.inc:248 +msgid "Display all values" +msgstr "Mostra tutti i valori" + +#: handlers/views_handler_argument.inc:258 +msgid "Display empty text" +msgstr "Mostra testo vuoto" + +#: includes/plugins.inc:94 +msgid "Displays rows one after another." +msgstr "Visualizza le righe una dopo l'altra." + +#: includes/plugins.inc:105 +msgid "Displays rows as an HTML list." +msgstr "Visualizza le righe come in una lista HTML." + +#: includes/plugins.inc:125 +msgid "Displays rows in a table." +msgstr "Visualizza le righe in una tabella." + +#: includes/plugins.inc:174 +msgid "Displays the fields with an optional template." +msgstr "Visualizza i campi con un template opzionale." + +#: modules/node.views.inc:628,617 +msgid "Display the node with standard node view." +msgstr "Visualizza il nodo con la standard node view." + +#: modules/node.views.inc:57 +msgid "Nid" +msgstr "Nid" + +#: modules/node.views.inc:108; +#: modules/comment.views.inc:133 +msgid "Post date" +msgstr "Data di inserimento" + +#: modules/node.views.inc:124 +msgid "Updated date" +msgstr "Data di aggiornamento" + +#: modules/node/views_handler_field_node.inc:32 +msgid "Link this field to its node" +msgstr "Collega questo campo al suo nodo" + +#: handlers/views_handler_field_boolean.inc:53 +msgid "On" +msgstr "On" + +#: handlers/views_handler_field_boolean.inc:53 +msgid "Off" +msgstr "Off" + +#: includes/view.inc:1861 +msgid "fields" +msgstr "campi" + +#: modules/system.views.inc:49 +msgid "File ID" +msgstr "ID file" + +#: handlers/views_handler_filter.inc:465 +msgid "<Any>" +msgstr "<Qualsiasi>" + +#: modules/node/views_plugin_row_node_rss.inc:24; +#: handlers/views_handler_field_prerender_list.inc:29 +msgid "Display type" +msgstr "Tipo di visualizzazione" + +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:125; +#: modules/taxonomy/views_handler_argument_taxonomy.inc:18 +msgid "No name" +msgstr "Nessun nome" + +#: handlers/views_handler_filter_string.inc:41 +msgid "contains" +msgstr "contiene" + +#: plugins/views_plugin_display.inc:752 +msgid "Information" +msgstr "Informazioni" + +#: includes/admin.inc:266 +msgid "Sort by" +msgstr "Ordina per" + +#: includes/plugins.inc:144,93 +msgid "Unformatted" +msgstr "Non formattato" + +#: modules/user/views_handler_field_user_mail.inc:19 +msgid "No link" +msgstr "Nessun link" + +#: theme/views-ui-edit-tab.tpl.php:31 +msgid "View settings" +msgstr "Impostazioni vista" + +#: handlers/views_handler_field_boolean.inc:24 +msgid "Output format" +msgstr "Formato di output" + +#: handlers/views_handler_filter_string.inc:58 +msgid "Starts with" +msgstr "Inizia con" + +#: handlers/views_handler_field_numeric.inc:38 +msgid "Precision" +msgstr "Precisione" + +#: views.module:629 +msgid "Broken handler @table.@field" +msgstr "Errato gestore @table.@field" + +#: views.module:747 +msgid "Skipping broken view @view" +msgstr "Salta la vista @view errata" + +#: views_ui.module:159 +msgid "The converter will make a best-effort attempt to convert a Views 1 view to Views 2. This conversion is not reliable; you will very likely have to make adjustments to your view to get it to match. You can import Views 1 views through the normal Import tab." +msgstr "Il convertitore farà del suo meglio per convertire una vista Views 1 a Views 2. Tale conversione non è affidabile; molto probabilmente si dovranno apportare degli aggiustamenti alla vista per farla corrispondere. È possibile importare una vista Views 1 tramite la scheda Importa normale." + +#: views_ui.module:265 +msgid "Changes cannot be made to a locked view." +msgstr "Non possono essere fatte modifiche a una vista bloccata." + +#: views.install:57 +msgid "A tag used to group/sort views in the admin interface" +msgstr "Un contrassegno usato per raggruppare/ordinare le viste nell'interfaccia di amministrazione" + +#: views.install:104 +msgid "The title of the display, viewable by the administrator." +msgstr "Il titolo della visualizzazione, visibile dall'amministratore." + +#: views.install:131 +msgid "A special cache used to store objects that are being edited; it serves to save state in an ordinarily stateless environment." +msgstr "Una cache speciale usata per memorizzare gli oggetti che vengono modificati; serve per salvare lo stato in un ambiente generalmente privo di stato." + +#: views.install:136 +msgid "The session ID this cache object belongs to." +msgstr "L'ID di sessione a cui appartiene questo oggetto cache." + +#: views.install:141 +msgid "The name of the view this cache is attached to." +msgstr "Il nome della vista alla quale è allegata questa cache." + +#: views.install:146 +msgid "The name of the object this cache is attached to; this essentially represents the owner so that several sub-systems can use this cache." +msgstr "Il nome dell'oggetto al quale è allegata questa cache; essenzialmente questo rappresenta il proprietario così che diversi sotto-sistemi possono usare questa cache." + +#: views.install:153 +msgid "The time this cache was created or updated." +msgstr "L'ora in cui questa cache è stata creata o aggiornata." + +#: views.install:157 +msgid "Serialized data being stored." +msgstr "I dati serializzati sono in memorizzazione." + +#: views_ui.info:0 +msgid "Administrative interface to views. Without this module, you cannot create or edit your views." +msgstr "Interfaccia di amministrazione delle viste. Senza questo modulo non si possono creare o modificare le viste." + +#: docs/docs.php:127 +msgid "Emulates the default Drupal front page; you may set the default home page path to this view to make it your front page." +msgstr "Emula la prima pagina predefinita di Drupal; si può impostare il percorso della home page predefinita a questa vista per renderla la propria prima pagina." + +#: docs/docs.php:349 +msgid "Front page feed" +msgstr "Feed prima pagina" + +#: handlers/views_handler_argument.inc:121 +msgid "The title to use when this argument is present. It will override the title of the view and titles from previous arguments. You can use percent substitution here to replace with argument titles. Use \"%1\" for the first argument, \"%2\" for the second, etc." +msgstr "Il titolo da usare quando questo argomento è presente. Modificherà il titolo della vista e i titoli degli argomenti precedenti. Qui è possibile usare un simbolo percentuale di sostituzione da rimpiazzare con i titoli degli argomenti. Usare \"%1\" per il primo argomento, \"%2\" per il secondo, ecc." + +#: handlers/views_handler_argument.inc:134 +msgid "Action to take if argument is not present" +msgstr "Azione da intraprendere se l'argomento non è presente" + +#: handlers/views_handler_argument.inc:149 +msgid "If this value is received as an argument, the argument will be ignored; i.e, \"all values\"" +msgstr "Se questo valore viene ricevuto come argomento, l'argomento sarà ignorato; vale a dire, \"tutti i valori\"" + +#: handlers/views_handler_argument.inc:155 +msgid "Wildcard title" +msgstr "Titolo jolly" + +#: handlers/views_handler_argument.inc:158 +msgid "The title to use for the wildcard in substitutions elsewhere." +msgstr "Il titolo da usare come jolly nelle sostituzioni altrove." + +#: handlers/views_handler_argument.inc:181 +msgid "Validator options" +msgstr "Opzioni del validatore" + +#: handlers/views_handler_argument.inc:186 +msgid "Validator" +msgstr "Validatore" + +#: handlers/views_handler_argument.inc:190 +msgid "<Basic validation>" +msgstr "<Validazione di base>" + +#: handlers/views_handler_argument.inc:229 +msgid "Action to take if argument does not validate" +msgstr "Azione da intraprendere se l'argomento non valida" + +#: handlers/views_handler_argument.inc:253 +msgid "Hide view / Page not found (404)" +msgstr "Nascondi vista / Pagina non trovata (404)" + +#: handlers/views_handler_argument.inc:277 +msgid "Provide default argument" +msgstr "Stabilire l'argomento predefinito" + +#: handlers/views_handler_argument.inc:310 +msgid "Provide default argument options" +msgstr "Stabilire le opzioni dell'argomento predefinito" + +#: handlers/views_handler_argument.inc:320 +msgid "Default argument type" +msgstr "Tipo di argomento predefinito" + +#: handlers/views_handler_sort.inc:66; +#: handlers/views_handler_relationship.inc:133; +#: handlers/views_handler_filter.inc:592; +#: handlers/views_handler_field.inc:227; +#: handlers/views_handler_argument.inc:708 +msgid "Broken/missing handler" +msgstr "Gestore rotto/mancante" + +#: handlers/views_handler_sort.inc:74; +#: handlers/views_handler_relationship.inc:141; +#: handlers/views_handler_filter.inc:600; +#: handlers/views_handler_field.inc:235; +#: handlers/views_handler_argument.inc:716 +msgid "The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item." +msgstr "Il gestore di questa voce è rotto o mancante e non può essere usato. Se un modulo che ha fornito un gestore viene disattivato, riattivandolo può ripristinarlo. Altrimenti si dovrà probabilmente eliminare questa voce." + +#: handlers/views_handler_argument_date.inc:29 +msgid "Current date" +msgstr "Data corrente" + +#: handlers/views_handler_argument_date.inc:30 +msgid "Current node's creation time" +msgstr "Data di inserimento del nodo corrente" + +#: handlers/views_handler_argument_date.inc:31 +msgid "Current node's update time" +msgstr "Data di aggiornamento del nodo corrente" + +#: handlers/views_handler_argument_numeric.inc:30; +#: handlers/views_handler_argument_many_to_one.inc:45 +msgid "Allow multiple terms per argument." +msgstr "Consente termini multipli per argomento." + +#: handlers/views_handler_argument_many_to_one.inc:46 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 (for OR) or 1,2,3 (for AND)." +msgstr "Se selezioato, gli utenti possono inserire nel form argomenti multipli nella forma di 1+2+3 (per OR) oppure 1,2,3 (per AND)." + +#: handlers/views_handler_argument_string.inc:95; +#: handlers/views_handler_argument_many_to_one.inc:53 +msgid "Allow multiple arguments to work together." +msgstr "Consenti agli argomenti multipli di funzionare insieme." + +#: handlers/views_handler_argument_string.inc:96; +#: handlers/views_handler_argument_many_to_one.inc:54 +msgid "If selected, multiple instances of this argument can work together, as though multiple terms were supplied to the same argument. This setting is not compatible with the \"Reduce duplicates\" setting." +msgstr "Se selezionato, le istanze multiple di questo argomento possono funzionare insieme, come se dei termini multipli fossero forniti allo stesso argomento. Questa impostazione non è compatibile con l'impostazione \"Riduci i duplicati\"." + +#: handlers/views_handler_argument_string.inc:102; +#: handlers/views_handler_argument_many_to_one.inc:60 +msgid "Do not display items with no value in summary" +msgstr "Non visualizzare le voci che non hanno alcun valore nel sommario" + +#: handlers/views_handler_argument_numeric.inc:61; +#: handlers/views_handler_argument_many_to_one.inc:113 +msgid "Invalid input" +msgstr "Inserimento non valido" + +#: handlers/views_handler_argument_null.inc:21 +msgid "Fail basic validation if any argument is given" +msgstr "Boccia la validazione di base se non viene dato alcun argomento" + +#: handlers/views_handler_argument_null.inc:23 +msgid "By checking this field, you can use this to make sure views with more arguments than necessary fail validation." +msgstr "Selezionando questo campo, lo si può usare per assicurarsi che le viste con più argomenti del necessario non superino la validazione." + +#: handlers/views_handler_argument_numeric.inc:31 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 or 1,2,3." +msgstr "Se selezionato gli utenti possono inserire argomenti multipli nella forma di 1+2+3 o 1,2,3." + +#: handlers/views_handler_argument_numeric.inc:37 +msgid "Exclude the argument" +msgstr "Escludi l'argomento" + +#: handlers/views_handler_argument_numeric.inc:38 +msgid "If selected, the numbers entered in the argument will be excluded rather than limiting the view." +msgstr "Se selezionato i numeri inseriti nell'argomento saranno esclusi anziché limitare la vista." + +#: handlers/views_handler_argument_string.inc:44 +msgid "Glossary mode" +msgstr "Modalità glossario" + +#: handlers/views_handler_argument_string.inc:45 +msgid "Glossary mode applies a limit to the number of characters used in the argument, which allows the summary view to act as a glossary." +msgstr "La modalitù glossario applica un limite al numero di caratteri usati nell'argomento, il che permette alla vista sommario di agire come un glossario." + +#: handlers/views_handler_argument_string.inc:51 +msgid "Character limit" +msgstr "Limite caratteri" + +#: handlers/views_handler_argument_string.inc:52 +msgid "How many characters of the argument to filter against. If set to 1, all fields starting with the letter in the argument would be matched." +msgstr "Quanti sono i caratteri dell'argomento con cui filtrare. Se impostato a 1, tutti i campi che iniziano con la lettera nell'argomento corrisponderanno." + +#: handlers/views_handler_argument_string.inc:61 +msgid "When printing the argument result, how to transform the case." +msgstr "Nello scrivere il risultato dell'argomento, come trasformare i caratteri." + +#: handlers/views_handler_argument_string.inc:77,63 +msgid "No transform" +msgstr "Nessuna trasformazione" + +#: handlers/views_handler_argument_string.inc:78,64 +msgid "Upper case" +msgstr "Maiuscole" + +#: handlers/views_handler_argument_string.inc:79,65 +msgid "Lower case" +msgstr "Minuscole" + +#: handlers/views_handler_argument_string.inc:80,66 +msgid "Capitalize first letter" +msgstr "Prima lettera maiuscola" + +#: handlers/views_handler_argument_string.inc:81,67 +msgid "Capitalize each word" +msgstr "Ogni parola in maiuscolo" + +#: handlers/views_handler_argument_string.inc:74 +msgid "Case in path" +msgstr "Caratteri nel percorso" + +#: handlers/views_handler_argument_string.inc:75 +msgid "When printing url paths, how to transform the of the argument. Do not use this unless with Postgres as it uses case sensitive comparisons." +msgstr "Nello scrivere i percorsi degli url, come trasformare il \"dell'argomento\". Non usare se non con Postgres, poiché esso utilizza la comparazione delle maiuscole/minuscole." + +#: handlers/views_handler_argument_string.inc:88 +msgid "Transform spaces to dashes in URL" +msgstr "Trasforma gli spazi negli URL in trattini" + +#: handlers/views_handler_field.inc:148 +msgid "The label for this field that will be displayed to end users if the style requires it." +msgstr "L'etichetta per questo campo che sarà mostrata agli utenti finali se lo stile lo richiede." + +#: handlers/views_handler_field.inc:152 +msgid "Exclude from display" +msgstr "Escludi dalla visualizzazione" + +#: handlers/views_handler_field.inc:154 +msgid "Check this box to not display this field, but still load it in the view. Use this option to not show a grouping field in each record, or when doing advanced theming." +msgstr "Selezionare questa casella per non mostrare questo campo, caricandolo comunque nella vista. Usare questa opzione per non mostrare un campo raggruppato in ogni documento, o quando si fa della temizzazione avanzata." + +#: handlers/views_handler_field_boolean.inc:26 +msgid "Yes/No" +msgstr "Sì/No" + +#: handlers/views_handler_field_boolean.inc:27 +msgid "True/False" +msgstr "True/False" + +#: handlers/views_handler_field_boolean.inc:28 +msgid "On/Off" +msgstr "On/Off" + +#: handlers/views_handler_field_boolean.inc:34 +msgid "Reverse" +msgstr "Inverti" + +#: handlers/views_handler_field_boolean.inc:35 +msgid "If checked, true will be displayed as false." +msgstr "Se selezionato, true verrà mostrato come false." + +#: handlers/views_handler_field_date.inc:37 +msgid "If \"Custom\", see <a href=\"http://us.php.net/manual/en/function.date.php\" target=\"_blank\">the PHP docs</a> for date formats. If \"Time ago\" this is the the number of different units to display, which defaults to two." +msgstr "Se è \"Personalizzato\", consultare <a href=\"http://us.php.net/manual/it/function.date.php\" target=\"_blank\">i documenti PHP</a> per i formati della data. Se è \"Tempo fa\", questo è il numero di unità differenti da mostrare, che si riduce a due." + +#: handlers/views_handler_field_numeric.inc:32 +msgid "Round" +msgstr "Arrotonda" + +#: handlers/views_handler_field_numeric.inc:33 +msgid "If checked, the number will be rounded." +msgstr "Se selezionato, il numero verrà arrotondato." + +#: handlers/views_handler_field_numeric.inc:40 +msgid "Specify how many digits to print after the decimal point." +msgstr "Specificare quante cifre scrivere dopo la virgola decimale." + +#: handlers/views_handler_field_numeric.inc:47 +msgid "Decimal point" +msgstr "Virgola decimale" + +#: handlers/views_handler_field_numeric.inc:49 +msgid "What single character to use as a decimal point." +msgstr "Il carattere singolo da utilizzare come virgola decimale." + +#: handlers/views_handler_field_numeric.inc:57 +msgid "What single character to use as the thousands separator." +msgstr "Il carattere singolo da utilizzare come separatore delle migliaia." + +#: handlers/views_handler_field_numeric.inc:64 +msgid "Text to put before the number, such as currency symbol." +msgstr "Testo da inserire prima del numero, tipo il simbolo della valuta." + +#: handlers/views_handler_field_numeric.inc:70 +msgid "Text to put after the number, such as currency symbol." +msgstr "Testo da inserire dopo il numero, tipo il simbolo della valuta." + +#: handlers/views_handler_field_prerender_list.inc:31; +#: plugins/views_plugin_style_list.inc:33 +msgid "Unordered list" +msgstr "Elenco non ordinato" + +#: handlers/views_handler_field_prerender_list.inc:32; +#: plugins/views_plugin_style_list.inc:33 +msgid "Ordered list" +msgstr "Elenco ordinato" + +#: handlers/views_handler_field_prerender_list.inc:33 +msgid "Simple separator" +msgstr "Separatore semplice" + +#: handlers/views_handler_field_prerender_list.inc:48 +msgid "Empty list text" +msgstr "Elenco di testo vuoto" + +#: handlers/views_handler_field_prerender_list.inc:50 +msgid "If the list is empty, you may enter text here that will be displayed." +msgstr "Se l'elenco è vuoto, qui si può inserire del testo da visualizzare." + +#: modules/statistics/views_handler_field_accesslog_path.inc:31; +#: handlers/views_handler_field_url.inc:24 +msgid "Display as link" +msgstr "Visualizza come link" + +#: handlers/views_handler_filter.inc:206 +msgid "This item is currently not exposed. If you <strong>expose</strong> it, users will be able to change the filter as they view it." +msgstr "Questa voce attualmente non è esposta. Se la si <strong>espone</strong>, gli utenti potranno cambiare il filtro quando la visualizzano." + +#: handlers/views_handler_filter.inc:218 +msgid "This item is currently exposed. If you <strong>hide</strong> it, users will not be able to change the filter as they view it." +msgstr "Questa voce attualmente è esposta. Se la si <strong>nasconde</strong> gli utenti non potranno modificare il filtro quando lo vedono." + +#: handlers/views_handler_filter.inc:289 +msgid "Unlock operator" +msgstr "Sblocca operatore" + +#: handlers/views_handler_filter.inc:290 +msgid "When checked, the operator will be exposed to the user" +msgstr "Quando selezionato, l'operatore sarà esposto all'utente" + +#: handlers/views_handler_filter.inc:296 +msgid "Operator identifier" +msgstr "Identificatore operatore" + +#: handlers/views_handler_filter.inc:298 +msgid "This will appear in the URL after the ? to identify this operator." +msgstr "Questo apparirà nell'URL dopo il ? per identificare questo operatore." + +#: handlers/views_handler_filter.inc:315 +msgid "Filter identifier" +msgstr "Identificatore filtro" + +#: handlers/views_handler_filter.inc:317 +msgid "This will appear in the URL after the ? to identify this filter. Cannot be blank." +msgstr "Questo apparirà nell'URL dopo il ? per identificare questo filtro. Non può essere vuoto." + +#: handlers/views_handler_filter.inc:334 +msgid "This exposed filter is optional and will have added options to allow it not to be set." +msgstr "Questo filtro esposto è opzionale e avrà aggiunte delle opzioni per consentirgli di non essere impostato." + +#: handlers/views_handler_filter.inc:340 +msgid "Force single" +msgstr "Forza singolo" + +#: handlers/views_handler_filter.inc:341 +msgid "Force this exposed filter to accept only one option." +msgstr "Forza questo filtro esposta ad accettare solo un'opzione." + +#: handlers/views_handler_filter.inc:347 +msgid "Remember" +msgstr "Ricorda" + +#: handlers/views_handler_filter.inc:348 +msgid "Remember the last setting the user gave this filter." +msgstr "Ricorda l'ultima impostazione data dall'utente a questo filtro." + +#: handlers/views_handler_filter.inc:359 +msgid "The identifier is required if the filter is exposed." +msgstr "Se il filtro è esposto, è richiesto l'identificatore." + +#: handlers/views_handler_filter.inc:364 +msgid "This identifier is not allowed." +msgstr "Questo identificatore non è consentito." + +#: handlers/views_handler_filter_string.inc:111; +#: handlers/views_handler_filter_numeric.inc:251; +#: handlers/views_handler_filter_in_operator.inc:175; +#: handlers/views_handler_filter_boolean_operator.inc:58 +msgid "exposed" +msgstr "esposto" + +#: handlers/views_handler_filter_date.inc:24 +msgid "Value type" +msgstr "Tipo di valore" + +#: handlers/views_handler_filter_date.inc:26 +msgid "A date in any machine readable format. CCYY-MM-DD HH:MM:SS is preferred." +msgstr "Una data in qualsiasi formato leggibile dal computer. È preferibile CCYY-MM-DD HH:MM:SS." + +#: handlers/views_handler_filter_date.inc:27 +msgid "An offset from the current time such as \"+1 day\" or \"-2 hours -30 minutes\"" +msgstr "Una deviazione dall'ora corrente, tipo \"+1 giorno\" o \"-2 ore -30 minuti\"" + +#: handlers/views_handler_filter_date.inc:87,83,77 +msgid "Invalid date format." +msgstr "Formato data non corretto." + +#: handlers/views_handler_filter_in_operator.inc:37 +msgid "Limit list to selected items" +msgstr "Limita l'elenco alle voci selezionate" + +#: handlers/views_handler_filter_in_operator.inc:38 +msgid "If checked, the selected items presented to the user will be the only ones selected here." +msgstr "Se attivato, le voci selezionate presentate all'utente saranno solamente quelle selezionate qui." + +#: handlers/views_handler_filter_many_to_one.inc:32; +#: handlers/views_handler_filter_in_operator.inc:57 +msgid "Is one of" +msgstr "È uno di" + +#: handlers/views_handler_filter_in_operator.inc:58 +msgid "Is not one of" +msgstr "Non è uno di" + +#: handlers/views_handler_filter_many_to_one.inc:33 +msgid "Is all of" +msgstr "È tutto di" + +#: handlers/views_handler_filter_many_to_one.inc:34 +msgid "Is none of" +msgstr "Non è nessuno di" + +#: handlers/views_handler_filter_numeric.inc:28 +msgid "<" +msgstr "<" + +#: handlers/views_handler_filter_numeric.inc:34 +msgid "<=" +msgstr "<=" + +#: handlers/views_handler_filter_numeric.inc:46 +msgid "!=" +msgstr "!=" + +#: handlers/views_handler_filter_numeric.inc:52 +msgid ">=" +msgstr ">=" + +#: handlers/views_handler_filter_numeric.inc:58 +msgid ">" +msgstr ">" + +#: handlers/views_handler_filter_numeric.inc:62 +msgid "Is between" +msgstr "È tra" + +#: handlers/views_handler_filter_numeric.inc:64 +msgid "between" +msgstr "tra" + +#: handlers/views_handler_filter_numeric.inc:68 +msgid "Is not between" +msgstr "Non è tra" + +#: handlers/views_handler_filter_numeric.inc:70 +msgid "not between" +msgstr "non tra" + +#: handlers/views_handler_filter_string.inc:80; +#: handlers/views_handler_filter_numeric.inc:79 +msgid "Is empty (NULL)" +msgstr "È vuoto (NULL)" + +#: handlers/views_handler_filter_string.inc:82; +#: handlers/views_handler_filter_numeric.inc:81 +msgid "empty" +msgstr "vuoto" + +#: handlers/views_handler_filter_string.inc:86; +#: handlers/views_handler_filter_numeric.inc:85 +msgid "Is not empty (NULL)" +msgstr "Non è vuoto (NULL)" + +#: handlers/views_handler_filter_string.inc:88; +#: handlers/views_handler_filter_numeric.inc:87 +msgid "not empty" +msgstr "non vuoto" + +#: handlers/views_handler_filter_numeric.inc:175 +msgid "Min" +msgstr "Min" + +#: handlers/views_handler_filter_numeric.inc:181 +msgid "And max" +msgstr "E max" + +#: handlers/views_handler_filter_numeric.inc:181 +msgid "And" +msgstr "E" + +#: handlers/views_handler_filter_numeric.inc:257 +msgid "@min and @max" +msgstr "@min e @max" + +#: handlers/views_handler_filter_string.inc:46 +msgid "Contains any word" +msgstr "Contiene ogni parola" + +#: handlers/views_handler_filter_string.inc:47 +msgid "has word" +msgstr "ha la parola" + +#: handlers/views_handler_filter_string.inc:52 +msgid "Contains all words" +msgstr "Contiene tutte le parole" + +#: handlers/views_handler_filter_string.inc:53 +msgid "has all" +msgstr "ha tutte" + +#: handlers/views_handler_filter_string.inc:59 +msgid "begins" +msgstr "inizia" + +#: handlers/views_handler_filter_string.inc:64 +msgid "Ends with" +msgstr "Termina con" + +#: handlers/views_handler_filter_string.inc:65 +msgid "ends" +msgstr "termina" + +#: handlers/views_handler_filter_string.inc:71 +msgid "!has" +msgstr "!has" + +#: handlers/views_handler_filter_string.inc:126 +msgid "Case sensitive" +msgstr "Maiuscole/minuscole" + +#: handlers/views_handler_filter_string.inc:128 +msgid "Case sensitive filters may be faster. MySQL might ignore case sensitivity." +msgstr "I filtri sensibili a maiuscole/minuscole possono essere più v eloci. MySQL potrebbe ignorare le maiuscole/minuscole." + +#: handlers/views_handler_relationship.inc:80 +msgid "The label for this relationship that will be displayed only administratively." +msgstr "L'etichetta per questa relazione che verrà mostrata solo in amministrazione." + +#: handlers/views_handler_relationship.inc:85 +msgid "Require this relationship" +msgstr "Richiedi questa relazione" + +#: handlers/views_handler_relationship.inc:86 +msgid "If required, items that do not contain this relationship will not appear." +msgstr "Se richiesta, le voci che non contengono questa relazione non compariranno." + +#: handlers/views_handler_sort.inc:38 +msgid "asc" +msgstr "asc" + +#: handlers/views_handler_sort.inc:42 +msgid "desc" +msgstr "disc" + +#: handlers/views_handler_sort.inc:54 +msgid "Sort order" +msgstr "Ordina per" + +#: handlers/views_handler_sort_date.inc:35 +msgid "The granularity is the smallest unit to use when determining whether two dates are the same; for example, if the granularity is \"Year\" then all dates in 1999, regardless of when they fall in 1999, will be considered the same date." +msgstr "La granularità è la più piccola unità usata quando si determina se due date sono uguali; per esempio, se la granularità è \"Anno\" allora tutte le date in 1999, indipendentemente da quando cadono nel 1999, saranno considerate la stessa data." + +#: includes/admin.inc:36 +msgid "If you <a href=\"@modules\">enable the advanced help module</a>, Views will provide more and better help. <a href=\"@hide\">Hide this message.</a>" +msgstr "Se si <a href=\"@modules\">attiva il modulo di aiuto avanzato</a>, Views fornirà un aiuto ulteriore e migliore. <a href=\"@hide\">Nascondi questo messaggio.</a>" + +#: includes/admin.inc:39 +msgid "If you install the advanced help module from !href, Views will provide more and better help. <a href=\"@hide\">Hide this message.</a>" +msgstr "Se si installa il modulo advanced help module da !href, Viste fornirà maggior e miglior aiuto. <a href=\"@hide\">Nascondi questo messaggio.</a>" + +#: includes/admin.inc:112 +msgid "Warning! Broken view!" +msgstr "Attenzione! Vista non funzionante!" + +#: includes/view.inc:1663; +#: includes/admin.inc:127 +msgid "Broken" +msgstr "Corrotto" + +#: includes/admin.inc:186 +msgid "Install the advanced help module for the getting started" +msgstr "Installare il modulo advanced help per iniziare" + +#: includes/admin.inc:189 +msgid "Not sure what to do? Try the \"!getting-started\" page." +msgstr "Non sai fare? Consulta la pagina \"!getting-started\"." + +#: includes/admin.inc:208 +msgid "Storage" +msgstr "Memoria" + +#: includes/admin.inc:259 +msgid "Displays" +msgstr "Visualizzazioni" + +#: includes/admin.inc:369 +msgid "These queries were run during view rendering:" +msgstr "Queste query sono state eseguite durante il rendering della vista:" + +#: includes/admin.inc:374 +msgid "[@time ms]" +msgstr "[@time ms]" + +#: includes/admin.inc:377 +msgid "Other queries" +msgstr "Altre query" + +#: includes/admin.inc:385 +msgid "This display has no path." +msgstr "Questa visualizzazione non ha un percorso." + +#: includes/admin.inc:390 +msgid "Query build time" +msgstr "Tempo di costruzione query" + +#: includes/admin.inc:392,391,390 +msgid "@time ms" +msgstr "@time ms" + +#: includes/admin.inc:391 +msgid "Query execute time" +msgstr "Tempo di esecuzione query" + +#: includes/admin.inc:392 +msgid "View render time" +msgstr "Tempo di resa della vista" + +#: includes/admin.inc:398 +msgid "No query was run" +msgstr "Non è stato eseguita alcuna query" + +#: includes/admin.inc:405 +msgid "Unable to preview due to validation errors." +msgstr "Non è possibile creare l'anteprima a causa di un errore di validazione." + +#: includes/admin.inc:466 +msgid "Separate arguments with a / as though they were a URL path." +msgstr "Separare gli argomenti con / come se fossero un percorso URL." + +#: includes/admin.inc:510 +msgid "Clone view %view" +msgstr "Clona la vista %view" + +#: includes/convert.inc:20; +#: includes/admin.inc:710,523 +msgid "View name" +msgstr "Nome della vista" + +#: includes/admin.inc:524 +msgid "This is the unique name of the view. It must contain only alphanumeric characters and underscores; it is used to identify the view internally and to generate unique theming template names for this view. If overriding a module provided view, the name must not be changed or instead a new view will be created." +msgstr "Questo è il nome univoco della vista. Può contenere solo caratteri alfanumerici e underscore (_); viene usato per identificare la vista internamente e per generare nomi di modelli di temi univoci per questa vista. Se si modifica la vista fornita da un modulo, il nome non deve essere cambiato altrimenti verrà creata una nuova vista." + +#: includes/admin.inc:1872,532 +msgid "View description" +msgstr "Descrizione vista" + +#: includes/admin.inc:1873,533 +msgid "This description will appear on the Views administrative UI to tell you what the view is about." +msgstr "La descrizione che comparirà nella UI di amministrazione di Viste per dare informazioni sulla vista." + +#: includes/admin.inc:1879,539 +msgid "View tag" +msgstr "Etichetta vista" + +#: includes/admin.inc:1880,540 +msgid "Enter an optional tag for this view; it is used only to help sort views on the administrative page." +msgstr "Inserire un'etichetta opzionale per questa vista; viene usata solo per ordinare le viste nella pagina di amministrazione." + +#: includes/admin.inc:553 +msgid "The view type is the primary table for which information is being retrieved. The view type controls what arguments, fields, sort criteria and filters are available, so once this is set it <strong>cannot be changed</strong>." +msgstr "Il tipo di vista è la tabella primaria per la quale l'informazione viene ricuperata. Il tipo di vista regola quali argomenti, campi, criteri di ordinamento sono disponibili, per cui una volta che ciò è impostato <strong>non può essere modificato</strong>." + +#: includes/admin.inc:586 +msgid "You must use a unique name for this view." +msgstr "Bisogna usare un nome univoco per questa vista." + +#: includes/admin.inc:619 +msgid "Are you sure you want to revert the view %name?" +msgstr "Sicuro di voler tornare alla vista %name?" + +#: includes/admin.inc:620 +msgid "Reverting the view will delete the view that is in the database, reverting it to the original default view. Any changes you have made will be lost and cannot be recovered." +msgstr "Tornando alla vista eliminerà la vista nel database, riportandola alla vista originale predefinita. Qualsiasi modifica fatta sarà persa e non potrà essere recuperata." + +#: includes/convert.inc:105; +#: includes/admin.inc:623 +msgid "Are you sure you want to delete the view %name?" +msgstr "Sicuro di voler eliminare la vista %name?" + +#: includes/admin.inc:624 +msgid "Deleting a view cannot be undone." +msgstr "L'eliminazione di una vista non può essere annullata." + +#: includes/admin.inc:641 +msgid "The view has been deleted." +msgstr "La vista è stata eliminata." + +#: includes/admin.inc:653 +msgid "There is no lock on view %view to break." +msgstr "Non ci sono <a href=\"http://it.wikipedia.org/wiki/Lock\">lock</a> nella vista %view da interrompere." + +#: includes/admin.inc:663 +msgid "Are you sure you want to break the lock on view %name?" +msgstr "Si è sicuri di voler interrompere il <a href=\"http://it.wikipedia.org/wiki/Lock\">blocco</a> sulla vista %name?" + +#: includes/admin.inc:666 +msgid "By breaking this lock, any unsaved changes made by !user will be lost!" +msgstr "Se si interrompe questo <a href=\"http://it.wikipedia.org/wiki/Lock\">blocco</a>, qualsiasi modifica non salvata fatta da !user andrà persa." + +#: includes/admin.inc:667 +msgid "Break lock" +msgstr "Interrompi il blocco" + +#: includes/admin.inc:677 +msgid "The lock has been broken and you may now edit this view." +msgstr "Il blocco è stato rimosso e ora è possibile modificare questa vista." + +#: includes/admin.inc:684 +msgid "Edit view %view" +msgstr "Modifica la vista %view" + +#: includes/admin.inc:711 +msgid "Enter the name to use for this view if it is different from the source view. Leave blank to use the name of the view." +msgstr "Inserire il nome da usare per questa vista, se è diverso dalla vista sorgente. Lasciare vuoto per usare il nome della vista." + +#: includes/admin.inc:716 +msgid "Paste view code here" +msgstr "Incollare qui il codice della vista" + +#: includes/admin.inc:738 +msgid "Unable to interpret view code." +msgstr "Impossibile interpretare il codice della vista." + +#: includes/admin.inc:746 +msgid "You are importing a view created in Views version 1. You may need to adjust some parameters to work correctly in version 2." +msgstr "Si sta importando una vista creata con Views versione 1. Può essere necessario regolare alcuni parametri per funzionare correttamente nella versione 2." + +#: includes/admin.inc:749 +msgid "That view is not compatible with this version of Views." +msgstr "La vista non è compatibile con questa versione di Viste." + +#: includes/admin.inc:764 +msgid "A view by that name already exists; please choose a different name" +msgstr "Una vista con quel nome esiste già; si prega di scegliere un nome differente" + +#: includes/admin.inc:773 +msgid "Display plugin @plugin is not available." +msgstr "Il plugin della visualizzazione @plugin non è disponibile." + +#: includes/admin.inc:780 +msgid "Style plugin @plugin is not available." +msgstr "Il plugin dello stile @plugin non è disponibile." + +#: includes/admin.inc:786 +msgid "Row plugin @plugin is not available." +msgstr "Il plugin della riga @plugin non è disponibile." + +#: includes/admin.inc:796 +msgid "@type handler @table.@field is not available." +msgstr "Il gestore di @type @table.@field non è disponibile." + +#: includes/admin.inc:809 +msgid "Unable to import view." +msgstr "Impossibile importare la vista." + +#: includes/admin.inc:882 +msgid "The view has been saved." +msgstr "La vista è stata salvata." + +#: includes/admin.inc:926 +msgid "Unknown or missing table name" +msgstr "Nome della tabella sconosciuto o mancante" + +#: includes/admin.inc:931 +msgid "Click on an item to edit that item's details." +msgstr "Selezionare una voce per modificarne i dettagli." + +#: includes/admin.inc:934 +msgid "This view has a broken default display and cannot be used." +msgstr "Questa vista ha una visualizzazione predefinita guasta e non può essere usata." + +#: includes/admin.inc:976; +#: theme/theme.inc:97 +msgid "Export this view" +msgstr "Esporta questa vista" + +#: includes/admin.inc:981; +#: theme/theme.inc:102 +msgid "Create a copy of this view" +msgstr "Crea una copia di questa vista" + +#: includes/admin.inc:992 +msgid "View \"!display\"" +msgstr "Visualizza \"!display\"" + +#: includes/admin.inc:993 +msgid "Go to the real page for this display" +msgstr "Vai alla pagina effettiva di questa vista" + +#: includes/admin.inc:1137 +msgid "Invalid" +msgstr "Scorretto" + +#: includes/admin.inc:1138 +msgid "Error: Display @display refers to a plugin named '@plugin', but that plugin doesn't exist!" +msgstr "Errore: La visualizzazione @display fa riferimento a un plugin denominato '@plugin', ma quel plugin non esiste!" + +#: includes/admin.inc:2590,2505,2437,2262,1213 +msgid "Error: handler for @table > @field doesn't exist!" +msgstr "Errore: il gestore per @table > @field non esiste!" + +#: includes/admin.inc:1237; +#: plugins/views_plugin_display.inc:616,598 +msgid "Missing style plugin" +msgstr "Plugin stile mancante" + +#: includes/admin.inc:1241; +#: plugins/views_plugin_display.inc:626,611 +msgid "Change settings for this style" +msgstr "Modifica le impostazioni per questo stile" + +#: includes/admin.inc:1244 +msgid " Style: !style" +msgstr " Stile: !style" + +#: includes/admin.inc:1275 +msgid "Invalid display id found while regenerating tabs" +msgstr "Trovato id visualizzazione non corretto mentre le schede venivano rigenerate" + +#: includes/admin.inc:1326 +msgid "Ok" +msgstr "Ok" + +#: includes/admin.inc:1597 +msgid "Unable to initialize default display" +msgstr "Impossibile inizializzare la visualizzazione predefinita" + +#: includes/admin.inc:1629 +msgid "Add display" +msgstr "Aggiungi" + +#: includes/admin.inc:1669 +msgid "Remove display" +msgstr "Rimuovi visualizzazione" + +#: includes/admin.inc:1680 +msgid "Restore display" +msgstr "Ripristina visualizzazione" + +#: includes/admin.inc:1752 +msgid "Analyze" +msgstr "Analizza" + +#: includes/admin.inc:1772 +msgid "This view has only a default display and therefore will not be placed anywhere on your site; perhaps you want to add a page or a block display." +msgstr "Questa vista ha solamente una visualizzazione predefinita per cui non sarà collocata da nessuna parte nel sito; si consiglia di aggiungere una visualizzazione pagina o blocco." + +#: includes/admin.inc:1784 +msgid "View analysis" +msgstr "Analisi vista" + +#: includes/admin.inc:1793 +msgid "View analysis can find nothing to report." +msgstr "L'analisi vista non ha trovato niente da riferire." + +#: includes/admin.inc:1867 +msgid "View details" +msgstr "Dettagli vista" + +#: includes/admin.inc:2583,2498,2430,2255,2163,2017,1962,1908 +msgid "Invalid display id @display" +msgstr "Scorretto id visualizzazione @display" + +#: includes/admin.inc:1966 +msgid "Configure @type" +msgstr "Configura @type" + +#: includes/admin.inc:2021 +msgid "Rearrange @type" +msgstr "Riordina @type" + +#: includes/admin.inc:2064 +msgid "Broken field @id" +msgstr "field @id guasto" + +#: includes/admin.inc:2169 +msgid "Add @type" +msgstr "Aggiungi @type" + +#: includes/admin.inc:2199 +msgid "!group: !field" +msgstr "!group: !field" + +#: includes/admin.inc:2208 +msgid "There are no @types available to add." +msgstr "Non ci sono @types disponibili da aggiungere." + +#: includes/admin.inc:2305 +msgid "Do not use a relationship" +msgstr "Non usare una relazione" + +#: includes/admin.inc:2332 +msgid "Configure @type %item" +msgstr "Configura @type %item" + +#: includes/admin.inc:2445 +msgid "Configure extra settings for @type %item" +msgstr "Configurare le impostazioni extra per @type %item" + +#: includes/admin.inc:2510 +msgid "Change summary style for @type %item" +msgstr "Modificare lo stile dommario per @type %item" + +#: includes/admin.inc:2547,2533 +msgid "Internal error: broken plugin." +msgstr "Errore interno: plugin guasto." + +#: includes/admin.inc:2597 +msgid "Configure summary style for @type %item" +msgstr "Configurare lo stile sommario per @type %item" + +#: includes/admin.inc:2689 +msgid "Clear Views' cache" +msgstr "Azzera la cache di Viste" + +#: includes/admin.inc:2695 +msgid "Add Views signature to all SQL queries" +msgstr "Aggiungere la firma di Viste a tutte le query SQL" + +#: includes/admin.inc:2696 +msgid "All Views-generated queries will include a special 'VIEWS' = 'VIEWS' string in the WHERE clause. This makes identifying Views queries in database server logs simpler, but should only be used when troubleshooting." +msgstr "Tutte le query generate da Viste includeranno una stringa speciale 'VIEWS' = 'VIEWS' nella clausola WHERE. Ciò rende semplice l'identificazione delle query di Viste nei registri del database del server, ma dovrebbe essere usata solo nella risoluzione di problemi." + +#: includes/admin.inc:2702 +msgid "Disable views data caching" +msgstr "Disattiva il caching dei dati delle viste" + +#: includes/admin.inc:2703 +msgid "Views caches data about tables, modules and views available, to increase performance. By checking this box, Views will skip this cache and always rebuild this data when needed. This can have a serious performance impact on your site." +msgstr "Viste memorizza in cache i dati sulle tabelle, sui moduli e sulle viste disponibili per incrementare le prestazioni. Selezionando questa casella, Viste salterà questa cache e ricostruirà sempre questi dati quando necessario. Ciò può avere un forte impatto sulle prestazioni del sito." + +#: includes/admin.inc:2709 +msgid "Ignore missing advanced help module" +msgstr "Ignora il modulo mancante advanced help" + +#: includes/admin.inc:2710 +msgid "Views uses the advanced help module to provide help text; if this module is not present Views will complain, unless this setting is checked." +msgstr "Viste usa il modulo advanced help per fornire un testo di aiuto; se questo modulo non è presente Viste protesterà, a meno che questa impostazione sia selezionata." + +#: includes/admin.inc:2716 +msgid "Show query above live preview" +msgstr "Mostra la query sopra l'anteprima in diretta" + +#: includes/admin.inc:2717 +msgid "The live preview feature will show you the output of the view you're creating, as well as the view. Check here to show the query and other information above the view; leave this unchecked to show that information below the view." +msgstr "La funzione anteprima in diretta mostrerà il risultato della vista che si sta creando, come pure la vista. Selezionare qui per mostrare la query e altre informazioni sopra la vista; lasciare deselezionato per mostrare quelle informazioni sotto la vista." + +#: includes/admin.inc:2723 +msgid "Show other queries run during render during live preview" +msgstr "Mostra altre esecuzioni di query durante il rendering dell'anteprima in diretta" + +#: includes/admin.inc:2724 +msgid "Drupal has the potential to run many queries while a view is being rendered. Checking this box will display every query run during view render as part of the live preview." +msgstr "Drupal ha la capacità di eseguire molte query mentre viene fatto il rendering di una vista. Selezionando questa casella si visualizzeranno tutte le query durante il rendering della vista come parte dell'anteprima in diretta." + +#: includes/admin.inc:2730 +msgid "Do not show hover links over views" +msgstr "Non mostrare i link hover nelle viste." + +#: includes/admin.inc:2731 +msgid "To make it easier to administrate your views, Views provides 'hover' links to take you to the edit and export screen of a view whenever the view is used. This can be distracting on some themes, though; if it is problematic, you can turn it off here." +msgstr "Per facilitare l'amministrazione delle viste, Viste fornisce i link 'hover' per andare alle videate di modifica ed esportazione di una vista ogniqualvolta essa viene usata. In alcuni temi ciò può distrarre; se è un problema si possono si può disattivare l'hover." + +#: includes/admin.inc:2737 +msgid "Enable views performance statistics via the Devel module" +msgstr "Attiva le statistiche delle prestazioni delle viste tramite il modulo Devel" + +#: includes/admin.inc:2738 +msgid "Check this to enable some Views query and performance statistics <em>if Devel is installed</em>." +msgstr "Selezionarlo per attivare alcune statistiche delle query e delle prestazioni di Viste, <em>nel caso sia installato Devel</em>." + +#: includes/admin.inc:2744 +msgid "Disable javascript with Views" +msgstr "Disattiva javascript con Viste" + +#: includes/admin.inc:2745 +msgid "If you are having problems with the javascript, you can disable it here; the Views UI should degrade and still be usable without javascript, it just not as good." +msgstr "Se si hanno problemi con javascript, è possibile disattivarlo qui; L'interfaccia Views UI dovrebbe degradare ed essere ancora funzionante senza javascript, semplicemente non è altrettanto bella." + +#: includes/admin.inc:2753 +msgid "Page region to output performance statistics" +msgstr "Area della pagina in cui riprodurre le statistiche delle prestazioni" + +#: includes/admin.inc:2766 +msgid "The cache has been cleared." +msgstr "La memoria cache è stata azzerata." + +#: includes/admin.inc:2932 +msgid "Error: missing @component" +msgstr "Errore: @component mancante" + +#: includes/admin.inc:3019 +msgid "Column" +msgstr "Colonna" + +#: includes/admin.inc:3026 +msgid "Default sort" +msgstr "Ordine predefinito" + +#: includes/ajax.inc:82 +msgid "Server reports invalid input error." +msgstr "Il server riporta un errore di inserimento scorretto." + +#: includes/convert.inc:14 +msgid "There are no Views 1 views stored in the database to convert." +msgstr "Nel database non ci sono viste Views 1 da convertire." + +#: includes/convert.inc:33 +msgid "Converted" +msgstr "Convertita" + +#: includes/convert.inc:68 +msgid "The table below lists Views version 1 views that are stored in the database. You can either convert them to work in Views version 2, or delete them. The views are convertible only if there is no Views 2 view with the same name." +msgstr "La tabella seguente elenca le viste di Views versione 1 memorizzatre nel database. È possibile sia convertirle per funzionare con Views versione 2, sia eliminarle. Le viste sono convertibili solo se non ci sono viste Views 2 con lo stesso nome." + +#: includes/convert.inc:79 +msgid "Unable to find view." +msgstr "Impossibile trovare la vista." + +#: includes/convert.inc:89 +msgid "Unable to convert view." +msgstr "Impossibile convertire la vista" + +#: includes/convert.inc:117 +msgid "The view has been deleted" +msgstr "La vista è stata eliminata" + +#: includes/handlers.inc:43 +msgid "Handler @handler include tried to loop infinitely!" +msgstr "Il gestore incluso @handler ha provato troppi loop all'infinito!" + +#: includes/handlers.inc:269 +msgid "!group: !title" +msgstr "!group: !title" + +#: includes/handlers.inc:507 +msgid "Reduce duplicates" +msgstr "Riduci duplicati" + +#: includes/handlers.inc:508 +msgid "This filter can cause items that have more than one of the selected options to appear as duplicate results. If this filter causes duplicate results to occur, this checkbox can reduce those duplicates; however, the more terms it has to search for, the less performant the query will be, so use this with caution." +msgstr "Questo filtro può causare che le voci con più di un'opzione selezionata compaiano come risultati duplicati. Se con questo filtro si verificano dei risultati duplicati, selezionando questa casella si possono ridurre quei duplicati; tuttavia, con più termini la query deve cercare, minore sarà la sua prestazione, quindi usare il filtro con cautela." + +#: includes/plugins.inc:26 +msgid "Default settings for this view." +msgstr "Impostazioni predefinite per questa vista." + +#: includes/plugins.inc:40 +msgid "Display the view as a page, with a URL and menu links." +msgstr "Visualizza la vista come una pagina, con un URL e i link del menu." + +#: includes/plugins.inc:52 +msgid "Display the view as a block." +msgstr "Visualizza la vista come blocco." + +#: includes/plugins.inc:65 +msgid "Attachments added to other displays to achieve multiple views in the same view." +msgstr "Allegati aggiunti ad altre visualizzazione per ottenere viste multiple nella stessa vista." + +#: includes/plugins.inc:73 +msgid "Display the view as a feed, such as an RSS feed." +msgstr "Visualizza la vista come feed, tipo un feed RSS." + +#: includes/plugins.inc:115 +msgid "Displays rows in a grid." +msgstr "Visualizza le righe in una griglia." + +#: includes/plugins.inc:136 +msgid "Displays the default summary as a list." +msgstr "Visualizza il sommario predefinito come un elenco." + +#: includes/plugins.inc:145 +msgid "Displays the summary unformatted, with option for one after another or inline." +msgstr "Visualizza il sommario non formattato, con le opzioni una dopo l'altra o allineate." + +#: includes/plugins.inc:154 +msgid "RSS Feed" +msgstr "Feed RSS" + +#: includes/plugins.inc:155 +msgid "Generates an RSS feed from a view." +msgstr "Genera un feed RSS da una vista." + +#: includes/plugins.inc:187 +msgid "Fixed entry" +msgstr "Voce fissa" + +#: includes/plugins.inc:203,191 +msgid "PHP Code" +msgstr "Codice PHP" + +#: includes/plugins.inc:207 +msgid "Numeric" +msgstr "Numerico" + +#: includes/plugins.inc:219 +msgid "Will be available to all users." +msgstr "Sarà disponibile a tutti gli utenti." + +#: includes/plugins.inc:225 +msgid "Access will be granted to users with any of the specified roles." +msgstr "L'accesso sarà garantito agli utenti con uno dei ruoli specificati." + +#: includes/plugins.inc:232 +msgid "Access will be granted to users with the specified permission string." +msgstr "L'accesso sarà garantito agli utenti con la stringa di permesso specificata." + +#: includes/view.inc:261 +msgid "set_display() called with invalid display id @display." +msgstr "set_display() chiamato con l'id di visualizzazione @display non corretto." + +#: includes/view.inc:1863 +msgid "field" +msgstr "campo" + +#: includes/view.inc:1868 +msgid "arguments" +msgstr "argomenti" + +#: includes/view.inc:1874 +msgid "Sort criteria" +msgstr "Criteri di ordinamento" + +#: includes/view.inc:1875 +msgid "sort criteria" +msgstr "criteri di ordinamento" + +#: includes/view.inc:1876 +msgid "Sort criterion" +msgstr "Criterio di ordinamento" + +#: includes/view.inc:1877 +msgid "sort criterion" +msgstr "criterio di ordinamento" + +#: includes/view.inc:1890 +msgid "relationships" +msgstr "relazioni" + +#: js/ajax_view.js:0; +#: js/ajax.js:0 +msgid "An error occurred at @path." +msgstr "Si è verificato un errore in @path." + +#: js/tabs.js:0 +msgid "jQuery UI Tabs: Mismatching fragment identifier." +msgstr "UI Schede jQuery: indentificatore frammenti discrepanti." + +#: js/tabs.js:0 +msgid "jQuery UI Tabs: Not enough arguments to add tab." +msgstr "UI Schede jQuery: non ci sono argomenti a sufficienza per aggiungere una scheda." + +#: modules/book.views.inc:31 +msgid "The book the node is in." +msgstr "Il libro in cui si trova il nodo." + +#: modules/book.views.inc:58 +msgid "The weight of the book page." +msgstr "Il peso della pagina del libro." + +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:24; +#: modules/comment.views.inc:202; +#: modules/book.views.inc:69 +msgid "Depth" +msgstr "Profondità" + +#: modules/book.views.inc:70 +msgid "The depth of the book page in the hierarchy; top level books have a depth of 1." +msgstr "La profondità della pagina del libro nella gerarchia; i libri top level hanno una profondità 1." + +#: modules/book.views.inc:88 +msgid "The order of pages in the book hierarchy. Remember to sort by weight too if you want exactly the right order." +msgstr "L'ordine delle pagine nella gerarchia del libro. Ricordarsi di ordinare anche per peso se si vuole proprio l'ordine corretto." + +#: modules/book.views.inc:111 +msgid "The parent book node." +msgstr "Il nodo del libro genitore." + +#: modules/comment.views.inc:27 +msgid "Comments are responses to node content." +msgstr "I commenti sono risposte al contenuto del nodo." + +#: modules/comment.views.inc:45 +msgid "The title of the comment." +msgstr "Il titolo del commento." + +#: modules/comment.views.inc:64 +msgid "The text of the comment." +msgstr "Il testo del commento." + +#: modules/comment.views.inc:77 +msgid "The comment ID of the field" +msgstr "L'ID commento del campo" + +#: modules/comment.views.inc:96 +msgid "The name of the poster." +msgstr "Il nome dell'autore." + +#: modules/comment.views.inc:114 +msgid "Author's website" +msgstr "Sito web dell'autore" + +#: modules/comment.views.inc:115 +msgid "The website address of the comment's author. Can be a link. The homepage can also be linked with the Name field. Will be empty if posted by a registered user." +msgstr "L'indirizzo del sito web dell'autore del commento. Può essere un link. Anche la homepage può essere collegata con il campo Nome. Sarà vuoto se inserito da un utente registrato." + +#: modules/comment.views.inc:134 +msgid "Date and time of when the comment was posted." +msgstr "Data e ora di quando è stato inserito il commento." + +#: modules/comment.views.inc:149 +msgid "In moderation" +msgstr "In moderazione" + +#: modules/comment.views.inc:150 +msgid "Whether or not the comment is currently in moderation." +msgstr "Se al momento il commento è o non è in moderazione." + +#: modules/comment.views.inc:167 +msgid "View link" +msgstr "Link guarda" + +#: modules/comment.views.inc:168 +msgid "Provide a simple link to view the comment." +msgstr "Fornisce un link semplice per vedere il commento." + +#: modules/user.views.inc:202; +#: modules/node.views.inc:250; +#: modules/comment.views.inc:176 +msgid "Edit link" +msgstr "Link modifica" + +#: modules/comment.views.inc:177 +msgid "Provide a simple link to edit the comment." +msgstr "Fornisce un link semplice per modificare il commento." + +#: modules/user.views.inc:210; +#: modules/node.views.inc:472,258; +#: modules/comment.views.inc:185 +msgid "Delete link" +msgstr "Link elimina" + +#: modules/comment.views.inc:186 +msgid "Provide a simple link to delete the comment." +msgstr "Fornisce un link semplice per eliminare il commento." + +#: modules/comment.views.inc:194 +msgid "Reply-to link" +msgstr "Link rispondi" + +#: modules/comment.views.inc:195 +msgid "Provide a simple link to reply to the comment." +msgstr "Fornisce un link semplice per rispondere al commento." + +#: modules/comment.views.inc:203 +msgid "Display the depth of the comment if it is threaded." +msgstr "Visualizza la profondità del commento se questo è in una sequenza (thread)." + +#: modules/comment.views.inc:208 +msgid "Sort by the threaded order. This will keep child comments together with their parents." +msgstr "Ordina per sequenza (thread). Ciò terrà i commenti figli assieme ai loro genitori." + +#: modules/comment.views.inc:215 +msgid "The node the comment is a reply to." +msgstr "Il nodo del quale il commento è una risposta." + +#: modules/comment.views.inc:226 +msgid "The user who wrote the comment." +msgstr "L'utente che ha scritto il commento." + +#: modules/comment.views.inc:236 +msgid "Parent CID" +msgstr "CID genitore" + +#: modules/comment.views.inc:237 +msgid "The Comment ID of the parent comment." +msgstr "Il Comment ID del commento genitore." + +#: modules/comment.views.inc:247,242 +msgid "Parent comment" +msgstr "Commento genitore" + +#: modules/comment.views.inc:243 +msgid "The parent comment." +msgstr "Il commento genitore." + +#: modules/comment.views.inc:268 +msgid "Last comment time" +msgstr "Ora dell'ultimo commento" + +#: modules/comment.views.inc:269 +msgid "Date and time of when the last comment was posted." +msgstr "Data e ora di quando è stato inserito l'ultimo commento." + +#: modules/comment.views.inc:284 +msgid "Last comment author" +msgstr "L'autore dell'ultimo commento" + +#: modules/comment.views.inc:285 +msgid "The name of the author of the last posted comment." +msgstr "Il nome dell'autore che ha inserito l'ultimo commento." + +#: modules/comment.views.inc:297 +msgid "Comment count" +msgstr "Numero commenti" + +#: modules/comment.views.inc:298 +msgid "The number of comments a node has." +msgstr "Il numero dei commenti di un nodo." + +#: modules/comment.views.inc:316 +msgid "Updated/commented date" +msgstr "Data di aggiornamento/inserimento commento" + +#: modules/comment.views.inc:317 +msgid "The most recent of last comment posted or node updated time." +msgstr "L'ora del più recente degli ultimi commenti inseriti o dell'ultimo aggiornamento del nodo." + +#: modules/comment.views.inc:340 +msgid "New comments" +msgstr "Nuovi commenti" + +#: modules/comment.views.inc:341 +msgid "The number of new comments on the node." +msgstr "Il numero di nuovi commenti al nodo." + +#: modules/comment.views.inc:349 +msgid "Comment status" +msgstr "Stato commenti" + +#: modules/comment.views.inc:350 +msgid "Whether comments are enabled or disabled on the node." +msgstr "Se i commenti sono attivati o disattivati per il nodo." + +#: modules/comment.views.inc:364 +msgid "User posted or commented" +msgstr "Utente che ha inserito o commentato" + +#: modules/comment.views.inc:365 +msgid "Display comments only if a user posted the node or commented on the node." +msgstr "Visualizza i commenti solo se un utente ha inserito il nodo o ha commentato il nodo." + +#: modules/comment.views.inc:385 +msgid "Display the comment with standard comment view." +msgstr "Visualizza il commento con una vista commento standard." + +#: modules/comment.views.inc:396 +msgid "Display the comment as RSS." +msgstr "Visualizza il commento come RSS." + +#: modules/node.views.inc:30 +msgid "Nodes are a Drupal site's primary content." +msgstr "I nodi sono i contenuti principali dei siti Drupal." + +#: modules/node.views.inc:58 +msgid "The node ID of the node." +msgstr "L'ID del nodo." + +#: modules/node.views.inc:414,86 +msgid "The title of the node." +msgstr "Il titolo del nodo." + +#: modules/node.views.inc:109 +msgid "The date the node was posted." +msgstr "La data in cui il nodo è stato inserito." + +#: modules/node.views.inc:125 +msgid "The date the node was last updated." +msgstr "La data in cui il nodo è stato aggiornato l'ultima volta." + +#: modules/node.views.inc:141 +msgid "The type of a node (for example, \"blog entry\", \"forum post\", \"story\", etc)." +msgstr "Il tipo di nodo (per esempio \"voce blog\", \"messaggio forum\", \"storia\", ecc)." + +#: modules/node.views.inc:160 +msgid "The published status of the node." +msgstr "Lo stato di pubblicazione del nodo." + +#: modules/node.views.inc:176 +msgid "Published or admin" +msgstr "Pubblicato o in amministrazione" + +#: modules/node.views.inc:177 +msgid "Filters out unpublished nodes if the current user cannot view them." +msgstr "Filtra i nodi nascosti se l'utente corrente non può vederli." + +#: modules/node.views.inc:188 +msgid "The front page of the node." +msgstr "La prima pagina del nodo." + +#: modules/node.views.inc:205 +msgid "Whether or not the node is moderated." +msgstr "Se il nodo è o no moderato." + +#: modules/node.views.inc:223 +msgid "Whether or not the node is sticky." +msgstr "Se il nodo debba essere fisso in cima." + +#: modules/node.views.inc:243 +msgid "Provide a simple link to the node." +msgstr "Fornire un link semplice al nodo." + +#: modules/node.views.inc:251 +msgid "Provide a simple link to edit the node." +msgstr "Fornire un link semplice per modificare il nodo." + +#: modules/node.views.inc:259 +msgid "Provide a simple link to delete the node." +msgstr "Fornire un link semplice per eliminare il nodo." + +#: modules/user.views.inc:123; +#: modules/node.views.inc:448,267 +msgid "Created date" +msgstr "Data di creazione" + +#: modules/node.views.inc:268 +msgid "In the form of CCYYMMDD." +msgstr "Nella forma di CCYYMMDD." + +#: modules/node.views.inc:276 +msgid "Created year + month" +msgstr "Creato anno + mese" + +#: modules/node.views.inc:277 +msgid "In the form of YYYYMM." +msgstr "Nella forma di YYYYMM." + +#: modules/node.views.inc:285 +msgid "Created year" +msgstr "Creato anno" + +#: modules/node.views.inc:286 +msgid "In the form of YYYY." +msgstr "Nella forma di YYYY." + +#: modules/node.views.inc:294 +msgid "Created month" +msgstr "Creato mese" + +#: modules/node.views.inc:295 +msgid "In the form of MM (01 - 12)." +msgstr "Nella forma di MM(01 - 12)" + +#: modules/node.views.inc:303 +msgid "Created day" +msgstr "Creato giorno" + +#: modules/node.views.inc:304 +msgid "In the form of DD (01 - 31)." +msgstr "Nella forma di DD(01 - 31)." + +#: modules/node.views.inc:312 +msgid "Created week" +msgstr "Creato settimana" + +#: modules/node.views.inc:313 +msgid "In the form of WW (01 - 53)." +msgstr "Nella forma di WW(01 - 53)." + +#: modules/node.views.inc:330,325 +msgid "Node revision" +msgstr "Revisione nodo" + +#: modules/node.views.inc:331 +msgid "Node revisions are a history of changes to nodes." +msgstr "Le revisioni del nodo sono una cronologia di modifiche ai nodi." + +#: modules/node.views.inc:346 +msgid "Relate a node revision to the user who created the revision." +msgstr "Collega la revisione di un nodo all'utente che ha creato la revisione." + +#: modules/node.views.inc:359 +msgid "The actual, full data in the body field; this may not be valid data on all node types." +msgstr "Gli effettivi dati completi nel campo corpo (o testo); ciò potrebbero non essere dei dati validi per tutti i tipi di nodo." + +#: modules/node.views.inc:374 +msgid "The stored teaser field. This may not be valid or useful data on all node types." +msgstr "Il campo anteprima memorizzato. Potrebbero non essere dei dati validi o utili per tutti i tipi di nodo." + +#: modules/node.views.inc:387 +msgid "Vid" +msgstr "Vid" + +#: modules/node.views.inc:388 +msgid "The revision ID of the node revision." +msgstr "L'ID revisione della revisione del nodo." + +#: modules/node.views.inc:435 +msgid "The log message entered when the revision was created." +msgstr "Il messaggio di log inserito quando la revisione è stata creata." + +#: modules/node.views.inc:449 +msgid "The date the node revision was created." +msgstr "Il data in cui la revisione del nodo è stata creata." + +#: modules/node.views.inc:464 +msgid "Revert link" +msgstr "Link Versione precedente" + +#: modules/node.views.inc:465 +msgid "Provide a simple link to revert to the revision." +msgstr "Fornisce un link semplice per tornare alla revisione." + +#: modules/node.views.inc:473 +msgid "Provide a simple link to delete the node revision." +msgstr "Fornisce un link semplice per eliminare la revisione del nodo." + +#: modules/node.views.inc:500 +msgid "Has new content" +msgstr "Ha nuovo contenuto" + +#: modules/node.views.inc:503 +msgid "Show a marker if the node has new or updated content." +msgstr "Mostra un segnale se il nodo ha un contenuto nuovo o aggiornato." + +#: modules/node.views.inc:506 +msgid "Show only nodes that have new content." +msgstr "Mostra solo i nodi che hanno del nuovo contenuto." + +#: modules/node.views.inc:646 +msgid "Node ID from URL" +msgstr "ID nodo dall'URL" + +#: modules/node.views.inc:708 +msgid "Display %display has no access control but does not contain a filter for published nodes." +msgstr "La visualizzazione %display non ha un controllo di accesso e non contiene filtri per i nodi pubblicati." + +#: modules/poll.views.inc:39 +msgid "Whether the poll is open for voting." +msgstr "Se il sondaggio è aperto alla votazione." + +#: modules/profile.views.inc:100 +msgid "@field-name" +msgstr "@field-name" + +#: modules/profile.views.inc:107 +msgid "Profile textfield" +msgstr "Campo di testo profilo" + +#: modules/profile.views.inc:126 +msgid "Profile textarea" +msgstr "Area di testo del profilo" + +#: modules/profile.views.inc:142 +msgid "Profile checkbox" +msgstr "Casella del profilo" + +#: modules/profile.views.inc:159 +msgid "Profile URL" +msgstr "URL del profilo" + +#: modules/profile.views.inc:175 +msgid "Profile selection" +msgstr "Selezione del profilo" + +#: modules/profile.views.inc:195 +msgid "Profile freeform list %field-name." +msgstr "Elenco libero %field-name del profilo." + +#: modules/profile.views.inc:207 +msgid "Profile date %field-name." +msgstr "Data del %field-name del profilo." + +#: modules/search.views.inc:73 +msgid "The score of the search item." +msgstr "Il punteggio della voce cerca." + +#: modules/search.views.inc:95 +msgid "Links from" +msgstr "Link da" + +#: modules/search.views.inc:96 +msgid "Nodes that link from the node." +msgstr "Nodi con link dal nodo." + +#: modules/search.views.inc:113 +msgid "Links to" +msgstr "Link a" + +#: modules/search.views.inc:114 +msgid "Nodes that link to the node." +msgstr "Nodi con link al nodo" + +#: modules/search.views.inc:125 +msgid "Search Terms" +msgstr "Termini per la ricerca" + +#: modules/search.views.inc:126 +msgid "The terms to search for." +msgstr "I termini da cercare." + +#: modules/search.views.inc:164 +msgid "Display the results with standard search view." +msgstr "Visualizza i risultati con una vista ricerca standard." + +#: modules/statistics.views.inc:24 +msgid "Node statistics" +msgstr "Statistiche nodo" + +#: modules/statistics.views.inc:36 +msgid "Total views" +msgstr "Visualizzazioni totali" + +#: modules/statistics.views.inc:37 +msgid "The total number of times the node has been viewed." +msgstr "Il numero totale di volte in cui il nodo è stato visualizzato." + +#: modules/statistics.views.inc:53 +msgid "Views today" +msgstr "Visualizzazioni oggi" + +#: modules/statistics.views.inc:54 +msgid "The total number of times the node has been viewed today." +msgstr "Il numero totale di volte in cui il nodo è stato visualizzato oggi." + +#: modules/statistics.views.inc:70 +msgid "Most recent view" +msgstr "Ultima visualizzazione" + +#: modules/statistics.views.inc:71 +msgid "The most recent time the node has been viewed." +msgstr "L'ultima volta che il nodo è stato visualizzato." + +#: modules/statistics.views.inc:91,86 +msgid "Access log" +msgstr "Registro degli accessi" + +#: modules/statistics.views.inc:92 +msgid "Stores site access information." +msgstr "Memorizza le informazioni sugli accessi al sito." + +#: modules/statistics.views.inc:106 +msgid "Session ID" +msgstr "ID sessione" + +#: modules/statistics.views.inc:202 +msgid "The user who visited the site." +msgstr "L'utente che ha visitato il sito." + +#: modules/statistics.views.inc:212 +msgid "Timer" +msgstr "Cronometro" + +#: modules/system.views.inc:31 +msgid "Files maintained by Drupal and various modules." +msgstr "File mantenuti da Drupal e da moduli vari." + +#: modules/system.views.inc:50 +msgid "The ID of the file." +msgstr "L'ID del file." + +#: modules/system.views.inc:70 +msgid "The name of the file." +msgstr "Il nome del file." + +#: modules/system.views.inc:89 +msgid "The path of the file." +msgstr "Il percorso del file." + +#: modules/system.views.inc:107 +msgid "Mime type" +msgstr "Tipo di mime" + +#: modules/system.views.inc:108 +msgid "The mime type of the file." +msgstr "Il tipo di mime del file." + +#: modules/system.views.inc:127 +msgid "The size of the file." +msgstr "La dimensione del file." + +#: modules/system.views.inc:143 +msgid "The status of the file." +msgstr "Lo stato del file." + +#: modules/system.views.inc:158 +msgid "Upload date" +msgstr "Data di caricamento" + +#: modules/system.views.inc:159 +msgid "The date the file was uploaded." +msgstr "La data in cui il file è stato caricato." + +#: modules/system.views.inc:204 +msgid "Temporary" +msgstr "Temporaneo" + +#: modules/system.views.inc:205 +msgid "Permanent" +msgstr "Permanente" + +#: modules/taxonomy.views.inc:50 +msgid "Name of the vocabulary a term is a member of. This will be the vocabulary that whichever term the \"Taxonomy: Term\" field is; and can similarly cause duplicates." +msgstr "Il nome del vocabolario di cui fa parte un termine. Questo sarà il vocabolario che conterrà qualsiasi termine del campo \"Tassonomia: Termine\"; allo stesso modo può creare duplicati." + +#: modules/taxonomy.views.inc:57 +msgid "The taxonomy vocabulary ID" +msgstr "L'ID del vocabolario della tassonomia" + +#: modules/taxonomy.views.inc:71 +msgid "Taxonomy terms are attached to nodes." +msgstr "I termini della tassonomia sono allegati ai nodi." + +#: modules/taxonomy.views.inc:197,97 +msgid "The taxonomy term ID" +msgstr "L'ID del termine della tassonomia" + +#: modules/taxonomy.views.inc:117 +msgid "Taxonomy terms. Note that using this can cause duplicate nodes to appear in views; you must add filters to reduce the result set." +msgstr "Termini della tassonomia. Notare che usandoli può dar luogo alla comparsa di nodi duplicati nelle viste; è necessario aggiungere dei filtri per ridurre i duplicati." + +#: modules/taxonomy.views.inc:127 +msgid "Taxonomy term name." +msgstr "Nome del termine della tassonomia." + +#: modules/taxonomy.views.inc:136 +msgid "The term weight field" +msgstr "Campo del peso del termine della tassonomia" + +#: modules/taxonomy.views.inc:149 +msgid "The description associated with a taxonomy term." +msgstr "La descrizione associata con un termine della tassonomia." + +#: modules/taxonomy.views.inc:161 +msgid "Filter the results of \"Taxonomy: Term\" to a particular vocabulary." +msgstr "Filtra i risultati di \"Tassonomia: Termine\" di un vocabolario particolare." + +#: modules/taxonomy.views.inc:199 +msgid "All terms" +msgstr "Tutti i termini" + +#: modules/taxonomy.views.inc:200 +msgid "Display all taxonomy terms associated with a node from specified vocabularies." +msgstr "Visualizzare tutti i termini della tassonomia associati con un nodo da vocabolari specifici." + +#: modules/taxonomy.views.inc:255 +msgid "The parent term of the term. This can produce duplicate entries if you are using a vocabulary that allows multiple parents." +msgstr "Il termine genitore del termine. Può produrre voci duplicate nel caso si stia usando un vocabolario che contente genitori multipli." + +#: modules/taxonomy.views.inc:287 +msgid "Term synonym" +msgstr "Sinonimo termine" + +#: modules/taxonomy.views.inc:288 +msgid "Term synonyms may be used to find terms by alternate names." +msgstr "I sinonimi dei termini possono essere usati per trovare i termini tramite nomi alternativi." + +#: modules/taxonomy.views.inc:304 +msgid "Term ID (with depth)" +msgstr "ID termine (con profondità)" + +#: modules/taxonomy.views.inc:305 +msgid "The depth filter is more complex, so provides fewer options." +msgstr "Il filtro profondità è più complesso, per cui fornisce meno opzioni." + +#: modules/taxonomy.views.inc:315 +msgid "Term ID depth modifier" +msgstr "Modificatore della profondità dell'ID termine" + +#: modules/taxonomy.views.inc:316 +msgid "Allows the \"depth\" for Taxonomy: Term ID (with depth) to be modified via an additional argument." +msgstr "Permette che la \"profondità\" della Tassonomia: ID termine (con profondità) sia modificata tramite un argomento aggiunto." + +#: modules/translation.views.inc:97,80,48,31 +msgid "Node translation" +msgstr "Traduzione nodo" + +#: modules/translation.views.inc:33 +msgid "The language the content is in." +msgstr "La lingua del contenuto." + +#: modules/translation.views.inc:49 +msgid "Translation set node ID" +msgstr "ID del gruppo di traduzione del nodo" + +#: modules/translation.views.inc:50 +msgid "The ID of the translation set the content belongs to." +msgstr "L'ID del gruppo di traduzione al quale appartiene il contenuto." + +#: modules/translation.views.inc:74,69 +msgid "Source translation" +msgstr "Sorgente della traduzione" + +#: modules/translation.views.inc:70 +msgid "The source that this content was translated from." +msgstr "La sorgente dalloa quale è stato tradotto questo contenuto." + +#: modules/translation.views.inc:85,82 +msgid "Versions of content in different languages." +msgstr "Versioni del contenuto in lingue differenti." + +#: modules/translation.views.inc:99 +msgid "The translation status of the node--whether or not the translation needs to be updated." +msgstr "Lo stato della traduzione del nodo - Se la traduzione deve essere tradotta o meno." + +#: modules/upload.views.inc:44 +msgid "The node the uploaded file is attached to" +msgstr "Il nodo a cui è allegato il file caricato" + +#: modules/upload.views.inc:57 +msgid "The description of the uploaded file." +msgstr "La descrizione del file allegato." + +#: modules/upload.views.inc:74 +msgid "Listed" +msgstr "Elencato" + +#: modules/upload.views.inc:75 +msgid "Whether or not the file is marked to be listed." +msgstr "Se il file deve essere elencato o meno." + +#: modules/upload.views.inc:91 +msgid "The weight, used for sorting." +msgstr "Il peso, usato nell'ordinamento." + +#: modules/upload.views.inc:114 +msgid "All files attached to a node with upload.module." +msgstr "Tutti i file allegati a un nodo con il modulo upload.module." + +#: modules/upload.views.inc:121; +#: modules/upload/views_handler_filter_upload_fid.inc:10 +msgid "Has attached files" +msgstr "Ha file allegati" + +#: modules/upload.views.inc:122 +msgid "Only display items with attached files. This can cause duplicates if there are multiple attached files." +msgstr "Visualizza solo le voci con file allegati. Questo può creare duplicati se ci sono file allegati multipli." + +#: modules/upload.views.inc:126 +msgid "Add a relationship to gain access to more file data for files uploaded by upload.module. Note that this relationship will cause duplicate nodes if there are multiple files attached to the node." +msgstr "Aggiungi una relazione per avere accesso a più file di dati caricati con il modulo upload.module. Notare che questa relazione creerà nodi duplicati se ci sono file multipli allegati al nodo." + +#: modules/user.views.inc:28 +msgid "Users who have created accounts on your site." +msgstr "Utenti che hanno creato un profilo nel sito." + +#: modules/user.views.inc:48 +msgid "Uid" +msgstr "Uid" + +#: modules/user.views.inc:49 +msgid "The user ID" +msgstr "L'ID dell'utente" + +#: modules/user.views.inc:70 +msgid "Current" +msgstr "Corrente" + +#: modules/user.views.inc:71 +msgid "Filter the view to the currently logged in user." +msgstr "Filtra la vista con l'utente attualmente autenticato." + +#: modules/user.views.inc:80 +msgid "The user or author name." +msgstr "Il nome dell'utente o dell'autore." + +#: modules/user.views.inc:97 +msgid "Email address for a given user. This field is not normally shown to users, so be cautious when using it." +msgstr "Indirizzo email di un dato utente. Questo campo normalmente non viene mostrato agli utenti, quindi usarlo con cautela." + +#: modules/user.views.inc:113 +msgid "The user's picture, if allowed." +msgstr "Il ritratto dell'utente, se consentito." + +#: modules/user.views.inc:124 +msgid "The date the user was created." +msgstr "Il data in cui è stato creato l'utente." + +#: modules/user.views.inc:140 +msgid "The user's last access date." +msgstr "La data dell'ultima accesso dell'utente." + +#: modules/user.views.inc:155 +msgid "Last login" +msgstr "Ultimo login" + +#: modules/user.views.inc:156 +msgid "The user's last login date." +msgstr "La data dell'ultimo login dell'utente." + +#: modules/user.views.inc:172 +msgid "Whether a user is active or blocked." +msgstr "Se un utente è attivo o bloccato." + +#: modules/user.views.inc:190 +msgid "The user's signature." +msgstr "La firma dell'utente." + +#: modules/user.views.inc:203 +msgid "Provide a simple link to edit the user." +msgstr "Fornisci un link semplice per modificare l'utente." + +#: modules/user.views.inc:211 +msgid "Provide a simple link to delete the user." +msgstr "Fornisci un link semplice per eliminare l'utente." + +#: modules/user.views.inc:241 +msgid "Roles that a user belongs to." +msgstr "I ruoli a cui l'utente appartiene." + +#: modules/user.views.inc:253 +msgid "No role" +msgstr "Nessun ruolo" + +#: modules/user.views.inc:296 +msgid "User ID from URL" +msgstr "ID utente dall'URL" + +#: modules/user.views.inc:302 +msgid "User ID from logged in user" +msgstr "ID Utente degli utenti autenticati" + +#: modules/views.views.inc:18 +msgid "Global" +msgstr "Globale" + +#: modules/views.views.inc:24 +msgid "Randomize the display order." +msgstr "Randomizzare l'ordine di visualizzazione." + +#: modules/views.views.inc:31 +msgid "Null" +msgstr "Null" + +#: modules/views.views.inc:32 +msgid "Allow an argument to be ignored. The query will not be altered by this argument." +msgstr "Consenti che l'argomento sia ignorato. La query non sarà alterata da questo argomento." + +#: modules/comment/views_handler_argument_comment_user_uid.inc:17 +msgid "No user" +msgstr "Nessun utente" + +#: modules/comment/views_handler_field_comment.inc:30 +msgid "Link this field to its comment" +msgstr "Collega questo campo al suo commento" + +#: modules/node/views_handler_field_node_link.inc:24; +#: modules/comment/views_handler_field_comment_link.inc:23; +#: modules/user/views_handler_field_user_link.inc:22 +msgid "Text to display" +msgstr "Testo da visualizzare" + +#: modules/comment/views_handler_field_comment_username.inc:25 +msgid "Link this field to its user or an author's homepage" +msgstr "Collega questo campo al suo utente o a una homepage dell'autore" + +#: modules/comment/views_handler_field_node_new_comments.inc:25 +msgid "Link this field to new comments" +msgstr "Collega questo campo ai nuovi commenti" + +#: modules/comment/views_handler_field_node_new_comments.inc:30 +msgid "Display nothing if no new comments" +msgstr "Non visualizzare nient'altro che i nuovi commenti" + +#: modules/node/views_handler_argument_dates_various.inc:167 +msgid "Week @week" +msgstr "Settimana @week" + +#: modules/translation/views_handler_argument_node_language.inc:29; +#: modules/node/views_handler_argument_node_language.inc:29 +msgid "Unknown language" +msgstr "Lingua sconosciuta" + +#: modules/node/views_handler_argument_node_type.inc:30 +msgid "Unknown node type" +msgstr "Tipo di nodo sconosciuto" + +#: modules/node/views_handler_field_history_user_timestamp.inc:32 +msgid "Check for new comments as well" +msgstr "Verifica anche per nuovi commenti" + +#: modules/translation/views_handler_filter_node_language.inc:10; +#: modules/node/views_handler_filter_node_language.inc:10 +msgid "Current user's language" +msgstr "Lingua corrente dell'utente" + +#: modules/translation/views_handler_filter_node_language.inc:10; +#: modules/node/views_handler_filter_node_language.inc:10 +msgid "No language" +msgstr "Nessuna lingua" + +#: modules/node/views_plugin_argument_validate_node.inc:32 +msgid "If you wish to validate for specific node types, check them; if none are checked, all nodes will pass." +msgstr "Se si desidera convalidare tipi di nodo specifici, selezionarli; se non ne viene selezionato alcuno, tutti i nodi passeranno." + +#: modules/node/views_plugin_argument_validate_node.inc:39 +msgid "Validate user has access to the node" +msgstr "L'utente convalidato ha accesso al nodo" + +#: modules/node/views_plugin_argument_validate_node.inc:50 +msgid "Node IDs separated by , or +" +msgstr "ID dei nodi separati da , o +" + +#: modules/node/views_plugin_row_node_rss.inc:27 +msgid "Title plus teaser" +msgstr "Titolo più anteprima" + +#: modules/node/views_plugin_row_node_rss.inc:29 +msgid "Use default RSS settings" +msgstr "Usa le impostazioni RSS predefinite" + +#: modules/node/views_plugin_row_node_view.inc:27 +msgid "Display only teaser" +msgstr "Visualizza solo l'anteprima" + +#: modules/node/views_plugin_row_node_view.inc:37 +msgid "Display node comments" +msgstr "Visualizza i commenti del nodo" + +#: modules/search/views_handler_filter_search.inc:23 +msgid "On empty input" +msgstr "Su inserimento vuoto" + +#: modules/search/views_handler_filter_search.inc:26 +msgid "Show All" +msgstr "Mostra tutto" + +#: modules/search/views_handler_filter_search.inc:27 +msgid "Show None" +msgstr "Non mostrare nulla" + +#: modules/search/views_plugin_row_search_view.inc:23 +msgid "Display score" +msgstr "Mostra punteggio" + +#: modules/system/views_handler_field_file.inc:29; +#: modules/upload/views_handler_field_upload_description.inc:24; +#: modules/upload/views_handler_field_upload_fid.inc:21 +msgid "Link this field to download the file" +msgstr "Collega questo campo per download il file" + +#: modules/taxonomy/views_handler_argument_term_node_tid.inc:17; +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:38 +msgid "Set the breadcrumb for the term parents" +msgstr "Imposta il breadcrumb dei termini genitori" + +#: modules/taxonomy/views_handler_argument_term_node_tid.inc:18; +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:39 +msgid "If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received." +msgstr "Se selezionato, il breadcrumb includerà i termini genitori, ognuno collegato alla propria vista. Nota che questo funziona solo se è stato ricevuto solo un termine." + +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:26 +msgid "The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term \"fruit\" and a child term \"apple\", with a depth of 1 (or higher) then filtering for the term \"fruit\" will get nodes that are tagged with \"apple\" as well as \"fruit\". If negative, the reverse is true; searching for \"apple\" will also pick up nodes tagged with \"fruit\" if depth is -1 (or lower)." +msgstr "La profondità combacerà con i nodi etichettati con i termini nella gerarchia. Per esempio, se si ha il termine \"frutta\" e un termine figlio \"mela\", con una profondità di 1 (o maggiore) allora il filtraggio del termine \"frutta\" otterrà i nodi etichettati con \"mela\" come pure quelli etichettati con \"frutta\". Se negativo, è vero il contrario; se la profondità è -1 (o inferiore) cercando \"mela\" si troveranno anche i nodi etichettati con \"frutta\"." + +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:31 +msgid "Allow multiple terms per argument" +msgstr "Consenti termini multipli per argomento" + +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:32 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3. Due to the number of JOINs it would require, AND will be treated as OR with this argument." +msgstr "Se selezionato, gli utenti possono inserire argomenti multipli nel formato 1+2+3. A causa del numero di JOIN che ciò richiede, con questo argomento AND verrà trattato come OR." + +#: modules/taxonomy/views_handler_argument_vocabulary_vid.inc:15 +msgid "No vocabulary" +msgstr "Nessun vocabolario" + +#: modules/taxonomy/views_handler_field_taxonomy.inc:33 +msgid "Link this field to its taxonomy term page" +msgstr "Collega questo campo alla pagina del suo termine tassonomico" + +#: modules/taxonomy/views_handler_field_term_node_tid.inc:34 +msgid "Link this field to its term page" +msgstr "Collega questo termine alla pagina del suo termine" + +#: modules/taxonomy/views_handler_field_term_node_tid.inc:41 +msgid "Limit terms by vocabulary" +msgstr "Limita i termini nel vocabolario" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:39 +msgid "Select which vocabulary to show terms for in the regular options." +msgstr "Selezionare per quale vocabolario mostrare i termini nelle opzioni regolari." + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:49 +msgid "Selection type" +msgstr "Tipo di selezione" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:50 +msgid "Dropdown" +msgstr "Menu a discesa" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:50 +msgid "Autocomplete" +msgstr "Autocompletamento" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:56 +msgid "Show hierarchy in dropdown" +msgstr "Mostra la gerarchia nel menu a discesa" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:73 +msgid "An invalid vocabulary is selected. Please change it in the options." +msgstr "È stato selezionato un vocabolario non valido. Si prega di modificarlo nelle opzioni." + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:147,91 +msgid "Select terms from vocabulary @voc" +msgstr "Selezionare i termini dal vocabolario @voc" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:255 +msgid "Unable to find term: @terms" +msgid_plural "Unable to find terms: @terms" +msgstr[0] "Impossibile trovare il termine: @terms" +msgstr[1] "Impossibile trovare i termini: @terms" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:26 +msgid "If you wish to validate for specific vocabularies, check them; if none are checked, all terms will pass." +msgstr "Se si desidera validare vocabolari specifici, selezionarli; se nessuno viene selezionato, tutti i termini passeranno." + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:36 +msgid "Term IDs separated by , or +" +msgstr "ID dei termini separati da , o +" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:37 +msgid "Term name or synonym" +msgstr "Nome del termine o sinonimo" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:38 +msgid "Term name/synonym converted to Term ID" +msgstr "Nome/sinonimo del termine convertito in ID del termine" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:41 +msgid "Select the form of this argument; if using term name, it is generally more efficient to convert it to a term ID and use Taxonomy: Term ID rather than Taxonomy: Term Name\" as an argument." +msgstr "Selezionare la forma di questo argomento; se si usa il nome del termine, in genere è più efficace convertirlo in ID del termine e usare come argomento \"Tassonomia: ID del Termine\" anziché \"Tassonomia: Nome del Termine\"." + +#: modules/translation/views_handler_filter_node_language.inc:10 +msgid "Default site language" +msgstr "Lingua predefinita del sito" + +#: modules/translation/views_handler_relationship_translation.inc:24 +msgid "Current language" +msgstr "Lingua attuale" + +#: modules/translation/views_handler_relationship_translation.inc:25 +msgid "Default language" +msgstr "Lingua predefinita" + +#: modules/translation/views_handler_relationship_translation.inc:32 +msgid "Translation option" +msgstr "Opzioni di traduzione" + +#: modules/translation/views_handler_relationship_translation.inc:33 +msgid "The translation options allows you to select which translation or translations in a translation set join on. Select \"Current language\" or \"Default language\" to join on the translation in the current or default language respectively. Select a specific language to join on a translation in that language. If you select \"All\", each translation will create a new row, which may appear to cause duplicates." +msgstr "Le opzioni di traduzione consentono di selezionare a quale traduzione o traduzioni unirsi in un gruppo di traduzione. Selezionare \"Lingua attuale\" per unirsi alla traduzione nella lingua attuale oppure o \"Lingua predefinita\" per unirsi alla lingua predefinita. Selezionare una lingua specifica per unirsi alla traduzione in quella lingua. Se si seleziona \"Tutte\", ogni traduzione creerà una nuova riga, che può sembrare essere la causa di duplicati." + +#: modules/upload/views_handler_field_upload_fid.inc:27 +msgid "Only show \"listed\" file attachments" +msgstr "Mostra solo i file allegati \"elencati\"" + +#: modules/user/views_handler_field_user.inc:30 +msgid "Link this field to its user" +msgstr "Collega questo campo al suo utente" + +#: modules/user/views_handler_field_user_mail.inc:16 +msgid "Link this field" +msgstr "Collega questo campo" + +#: modules/user/views_handler_field_user_mail.inc:20 +msgid "To the user" +msgstr "All'utente" + +#: modules/user/views_handler_field_user_mail.inc:21 +msgid "With a mailto:" +msgstr "Con un mailto:" + +#: modules/user/views_handler_filter_user_current.inc:10 +msgid "Is the logged in user" +msgstr "È l'utente autenticato" + +#: modules/user/views_handler_filter_user_name.inc:28 +msgid "Usernames" +msgstr "Nomi utente" + +#: modules/user/views_handler_filter_user_name.inc:29 +msgid "Enter a comma separated list of user names." +msgstr "Inserire un elenco di nome utente separati da una virgola." + +#: modules/user/views_handler_filter_user_name.inc:112 +msgid "Unable to find user: @users" +msgid_plural "Unable to find users: @users" +msgstr[0] "Impossibile trovare l'utente: @users" +msgstr[1] "Impossibile trovare gli utenti: @users" + +#: modules/user/views_plugin_argument_default_user.inc:17 +msgid "Also look for a node and use the node author" +msgstr "Cercare anche un nodo e usare l'autore del nodo" + +#: plugins/views_plugin_access_none.inc:9 +msgid "Unrestricted" +msgstr "Senza restrizioni" + +#: plugins/views_plugin_access_perm.inc:37 +msgid "Only users with the selected permission flag will be able to access this display. Note that users with \"access all views\" can see any view, regardless of other permissions." +msgstr "Solo gli utenti con l'indicatore del permesso selezionato potranno accedere a questa visualizzazione. Notare che gli utenti con il permesso \"accesso a tutte le viste\" possono vedere qualsiasi vista, indipendentemente dagli altri permessi." + +#: plugins/views_plugin_access_role.inc:21 +msgid "No role(s) selected" +msgstr "Nessun ruolo selezionato" + +#: plugins/views_plugin_access_role.inc:24 +msgid "Multiple roles" +msgstr "Ruoli multipli" + +#: plugins/views_plugin_access_role.inc:43 +msgid "Only the checked roles will be able to access this display. Note that users with \"access all views\" can see any view, regardless of role." +msgstr "Solo i ruoli selezionati potranno accedere a questa visualizzazione. Notare che gli utenti con il permesso \"accesso a tutte le viste\" possono vedere qualsiasi vista, a dispetto del ruolo." + +#: plugins/views_plugin_access_role.inc:49 +msgid "You must select at least one role if type is \"by role\"" +msgstr "Se il tipo è \"per ruolo\", bisogna selezionare almeno un ruolo" + +#: plugins/views_plugin_argument_default.inc:32 +msgid "Default argument" +msgstr "Argomento predefinito" + +#: plugins/views_plugin_argument_default.inc:54 +msgid "Note: you do not have permission to modify this. If you change the default argument type, this setting will be lost and you will NOT be able to get it back." +msgstr "Nota: non hai il permesso per modificarlo. Se modifichi il tipo di argomento predefinito, questa impostazione andrà persa e NON potrai tornare indietro." + +#: plugins/views_plugin_argument_default_php.inc:17 +msgid "PHP argument code" +msgstr "Codice PHP dell'argomento" + +#: plugins/views_plugin_argument_default_php.inc:20 +msgid "Enter PHP code that returns a value to use for this argument. Do not use <?php ?>. You must return only a single value for just this argument." +msgstr "Inserire il codice PHP che restituisce un valore da usare per questo argomento" + +#: plugins/views_plugin_argument_validate.inc:43 +msgid "Note: you do not have permission to modify this. If you change the validator, this setting will be lost and you will NOT be able to get it back." +msgstr "Nota: non hai il permesso per modificarlo. Se modifichi il validatore, questa impostazione andrà persa e NON potrai tornare indietro." + +#: plugins/views_plugin_argument_validate_php.inc:19 +msgid "PHP validate code" +msgstr "Codice PHP di validazione" + +#: plugins/views_plugin_argument_validate_php.inc:21 +msgid "Enter PHP code that returns TRUE or FALSE. No return is the same as FALSE, so be SURE to return something if you do not want to declare the argument invalid. Do not use <?php ?>. The argument to validate will be \"$argument\" and the view will be \"$view\". You may change the argument by setting \"$handler->argument\"." +msgstr "Inserire il codice PHP che restituisce TRUE o FALSE. Nessuna restituzione corrisponde a FALSE, per cui assicurarsi che qualcosa venga restituito se non si vuole dichiarare invalido l'argomento. Non usare <?php ?>. L'argomento da validre sarà \"$argument\" e la vista sarà \"$view\". Si può modificare l'argomento impostando \"$handler->argument\"." + +#: plugins/views_plugin_display.inc:558 +msgid "Broken field" +msgstr "Campo guasto" + +#: plugins/views_plugin_display.inc:582 +msgid "Change the name of this display." +msgstr "Cambia il nome di questa vista." + +#: plugins/views_plugin_display.inc:594 +msgid "Change the title that this display will use." +msgstr "Cambia il titolo che questa vista userà." + +#: plugins/views_plugin_display.inc:606 +msgid "Change the style plugin." +msgstr "Cambia il plugin stile." + +#: plugins/views_plugin_display.inc:620 +msgid "Row style" +msgstr "Stile riga" + +#: plugins/views_plugin_display.inc:622 +msgid "Change the row plugin." +msgstr "Cambia il plugin riga." + +#: plugins/views_plugin_display.inc:632 +msgid "Use AJAX" +msgstr "Usa AJAX" + +#: plugins/views_plugin_display.inc:634 +msgid "Change whether or not this display will use AJAX." +msgstr "Modifica se questa visualizzazione userà o meno AJAX." + +#: plugins/views_plugin_display.inc:642 +msgid "Mini" +msgstr "Mini" + +#: plugins/views_plugin_display.inc:643 +msgid "Change this display's pager setting." +msgstr "Modifica le impostazioni del paginatore di questa visualizzazione." + +#: plugins/views_plugin_display.inc:822,650 +msgid "Items per page" +msgstr "Voci per pagina" + +#: plugins/views_plugin_display.inc:822,650; +#: plugins/views_plugin_style_summary.inc:43 +msgid "Items to display" +msgstr "Voci da visualizzare" + +#: plugins/views_plugin_display.inc:652 +msgid "Change how many items to display." +msgstr "Modifica quante voci visualizzare." + +#: plugins/views_plugin_display.inc:658 +msgid "More link" +msgstr "Link altro" + +#: plugins/views_plugin_display.inc:660 +msgid "Specify whether this display will provide a \"more\" link." +msgstr "Specificare se questa visualizzazione deve fornire un link \"altro\"." + +#: plugins/views_plugin_display.inc:849,666 +msgid "Distinct" +msgstr "Distinta" + +#: plugins/views_plugin_display.inc:846,668 +msgid "Display only distinct items, without duplicates." +msgstr "Visualizza solo voci distinte, senza duplicati." + +#: plugins/views_plugin_display.inc:683 +msgid "Specify access control type for this display." +msgstr "Specifica il tipo di controllo di accesso per questa visualizzazione." + +#: plugins/views_plugin_display.inc:687 +msgid "Change settings for this access type." +msgstr "Modifica le impostazioni per questo tipo di accesso." + +#: plugins/views_plugin_display.inc:707 +msgid "Link display" +msgstr "Collega visualizzazione" + +#: plugins/views_plugin_display.inc:709 +msgid "Specify which display this display will link to." +msgstr "Specifica a quale visualizzazione questa visualizzazione sarà collegata." + +#: plugins/views_plugin_display.inc:716 +msgid "Exposed form in block" +msgstr "Form esposto nel blocco" + +#: plugins/views_plugin_display.inc:718 +msgid "Allow the exposed form to appear in a block instead of the view." +msgstr "Consente al form esposto di apparire in un blocco anziché nella vista." + +#: plugins/views_plugin_display.inc:737 +msgid "Unknown/missing format" +msgstr "Formato sconosciuto/mancante" + +#: plugins/views_plugin_display.inc:745 +msgid "Change this display's !name." +msgstr "Cambiare !name di questa visualizzazione." + +#: plugins/views_plugin_display.inc:753 +msgid "Get information on how to theme this display" +msgstr "Informazioni su come temizzare questa visualizzazione" + +#: plugins/views_plugin_display.inc:779 +msgid "The name of this display" +msgstr "Il nome di questa visualizzazione" + +#: plugins/views_plugin_display.inc:782 +msgid "This title will appear only in the administrative interface for the View." +msgstr "Questo titolo comparirà nell'interfaccia di amministrazione di Viste." + +#: plugins/views_plugin_display.inc:787 +msgid "The title of this view" +msgstr "Il titolo di questa vista" + +#: plugins/views_plugin_display.inc:790 +msgid "This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc." +msgstr "Questo titolo sarà visualizzato con la vista, dovunque vengono visualizzati normalmente i titoli; cioè, come il titolo della pagina, titolo del blocco, ecc." + +#: plugins/views_plugin_display.inc:795 +msgid "Use AJAX when available to load this view" +msgstr "Quando disponibile, usare AJAX per caricare questa vista" + +#: plugins/views_plugin_display.inc:799 +msgid "If set, this view will use an AJAX mechanism for paging, table sorting and exposed filters. This means the entire page will not refresh. It is not recommended that you use this if this view is the main content of the page as it will prevent deep linking to specific pages, but it is very useful for side content." +msgstr "Se impostato, questa vista userà un meccanismo AJAX per la paginazione, l'ordinamento della tabella e i filtri esposti. Ciò significa che la pagina intera non si aggiornerà. Non ne è raccomandato l'uso se questa vista è il contenuto principale della pagina poiché impedirà il collegamento diretto (deep linking) a pagine specifiche, ma è molto utile per i contenuti laterali." + +#: plugins/views_plugin_display.inc:808 +msgid "Use a pager for this view" +msgstr "Usa un paginatore per questa vista" + +#: plugins/views_plugin_display.inc:811 +msgid "Full pager" +msgstr "Paginatore completo" + +#: plugins/views_plugin_display.inc:811 +msgid "Mini pager" +msgstr "Mini paginatore" + +#: plugins/views_plugin_display.inc:816 +msgid "Pager element" +msgstr "Elemento paginatore" + +#: plugins/views_plugin_display.inc:817 +msgid "Unless you're experiencing problems with pagers related to this view, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible." +msgstr "A meno che non si stia sperimentando problemi con i paginatori collegati a questa vista, si dovrebbe lasciarlo a 0. Se si stanno usando dei multi-paginatori su una pagina potrebbe essere necessario impostare questo numero a un valore maggiore in modo che non vada in conflitto con ?page= array. I valori ampi aggiungeranno molte virgole agli URL, per cui evitarli se possibile." + +#: plugins/views_plugin_display.inc:826 +msgid "The number of items to display per page. Enter 0 for no limit." +msgstr "Il numero di voci da mostrare per pagina. Inserire 0 per nessun limite." + +#: plugins/views_plugin_display.inc:832 +msgid "The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed. Offset can not be used if items to display is 0; instead use a very large number there." +msgstr "Il numero di voci da saltare. Per esempio, se questo campo è 3, le prime 3 voci verranno saltate e non mostrate. Lo slittamento (<a href=\"http://it.wikipedia.org/wiki/Offset\">offset</a>) non può essere usato se le voci da mostrare sono 0; in questo caso usare invece un numero molto grande." + +#: plugins/views_plugin_display.inc:837 +msgid "Add a more link to the bottom of the display." +msgstr "Aggiungere un link altro in fondo alla visualizzazione." + +#: plugins/views_plugin_display.inc:840 +msgid "Create more link" +msgstr "Crea un link altro" + +#: plugins/views_plugin_display.inc:841 +msgid "This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' above." +msgstr "Aggiungerà un link altro in fondo a questa vista, che si collegherà alla vista pagina. Se ci sono più di una vista pagina, il link punterà alla visualizzazione specificata in 'Link display' sopra" + +#: plugins/views_plugin_display.inc:850 +msgid "This will make the view display only distinct items. If there are multiple identical items, each will be displayed only once. You can use this to try and remove duplicates from a view, though it does not always work. Note that this can slow queries down, so use it with caution." +msgstr "Questo farà sì che la vista visualizzi solo voci distinte. Se ci sono voci multiple identiche, ognuna verrà visualizzata solo una volta. Si può usare questo per cercare e rimuovere i duplicati da una vista, sebbene non sempre funzioni. Notare che questo può rallentare le query, quindi usarlo con cautela." + +#: plugins/views_plugin_display.inc:855 +msgid "Access restrictions" +msgstr "Restrizioni accesso" + +#: plugins/views_plugin_display.inc:954,874 +msgid "You may also adjust the !settings for the currently selected style by clicking on the icon." +msgstr "È anche possibile regolare le !settings dello stile attualmente selezionato cliccando sull'icona." + +#: plugins/views_plugin_display.inc:882 +msgid "Access options" +msgstr "Opzioni accesso" + +#: plugins/views_plugin_display.inc:916,900 +msgid "Display even if view has no result" +msgstr "Visualizza anche se la vista non da risultati" + +#: plugins/views_plugin_display.inc:923 +msgid "Text to display beneath the view. May contain an explanation or links or whatever you like. Optional." +msgstr "Testo da visualizzare sotto la vista. Può contenere una spiegazione o dei link o qualsiasi cosa si desidera. Opzionale." + +#: plugins/views_plugin_display.inc:934 +msgid "Text to display if the view has no results. Optional." +msgstr "Testo da visualizzare se la vista non ha risultati. Opzionale." + +#: plugins/views_plugin_display.inc:940 +msgid "How should this view be styled" +msgstr "Come deve essere stilizzata questa vista" + +#: plugins/views_plugin_display.inc:946 +msgid "If the style you choose has settings, be sure to click the settings button that will appear next to it in the View summary." +msgstr "Se lo stile scelto ha delle impostazioni, assicurarsi di selezionare il pulsante impostazioni che comparirà vicino ad esso nel sommario Vista." + +#: plugins/views_plugin_display.inc:960 +msgid "Style options" +msgstr "Opzioni stile" + +#: plugins/views_plugin_display.inc:971 +msgid "Row style options" +msgstr "Opzioni stile riga" + +#: plugins/views_plugin_display.inc:986 +msgid "How should each row in this view be styled" +msgstr "Come deve essere stilizzata ogni riga di questa vista" + +#: plugins/views_plugin_display.inc:999 +msgid "You may also adjust the !settings for the currently selected row style by clicking on the icon." +msgstr "Si possono anche regolare le !settings della riga correntemente selezionata cliccando sull'icona." + +#: plugins/views_plugin_display.inc:1005 +msgid "Which display to use for path" +msgstr "Quale visualizzazione usare per il percorso" + +#: plugins/views_plugin_display.inc:1014 +msgid "Which display to use to get this display's path for things like summary links, rss feed links, more links, etc." +msgstr "Quale visualizzazione usare per avere il percorso di questa visualizzazione in cose come link del sommario, link dei feed rss, link altro, ecc." + +#: plugins/views_plugin_display.inc:1019 +msgid "Theming information" +msgstr "Informazioni sul tema" + +#: plugins/views_plugin_display.inc:1027 +msgid "Display output" +msgstr "Output della visualizzazione" + +#: plugins/views_plugin_display.inc:1031 +msgid "Alternative display output" +msgstr "Output alternativo della visualizzazione" + +#: plugins/views_plugin_display.inc:1038 +msgid "Style output" +msgstr "Output dello stile" + +#: plugins/views_plugin_display.inc:1042 +msgid "Alternative style" +msgstr "Output alternativo dello stile" + +#: plugins/views_plugin_display.inc:1049 +msgid "Row style output" +msgstr "Output dello stile di riga" + +#: plugins/views_plugin_display.inc:1053 +msgid "Alternative row style" +msgstr "Output alternativo dello stile di riga" + +#: plugins/views_plugin_display.inc:1061 +msgid "Field @field (ID: @id)" +msgstr "Campo @field (ID: @id)" + +#: plugins/views_plugin_display.inc:1069 +msgid "This section lists all possible templates for the display plugin and for the style plugins, ordered roughly from the least specific to the most specific. The active template for each plugin -- which is the most specific template found on the system -- is highlighted in bold." +msgstr "Questa sezione elenca tutti i possibili modelli per il plugin visualizzazione e per i plugin stile, ordinati grosso modo dal meno specifico al più specifico. Il modello attivo per ciascun plugin -- che è il modello più specifico trovato nel sistema -- è evidenziato in grassetto." + +#: plugins/views_plugin_display.inc:1084 +msgid "Rescan template files" +msgstr "Rianalizza i file modello" + +#: plugins/views_plugin_display.inc:1090 +msgid "<strong>Important!</strong> When adding, removing, or renaming template files, it is necessary to make Drupal aware of the changes by making it rescan the files on your system. By clicking this button you clear Drupal's theme registry and thereby trigger this rescanning process. The highlighted templates above will then reflect the new state of your system." +msgstr "<strong>Importante!</strong> Quando si aggiungono, rimuovono o rinominano i file modello, è necessario rendere Drupal consapevole delle modifiche facendogli rianalizzare i file del sistema. Cliccando questo pulsante si azzera il registro del tema di Drupal avviando perciò il processo di rianalisi. I modelli evidenziati sopra rifletteranno quindi il nuovo stato del sistema." + +#: plugins/views_plugin_display.inc:1096 +msgid "Theming information (display)" +msgstr "Informazioni sulla temizzazione (visualizzazione)" + +#: plugins/views_plugin_display.inc:1182,1153,1124,1097 +msgid "Back to !info." +msgstr "Torna a !info." + +#: plugins/views_plugin_display.inc:1182,1153,1124,1097 +msgid "theming information" +msgstr "informazioni sulla temizzazione" + +#: plugins/views_plugin_display.inc:1100 +msgid "This display has no theming information" +msgstr "La visualizzazione non ha informazioni sulla temizzazione" + +#: plugins/views_plugin_display.inc:1103 +msgid "This is the default theme template used for this display." +msgstr "Questo è il modello di tema predefinito usato per questa visualizzazione." + +#: plugins/views_plugin_display.inc:1109 +msgid "This is an alternative template for this display." +msgstr "Questo è un modello alternativo per questa visualizzazione." + +#: plugins/views_plugin_display.inc:1123 +msgid "Theming information (style)" +msgstr "Informazioni temizzazione (stile)" + +#: plugins/views_plugin_display.inc:1129 +msgid "This display has no style theming information" +msgstr "Questa visualizzazione non ha informazioni sulla temizzazione dello stile" + +#: plugins/views_plugin_display.inc:1132 +msgid "This is the default theme template used for this style." +msgstr "Questo è il modello di tema predefinito usato per questo stile." + +#: plugins/views_plugin_display.inc:1138 +msgid "This is an alternative template for this style." +msgstr "Questo è un modello alternativo per questo stile." + +#: plugins/views_plugin_display.inc:1181,1152 +msgid "Theming information (row style)" +msgstr "Informazioni temizzazione (stile riga)" + +#: plugins/views_plugin_display.inc:1158 +msgid "This display has no row style theming information" +msgstr "Questa visualizzazione non ha informazioni sulla temizzazione dello stile riga" + +#: plugins/views_plugin_display.inc:1184,1161 +msgid "This is the default theme template used for this row style." +msgstr "Questo è il modello del tema predefinito usato per questo stile riga." + +#: plugins/views_plugin_display.inc:1167 +msgid "This is an alternative template for this row style." +msgstr "Questo è un modello alternativo per questo stile riga." + +#: plugins/views_plugin_display.inc:1199 +msgid "Put the exposed form in a block" +msgstr "Metti il form esposto in un blocco" + +#: plugins/views_plugin_display.inc:1203 +msgid "If set, any exposed widgets will not appear with this view. Instead, a block will be made available to the Drupal block administration system, and the exposed form will appear there. Note that this block must be enabled manually, Views will not enable it for you." +msgstr "Se impostato, qualsiasi widget esposto non apparirà in questa vista. Sarà invece reso disponibile un blocco nel sistema di amministrazione blocchi di Drupal e il form esposto comparirà lì. Notare che questo blocco deve essere attivato manualmente, Viste non lo attiverà in automatico." + +#: plugins/views_plugin_display.inc:1238 +msgid "File found in folder @template-path" +msgstr "(File trovato nella cartella @template-path)" + +#: plugins/views_plugin_display.inc:1242 +msgid "(File not found, in folder @template-path)" +msgstr "(File non trovato nella cartella @template-path)" + +#: plugins/views_plugin_display.inc:1404 +msgid "Status: using default values." +msgstr "Stato: utilizzazione valori predefiniti." + +#: plugins/views_plugin_display.inc:1408 +msgid "Update default display" +msgstr "Aggiorna visualizzazione predefinita" + +#: plugins/views_plugin_display.inc:1413 +msgid "Use default" +msgstr "Usa predefinito" + +#: plugins/views_plugin_display.inc:1418 +msgid "Status: using overridden values." +msgstr "Stato: utilizzo di valori modificati." + +#: plugins/views_plugin_display.inc:1633 +msgid "Display @display uses fields but there are none defined for it or all are excluded." +msgstr "La visualizzazione @display usa dei campi ma non ci sono campi definiti per essa oppure sono tutti esclusi." + +#: plugins/views_plugin_display.inc:1638 +msgid "Display @display uses path but path is undefined." +msgstr "La visualizzazione @display usa il percorso ma il percorso non è definito." + +#: plugins/views_plugin_display.inc:1643 +msgid "Display @display has an invalid style plugin." +msgstr "La visualizzazione @display ha un plugin stile non valido." + +#: plugins/views_plugin_display.inc:1659 +msgid "Exposed form: @view-@display_id" +msgstr "Form esposto: @view-@display_id" + +#: plugins/views_plugin_display_attachment.inc:35 +msgid "Before" +msgstr "Prima" + +#: plugins/views_plugin_display_attachment.inc:36 +msgid "After" +msgstr "Dopo" + +#: plugins/views_plugin_display_attachment.inc:57 +msgid "Attachment settings" +msgstr "Impostazioni allegati" + +#: plugins/views_plugin_display_attachment.inc:109,62 +msgid "Inherit arguments" +msgstr "Eredita argomenti" + +#: plugins/views_plugin_display_attachment.inc:118,68 +msgid "Inherit exposed filters" +msgstr "Eredita filtri esposti" + +#: plugins/views_plugin_display_attachment.inc:127,74 +msgid "Position" +msgstr "Posizione" + +#: plugins/views_plugin_display_attachment.inc:80; +#: plugins/views_plugin_display_feed.inc:98 +msgid "Multiple displays" +msgstr "Visualizzazioni multiple" + +#: plugins/views_plugin_display_attachment.inc:136,95; +#: plugins/views_plugin_display_feed.inc:140,113 +msgid "Attach to" +msgstr "Allega a" + +#: plugins/views_plugin_display_attachment.inc:121,112 +msgid "Inherit" +msgstr "Eredita" + +#: plugins/views_plugin_display_attachment.inc:113 +msgid "Should this display inherit its arguments from the parent display to which it is attached?" +msgstr "Questa visualizzazione deve ereditare i propri argomenti dalla visualizzazione genitore a cui è allegata?" + +#: plugins/views_plugin_display_attachment.inc:122 +msgid "Should this display inherit its exposed filter values from the parent display to which it is attached?" +msgstr "Questa visualizzazione deve ereditare i valori dei filtri esposti nella visualizzazione genitore a cui è allegata?" + +#: plugins/views_plugin_display_attachment.inc:130 +msgid "Attach before or after the parent display?" +msgstr "Allegare prima o dopo la visualizzazione genitore?" + +#: plugins/views_plugin_display_attachment.inc:145 +msgid "Select which display or displays this should attach to." +msgstr "Selezionare la visualizzazione / le visualizzazioni a cui questa deve essere allegata." + +#: plugins/views_plugin_display_block.inc:106 +msgid "Do not cache" +msgstr "Non mettere i cache" + +#: plugins/views_plugin_display_block.inc:107 +msgid "Cache once for everything (global)" +msgstr "Metti in cache una volta per tutto (globale)" + +#: plugins/views_plugin_display_block.inc:108 +msgid "Per page" +msgstr "Per pagina" + +#: plugins/views_plugin_display_block.inc:109 +msgid "Per role" +msgstr "Per ruolo" + +#: plugins/views_plugin_display_block.inc:110 +msgid "Per role per page" +msgstr "Per ruolo per pagina" + +#: plugins/views_plugin_display_block.inc:111 +msgid "Per user" +msgstr "Per utente" + +#: plugins/views_plugin_display_block.inc:112 +msgid "Per user per page" +msgstr "Per utente per pagina" + +#: plugins/views_plugin_display_block.inc:137 +msgid "Block admin description" +msgstr "Descrizione amministrazione blocco" + +#: plugins/views_plugin_display_block.inc:140 +msgid "This will appear as the name of this block in administer >> site building >> blocks." +msgstr "Verrà mostrato come nome di questo blocco in amministrazione >> struttura del sito >> blocchi." + +#: plugins/views_plugin_display_block.inc:145 +msgid "Block caching type" +msgstr "Tipo di cache del blocco" + +#: plugins/views_plugin_display_block.inc:149 +msgid "This sets the default status for Drupal's built-in block caching method; this requires that caching be turned on in block administration, and be careful because you have little control over when this cache is flushed." +msgstr "Questo imposta lo stato predefinito del metodo integrato di caching del blocco in Drupal; richiede che il caching sia attivato in amministrazione blocchi. Prestare attenzione poiché si ha poco controllo quando questa cache viene svuotata." + +#: plugins/views_plugin_display_feed.inc:86 +msgid "Feed settings" +msgstr "Impostazioni feed" + +#: plugins/views_plugin_display_feed.inc:90 +msgid "Using the site name" +msgstr "Usa il nome del sito" + +#: plugins/views_plugin_display_feed.inc:132 +msgid "Use the site name for the title" +msgstr "Per il titolo usa il nome del sito" + +#: plugins/views_plugin_display_feed.inc:149 +msgid "The feed icon will be available only to the selected displays." +msgstr "L'icona feed sarà disponibile solo nella visualizzazione selezionata." + +#: plugins/views_plugin_display_feed.inc:155 +msgid "This view will be displayed by visiting this path on your site. It is recommended that the path be something like \"path/%/%/feed\" or \"path/%/%/rss.xml\", putting one % in the path for each argument you have defined in the view." +msgstr "Questa vista sarà visualizzata visitando questo percorso sul sito. Si raccomanda che il percorso sia qualcosa del tipo \"percorso/%/%/feed\" oppure \"percorso/%/%/rss.xml\", mettendo un % nel percorso per ogni argomento definito nella vista." + +#: plugins/views_plugin_display_page.inc:213 +msgid "No menu" +msgstr "Nessun menu" + +#: plugins/views_plugin_display_page.inc:216 +msgid "Normal: @title" +msgstr "Normale: @title" + +#: plugins/views_plugin_display_page.inc:220 +msgid "Tab: @title" +msgstr "Scheda: @title" + +#: plugins/views_plugin_display_page.inc:236 +msgid "Change settings for the parent menu" +msgstr "Impostazioni cache per il menu genitore" + +#: plugins/views_plugin_display_page.inc:249 +msgid "The menu path or URL of this view" +msgstr "Il percorso del menu o URL di questa vista" + +#: plugins/views_plugin_display_page.inc:253 +msgid "This view will be displayed by visiting this path on your site. You may use \"%\" in your URL to represent values that will be used for arguments: For example, \"node/%/feed\"." +msgstr "Questa vista verrà visualizzata visitando questo percorso del sito. Negli URL si può usare \"%\" per rappresentare i valori che saranno utilizzati come argomenti. Per esempio, \"node/%/feed\"." + +#: plugins/views_plugin_display_page.inc:259 +msgid "Menu item entry" +msgstr "Inserimento voce di menu" + +#: plugins/views_plugin_display_page.inc:276 +msgid "No menu entry" +msgstr "Nessuna voce di menu" + +#: plugins/views_plugin_display_page.inc:277 +msgid "Normal menu entry" +msgstr "Voce di menu normale" + +#: plugins/views_plugin_display_page.inc:343,278 +msgid "Menu tab" +msgstr "Scheda menu" + +#: plugins/views_plugin_display_page.inc:279 +msgid "Default menu tab" +msgstr "Scheda menu predefinita" + +#: plugins/views_plugin_display_page.inc:288 +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "Se impostato a normale o scheda, inserire il testo da usare per la voce del menu." + +#: plugins/views_plugin_display_page.inc:295 +msgid "Warning: Changing this item's menu will not work reliably in Drupal 6.4 or earlier. Please upgrade your copy of Drupal at !url." +msgstr "Attenzione: La modifica di questa voce del menu non funzionarà con attendibilità in Drupal 6.4 o precedente. Aggiornare Drupal a !url." + +#: plugins/views_plugin_display_page.inc:306 +msgid "Insert item into an available menu." +msgstr "Inserire la voce in un menu disponibile." + +#: plugins/views_plugin_display_page.inc:315 +msgid "The lower the weight the higher/further left it will appear." +msgstr "Minore è il peso, più in alto o più a sinistra sarà mostrato." + +#: plugins/views_plugin_display_page.inc:321 +msgid "Default tab options" +msgstr "Opzioni predefinite scheda" + +#: plugins/views_plugin_display_page.inc:330 +msgid "When providing a menu item as a 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>." +msgstr "Quando si crea una voce di menu come scheda, Drupal ha bisogno di sapere quale sarà la voce di menu genitore di quella scheda. Alcune volte il genitore esiste già, mentre altre volte si deve crearne uno. Il percorso di una voce genitore sarà sempre lo stesso percorso con l'esclusione dell'ultima parte, cioè, se il percorso di questa vista è <em>foo/bar/baz</em>, il percorso genitore sarà <em>foo/bar</em>." + +#: plugins/views_plugin_display_page.inc:341 +msgid "Parent menu item" +msgstr "Voce genitore del menu" + +#: plugins/views_plugin_display_page.inc:343 +msgid "Already exists" +msgstr "Esiste già" + +#: plugins/views_plugin_display_page.inc:351 +msgid "If creating a parent menu item, enter the title of the item." +msgstr "Se si crea una voce genitore del menu, inserire il titolo della voce." + +#: plugins/views_plugin_display_page.inc:357 +msgid "Tab weight" +msgstr "Peso della scheda" + +#: plugins/views_plugin_display_page.inc:361 +msgid "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." +msgstr "Se la voce genitore del menu è una scheda, inserire il peso della scheda. più basso è il numero, più a sinistra sarà la scheda." + +#: plugins/views_plugin_display_page.inc:375 +msgid "\"$arg\" is no longer supported. Use % instead." +msgstr "\"$arg\" non è più supportato. Usare invece %." + +#: plugins/views_plugin_display_page.inc:379 +msgid "\"%\" may not be used for the first segment of a path." +msgstr "\"%\" non può essere usato nel primo segmento di un percorso." + +#: plugins/views_plugin_display_page.inc:389 +msgid "Views cannot create normal menu items for paths with a % in them." +msgstr "Le viste non possono creare voci di menu normali per i percorsi che contengono un %." + +#: plugins/views_plugin_display_page.inc:396 +msgid "A display whose path ends with a % cannot be a tab." +msgstr "Una visualizzazione il cui percorso termina con un % non può essere una scheda." + +#: plugins/views_plugin_display_page.inc:401 +msgid "Title is required for this menu type." +msgstr "È richiesto il titolo per questo tipo di menu." + +#: plugins/views_plugin_display_page.inc:432 +msgid "Display @display is set to use a menu but the menu title is not set." +msgstr "La visualizzazione @display è impostata per usare un menu ma il titolo del menu non è specificato." + +#: plugins/views_plugin_display_page.inc:438 +msgid "Display @display is set to use a parent menu but the parent menu title is not set." +msgstr "La visualizzazione @display è impostata per usare un menu genitore ma il titolo del menu genitore non è specificato." + +#: plugins/views_plugin_row_fields.inc:40 +msgid "Inline fields" +msgstr "Campi allineati" + +#: plugins/views_plugin_row_fields.inc:43 +msgid "Inline fields will be displayed next to each other rather than one after another." +msgstr "I campi allineati saranno visualizzati uno in fianco all'altro anziché uno dopo l'altro." + +#: plugins/views_plugin_row_fields.inc:51 +msgid "The separator may be placed between inline fields to keep them from squishing up next to each other. You can use HTML in this field." +msgstr "Il separatore può essere posizionato tra i campi allineati per impedirgli di schiacciarsi uno sull'altro. In questo campo si può usare l'HTML." + +#: plugins/views_plugin_style.inc:91 +msgid "Grouping field" +msgstr "Raggruppamento campi" + +#: plugins/views_plugin_style.inc:94 +msgid "You may optionally specify a field by which to group the records. Leave blank to not group." +msgstr "Si può specificare in via facoltativa un campo tramite il quale raggruppare le registrazioni. Lasciare vuoto per non raggruppare." + +#: plugins/views_plugin_style.inc:191 +msgid "Style @style requires a row style but the row plugin is invalid." +msgstr "Lo stile @style richiede uno stile riga ma il plugin riga non è valido." + +#: plugins/views_plugin_style_grid.inc:39 +msgid "Horizontal" +msgstr "Orizzontale" + +#: plugins/views_plugin_style_grid.inc:39 +msgid "Vertical" +msgstr "Verticale" + +#: plugins/views_plugin_style_grid.inc:41 +msgid "Horizontal alignment will place items starting in the upper left and moving right. Vertical alignment will place items starting in the upper left and moving down." +msgstr "L'allineamento orizzontale posizionerà le voci iniziando dalla parte superiore sinistra e spostandosi a destra. L'allineamento verticale posizionerà le voci iniziando dalla parte superiore sinistra e spostandosi in giù." + +#: plugins/views_plugin_style_rss.inc:56 +msgid "Use the site mission for the description" +msgstr "Usare la mission del sito per la descrizione" + +#: plugins/views_plugin_style_rss.inc:60 +msgid "RSS description" +msgstr "Descrizione RSS" + +#: plugins/views_plugin_style_rss.inc:62 +msgid "This will appear in the RSS feed itself." +msgstr "Comparirà nel feed RSS." + +#: plugins/views_plugin_style_summary.inc:34 +msgid "Display record count with link" +msgstr "Visualizza il conteggio dei record con un link" + +#: plugins/views_plugin_style_summary.inc:39 +msgid "Override number of items to display" +msgstr "Modifica il numero di voci da visualizzare" + +#: plugins/views_plugin_style_summary_unformatted.inc:26 +msgid "Display items inline" +msgstr "Visualizza le voci allineate" + +#: plugins/views_plugin_style_table.inc:126 +msgid "You need at least one field before you can configure your table settings" +msgstr "È necessario almeno un campo prima di poter configurare le impostazioni della tabella" + +#: plugins/views_plugin_style_table.inc:135 +msgid "Override normal sorting if click sorting is used" +msgstr "Modifica l'ordinamento normale se viene usato l'ordinamento tramite click" + +#: plugins/views_plugin_style_table.inc:141 +msgid "Enable Drupal style \"sticky\" table headers (Javascript)" +msgstr "Attiva lo stile di Drupal intestazioni tabelle \"fisse in cima\" (Javascript)" + +#: plugins/views_plugin_style_table.inc:143 +msgid "(Sticky header effects will not be active for preview below, only on live output.)" +msgstr "(L'effetto intestazioni fisse in cima non sarà attivo per l'anteprima sotto, ma solo nell'output vero e prorio.)" + +#: plugins/views_plugin_style_table.inc:148 +msgid "Default sort order" +msgstr "Ordinamento predefinito" + +#: plugins/views_plugin_style_table.inc:151 +msgid "If a default sort order is selected, what order should it use by default." +msgstr "Se viene selezionato un ordinamento predefinito, quale ordine deve essere usato in modo predefinito" + +#: plugins/views_plugin_style_table.inc:237 +msgid "Place fields into columns; you may combine multiple fields into the same column. If you do, the separator in the column specified will be used to separate the fields. Check the sortable box to make that column click sortable, and check the default sort radio to determine which column will be sorted by default, if any. You may control column order and field labels in the fields section." +msgstr "Inserire i campi nelle colonne; si possono combinare campi multipli nella stessa colonna. Se lo si fa, il separatore nella colonna specificata sarà usato per separare i campi. Selezionare la casella ordinabile per rendere la colonna ordinabile tramite click e selezionare il bottone radio predefinito ordina per determinare quale colonna verrà ordinata in modo predefinito. È possibile gestire l'ordine delle colonne e le etichette dei campi nella sezione campi." + +#: theme/views-ui-edit-item.tpl.php:32 +msgid "The style selected does not utilize fields." +msgstr "Lo stile selezionato non utilizza i campi." + +#: theme/views-ui-edit-item.tpl.php:34 +msgid "None defined" +msgstr "Non definito" + +#: theme/views-ui-edit-view.tpl.php:11 +msgid "This view 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>." +msgstr "Questa vista sta venendo modificata dall'utente !user ed è perciò bloccata alle modifiche di altri. Questo blocco è vecchio di !age. Cliccare qui per <a href=\"!break\">interrompere il blocco</a>." + +#: theme/views-ui-edit-view.tpl.php:16 +msgid "New view" +msgstr "Nuova vista" + +#: theme/views-ui-edit-view.tpl.php:18 +msgid "Changed view" +msgstr "Vista modificata" + +#: theme/views-ui-edit-view.tpl.php:23 +msgid "View %name, displaying items of type <strong>@base</strong>." +msgstr "Vista %name, visualizza voci del tipo <strong>@base</strong>." + +#: theme/views-ui-edit-view.tpl.php:42 +msgid "Live preview" +msgstr "Anteprima in diretta" + +#: theme/views-ui-list-views.tpl.php:17 +msgid "<em>@type</em> @base view: <strong>@view</strong>" +msgstr "<em>@type</em> @base vista: <strong>@view</strong>" + +#: theme/views-ui-list-views.tpl.php:27 +msgid "Title: @title" +msgstr "Titolo: @title" + +#: theme/views-ui-list-views.tpl.php:30 +msgid "Path: !path" +msgstr "Percorso: !path" + +#: theme/theme.inc:90 +msgid "Edit this view" +msgstr "Modifica questa vista" + +#: theme/theme.inc:559 +msgid "‹‹" +msgstr "‹‹" + +#: theme/theme.inc:560 +msgid "››" +msgstr "››" + +#: theme/theme.inc:570 +msgid "@current of @max" +msgstr "@current di @max" + +#: views_export/views_export.module:76 +msgid "There are no views to be exported at this time." +msgstr "Al momento non ci sono viste da esportare." + +#: views_export/views_export.module:108 +msgid "Show only these tags" +msgstr "Mostra solo questi tag" + +#: views_export/views_export.module:122 +msgid "Module name" +msgstr "Nome modulo" + +#: views_export/views_export.module:123 +msgid "Enter the module name to export code to." +msgstr "Inserire il nome del modulo per il quale si esporta il codice." + +#: views_export/views_export.module:190 +msgid "Put this in @module.views_default.inc in your modules/@module directory or modules/@module/includes directory" +msgstr "Metterlo in @module.views_default.inc nella cartella modules/@module oppure nella cartella modules/@module/includes" + +#: views_export/views_export.info:0 +msgid "Views exporter" +msgstr "Esportatore Viste" + diff --git a/sites/all/modules/views/translations/pl.po b/sites/all/modules/views/translations/pl.po new file mode 100644 index 0000000000000000000000000000000000000000..25bd694284038691d464a6034b8dca6ffce7723a --- /dev/null +++ b/sites/all/modules/views/translations/pl.po @@ -0,0 +1,3994 @@ +# $Id: pl.po,v 1.2.4.2 2010/03/10 20:27:33 merlinofchaos Exp $ +# +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# views.module,v 1.294 2008/06/11 19:32:46 merlinofchaos +# admin.inc,v 1.115 2008/06/11 19:32:47 merlinofchaos +# views_ui.module,v 1.99 2008/06/04 00:09:53 merlinofchaos +# views_export.module,v 1.1 2008/06/12 16:17:25 merlinofchaos +# views.info,v 1.7 2007/08/12 06:52:14 merlinofchaos +# views_ui.info,v 1.10 2008/01/09 00:05:08 merlinofchaos +# views_export.info,v 1.1 2008/06/12 16:17:25 merlinofchaos +# plugins.inc,v 1.118 2008/06/13 15:50:00 merlinofchaos +# convert.inc,v 1.9 2008/06/11 18:42:11 merlinofchaos +# theme.inc,v 1.50 2008/06/10 22:10:20 merlinofchaos +# views.install,v 1.41 2008/06/03 23:50:44 merlinofchaos +# docs.php,v 1.7 2008/06/07 00:12:11 merlinofchaos +# node.views.inc,v 1.72 2008/06/11 01:22:03 merlinofchaos +# view.inc,v 1.108 2008/06/10 22:10:20 merlinofchaos +# system.views.inc,v 1.5 2008/06/03 22:34:46 merlinofchaos +# user.views.inc,v 1.44 2008/06/03 22:34:46 merlinofchaos +# argument.handlers.inc,v 1.25 2008/06/03 22:36:55 merlinofchaos +# comment.views.inc,v 1.16 2008/06/03 22:34:46 merlinofchaos +# statistics.views.inc,v 1.6 2008/06/03 22:34:46 merlinofchaos +# upload.views.inc,v 1.8 2008/06/03 22:34:46 merlinofchaos +# book.views.inc,v 1.3 2008/04/10 20:23:30 merlinofchaos +# taxonomy.views.inc,v 1.31 2008/06/10 18:35:26 merlinofchaos +# ajax.inc,v 1.14 2008/06/03 22:34:46 merlinofchaos +# field.handlers.inc,v 1.12 2008/06/03 22:34:46 merlinofchaos +# filter.handlers.inc,v 1.20 2008/06/03 23:34:39 merlinofchaos +# relationship.handlers.inc,v 1.5 2008/06/03 22:34:46 merlinofchaos +# handlers.inc,v 1.84 2008/06/10 18:35:26 merlinofchaos +# sort.handlers.inc,v 1.5 2008/06/03 22:34:46 merlinofchaos +# ajax.js,v 1.21 2008/05/27 22:31:59 merlinofchaos +# ajax_view.js,v 1.5 2008/05/27 22:31:59 merlinofchaos +# tabs.js,v 1.3 2008/03/30 15:58:26 merlinofchaos +# poll.views.inc,v 1.2 2008/03/12 04:32:07 merlinofchaos +# profile.views.inc,v 1.6 2008/04/21 17:52:10 merlinofchaos +# search.views.inc,v 1.7 2008/06/03 23:53:05 merlinofchaos +# views.views.inc,v 1.3 2008/06/03 22:34:46 merlinofchaos +# views-more.tpl.php,v 1.2 2008/04/11 08:46:26 merlinofchaos +# views-ui-edit-item.tpl.php,v 1.7 2008/05/09 19:32:12 merlinofchaos +# views-ui-edit-tab.tpl.php,v 1.10 2008/05/14 00:30:25 merlinofchaos +# views-ui-edit-view.tpl.php,v 1.8 2008/05/14 00:52:10 merlinofchaos +# views-ui-list-views.tpl.php,v 1.5 2008/05/08 05:29:30 merlinofchaos +# +msgid "" +msgstr "" +"Project-Id-Version: 1.0\n" +"POT-Creation-Date: 2008-06-15 10:44+0200\n" +"PO-Revision-Date: 2008-10-07 13:02+0100\n" +"Last-Translator: Bartlomiej Opajdowski <bopajdowski@gmail.com>\n" +"Language-Team: Polish <bopajdowski@gmail.com>\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==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Poedit-Language: Polish\n" +"X-Poedit-Country: POLAND\n" + +#: views.module:625 +msgid "Skipping broken view @view" +msgstr "Pomiń uszkodzony widok @view" + +#: views.module:672;712 +#: includes/admin.inc:92;253;253;599 +msgid "Overridden" +msgstr "Nadpisany" + +#: views.module:675;708 +#: views_ui.module:284 +#: includes/admin.inc:91;252;252;566;738 +msgid "Default" +msgstr "Domyślny" + +#: views.module:824 +#: includes/admin.inc:286 +#: views_export/views_export.module:116 +msgid "Apply" +msgstr "Zastosuj" + +#: views.module:109 +#: views_ui.module:23 +#: views.info:0;0 +#: views_ui.info:0 +#: views_export/views_export.info:0 +msgid "Views" +msgstr "Widoki" + +#: views.module:114 +msgid "Ajax callback for view loading." +msgstr "funkcja zwrotna dla asynchronicznego ładowania widoku." + +#: views.module:0 +msgid "views" +msgstr "widoki" + +#: views_ui.module:158 +msgid "The converter will make a best-effort attempt to convert a Views 1 view to Views 2. This conversion is not reliable; you will very likely have to make adjustments to your view to get it to match. You can import Views 1 views through the normal Import tab." +msgstr "Konwerter próbuje przetworzyć widoki Views 1 na Views 2. Konwersja nie jest niezawodna; Być może będzie trzeba coś dopasować. Możesz importować widoki Views 1 używając zakładki Import." + +#: views_ui.module:25 +msgid "Views are customized lists of content on your system; they are highly configurable and give you control over how lists of content are presented." +msgstr "Widoki są spersonalizowaną listą zawartości; Są wysoce konfigurowywalne i dają kontrolę nad prezentowaną listą zawartości." + +#: views_ui.module:29 +#: includes/plugins.inc:88;116 +msgid "List" +msgstr "Lista" + +#: views_ui.module:35 +#: includes/admin.inc:1081;1081;2093 +msgid "Add" +msgstr "Dodaj" + +#: views_ui.module:40 +#: includes/admin.inc:702 +msgid "Import" +msgstr "Importuj" + +#: views_ui.module:46 +msgid "Tools" +msgstr "Narzędzia" + +#: views_ui.module:52 +msgid "Basic" +msgstr "Podstawowy" + +#: views_ui.module:60 +#: includes/convert.inc:30 +msgid "Convert" +msgstr "Konweruj" + +#: views_ui.module:61 +msgid "Convert stored Views 1 views." +msgstr "Konwertuj widok Views 1" + +#: views_ui.module:67;80;85 +msgid "Delete view" +msgstr "Usuń widok" + +#: views_ui.module:73 +msgid "Convert view" +msgstr "Konwertuj widok" + +#: views_ui.module:110 +#: includes/admin.inc:87 +#: theme/theme.inc:89 +msgid "Edit" +msgstr "Edytuj" + +#: views_ui.module:0 +msgid "views_ui" +msgstr "views_ui" + +#: views.install:31 +msgid "Stores the general data for a view." +msgstr "Przechowuje główne dane dla widoku." + +#: views.install:37 +msgid "The view ID of the field, defined by the database." +msgstr "ID widoku definiowane przez bazę danych." + +#: views.install:45 +msgid "The unique name of the view. This is the primary field views are loaded from, and is used so that views may be internal and not necessarily in the database. May only be alphanumeric characters plus underscores." +msgstr "Unikalna nazwa widoku. To " + +#: views.install:51 +msgid "A description of the view for the admin interface." +msgstr "Opis widoku dla interfejsu administracyjnego." + +#: views.install:57 +msgid "A tag used to group/sort views in the admin interface" +msgstr "Tag używany do grupowania/sortowania interfejsu administracyjnego" + +#: views.install:61 +msgid "A chunk of PHP code that can be used to provide modifications to the view prior to building." +msgstr "Kawałek kodu PHP do modyfikacjimodyfikacji widoku zanim ten zostanie zbudowany." + +#: views.install:68 +msgid "What table this view is based on, such as node, user, comment, or term." +msgstr "Na jakiej tabeli bazuje widok: segment, użytkownik, komentarz, wyrażenie." + +#: views.install:74 +msgid "A boolean to indicate whether or not this view may have its query cached." +msgstr "Wartość boolean oznaczająca czy zapytania powinny używać pamięci podręcznej czy też nie." + +#: views.install:82 +msgid "Stores information about each display attached to a view." +msgstr "Przechowuje informację o każdym podglądzie dołączonym do widoku." + +#: views.install:89 +msgid "The view this display is attached to." +msgstr "Widok dołączonego podglądu." + +#: views.install:97 +msgid "An identifier for this display; usually generated from the display_plugin, so should be something like page or page_1 or block_2, etc." +msgstr "Identyfikator tego podglądu; zwykle generowany z display_plugin, więc powinien wyglądać mniej sięcej jak: page_1 albo block_2 itp." + +#: views.install:104 +msgid "The title of the display, viewable by the administrator." +msgstr "Tytuł podglądu, widoczny dla administratora." + +#: views.install:111 +msgid "The type of the display. Usually page, block or embed, but is pluggable so may be other things." +msgstr "Typ podglądu. Zwykle strona, blok lub osadzony fragment, ma charakter pluginu, więc może być czymkolwiek." + +#: views.install:116 +msgid "The order in which this display is loaded." +msgstr "Kolejność ładowania podglądów." + +#: views.install:120 +msgid "A serialized array of options for this display; it contains options that are generally only pertinent to that display plugin type." +msgstr "Zserializowana tablica opcji dla tego podglądu; zawiera tylko opcje które są właściwe do wyświetlania typu plugina." + +#: views.install:131 +msgid "A special cache used to store objects that are being edited; it serves to save state in an ordinarily stateless environment." +msgstr "Specjalna pamięć podręczna używana do przechowywania obiektów będących w trakcie edycji; " + +#: views.install:136 +msgid "The session ID this cache object belongs to." +msgstr "ID sesji do której należy obiekt pamięci podręcznej." + +#: views.install:141 +msgid "The name of the view this cache is attached to." +msgstr "Nazwa widoku do którego dołączona jest ta pamięć podręczna." + +#: views.install:146 +msgid "The name of the object this cache is attached to; this essentially represents the owner so that several sub-systems can use this cache." +msgstr "Nazwa obiektu do którego dołączona jest ta pamięć podręczna. Określa dokładnie właścicela, tak więc klika podsystemów może jej używać." + +#: views.install:153 +msgid "The time this cache was created or updated." +msgstr "Czas utworzenia lub uaktualnienia pamięci podręcznej." + +#: views.install:157 +msgid "Serialized data being stored." +msgstr "Zserializowane dane będą zachowane." + +#: views.info:0 +msgid "Create customized lists and queries from your database." +msgstr "Tworzy własną listę zapytań z Twojej bazy danych." + +#: views_ui.info:0 +msgid "Views UI" +msgstr "Panel administracyjny widoków" + +#: views_ui.info:0 +msgid "Administrative interface to views. Without this module, you cannot create or edit your views." +msgstr "Administrowalny interfejs widoków. Bez tego modułu nie będzie możliwe tworzenie i edytowanie własnych widoków." + +#: docs/docs.php:106 +msgid "Emulates the default Drupal front page; you may set the default home page path to this view to make it your front page." +msgstr "Emuluje domyślną główną strone Drupala; możesz ustawić ścieżkę domyślnej strony domowej na ten widok aby była stroną główną" + +#: docs/docs.php:107 +msgid "default" +msgstr "domyślny" + +#: docs/docs.php:116 +#: includes/plugins.inc:18 +msgid "Defaults" +msgstr "Ustawienia domyślne" + +#: docs/docs.php:205 +#: includes/plugins.inc:32;40 +msgid "Page" +msgstr "Strona" + +#: docs/docs.php:260 +#: includes/plugins.inc:65;72 +msgid "Feed" +msgstr "Kanał" + +#: docs/docs.php:328 +msgid "Front page feed" +msgstr "Kanał strony głównej" + +#: includes/admin.inc:34 +msgid "If you install the advanced help module from !href, Views will provide more and better help. <a href=\"@hide\">Hide this message.</a>" +msgstr "Obszerniejsza pomoc dla modułu widoków znajduje się tutaj: !href . <a href=\"@hide\">Ukryj tą wiadomość.</a>" + +#: includes/admin.inc:88;900 +#: theme/theme.inc:96 +#: views_export/views_export.module:128 +msgid "Export" +msgstr "Eksportuj" + +#: includes/admin.inc:89;905 +#: theme/theme.inc:101 +msgid "Clone" +msgstr "Klonuj" + +#: includes/admin.inc:92 +msgid "Revert" +msgstr "Odwróć" + +#: includes/admin.inc:92;612;774 +#: includes/convert.inc:35;109 +msgid "Delete" +msgstr "Usuń" + +#: includes/admin.inc:97 +msgid "Disable" +msgstr "Wyłącz" + +#: includes/admin.inc:100 +msgid "Enable" +msgstr "Włącz" + +#: includes/admin.inc:106 +msgid "Warning! Broken view!" +msgstr "Ostrzeżenie! Uszkodzony widok!" + +#: includes/admin.inc:121 +msgid "Broken" +msgstr "Uszkodzony" + +#: includes/admin.inc:180 +msgid "Install the advanced help module for the getting started" +msgstr "Instalacja dodatkowego modułu pomocy" + +#: includes/admin.inc:183 +msgid "Not sure what to do? Try the \"!getting-started\" page." +msgstr "Nie jesteś pewien co zrobić? Spróbuj na stronie \"!getting-started\"." + +#: includes/admin.inc:197;250;2059 +msgid "<All>" +msgstr "<Wszystko>" + +#: includes/admin.inc:198 +#: includes/plugins.inc:2820 +msgid "<None>" +msgstr "<Nic>" + +#: includes/admin.inc:213;264;985 +#: views_export/views_export.module:146 +msgid "Tag" +msgstr "Tag" + +#: includes/admin.inc:229 +msgid "Displays" +msgstr "Podglądy" + +#: includes/admin.inc:241;266 +#: includes/plugins.inc:1102;2079 +#: modules/node.views.inc:139 +msgid "Type" +msgstr "Typ" + +#: includes/admin.inc:248 +msgid "Storage" +msgstr "Magazyn(storage)" + +#: includes/admin.inc:251;251 +#: includes/view.inc:993;1043 +msgid "Normal" +msgstr "Normalny" + +#: includes/admin.inc:260 +msgid "Sort by" +msgstr "Sortuj po" + +#: includes/admin.inc:262 +#: includes/plugins.inc:805 +#: modules/system.views.inc:69 +#: modules/user.views.inc:59;79 +msgid "Name" +msgstr "Nazwa" + +#: includes/admin.inc:263;361 +#: includes/argument.handlers.inc:111 +#: includes/plugins.inc:817;2091;2136 +#: modules/comment.views.inc:44 +#: modules/node.views.inc:84;402 +msgid "Title" +msgstr "Tytuł" + +#: includes/admin.inc:265;369 +#: includes/plugins.inc:2008 +#: modules/statistics.views.inc:146 +#: modules/system.views.inc:88 +msgid "Path" +msgstr "Ścieżka" + +#: includes/admin.inc:267 +#: includes/convert.inc:21 +#: modules/upload.views.inc:48 +#: views_export/views_export.module:146 +msgid "Description" +msgstr "Opis" + +#: includes/admin.inc:274 +msgid "Order" +msgstr "Kolejność" + +#: includes/admin.inc:276 +msgid "Up" +msgstr "Rosnąco" + +#: includes/admin.inc:277 +msgid "Down" +msgstr "Malejąco" + +#: includes/admin.inc:360;379 +msgid "Query" +msgstr "Zapytanie(query)" + +#: includes/admin.inc:366 +msgid "This display has no path." +msgstr "Ten podgląd nie ma podanej ścieżki." + +#: includes/admin.inc:371 +msgid "Query build time" +msgstr "Czas budowania zapytania" + +#: includes/admin.inc:371;372;373 +msgid "@time ms" +msgstr "@time ms" + +#: includes/admin.inc:372 +msgid "Query execute time" +msgstr "Czas wykonywania zapytania" + +#: includes/admin.inc:373 +msgid "View render time" +msgstr "Czas tworzenia widoku" + +#: includes/admin.inc:379 +msgid "No query was run" +msgstr "Żadne zapytanie nie zostało wykonane" + +#: includes/admin.inc:386 +msgid "Unable to preview due to validation errors." +msgstr "Nie mogę podejrzeć prawidłowego sprawdzania błędów." + +#: includes/admin.inc:437 +msgid "Display" +msgstr "Podgląd" + +#: includes/admin.inc:445 +#: includes/view.inc:1670 +msgid "Arguments" +msgstr "Argumenty" + +#: includes/admin.inc:447 +msgid "Separate arguments with a / as though they were a URL path." +msgstr "Argumenty oddzielamy / tak jak by były ścieżką w URLu." + +#: includes/admin.inc:453 +msgid "Preview" +msgstr "Podgląd" + +#: includes/admin.inc:491 +msgid "Clone view @view" +msgstr "Sklonuj widok @view" + +#: includes/admin.inc:504;691 +#: includes/convert.inc:20 +msgid "View name" +msgstr "Nazwa widoku" + +#: includes/admin.inc:505 +msgid "This is the unique name of the view. It must contain only alphanumeric characters and underscores; it is used to identify the view internally and to generate unique theming template names for this view. If overriding a module provided view, the name must not be changed or instead a new view will be created." +msgstr "To jest unikalna nazwa widoku. Może zawierać tylko znaki alfanumeryczne i podkreślenia; używana jest do identyfikowania widoku wewnętrznie i do generowania unikalnych nazw wzorów dla tego widoku. Jeśli nadpisujemy dostarczony wraz z modułem widok, nazwa nie może zostać zmieniona albo zostanie utworzony nowy widok." + +#: includes/admin.inc:513;1769 +msgid "View description" +msgstr "Opis widoku" + +#: includes/admin.inc:514;1770 +msgid "This description will appear on the Views administrative UI to tell you what the view is about." +msgstr "Ten opis ukaże się w panelu administracyjnym użytkownika, abyś wiedział do czego ten widok służy" + +#: includes/admin.inc:520;1776 +msgid "View tag" +msgstr "Tag widoku" + +#: includes/admin.inc:521;1777 +msgid "Enter an optional tag for this view; it is used only to help sort views on the administrative page." +msgstr "Wprowadź opcjonalny tag dla tego widoku; Będzie on używany by pomóc w ich sortowaniu na stronie administracyjnej." + +#: includes/admin.inc:533 +msgid "View type" +msgstr "Typ widoku" + +#: includes/admin.inc:534 +msgid "The view type is the primary table for which information is being retrieved. The view type controls what arguments, fields, sort criteria and filters are available, so once this is set it <strong>cannot be changed</strong>." +msgstr "Typ widoku jest pierwszą tabelą dla której informacje zostaną odzyskane. Typ widoku kontroluje jakie argumenty, pola, kryteria sortowania i filtry są dostępne, więc raz ustawione <strong> nie mogą być zmieniane<strong>." + +#: includes/admin.inc:545 +msgid "Next" +msgstr "Następne" + +#: includes/admin.inc:561 +msgid "View name must be alphanumeric or underscores only." +msgstr "Nazwa widoku może zawierać tylko znaki alfanumeryczne albo podkreślenia." + +#: includes/admin.inc:567 +msgid "You must use a unique name for this view." +msgstr "Musisz użyć unikalnej nazwy dla tego widoku." + +#: includes/admin.inc:600 +msgid "Are you sure you want to revert the view %name?" +msgstr "Jesteś pewny że chcesz powrócić do nazwy widoku %name?" + +#: includes/admin.inc:601 +msgid "Reverting the view will delete the view that is in the database, reverting it to the original default view. Any changes you have made will be lost and cannot be recovered." +msgstr "Przywracanie widoku spowoduje skasowanie widoku z bazy danych i przywrócenie oryginalnie dostarczonego widoku. Wszystkie zmiany które zrobiłeś będą utracone i nie będą mogły być odtworzone." + +#: includes/admin.inc:604 +#: includes/convert.inc:105 +msgid "Are you sure you want to delete the view %name?" +msgstr "Jesteś pewien że chcesz skasować widok %name?" + +#: includes/admin.inc:605 +msgid "Deleting a view cannot be undone." +msgstr "Kasowanie nie może być cofnięte." + +#: includes/admin.inc:613;649;767;1225 +#: includes/convert.inc:110 +msgid "Cancel" +msgstr "Anuluj" + +#: includes/admin.inc:622 +msgid "The view has been deleted." +msgstr "Widok został skasowany." + +#: includes/admin.inc:634 +msgid "There is no lock on view %view to break." +msgstr "Nie ma blokad do złamania na widoku %view." + +#: includes/admin.inc:644 +msgid "Are you sure you want to break the lock on view %name?" +msgstr "Jesteś pewien, że chcesz złamać blokadę na widoku %name?" + +#: includes/admin.inc:647 +msgid "By breaking this lock, any unsaved changes made by !user will be lost!" +msgstr "Przez złamanie tej blokady wszystkie niezapisane zmiany zrobione przez !user będą utracone!" + +#: includes/admin.inc:648 +msgid "Break lock" +msgstr "Złam blokadę" + +#: includes/admin.inc:665 +msgid "Edit view \"%view\"" +msgstr "Edytuj widok \"%view\"" + +#: includes/admin.inc:692 +msgid "Enter the name to use for this view if it is different from the source view. Leave blank to use the name of the view." +msgstr "Wprowadź nazwę używaną dla tego widoku jeśli jest inna niż źródłowa. Pozostaw puste aby użyć oryginalnej nazwy widoku." + +#: includes/admin.inc:697 +msgid "Paste view code here" +msgstr "Wklej kod widoku tutaj" + +#: includes/admin.inc:719 +msgid "Unable to interpret view code." +msgstr "Nie można zinterpretować kodu widoku." + +#: includes/admin.inc:726 +msgid "You are importing a view created in Views version 1. You may need to adjust some parameters to work correctly in version 2." +msgstr "Importujesz widok utworzony w Views 1. Prawdopodobnie trzeba będzie poprawić część parametrów aby widok działał z wersją widoków View 2." + +#: includes/admin.inc:729 +msgid "That view is not compatible with this version of Views." +msgstr "Ten widok nie jest kompatybilny z tą wersją Widoków." + +#: includes/admin.inc:739 +msgid "A view by that name already exists; please choose a different name" +msgstr "Widok o takiej nazwie juz istnieje; nazwij go inaczej" + +#: includes/admin.inc:760;788 +msgid "Save" +msgstr "Zachowaj" + +#: includes/admin.inc:812 +msgid "The view has been saved." +msgstr "Widok został zachowany." + +#: includes/admin.inc:851 +msgid "Unknown or missing table name" +msgstr "Nieznana lub utracona nazwa tabeli" + +#: includes/admin.inc:856 +msgid "Click on an item to edit that item's details." +msgstr "Kliknij na pozycję aby edytować jej szczegóły." + +#: includes/admin.inc:859 +msgid "This view has a broken default display and cannot be used." +msgstr "Ten widok nie może być użyty, gdyż został uszkodzony podgląd domyślny." + +#: includes/admin.inc:895 +msgid "break this lock" +msgstr "złam tą blokadę" + +#: includes/admin.inc:901 +#: theme/theme.inc:97 +msgid "Export this view" +msgstr "Eksportuj ten widok" + +#: includes/admin.inc:906 +#: theme/theme.inc:102 +msgid "Create a copy of this view" +msgstr "Stwórz kopię tych widoków" + +#: includes/admin.inc:917 +msgid "View \"!display\"" +msgstr "Podgląd \"!display\"" + +#: includes/admin.inc:918 +msgid "Go to the real page for this display" +msgstr "Idź do właściwej strony podglądu." + +#: includes/admin.inc:984 +#: includes/plugins.inc:812;943;955;1999;2293;2467;2659;3299 +msgid "None" +msgstr "Nic" + +#: includes/admin.inc:1058 +msgid "Invalid" +msgstr "Nieprawidłowy" + +#: includes/admin.inc:1058 +msgid "Error: Display @display refers to a plugin named '@plugin', but that plugin doesn't exist!" +msgstr "Błąd: Podgląd @display odwołuje się do nieistniejącego pluginu '@plugin'" + +#: includes/admin.inc:1079;1079 +msgid "Rearrange" +msgstr "Popraw" + +#: includes/admin.inc:1112;2144;2323;2391;2476 +msgid "Error: handler for @table > @field doesn't exist!" +msgstr "Błąd: uchwyt dla @table > @field nie istnieje!" + +#: includes/admin.inc:1131;1131;1140 +msgid "Settings" +msgstr "Ustawienia" + +#: includes/admin.inc:1136 +#: includes/plugins.inc:823;841 +msgid "Missing style plugin" +msgstr "Utracony styl pluginu" + +#: includes/admin.inc:1140 +#: includes/plugins.inc:836;851 +msgid "Change settings for this style" +msgstr "Zmień ustawienia dla tego stylu" + +#: includes/admin.inc:1143 +msgid " Style: !style" +msgstr " Styl: !style" + +#: includes/admin.inc:1174 +msgid "Invalid display id while regenerating tabs" +msgstr "Niepoprawne ID podglądu przy odtwarzaniu zakładek" + +#: includes/admin.inc:1207 +msgid "Update" +msgstr "Uaktualnij" + +#: includes/admin.inc:1225 +msgid "Ok" +msgstr "Ok" + +#: includes/admin.inc:1494 +msgid "Unable to initialize default display" +msgstr "Nie można zainicjować domyślnego podglądu" + +#: includes/admin.inc:1526 +msgid "Add display" +msgstr "Dodaj podgląd" + +#: includes/admin.inc:1566 +msgid "Remove display" +msgstr "Usuń podgląd" + +#: includes/admin.inc:1577 +msgid "Restore display" +msgstr "Odtwórz podgląd" + +#: includes/admin.inc:1649 +msgid "Analyze" +msgstr "Analizuj" + +#: includes/admin.inc:1669 +msgid "This view has only a default display and therefore will not be placed anywhere on your site; perhaps you want to add a page or a block display." +msgstr "Ten widok posiada tylko podgląd domyślny dlatego nie będzie umieszczony nigdzie na Twojej stronie; prawdopodobnie chcesz dodać stronę albo blok podglądu." + +#: includes/admin.inc:1681 +msgid "View analysis" +msgstr "Analiza widoku" + +#: includes/admin.inc:1690 +msgid "View analysis can find nothing to report." +msgstr "Analiza widoku przebiegła poprawnie." + +#: includes/admin.inc:1764 +msgid "View details" +msgstr "Szczegóły widoku" + +#: includes/admin.inc:1805;1854;1904;2045;2137;2316;2384;2469 +msgid "Invalid display id @display" +msgstr "Niewłąsciwe ID podglądu @display" + +#: includes/admin.inc:1858 +msgid "Configure @type" +msgstr "Konfiguruj @type" + +#: includes/admin.inc:1908 +msgid "Rearrange @type" +msgstr "Popraw @type" + +#: includes/admin.inc:1951 +msgid "Broken field @id" +msgstr "Uszkodzone pole @id" + +#: includes/admin.inc:1986;1995;2232;2341 +msgid "Remove" +msgstr "Usuń" + +#: includes/admin.inc:1986;1986 +msgid "Remove this item" +msgstr "Usuń tą pozycję" + +#: includes/admin.inc:1992 +msgid "No fields available." +msgstr "Brak dostępnych pól" + +#: includes/admin.inc:1995 +#: includes/plugins.inc:2100 +#: modules/book.views.inc:57 +#: modules/taxonomy.views.inc:126 +#: modules/upload.views.inc:82 +msgid "Weight" +msgstr "Waga" + +#: includes/admin.inc:2051 +msgid "Add @type" +msgstr "Dodaj @type" + +#: includes/admin.inc:2062 +msgid "Groups" +msgstr "Grupy" + +#: includes/admin.inc:2081 +msgid "!group: !field" +msgstr "!group: !field" + +#: includes/admin.inc:2090 +msgid "There are no @types available to add." +msgstr "Brak dostępnych @types do dodania." + +#: includes/admin.inc:2155 +#: includes/plugins.inc:1556 +msgid "Status: using default values." +msgstr "Status: użyto domyślnych wartości." + +#: includes/admin.inc:2162 +#: includes/plugins.inc:1568 +msgid "Status: using overridden values." +msgstr "Status: nadpisano wartości." + +#: includes/admin.inc:2200 +msgid "Do not use a relationship" +msgstr "Nie używaj zależności" + +#: includes/admin.inc:2209 +#: includes/view.inc:1694;1695 +msgid "Relationship" +msgstr "Zależność" + +#: includes/admin.inc:2222 +msgid "Configure @type \"@item\"" +msgstr "Konfiguruj @type\"@item\"" + +#: includes/admin.inc:2331 +msgid "Configure extra settings for @type \"@item\"" +msgstr "Konfiuruj dodatkowe ustawienia dla @type \"@item\"" + +#: includes/admin.inc:2396 +msgid "Change summary style for @type \"@item\"" +msgstr "Zmien zbiorczy styl dla @type \"@item\"" + +#: includes/admin.inc:2419;2433 +msgid "Internal error: broken plugin." +msgstr "Wewnętrzny błąd: uszkodzony plugin." + +#: includes/admin.inc:2483 +msgid "Configure summary style for @type \"@item\"" +msgstr "Konfiguruj zmiorczy styl dla @type \"@item\"" + +#: includes/admin.inc:2575 +msgid "Clear Views' cache" +msgstr "Wyczyść pamięć podręczną widoków." + +#: includes/admin.inc:2581 +msgid "Add Views signature to all SQL queries" +msgstr "Dodaj sygnature widoku dla wszystkich zapytań SQL" + +#: includes/admin.inc:2582 +msgid "All Views-generated queries will include a special 'VIEWS' = 'VIEWS' string in the WHERE clause. This makes identifying Views queries in database server logs simpler, but should only be used when troubleshooting." +msgstr "Wszystkie wygenerowane zapytania będą zawierały 'VIEWS' = 'VIEWS' w sekcji WHERE. Pomoże to w identyfikacji zapytań wysyłanych przez widoki w logach ale powinno być używane tylko w momencie gdy szukamy błędów." + +#: includes/admin.inc:2588 +msgid "Disable views data caching" +msgstr "Wyłącz pamięć podręczną dla danych zawartych w widokach" + +#: includes/admin.inc:2589 +msgid "Views caches data about tables, modules and views available, to increase performance. By checking this box, Views will skip this cache and always rebuild this data when needed. This can have a serious performance impact on your site." +msgstr "Pamięć podręczna widoków przechowuje w pamięci podręcznej dane o tabelach, modułach i dostępności widoków aby zwiększyć wydajność. Zaznaczając to pole, widoki będą pomijać przechowywanie danych i będą zawsze odbudowywać dane kiedy zajdzie taka potrzeba. To może spowodować poważny spadek wydajności twojej witryny." + +#: includes/admin.inc:2595 +msgid "Ignore missing advanced help module" +msgstr "Ignoruj brak dodatkowy modułów pomocy" + +#: includes/admin.inc:2596 +msgid "Views uses the advanced help module to provide help text; if this module is not present Views will complain, unless this setting is checked." +msgstr "Widoki używają dodatkowych modułów pomocy; jeśli brak tego modułu Widoki będą to zgłaszały do momentu zaznaczenia." + +#: includes/admin.inc:2602 +msgid "Show query above live preview" +msgstr "Wyświetl zapytanie powyżej podglądu na żywo" + +#: includes/admin.inc:2603 +msgid "The live preview feature will show you the output of the view you're creating, as well as the view. Check here to show the query and other information above the view; leave this unchecked to show that information below the view." +msgstr "Podgląd na żywo pokazuje jak będzie wyglądał widok nad którym właśnie pracujesz. Zaznacz aby wyświetlać zapytania i inne informację powyżej widoku; gdy niezaznaczone, informację będą pojawiać się poniżej widoku." + +#: includes/admin.inc:2609 +msgid "Do not show hover links over views" +msgstr "Nie wyświetlaj \"fruwających\" odnośników do widoków" + +#: includes/admin.inc:2610 +msgid "To make it easier to administrate your views, Views provides 'hover' links to take you to the edit and export screen of a view whenever the view is used. This can be distracting on some themes, though; if it is problematic, you can turn it off here." +msgstr "Aby ułatwić administrowanie widokami, widoki dostarczają \"fruwające\" odnośniki aby dać możliwość edytowania czy eksportowania kiedy widok jest używany. Może to wprowadząć bałagan w niektórych skórkach, Jeśli tak się dzieje, można to wyłączyć własnie tutaj." + +#: includes/admin.inc:2616 +msgid "Enable views performance statistics via the Devel module" +msgstr "Włącz wydajność statystyk widoków przez moduł Devel" + +#: includes/admin.inc:2617 +msgid "Check this to enable some Views query and performance statistics <em>if Devel is installed</em>." +msgstr "Zaznacz by włączyć zapytania Widoków i statystyki wydajności <em>gdy moduł Devel jest zainstalowany</em>." + +#: includes/admin.inc:2623 +msgid "Disable javascript with Views" +msgstr "Wyłącz JavaStript w Widokach" + +#: includes/admin.inc:2624 +msgid "If you are having problems with the javascript, you can disable it here; the Views UI should degrade and still be usable without javascript, it just not as good." +msgstr "Jeśli masz problem z JavaScript, możesz wyłączyćto tutaj; Panel administracyjny Widoków powinien zachować funkcjonalność bez JavaScript, lecz nie pełną." + +#: includes/admin.inc:2632 +msgid "Page region to output performance statistics" +msgstr "Obszar strony do umieszczania statystyk wydajności" + +#: includes/admin.inc:2645 +msgid "The cache has been cleared." +msgstr "Pamięć podręczna została wyczyszczona." + +#: includes/admin.inc:2809 +msgid "Error: missing @component" +msgstr "Error: brak @component" + +#: includes/ajax.inc:73 +msgid "Server reports invalid input error." +msgstr "Serwer zwrócił błąd wejścia." + +#: includes/ajax.inc:74 +msgid "Error" +msgstr "Błąd" + +#: includes/argument.handlers.inc:91 +msgid "All" +msgstr "Wszystko" + +#: includes/argument.handlers.inc:113 +msgid "The title to use when this argument is present; it will override the title of the view and titles from previous arguments. You can use percent substitution here to replace with argument titles. Use \"%1\" for the first argument, \"%2\" for the second, etc." +msgstr "Tytuł używany kiedy argument istnieje; Nadpisze tytuł widoku obecnego i poprzednich argumentów. Możesz użyć '%n' aby zastąpić argument w tytule. Na przykład \"%1\" dla pierwszego argumentu itd." + +#: includes/argument.handlers.inc:126 +msgid "Action to take if argument is not present" +msgstr "Działanie podjęte gdy brak argumentu" + +#: includes/argument.handlers.inc:138 +msgid "Wildcard" +msgstr "Wildcard" + +#: includes/argument.handlers.inc:141 +msgid "If this value is received as an argument, the argument will be ignored; i.e, \"all values\"" +msgstr "Jeśli wartośc została otrzymana jako argument, argument zostanie zignorowany; Na przykład \"all values\" (wszystkie wartości)" + +#: includes/argument.handlers.inc:147 +msgid "Wildcard title" +msgstr "Tytuł dla Wildcard" + +#: includes/argument.handlers.inc:150 +msgid "The title to use for the wildcard in substitutions elsewhere." +msgstr "Tytuł używny dla zastąpienia gdzie indziej." + +#: includes/argument.handlers.inc:173 +msgid "Validator" +msgstr "Validator" + +#: includes/argument.handlers.inc:177 +msgid "<Basic validation>" +msgstr "<Sprawdzanie podstaw>" + +#: includes/argument.handlers.inc:213 +msgid "Action to take if argument does not validate" +msgstr "Działanie podjęte gdy sprawdzanie nie powiodło się" + +#: includes/argument.handlers.inc:228 +msgid "Display all values" +msgstr "Wyświetl wszystkie wartości" + +#: includes/argument.handlers.inc:233 +msgid "Hide view / Page not found (404)" +msgstr "Ukryj widok / Nie odnaleziono strony (404)" + +#: includes/argument.handlers.inc:237 +msgid "Display empty text" +msgstr "Wyświetl pusty tekst" + +#: includes/argument.handlers.inc:242 +msgid "Summary, sorted ascending" +msgstr "Podsumowanie, posortowane rosnąco" + +#: includes/argument.handlers.inc:249 +msgid "Summary, sorted descending" +msgstr "Podsumowanie, posortowane malejąco" + +#: includes/argument.handlers.inc:256 +msgid "Provide default argument" +msgstr "Dostarcz domyślny argument" + +#: includes/argument.handlers.inc:287 +msgid "Default argument type" +msgstr "Domyślny typ argumentu" + +#: includes/argument.handlers.inc:702 +msgid "Current date" +msgstr "Dzisiejsza data" + +#: includes/argument.handlers.inc:757 +msgid "Glossary mode" +msgstr "Tryb Słownika" + +#: includes/argument.handlers.inc:758 +msgid "Glossary mode applies a limit to the number of characters used in the argument, which allows the summary view to act as a glossary." +msgstr "Ten tryb ustawia limit znaków użytych w argumencie w podsumowaniach Słownika." + +#: includes/argument.handlers.inc:764 +msgid "Character limit" +msgstr "Limit znaków" + +#: includes/argument.handlers.inc:765 +msgid "How many characters of the argument to filter against. If set to 1, all fields starting with the letter in the argument would be matched." +msgstr "Ile znaków w argumencie ma być filtrowanych. Jeśli ustawimy to na 1, wszystkie pola zaczynające się na 1 literę dostarczona w argumencie będą pasować" + +#: includes/argument.handlers.inc:773 +msgid "Case" +msgstr "w przypadku" + +#: includes/argument.handlers.inc:774 +msgid "When printing the argument result, how to transform the case." +msgstr "Jak przekształcić w przypadku kiedy wyświetlamy wynik dla argumentu." + +#: includes/argument.handlers.inc:776;790 +msgid "No transform" +msgstr "Nie przekształcaj" + +#: includes/argument.handlers.inc:777;791 +msgid "Upper case" +msgstr "Dużymi literami" + +#: includes/argument.handlers.inc:778;792 +msgid "Lower case" +msgstr "Małymi literami" + +#: includes/argument.handlers.inc:779;793 +msgid "Capitalize first letter" +msgstr "Pierwsza litera duża" + +#: includes/argument.handlers.inc:780;794 +msgid "Capitalize each word" +msgstr "Każde słowo zaczynaj wielką literą" + +#: includes/argument.handlers.inc:787 +msgid "Case in path" +msgstr "Przypadki w ścieżkach" + +#: includes/argument.handlers.inc:788 +msgid "When printing url paths, how to transform the of the argument. Do not use this unless with Postgres as it uses case sensitive comparisons." +msgstr "Jak przekształcić argument w URLu. Nie używaj dopóki Postgres jest wrażliwy na porównywanie wielkości znaków." + +#: includes/argument.handlers.inc:801 +msgid "Transform spaces to dashes in URL" +msgstr "Zmieniaj znaki spacji na _ w URL" + +#: includes/argument.handlers.inc:808;1046 +msgid "Allow multiple arguments to work together." +msgstr "Pozwól na pracę wielu argumentów razem." + +#: includes/argument.handlers.inc:809;1047 +msgid "If selected, multiple instances of this argument can work together, as though multiple terms were supplied to the same argument. This setting is not compatible with the \"Reduce duplicates\" setting." +msgstr "Jeśli pole jest zaznaczone wiele instancji argumentu może pracować razem, jak gdyby wiele wyrażeń było dostarczonych dla jednego argumentu. To ustawienie nie jest kompatybilne z \"Reduce duplicates\"(redukuj duplikaty)" + +#: includes/argument.handlers.inc:815;1053 +msgid "Do not display items with no value in summary" +msgstr "Nie wyświetlaj pozycji bez wartości w podsumowaniu" + +#: includes/argument.handlers.inc:936;1038 +msgid "Allow multiple terms per argument." +msgstr "Pozwól na wiele wyrażeń dla argumentu." + +#: includes/argument.handlers.inc:937 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 or 1,2,3." +msgstr "Jeśli pole jest zaznaczone, użytkownik może wprowadzić wiele argumentów w postaci 1+2+3 lub 1,2,3." + +#: includes/argument.handlers.inc:943 +msgid "Exclude the argument" +msgstr "Wyklucz argument" + +#: includes/argument.handlers.inc:944 +msgid "If selected, the numbers entered in the argument will be excluded rather than limiting the view." +msgstr "Jeśli pole jest zaznaczone, wartości argumentów zostaną wykluczone." + +#: includes/argument.handlers.inc:951;963;1088;1102 +#: modules/taxonomy.views.inc:120;204;287 +msgid "Uncategorized" +msgstr "Nieskategoryzowany" + +#: includes/argument.handlers.inc:967;1106 +msgid "Invalid input" +msgstr "Nieprawidłowe wejscie" + +#: includes/argument.handlers.inc:1039 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 (for OR) or 1,2,3 (for AND)." +msgstr "Jeśli pole jest zaznaczone, użytkownik może wprowadzić wiele argumentów 1+2+3 (dla OR) albo 1,2,3 (dla AND)." + +#: includes/convert.inc:14 +msgid "There are no Views 1 views stored in the database to convert." +msgstr "Brak widoków typu Views 1 do konwersji w bazie." + +#: includes/convert.inc:22 +msgid "Operations" +msgstr "Operacje" + +#: includes/convert.inc:33 +msgid "Converted" +msgstr "Skonwertowano" + +#: includes/convert.inc:68 +msgid "The table below lists Views version 1 views that are stored in the database. You can either convert them to work in Views version 2, or delete them. The views are convertible only if there is no Views 2 view with the same name." +msgstr "Tabela poniżej jest listą widoków Views 1 przechowywanych w bazie. Możesz je skonwertować do Views 2 lub je skasować. Widoki te są konwertowalne tylko jeśli nie istnieją widoki w wersji 2 o takiej samej nazwie." + +#: includes/convert.inc:79 +msgid "Unable to find view." +msgstr "Nie można znaleźć widoku." + +#: includes/convert.inc:89 +msgid "Unable to convert view." +msgstr "Nie można skonwertować widoku." + +#: includes/convert.inc:108 +msgid "This action cannot be undone." +msgstr "Tej akcji nie można cofnąć." + +#: includes/convert.inc:118 +msgid "The view has been deleted" +msgstr "Widok został skasowany" + +#: includes/field.handlers.inc:130 +#: includes/filter.handlers.inc:304 +#: includes/relationship.handlers.inc:60 +msgid "Label" +msgstr "Etykieta" + +#: includes/field.handlers.inc:132 +msgid "The label for this field that will be displayed to end users if the style requires it." +msgstr " Jeśli styl tego wymaga, etykieta dla tego pola zostanie wyświetlona użytkownikowi końcowemu." + +#: includes/field.handlers.inc:136 +msgid "Exclude from display" +msgstr "Wyklucz z podglądu" + +#: includes/field.handlers.inc:138 +msgid "Check this box to not display this field, but still load it in the view. Use this option to not show a grouping field in each record, or when doing advanced theming." +msgstr "Zaznacz jeśli nie chcesz aby podgląd był wyświetlany, ale wciąż ładowany do widoku. Użyj tej opcji aby nie pokazywać grup pól w każdym rekordzie, lub kiedy tworzysz zaawansowane motywy." + +#: includes/field.handlers.inc:223 +msgid "Date format" +msgstr "Format daty" + +#: includes/field.handlers.inc:228 +msgid "Custom" +msgstr "Własny" + +#: includes/field.handlers.inc:229 +msgid "Time ago" +msgstr "Time ago" + +#: includes/field.handlers.inc:235 +msgid "Custom date format" +msgstr "Własny format daty" + +#: includes/field.handlers.inc:236 +msgid "If \"Custom\", see <a href=\"http://us.php.net/manual/en/function.date.php\">the PHP docs</a> for date formats. If \"Time ago\" this is the the number of different units to display, which defaults to two." +msgstr "Gdy chcesz użyć własnego formatu daty przeczytaj <a href=\"http://us.php.net/manual/en/function.date.php\">dokumentacje PHP</a>. Jeżeli \"Time ago\" jest liczbą w innych jednostkach, domyślnie - dwa." + +#: includes/field.handlers.inc:252 +msgid "%time ago" +msgstr "%time ago" + +#: includes/field.handlers.inc:280 +msgid "Output format" +msgstr "Format wyjściowy" + +#: includes/field.handlers.inc:282 +msgid "Yes/No" +msgstr "Tak/Nie" + +#: includes/field.handlers.inc:283 +msgid "True/False" +msgstr "Prawda/Fałsz" + +#: includes/field.handlers.inc:284 +msgid "On/Off" +msgstr "Włącz/Wyłącz" + +#: includes/field.handlers.inc:290 +msgid "Reverse" +msgstr "Odwrotnie" + +#: includes/field.handlers.inc:291 +msgid "If checked, true will be displayed as false." +msgstr "Gdy zaznaczone, Prawda wyświetlana jest jako Fałsz." + +#: includes/field.handlers.inc:305 +#: includes/filter.handlers.inc:853;898 +#: includes/plugins.inc:858;867;884;892;1035;2446 +msgid "Yes" +msgstr "Tak" + +#: includes/field.handlers.inc:305 +#: includes/filter.handlers.inc:853;898 +#: includes/plugins.inc:858;867;884;892;1035;1043;2446 +msgid "No" +msgstr "Nie" + +#: includes/field.handlers.inc:307 +#: includes/filter.handlers.inc:822;863 +msgid "True" +msgstr "Prawda" + +#: includes/field.handlers.inc:307 +#: includes/filter.handlers.inc:863 +msgid "False" +msgstr "Fałsz" + +#: includes/field.handlers.inc:309 +msgid "On" +msgstr "Włącz" + +#: includes/field.handlers.inc:309 +msgid "Off" +msgstr "Wyłącz" + +#: includes/field.handlers.inc:368 +#: modules/statistics.views.inc:276 +msgid "Display as link" +msgstr "Wyświetlaj jako odnośnik" + +#: includes/field.handlers.inc:410 +#: modules/node.views.inc:1289 +msgid "Display type" +msgstr "Wyświetl typ" + +#: includes/field.handlers.inc:412 +#: includes/plugins.inc:2971 +msgid "Unordered list" +msgstr "Nieuporządkowana lista" + +#: includes/field.handlers.inc:413 +#: includes/plugins.inc:2971 +msgid "Ordered list" +msgstr "Uporządkowana lista" + +#: includes/field.handlers.inc:414 +msgid "Simple separator" +msgstr "Prosty separator" + +#: includes/field.handlers.inc:421 +#: includes/plugins.inc:3265;3376;3557 +msgid "Separator" +msgstr "Separator" + +#: includes/field.handlers.inc:429 +msgid "Empty list text" +msgstr "Puste pole tekstowe" + +#: includes/field.handlers.inc:431 +msgid "If the list is empty, you may enter text here that will be displayed." +msgstr "Jeśli lista jest pusta, możesz wprowadzić tekst który będzie wyświetlony." + +#: includes/field.handlers.inc:480 +msgid "Round" +msgstr "Zaokrąglaj" + +#: includes/field.handlers.inc:481 +msgid "If checked, the number will be rounded." +msgstr "Jesli pole jest zaznaczone, liczby będą zaokrąglane." + +#: includes/field.handlers.inc:486 +msgid "Precision" +msgstr "Dokładność" + +#: includes/field.handlers.inc:488 +msgid "Specify how many digits to print after the decimal point." +msgstr "Określa dokładnośc z jaka będą wyświetlane liczby po przecinku." + +#: includes/field.handlers.inc:495 +msgid "Decimal point" +msgstr "Separator dziesiętny" + +#: includes/field.handlers.inc:497 +msgid "What single character to use as a decimal point." +msgstr "Znak oddzielający liczbę od jej częsci dziesiętnej." + +#: includes/field.handlers.inc:503 +msgid "Thousands separator" +msgstr "Separator setek" + +#: includes/field.handlers.inc:505 +msgid "What single character to use as the thousands separator." +msgstr "Znak oddzielający setki w liczbie. np. 1000 ze spacją jako separatorem będzie wyglądać tak: 1 000" + +#: includes/field.handlers.inc:510 +msgid "Prefix" +msgstr "Prefix" + +#: includes/field.handlers.inc:512 +msgid "Text to put before the number, such as currency symbol." +msgstr "Tekst poprzedzający liczbę, taki jak na przykład $." + +#: includes/field.handlers.inc:516 +msgid "Suffix" +msgstr "Suffix" + +#: includes/field.handlers.inc:518 +msgid "Text to put after the number, such as currency symbol." +msgstr "Tekst dołączany na końcu liczby np. zł" + +#: includes/filter.handlers.inc:119 +msgid "Operator" +msgstr "Operator" + +#: includes/filter.handlers.inc:183 +msgid "Expose" +msgstr "Ujawnij" + +#: includes/filter.handlers.inc:188 +msgid "This item is currently not exposed. If you <strong>expose</strong> it, users will be able to change the filter as they view it." +msgstr "Ta pozycja nie jest obecnie pokazywana. Gdy wybierzesz <strong>Ujawnij</strong> użytkownik będzie w stanie zmieniać filtr." + +#: includes/filter.handlers.inc:195 +msgid "Hide" +msgstr "Ukryj" + +#: includes/filter.handlers.inc:200 +msgid "This item is currently exposed. If you <strong>hide</strong> it, users will not able to change the filter as they view it." +msgstr "Ta pozycja jest obecnie pokazywana. Gdy wybierzesz <strong>Ukryj</strong> użytkownik nie będzie w stanie zmienić filtra." + +#: includes/filter.handlers.inc:271 +msgid "Unlock operator" +msgstr "Odblokuj operator" + +#: includes/filter.handlers.inc:272 +msgid "When checked, the operator will be exposed to the user" +msgstr "Gdy zaznaczone, operator będzie widoczny dla użytkownika" + +#: includes/filter.handlers.inc:278 +msgid "Operator identifier" +msgstr "Identyfikator operatora" + +#: includes/filter.handlers.inc:280 +msgid "This will appear in the URL after the ? to identify this operator." +msgstr "Włącza ukazywanie się identyfikatora operatora po ? w URLu." + +#: includes/filter.handlers.inc:297 +msgid "Filter identifier" +msgstr "Identyfikator filtra" + +#: includes/filter.handlers.inc:299 +msgid "This will appear in the URL after the ? to identify this filter. Cannot be blank." +msgstr "Włącza ukazywanie się identyfikatora filtra po ? w URLu. Nie może być puste." + +#: includes/filter.handlers.inc:315 +msgid "Optional" +msgstr "Opcjonalnie" + +#: includes/filter.handlers.inc:316 +msgid "This exposed filter is optional and will have added options to allow it not to be set." +msgstr "Ujawnienie filtra jest opcjonalne." + +#: includes/filter.handlers.inc:322 +msgid "Force single" +msgstr "Wymuś pojedyncze" + +#: includes/filter.handlers.inc:323 +msgid "Force this exposed filter to accept only one option." +msgstr "Pozwala filtrowi na akceptowanie tylko jednej opcji." + +#: includes/filter.handlers.inc:329 +msgid "Remember" +msgstr "Pamiętaj" + +#: includes/filter.handlers.inc:330 +msgid "Remember the last setting the user gave this filter." +msgstr "Pamięta ostatnie ustawienienie filtra użytkownika." + +#: includes/filter.handlers.inc:341 +msgid "" +"The identifier is required if the filter is\n" +" exposed." +msgstr "" +"Identyfikator jest wymagany jesli filtr jest\n" +" ujawniony." + +#: includes/filter.handlers.inc:347 +msgid "This identifier is not allowed." +msgstr "Ten identyfikator nie jest dozwolony" + +#: includes/filter.handlers.inc:448 +msgid "<Any>" +msgstr "<Dowolny>" + +#: includes/filter.handlers.inc:540;582;1089 +msgid "Is equal to" +msgstr "Jest równy" + +#: includes/filter.handlers.inc:541;588;1095 +msgid "Is not equal to" +msgstr "Nie jest równy" + +#: includes/filter.handlers.inc:551;714;1197 +msgid "Value" +msgstr "Wartość" + +#: includes/filter.handlers.inc:583;589;1091 +msgid "=" +msgstr "=" + +#: includes/filter.handlers.inc:594 +msgid "Contains" +msgstr "Zawiera" + +#: includes/filter.handlers.inc:595 +msgid "contains" +msgstr "zawiera" + +#: includes/filter.handlers.inc:600 +msgid "Contains any word" +msgstr "Zawiera tylko słowo" + +#: includes/filter.handlers.inc:601 +msgid "has word" +msgstr "ma słowo" + +#: includes/filter.handlers.inc:606 +msgid "Contains all words" +msgstr "Zawiera wszystkie słowa" + +#: includes/filter.handlers.inc:607 +msgid "has all" +msgstr "ma wszystkie" + +#: includes/filter.handlers.inc:612 +msgid "Starts with" +msgstr "Rozpoczyna się od" + +#: includes/filter.handlers.inc:613 +msgid "begins" +msgstr "rozpoczyna" + +#: includes/filter.handlers.inc:618 +msgid "Ends with" +msgstr "Kończy sie na" + +#: includes/filter.handlers.inc:619 +msgid "ends" +msgstr "kończy" + +#: includes/filter.handlers.inc:624 +msgid "Does not contain" +msgstr "Nie zawiera" + +#: includes/filter.handlers.inc:625 +msgid "!has" +msgstr "!has" + +#: includes/filter.handlers.inc:634;1130 +msgid "Is empty (NULL)" +msgstr "Jest pusty (NULL)" + +#: includes/filter.handlers.inc:636;1132 +msgid "empty" +msgstr "pusty" + +#: includes/filter.handlers.inc:640;1136 +msgid "Is not empty (NULL)" +msgstr "Nie jest pusty (NULL)" + +#: includes/filter.handlers.inc:642;1138 +msgid "not empty" +msgstr "nie pusty" + +#: includes/filter.handlers.inc:665 +msgid "exposed>" +msgstr "ujawniony>" + +#: includes/filter.handlers.inc:672 +msgid "Case sensitive" +msgstr "Wrażliwy na wielkość liter" + +#: includes/filter.handlers.inc:674 +msgid "Case sensitive filters may be faster; MySQL might ignore case sensitivity." +msgstr "Filtry wrażliwe na wielkość liter mogą być szybsze; MySQL moze ignorować rozróżnianie wielkości liter." + +#: includes/filter.handlers.inc:860;1009 +msgid "exposed" +msgstr "ujawniony" + +#: includes/filter.handlers.inc:888 +msgid "Options" +msgstr "Opcje" + +#: includes/filter.handlers.inc:910 +msgid "Limit list to selected items" +msgstr "Ogranicz listę do wybranych elementów" + +#: includes/filter.handlers.inc:911 +msgid "If checked, the selected items presented to the user will be the only ones selected here." +msgstr "Jeśli zaznaczysz to pole, wybrane elementy prezentowane użytkownikowi będą tylko raz zaznaczone tutaj." + +#: includes/filter.handlers.inc:930;1459 +msgid "Is one of" +msgstr "Jeden z" + +#: includes/filter.handlers.inc:931 +msgid "Is not one of" +msgstr "Żaden z" + +#: includes/filter.handlers.inc:1022 +#: modules/system.views.inc:236 +msgid "Unknown" +msgstr "Nieznany" + +#: includes/filter.handlers.inc:1077 +msgid "Is less than" +msgstr "Mniej niż" + +#: includes/filter.handlers.inc:1079 +msgid "<" +msgstr "<" + +#: includes/filter.handlers.inc:1083 +msgid "Is less than or equal to" +msgstr "Mniejszy bądź równy" + +#: includes/filter.handlers.inc:1085 +msgid "<=" +msgstr "<=" + +#: includes/filter.handlers.inc:1097 +msgid "!=" +msgstr "!=" + +#: includes/filter.handlers.inc:1101 +msgid "Is greater than or equal to" +msgstr "Większy bądź równy" + +#: includes/filter.handlers.inc:1103 +msgid ">=" +msgstr ">=" + +#: includes/filter.handlers.inc:1107 +msgid "Is greater than" +msgstr "Większy niż" + +#: includes/filter.handlers.inc:1109 +msgid ">" +msgstr ">" + +#: includes/filter.handlers.inc:1113 +msgid "Is between" +msgstr "W przedziale" + +#: includes/filter.handlers.inc:1115 +msgid "between" +msgstr "pomiędzy" + +#: includes/filter.handlers.inc:1119 +msgid "Is not between" +msgstr "Poza przedziałem" + +#: includes/filter.handlers.inc:1121 +msgid "not between" +msgstr "poza" + +#: includes/filter.handlers.inc:1212 +msgid "Min" +msgstr "Min" + +#: includes/filter.handlers.inc:1218 +msgid "And max" +msgstr "i max" + +#: includes/filter.handlers.inc:1218 +msgid "And" +msgstr "i" + +#: includes/filter.handlers.inc:1275 +msgid "@min and @max" +msgstr "@min and @max" + +#: includes/filter.handlers.inc:1301 +msgid "Value type" +msgstr "Typ wartości" + +#: includes/filter.handlers.inc:1303 +msgid "A date in any machine readable format. CCYY-MM-DD HH:MM:SS is preferred." +msgstr "Data w formacie maszynowym (machine redable format). Preferowana CCYY-MM-DD HH:MM:SS ." + +#: includes/filter.handlers.inc:1304 +msgid "An offset from the current time such as \"+1 day\" or \"-2 hours -30 minutes\"" +msgstr "Przesunięcie od obecnego czasu takie jak \"+1 dzień\" albo \"-2 godziny -30 minut\"" + +#: includes/filter.handlers.inc:1354;1360;1364 +msgid "Invalid date format." +msgstr "Niewłaściwy format daty." + +#: includes/filter.handlers.inc:1460 +msgid "Is all of" +msgstr "Należy do" + +#: includes/filter.handlers.inc:1461 +msgid "Is none of" +msgstr "Nie należy do" + +#: includes/handlers.inc:136 +msgid "!group: !title" +msgstr "!group: !title" + +#: includes/handlers.inc:336 +msgid "Broken/missing handler" +msgstr "Uszkodzony/utracony uchwyt(handler)" + +#: includes/handlers.inc:344 +msgid "The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item." +msgstr "Uchwyt do tego elementu jest uszkodzony lub nie istnieje i nie może zostać użyty. Jeśli moduł dostarcza uchwyt i został wyłączony ponowne włączenie modułu może pomóc. Jeśli nie pomoże prawdopodobnie trzeba skasować ten element." + +#: includes/handlers.inc:380 +msgid "Reduce duplicates" +msgstr "Usuń duplikaty" + +#: includes/handlers.inc:381 +msgid "This filter can cause items that have more than one of the selected options to appear as duplicate results. If this filter causes duplicate results to occur, this checkbox can reduce those duplicates; however, the more terms it has to search for, the less performant the query will be, so use this with caution." +msgstr "Zaznaczenie więcej niż jednej opcji w tym filtrze może powodować pojawienie się duplikatów w wynikach. Jeśli wystąpią duplikaty, zaznaczenie tej opcji wyeliminuje je; Czym więcej wyrażeń szukamy, tym mniej wydajne będą zapytania więc należy używać z rozwagą." + +#: includes/plugins.inc:19 +msgid "Default settings for this view." +msgstr "Domyślne ustawienia dla tego widoku." + +#: includes/plugins.inc:33 +msgid "Display the view as a page, with a URL and menu links." +msgstr "Wyświetl widok jako stronę, z URLem i menu." + +#: includes/plugins.inc:44;53 +msgid "Block" +msgstr "Blok" + +#: includes/plugins.inc:45 +msgid "Display the view as a block." +msgstr "Wyświetl widok jako blok." + +#: includes/plugins.inc:57 +msgid "Attachment" +msgstr "Załącznik" + +#: includes/plugins.inc:58 +msgid "Attachments added to other displays to achieve multiple views in the same view." +msgstr "Załączniki dołączone do tego podglądu tworzą wiele widoków w jednym." + +#: includes/plugins.inc:66 +msgid "Display the view as a feed, such as an RSS feed." +msgstr "Wyświetl widok jako kanał, np. RSS." + +#: includes/plugins.inc:78;124 +msgid "Unformatted" +msgstr "Niesformatowany" + +#: includes/plugins.inc:79 +msgid "Displays rows one after another." +msgstr "Wyświetl rzędy jeden po drugim." + +#: includes/plugins.inc:89 +msgid "Displays rows as an HTML list." +msgstr "Wyświetl rzędy jako liste HTML." + +#: includes/plugins.inc:97 +msgid "Grid" +msgstr "Siatka" + +#: includes/plugins.inc:98 +msgid "Displays rows in a grid." +msgstr "Wyświetl rzędy na siatce." + +#: includes/plugins.inc:106 +msgid "Table" +msgstr "Tabela" + +#: includes/plugins.inc:107 +msgid "Displays rows in a table." +msgstr "Wyświetl rzędy w tabeli." + +#: includes/plugins.inc:117 +msgid "Displays the default summary summary as a list." +msgstr "Wyświetl domyślnie podumowanie jako listę." + +#: includes/plugins.inc:125 +msgid "Displays the summary unformatted, with option for one after another or inline." +msgstr "Wyświetl podsumowanie nie formatując, z opcją \"jeden po drugim\" lub wyrównane." + +#: includes/plugins.inc:132 +msgid "RSS Feed" +msgstr "Kanał RSS" + +#: includes/plugins.inc:133 +msgid "Generates an RSS feed from a view." +msgstr "Generuje kanały RSS z widoku." + +#: includes/plugins.inc:143 +#: includes/view.inc:1663 +msgid "Fields" +msgstr "Pola" + +#: includes/plugins.inc:144 +msgid "Displays the fields with an optional template." +msgstr "Wyświetl pola w opcjonalnym szablonie." + +#: includes/plugins.inc:154 +msgid "Fixed entry" +msgstr "Stały wpis" + +#: includes/plugins.inc:158;164 +msgid "PHP Code" +msgstr "Kod PHP" + +#: includes/plugins.inc:168 +msgid "Numeric" +msgstr "Numeryczny" + +#: includes/plugins.inc:783 +msgid "Broken field" +msgstr "Uszkodzone pole" + +#: includes/plugins.inc:800 +msgid "Basic settings" +msgstr "Ustawienia podstawowe" + +#: includes/plugins.inc:807 +msgid "Change the name of this display." +msgstr "Zmień nazwę podglądu." + +#: includes/plugins.inc:819 +msgid "Change the title that this display will use." +msgstr "Zmień na tytuł którego podgląd będzie używał." + +#: includes/plugins.inc:829 +msgid "Style" +msgstr "Styl" + +#: includes/plugins.inc:831 +msgid "Change the style plugin." +msgstr "Zmień plugin stylu." + +#: includes/plugins.inc:845 +msgid "Row style" +msgstr "Styl rzędu" + +#: includes/plugins.inc:847 +msgid "Change the row plugin." +msgstr "Zmień plugin rzędu." + +#: includes/plugins.inc:857 +msgid "Use AJAX" +msgstr "Użyj AJAXa" + +#: includes/plugins.inc:859 +msgid "Change whether or not this display will use AJAX." +msgstr "Wybierz czy podgląd ma używać AJAXa czy nie." + +#: includes/plugins.inc:866 +msgid "Use pager" +msgstr "Użyj podziału na strony" + +#: includes/plugins.inc:867 +msgid "Mini" +msgstr "Mini" + +#: includes/plugins.inc:868 +msgid "Change this display's pager setting." +msgstr "Zmień ustawienia podziału na strony dla podglądu." + +#: includes/plugins.inc:875;1054 +msgid "Items per page" +msgstr "Elementów na stronę" + +#: includes/plugins.inc:875;1054;3339 +msgid "Items to display" +msgstr "Elementy do wyświetlenia" + +#: includes/plugins.inc:876 +msgid "Unlimited" +msgstr "Nieograniczone" + +#: includes/plugins.inc:877 +msgid "Change how many items to display." +msgstr "Zmień ile elementów wyświetlać." + +#: includes/plugins.inc:883 +msgid "More link" +msgstr "Więcej odnosników" + +#: includes/plugins.inc:885 +msgid "Specify whether this display will provide a \"more\" link." +msgstr "Określa, czy podgląd ma wyświetlać \"więcej...\" odnośników" + +#: includes/plugins.inc:891;1081 +msgid "Distinct" +msgstr "Niepowtarzalne" + +#: includes/plugins.inc:893;1078 +msgid "Display only distinct items, without duplicates." +msgstr "Wyświetla liste elementów bez duplikatów." + +#: includes/plugins.inc:904;1104 +msgid "Unrestricted" +msgstr "Nieograniczone" + +#: includes/plugins.inc:912 +msgid "Multiple roles" +msgstr "Wiele ról" + +#: includes/plugins.inc:924 +msgid "Access" +msgstr "Dostęp" + +#: includes/plugins.inc:926 +msgid "Specify access control settings for this display." +msgstr "Określa, sposób dostępu do ustawień dla tego podglądu." + +#: includes/plugins.inc:946 +msgid "Link display" +msgstr "Powiąż z podglądem" + +#: includes/plugins.inc:948 +msgid "Specify which display this display will link to." +msgstr "Określa, który podgląd odnosi się do tego podglądu." + +#: includes/plugins.inc:953;1143 +msgid "Header" +msgstr "Nagłówek" + +#: includes/plugins.inc:953;1159 +msgid "Footer" +msgstr "Stopka" + +#: includes/plugins.inc:953;1175 +msgid "Empty text" +msgstr "Pusty tekst" + +#: includes/plugins.inc:969 +msgid "Unknown/missing filter" +msgstr "Nieznany/Utracony filtr" + +#: includes/plugins.inc:977 +msgid "Change this display's !name." +msgstr "Zmień nazwe podglądu !name." + +#: includes/plugins.inc:983 +msgid "Theme" +msgstr "Skórka" + +#: includes/plugins.inc:984 +msgid "Information" +msgstr "Informacja" + +#: includes/plugins.inc:985 +msgid "Get information on how to theme this display" +msgstr "Pobiera informację jak skórka ma wyświetlać ten podgląd" + +#: includes/plugins.inc:1011 +msgid "The name of this display" +msgstr "Nazwa podglądu" + +#: includes/plugins.inc:1014 +msgid "This title will appear only in the administrative interface for the View." +msgstr "Ten tytuł ukaże się tylko w panelu administracyjnym Widoków." + +#: includes/plugins.inc:1019 +msgid "The title of this view" +msgstr "Tytuł tego widoku" + +#: includes/plugins.inc:1022 +msgid "This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc." +msgstr "Ten tytuł będzie wyświetlany z widokiem wszędzie tam, gdzie tytuły sa normalnie wyświetlane; Na przykład Tytuł strony czy Tytuł bloku." + +#: includes/plugins.inc:1027 +msgid "Use AJAX when available to load this view" +msgstr "Użyj AJAXa do ładowania tego widoku jeśli dostępny" + +#: includes/plugins.inc:1031 +msgid "If set, this view will use an AJAX mechanism for paging, table sorting and exposed filters. This means the entire page will not refresh. It is not recommended that you use this if this view is the main content of the page as it will prevent deep linking to specific pages, but it is very useful for side content." +msgstr "Jeśli zaznaczysz to pole, widok będzie używał AJAXa do dzielenia widoku na strony, sortowania tabel i pokazywania filtrów. Oznacza to, że strona nie będzie kompletnie odświeżana. Nie poleca się używania dla głównej treści strony, może zapobiegać głębokiemu linkowaniu specyficznych stron, ale jest bardzo użyteczne dla zawartości strony." + +#: includes/plugins.inc:1040 +msgid "Use a pager for this view" +msgstr "Użyj podziału na strony dla tego widoku" + +#: includes/plugins.inc:1043 +msgid "Full pager" +msgstr "Wszystkie opcje" + +#: includes/plugins.inc:1043 +msgid "Mini pager" +msgstr "Podstawowe opcje" + +#: includes/plugins.inc:1048 +msgid "Pager element" +msgstr "Pager element" + +#: includes/plugins.inc:1049 +msgid "Unless you're experiencing problems with pagers related to this view, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible." +msgstr "Dopóki podział na strony działa, powinieneś ustawić wartośc na 0. Jeśli używasz wielu podziałów stron na jednej stronie, powinienes ustawić wartość na większą nie kolidującą z ?page= array. Duża wartośc doda wiele przecinków w Twoim URLu, więc unikaj takiego rozwiązania jeśli to możliwe." + +#: includes/plugins.inc:1058 +msgid "The number of items to display per page. Enter 0 for no limit." +msgstr "Liczba elementów wyświetlanych na stronie. 0 - bez limitu." + +#: includes/plugins.inc:1063 +msgid "Offset" +msgstr "Przesunięcie" + +#: includes/plugins.inc:1064 +msgid "The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed. Offset can not be used if items to display is 0; instead use a very large number there." +msgstr "Liczba elementów do pominięcia. Dla przykładu jeśli pole jest ustawione na 3, to 3 pierwsze elementy będa pominięte i nie będą wyświetlone. Przesunięcie nie może byc użyte jeżeli elementów nie ma; zamiast używania wielkich liczb tutaj. " + +#: includes/plugins.inc:1069 +msgid "Add a more link to the bottom of the display." +msgstr "Dodaj więcej odnośników w dolnej częsci podglądu." + +#: includes/plugins.inc:1072 +msgid "Create more link" +msgstr "Utwórz więcej odnosników" + +#: includes/plugins.inc:1073 +msgid "This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' above." +msgstr "Dodaje więcej odnosników w dolnej częsci widoku, które odnoszą się do strony widoku. Jeśli masz więcej niż jedną stronę widoków, odnośnik będzie się odnosił do podglądu określonego w 'Powiąż z podglądem' powyżej." + +#: includes/plugins.inc:1082 +msgid "This will make the view display only distinct items. If there are multiple identical items, each will be displayed only once. You can use this to try and remove duplicates from a view, though it does not always work. Note that this can slow queries down, so use it with caution." +msgstr "Tworzy widok podglądu elementów niepowtarzających się. Jeśli masz wiele elementów identycznych, każdy zostanie wyświetlony tylko raz. Możesz tego użyć do usuwania powtarzających się widoków jednakże nie zawsze sie udaje. Uwaga operacja może spowolnić wykonywanie się zapytań, proszę używać ostrożnie." + +#: includes/plugins.inc:1087 +msgid "Access restrictions" +msgstr "Ograniczenie dostępu" + +#: includes/plugins.inc:1104 +msgid "By role" +msgstr "Przez rolę" + +#: includes/plugins.inc:1104 +msgid "By permission" +msgstr "Przez uprawnienia" + +#: includes/plugins.inc:1113 +msgid "If by role" +msgstr "Jeśli przez role" + +#: includes/plugins.inc:1116 +msgid "Only the checked roles will be able to access this display. Note that users with \"access all views\" can see any view, regardless of role." +msgstr "Tylko zaznaczone rolę będą miały dostęp do podglądu. Uwaga, użytkownicy z \"dostępem do wszystkich widoków\" będą mogli zobaczyć dowolny widok bez względu na rolę." + +#: includes/plugins.inc:1133 +msgid "If by permission" +msgstr "Jeśli przez uprzenienia" + +#: includes/plugins.inc:1135 +msgid "Only users with the selected permission flag will be able to access this display. Note that users with \"access all views\" can see any view, regardless of other permissions." +msgstr "Dostęp do podglądu będą mieć tylko użytkownicy z zaznaczonym dostępem. Uwaga, użytkownicy z \"Dostęp do wszystkich widoków\" będą widzieć wszystkie widoki bez względu na inne ustawienia dostępu. " + +#: includes/plugins.inc:1146;1162 +msgid "Display even if view has no result" +msgstr "Wyświetl nawet gdy widok nie zawiera danych" + +#: includes/plugins.inc:1153 +msgid "Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional." +msgstr "Tekst wyświetlany na górze widoku. Może zawierać opis albo odnośniki, co tylko chcesz. Ustawienie opcjonalne." + +#: includes/plugins.inc:1169 +msgid "Text to display beneath the view. May contain an explanation or links or whatever you like. Optional." +msgstr "Tekst wyświetlany poniżej widoku. Może zawierać opis albo odnośniki, co tylko chcesz. Ustawienie opcjonalne." + +#: includes/plugins.inc:1180 +msgid "Text to display if the view has no results. Optional." +msgstr "Tekst wyświetlany w przypadku braku danych w widoku. Ustawienie opcjonalne." + +#: includes/plugins.inc:1186 +msgid "How should this view be styled" +msgstr "Jakiego stylu powinieneś użyć dla tego widoku" + +#: includes/plugins.inc:1192 +msgid "If the style you choose has settings, be sure to click the settings button that will appear next to it in the View summary." +msgstr "Jeśli styl który wybrałes ma ustawienia, upewnij się że przycisk ustawień pojawił się obok Widoku podsumowań." + +#: includes/plugins.inc:1200 +msgid "You may also adjust the !settings for the currently selected style by clicking on the icon." +msgstr "Powinieneś również dostosować !settings obecnie wybrany styl poprzez klinięcie na ikonkę." + +#: includes/plugins.inc:1200;1242 +msgid "settings" +msgstr "ustawienia" + +#: includes/plugins.inc:1206 +msgid "Style options" +msgstr "Opcje stylów" + +#: includes/plugins.inc:1218 +msgid "Row style options" +msgstr "Opcje stylu rzędów" + +#: includes/plugins.inc:1230 +msgid "How should each row in this view be styled" +msgstr "Jakiego stylu każdy rząd danych ma używać" + +#: includes/plugins.inc:1242 +msgid "You may also adjust the !settings for the currently selected row style by clicking on the icon." +msgstr "Powinieneś również dostosować !settings obecnie wybrany styl rzędu danych poprzez klinięcie na ikonkę." + +#: includes/plugins.inc:1248 +msgid "Which display to use for path" +msgstr "Którego podglądu użyć dla ściezki" + +#: includes/plugins.inc:1257 +msgid "Which display to use to get this display's path for things like summary links, rss feed links, more links, etc." +msgstr "Którego podglądu użyć aby otrzymać scieżkę podglądu dla odnośników do danych takich jak : podsumowanie, kanały RSS, więcej odnośników itd." + +#: includes/plugins.inc:1262 +msgid "Theming information" +msgstr "Informacje o skórkach" + +#: includes/plugins.inc:1270 +msgid "Display output" +msgstr "Wygląd podglądu" + +#: includes/plugins.inc:1275 +msgid "Style output" +msgstr "Wygląd stylu" + +#: includes/plugins.inc:1280 +msgid "Row style output" +msgstr "Wygląd lini tekstu" + +#: includes/plugins.inc:1286 +msgid "Field @field" +msgstr "Pole @field" + +#: includes/plugins.inc:1294 +msgid "<strong>Important!</strong> When you add a new template to your theme, be sure to clear the theme registry cache. You can do this by visiting administer >> site building >> themes -- just loading the page should clear the cache." +msgstr "<strong>Ważne!</strong> Kiedy dodajesz nowy szablon do skórki, upewnij się że wyczyściłes pamięć podręczną skórki. Możesz tego dokonać wchodząć w ustawienia >> Zarządzaj >> Budowa witryny >> Skórki -- właściwe łądowanie strony powinno oczyścić pamięć podręczną." + +#: includes/plugins.inc:1306 +msgid "Theming information (display)" +msgstr "Informacje o skórce (podgląd)" + +#: includes/plugins.inc:1307;1326;1347;1368 +msgid "Back to !info." +msgstr "Wróć do !info" + +#: includes/plugins.inc:1307;1326;1347;1368 +msgid "theming information" +msgstr "informacje o tworzeniu skórek" + +#: includes/plugins.inc:1310 +msgid "This display has no theming information" +msgstr "Ten podgląd nie posiada informacji o tworzeniu skórek" + +#: includes/plugins.inc:1313 +msgid "This is the default theme template used for this display." +msgstr "To jest domyslny szablon skórki używanej w tym podglądzie." + +#: includes/plugins.inc:1325 +msgid "Theming information (style)" +msgstr "Informację o tworzeniu skórki (styl)" + +#: includes/plugins.inc:1331 +msgid "This display has no style theming information" +msgstr "Ten podgląd nie posiada informacji o stylach skórek" + +#: includes/plugins.inc:1334 +msgid "This is the default theme template used for this style." +msgstr "Domyslna skórka używana w tym szablonie dla tego stylu." + +#: includes/plugins.inc:1346;1367 +msgid "Theming information (row style)" +msgstr "Informacje o tworzeniu skórki (styl lini tekstu)" + +#: includes/plugins.inc:1352 +msgid "This display has no row style theming information" +msgstr "Ten podgląd nie ma informacji o tworzeniu skórek dla wierszy tabel" + +#: includes/plugins.inc:1355;1370 +msgid "This is the default theme template used for this row style." +msgstr "To jest domyślny szablon skórki dla tego stylu lini danych" + +#: includes/plugins.inc:1434 +msgid "You must select at least one role if type is \"by role\"" +msgstr "Musisz wybrać przynajmniej jedną rolę gdy typ jest \"przez rolę\"" + +#: includes/plugins.inc:1551 +msgid "Override" +msgstr "Nadpisz" + +#: includes/plugins.inc:1563 +msgid "Use default" +msgstr "Użyj domślnych" + +#: includes/plugins.inc:1756 +msgid "Display @display uses fields but there are none defined for it." +msgstr "Podgląd @display używa pól, ale żadne nie jest zdefiniowane." + +#: includes/plugins.inc:1760 +msgid "Display @display uses path but path is undefined." +msgstr "Podgląd @display używa ścieżki ale żadna nie jest zdefiniowana." + +#: includes/plugins.inc:1765 +msgid "Display @display has an invalid style plugin." +msgstr "Podgląd @display ma nieprawidłowy plugin stylu." + +#: includes/plugins.inc:1994 +msgid "Page settings" +msgstr "Ustawienia strony" + +#: includes/plugins.inc:2019 +msgid "No menu" +msgstr "Brak menu" + +#: includes/plugins.inc:2022 +msgid "Normal: @title" +msgstr "Zwykły: @title" + +#: includes/plugins.inc:2026 +msgid "Tab: @title" +msgstr "Zakładka: @tab" + +#: includes/plugins.inc:2036 +msgid "Menu" +msgstr "Menu" + +#: includes/plugins.inc:2042 +msgid "Change settings for the parent menu" +msgstr "Zmień ustawienia dla nadrzędnego menu" + +#: includes/plugins.inc:2055 +msgid "The menu path or URL of this view" +msgstr "Ścieżka menu albo URL tego widoku" + +#: includes/plugins.inc:2059 +msgid "This view will be displayed by visiting this path on your site. You may use \"%\" in your URL to represent values that will be used for arguments: For example, \"node/%/feed\"." +msgstr "Widok będzie wyświetlony przez odwiedzenie tej ścieżki na Twojej stronie. Możesz użyć \"%\" w URLu reprezentując wartości użyte dla argumentów: Na przykład, \"node/%/feed\"." + +#: includes/plugins.inc:2065 +msgid "Menu item entry" +msgstr "Lista elementów menu" + +#: includes/plugins.inc:2082 +msgid "No menu entry" +msgstr "Brak listy elementów menu" + +#: includes/plugins.inc:2083 +msgid "Normal menu entry" +msgstr "Zwykły wpis w menu" + +#: includes/plugins.inc:2084;2131 +msgid "Menu tab" +msgstr "Zakładka menu" + +#: includes/plugins.inc:2085 +msgid "Default menu tab" +msgstr "Domyslna zakładka menu" + +#: includes/plugins.inc:2094 +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "Wprowadź tekst by użyć elementu menu, gdy menu jest zwykłe lub gdy jest zakładką." + +#: includes/plugins.inc:2103 +msgid "If set to tab, enter the weight of the item. The lower th weight the higher/further left it will appear." +msgstr "Wpisz wagę elementu gdy przypisujesz zakładce. Im mniejsza waga tym zakładka pojawi się bardziej z lewej strony." + +#: includes/plugins.inc:2109 +msgid "Default tab options" +msgstr "Domyślne opcje zakładek" + +#: includes/plugins.inc:2118 +msgid "When providing a menu item as a 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>." +msgstr "Kiedy dostarczamy menu jako zakłądki, Drupal musi wiedzieć jaki będzie element nadrzędny menu zakładki. Czasami element nadrzędny istnieje, ale czasami będzie trzeba go utworzyć. Ścieżką elementu nadrzędnego zawsze będzie częścią powstałą przez odłączenie ostatniego fragmentu ścieżki podrzędnej. Na przykład ścieżka do widoku jest: </em>foo/bar/baz</em> nadrzędną ścieżka będzie <em>foo/bar</em>." + +#: includes/plugins.inc:2129 +msgid "Parent menu item" +msgstr "Nadrzędny element menu" + +#: includes/plugins.inc:2131 +msgid "Already exists" +msgstr "Już istnieje" + +#: includes/plugins.inc:2131 +msgid "Normal menu item" +msgstr "Standardowy element menu" + +#: includes/plugins.inc:2139 +msgid "If creating a parent menu item, enter the title of the item." +msgstr "Gdy dodajesz element nadrzędny menu, wprowadź jego tytuł." + +#: includes/plugins.inc:2145 +msgid "Tab weight" +msgstr "Waga zakładki" + +#: includes/plugins.inc:2149 +msgid "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." +msgstr "Gdy element nadrzędny menu jest zakładką, wprowadź jej wagę. Im mniejszy numer, tym bardziej będzie z lewej." + +#: includes/plugins.inc:2163 +msgid "\"$arg\" is no longer supported. Use % instead." +msgstr "\"$arg\" już nie używamy. Użyj w zamian %. " + +#: includes/plugins.inc:2173 +msgid "Views cannot create normal menu items for paths with a % in them." +msgstr "Widok nie może tworzyć standardowych elementów menu dla ścieżek z % w nich." + +#: includes/plugins.inc:2180 +msgid "A display whose path ends with a % cannot be a tab." +msgstr "Wyświetla które ścieżki kończące się % nie mogą być zakładką." + +#: includes/plugins.inc:2185 +msgid "Title is required for this menu type." +msgstr "Tytuł jest wymagany dla tego typu menu" + +#: includes/plugins.inc:2216 +msgid "Display @display is set to use a menu but the menu title is not set." +msgstr "Podgląd @display jest ustawiony tak, by używać tytułu menu ale tytuł nie został ustawiony." + +#: includes/plugins.inc:2222 +msgid "Display @display is set to use a parent menu but the parent menu title is not set." +msgstr "Podgląd @display jest ustawiony by używać nadrzędnego menu, ale tytuł elementu menu nie został ustawiony." + +#: includes/plugins.inc:2288 +msgid "Block settings" +msgstr "Ustawienia Bloków" + +#: includes/plugins.inc:2302 +msgid "Admin" +msgstr "Admin" + +#: includes/plugins.inc:2314 +msgid "Caching" +msgstr "Zapis do pamięci podręcznej" + +#: includes/plugins.inc:2324 +msgid "Do not cache" +msgstr "Nie zapisuj w pamięci podręcznej" + +#: includes/plugins.inc:2325 +msgid "Cache once for everything (global)" +msgstr "Jedna pamięć podręczna dla wszystkiego (globalna)" + +#: includes/plugins.inc:2326 +msgid "Per page" +msgstr "Na stronę" + +#: includes/plugins.inc:2327 +msgid "Per role" +msgstr "Na rolę" + +#: includes/plugins.inc:2328 +msgid "Per role per page" +msgstr "Na rolę na stronę" + +#: includes/plugins.inc:2329 +msgid "Per user" +msgstr "Na użytkownika" + +#: includes/plugins.inc:2330 +msgid "Per user per page" +msgstr "Na użytkownika na stronę" + +#: includes/plugins.inc:2355 +msgid "Block admin description" +msgstr "Opis bloku administracyjnego" + +#: includes/plugins.inc:2358 +msgid "This will appear as the name of this block in administer >> site building >> blocks." +msgstr "To ukaże się jako nazwa bloku w Zarządzaj >> Konfiguracja witryny >> Bloki." + +#: includes/plugins.inc:2363 +msgid "Block caching type" +msgstr "Typ pamięci podręcznej dla bloku" + +#: includes/plugins.inc:2367 +msgid "This sets the default status for Drupal's built-in block caching method; this requires that caching be turned on in block administration, and be careful because you have little control over when this cache is flushed." +msgstr "To ustawia domyslny status dla wbudowanej metody blokowego cache'owania; to wymaga by cache'owanie bylo wlaczone w bloku administracyjnym, i badz ostrozny poniewaz masz mala kontrole na tym kiedy cache jest opróżniany." + +#: includes/plugins.inc:2418 +msgid "Before" +msgstr "Przed" + +#: includes/plugins.inc:2419 +msgid "After" +msgstr "Po" + +#: includes/plugins.inc:2420 +msgid "Both" +msgstr "Oba" + +#: includes/plugins.inc:2440 +msgid "Attachment settings" +msgstr "Ustawienia załączników" + +#: includes/plugins.inc:2445;2486 +msgid "Inherit arguments" +msgstr "Dziedziczenie argumentów" + +#: includes/plugins.inc:2451;2495 +msgid "Position" +msgstr "Pozycja" + +#: includes/plugins.inc:2457;2649 +msgid "Multiple displays" +msgstr "Wiele podglądów" + +#: includes/plugins.inc:2472;2504;2664;2678 +msgid "Attach to" +msgstr "Dołącz do" + +#: includes/plugins.inc:2489 +msgid "Inherit" +msgstr "Dziedzicz" + +#: includes/plugins.inc:2490 +msgid "Should this display inherit its arguments from the parent display to which it is attached?" +msgstr "Czy podgląd ma dziedziczyć argumenty z nadrzędnego podglądu do którego jest dołączony?" + +#: includes/plugins.inc:2498;2687 +msgid "Attach before or after the parent display?" +msgstr "Dołączyć przed czy po nadrzędnym podglądzie?" + +#: includes/plugins.inc:2513 +msgid "Select which display or displays this should attach to." +msgstr "Wybierz, który lub które podglądy powinny być dołączone." + +#: includes/plugins.inc:2641 +msgid "Feed settings" +msgstr "Ustawienia kanału" + +#: includes/plugins.inc:2693 +msgid "This view will be displayed by visiting this path on your site. It is recommended that the path be something like \"path/%/%/feed\" or \"path/%/%/rss.xml\", putting one % in the path for each argument you have defined in the view." +msgstr "Ten widok będzie wyświetlany odwiedzającym tą ścieżkę w adresie Twojej strony. Poleca się by ścieżka wyglądała \"path/%/%/feed\" albo \"path/%/%/rss.xml\", umieszczamy JEDEN % w ścieżce dla każdego ze zdefiniowanych argumentów w widoku." + +#: includes/plugins.inc:2835 +msgid "Grouping field" +msgstr "Pole grupujące" + +#: includes/plugins.inc:2838 +msgid "You may optionally specify a field by which to group the records. Leave blank to not group." +msgstr "Opcjonalnie możesz okreslić pole grupujące dane. Pozostaw puste by nie grupować. " + +#: includes/plugins.inc:2923 +msgid "Style @style requires a row style but the row plugin is invalid." +msgstr "Styl @style wymaga stylu wiersza tabeli, a plugin wiersza tabeli jest niewłaściwy." + +#: includes/plugins.inc:2970 +msgid "List type" +msgstr "Typ listy" + +#: includes/plugins.inc:3000 +msgid "Number of columns" +msgstr "Liczba kolumn" + +#: includes/plugins.inc:3005 +msgid "Alignment" +msgstr "Wyrównanie" + +#: includes/plugins.inc:3006 +msgid "Horizontal" +msgstr "Poziomo" + +#: includes/plugins.inc:3006 +msgid "Vertical" +msgstr "Pionowo" + +#: includes/plugins.inc:3008 +msgid "Horizontal alignment will place items starting in the upper left and moving right. Vertical alignment will place items starting in the upper left and moving down." +msgstr "Wyrównanie poziome umieści elementy zaczynając od części lewej górnej w strone prawej. Pionowe zaś umieśi je od części lewej górnej w dół." + +#: includes/plugins.inc:3127 +msgid "You need at least one field before you can configure your table settings" +msgstr "Potrzebujesz przynajmniej jednego pola zanim zaczniesz konfigurować ustawienia tabel" + +#: includes/plugins.inc:3136 +msgid "Override normal sorting if click sorting is used" +msgstr "Nadpisz normalne sortowanie jeśli ktoś kliknął \"sortuj\"" + +#: includes/plugins.inc:3142 +msgid "Enable Drupal style \"sticky\" table headers (Javascript)" +msgstr "Włącz styl \"przyklejony\" do nagłówków tabel (JavaScript)" + +#: includes/plugins.inc:3144 +msgid "(Sticky header effects will not be active for preview below, only on live output.)" +msgstr "(Przyklejone nagłówki nie będą aktywne przy podglądzie poniżej tylko w podglądzie na żywo.)" + +#: includes/plugins.inc:3149 +msgid "Default sort order" +msgstr "Domyślne sortowanie" + +#: includes/plugins.inc:3150 +#: includes/sort.handlers.inc:60 +msgid "Ascending" +msgstr "Rosnąco" + +#: includes/plugins.inc:3150 +#: includes/sort.handlers.inc:60 +msgid "Descending" +msgstr "Malejąco" + +#: includes/plugins.inc:3152 +msgid "If a default sort order is selected, what order should it use by default." +msgstr "Jakie sortowanie ma być stosowane domyślnie gdy zaznaczymy sorotwanie domyślne." + +#: includes/plugins.inc:3238 +msgid "Place fields into columns; you may combine multiple fields into the same column. If you do, the separator in the column specified will be used to separate the fields. Check the sortable box to make that column clicksortable, and check the default sort radio to determine which column will be sorted by default, if any. You may control column order and field labels in the fields section." +msgstr "Umieść pola w kolumnach; możesz ustawić wiele pól w tej samej kolumnie. Separator w wybranych kolumnach będzie oddzielał pola. Zaznacz pole sortowania, aby wybrać jak domyślnie dana kolumna ma być sortowana. Porządek sortowania i opisy etykiet pól możesz kontrolować w sekcji pól." + +#: includes/plugins.inc:3263 +#: includes/view.inc:1665 +msgid "Field" +msgstr "Pole" + +#: includes/plugins.inc:3264 +msgid "Column" +msgstr "Kolumna" + +#: includes/plugins.inc:3267 +msgid "Sortable" +msgstr "Sortowalny" + +#: includes/plugins.inc:3271 +msgid "Default sort" +msgstr "Standardowe sortowanie" + +#: includes/plugins.inc:3330 +msgid "Display record count with link" +msgstr "Wyświetl ilośc rekordów z odnośnikiem" + +#: includes/plugins.inc:3335 +msgid "Override number of items to display" +msgstr "Nadpisz liczbę elementów do wyświetlenia" + +#: includes/plugins.inc:3372 +msgid "Display items inline" +msgstr "Wyświetl elementy \"inline\"" + +#: includes/plugins.inc:3421 +msgid "Use the site mission for the description" +msgstr "Używaj misji strony do opisu" + +#: includes/plugins.inc:3425 +msgid "RSS description" +msgstr "Opis kanału RSS" + +#: includes/plugins.inc:3427 +msgid "This will appear in the RSS feed itself." +msgstr "To pojawi się samo w kanale RSS." + +#: includes/plugins.inc:3550 +msgid "Inline fields" +msgstr "Pola \"inline\"" + +#: includes/plugins.inc:3553 +msgid "Inline fields will be displayed next to each other rather than one after another." +msgstr "Pola \"inline\" będą wyświetlone obok siebie względnie jedno pod drugim." + +#: includes/plugins.inc:3561 +msgid "The separator may be placed between inline fields to keep them from squishing up next to each other. You can use HTML in this field." +msgstr "Separator może być umiejscowiony pomiędzy polami \"inline\" by trzymać je ściśnięte razem. W tym polu możesz użyć HTMLa." + +#: includes/plugins.inc:3611 +msgid "Default argument" +msgstr "Domyślny argument" + +#: includes/plugins.inc:3653 +msgid "PHP argument code" +msgstr "Kod argumentu PHP (PHP argument code)" + +#: includes/plugins.inc:3656 +msgid "Enter PHP code that returns a value to use for this argument. Do not use <?php ?>. You must return only a single value for just this argument." +msgstr "Wprowadź kod PHP który zwróci wartość użytą dla tego argumentu. Nie używaj <?php ?>. Musisz zwrócić tylko jedną wartość dla jednego argumentu." + +#: includes/plugins.inc:3760 +msgid "PHP validate code" +msgstr "Kod poprawności PHP" + +#: includes/plugins.inc:3762 +msgid "Enter PHP code that returns TRUE or FALSE. No return is the same as FALSE, so be SURE to return something if you do not want to declare the argument invalid. Do not use <?php ?>. The argument to validate will be \"$argument\" and the view will be \"$view\". You may change the argument by setting \"$handler->argument\"." +msgstr "Ten kod zwraca PRAWDĘ (true) lub FAŁSZ(false). Brak zwróconej wartości jest równoznaczny z FAŁSZem więć upewnij się że zwracasz coś by deklarować argument właściwie. Nie używaj <?php ?>. Argument mozna sprawdzić wpisując \"$argument\" , widok \"$view\". Możesz zmienić argument poprzez ustawienie \"$handler->argument\"." + +#: includes/relationship.handlers.inc:62 +msgid "The label for this relationship that will be displayed only administratively." +msgstr "Etykieta dla tego powiązania, która będzie wyświetlana tylko w trybie administracji." + +#: includes/relationship.handlers.inc:67 +msgid "Require this relationship" +msgstr "Wymaga zalezności" + +#: includes/relationship.handlers.inc:68 +msgid "If required, items that do not contain this relationship will not appear." +msgstr "Gdy wymagane, elementy niezawierające tej relacji nie ukażą się." + +#: includes/sort.handlers.inc:43 +msgid "asc" +msgstr "asc" + +#: includes/sort.handlers.inc:47 +msgid "desc" +msgstr "desc" + +#: includes/sort.handlers.inc:59 +msgid "Sort order" +msgstr "Kolejność sortowania" + +#: includes/sort.handlers.inc:76 +msgid "views_handler_sort_formula missing default: @formula" +msgstr "views_handler_sort_formula utracona domyślnie: @formula" + +#: includes/sort.handlers.inc:116 +msgid "Granularity" +msgstr "Ziarnistość" + +#: includes/sort.handlers.inc:118 +msgid "Second" +msgstr "Drugi" + +#: includes/sort.handlers.inc:119 +msgid "Minute" +msgstr "Minuta" + +#: includes/sort.handlers.inc:120 +msgid "Hour" +msgstr "Godzina" + +#: includes/sort.handlers.inc:121 +msgid "Day" +msgstr "Dzień" + +#: includes/sort.handlers.inc:122 +msgid "Month" +msgstr "Miesiąc" + +#: includes/sort.handlers.inc:123 +msgid "Year" +msgstr "Rok" + +#: includes/sort.handlers.inc:125 +msgid "The granularity is the smallest unit to use when determining whether two dates are the same; for example, if the granularity is \"Year\" then all dates in 1999, regardless of when they fall in 1999, will be considered the same date." +msgstr "Ziarnistość jest najmniejszą jednostką używaną do określenia czy dwie daty są takie same; na przykład gdy ziarnistością jest \"Rok\" to wszystkie daty zawierające 1999 będą traktowane jako jedna data." + +#: includes/view.inc:224 +msgid "set_display called with invalid display id @display" +msgstr "set_display wołany z nieprawidłowym ID Podglądu @display" + +#: includes/view.inc:946 +msgid "Home" +msgstr "Start" + +#: includes/view.inc:1664 +msgid "fields" +msgstr "pola" + +#: includes/view.inc:1666 +msgid "field" +msgstr "pole" + +#: includes/view.inc:1671 +msgid "arguments" +msgstr "argumenty" + +#: includes/view.inc:1672;1673 +msgid "Argument" +msgstr "Argument" + +#: includes/view.inc:1677 +msgid "Sort criteria" +msgstr "Kryteria sortowania" + +#: includes/view.inc:1678 +msgid "sort criteria" +msgstr "kryteria sortowania" + +#: includes/view.inc:1679 +msgid "Sort criterion" +msgstr "Kryterium sortowania" + +#: includes/view.inc:1680 +msgid "sort criterion" +msgstr "kryterium sortowania" + +#: includes/view.inc:1684 +msgid "Filters" +msgstr "Filtry" + +#: includes/view.inc:1685 +msgid "filters" +msgstr "filtry" + +#: includes/view.inc:1686 +msgid "Filter" +msgstr "Filtr" + +#: includes/view.inc:1687 +msgid "filter" +msgstr "filtr" + +#: includes/view.inc:1692 +msgid "Relationships" +msgstr "Zależności" + +#: includes/view.inc:1693 +msgid "relationships" +msgstr "zależności" + +#: js/ajax.js:0;0;0;0;0;0;0 +#: js/ajax_view.js:0;0;0 +msgid "An error occurred at " +msgstr "Błąd wystąpił w " + +#: js/tabs.js:0 +msgid "jQuery UI Tabs: Mismatching fragment identifier." +msgstr "jQuery UI Tabs: Niepasujący fragment identyfikatora." + +#: js/tabs.js:0 +msgid "jQuery UI Tabs: Not enough arguments to add tab." +msgstr "jQuery UI Tabs: Za mało argumentów by dodać zakładkę." + +#: modules/book.views.inc:21;36;46;99 +msgid "Book" +msgstr "Książka" + +#: modules/book.views.inc:30 +msgid "Top level book" +msgstr "Najwyższy poziom książki" + +#: modules/book.views.inc:31 +msgid "The book the node is in" +msgstr "Książka w której jest segment" + +#: modules/book.views.inc:58 +msgid "The weight of the book page." +msgstr "Waga strony książki" + +#: modules/book.views.inc:69 +#: modules/comment.views.inc:202 +#: modules/taxonomy.views.inc:339 +msgid "Depth" +msgstr "Głębokość" + +#: modules/book.views.inc:70 +msgid "The depth of the book page in the hierarchy; top level books have a depth of 1." +msgstr "Głębokość strony książki w hierarchi; książki najwyższego poziomu mają głębokość 1." + +#: modules/book.views.inc:87 +msgid "Hierarchy" +msgstr "Hierarchia" + +#: modules/book.views.inc:88 +msgid "The order of pages in the book hierarchy. Remember to sort by weight too if you want exactly the right order." +msgstr "Kolejność stron w hierarchi książki. Pamiętaj by sortować po wadze również jeśli chcesz mieć właściwie posortowane." + +#: modules/book.views.inc:110 +msgid "Parent" +msgstr "Nadrzędny" + +#: modules/book.views.inc:111 +msgid "The parent book node" +msgstr "Nadrzędny segment książki" + +#: modules/book.views.inc:116 +msgid "Book parent" +msgstr "Rodzic książki" + +#: modules/comment.views.inc:22;26;382;391 +msgid "Comment" +msgstr "Komentarz" + +#: modules/comment.views.inc:27 +msgid "Comments are responses to node content." +msgstr "Komentarze są odpowiedziami na zawartość segmentów." + +#: modules/comment.views.inc:45 +msgid "The title of the comment." +msgstr "Tytuł komentarza" + +#: modules/comment.views.inc:63 +#: modules/node.views.inc:348 +msgid "Body" +msgstr "Treść" + +#: modules/comment.views.inc:64 +msgid "The text of the comment." +msgstr "Tekst komentarza" + +#: modules/comment.views.inc:76 +msgid "ID" +msgstr "ID" + +#: modules/comment.views.inc:77 +msgid "The commment ID of the field" +msgstr "ID komentarza pola" + +#: modules/comment.views.inc:95 +msgid "Author" +msgstr "Autor" + +#: modules/comment.views.inc:96 +msgid "The name of the poster." +msgstr "Imie nadsyłającego." + +#: modules/comment.views.inc:114 +msgid "Author's website" +msgstr "Adres strony nadsyłającego" + +#: modules/comment.views.inc:115 +msgid "The website address of the comment's author. Can be a link. The homepage can also be linked with the Name field. Will be empty if posted by a registered user." +msgstr "Adres strony domowej autora. Może być odnośnikiem. Pole nazwy użytkownika również może być odnośnikiem do strony domowej. Pozostanie puste w przypadku gdy nadsyłającym jest użytkownik zarejestrowany." + +#: modules/comment.views.inc:133 +#: modules/node.views.inc:107 +msgid "Post date" +msgstr "Data nadesłania" + +#: modules/comment.views.inc:134 +msgid "Date and time of when the comment was posted." +msgstr "Data i czas wysłania komentarza." + +#: modules/comment.views.inc:149 +msgid "In moderation" +msgstr "W moderacji" + +#: modules/comment.views.inc:150 +msgid "Whether or not the comment is currently in moderation." +msgstr "Czy ten komentarz jest obecnie moderowany czy nie." + +#: modules/comment.views.inc:157 +msgid "Moderated" +msgstr "Moderowane" + +#: modules/comment.views.inc:167 +msgid "View link" +msgstr "Podgląd" + +#: modules/comment.views.inc:168 +msgid "Provide a simple link to view the comment." +msgstr "Dostarcza prosty odnośnik do podglądania komentarzy." + +#: modules/comment.views.inc:176 +#: modules/node.views.inc:231 +#: modules/user.views.inc:204 +msgid "Edit link" +msgstr "Edytuj" + +#: modules/comment.views.inc:177 +msgid "Provide a simple link to edit the comment." +msgstr "Dostarcza prosty odnośnik do edycji komentarzy" + +#: modules/comment.views.inc:185 +#: modules/node.views.inc:239;461 +#: modules/user.views.inc:212 +msgid "Delete link" +msgstr "Usuń" + +#: modules/comment.views.inc:186 +msgid "Provide a simple link to delete the comment." +msgstr "Dostarcza prosty odnośnik do usuwania komentarzy." + +#: modules/comment.views.inc:194 +msgid "Reply-to link" +msgstr "link Odpowiedz" + +#: modules/comment.views.inc:195 +msgid "Provide a simple link to reply to the comment." +msgstr "Dostarcza prosty odnośnik do odpowiedzi na komentarze." + +#: modules/comment.views.inc:203 +msgid "Display the depth of the comment if it is threaded." +msgstr "Wyświetl głebokość komentarzy gdy są w wątku." + +#: modules/comment.views.inc:207 +msgid "Thread" +msgstr "Wątek" + +#: modules/comment.views.inc:208 +msgid "Sort by the threaded order. This will keep child comments together with their parents." +msgstr "Sortuj w kolejności wątków. To pomoże trzymać podrzędne komentarze wraz z nadrzędnymi razem." + +#: modules/comment.views.inc:214 +#: modules/node.views.inc:1413 +msgid "Node ID" +msgstr "ID segmentu (Node ID)" + +#: modules/comment.views.inc:215 +msgid "The node the comment is a reply to." +msgstr "Segment do którego ten komentarz jest odpowiedzią." + +#: modules/comment.views.inc:220;253 +#: modules/node.views.inc:24;29;89;347;362;473;1178;1187;1197 +msgid "Node" +msgstr "Segment" + +#: modules/comment.views.inc:225 +msgid "User ID" +msgstr "ID użytkownika (User ID)" + +#: modules/comment.views.inc:226 +msgid "The user who wrote the comment." +msgstr "Użytkownik który napisał komentarz." + +#: modules/comment.views.inc:231 +#: modules/node.views.inc:335 +#: modules/statistics.views.inc:201 +#: modules/user.views.inc:23;27;221 +msgid "User" +msgstr "Użytkownik" + +#: modules/comment.views.inc:236 +msgid "Parent CID" +msgstr "CID rodzica (Parent CID)" + +#: modules/comment.views.inc:237 +msgid "The Comment ID of the parent comment." +msgstr "ID komentarza (Comment ID) nadrzędnego komentarza." + +#: modules/comment.views.inc:245 +msgid "Parent comment" +msgstr "Poprzednia odpowiedź" + +#: modules/comment.views.inc:266 +msgid "Last comment time" +msgstr "Ostatnio komentowane" + +#: modules/comment.views.inc:267 +msgid "Date and time of when the last comment was posted." +msgstr "Data i czas ostatniego komentarza." + +#: modules/comment.views.inc:282 +msgid "Last comment author" +msgstr "Autor ostatniego komentarza" + +#: modules/comment.views.inc:283 +msgid "The name of the author of the last posted comment." +msgstr "Dane autora ostatniego komentarza." + +#: modules/comment.views.inc:295 +msgid "Comment count" +msgstr "Liczba komentarzy" + +#: modules/comment.views.inc:296 +msgid "The number of comments a node has." +msgstr "Liczba komentarzy dla segmentu." + +#: modules/comment.views.inc:314 +msgid "Updated/commented date" +msgstr "Data aktualizacji/komentarza" + +#: modules/comment.views.inc:315 +msgid "The most recent of last comment posted or node updated time." +msgstr "Ostatni czas modyfikacji segmentu lub nadesłania komentarza." + +#: modules/comment.views.inc:338 +msgid "New comments" +msgstr "Nowe komentarze" + +#: modules/comment.views.inc:339 +msgid "The number of new comments on the node." +msgstr "Liczba nowych komentarzy w segmencie." + +#: modules/comment.views.inc:347 +msgid "Comment status" +msgstr "Status komentarza" + +#: modules/comment.views.inc:348 +msgid "Whether comments are enabled or disabled on the node." +msgstr "Czy komentarze w segmencie mają być włączone czy też nie." + +#: modules/comment.views.inc:362 +msgid "User posted or commented" +msgstr "Użytkownik nadesłał lub komentował" + +#: modules/comment.views.inc:363 +msgid "Display comments only if a user posted the node or commented on the node." +msgstr "Wyświetl komentarze jedynie gdy użytkownik wysłał lub komentował segment." + +#: modules/comment.views.inc:383 +msgid "Display the comment with standard comment view." +msgstr "Wyświetl komentarz w standardowym widoku komentarza." + +#: modules/comment.views.inc:392 +msgid "Display the comment as RSS." +msgstr "Wyświetl komentarz jako kanał RSS." + +#: modules/comment.views.inc:462 +msgid "Link this field to its comment" +msgstr "Podlinkuj to pole do jego komentarza" + +#: modules/comment.views.inc:506 +msgid "Link this field to its user or an author's homepage" +msgstr "Podlinkuj to pole do jego użytkownika lub strony domowej autora" + +#: modules/comment.views.inc:553 +#: modules/node.views.inc:601 +#: modules/user.views.inc:447 +msgid "Text to display" +msgstr "Tekst do wyświetlenia" + +#: modules/comment.views.inc:564 +#: modules/node.views.inc:612 +#: modules/user.views.inc:463 +msgid "view" +msgstr "przeglądaj" + +#: modules/comment.views.inc:589 +#: modules/node.views.inc:643 +#: modules/user.views.inc:481 +msgid "edit" +msgstr "edytuj" + +#: modules/comment.views.inc:605 +#: modules/node.views.inc:673;752 +#: modules/user.views.inc:499 +msgid "delete" +msgstr "usuń" + +#: modules/comment.views.inc:621 +msgid "reply" +msgstr "powtórz" + +#: modules/comment.views.inc:764 +msgid "Link this field to new comments" +msgstr "Podlinkuj to pole do \"nowe komentarze\"" + +#: modules/comment.views.inc:769 +msgid "Display nothing if no new comments" +msgstr "Nie wyświetlaj nic, gdy nie ma odpowiedzi" + +#: modules/comment.views.inc:836 +#: modules/user.views.inc:606 +msgid "Anonymous" +msgstr "Anonimowy" + +#: modules/comment.views.inc:842 +msgid "No user" +msgstr "Brak użytkownika" + +#: modules/comment.views.inc:878;895 +msgid "Disabled" +msgstr "Wyłączone" + +#: modules/comment.views.inc:880;896 +msgid "Read only" +msgstr "Tylko do odczytu" + +#: modules/comment.views.inc:882;897 +msgid "Read/Write" +msgstr "Odczyt/Zapis" + +#: modules/comment.views.inc:917 +#: modules/node.views.inc:1235 +msgid "Display links" +msgstr "Wyświetlaj odnosniki" + +#: modules/node.views.inc:30 +msgid "Nodes are a Drupal site's primary content." +msgstr "Segmenty są główną zawartością stron w Drupalu." + +#: modules/node.views.inc:57 +msgid "Nid" +msgstr "Nid" + +#: modules/node.views.inc:58 +msgid "The node ID of the node." +msgstr "ID segmentu" + +#: modules/node.views.inc:85;403 +msgid "The title of the node." +msgstr "Tytuł segmentu." + +#: modules/node.views.inc:108 +msgid "The date the node was posted." +msgstr "Data wysłania segmentu." + +#: modules/node.views.inc:123 +msgid "Updated date" +msgstr "Data uaktualnienia" + +#: modules/node.views.inc:124 +msgid "The date the node was last updated." +msgstr "Data ostatniej aktualizacji segmentu." + +#: modules/node.views.inc:140 +msgid "The type of a node (for example, \"blog entry\", \"forum post\", \"story\", etc)." +msgstr "Typ segmentu (np. \"blog entry\", \"forum post\", \"story\", etc)." + +#: modules/node.views.inc:158;166;180 +#: modules/upload.views.inc:74 +msgid "Published" +msgstr "Opublikowany" + +#: modules/node.views.inc:159 +msgid "The published status of the node." +msgstr "Opublikowany status segmentu." + +#: modules/node.views.inc:175 +msgid "Published or admin" +msgstr "Opublikowany albo tryb administracji" + +#: modules/node.views.inc:176 +msgid "Filters out unpublished nodes if the current user cannot view them." +msgstr "Filtruje nieopublikowane segmenty jeśli dany użytkownik nie może ich przeglądać." + +#: modules/node.views.inc:186;194 +msgid "Promoted to front page" +msgstr "Promowany na stronie głównej" + +#: modules/node.views.inc:187 +msgid "The front page of the node." +msgstr "Strona główna segmentu." + +#: modules/node.views.inc:203;212 +msgid "Sticky" +msgstr "Przyklejony" + +#: modules/node.views.inc:204 +msgid "Whether or not the node is sticky." +msgstr "Czy segment ma być przyklejony czy nie." + +#: modules/node.views.inc:223 +msgid "Link" +msgstr "Odnośnik" + +#: modules/node.views.inc:224 +msgid "Provide a simple link to the node." +msgstr "Dostarcza prosty odnosnik do segmentu." + +#: modules/node.views.inc:232 +msgid "Provide a simple link to edit the node." +msgstr "Dostarcza prosty odnośnik do edytowania segmentu." + +#: modules/node.views.inc:240 +msgid "Provide a simple link to delete the node." +msgstr "Dostarcza prosty odnosnik do kasowania segmentu." + +#: modules/node.views.inc:248;1115 +msgid "Language" +msgstr "Język" + +#: modules/node.views.inc:249 +msgid "The language the content is in." +msgstr "Język w jakim jest treść." + +#: modules/node.views.inc:266;437 +#: modules/user.views.inc:125 +msgid "Created date" +msgstr "Data utworzenia" + +#: modules/node.views.inc:267 +msgid "In the form of CCYYMMDD." +msgstr "Format danych: CCYYMMDD" + +#: modules/node.views.inc:275 +msgid "Created year + month" +msgstr "Rok i miesiąc utworzenia" + +#: modules/node.views.inc:276 +msgid "In the form of YYYYMM." +msgstr "Format danych: YYYYMM." + +#: modules/node.views.inc:284 +msgid "Created year" +msgstr "Rok utworzenia" + +#: modules/node.views.inc:285 +msgid "In the form of YYYY." +msgstr "Format danych YYYY" + +#: modules/node.views.inc:293 +msgid "Created month" +msgstr "Miesiąc utworzenia" + +#: modules/node.views.inc:294 +msgid "In the form of MM (01 - 12)." +msgstr "Format danych MM (01 - 12)." + +#: modules/node.views.inc:302 +msgid "Created week" +msgstr "Tydzień utworzenia" + +#: modules/node.views.inc:303 +msgid "In the form of WW (01 - 53)." +msgstr "Format danych WW(01 - 53)." + +#: modules/node.views.inc:315;320 +msgid "Node revision" +msgstr "Wersja segmentu" + +#: modules/node.views.inc:321 +msgid "Node revisions are a history of changes to nodes." +msgstr "Wersje segmentu są historią zmian w nich." + +#: modules/node.views.inc:336 +msgid "Relate a node revision to the user who created the revision." +msgstr "Powiązuje wersje segmentu z użytkownikiem który stworzył wersje." + +#: modules/node.views.inc:341 +msgid "user" +msgstr "użytkownik" + +#: modules/node.views.inc:349 +msgid "The actual, full data in the body field; this may not be valid data on all node types." +msgstr "Faktyczna, pełne dane w polu treści; Mogą nie być właściwe dla wszystkich segmentów." + +#: modules/node.views.inc:363 +msgid "Teaser" +msgstr "Skrót" + +#: modules/node.views.inc:364 +msgid "The stored teaser field. This may not be valid or useful data on all node types." +msgstr "Pole przechowywania skrótu. Nie poleca się przechowywania pożytecznych danych we wszystkich segmentach." + +#: modules/node.views.inc:377 +msgid "Vid" +msgstr "Vid" + +#: modules/node.views.inc:378 +msgid "The revision ID of the node revision." +msgstr "ID wersji wersji segmentu." + +#: modules/node.views.inc:423 +msgid "Log message" +msgstr "Dziennik wiadomości" + +#: modules/node.views.inc:424 +msgid "The log message entered when the revision was created." +msgstr "Wiadomość wprowadzona do dziennika w momencie utworzenia wersji." + +#: modules/node.views.inc:438 +msgid "The date the node revision was created." +msgstr "Data stworzenia wersji dla segmentu." + +#: modules/node.views.inc:453 +msgid "Revert link" +msgstr "Powrót" + +#: modules/node.views.inc:454 +msgid "Provide a simple link to revert to the revision." +msgstr "Dostarcza prosty odnośnik do powrotu do poprzedniej wersji." + +#: modules/node.views.inc:462 +msgid "Provide a simple link to delete the node revision." +msgstr "Dostarcza prosty odnośnik do kasowania wersji segmentu." + +#: modules/node.views.inc:489 +msgid "Has new content" +msgstr "Ma nową zawartość" + +#: modules/node.views.inc:492 +msgid "Show a marker if the node has new or updated content." +msgstr "Oznacza, jeśli segment jest nowy lub zawiera nową treść." + +#: modules/node.views.inc:495 +msgid "Show only nodes that have new content." +msgstr "Pokazuj tylko te segmenty, które maja nową zawartość." + +#: modules/node.views.inc:528 +msgid "Link this field to its node" +msgstr "Odnieś to pole do segmentu" + +#: modules/node.views.inc:713 +msgid "revert" +msgstr "powrót" + +#: modules/node.views.inc:788 +msgid "Check for new comments as well" +msgstr "Sprawdzaj również dla nowych odpowiedzi" + +#: modules/node.views.inc:860 +msgid "Unknown node type" +msgstr "Nieznany typ segmentu" + +#: modules/node.views.inc:1043 +msgid "Week @week" +msgstr "Tydzień @week" + +#: modules/node.views.inc:1055 +msgid "Node type" +msgstr "Typ segmentu" + +#: modules/node.views.inc:1116 +msgid "Current user's language" +msgstr "Bieżący język użytkownika." + +#: modules/node.views.inc:1116 +msgid "No language" +msgstr "Brak języka" + +#: modules/node.views.inc:1166 +msgid "Unknown language" +msgstr "Nieznany język" + +#: modules/node.views.inc:1179;1188 +msgid "Display the node with standard node view." +msgstr "Wyświetlaj segment widokiem standardowym." + +#: modules/node.views.inc:1203 +msgid "Node ID from URL" +msgstr "ID segmentu z URLa" + +#: modules/node.views.inc:1230 +msgid "Display only teaser" +msgstr "Wyświetlaj tylko skrót" + +#: modules/node.views.inc:1291 +msgid "Full text" +msgstr "Pełen tekst" + +#: modules/node.views.inc:1292 +msgid "Title plus teaser" +msgstr "Tytuł i skrót" + +#: modules/node.views.inc:1293 +msgid "Title only" +msgstr "Tylko tytuł" + +#: modules/node.views.inc:1294 +msgid "Use default RSS settings" +msgstr "Użyj domyślnych ustawień RSS" + +#: modules/node.views.inc:1360 +msgid "read more" +msgstr "czytaj więcej" + +#: modules/node.views.inc:1393 +msgid "Types" +msgstr "Typy" + +#: modules/node.views.inc:1396 +msgid "If you wish to validate for specific node types, check them; if none are checked, all nodes will pass." +msgstr "Zaznacz, jeśli chcesz sprawdzać poprawność dla konkretnego typu segmentu. Gdy nie znaznaczysz - wszystkie segmenty będą sprawdzane." + +#: modules/node.views.inc:1403 +msgid "Validate user has access to the node" +msgstr "Sprawdza czy użytkownik ma dostęp do segmentu" + +#: modules/node.views.inc:1411 +#: modules/taxonomy.views.inc:1044 +msgid "Argument type" +msgstr "Typ argumentu" + +#: modules/node.views.inc:1414 +msgid "Node IDs separated by , or +" +msgstr "ID Segmentów oddzielone przez , lub + " + +#: modules/node.views.inc:1533 +msgid "Display %display has no access control but does not contain a filter for published nodes." +msgstr "Podgląd %display nie ma dostępu ale i nie zawiera filtrów do publikacji segmentów." + +#: modules/poll.views.inc:23 +msgid "Poll" +msgstr "Ankieta" + +#: modules/poll.views.inc:38;47 +#: modules/user.views.inc:173;182 +msgid "Active" +msgstr "Aktywny/e" + +#: modules/poll.views.inc:39 +msgid "Whether the poll is open for voting." +msgstr "Czy ankieta jest otwarta do głosowania." + +#: modules/profile.views.inc:20;40 +msgid "Profile" +msgstr "Profil" + +#: modules/profile.views.inc:100 +msgid "@field-name" +msgstr "@firld-name" + +#: modules/profile.views.inc:107 +msgid "Profile textfield" +msgstr "Profil pola tekstowego" + +#: modules/profile.views.inc:126 +msgid "Profile textarea" +msgstr "Profil obszaru tekstowego" + +#: modules/profile.views.inc:142 +msgid "Profile checkbox" +msgstr "Profil checkboxa" + +#: modules/profile.views.inc:159 +msgid "Profile URL" +msgstr "Profil URLa" + +#: modules/profile.views.inc:175 +msgid "Profile selection" +msgstr "Profil wyboru" + +#: modules/profile.views.inc:195 +msgid "Profile freeform list %field-name." +msgstr "Lista profilu %field-name." + +#: modules/profile.views.inc:207 +msgid "Profile date %field-name." +msgstr "Data profilu %field-name." + +#: modules/search.views.inc:23;77;88;106;172;247 +msgid "Search" +msgstr "Szukaj" + +#: modules/search.views.inc:72 +msgid "Score" +msgstr "Punkty" + +#: modules/search.views.inc:73 +msgid "The score of the search item." +msgstr "Ilość trafień " + +#: modules/search.views.inc:95 +msgid "Links from" +msgstr "Odnośniki z" + +#: modules/search.views.inc:96 +msgid "Nodes that link from the node." +msgstr "segmenty odnoszące z segmentu." + +#: modules/search.views.inc:113 +msgid "Links to" +msgstr "Odnosniki do" + +#: modules/search.views.inc:114 +msgid "Nodes that link to the node." +msgstr "segmenty odnoszące się do segmentu." + +#: modules/search.views.inc:125 +msgid "Search Terms" +msgstr "Szukane wyrażenia" + +#: modules/search.views.inc:126 +msgid "The terms to search for." +msgstr "Lista szukanych wyrażeń" + +#: modules/search.views.inc:156 +msgid "On empty input" +msgstr "Na puste wejście" + +#: modules/search.views.inc:159 +msgid "Show All" +msgstr "Pokaż wszystko" + +#: modules/search.views.inc:160 +msgid "Show None" +msgstr "Nic nie pokazuj" + +#: modules/search.views.inc:175 +msgid "Enter the terms you wish to search for." +msgstr "Wpisz terminy których szukasz." + +#: modules/search.views.inc:190 +msgid "You must include at least one positive keyword with @count characters or more." +msgstr "Musisz wstawić przynajmniej jedno właściwe słowo z @count znakami lub więcej. " + +#: modules/search.views.inc:194 +msgid "Search for either of the two terms with uppercase <strong>OR</strong>. For example, <strong>cats OR dogs</strong>." +msgstr "Wyszukiwanie dla obu wyrażeń wpisujemy wielkimi literami <strong>OR</strong>. Na przykład, <strong> koty OR psy</strong>." + +#: modules/search.views.inc:248 +msgid "Display the results with standard search view." +msgstr "Wyświetl wyniki za pomocą widoku standardowego wyszukiwania." + +#: modules/search.views.inc:274 +msgid "Display score" +msgstr "Wyświetl wynik" + +#: modules/statistics.views.inc:24 +msgid "Node statistics" +msgstr "Statystyki segmentu" + +#: modules/statistics.views.inc:36 +msgid "Total views" +msgstr "Wszystkie odwiedziny" + +#: modules/statistics.views.inc:37 +msgid "The total number of times the node has been viewed." +msgstr "Ogolna liczba wizyt dla segmentu." + +#: modules/statistics.views.inc:53 +msgid "Views today" +msgstr "Wizyt dzisiaj" + +#: modules/statistics.views.inc:54 +msgid "The total number of times the node has been viewed today." +msgstr "Całkowita liczba wyświetleń segmentu dzisiaj." + +#: modules/statistics.views.inc:70 +msgid "Most recent view" +msgstr "Najczęściej odwiedzane" + +#: modules/statistics.views.inc:71 +msgid "The most recent time the node has been viewed." +msgstr "Ostatni czas kiedy segment był przeglądany." + +#: modules/statistics.views.inc:86;91 +msgid "Access log" +msgstr "Dziennik dostępu" + +#: modules/statistics.views.inc:92 +msgid "Stores site access information." +msgstr "Przechowuje informacje o dostępie do strony." + +#: modules/statistics.views.inc:106 +msgid "Session ID" +msgstr "ID Sesji (Session ID)" + +#: modules/statistics.views.inc:107 +msgid "Browser session ID of user that visited page." +msgstr "ID Sesji przeglądarki użytkownika odwiedzającego stronę." + +#: modules/statistics.views.inc:126 +msgid "Page title" +msgstr "Tytuł strony" + +#: modules/statistics.views.inc:127 +msgid "Title of page visited." +msgstr "Tytuł odwiedzonej strony." + +#: modules/statistics.views.inc:147 +msgid "Internal path to page visited (relative to Drupal root.)" +msgstr "Wewnetrzna scieżka strony (relatywna do głównej Drupala)." + +#: modules/statistics.views.inc:166 +msgid "Referrer" +msgstr "Odwołuje się" + +#: modules/statistics.views.inc:167 +msgid "Referrer URI." +msgstr "Odwołuje się do URLa" + +#: modules/statistics.views.inc:182 +msgid "Hostname" +msgstr "Hostname" + +#: modules/statistics.views.inc:183 +msgid "Hostname of user that visited the page." +msgstr "Nazwy hostów użytkowników którzy odwiedzili stronę." + +#: modules/statistics.views.inc:202 +msgid "The user who visited the site." +msgstr "Użytkownik który odwiedził witrynę." + +#: modules/statistics.views.inc:212 +msgid "Timer" +msgstr "Czasomierz (Timer)" + +#: modules/statistics.views.inc:213 +msgid "Time in milliseconds that the page took to load." +msgstr "Czas ładowania strony w milisekundach." + +#: modules/statistics.views.inc:228 +msgid "Timestamp" +msgstr "Timestamp" + +#: modules/statistics.views.inc:229 +msgid "Timestamp of when the page was visited." +msgstr "Znacznik czasu wizyty strony." + +#: modules/system.views.inc:25;30 +msgid "File" +msgstr "Plik" + +#: modules/system.views.inc:31 +msgid "Files maintained by Drupal and various modules." +msgstr "Pliki zarządzane przez Drupala i różne moduły." + +#: modules/system.views.inc:49 +msgid "File ID" +msgstr "ID pliku (File ID)" + +#: modules/system.views.inc:50 +msgid "The ID of the file." +msgstr "ID pliku" + +#: modules/system.views.inc:70 +msgid "The name of the file." +msgstr "Nazwa pliku." + +#: modules/system.views.inc:89 +msgid "The path of the file." +msgstr "Ścieżka pliku." + +#: modules/system.views.inc:107 +msgid "Mime type" +msgstr "Mime type" + +#: modules/system.views.inc:108 +msgid "The mime type of the file." +msgstr "\"mime type\" pliku." + +#: modules/system.views.inc:126 +msgid "Size" +msgstr "Rozmiar" + +#: modules/system.views.inc:127 +msgid "The size of the file." +msgstr "Rozmiar pliku." + +#: modules/system.views.inc:142 +msgid "Status" +msgstr "Status" + +#: modules/system.views.inc:143 +msgid "The status of the file." +msgstr "Status pliku." + +#: modules/system.views.inc:158 +msgid "Upload date" +msgstr "Data dodania" + +#: modules/system.views.inc:159 +msgid "The date the file was uploaded." +msgstr "Data dodania pliku." + +#: modules/system.views.inc:204 +#: modules/upload.views.inc:145;216 +msgid "Link this field to download the file" +msgstr "Podlinkuj to pole do \"pobierz plik\"" + +#: modules/system.views.inc:231 +msgid "Temporary" +msgstr "Stały/e" + +#: modules/system.views.inc:232 +msgid "Permanent" +msgstr "Stały/e" + +#: modules/system.views.inc:278 +msgid "No title" +msgstr "Brak tytułu" + +#: modules/taxonomy.views.inc:24;73;143;161;219;255;298;309 +msgid "Taxonomy" +msgstr "Taxonomia" + +#: modules/taxonomy.views.inc:54 +msgid "Vocabulary name" +msgstr "Nazwa słownika" + +#: modules/taxonomy.views.inc:56 +msgid "Name of the vocabulary a term is a member of. This will be the vocabulary that whichever term the \"Taxonomy: Term\" field is; and can similarly cause duplicates." +msgstr "Nazwa słownika w którym znajduje się wyrażenie. To będzie słownik dla któregokolwiek wyrażenia pola \"Taksonomia: wyrażenie\"; i może powodować powstawanie duplikatów." + +#: modules/taxonomy.views.inc:62 +msgid "Vocabulary ID" +msgstr "ID Słownika (Vocabluary ID)" + +#: modules/taxonomy.views.inc:63 +msgid "The taxonomy vocabulary ID" +msgstr "ID słownika w taksonomi" + +#: modules/taxonomy.views.inc:76;107 +msgid "Term" +msgstr "Wyrażenie" + +#: modules/taxonomy.views.inc:77 +msgid "Taxonomy terms are attached to nodes." +msgstr "Wyrażenia Taxonomi dołączone do segmentów." + +#: modules/taxonomy.views.inc:108 +msgid "Taxonomy terms. Note that using this can cause duplicate nodes to appear in views; you must add filters to reduce the resultset." +msgstr "Wyrażenia z taksonomi. Uwaga może to powodować duplikaty segmentów pojawiające się w widokach; Musisz dodać filtry by zredukować ilość wyników tamże." + +#: modules/taxonomy.views.inc:118 +msgid "Taxonomy term name" +msgstr "Nazwa wyrażenia w taxonomi" + +#: modules/taxonomy.views.inc:127 +msgid "The term weight field" +msgstr "Pole wagi wyrażenia" + +#: modules/taxonomy.views.inc:139 +msgid "Term description" +msgstr "Opis wyrażenia" + +#: modules/taxonomy.views.inc:140 +msgid "The description associated with a taxonomy term." +msgstr "Opis powiązany z wyrażeniem taxonomi." + +#: modules/taxonomy.views.inc:151;763 +msgid "Vocabulary" +msgstr "Słownik" + +#: modules/taxonomy.views.inc:152 +msgid "Filter the results of \"Taxonomy: Term\" to a particular vocabulary." +msgstr "Ogranicza wyniki \"Taksonomia: wyrażenie\" do konkretnego słownika." + +#: modules/taxonomy.views.inc:193;1046 +msgid "Term ID" +msgstr "ID Wyrażenia" + +#: modules/taxonomy.views.inc:194 +msgid "The taxonomy term ID" +msgstr "ID wyrażenia w taxonomi" + +#: modules/taxonomy.views.inc:196 +msgid "All terms" +msgstr "Wszystkie wyrażenia" + +#: modules/taxonomy.views.inc:197 +msgid "Display all taxonomy terms associated with a node." +msgstr "Wyświetl wszystkie wyrażenia Taxonomi powiązane z segmentem." + +#: modules/taxonomy.views.inc:282 +msgid "Term synonym" +msgstr "Synonim wyrażenia" + +#: modules/taxonomy.views.inc:283 +msgid "Term synonyms may be used to find terms by alternate names." +msgstr "Synonimy mogą być używane do znajdowania wyrażenia jako alternatywa." + +#: modules/taxonomy.views.inc:299 +msgid "Term ID (with depth)" +msgstr "ID Wyrażenia (z głębokością)" + +#: modules/taxonomy.views.inc:300 +msgid "The depth filter is more complex, so provides fewer options." +msgstr "Filtr głębokości jest bardziej kompleksowy (complex), dlatego udostępnia mniej opcji." + +#: modules/taxonomy.views.inc:310 +msgid "Term ID depth modifier" +msgstr "Modyfikator głębokości Identyfikatora wyrażenia" + +#: modules/taxonomy.views.inc:311 +msgid "Allows the \"depth\" for Taxonomy: Term ID (with depth) to be modified via an additional argument." +msgstr "Zezwala na modyfikowanie \"głębokość\" dla Taksonomi: ID wyrażenia (z głębokością) poprzez dodatkowy argument." + +#: modules/taxonomy.views.inc:341 +msgid "The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term \"fruit\" and a child term \"apple\", with a depth of 1 (or higher) then filtering for the term \"fruit\" will get nodes that are tagged with \"apple\" as well as \"fruit\". If negative, the reverse is true; searching for \"apple\" will also pick up nodes tagged with \"fruit\" if depth is -1 (or lower)." +msgstr "Głębokość dopasuje segmenty oznaczone w hierarchi. Na przykład, jeśli masz wyrażenie \"owoc\" i jego dziecko - wyrażenie \"jabłko\", z głębokością 1 (lub wyższą) wtedy filtrowanie dla wyrażenia \"owoc\" zbierze razem segmenty oznaczone zarówno jako \"jabłko\" jak i \"owoc\". Działa to również w drugą stronę; jeśli głębokość jest -1 (lub niższa) szukając \"jabłko\" zbierzemy razem segmenty oznaczone jako \"owoc\" " + +#: modules/taxonomy.views.inc:346 +msgid "Allow multiple terms per argument" +msgstr "Pozwól na wiele wyrażeń przypadających na argument" + +#: modules/taxonomy.views.inc:347 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3. Due to the number of JOINs it would require, AND will be treated as OR with this argument." +msgstr "Gdy zaznaczone, użytkownicy będą mogli wprowadzać wiele argumentów w postaci 1+2+3. W związku z wymaganą przez to liczbą złączeń (JOINs), \"'oraz\" (AND) będą traktowane jako \"lub\" (OR)." + +#: modules/taxonomy.views.inc:353;978 +msgid "Set the breadcrumb for the term parents" +msgstr " Ustaw trop dla wyrażeń nadrzędnych" + +#: modules/taxonomy.views.inc:354;979 +msgid "If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received." +msgstr "Jeśli zaznaczone, trop będzie zawierał wszystkie wyrażenia nadrzędne (parents), każde odnoszące się do tego widoku. Uwaga, działa gdy otrzymano tylko jedno wyrażenie." + +#: modules/taxonomy.views.inc:440;685 +msgid "No name" +msgstr "Brak nazwy" + +#: modules/taxonomy.views.inc:551 +msgid "Link this field to its term page" +msgstr "Podlinkuj to pole do jego strony wyrażeń" + +#: modules/taxonomy.views.inc:558 +msgid "Limit terms by vocabulary" +msgstr "Ogranicz wyrażenia do słownika" + +#: modules/taxonomy.views.inc:572;1034 +msgid "Vocabularies" +msgstr "Słowniki" + +#: modules/taxonomy.views.inc:645 +msgid "Link this field to its taxonomy term page" +msgstr "Odnosnik do strony z listą wyrażeń taksonomi" + +#: modules/taxonomy.views.inc:721 +msgid "No vocabulary" +msgstr "Brak słownika" + +#: modules/taxonomy.views.inc:765 +msgid "Select which vocabulary to show terms for in the regular options." +msgstr "Wybierz, który ze słowników ma wyświetlać wyrażenia" + +#: modules/taxonomy.views.inc:775 +msgid "Selection type" +msgstr "Typ wyboru" + +#: modules/taxonomy.views.inc:776 +msgid "Dropdown" +msgstr "Rozwiń" + +#: modules/taxonomy.views.inc:776 +msgid "Autocomplete" +msgstr "Autouzupełnianie" + +#: modules/taxonomy.views.inc:782 +msgid "Show hierarchy in dropdown" +msgstr "Pokaż hierarchie jako menu rozwijane." + +#: modules/taxonomy.views.inc:799 +msgid "An invalid vocabulary is selected. Please change it in the options." +msgstr "Wybrano niewłaściwy słownik. Wybierz inny." + +#: modules/taxonomy.views.inc:817;851 +msgid "Select terms from vocabulary @voc" +msgstr "Wybierz wyrażenia ze słownika @voc " + +#: modules/taxonomy.views.inc:1012 +msgid "Taxonomy term" +msgstr "Wyrażenia taksonomi" + +#: modules/taxonomy.views.inc:1037 +msgid "If you wish to validate for specific vocabularies, check them; if none are checked, all nodes will pass." +msgstr "Jeśli chcesz sprawdzać poprawność dla określonych słowników - zaznacz; jeśli nie, nie zaznaczaj, wtedy wszystkie segmenty będą sprawdzane." + +#: modules/taxonomy.views.inc:1047 +msgid "Term IDs separated by , or +" +msgstr "ID wrażeń oddzielone , lub +" + +#: modules/taxonomy.views.inc:1048 +msgid "Term name or synonym" +msgstr "Nazwa wyrazenia lub synonim" + +#: modules/taxonomy.views.inc:1049 +msgid "Term name/synonym converted to Term ID" +msgstr "Wyrażenie/synonim skonwertowany do ID Wyrażenia (Term ID)" + +#: modules/taxonomy.views.inc:1052 +msgid "Select the form of this argument; if using term name, it is generally more efficient to convert it to a term ID and use Taxonomy: Term ID rather than Taxonomy: Term Name\" as an argument." +msgstr " " + +#: modules/taxonomy.views.inc:937 +msgid "Unable to find term: @terms" +msgid_plural "Unable to find terms: @terms" +msgstr[0] "Nie znaleziono wyrażenia: @terms" +msgstr[1] "Nie znaleziono wyrażeń: @terms" +msgstr[2] "Nie znaleziono wyrażeń: @terms" + +#: modules/upload.views.inc:25 +msgid "Upload" +msgstr "Dodaj plik" + +#: modules/upload.views.inc:49 +msgid "The description of the uploaded file." +msgstr "Opis wgranego pliku." + +#: modules/upload.views.inc:66 +msgid "Listed" +msgstr "Wylistowany" + +#: modules/upload.views.inc:67 +msgid "Whether or not the file is marked to be listed." +msgstr "Czy pliki mają być wylistowane czy też nie." + +#: modules/upload.views.inc:83 +msgid "The weight, used for sorting." +msgstr "Waga użytego sortowania." + +#: modules/upload.views.inc:101;113 +msgid "Attached files" +msgstr "Dołączone pliki" + +#: modules/upload.views.inc:102 +msgid "All files attached to a node with upload.module." +msgstr "Wszystkie pliki dołączone do segmentu z upload.module." + +#: modules/upload.views.inc:109;274 +msgid "Has attached files" +msgstr "Ma dołączone pliki" + +#: modules/upload.views.inc:110 +msgid "Only display items with attached files. This can cause duplicates if there are multiple attached files." +msgstr "Wyświetla tylko elementy z dołączonymi plikami. To może powodować powstawanie duplikatów jeśli jest wiele dołączonych plików." + +#: modules/upload.views.inc:114 +msgid "Add a relationship to gain access to more file data for files uploaded by upload.module. Note that this relationship will cause duplicate nodes if there are multiple files attached to the node." +msgstr "Dodaj zależności zyskujące dostęp do plików danych załadowanych przez upload.module. Uwaga, ta zalezność może spowodować pojawienie się duplikatów wielu plików dołączonych do segmentu." + +#: modules/upload.views.inc:120 +msgid "Files" +msgstr "Pliki" + +#: modules/upload.views.inc:151 +msgid "Only show \"listed\" file attachments" +msgstr "Pokazuj tylko załączniki \"listed\"" + +#: modules/user.views.inc:28 +msgid "Users who have created accounts on your site." +msgstr "Użytkownicy którzy założyli konto na Twojej witrynie." + +#: modules/user.views.inc:48 +msgid "Uid" +msgstr "Uid" + +#: modules/user.views.inc:49 +msgid "The user ID" +msgstr "ID użytkownika" + +#: modules/user.views.inc:70 +msgid "Current" +msgstr "Bieżący" + +#: modules/user.views.inc:71 +msgid "Filter the view to the currently logged in user." +msgstr "Filtr do przeglądania obecnie zalogowanych użytkowników." + +#: modules/user.views.inc:80 +msgid "The user or author name." +msgstr "Użytkownik lub dane autora" + +#: modules/user.views.inc:96 +msgid "E-mail" +msgstr "E-mail" + +#: modules/user.views.inc:97 +msgid "Email address for a given user. Only accessible to users with <em>administer users</em> permission" +msgstr "Adres e-mail dla danego użytkownika. Dostępne tylko dla użytkowników z prawami administratora." + +#: modules/user.views.inc:114 +msgid "Picture" +msgstr "Obraz" + +#: modules/user.views.inc:115 +msgid "The user's picture, if allowed." +msgstr "Obrzy użytkownika, jeśli dozwolone." + +#: modules/user.views.inc:126 +msgid "The date the user was created." +msgstr "Data stworzenia użytkownika." + +#: modules/user.views.inc:141 +msgid "Last access" +msgstr "Ostatni dostęp" + +#: modules/user.views.inc:142 +msgid "The user's last access date." +msgstr "Data ostatniego dostępu użytkownika." + +#: modules/user.views.inc:157 +msgid "Last login" +msgstr "Ostatni login" + +#: modules/user.views.inc:158 +msgid "The user's last login date." +msgstr "Data ostatniego loginu użytkownika." + +#: modules/user.views.inc:174 +msgid "Whether a user is active or blocked." +msgstr "Czy użytkownik jest aktywny, czy zablokowany." + +#: modules/user.views.inc:191 +msgid "Signature" +msgstr "Podpis" + +#: modules/user.views.inc:192 +msgid "The user's signature." +msgstr "Podpis użytkownika" + +#: modules/user.views.inc:205 +msgid "Provide a simple link to edit the user." +msgstr "Dostarcza prosty odnośnik do edycji użytkownika." + +#: modules/user.views.inc:213 +msgid "Provide a simple link to delete the user." +msgstr "Dostarcza prosty odnośnik do usunięcia użytkownika." + +#: modules/user.views.inc:242 +msgid "Roles" +msgstr "Role" + +#: modules/user.views.inc:243 +msgid "Roles that a user belongs to." +msgstr "Role do których należy użytkownik" + +#: modules/user.views.inc:255 +msgid "No role" +msgstr "Brak roli" + +#: modules/user.views.inc:306 +msgid "User ID from URL" +msgstr "ID użytkownika z URL" + +#: modules/user.views.inc:322 +msgid "Also look for a node and use the node author" +msgstr "Patrz również na segment i użyj jego autora." + +#: modules/user.views.inc:387 +msgid "Link this field to its user" +msgstr "Podlinkuj to pole do użytkownika" + +#: modules/user.views.inc:520 +msgid "Link this field" +msgstr "Podlinkuj to pole" + +#: modules/user.views.inc:523 +msgid "No link" +msgstr "Brak odnośnika" + +#: modules/user.views.inc:524 +msgid "To the user" +msgstr "Dla użytkownika" + +#: modules/user.views.inc:525 +msgid "With a mailto:" +msgstr "Z \"wyślij do:\" (mailto:)" + +#: modules/user.views.inc:643 +msgid "Usernames" +msgstr "Lista użytkowników" + +#: modules/user.views.inc:644 +msgid "Enter a comma separated list of user names." +msgstr "Wprowadź liste użytkowników oddzieloną przecinkami." + +#: modules/user.views.inc:752 +msgid "Is the logged in user" +msgstr "Zalogowany użytkownik" + +#: modules/user.views.inc:710 +msgid "Unable to find user: @users" +msgid_plural "Unable to find users: @users" +msgstr[0] "Nie mogę znaleźć użytkownika: @users" +msgstr[1] "Nie mogę znaleźć użytkowników: @users" +msgstr[2] "Nie mogę znaleźć użytkowników: @users" + +#: modules/views.views.inc:18 +msgid "Global" +msgstr "Globalne" + +#: modules/views.views.inc:23 +msgid "Random" +msgstr "Losowy" + +#: modules/views.views.inc:24 +msgid "Randomize the display order." +msgstr "Losowa kolejność wyświetlania." + +#: modules/views.views.inc:31 +msgid "Null" +msgstr "Null" + +#: modules/views.views.inc:32 +msgid "Allow an argument to be ignored. The query will not be altered by this argument." +msgstr "Zezwól na ignorowanie argumentu. Ten argument nie będzie miał wpływu na zapytanie." + +#: modules/views.views.inc:88 +msgid "Fail basic validation if any argument is given" +msgstr "Zawodzi podstawowe sprawdzanie poprawności jeśli podamy jakikolwiek argument." + +#: modules/views.views.inc:90 +msgid "By checking this field, you can use this to make sure views with more arguments than necessary fail validation." +msgstr "Zaznaczając to pole, używając tego możesz wymusić błąd poprawności dla widoków z większą niż wymaganą liczbą argumentów." + +#: theme/views-more.tpl.php:15 +msgid "more" +msgstr "więcej" + +#: theme/views-ui-edit-item.tpl.php:18 +msgid "None defined" +msgstr "Niezdefiniowane" + +#: theme/views-ui-edit-tab.tpl.php:31 +msgid "View settings" +msgstr "Ustawienia widoków" + +#: theme/views-ui-edit-view.tpl.php:11 +msgid "This view is being edited by user !user, and is therefore locked from editing by others. This lock is !age old. Click here to !break." +msgstr "Ten widok jest edytowany przez !user, dlatego nikt inny w tej chwili nie może go edytować. Blokadę założono !age temu. Kliknij !break aby zlikwidować blokadę." + +#: theme/views-ui-edit-view.tpl.php:16 +msgid "New view" +msgstr "Nowy widok" + +#: theme/views-ui-edit-view.tpl.php:18 +msgid "Changed view" +msgstr "Zmień widok" + +#: theme/views-ui-edit-view.tpl.php:23 +msgid "View %name, displaying items of type <strong>@base</strong>." +msgstr "Widok %name, wyświetlający typy elementów <strong>@base</strong>." + +#: theme/views-ui-edit-view.tpl.php:42 +msgid "Live preview" +msgstr "Podgląd" + +#: theme/views-ui-list-views.tpl.php:17 +msgid "<em>@type</em> @base view: <strong>@view</strong>" +msgstr "<em>@type</em> @base widok: <strong>@view</strong>" + +#: theme/views-ui-list-views.tpl.php:27 +msgid "Title: @title" +msgstr "Tytuł: @title" + +#: theme/views-ui-list-views.tpl.php:30 +msgid "Path: !path" +msgstr "Śćiezka: !path" + +#: theme/theme.inc:90 +msgid "Edit this view" +msgstr "Edytuj widok" + +#: theme/theme.inc:289 +msgid "sort by @s" +msgstr "Sortuj po @s" + +#: theme/theme.inc:490 +msgid "‹‹" +msgstr "‹‹" + +#: theme/theme.inc:491 +msgid "››" +msgstr "››" + +#: theme/theme.inc:501 +msgid "@current of @max" +msgstr "@current z @max" + +#: views_export/views_export.module:76 +msgid "There are no views to be exported at this time." +msgstr "W tym momencie nie ma widoków do eksportu." + +#: views_export/views_export.module:108 +msgid "Show only these tags" +msgstr "Pokazuj tylko te tagi" + +#: views_export/views_export.module:122 +msgid "Module name" +msgstr "Nazwa modułu" + +#: views_export/views_export.module:123 +msgid "Enter the module name to export code to." +msgstr "Wprowadź nazwe modułu dla którego kod ma byś wyeksportowany." + +#: views_export/views_export.module:190 +msgid "Put this in @module.views_default.inc in your modules/@module directory or modules/@module/includes directory" +msgstr "Umieść @module.views_default.inc w swoim katalogu modules/@module lub modules/@module/includes" + +#: views_export/views_export.module:44 +msgid "use views exporter" +msgstr "Użyj eksportera widoków" + +#: views_export/views_export.module:17 +msgid "Bulk export" +msgstr "Hurtowy eksport" + +#: views_export/views_export.module:0 +msgid "views_export" +msgstr "views_export" + +#: views_export/views_export.info:0 +msgid "Views exporter" +msgstr "Eksporter Widoków" + +#: views_export/views_export.info:0 +msgid "Allows exporting multiple views at once." +msgstr "Zezwala na eksportowanie wielu widoków na raz" + diff --git a/sites/all/modules/views/translations/uk.po b/sites/all/modules/views/translations/uk.po new file mode 100644 index 0000000000000000000000000000000000000000..3d4697ba8b5022effbc763fe0beec5c1a3a58390 --- /dev/null +++ b/sites/all/modules/views/translations/uk.po @@ -0,0 +1,4863 @@ +# Ukrainian translation of Views (all releases) +# Copyright (c) 2009 by the Ukrainian translation team +# +msgid "" +msgstr "" +"Project-Id-Version: Views (all releases)\n" +"POT-Creation-Date: 2009-10-08 19:03+0000\n" +"PO-Revision-Date: 2009-10-08 22:04+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 "Home" +msgstr "Головна" + +msgid "Title" +msgstr "Назва" + +msgid "Body" +msgstr "Тіло" + +msgid "Next" +msgstr "Наступний" + +msgid "user" +msgstr "користувач" + +msgid "delete" +msgstr "видалити" + +msgid "Status" +msgstr "Статус" + +msgid "Prefix" +msgstr "Префікс" + +msgid "Suffix" +msgstr "Суфікс" + +msgid "E-mail" +msgstr "Адреса електронної пошти" + +msgid "Delete" +msgstr "Видалити" + +msgid "Submit" +msgstr "Надіслати" + +msgid "Operations" +msgstr "Дії" + +msgid "Value" +msgstr "Значення" + +msgid "Groups" +msgstr "Групи" + +msgid "Group" +msgstr "Група" + +msgid "Type" +msgstr "Тип" + +msgid "Author" +msgstr "Автор" + +msgid "Replies" +msgstr "Відповіді" + +msgid "Last Post" +msgstr "Останнє повідомлення" + +msgid "List" +msgstr "Список" + +msgid "Actions" +msgstr "Дії" + +msgid "Cancel" +msgstr "Скасувати" + +msgid "Remove" +msgstr "Вилучити" + +msgid "Description" +msgstr "Опис" + +msgid "Language" +msgstr "Мова" + +msgid "more" +msgstr "більше" + +msgid "Enable" +msgstr "Ввімкнути" + +msgid "Disable" +msgstr "Вимкнено" + +msgid "Disabled" +msgstr "Вимкнено" + +msgid "Enabled" +msgstr "Ввімкнено" + +msgid "On" +msgstr "Увімкнути" + +msgid "Taxonomy" +msgstr "Таксономія" + +msgid "Yes" +msgstr "Так" + +msgid "No" +msgstr "Ні" + +msgid "Version" +msgstr "Версія" + +msgid "view" +msgstr "переглянути" + +msgid "File" +msgstr "Файл" + +msgid "Tag" +msgstr "Таг" + +msgid "Edit" +msgstr "Редагувати" + +msgid "Size" +msgstr "Розмір" + +msgid "Search" +msgstr "Пошук" + +msgid "Reset" +msgstr "Скинути" + +msgid "None" +msgstr "Жодного" + +msgid "default" +msgstr "типовий" + +msgid "This action cannot be undone." +msgstr "Цю дію не можна буде скасувати." + +msgid "Block settings" +msgstr "Параметри Блоку" + +msgid "Weight" +msgstr "Вага" + +msgid "Link" +msgstr "Посилання" + +msgid "Types" +msgstr "Типи" + +msgid "Hierarchy" +msgstr "Ієрархія" + +msgid "Parent" +msgstr "Попередник" + +msgid "Depth" +msgstr "Глибина" + +msgid "Category" +msgstr "Категорія" + +msgid "Settings" +msgstr "Налаштування" + +msgid "Feed" +msgstr "RSS стрічка" + +msgid "Name" +msgstr "Назва" + +msgid "edit" +msgstr "редагувати" + +msgid "Import" +msgstr "Імпорт" + +msgid "Book" +msgstr "Книга" + +msgid "Export" +msgstr "Експорт" + +msgid "Taxonomy term" +msgstr "Термін таксономії" + +msgid "settings" +msgstr "налаштування" + +msgid "Node ID" +msgstr "Ідентифікатор ноди" + +msgid "Field" +msgstr "Поле" + +msgid "Label" +msgstr "Заголовок" + +msgid "Preview" +msgstr "Перегляд" + +msgid "Save" +msgstr "Зберегти" + +msgid "True" +msgstr "Так" + +msgid "False" +msgstr "Ні" + +msgid "Default" +msgstr "Типовий" + +msgid "Update" +msgstr "Оновити" + +msgid "Top" +msgstr "Вгору" + +msgid "As Link" +msgstr "" + +msgid "Without Link" +msgstr "" + +msgid "Icon" +msgstr "Значок" + +msgid "Views" +msgstr "Views" + +msgid "Access" +msgstr "Доступ" + +msgid "Add" +msgstr "Додати" + +msgid "View" +msgstr "Перегляд" + +msgid "URL" +msgstr "URL" + +msgid "Path" +msgstr "Шлях" + +msgid "Vocabularies" +msgstr "Словники" + +msgid "Display" +msgstr "Відображення" + +msgid "Node type" +msgstr "Тип ноди" + +msgid "Menu" +msgstr "Меню" + +msgid "Teaser" +msgstr "Анонс" + +msgid "never" +msgstr "ніколи" + +msgid "Text" +msgstr "Текст" + +msgid "Theme" +msgstr "Шаблон" + +msgid "read more" +msgstr "докладніше" + +msgid "Timestamp" +msgstr "Мітка часу" + +msgid "ID" +msgstr "Ідентифікатор" + +msgid "Unknown" +msgstr "Невідомо" + +msgid "Attachment" +msgstr "Долучення" + +msgid "Upload" +msgstr "Вивантажити" + +msgid "Picture" +msgstr "Зображення" + +msgid "Before" +msgstr "До" + +msgid "After" +msgstr "Після" + +msgid "User" +msgstr "Користувач" + +msgid "Files" +msgstr "Файли" + +msgid "Error" +msgstr "Помилка" + +msgid "Options" +msgstr "Параметри" + +msgid "Created" +msgstr "Створено" + +msgid "Node" +msgstr "Матеріал" + +msgid "Number of columns" +msgstr "Кількість колонок" + +msgid "Separator" +msgstr "Розділювач" + +msgid "Horizontal" +msgstr "Горизонтально" + +msgid "Vertical" +msgstr "Вертикально" + +msgid "Are you sure you want to delete %title?" +msgstr "Ви дійсно бажаєте стерти %title?" + +msgid "All" +msgstr "Все" + +msgid "Access log" +msgstr "Лоґ доступу" + +msgid "Active" +msgstr "Діючий" + +msgid "Year" +msgstr "Рік" + +msgid "Date format" +msgstr "Формат дати" + +msgid "Page title" +msgstr "Назва сторінки" + +msgid "Block" +msgstr "Блок" + +msgid "Display links" +msgstr "Відображення посилань" + +msgid "View type" +msgstr "Тип Вигляду" + +msgid "Page" +msgstr "Сторінка" + +msgid "Bottom" +msgstr "Донизу" + +msgid "Breadcrumb" +msgstr "" + +msgid "Off" +msgstr "Вимкнено" + +msgid "Header" +msgstr "Заголовок" + +msgid "Footer" +msgstr "Нижній колонтитул" + +msgid "Aggregator category" +msgstr "" + +msgid "Aggregator feed" +msgstr "Стрічка збиральника" + +msgid "Aggregator item" +msgstr "Агрегатор пункту" + +msgid "Custom" +msgstr "Власний" + +msgid "Roles" +msgstr "Ролі" + +msgid "Comment" +msgstr "Коментар" + +msgid "Hostname" +msgstr "Сервер:" + +msgid "Score" +msgstr "Вага" + +msgid "Published" +msgstr "Опубліковано" + +msgid "Input format" +msgstr "Формат вводу" + +msgid "Signature" +msgstr "Підпис" + +msgid "Filter" +msgstr "Фільтр" + +msgid "Location" +msgstr "Адреса" + +msgid "Promoted to front page" +msgstr "Розміщене на першій сторінці" + +msgid "Log message" +msgstr "Повідомлення в системний журнал" + +msgid "Session ID" +msgstr "ID сесії" + +msgid "File ID" +msgstr "ID файлу" + +msgid "Vocabulary" +msgstr "Словник" + +msgid "Vocabulary ID" +msgstr "ID словника" + +msgid "Vocabulary name" +msgstr "Назва словника" + +msgid "Term" +msgstr "Термін" + +msgid "Term ID" +msgstr "ID терміну" + +msgid "Last access" +msgstr "Останній вхід" + +msgid "Last login" +msgstr "Останній вхід" + +msgid "Fields" +msgstr "Поля" + +msgid "Contains" +msgstr "Містить" + +msgid "Does not contain" +msgstr "Не містить" + +msgid "Is less than" +msgstr "Є меншим, ніж" + +msgid "Is less than or equal to" +msgstr "Є меншим або рівним, ніж" + +msgid "Is equal to" +msgstr "Є рівним" + +msgid "Is greater than or equal to" +msgstr "Є більшим або рівним за" + +msgid "Is greater than" +msgstr "Є більшим, ніж" + +msgid "Is not equal to" +msgstr "Не є рівним" + +msgid "Overridden" +msgstr "Пріоритетно" + +msgid "Watchdog" +msgstr "Вартовий" + +msgid "Normal" +msgstr "Нормально" + +msgid "%time ago" +msgstr "%time тому" + +msgid "Sort order" +msgstr "Сортування" + +msgid "Up" +msgstr "Вгору" + +msgid "Sortable" +msgstr "Сортується" + +msgid "Caching" +msgstr "" + +msgid "Month" +msgstr "Місяць" + +msgid "Basic Information" +msgstr "" + +msgid "Unlimited" +msgstr "Необмежено" + +msgid "Current" +msgstr "Поточна" + +msgid "Recent posts" +msgstr "Останні повідомлення" + +msgid "Day" +msgstr "День" + +msgid "Table" +msgstr "Таблиця" + +msgid "Basic" +msgstr "Базовий" + +msgid "List type" +msgstr "Тип списку" + +msgid "Role" +msgstr "Роль" + +msgid "Case" +msgstr "Вибір" + +msgid "Referrer" +msgstr "Джерело" + +msgid "Exists" +msgstr "Існує" + +msgid "Both" +msgstr "Все" + +msgid "Maximum length" +msgstr "Максимальна довжина" + +msgid "Argument" +msgstr "Аргумент" + +msgid "Anonymous" +msgstr "Гість" + +msgid "The views module creates customized views of node lists. You may need to activate the Views UI module to get to the user administration pages." +msgstr "Модуль Види створює керовані види списків матеріалів. Вам потрібно задіяти модуль Інтерфейса Видів для доступу до сторінок керування" + +msgid "<All>" +msgstr "<Всі>" + +msgid "As Short Date" +msgstr "Коротка дата" + +msgid "As Medium Date" +msgstr "Середня дата" + +msgid "As Long Date" +msgstr "Довга дата" + +msgid "As Custom Date" +msgstr "Власна дата" + +msgid "As Time Ago" +msgstr "" + +msgid "Granularity: minute" +msgstr "Деталізація: хвилина" + +msgid "Granularity: hour" +msgstr "Деталізація: година" + +msgid "Granularity: day" +msgstr "Деталізація: день" + +msgid "Granularity: month" +msgstr "Деталізація: місяць" + +msgid "Granularity: year" +msgstr "Деталізація: рік" + +msgid "Is All Of" +msgstr "Все з" + +msgid "Is One Of" +msgstr "Одне з" + +msgid "Is None Of" +msgstr "Жодне з" + +msgid "Is Equal To" +msgstr "Дорівнює" + +msgid "Is Not Equal To" +msgstr "Не дорівнює" + +msgid "Is Greater Than" +msgstr "Більше за" + +msgid "Is Greater Than Or Equals" +msgstr "Більше чи дорінює" + +msgid "Is Less Than Or Equals" +msgstr "Менеше чи дорінює" + +msgid "Is Less Than" +msgstr "Менше за" + +msgid "List View" +msgstr "Списком" + +msgid "Table View" +msgstr "Таблицею" + +msgid "Teaser List" +msgstr "" + +msgid "Full Nodes" +msgstr "" + +msgid "Contains Any Word" +msgstr "Не містить жодного слова" + +msgid "Contains All Words" +msgstr "Містить всі слова" + +msgid "Starts With" +msgstr "Починається з" + +msgid "Ends With" +msgstr "Закінчується з" + +msgid "Does Not Contain" +msgstr "Не містить" + +msgid "Save and edit" +msgstr "Зберегти і відредагувати" + +msgid "@filter must have a value!" +msgstr "@filter мусить містити значення!" + +msgid "The \"Value\" can either be a date in the format: CCYY-MM-DD HH:MM:SS or the word \"now\" to use the current time. You may enter a positive or negative number in the \"Option\" field that will represent the amount of seconds that will be added or substracted to the time; this is most useful when combined with \"now\". If you have the jscalendar module from jstools installed, you can use a popup date picker here." +msgstr "" + +msgid "access all views" +msgstr "доступ до всіх видів" + +msgid "Views RSS: RSS feed" +msgstr "" + +msgid "RSS: RSS Feed Selector" +msgstr "" + +msgid "This argument specifies a specific RSS feed selector; it will only select RSS feeds, unlike the built-in selector which can select pluggable feeds. You may enter the title the feed will advertise in the title field here, and the description of the feed in the option field here." +msgstr "" + +msgid "Theme wizard" +msgstr "Майстер шаблонів" + +msgid "<p>The views theming wizard generates code that you can use in your phptemplate theme to help you customize the output of a view. Simply select a theme and it will generate code for your template.php as well as template files for the individual views.</p><p>At this time this code assumes your view is a <b>list type view</b>! It may not generate effective code for other types of views. Future versions of this program will be smarter, and give more options, but this wizard is still a huge start.</p>" +msgstr "<p>Майстер шаблонів створює код, який ви можете використати у вашому phptemplate шаблоні щоб допомогти вам змінити вигляд виводу. Просто виберіть шаблон і він створить код для вашого template.php так само як файли шаблонів для окремих виглядів.</p><p>Зараз цей код припускає, що ваш вид<b>список</b>! Він може генерувати не ефективний код для інших типів вигляду. Наступні версії цього додатку будуть кмітливіші і даватимуть змогу більше налаштовувати його, але цей майстер це лише величезний початок.</p>" + +msgid "Select a view" +msgstr "Вибір виду" + +msgid "Select Theme Type" +msgstr "Вибір типу шаблону" + +msgid "List Theme Fields" +msgstr "" + +msgid "This is a list of all the theme functions you can use to override individual field displays" +msgstr "" + +msgid "This is a basic theme function" +msgstr "" + +msgid "Generate Theme" +msgstr "Генерувати шаблон" + +msgid "This code goes in your template.php file" +msgstr "" + +msgid "This code goes in a file named views-list-@s.tpl.php" +msgstr "" + +msgid "This code goes in a file named views-list-@s.css" +msgstr "" + +msgid "Simple List" +msgstr "Простий список" + +msgid "Grouped List" +msgstr "Групований список" + +msgid "Nested Tree" +msgstr "Вкладене дерево" + +msgid "Select the field on which to group" +msgstr "Виберіть поле за яким групувати" + +msgid "Select the field to use as the ID for each row (usually nid)" +msgstr "" + +msgid "Select the field that refers to the parent node by the ID field" +msgstr "" + +msgid "You may import a view by cut-and-pasting the results of an export view. If the import is successful you will be taken to the Add View page with all of the settings of the imported view.." +msgstr "" + +msgid "This screen shows all of the views that are currently defined in your system. The default views are provided by Views and other modules and are automatically available. If a customized view of the same name exists, it will be used in place of a default view." +msgstr "" + +msgid "Please see !s or the views documentation on drupal.org for help here." +msgstr "" + +msgid "the views help page" +msgstr "довідник видів" + +msgid "You may cut & paste this view into an import function on another system. The view will only work if all modules required by the view are installed on the target location." +msgstr "" + +msgid "<p>A view retrieves some number of nodes from the database and displays them in a variety of formats.</p>" +msgstr "" + +msgid "" +"<h3>View Types</h3>\n" +" <dl>\n" +" <dt><em>List View</em></dt><dd>A List View provides the data for each node retrieved in the form of an unordered list. Each item in the Fields section will be displayed; the Title will be displayed as a label. The order the items appear in the Fields list is the order the items will appear in the output. Leaving the title blank will cause the field to appear with no label (which is desirable in lists that just display titles, for example).</dd>\n" +" <dt><em>Table View</em></dt><dd>A Table View provides the data for each node as one row of a table. The Fields selected in the Fields list will be displayed in the order they are listed. The title column will be shown in the header. If you set the field to 'sortable' then the header will be click-sortable; be careful here as click-sorts will be processed after built-in sort criteria, and built-in sort criteria can easily make click-sorts invalid. If using click-sorts, choose a field to be the default sort; otherwise the first field presented will be the default sort.</dd>\n" +" <dt><em>Teaser List</em></dt><dd>A Teaser List will simply present the teaser of each node retrieved.</dd>\n" +" <dt><em>Full Nodes</em></dt><dd>This will show the full content of each node retrieved.</dd>\n" +" <dt><em>Random Teaser</em></dt><dd>This will show a single random teaser.</dd>\n" +" <dt><em>Random Node</em></dt><dd>This will show a single random node's full view.</dd>\n" +" </dl>" +msgstr "" + +msgid "<h3>Fields</h3>\n" +msgstr "" + +msgid "<p>When using List or Table view, it is necessary to choose which fields will be displayed to the user.</p><dl>\n" +msgstr "" + +msgid "<h3>Arguments</h3>\n" +msgstr "<h3>Аргументи</h3>\n" + +msgid "<p>Arguments can be passed to the View through the URL, in order to create views that are configurable by the user. This is very useful to create views for taxonomy, or to sort by user. When using arguments, substitution is performed on the title. %1 will represent argument 1, %2 will represent argument 2. Each argument has a title field; this title is used if providing a summary view (which can matter because the argument is missing which could result in confusing phrases such as 'view for')</p><dl>\n" +msgstr "" + +msgid "<h3>Filters</h3>\n" +msgstr "<h3>Фільтри</h3>\n" + +msgid "<p>Views may be filtered to restrict the view on a number of criteria.</p><dl>\n" +msgstr "" + +msgid "<h3>Sorting Critera</h3>\n" +msgstr "<h3>Правило сортування</h3>\n" + +msgid "<p>The result set may be sorted on any of the following criteria.</p><dl>\n" +msgstr "" + +msgid "Views are customized lists of content on your system; they are highly configurable and give you control over how lists of content are presented." +msgstr "Види - це особливі списки матеріалу в Вашій системі; вони глибоко модифікуються і дають можливість керувати виглядом відображених матеріалів" + +msgid "Tools" +msgstr "Інструменти" + +msgid "Edit view" +msgstr "Правка виду" + +msgid "Override" +msgstr "Переназначити" + +msgid "Clone" +msgstr "Клонування" + +msgid "Administer views" +msgstr "Керування видами" + +msgid "No Page View" +msgstr "" + +msgid "Provides" +msgstr "Надає" + +msgid "Existing Views" +msgstr "Доступні види" + +msgid "<p>No views have currently been defined.</p>" +msgstr "" + +msgid "<p>Below are system default views; if you edit one of these, a view will be created that will override any system use of the view.</p>" +msgstr "" + +msgid "Default view" +msgstr "Базовий вид" + +msgid "Default Views" +msgstr "Базові види" + +msgid "<p>Occasionally, something or other can cause the Views cache to contain stale data; this is particularly true after module updates and sometimes true after taxonomy and profile updates. If you are having problems with Views creating malformed queries, the first thing you should always do is clear the Views cache to see if that is the problem.</p>" +msgstr "" + +msgid "Clear views cache" +msgstr "" + +msgid "Import View Code" +msgstr "Втягнути код виду" + +msgid "Cut and paste the results of an Export View here." +msgstr "" + +msgid "Add a View" +msgstr "Додати вид" + +msgid "You don't seem to have the following requirements: " +msgstr "" + +msgid "Unable to get a view out of that." +msgstr "" + +msgid "Edit view %n" +msgstr "" + +msgid "Return Page Not Found" +msgstr "" + +msgid "Display All Values" +msgstr "" + +msgid "Summary, unsorted" +msgstr "" + +msgid "Summary, sorted ascending" +msgstr "Сумарно, сортування пряме" + +msgid "Summary, sorted descending" +msgstr "Сумарно, сортування зворотнє" + +msgid "Summary, sorted as view" +msgstr "" + +msgid "Use Empty Text" +msgstr "" + +msgid "Ascending" +msgstr "Зростання" + +msgid "Descending" +msgstr "Спадання" + +msgid "Add Filter" +msgstr "Додати фільтр" + +msgid "Add Criteria" +msgstr "" + +msgid "Add Argument" +msgstr "" + +msgid "Add Field" +msgstr "" + +msgid "Expose Filter" +msgstr "" + +msgid "You have modified this view; changes will not be recorded until you Save the form." +msgstr "" + +msgid "The unique identifier of the view; it is only important for overridden views and views that modules or themes will need to use. Only alphanumeric and _ allowed here" +msgstr "" + +msgid "Only the checked roles will be able to see this view in any form; if no roles are checked, access will not be restricted." +msgstr "" + +msgid "A description of the view for the admin list." +msgstr "" + +msgid "Provide Page View" +msgstr "" + +msgid "If checked this view will be provided as a page. If not checked, the fields in this group will be ignored." +msgstr "" + +msgid "Enter the URL to use for this view in the form of 'dir/dir'. Do not begin or end the URL with a /. Example: 'view/tracker'. This is required if providing a page view. You can also add $arg as a placeholder for arguments passed in the URL, for example 'user/$arg/tracker' or 'node/$arg/related'. Note that any arguments listed here will be required, even if they are listed as optional below. You do not need to list arguments at the end of the path. Do not try to use URLs such as taxonomy/term/$arg." +msgstr "" + +msgid "View Type" +msgstr "Тип Перегляду" + +msgid "How the nodes should be displayed to the user." +msgstr "" + +msgid "The title that be shown at the top of the view. May be blank. This title ignores arguments; if you want your title to take arguments into account, use the \"title\" field in the arguments section." +msgstr "" + +msgid "Use Pager" +msgstr "Сторінка Користувача" + +msgid "If checked this query may be multiple pages. If not checked this query will be one page." +msgstr "" + +msgid "Breadcrumb trail should not include \"Home\"" +msgstr "" + +msgid "If checked the breadcrumb trail for this page will discard \"Home\". Usually you will not set this, but this is used for the Front Page View, where it IS Home and should not leave a trail to itself." +msgstr "" + +msgid "Nodes per Page" +msgstr "" + +msgid "The number of nodes to display per page. If 0, all nodes will be displayed. If not using a pager, this will be the maximum number of nodes in the list." +msgstr "" + +msgid "Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional." +msgstr "" + +msgid "Text to display at the bottom of the view. May contain an explanation or links or whatever you like. Optional." +msgstr "" + +msgid "Empty Text" +msgstr "" + +msgid "Text to display if a view returns no nodes. Optional." +msgstr "" + +msgid "Provide Menu" +msgstr "" + +msgid "If checked this view be given a menu entry in the Drupal menu system. If not checked the data in this group will be ignored." +msgstr "" + +msgid "Provide Menu as Tab" +msgstr "" + +msgid "If checked this view's menu entry will be provided as a tab rather than in the main menu system." +msgstr "" + +msgid "Tab Weight" +msgstr "" + +msgid "If this is a menu tab, select the weight; lower numbers will be further to the left." +msgstr "" + +msgid "Menu Title" +msgstr "" + +msgid "Enter the title to use for the menu entry or tab. If blank, the page title will be used." +msgstr "" + +msgid "Default Menu Tab" +msgstr "" + +msgid "Make Default Menu Tab" +msgstr "" + +msgid "If checked this view's menu entry will be provided as a tab, and will be the default tab for that URL path. For example, if the URL is 'tracker/all' and it is set as the default menu tab, it will be put into the menu as 'tracker' and 'tracker/all' will be the default tab. The following settings allow you to customize the parent item, for example 'tracker'. For tabs to work properly, one tab in the group must be set as the default." +msgstr "" + +msgid "Parent Menu Item Type" +msgstr "" + +msgid "Tab" +msgstr "Закладка" + +msgid "Normal menu item" +msgstr "Нормальний елемент меню" + +msgid "Already exists (don't create)" +msgstr "" + +msgid "Select type of parent item to use for this default menu tab. You can either specify the parent should be a tab (the default), a normal menu item, or to use the menu item that already exists at the specified URL. For example, if the URL for the default tab is 'tracker/all', then 'tracker' would already have to be a valid menu item to use this final choice." +msgstr "" + +msgid "If the parent menu item is a tab, select the weight; lower numbers will be further to the left." +msgstr "" + +msgid "Parent Menu Item Title" +msgstr "" + +msgid "If the Parent Menu Item is being defined by this view (if you set the %type_field to either %tab or %menu), you can specify its title here. If blank, the menu title will be used if that is defined, or the page title if not." +msgstr "" + +msgid "Provide Block" +msgstr "" + +msgid "If checked this view will be provided as a block. If checked title may not be blank." +msgstr "" + +msgid "The title that will be shown at the top of the block. May be blank." +msgstr "" + +msgid "Nodes per Block" +msgstr "" + +msgid "If using a block, the maximum number of items to display in the block. Pagers are not used in blocks." +msgstr "" + +msgid "[More] Link?" +msgstr "" + +msgid "If using a view as both a page and a block, display a more link in the block that links to the view URL?" +msgstr "" + +msgid "Use Page Header" +msgstr "" + +msgid "If checked, use the Page Header for block view instead. If so, you should leave the Block Header blank." +msgstr "" + +msgid "Use Page Footer" +msgstr "" + +msgid "If checked, use the page footer for block view instead. If so, you should leave the block footer blank." +msgstr "" + +msgid "Empty text" +msgstr "Пустий текст" + +msgid "Use Page empty" +msgstr "" + +msgid "If checked, use the Page Empty Text for block view instead. If so, you should leave the block empty text blank." +msgstr "" + +msgid "Text to display if a view results in no nodes. Optional." +msgstr "" + +msgid "Argument Handling Code" +msgstr "" + +msgid "Argument Code" +msgstr "" + +msgid "Advanced Usage Only: PHP code that returns a custom array of arguments for the view. Should not include <?php ?> delimiters." +msgstr "" + +msgid "For more information, please see the <a href=\"!arg\">Argument Handling Code documentation</a> in the Drupal handbook." +msgstr "" + +msgid "Expose" +msgstr "Виставляти" + +msgid "Delete this item." +msgstr "" + +msgid "Move this item up." +msgstr "" + +msgid "Down" +msgstr "Вниз" + +msgid "Move this item down." +msgstr "" + +msgid "Move this item to the top." +msgstr "" + +msgid "Move this item to the bottom." +msgstr "" + +msgid "Handler" +msgstr "Обробник" + +msgid "Option" +msgstr "Параметр" + +msgid "Default Sort" +msgstr "" + +msgid "Fields are only meaningful with List view and Table View; they allow you to choose which fields are presented and in what order." +msgstr "" + +msgid "Argument Type" +msgstr "" + +msgid "Wildcard" +msgstr "Джокер" + +msgid "Wildcard Sub" +msgstr "" + +msgid "Arguments are parsed directly from the URL. They are not necessary to any given view, but allow flexibility." +msgstr "" + +msgid "Arguments" +msgstr "Аргументи" + +msgid "Operator" +msgstr "Оператор" + +msgid "Filters allow you to select a subset of all the nodes to display. All Filters are ANDed together." +msgstr "" + +msgid "Filters" +msgstr "Фільтри" + +msgid "Optional" +msgstr "Необов'язкове" + +msgid "Filter settings Default" +msgstr "" + +msgid "Force Single" +msgstr "" + +msgid "Lock Operator" +msgstr "" + +msgid "Exposed filters will be presented to the viewer. If not set required, then filters will include a \"<None>\" Value if possible. If set default, filters will default as set here, otherwise filter settings will be ignored. If Lock Operator is set, no operator will be made available to the user." +msgstr "" + +msgid "Exposed Filters" +msgstr "" + +msgid "Order" +msgstr "Замовлення" + +msgid "Add criteria" +msgstr "Додати критерій" + +msgid "Sort Criteria" +msgstr "Критерії впорядкування" + +msgid "This view currently has no %s defined." +msgstr "" + +msgid "Ops" +msgstr "" + +msgid "Another user has modified this view, unable to save. You can get this error by using the Back button to re-edit a view after saving one; if you do this, be sure to Reload before making any changes!" +msgstr "" + +msgid "View name is required." +msgstr "" + +msgid "View name must be alphanumeric or underscores only." +msgstr "" + +msgid "View name already in use." +msgstr "" + +msgid "Nodes per page cannot be 0 if using the pager." +msgstr "" + +msgid "If being used as a block, Nodes Per Block must be positive." +msgstr "" + +msgid "View successfully saved." +msgstr "" + +msgid "View successfully added." +msgstr "" + +msgid "List and Table types require at least one field." +msgstr "" + +msgid "You can only set on Default Sort on one field." +msgstr "" + +msgid "View '%vid' not found." +msgstr "" + +msgid "administer views" +msgstr "адмініструвати види" + +msgid "Views module installed tables successfully." +msgstr "" + +msgid "The installation of views module was unsuccessful." +msgstr "" + +msgid "The views module creates customized views of node lists." +msgstr "" + +msgid "Views RSS" +msgstr "" + +msgid "RSS plugin for the views feed selector argument." +msgstr "" + +msgid "Views Theme Wizard" +msgstr "" + +msgid "The views theme wizard helps create stub theming for views." +msgstr "" + +msgid "Views UI" +msgstr "Views UI" + +msgid "The Views UI module allows you to create and edit views." +msgstr "" + +msgid "Book: Parent Node" +msgstr "" + +msgid "This allows you to filter books based on parent node." +msgstr "" + +msgid "Book: Weight" +msgstr "" + +msgid "This will sort the view by book weight, if that is applicable." +msgstr "" + +msgid "Book: Parent Title" +msgstr "" + +msgid "Display the title of the parent node" +msgstr "" + +msgid "Sort by the title of the parent node" +msgstr "" + +msgid "Book: Parent Node ID" +msgstr "" + +msgid "Comment: Subject" +msgstr "Коментар: Тема" + +msgid "With updated mark" +msgstr "" + +msgid "Comment: Comment" +msgstr "" + +msgid "Display the content of a comment." +msgstr "" + +msgid "Comment: Comment ID" +msgstr "" + +msgid "Display the CID of a comment." +msgstr "" + +msgid "Comment: Created Time" +msgstr "" + +msgid "Display the post time of the comment." +msgstr "" + +msgid "Comment: Author Name" +msgstr "" + +msgid "This will display the author of the node." +msgstr "" + +msgid "Comment: Add link" +msgstr "" + +msgid "Display a link to add a comment to the node. Enter the text of this link into the option field; if blank the default \"Comment\" will be used." +msgstr "" + +msgid "Comment: Pending approval" +msgstr "" + +msgid "Equals" +msgstr "Рівне" + +msgid "Sort by the created time of comments." +msgstr "" + +msgid "Comment: Last Comment Time" +msgstr "" + +msgid "This will display the last comment time." +msgstr "" + +msgid "Comment: Last Comment Author" +msgstr "" + +msgid "This will display the name of the last user to comment on the post." +msgstr "" + +msgid "Comment: Count" +msgstr "" + +msgid "With New Count" +msgstr "" + +msgid "This will display the comment count." +msgstr "" + +msgid "Comment: Last Changed Time" +msgstr "" + +msgid "This will display the time of the last comment or node edit." +msgstr "" + +msgid "Comment: Comment Count" +msgstr "" + +msgid "This filter allows you to filter by the amount of comments." +msgstr "" + +msgid "This filter allows nodes to be filtered by the timestamp for the last comment or node edit." +msgstr "" + +msgid "Comment: Last Comment Date" +msgstr "" + +msgid "This will allow you to sort by the date of the most recent comment on a node." +msgstr "" + +msgid "This filter allows you to sort by the number of comments." +msgstr "" + +msgid "Comment: Last Changed" +msgstr "" + +msgid "Sort based on the most recent comment or edit for the node." +msgstr "" + +msgid "@num new" +msgstr "" + +msgid "Display recent comments block" +msgstr "" + +msgid "Recent comments" +msgstr "Останні коментарі" + +msgid "Node: Title" +msgstr "" + +msgid "Display the title of the node." +msgstr "" + +msgid "Node: ID" +msgstr "" + +msgid "Display the NID of a node." +msgstr "" + +msgid "Node: Created Time" +msgstr "" + +msgid "Display the post time of the node." +msgstr "" + +msgid "The option field may be used to specify the custom date format as it's required by the date() function or if \"as time ago\" has been chosen to customize the granularity of the time interval." +msgstr "" + +msgid "Node: Updated Time" +msgstr "" + +msgid "Display the last time the node was updated." +msgstr "" + +msgid "Node: Type" +msgstr "" + +msgid "The Node Type field will display the type of a node (for example, 'blog entry', 'forum post', 'story', etc)" +msgstr "" + +msgid "Node: Link to node" +msgstr "" + +msgid "This will create a link to the node; fill the option field with the text for the link. If you want titles that link to the node, use Node: Title instead." +msgstr "" + +msgid "Node: Body" +msgstr "" + +msgid "Full Text" +msgstr "Повний текст" + +msgid "Display the Main Content." +msgstr "" + +msgid "Node: View link" +msgstr "" + +msgid "Display a link to view the node. Enter the text of this link into the option field; if blank the default \"View\" will be used." +msgstr "" + +msgid "Node: Edit link" +msgstr "" + +msgid "Return To View" +msgstr "" + +msgid "Return to Node" +msgstr "" + +msgid "Display a link to edit the node. Enter the text of this link into the option field; if blank the default \"Edit\" will be used." +msgstr "" + +msgid "Node: Delete link" +msgstr "" + +msgid "Return To The Frontpage" +msgstr "" + +msgid "Display a link to delete the node. Enter the text of this link into the option field; if blank the default \"Delete\" will be used." +msgstr "" + +msgid "Sort by the database ID of the node." +msgstr "" + +msgid "Sort by the submission date of the node." +msgstr "" + +msgid "Sort by the last update date of the node." +msgstr "" + +msgid "Node: Sticky" +msgstr "" + +msgid "Sort by whether or not the node is sticky. Choose descending to put sticky nodes at the top." +msgstr "" + +msgid "Sort by the node title, alphabetically" +msgstr "" + +msgid "Sort by the node type, alphabetically" +msgstr "" + +msgid "Random" +msgstr "Випадково" + +msgid "By choosing random, nodes will be ordered completely randomly. This is a good way to choose X random nodes from a group of nodes." +msgstr "" + +msgid "Node: Published" +msgstr "" + +msgid "Filter by whether or not the node is published. This is recommended for most Views!" +msgstr "" + +msgid "Node: Front Page" +msgstr "" + +msgid "Filter by whether or not the node has been promoted to Front Page." +msgstr "" + +msgid "Filter by whether or not the node is set sticky." +msgstr "" + +msgid "Node: Moderated" +msgstr "" + +msgid "Filter by whether or not the node is moderated." +msgstr "" + +msgid "Include or exclude nodes of the selected types." +msgstr "" + +msgid "Node: Author is Anonymous" +msgstr "" + +msgid "This allows you to filter by whether or not the node author is anonymous." +msgstr "" + +msgid "Node: Author is Current User" +msgstr "" + +msgid "This allows you to filter by whether or not the node was authored by the logged in user of the view." +msgstr "" + +msgid "Node: Current User Authored or Commented" +msgstr "" + +msgid "This allows you to filter by whether or not the logged in user authored or commented on the node." +msgstr "" + +msgid "Node: Distinct" +msgstr "" + +msgid "This filter ensures that each node may only be listed once, even if it matches multiple criteria. Use this if multiple taxonomy matches return duplicated nodes." +msgstr "" + +msgid "This filter allows nodes to be filtered by their title." +msgstr "" + +msgid "This filter allows nodes to be filtered by their creation date." +msgstr "" + +msgid "This filter allows nodes to be filtered by the time they were updated." +msgstr "" + +msgid "This filter allows nodes to be filtered by their body." +msgstr "" + +msgid "Node: Has New Content" +msgstr "" + +msgid "Including this filter will reduce the node set to nodes that have been updated or have new content since the user last read the node, as well as unread nodes." +msgstr "" + +msgid "The node type argument allows users to filter a view by specifying the type of node." +msgstr "" + +msgid "The argument will filter by the node title. For this argument, set the option to the number of characters, using 0 for full term; use 1 for an A/B/C style glossary." +msgstr "" + +msgid "Node: Posted Year" +msgstr "" + +msgid "This argument allows users to filter by what year the node was posted, in the form of CCYY." +msgstr "" + +msgid "Node: Posted Month" +msgstr "" + +msgid "Months are specified by the numbers 1-12. Since this argument does not specify a year, it is recommended that it usually follow a 'Year' argument." +msgstr "" + +msgid "Node: Posted Week" +msgstr "" + +msgid "This allows the user to filter a view by the week number from 1-52. It is recommended this argument follow a 'Year' argument." +msgstr "" + +msgid "Node: Posted Month + Year" +msgstr "" + +msgid "This argument combines Month and Year into a single argument, specified in the form CCYYMM." +msgstr "" + +msgid "Node: Posted Full Date" +msgstr "" + +msgid "This argument is a complete date in the form of CCYYMMDD." +msgstr "" + +msgid "This argument is a single Node ID." +msgstr "" + +msgid "Node: Feed Selector" +msgstr "" + +msgid "This argument allows pluggable \"feed\" selectors. If using views_rss module, \"feed\" will turn the view into an RSS feed. Other modules may provide their own feeds. You may enter the title the feed will advertise in the title field here. If the feed type offers a description, enter the description of the feed in the option field here." +msgstr "" + +msgid "The basic front page view." +msgstr "" + +msgid "Untitled" +msgstr "Без назви" + +msgid "Profile: @field-name" +msgstr "" + +msgid "This will display all options of the profile field %field-name. " +msgstr "" + +msgid "Display the date of the %field-name field." +msgstr "" + +msgid "Checkbox based profile field help" +msgstr "" + +msgid "Other types based profile field help" +msgstr "" + +msgid "This allows you to sort by vocabulary terms" +msgstr "" + +msgid "This allows you to sort by selection options" +msgstr "" + +msgid "This allows you to sort by date" +msgstr "" + +msgid "This allows you to sort yes/no" +msgstr "" + +msgid "Taxonomy based profile field help" +msgstr "" + +msgid "Selection based profile field help" +msgstr "" + +msgid "Search: Index" +msgstr "" + +msgid "Node: Total Hits" +msgstr "" + +msgid "This will display the number of times a node has been read." +msgstr "" + +msgid "Node: Recent Hits" +msgstr "" + +msgid "This will display the number of times a node has been read recently." +msgstr "" + +msgid "Node: Last Hit Time" +msgstr "" + +msgid "Display the time the node was last read." +msgstr "" + +msgid "This allows you to sort by the number of times a node has been read." +msgstr "" + +msgid "This allows you to sort by the number of times a node has been read recently." +msgstr "" + +msgid "This allows you to sort by the time a node was last read." +msgstr "" + +msgid "Nodes sorted by recent page-views" +msgstr "" + +msgid "Recent popular content" +msgstr "Популярне останнім часом" + +msgid "Recent hits" +msgstr "Останні хіти" + +msgid "Nodes sorted by total page-views" +msgstr "" + +msgid "All-time popular content" +msgstr "Популярне за весь час" + +msgid "Reads" +msgstr "" + +msgid "Taxonomy: Terms for @voc-name" +msgstr "" + +msgid "This will display all taxonomy terms associated with the node that are members of %voc-name. Note that this causes one extra query per row displayed, and might have a minor performance impact." +msgstr "" + +msgid "Only terms associated with %voc-name will appear in the select box for this filter. When filtering by taxonomy term you may specify the 'depth' as an option. Please see the taxonomy help for more information." +msgstr "" + +msgid "Taxonomy: Term" +msgstr "" + +msgid "This will display one of the taxonomy terms associated with the node; if taxonomy terms were used to filter or sort, it will be the one that triggered the sort or filter." +msgstr "" + +msgid "Taxonomy: Term Description" +msgstr "" + +msgid "This will display the description associated with a taxonomy term." +msgstr "" + +msgid "Taxonomy: Term Name" +msgstr "" + +msgid "This will sort nodes by taxonomy weight and name, as defined in the category administration." +msgstr "" + +msgid "Taxonomy: Vocabulary Name" +msgstr "" + +msgid "This will filter a view to only nodes that contain a term in the associated vocabulary." +msgstr "" + +msgid "Taxonomy: Term ID" +msgstr "" + +msgid "The argument will filter by a taxonomy term ID. For this argument, set the option to the depth to search. See taxonomy for more information." +msgstr "" + +msgid "The argument will filter by a taxonomy term name. For this argument, set the option to the number of characters, using 0 for full term; use 1 for an A/B/C style glossary." +msgstr "" + +msgid "Taxonomy: Vocabulary ID" +msgstr "" + +msgid "The argument will filter to nodes with terms in a vocabulary." +msgstr "" + +msgid "The taxonomy view with a depth of 0." +msgstr "" + +msgid "Uncategorized" +msgstr "Без категорії" + +msgid "Uncatgorized" +msgstr "" + +msgid "File: Id" +msgstr "" + +msgid "File Id which represents the file." +msgstr "Файл Id, який представляє файл." + +msgid "Sort by File Id" +msgstr "" + +msgid "File: Has file downloads" +msgstr "" + +msgid "Filter whether the node has files for download" +msgstr "" + +msgid "File: Listed in file downloads" +msgstr "" + +msgid "Filter whether the file is listed in downloads" +msgstr "" + +msgid "File: All files" +msgstr "" + +msgid "All files" +msgstr "Всі файли" + +msgid "Listed files" +msgstr "" + +msgid "File names with links" +msgstr "" + +msgid "File names without links" +msgstr "" + +msgid "File descriptions with links" +msgstr "" + +msgid "File descriptions without links" +msgstr "" + +msgid "Display all attached files in one field." +msgstr "" + +msgid "File: Name" +msgstr "" + +msgid "Plain" +msgstr "Простий" + +msgid "With download link" +msgstr "З посиланням завантаження" + +msgid "Display file name" +msgstr "Відобразити ім'я файлу" + +msgid "File: Path" +msgstr "" + +msgid "Display Path to File." +msgstr "Показати шлях до файлу." + +msgid "File: Size" +msgstr "" + +msgid "Display the size of the associated file." +msgstr "" + +msgid "File: Mime type" +msgstr "" + +msgid "This filter allows nodes to be filtered by mime type." +msgstr "Цей фільтр дозволяє повідомлення фільтруватися типом MIME." + +msgid "File: Filename" +msgstr "" + +msgid "This filter allows nodes to be filtered by the name of attached files." +msgstr "" + +msgid "This filter allows nodes to be filtered by file size." +msgstr "" + +msgid "File: Sort by Filename" +msgstr "" + +msgid "Sort by file name" +msgstr "" + +msgid "File: File size" +msgstr "" + +msgid "Sort by file size." +msgstr "" + +msgid "Sort by mime type." +msgstr "" + +msgid "Node: Author Name" +msgstr "" + +msgid "User: Author Picture" +msgstr "" + +msgid "Display the user picture of the author." +msgstr "Показати зображення автора." + +msgid "This allows you to sort alphabetically by author." +msgstr "" + +msgid "This allows you to filter by a particular user. You might not find this useful if you have a lot of users." +msgstr "" + +msgid "Node: Authors in role %role-name" +msgstr "" + +msgid "Only users in role %role-name will appear in the select box for this filter." +msgstr "" + +msgid "Role: Author Role" +msgstr "" + +msgid "Include the node only if the author is a member of the selected role." +msgstr "" + +msgid "User: UID is Author" +msgstr "" + +msgid "The User ID argument allows users to filter to nodes authored by the specified user ID." +msgstr "" + +msgid "User: UID Authored or Commented" +msgstr "" + +msgid "The User ID argument allows users to filter a to nodes authored or commented on the specified user ID." +msgstr "" + +msgid "User: Username is Author" +msgstr "" + +msgid "views_handler_arg_username" +msgstr "" + +msgid "The Username argument allows users to file to a nodes authored by the specified username." +msgstr "" + +msgid "Shows all new activity on system." +msgstr "" + +msgid "recent posts for %1" +msgstr "" + +msgid "Currently Logged In User" +msgstr "" + +msgid "Position" +msgstr "Розташування" + +msgid "Basic settings" +msgstr "Базові параметри" + +msgid "Last checked" +msgstr "Востаннє перевірено" + +msgid "Profile" +msgstr "Профіль" + +msgid "filters" +msgstr "фільтри" + +msgid "Term description" +msgstr "Опис терміна" + +msgid "fields" +msgstr "поля" + +msgid "reply" +msgstr "відповісти" + +msgid "Defaults" +msgstr "Типово" + +msgid "=" +msgstr "=" + +msgid "Sort by" +msgstr "Сортувати за" + +msgid "Created date" +msgstr "Дата створення" + +msgid "Updated date" +msgstr "Дата оновлення" + +msgid "Default language" +msgstr "Базова мова" + +msgid "Other queries" +msgstr "Інші запити" + +msgid "Timer" +msgstr "Таймер" + +msgid "in" +msgstr "в" + +msgid "Full text" +msgstr "Повний текст" + +msgid "Feed settings" +msgstr "Налаштування вибірок" + +msgid "Source" +msgstr "Джерело" + +msgid "Replacement patterns" +msgstr "Шаблони заміни" + +msgid "Query" +msgstr "Запит" + +msgid "Hour" +msgstr "Година" + +msgid "Minute" +msgstr "Хвилина" + +msgid "Second" +msgstr "Секунда" + +msgid "Granularity" +msgstr "Деталізація" + +msgid "Moderated" +msgstr "Модеровано" + +msgid "Alignment" +msgstr "Вирівнювання" + +msgid "Link label" +msgstr "" + +msgid "Revert" +msgstr "Відновити" + +msgid "or" +msgstr "або" + +msgid "Convert" +msgstr "Перетворити" + +msgid "Parent term" +msgstr "Терм-попередник" + +msgid "Style" +msgstr "Стиль" + +msgid "revert" +msgstr "повернути" + +msgid "Last modified" +msgstr "Востаннє змінено" + +msgid "Reverse" +msgstr "Зворотній" + +msgid "Thousands separator" +msgstr "Розділювач тисяч" + +msgid "Unformatted" +msgstr "Неформатоване" + +msgid "RSS Feed" +msgstr "RSS потік" + +msgid "New comments" +msgstr "Новий коментар" + +msgid "Relationships" +msgstr "Зв'язки" + +msgid "Plural" +msgstr "Множина" + +msgid "Relationship" +msgstr "Зв'язок" + +msgid "relationships" +msgstr "зв'язки" + +msgid "Sort criteria" +msgstr "Критерій сортування" + +msgid "Parent menu item" +msgstr "Батьківський елемент меню" + +msgid "Translations" +msgstr "Переклади" + +msgid "Sticky" +msgstr "Приліпити" + +msgid "Read only" +msgstr "Тільки для читання" + +msgid "Ok" +msgstr "Гаразд" + +msgid "Output format" +msgstr "Вихідний формат" + +msgid "Storage" +msgstr "Накопичувач" + +msgid "Apply" +msgstr "Застосувати" + +msgid "Enter the terms you wish to search for." +msgstr "Впишіть слова для пошуку." + +msgid "Information" +msgstr "Інформація" + +msgid "PHP Code" +msgstr "Код PHP" + +msgid "Translation" +msgstr "Переклад" + +msgid "Translation status" +msgstr "Статус перекладу" + +msgid "@min and @max" +msgstr "@min та @max" + +msgid "Full node" +msgstr "Повний матеріал" + +msgid "Precision" +msgstr "Точність" + +msgid "Permission" +msgstr "Повноваження" + +msgid "Grid" +msgstr "Ґратка" + +msgid "Hide" +msgstr "Сховати" + +msgid "Read/Write" +msgstr "Читати/Писати" + +msgid "Global" +msgstr "Глобальне" + +msgid "arguments" +msgstr "аргументи" + +msgid "Thread" +msgstr "Гілки" + +msgid "You must include at least one positive keyword with @count characters or more." +msgstr "Вам необхідно вказати хоча б одне ключове слово, що містить не менше @count символів." + +msgid "Distinct" +msgstr "Окремий" + +msgid "<None>" +msgstr "<Нічого>" + +msgid "Node access" +msgstr "" + +msgid "<Any>" +msgstr "<любе>" + +msgid "Rearrange" +msgstr "Пересортувати" + +msgid "empty" +msgstr "пусто" + +msgid "Aggregator" +msgstr "Підбірка новин" + +msgid "Attach to" +msgstr "Приєднати до" + +msgid "Argument type" +msgstr "Тип аргументу" + +msgid "Attached files" +msgstr "Вкладені файли" + +msgid "Remove this item" +msgstr "Видалити цей елемент" + +msgid "No title" +msgstr "Без заголовку" + +msgid "Module name" +msgstr "Ім'я модуля" + +msgid "Enter the module name to export code to." +msgstr "" + +msgid "Page settings" +msgstr "Параметри сторінки" + +msgid "Use pager" +msgstr "Використовувати сторінковість" + +msgid "Items to display" +msgstr "Відображати елементів" + +msgid "Offset" +msgstr "Зміщення" + +msgid "More link" +msgstr "Посилання \"ще(далі)\"" + +msgid "More link text" +msgstr "" + +msgid "Edit this view" +msgstr "Правити вид" + +msgid "Book parent" +msgstr "" + +msgid "Top level book" +msgstr "" + +msgid "contains" +msgstr "містить" + +msgid "Selection type" +msgstr "Тип вибору" + +msgid "No name" +msgstr "Без назви" + +msgid "Validation error, please try again. If this error persists, please contact the site administrator." +msgstr "Помилка при перевірці значення, будь-ласка, спробуйте ще. Якщо помилка повториться, повідомте адміністратора сайту." + +msgid "In moderation" +msgstr "В модерації" + +msgid "Ordered list" +msgstr "Нумерований список" + +msgid "Unordered list" +msgstr "Ненумерований список" + +msgid "Case sensitive" +msgstr "Враховувати регістр" + +msgid "Link class" +msgstr "" + +msgid "Column" +msgstr "Стовпець" + +msgid "Default sort" +msgstr "Базове сортування" + +msgid "sort by @s" +msgstr "сортувати за @s" + +msgid "and" +msgstr "і" + +msgid "Add @type" +msgstr "Додати @type" + +msgid "Nid" +msgstr "Nid" + +msgid "Parent comment" +msgstr "Батьківський коментар" + +msgid "The parent comment." +msgstr "Батьківський коментар." + +msgid "Author's website" +msgstr "Сайт автора" + +msgid "Display the depth of the comment if it is threaded." +msgstr "" + +msgid "Sort by the threaded order. This will keep child comments together with their parents." +msgstr "" + +msgid "Reply-to link" +msgstr "Посилання відповіді" + +msgid "Provide a simple link to reply to the comment." +msgstr "" + +msgid "Text to display" +msgstr "Текст для виду" + +msgid "Link this field to its user or an author's homepage" +msgstr "" + +msgid "field" +msgstr "поле" + +msgid "The node the uploaded file is attached to" +msgstr "" + +msgid "View settings" +msgstr "Параметри видів" + +msgid "Week @week" +msgstr "Тиждень @week" + +msgid "Delete view" +msgstr "Стерти вид" + +msgid "Time ago" +msgstr "Часу назад" + +msgid "The taxonomy vocabulary ID" +msgstr "" + +msgid "The taxonomy term ID" +msgstr "" + +msgid "Force single" +msgstr "Примусово одиничний" + +msgid "The language the content is in." +msgstr "" + +msgid "Title only" +msgstr "Тільки назва" + +msgid "Validator" +msgstr "Перевірка" + +msgid "Inherit" +msgstr "Залежність" + +msgid "Mime type" +msgstr "MIME Тип" + +msgid "Use default" +msgstr "Використовувати базове" + +msgid "The weight, used for sorting." +msgstr "" + +msgid "The date the node was last updated." +msgstr "" + +msgid "In the form of WW (01 - 53)." +msgstr "У форматі ТТ (01 - 53)." + +msgid "Category ID" +msgstr "" + +msgid "!group: !field" +msgstr "!group: !field" + +msgid "Invalid display id @display" +msgstr "" + +msgid "Error: handler for @table > @field doesn't exist!" +msgstr "" + +msgid "Do not use a relationship" +msgstr "" + +msgid "Display type" +msgstr "Тип виду" + +msgid "The cache has been cleared." +msgstr "Кеш - очищено!" + +msgid "Default sort order" +msgstr "Базове сортування" + +msgid "An error occurred at @path." +msgstr "Помилка на @path." + +msgid "No link" +msgstr "Без посилання" + +msgid "Path: !path" +msgstr "Шлях: !path" + +msgid "Is not one of" +msgstr "Жоден з" + +msgid "Analyze" +msgstr "Аналіз" + +msgid "Admin" +msgstr "Адмін" + +msgid "Starts with" +msgstr "Починається з" + +msgid "Autocomplete" +msgstr "Автодоповнення" + +msgid "Decimal point" +msgstr "Десяткова кома" + +msgid "Permanent" +msgstr "Постійна" + +msgid "Temporary" +msgstr "Тимчасово" + +msgid "Custom date format" +msgstr "Власний формат дати" + +msgid "Is one of" +msgstr "Один з" + +msgid "Access will be granted to users with the specified permission string." +msgstr "Доступ буде надано користувачам вказаного рядка повноважень" + +msgid "Show All" +msgstr "Показати все" + +msgid "Nodes are a Drupal site's primary content." +msgstr "Матеріал є основним вмістом сайтів на Drupal." + +msgid "Comments are responses to node content." +msgstr "Коментарі є відгуками на матеріал вмісту." + +msgid "Users who have created accounts on your site." +msgstr "" + +msgid "!group: !title" +msgstr "!group: !title" + +msgid "!=" +msgstr "!=" + +msgid "Is empty (NULL)" +msgstr "Пусто (NULL)" + +msgid "Is not empty (NULL)" +msgstr "Не пусто (NOT NULL)" + +msgid "not empty" +msgstr "не пусто" + +msgid "Theming information" +msgstr "Інформація для розробки шаблонів" + +msgid "Ends with" +msgstr "Закінчується на" + +msgid "Upload date" +msgstr "Дата завантаження" + +msgid "Do not cache" +msgstr "Не кешувати" + +msgid "Action to take if argument is not present" +msgstr "" + +msgid "If this value is received as an argument, the argument will be ignored; i.e, \"all values\"" +msgstr "" + +msgid "Wildcard title" +msgstr "Джокер назви" + +msgid "The title to use for the wildcard in substitutions elsewhere." +msgstr "" + +msgid "<Basic validation>" +msgstr "<Базова перевірка>" + +msgid "Action to take if argument does not validate" +msgstr "" + +msgid "Link this field to its user" +msgstr "" + +msgid "This will override any other link you have set." +msgstr "" + +msgid "Overwrite the value to display for anonymous users" +msgstr "" + +msgid "If selected, you will see a field to enter the text to use for anonymous users." +msgstr "" + +msgid "Text to display for anonymous users" +msgstr "" + +msgid "Use default RSS settings" +msgstr "Використовувати стандартні налаштування RSS" + +msgid "Title plus teaser" +msgstr "Назва плюс анонс" + +msgid "Front page feed" +msgstr "Стрічка головної сторінки" + +msgid "This will appear as the name of this block in administer >> site building >> blocks." +msgstr "" + +msgid "The node ID of the node." +msgstr "Ідентифікатор матеріалу" + +msgid "Tab weight" +msgstr "Вага закладки" + +msgid "No role" +msgstr "Без ролі" + +msgid "View link" +msgstr "Показати посилання" + +msgid "The size of the file." +msgstr "Розмір файлу" + +msgid "Link this field" +msgstr "" + +msgid "Only show \"listed\" file attachments" +msgstr "" + +msgid "Link this field to its node" +msgstr "" + +msgid "Delete link" +msgstr "Посилання на видалення" + +msgid "Filter the view to the currently logged in user." +msgstr "" + +msgid "Cache once for everything (global)" +msgstr "Кеш разово для всього (глобально)" + +msgid "Per page" +msgstr "Для сторінки" + +msgid "Per role" +msgstr "Для ролі" + +msgid "Per role per page" +msgstr "Для ролі і для сторінки" + +msgid "Per user" +msgstr "Для користувача" + +msgid "Per user per page" +msgstr "Для користувача і для сторінки" + +msgid "Has Avatar" +msgstr "Має Аватар" + +msgid "Display the node with standard node view." +msgstr "Показує матеріал з стандартним видом." + +msgid "Capitalize first letter" +msgstr "Виправлення першої букви" + +msgid "Uid" +msgstr "Uid" + +msgid "Custom text" +msgstr "Свій текст" + +msgid "Default argument" +msgstr "Базовий аргумент" + +msgid "Yes/No" +msgstr "Так/Ні" + +msgid "No fields available." +msgstr "Недоступні поля" + +msgid "Numeric" +msgstr "Числовий" + +msgid "Alt text" +msgstr "Альтернативний текст" + +msgid "Edit link" +msgstr "Посилання на редагування" + +msgid "Broken handler @table.@field" +msgstr "Втрачено handler @table.@field" + +msgid "Skipping broken view @view" +msgstr "Пропущено поломаний вид @view" + +msgid "Ajax callback for view loading." +msgstr "Ajax callback для завантаження вида." + +msgid "The converter will make a best-effort attempt to convert a Views 1 view to Views 2. This conversion is not reliable; you will very likely have to make adjustments to your view to get it to match. You can import Views 1 views through the normal Import tab." +msgstr "" + +msgid "Changes cannot be made to a locked view." +msgstr "Зміни не можуть бути зроблені до заблокованого виду." + +msgid "Convert stored Views 1 views." +msgstr "Конвертувати збережений View 1 view." + +msgid "Convert view" +msgstr "Конвертація виду" + +msgid "Create customized lists and queries from your database." +msgstr "Створення видозмінених видів і запитів з Вашої Бази Даних" + +msgid "Administrative interface to views. Without this module, you cannot create or edit your views." +msgstr "Адміністративний інтерфейс для видів. Без цього модуля Ви не зможете створювати або змінювати Ваші види." + +msgid "Example table" +msgstr "Таблиця приклад" + +msgid "Example table contains example content and can be related to nodes." +msgstr "Таблиця прикладів відображає варіанти і може бути застосована для матеріалів." + +msgid "Example content" +msgstr "Матеріал приклад" + +msgid "Some example content that references a node." +msgstr "Деякі приклади, пов'язані з матеріалами" + +msgid "Example node" +msgstr "Матеріал приклад" + +msgid "Plain text field" +msgstr "Поле чистого тексту" + +msgid "Just a plain text field." +msgstr "Просто поле з просто текстом." + +msgid "Numeric field" +msgstr "Цифрове поле" + +msgid "Just a numeric field." +msgstr "Просто поле з просто цифр." + +msgid "Boolean field" +msgstr "Булеве поле" + +msgid "Just an on/off field." +msgstr "Просто поле так/ні, 1/0, ввімкнено/вимкнено" + +msgid "Timestamp field" +msgstr "Поле моменту часу" + +msgid "Just a timestamp field." +msgstr "Просто поле для часу" + +msgid "Emulates the default Drupal front page; you may set the default home page path to this view to make it your front page." +msgstr "Емулює базову головну сторінку Друпал; Ви можете встановити базовою сторінкою сайту цей вид, щоб спробувати різні модифікації головної сторінки" + +msgid "The title to use when this argument is present. It will override the title of the view and titles from previous arguments. You can use percent substitution here to replace with argument titles. Use \"%1\" for the first argument, \"%2\" for the second, etc." +msgstr "" + +msgid "The Breadcrumb title to use when this argument is present. If no breadcrumb is setted here, default Title values will be used, see \"Title\" for percent substitutions." +msgstr "" + +msgid "Validator options" +msgstr "Параметри перевірки" + +msgid "Display all values" +msgstr "Показувати всі значення" + +msgid "Hide view / Page not found (404)" +msgstr "Сховати вид / Сторінку не знайдено (404)" + +msgid "Display empty text" +msgstr "Відображати пустий текст" + +msgid "Provide default argument" +msgstr "Вказати аргумент по замовчуванню" + +msgid "Provide default argument options" +msgstr "" + +msgid "Default argument type" +msgstr "Базовий тип аргумента" + +msgid "Broken/missing handler" +msgstr "Пошкоджена/відсутня оболонка" + +msgid "The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item." +msgstr "" + +msgid "Current date" +msgstr "Поточна дата" + +msgid "Current node's creation time" +msgstr "" + +msgid "Current node's update time" +msgstr "" + +msgid "Allow multiple terms per argument." +msgstr "Дозволити багато термінів на аргумент" + +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 (for OR) or 1,2,3 (for AND)." +msgstr "" + +msgid "Allow multiple arguments to work together." +msgstr "Дозволити багато аргументів в спільній роботі" + +msgid "If selected, multiple instances of this argument can work together, as though multiple terms were supplied to the same argument. This setting is not compatible with the \"Reduce duplicates\" setting." +msgstr "" + +msgid "Do not display items with no value in summary" +msgstr "" + +msgid "Invalid input" +msgstr "Некоректний ввід" + +msgid "Fail basic validation if any argument is given" +msgstr "" + +msgid "By checking this field, you can use this to make sure views with more arguments than necessary fail validation." +msgstr "" + +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 or 1,2,3." +msgstr "" + +msgid "Exclude the argument" +msgstr "Пропук аргумента" + +msgid "If selected, the numbers entered in the argument will be excluded rather than limiting the view." +msgstr "" + +msgid "Glossary mode" +msgstr "Режим глосарію" + +msgid "Glossary mode applies a limit to the number of characters used in the argument, which allows the summary view to act as a glossary." +msgstr "" + +msgid "Character limit" +msgstr "Лімит символа" + +msgid "How many characters of the argument to filter against. If set to 1, all fields starting with the letter in the argument would be matched." +msgstr "" + +msgid "When printing the argument result, how to transform the case." +msgstr "" + +msgid "No transform" +msgstr "Без перетворення" + +msgid "Upper case" +msgstr "Великі літери" + +msgid "Lower case" +msgstr "Малі літери" + +msgid "Capitalize each word" +msgstr "Виправлення першої літери в кожному слові" + +msgid "Case in path" +msgstr "Вибір в шляху" + +msgid "When printing url paths, how to transform the of the argument. Do not use this unless with Postgres as it uses case sensitive comparisons." +msgstr "" + +msgid "Transform spaces to dashes in URL" +msgstr "" + +msgid "The label for this field that will be displayed to end users if the style requires it." +msgstr "" + +msgid "Exclude from display" +msgstr "Прибрати з показу" + +msgid "Check this box to not display this field, but still load it in the view. Use this option to not show a grouping field in each record, or when doing advanced theming." +msgstr "" + +msgid "Rewrite the output of this field" +msgstr "" + +msgid "If checked, you can alter the output of this field by specifying a string of text with replacement tokens that can use any existing field output." +msgstr "" + +msgid "The text to display for this field. You may include HTML. You may enter data from this view as per the \"Replacement patterns\" below." +msgstr "" + +msgid "Output this field as a link" +msgstr "Вивід даного поля посиланням" + +msgid "If checked, this field will be made into a link. The destination must be given below." +msgstr "" + +msgid "Link path" +msgstr "Шлях посилання" + +msgid "The Drupal path or absolute URL for this link. You may enter data from this view as per the \"Replacement patterns\" below." +msgstr "" + +msgid "The CSS class to apply to the link." +msgstr "" + +msgid "Text to place as \"alt\" text which most browsers display as a tooltip when hovering over the link." +msgstr "" + +msgid "Prefix text" +msgstr "Текст-префікс" + +msgid "Any text to display before this link. You may include HTML." +msgstr "" + +msgid "Suffix text" +msgstr "Текст-суфікс" + +msgid "Any text to display after this link. You may include HTML." +msgstr "" + +msgid "<p>You must add some additional fields to this display before using this field. These fields may be marked as <em>Exclude from display</em> if you prefer. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.</p>" +msgstr "" + +msgid "<p>The following substitution patterns are available for this display. Use the pattern shown on the left to display the value indicated on the right. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.</p>" +msgstr "" + +msgid "Trim this field to a maximum length" +msgstr "Скоротити це поле до максимальної довжини" + +msgid "If checked, this field be trimmed to a maximum length in characters." +msgstr "" + +msgid "The maximum number of characters his field can be." +msgstr "Максимальна кількість символів в полі." + +msgid "Trim only on a word boundary" +msgstr "Обрізати тільки слова на межі" + +msgid "If checked, this field be trimmed only on a word boundary. This is guaranteed to be the maximum characters stated or less. If there are no word boundaries this could trim a field to nothing." +msgstr "" + +msgid "Add an ellipsis" +msgstr "Додати три крапки" + +msgid "If checked, a \"...\" will be added if a field was trimmed." +msgstr "" + +msgid "Strip HTML tags" +msgstr "Обмежувати теги HTML" + +msgid "If checked, all HTML tags will be stripped." +msgstr "" + +msgid "Field can contain HTML" +msgstr "Поле може сприймати HTML" + +msgid "If checked, HTML corrector will be run to ensure tags are properly closed after trimming." +msgstr "" + +msgid "File size display" +msgstr "" + +msgid "Formatted (in KB or MB)" +msgstr "" + +msgid "Raw bytes" +msgstr "" + +msgid "True/False" +msgstr "True/False" + +msgid "On/Off" +msgstr "Ввімкнено/Вимкнено" + +msgid "If checked, true will be displayed as false." +msgstr "Відмічене - TRUE буде відображене як FALSE" + +msgid "Time ago (with \"ago\" appended)" +msgstr "" + +msgid "Time span (future dates start with - )" +msgstr "" + +msgid "Time span (with \"ago/hence\" appended)" +msgstr "" + +msgid "If \"Custom\", see <a href=\"http://us.php.net/manual/en/function.date.php\" target=\"_blank\">the PHP docs</a> for date formats. If \"Time ago\" this is the the number of different units to display, which defaults to two." +msgstr "" + +msgid "Round" +msgstr "Округлення" + +msgid "If checked, the number will be rounded." +msgstr "" + +msgid "Specify how many digits to print after the decimal point." +msgstr "" + +msgid "What single character to use as a decimal point." +msgstr "" + +msgid "What single character to use as the thousands separator." +msgstr "" + +msgid "Text to put before the number, such as currency symbol." +msgstr "" + +msgid "Text to put after the number, such as currency symbol." +msgstr "" + +msgid "Simple separator" +msgstr "Простий розділювач" + +msgid "Empty list text" +msgstr "Текст, коли пустий список" + +msgid "If the list is empty, you may enter text here that will be displayed." +msgstr "Якщо список порожній, Ви можете ввести текст тут і його буде відображено." + +msgid "Display as link" +msgstr "Відображати як посилання" + +msgid "This item is currently not exposed. If you <strong>expose</strong> it, users will be able to change the filter as they view it." +msgstr "" + +msgid "This item is currently exposed. If you <strong>hide</strong> it, users will not be able to change the filter as they view it." +msgstr "" + +msgid "Unlock operator" +msgstr "Розблокувати оператор" + +msgid "When checked, the operator will be exposed to the user" +msgstr "" + +msgid "Operator identifier" +msgstr "Ідентифікатор оператора" + +msgid "This will appear in the URL after the ? to identify this operator." +msgstr "" + +msgid "Filter identifier" +msgstr "Ідентифікатор фільтра" + +msgid "This will appear in the URL after the ? to identify this filter. Cannot be blank." +msgstr "" + +msgid "This exposed filter is optional and will have added options to allow it not to be set." +msgstr "" + +msgid "Force this exposed filter to accept only one option." +msgstr "" + +msgid "Remember" +msgstr "Запам'ятати" + +msgid "Remember the last setting the user gave this filter." +msgstr "" + +msgid "The identifier is required if the filter is exposed." +msgstr "" + +msgid "This identifier is not allowed." +msgstr "Ідентифікатор недозволено" + +msgid "- Any -" +msgstr "- любе -" + +msgid "You must select a value unless this is an optional exposed filter." +msgstr "" + +msgid "exposed" +msgstr "відображено" + +msgid "Value type" +msgstr "Тип значення" + +msgid "A date in any machine readable format. CCYY-MM-DD HH:MM:SS is preferred." +msgstr "" + +msgid "An offset from the current time such as \"+1 day\" or \"-2 hours and 30 minutes\"" +msgstr "" + +msgid "Invalid date format." +msgstr "Некоректний формат дати" + +msgid "Limit list to selected items" +msgstr "Ліміт списку обраних пунктів" + +msgid "If checked, the only items presented to the user will be the ones selected here." +msgstr "" + +msgid "not in" +msgstr "не в" + +msgid "<>" +msgstr "<>" + +msgid "Is all of" +msgstr "З всіма" + +msgid "Is none of" +msgstr "Без жодного" + +msgid "not" +msgstr "не" + +msgid "<" +msgstr "<" + +msgid "<=" +msgstr "<=" + +msgid ">=" +msgstr ">=" + +msgid ">" +msgstr ">" + +msgid "Is between" +msgstr "Між" + +msgid "between" +msgstr "між" + +msgid "Is not between" +msgstr "Поза межами" + +msgid "not between" +msgstr "оза межами" + +msgid "Min" +msgstr "Мін" + +msgid "And max" +msgstr "І макс" + +msgid "And" +msgstr "І" + +msgid "Contains any word" +msgstr "Містить будь-яке слово" + +msgid "has word" +msgstr "містить слово" + +msgid "Contains all words" +msgstr "Містить всі слова" + +msgid "has all" +msgstr "містить всі" + +msgid "begins" +msgstr "починається" + +msgid "ends" +msgstr "закінчується" + +msgid "!has" +msgstr "!has" + +msgid "Case sensitive filters may be faster. MySQL might ignore case sensitivity." +msgstr "" + +msgid "The label for this relationship that will be displayed only administratively." +msgstr "" + +msgid "Require this relationship" +msgstr "" + +msgid "If required, items that do not contain this relationship will not appear." +msgstr "" + +msgid "asc" +msgstr "зрост" + +msgid "desc" +msgstr "спад" + +msgid "The granularity is the smallest unit to use when determining whether two dates are the same; for example, if the granularity is \"Year\" then all dates in 1999, regardless of when they fall in 1999, will be considered the same date." +msgstr "" + +msgid "views_handler_sort_formula missing default: @formula" +msgstr "" + +msgid "If you <a href=\"@modules\">enable the advanced help module</a>, Views will provide more and better help. <a href=\"@hide\">Hide this message.</a>" +msgstr "" + +msgid "If you install the advanced help module from !href, Views will provide more and better help. <a href=\"@hide\">Hide this message.</a>" +msgstr "Проінсталювавши advanced help модуль із !href, Views буде описано краще. <a href=\"@hide\">Сховати.</a>" + +msgid "Warning! Broken view!" +msgstr "" + +msgid "Broken" +msgstr "Пошкоджено" + +msgid "Install the advanced help module for the getting started" +msgstr "Проінсталюйте модуль advanced help для початку роботи" + +msgid "Not sure what to do? Try the \"!getting-started\" page." +msgstr "Не впевнені що робити?? Спробуйте \"!getting-started\" сторінку." + +msgid "Displays" +msgstr "Відображення" + +msgid "These queries were run during view rendering:" +msgstr "" + +msgid "[@time ms]" +msgstr "[@time мсек]" + +msgid "This display has no path." +msgstr "Цей вид немає шляху" + +msgid "Query build time" +msgstr "Час побудови запиту" + +msgid "@time ms" +msgstr "@time мсек" + +msgid "Query execute time" +msgstr "Час виконання запиту" + +msgid "View render time" +msgstr "Переглянути час рендерингу" + +msgid "No query was run" +msgstr "Немає запущених запитів" + +msgid "Unable to preview due to validation errors." +msgstr "" + +msgid "Separate arguments with a / as though they were a URL path." +msgstr "" + +msgid "Clone view %view" +msgstr "Копія виду %view" + +msgid "View name" +msgstr "Ім'я Вигляду" + +msgid "This is the unique name of the view. It must contain only alphanumeric characters and underscores; it is used to identify the view internally and to generate unique theming template names for this view. If overriding a module provided view, the name must not be changed or instead a new view will be created." +msgstr "" + +msgid "View description" +msgstr "Опис Вигляду" + +msgid "This description will appear on the Views administrative UI to tell you what the view is about." +msgstr "" + +msgid "View tag" +msgstr "Тег Вигляду" + +msgid "Enter an optional tag for this view; it is used only to help sort views on the administrative page." +msgstr "" + +msgid "The view type is the primary table for which information is being retrieved. The view type controls what arguments, fields, sort criteria and filters are available, so once this is set it <strong>cannot be changed</strong>." +msgstr "" + +msgid "You must use a unique name for this view." +msgstr "" + +msgid "Are you sure you want to revert the view %name?" +msgstr "" + +msgid "Reverting the view will delete the view that is in the database, reverting it to the original default view. Any changes you have made will be lost and cannot be recovered." +msgstr "" + +msgid "Are you sure you want to delete the view %name?" +msgstr "" + +msgid "Deleting a view cannot be undone." +msgstr "" + +msgid "The view has been deleted." +msgstr "Вид видалено." + +msgid "There is no lock on view %view to break." +msgstr "" + +msgid "Are you sure you want to break the lock on view %name?" +msgstr "" + +msgid "By breaking this lock, any unsaved changes made by !user will be lost!" +msgstr "" + +msgid "Break lock" +msgstr "Перервати блокування" + +msgid "The lock has been broken and you may now edit this view." +msgstr "" + +msgid "Edit view %view" +msgstr "Змінити вид %view" + +msgid "Enter the name to use for this view if it is different from the source view. Leave blank to use the name of the view." +msgstr "" + +msgid "Paste view code here" +msgstr "Вставити код виду сюди" + +msgid "Unable to interpret view code." +msgstr "Неможливо інтерпретувати код виду" + +msgid "You are importing a view created in Views version 1. You may need to adjust some parameters to work correctly in version 2." +msgstr "" + +msgid "That view is not compatible with this version of Views." +msgstr "" + +msgid "A view by that name already exists; please choose a different name" +msgstr "" + +msgid "Display plugin @plugin is not available." +msgstr "" + +msgid "Style plugin @plugin is not available." +msgstr "" + +msgid "Row plugin @plugin is not available." +msgstr "" + +msgid "@type handler @table.@field is not available." +msgstr "" + +msgid "Unable to import view." +msgstr "" + +msgid "The view has been saved." +msgstr "" + +msgid "Unknown or missing table name" +msgstr "" + +msgid "Click on an item to edit that item's details." +msgstr "" + +msgid "This view has a broken default display and cannot be used." +msgstr "" + +msgid "Export this view" +msgstr "Експортувати вид" + +msgid "Create a copy of this view" +msgstr "Створити копію даного виду" + +msgid "View \"@display\"" +msgstr "" + +msgid "Go to the real page for this display" +msgstr "" + +msgid "Invalid" +msgstr "Некоректно" + +msgid "Error: Display @display refers to a plugin named '@plugin', but that plugin doesn't exist!" +msgstr "" + +msgid "Missing style plugin" +msgstr "Загублено додаток стилю" + +msgid "Change settings for this style" +msgstr "" + +msgid " Style: !style" +msgstr " Стиль: !style" + +msgid "Invalid display id found while regenerating tabs" +msgstr "" + +msgid "Unable to initialize default display" +msgstr "" + +msgid "Add display" +msgstr "Додати вид" + +msgid "Remove display" +msgstr "Видалити вид" + +msgid "Restore display" +msgstr "Відновити вид" + +msgid "View analysis" +msgstr "Аналізування Вигляду" + +msgid "View details" +msgstr "Деталі Вигляду" + +msgid "Configure @type" +msgstr "Конфігурування @type" + +msgid "Rearrange @type" +msgstr "Пересортування @type" + +msgid "Broken field @id" +msgstr "Втрачене поле @id" + +msgid "There are no @types available to add." +msgstr "" + +msgid "Configure @type %item" +msgstr "" + +msgid "Configure extra settings for @type %item" +msgstr "" + +msgid "Change summary style for @type %item" +msgstr "" + +msgid "Internal error: broken plugin." +msgstr "" + +msgid "Configure summary style for @type %item" +msgstr "" + +msgid "Clear Views' cache" +msgstr "Очистити кеш" + +msgid "Add Views signature to all SQL queries" +msgstr "" + +msgid "All Views-generated queries will include a special 'VIEWS' = 'VIEWS' string in the WHERE clause. This makes identifying Views queries in database server logs simpler, but should only be used when troubleshooting." +msgstr "" + +msgid "Disable views data caching" +msgstr "" + +msgid "Views caches data about tables, modules and views available, to increase performance. By checking this box, Views will skip this cache and always rebuild this data when needed. This can have a serious performance impact on your site." +msgstr "" + +msgid "Ignore missing advanced help module" +msgstr "" + +msgid "Views uses the advanced help module to provide help text; if this module is not present Views will complain, unless this setting is checked." +msgstr "" + +msgid "Show query above live preview" +msgstr "" + +msgid "The live preview feature will show you the output of the view you're creating, as well as the view. Check here to show the query and other information above the view; leave this unchecked to show that information below the view." +msgstr "" + +msgid "Show other queries run during render during live preview" +msgstr "" + +msgid "Drupal has the potential to run many queries while a view is being rendered. Checking this box will display every query run during view render as part of the live preview." +msgstr "" + +msgid "Do not show hover links over views" +msgstr "" + +msgid "To make it easier to administrate your views, Views provides 'hover' links to take you to the edit and export screen of a view whenever the view is used. This can be distracting on some themes, though; if it is problematic, you can turn it off here." +msgstr "" + +msgid "Enable views performance statistics via the Devel module" +msgstr "" + +msgid "Check this to enable some Views query and performance statistics <em>if Devel is installed</em>." +msgstr "" + +msgid "Disable javascript with Views" +msgstr "" + +msgid "If you are having problems with the javascript, you can disable it here; the Views UI should degrade and still be usable without javascript, it just not as good." +msgstr "" + +msgid "Page region to output performance statistics" +msgstr "" + +msgid "Label for \"Any\" value on optional single-select exposed filters" +msgstr "" + +msgid "Error: missing @component" +msgstr "" + +msgid "Server reports invalid input error." +msgstr "" + +msgid "View analysis can find nothing to report." +msgstr "" + +msgid "This view has only a default display and therefore will not be placed anywhere on your site; perhaps you want to add a page or a block display." +msgstr "" + +msgid "There are no Views 1 views stored in the database to convert." +msgstr "" + +msgid "Converted" +msgstr "Конвертовано" + +msgid "The table below lists Views version 1 views that are stored in the database. You can either convert them to work in Views version 2, or delete them. The views are convertible only if there is no Views 2 view with the same name." +msgstr "" + +msgid "Unable to find view." +msgstr "Неможливо знайти вид" + +msgid "Unable to convert view." +msgstr "Неможливо перетворити вид" + +msgid "The view has been deleted" +msgstr "Вид видалено." + +msgid "Handler @handler include tried to loop infinitely!" +msgstr "" + +msgid "Reduce duplicates" +msgstr "Зменшення дублів" + +msgid "This filter can cause items that have more than one of the selected options to appear as duplicate results. If this filter causes duplicate results to occur, this checkbox can reduce those duplicates; however, the more terms it has to search for, the less performant the query will be, so use this with caution." +msgstr "" + +msgid "Default settings for this view." +msgstr "Базові налаштування для виду" + +msgid "Display the view as a page, with a URL and menu links." +msgstr "Відображення вигляду сторінкою, з адресою і елементом меню" + +msgid "Display the view as a block." +msgstr "Відображення вигляду блоком" + +msgid "Attachments added to other displays to achieve multiple views in the same view." +msgstr "Додатки додаються до інших видів для збору кількох видів в один." + +msgid "Display the view as a feed, such as an RSS feed." +msgstr "Відображення вигляду потоком, наприклад RSS" + +msgid "Displays rows one after another." +msgstr "Відображення рядків один за іншим" + +msgid "HTML List" +msgstr "Список HTML" + +msgid "Displays rows as an HTML list." +msgstr "Показувати рядки як HTML-список." + +msgid "Displays rows in a grid." +msgstr "Відображає рядків у сітці." + +msgid "Displays rows in a table." +msgstr "Показувати рядки в таблиці" + +msgid "Displays the default summary as a list." +msgstr "Відображає стандартний анонс списком" + +msgid "Displays the summary unformatted, with option for one after another or inline." +msgstr "Відображає сумарно, неформатовано, з опцією для одного за одним або в лінію." + +msgid "Generates an RSS feed from a view." +msgstr "Ґенерує RSS-стрічку з виду." + +msgid "Displays the fields with an optional template." +msgstr "Відображенян полів з необов'язковим шаблоном" + +msgid "Fixed entry" +msgstr "Фіксований запис" + +msgid "Will be available to all users." +msgstr "Буде доступно всім користувачам" + +msgid "Access will be granted to users with any of the specified roles." +msgstr "Доступ буде надано користувачам будь-якої вказаної ролі" + +msgid "No caching of Views data." +msgstr "Без кешування даних Видів" + +msgid "Time-based" +msgstr "Базовано на часі" + +msgid "Simple time-based caching of data." +msgstr "Просте кешування базоване на часі" + +msgid "set_display() called with invalid display id @display." +msgstr "" + +msgid "sort criteria" +msgstr "критерій сортування" + +msgid "Sort criterion" +msgstr "Критерій сортування" + +msgid "sort criterion" +msgstr "критерій сортування" + +msgid "filter" +msgstr "фільтр" + +msgid "jQuery UI Tabs: Mismatching fragment identifier." +msgstr "" + +msgid "jQuery UI Tabs: Not enough arguments to add tab." +msgstr "" + +msgid "Aggregator items are imported from external RSS and Atom news feeds." +msgstr "" + +msgid "The title of the aggregator item." +msgstr "" + +msgid "The link to the original source URL of the item." +msgstr "" + +msgid "The author of the original imported item." +msgstr "" + +msgid "The actual content of the imported item." +msgstr "" + +msgid "The date the original feed item was posted. (With some feeds, this will be the date it was imported.)" +msgstr "" + +msgid "Feed ID" +msgstr "Feed ID" + +msgid "The unique ID of the aggregator feed." +msgstr "" + +msgid "The title of the aggregator feed." +msgstr "Заголовок агрегатора пункту." + +msgid "The link to the source URL of the feed." +msgstr "Посилання на URL каналу." + +msgid "The date the feed was last checked for new content." +msgstr "" + +msgid "The description of the aggregator feed." +msgstr "" + +msgid "The date of the most recent new content onf the feed." +msgstr "" + +msgid "The unique ID of the aggregator category." +msgstr "" + +msgid "The title of the aggregator category." +msgstr "" + +msgid "Display the aggregator item using the data from the original source." +msgstr "" + +msgid "The book the node is in." +msgstr "" + +msgid "The weight of the book page." +msgstr "" + +msgid "The depth of the book page in the hierarchy; top level books have a depth of 1." +msgstr "" + +msgid "The order of pages in the book hierarchy. If you want the exactly right order, remember to sort by weight, too." +msgstr "" + +msgid "The parent book node." +msgstr "" + +msgid "The title of the comment." +msgstr "Тема коментаря" + +msgid "The text of the comment." +msgstr "Текст коментаря" + +msgid "The comment ID of the field" +msgstr "ID коментаря поля" + +msgid "The name of the comment's author. Can be rendered as a link to the author's homepage." +msgstr "" + +msgid "The website address of the comment's author. Can be rendered as a link. Will be empty if the author is a registered user." +msgstr "" + +msgid "Post date" +msgstr "Дата публікації" + +msgid "Date and time of when the comment was posted." +msgstr "" + +msgid "Whether or not the comment is currently in moderation." +msgstr "" + +msgid "Provide a simple link to view the comment." +msgstr "" + +msgid "Provide a simple link to edit the comment." +msgstr "" + +msgid "Provide a simple link to delete the comment." +msgstr "" + +msgid "Node link" +msgstr "Посилання матеріалу" + +msgid "Display the standard comment link used on regular nodes." +msgstr "" + +msgid "The node the comment is a reply to." +msgstr "" + +msgid "The User ID of the comment's author." +msgstr "ID користувача-автора коментаря" + +msgid "Parent CID" +msgstr "Батьківська CID" + +msgid "The Comment ID of the parent comment." +msgstr "" + +msgid "Last comment time" +msgstr "Час останнього коментаря" + +msgid "Date and time of when the last comment was posted." +msgstr "" + +msgid "Last comment author" +msgstr "Автор останнього коментаря" + +msgid "The name of the author of the last posted comment." +msgstr "" + +msgid "Comment count" +msgstr "Кількість коментарів" + +msgid "The number of comments a node has." +msgstr "" + +msgid "Updated/commented date" +msgstr "Дата оновлення/коментування" + +msgid "The most recent of last comment posted or node updated time." +msgstr "" + +msgid "The number of new comments on the node." +msgstr "" + +msgid "Comment status" +msgstr "Статус коментарів" + +msgid "Whether comments are enabled or disabled on the node." +msgstr "" + +msgid "User posted or commented" +msgstr "" + +msgid "Display nodes only if a user posted the node or commented on the node." +msgstr "" + +msgid "Display the comment with standard comment view." +msgstr "Відображення коментаря стандартним виглядом коментарів" + +msgid "Display the comment as RSS." +msgstr "Показати коментарі у форматі RSS." + +msgid "Link to contact page" +msgstr "" + +msgid "Provide a simple link to the user contact page." +msgstr "" + +msgid "Locale source" +msgstr "Локальне джерело" + +msgid "A source string for translation, in English or the default site language." +msgstr "" + +msgid "LID" +msgstr "LID" + +msgid "The ID of the source string." +msgstr "ID початкового джерела." + +msgid "A description of the location or context of the string." +msgstr "" + +msgid "The group the translation is in." +msgstr "" + +msgid "The full original string." +msgstr "Повний оригінальний текст." + +msgid "The version of Drupal core that this string is for." +msgstr "" + +msgid "Provide a simple link to edit the translations." +msgstr "" + +msgid "Locale target" +msgstr "" + +msgid "The full translation string." +msgstr "" + +msgid "The language this translation is in." +msgstr "" + +msgid "Singular LID" +msgstr "Одинична LID" + +msgid "The ID of the parent translation." +msgstr "ID батьківського перекладу." + +msgid "Whether or not the translation is plural." +msgstr "" + +msgid "The title of the node." +msgstr "Тема матеріалу" + +msgid "The date the node was posted." +msgstr "" + +msgid "The type of a node (for example, \"blog entry\", \"forum post\", \"story\", etc)." +msgstr "" + +msgid "Whether or not the node is published." +msgstr "" + +msgid "Published or admin" +msgstr "Опубліковано або адміністування" + +msgid "Filters out unpublished nodes if the current user cannot view them." +msgstr "" + +msgid "Whether or not the node is promoted to the front page." +msgstr "" + +msgid "Whether or not the node is moderated." +msgstr "" + +msgid "Whether or not the node is sticky." +msgstr "" + +msgid "Provide a simple link to the node." +msgstr "" + +msgid "Provide a simple link to edit the node." +msgstr "" + +msgid "Provide a simple link to delete the node." +msgstr "" + +msgid "In the form of CCYYMMDD." +msgstr "" + +msgid "Created year + month" +msgstr "Рік створення + місяць" + +msgid "In the form of YYYYMM." +msgstr "У форматі РРРРММ." + +msgid "Created year" +msgstr "Рік створення" + +msgid "In the form of YYYY." +msgstr "У форматі РРРР." + +msgid "Created month" +msgstr "Місяць створення" + +msgid "In the form of MM (01 - 12)." +msgstr "У форматі ММ(01 - 12)." + +msgid "Created day" +msgstr "День створення" + +msgid "In the form of DD (01 - 31)." +msgstr "У форматі ДД (01 - 31)." + +msgid "Created week" +msgstr "Тиждень створення" + +msgid "Updated year + month" +msgstr "" + +msgid "Updated year" +msgstr "" + +msgid "Updated month" +msgstr "" + +msgid "Updated day" +msgstr "" + +msgid "Updated week" +msgstr "" + +msgid "Node revision" +msgstr "Ревізія матеріалу" + +msgid "Node revisions are a history of changes to nodes." +msgstr "Ревізія матеріалів це історія змін." + +msgid "Relate a node revision to the user who created the revision." +msgstr "Відносити матеріал до користувача, який створив ревізію." + +msgid "The actual, full data in the body field; this may not be valid data on all node types." +msgstr "" + +msgid "The stored teaser field. This may not be valid or useful data on all node types." +msgstr "" + +msgid "Vid" +msgstr "Vid" + +msgid "The revision ID of the node revision." +msgstr "Ідентифікатор версії матеріалу" + +msgid "The log message entered when the revision was created." +msgstr "" + +msgid "The date the node revision was created." +msgstr "" + +msgid "Input format id" +msgstr "" + +msgid "The numeric input format of the node revision. !default means the default input format." +msgstr "" + +msgid "The name of the input format of the node revision." +msgstr "" + +msgid "Revert link" +msgstr "Посилання повернення" + +msgid "Provide a simple link to revert to the revision." +msgstr "" + +msgid "Provide a simple link to delete the node revision." +msgstr "" + +msgid "Filter by access." +msgstr "" + +msgid "Filter for nodes by view access. <strong>Not necessary if you are using node as your base table.</strong>" +msgstr "" + +msgid "Has new content" +msgstr "Має новий вміст" + +msgid "Show a marker if the node has new or updated content." +msgstr "" + +msgid "Show only nodes that have new content." +msgstr "" + +msgid "Node ID from URL" +msgstr "ID матеріалу з URL" + +msgid "Display %display has no access control but does not contain a filter for published nodes." +msgstr "" + +msgid "Poll" +msgstr "Опитування" + +msgid "Whether the poll is open for voting." +msgstr "" + +msgid "@field-name" +msgstr "@назва поля" + +msgid "Profile textfield" +msgstr "Однорядкове поле введення тексту профілю" + +msgid "Profile textarea" +msgstr "Багаторядкове поле введення тексту профілю" + +msgid "Profile checkbox" +msgstr "Чекбокс профілю" + +msgid "Profile URL" +msgstr "URL профілю" + +msgid "Profile selection" +msgstr "Вибір профілю" + +msgid "Profile freeform list %field-name." +msgstr "Profile freeform list %field-name." + +msgid "Profile date %field-name." +msgstr "Профіль датою %field-name." + +msgid "The score of the search item. This will not be used if the search filter is not also present." +msgstr "" + +msgid "Links from" +msgstr "Посилання з" + +msgid "Other nodes that are linked from the node." +msgstr "" + +msgid "Links to" +msgstr "Посилання на" + +msgid "Other nodes that link to the node." +msgstr "" + +msgid "Search Terms" +msgstr "Пошукові терміни" + +msgid "The terms to search for." +msgstr "Терміни для пошуку." + +msgid "Display the results with standard search view." +msgstr "Відображає результати пошуку з стандартним видом." + +msgid "Node statistics" +msgstr "Статистика матеріалів" + +msgid "Total views" +msgstr "Переглядів" + +msgid "The total number of times the node has been viewed." +msgstr "" + +msgid "Views today" +msgstr "Переглядів сьогодні" + +msgid "The total number of times the node has been viewed today." +msgstr "" + +msgid "Most recent view" +msgstr "Найактуальніший вид" + +msgid "The most recent time the node has been viewed." +msgstr "" + +msgid "Stores site access information." +msgstr "" + +msgid "Browser session ID of user that visited page." +msgstr "" + +msgid "Title of page visited." +msgstr "Заголовок відвідуваної сторінки." + +msgid "Internal path to page visited (relative to Drupal root.)" +msgstr "Внутрішній шлях до відвідуваної сторінки (відносно папки, де встановлено Drupal)." + +msgid "Referrer URI." +msgstr "URI реферала." + +msgid "Hostname of user that visited the page." +msgstr "" + +msgid "The user who visited the site." +msgstr "" + +msgid "Time in milliseconds that the page took to load." +msgstr "" + +msgid "Timestamp of when the page was visited." +msgstr "" + +msgid "Files maintained by Drupal and various modules." +msgstr "" + +msgid "The ID of the file." +msgstr "ID файлу." + +msgid "The name of the file." +msgstr "Ім'я файлу" + +msgid "The path of the file." +msgstr "Шлях до файлу." + +msgid "The mime type of the file." +msgstr "Mime-тип файлу." + +msgid "The status of the file." +msgstr "Статус файлу." + +msgid "The date the file was uploaded." +msgstr "Дата завантаження." + +msgid "Name of the vocabulary a term is a member of. This will be the vocabulary that whichever term the \"Taxonomy: Term\" field is; and can similarly cause duplicates." +msgstr "" + +msgid "Taxonomy terms are attached to nodes." +msgstr "" + +msgid "Taxonomy terms. Note that using this can cause duplicate nodes to appear in views; you must add filters to reduce the result set." +msgstr "" + +msgid "Taxonomy term name." +msgstr "" + +msgid "The term weight field" +msgstr "Термі напівжирного поля" + +msgid "The description associated with a taxonomy term." +msgstr "" + +msgid "Filter the results of \"Taxonomy: Term\" to a particular vocabulary." +msgstr "" + +msgid "All terms" +msgstr "Всі терміни" + +msgid "Display all taxonomy terms associated with a node from specified vocabularies." +msgstr "" + +msgid "The parent term of the term. This can produce duplicate entries if you are using a vocabulary that allows multiple parents." +msgstr "" + +msgid "The parent term of the term." +msgstr "Терм-попередник" + +msgid "Term synonym" +msgstr "Термін синонім" + +msgid "Term synonyms may be used to find terms by alternate names." +msgstr "" + +msgid "Term ID (with depth)" +msgstr "" + +msgid "The depth filter is more complex, so provides fewer options." +msgstr "" + +msgid "Term ID depth modifier" +msgstr "" + +msgid "Allows the \"depth\" for Taxonomy: Term ID (with depth) to be modified via an additional argument." +msgstr "" + +msgid "Node translation" +msgstr "Переклад матеріалу" + +msgid "Translation set node ID" +msgstr "Задати ID перекладу матеріалу" + +msgid "The ID of the translation set the content belongs to." +msgstr "" + +msgid "Source translation" +msgstr "Базовий переклад" + +msgid "The source that this content was translated from." +msgstr "" + +msgid "Versions of content in different languages." +msgstr "" + +msgid "Nodes that are either untranslated or are the original versions of a translation set." +msgstr "" + +msgid "Child translation" +msgstr "Дочірній переклад" + +msgid "Nodes that are translations of a source translation." +msgstr "" + +msgid "The translation status of the node--whether or not the translation needs to be updated." +msgstr "" + +msgid "Outdated" +msgstr "Просрочений" + +msgid "upload" +msgstr "завантажити" + +msgid "The description of the uploaded file." +msgstr "" + +msgid "Listed" +msgstr "Списком" + +msgid "Whether or not the file is marked to be listed." +msgstr "" + +msgid "All files attached to a node with upload.module." +msgstr "" + +msgid "Has attached files" +msgstr "Присутні вкладені файли" + +msgid "Only display items with attached files. This can cause duplicates if there are multiple attached files." +msgstr "" + +msgid "Add a relationship to gain access to more file data for files uploaded by upload.module. Note that this relationship will cause duplicate nodes if there are multiple files attached to the node." +msgstr "" + +msgid "The user ID" +msgstr "ID користувача" + +msgid "The user or author name." +msgstr "Користувач або ім’я автора" + +msgid "Email address for a given user. This field is normally not shown to users, so be cautious when using it." +msgstr "" + +msgid "Language of the user" +msgstr "" + +msgid "The user's picture, if allowed." +msgstr "Зображення користувача. якщо дозволено." + +msgid "The date the user was created." +msgstr "Дата створення користувача." + +msgid "The user's last access date." +msgstr "Дата останнього візиту користувача." + +msgid "The user's last login date." +msgstr "Остання дата входу користувача" + +msgid "Whether a user is active or blocked." +msgstr "" + +msgid "The user's signature." +msgstr "Підпис користувача" + +msgid "Provide a simple link to edit the user." +msgstr "" + +msgid "Provide a simple link to delete the user." +msgstr "" + +msgid "Roles that a user belongs to." +msgstr "" + +msgid "User ID from URL" +msgstr "ІД користувача з Адреси" + +msgid "User ID from logged in user" +msgstr "ІД зареєстрованого користувача" + +msgid "Randomize the display order." +msgstr "Випадковість сортування виду" + +msgid "Null" +msgstr "Зеро" + +msgid "Allow an argument to be ignored. The query will not be altered by this argument." +msgstr "" + +msgid "Provide custom text or link." +msgstr "Занзачити свій текст або посилання" + +msgid "View result counter" +msgstr "Перегляд лічильника результату" + +msgid "Displays the actual position of the view result" +msgstr "" + +msgid "Link this field to its aggregator category page" +msgstr "" + +msgid "No user" +msgstr "Нема користувача" + +msgid "Link this field to its comment" +msgstr "" + +msgid "Show teaser-style link" +msgstr "" + +msgid "Link this field to new comments" +msgstr "" + +msgid "Display nothing if no new comments" +msgstr "Не відображає нічого, за відсутності коментарів" + +msgid "Type of link" +msgstr "" + +msgid "contact" +msgstr "контакт" + +msgid "Contact %user" +msgstr "" + +msgid "Unknown group" +msgstr "Невідома група" + +msgid "Unknown language" +msgstr "Невідома мова" + +msgid "Current user's language" +msgstr "Теперішня мова користувача" + +msgid "Default site language" +msgstr "Базова мова сайту" + +msgid "No language" +msgstr "Нема мови" + +msgid "Current installed version" +msgstr "Теперішня встановлена версія" + +msgid "Unknown node type" +msgstr "Невідомий тип матеріалу" + +msgid "Check for new comments as well" +msgstr "" + +msgid "If you wish to validate for specific node types, check them; if none are checked, all nodes will pass." +msgstr "" + +msgid "Validate user has access to the node" +msgstr "" + +msgid "Node IDs separated by , or +" +msgstr "" + +msgid "Build mode" +msgstr "Створення режиму" + +msgid "Display node comments" +msgstr "Відображає коментарі до матеріалу" + +msgid "No alternate" +msgstr "нема альтернативних" + +msgid "Alternative sort" +msgstr "Альтернативне сортування" + +msgid "If no search is performed and this field does not appear, pick an alternative default table sort field." +msgstr "" + +msgid "Alternate sort order" +msgstr "" + +msgid "On empty input" +msgstr "На порожньому полі" + +msgid "Show None" +msgstr "Не позувати нічого" + +msgid "Search for either of the two terms with uppercase <strong>OR</strong>. For example, <strong>cats OR dogs</strong>." +msgstr "" + +msgid "Display score" +msgstr "Відображає оцінку" + +msgid "Link this field to download the file" +msgstr "" + +msgid "Set the breadcrumb for the term parents" +msgstr "" + +msgid "If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received." +msgstr "" + +msgid "The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term \"fruit\" and a child term \"apple\", with a depth of 1 (or higher) then filtering for the term \"fruit\" will get nodes that are tagged with \"apple\" as well as \"fruit\". If negative, the reverse is true; searching for \"apple\" will also pick up nodes tagged with \"fruit\" if depth is -1 (or lower)." +msgstr "" + +msgid "Allow multiple terms per argument" +msgstr "Дозволити багато термінів на аргумент" + +msgid "If selected, users can enter multiple arguments in the form of 1+2+3. Due to the number of JOINs it would require, AND will be treated as OR with this argument." +msgstr "" + +msgid "No vocabulary" +msgstr "Без словника" + +msgid "Link this field to its taxonomy term page" +msgstr "" + +msgid "Link this field to its term page" +msgstr "" + +msgid "Limit terms by vocabulary" +msgstr "Ліміт термінів словника" + +msgid "Select which vocabulary to show terms for in the regular options." +msgstr "" + +msgid "Dropdown" +msgstr "Випадання" + +msgid "Show hierarchy in dropdown" +msgstr "" + +msgid "An invalid vocabulary is selected. Please change it in the options." +msgstr "" + +msgid "Select terms from vocabulary @voc" +msgstr "" + +msgid "Select terms" +msgstr "Вибір термінів" + +msgid "Unable to find term: @terms" +msgid_plural "Unable to find terms: @terms" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +msgid "If you wish to validate for specific vocabularies, check them; if none are checked, all terms will pass." +msgstr "" + +msgid "Term IDs separated by , or +" +msgstr "" + +msgid "Term name or synonym" +msgstr "" + +msgid "Term name/synonym converted to Term ID" +msgstr "" + +msgid "Select the form of this argument; if using term name, it is generally more efficient to convert it to a term ID and use Taxonomy: Term ID rather than Taxonomy: Term Name\" as an argument." +msgstr "" + +msgid "Transform dashes in URL to spaces in term name arguments" +msgstr "" + +msgid "Include untranslated nodes" +msgstr "" + +msgid "Current language" +msgstr "Теперішня мова" + +msgid "Translation option" +msgstr "Параметри перекладу" + +msgid "The translation options allows you to select which translation or translations in a translation set join on. Select \"Current language\" or \"Default language\" to join on the translation in the current or default language respectively. Select a specific language to join on a translation in that language. If you select \"All\", each translation will create a new row, which may appear to cause duplicates." +msgstr "" + +msgid "To the user" +msgstr "До користувача" + +msgid "With a mailto:" +msgstr "З mailto:" + +msgid "Is the logged in user" +msgstr "Залоґований користувач" + +msgid "Usernames" +msgstr "Імена користувачів" + +msgid "Enter a comma separated list of user names." +msgstr "" + +msgid "Unable to find user: @users" +msgid_plural "Unable to find users: @users" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +msgid "Also look for a node and use the node author" +msgstr "" + +msgid "Type of user argument to allow" +msgstr "" + +msgid "Only allow numeric UIDs" +msgstr "" + +msgid "Only allow string usernames" +msgstr "" + +msgid "Allow both numeric UIDs and string usernames" +msgstr "" + +msgid "Restrict user based on role" +msgstr "" + +msgid "Restrict to the selected roles" +msgstr "" + +msgid "If no roles are selected, users from any role will be allowed." +msgstr "" + +msgid "Unrestricted" +msgstr "Необмежено" + +msgid "Only users with the selected permission flag will be able to access this display. Note that users with \"access all views\" can see any view, regardless of other permissions." +msgstr "" + +msgid "No role(s) selected" +msgstr "Жодної ролі(ролей не обрано)" + +msgid "Multiple roles" +msgstr "Багато ролей" + +msgid "Only the checked roles will be able to access this display. Note that users with \"access all views\" can see any view, regardless of role." +msgstr "" + +msgid "You must select at least one role if type is \"by role\"" +msgstr "" + +msgid "Note: you do not have permission to modify this. If you change the default argument type, this setting will be lost and you will NOT be able to get it back." +msgstr "" + +msgid "PHP argument code" +msgstr "" + +msgid "Enter PHP code that returns a value to use for this argument. Do not use <?php ?>. You must return only a single value for just this argument." +msgstr "" + +msgid "Note: you do not have permission to modify this. If you change the validator, this setting will be lost and you will NOT be able to get it back." +msgstr "" + +msgid "PHP validate code" +msgstr "" + +msgid "Enter PHP code that returns TRUE or FALSE. No return is the same as FALSE, so be SURE to return something if you do not want to declare the argument invalid. Do not use <?php ?>. The argument to validate will be \"$argument\" and the view will be \"$view\". You may change the argument by setting \"$handler->argument\"." +msgstr "" + +msgid "Never cache" +msgstr "" + +msgid "Query results" +msgstr "" + +msgid "The length of time raw query results should be cached." +msgstr "" + +msgid "Rendered output" +msgstr "" + +msgid "The length of time rendered HTML output should be cached." +msgstr "" + +msgid "Broken field" +msgstr "" + +msgid "Change the name of this display." +msgstr "" + +msgid "Change the title that this display will use." +msgstr "" + +msgid "Change the style plugin." +msgstr "Змінити додаток стилю" + +msgid "Row style" +msgstr "Рядковий стиль" + +msgid "Change the row plugin." +msgstr "" + +msgid "Use AJAX" +msgstr "Використовувати AJAX" + +msgid "Change whether or not this display will use AJAX." +msgstr "" + +msgid "Mini" +msgstr "Міні" + +msgid "Change this display's pager setting." +msgstr "" + +msgid "Items per page" +msgstr "Елементів на сторінку" + +msgid "Change how many items to display." +msgstr "" + +msgid "Specify whether this display will provide a \"more\" link." +msgstr "" + +msgid "Display only distinct items, without duplicates." +msgstr "" + +msgid "Specify access control type for this display." +msgstr "" + +msgid "Change settings for this access type." +msgstr "" + +msgid "Specify caching type for this display." +msgstr "" + +msgid "Change settings for this caching type." +msgstr "" + +msgid "Link display" +msgstr "Відображення посилання" + +msgid "Specify which display this display will link to." +msgstr "" + +msgid "Exposed form in block" +msgstr "" + +msgid "Allow the exposed form to appear in a block instead of the view." +msgstr "" + +msgid "Unknown/missing format" +msgstr "" + +msgid "Change this display's !name." +msgstr "" + +msgid "Get information on how to theme this display" +msgstr "" + +msgid "The name of this display" +msgstr "Ім'я виду" + +msgid "This title will appear only in the administrative interface for the View." +msgstr "" + +msgid "The title of this view" +msgstr "" + +msgid "This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc." +msgstr "" + +msgid "Use AJAX when available to load this view" +msgstr "" + +msgid "If set, this view will use an AJAX mechanism for paging, table sorting and exposed filters. This means the entire page will not refresh. It is not recommended that you use this if this view is the main content of the page as it will prevent deep linking to specific pages, but it is very useful for side content." +msgstr "" + +msgid "Use a pager for this view" +msgstr "Використовувати розбиття по сторінках для цього виду" + +msgid "Full pager" +msgstr "Повний стиль" + +msgid "Mini pager" +msgstr "Міні стиль" + +msgid "Pager element" +msgstr "Розбиття по сторінках" + +msgid "Unless you're experiencing problems with pagers related to this view, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible." +msgstr "" + +msgid "The number of items to display per page. Enter 0 for no limit." +msgstr "" + +msgid "The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed. Offset can not be used if items to display is 0; instead use a very large number there." +msgstr "" + +msgid "Add a more link to the bottom of the display." +msgstr "" + +msgid "Create more link" +msgstr "Створити посилання \"далі(ще)\"" + +msgid "This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' above." +msgstr "" + +msgid "Text to use for the more link." +msgstr "" + +msgid "The text to display for the more link." +msgstr "" + +msgid "This will make the view display only distinct items. If there are multiple identical items, each will be displayed only once. You can use this to try and remove duplicates from a view, though it does not always work. Note that this can slow queries down, so use it with caution." +msgstr "" + +msgid "Access restrictions" +msgstr "Обмеження доступу" + +msgid "You may also adjust the !settings for the currently selected style by clicking on the icon." +msgstr "" + +msgid "Access options" +msgstr "Параметри доступу" + +msgid "Caching options" +msgstr "" + +msgid "Display even if view has no result" +msgstr "" + +msgid "Text to display beneath the view. May contain an explanation or links or whatever you like. Optional." +msgstr "" + +msgid "Text to display if the view has no results. Optional." +msgstr "" + +msgid "How should this view be styled" +msgstr "" + +msgid "If the style you choose has settings, be sure to click the settings button that will appear next to it in the View summary." +msgstr "" + +msgid "Style options" +msgstr "Параметри стилю" + +msgid "Row style options" +msgstr "Параметри стилю рядка" + +msgid "How should each row in this view be styled" +msgstr "" + +msgid "You may also adjust the !settings for the currently selected row style by clicking on the icon." +msgstr "" + +msgid "Which display to use for path" +msgstr "" + +msgid "Which display to use to get this display's path for things like summary links, rss feed links, more links, etc." +msgstr "" + +msgid "Display output" +msgstr "Відображення виводу" + +msgid "Alternative display output" +msgstr "Альтернативний стиль виду" + +msgid "Style output" +msgstr "Стиль виводу" + +msgid "Alternative style" +msgstr "Альтернативний стиль" + +msgid "Row style output" +msgstr "Стиль виводу - в рядок" + +msgid "Alternative row style" +msgstr "Альтернативний стиль рядка" + +msgid "Field @field (ID: @id)" +msgstr "" + +msgid "This section lists all possible templates for the display plugin and for the style plugins, ordered roughly from the least specific to the most specific. The active template for each plugin -- which is the most specific template found on the system -- is highlighted in bold." +msgstr "" + +msgid "Change theme" +msgstr "" + +msgid "Rescan template files" +msgstr "Перечитати файли шаблона" + +msgid "<strong>Important!</strong> When adding, removing, or renaming template files, it is necessary to make Drupal aware of the changes by making it rescan the files on your system. By clicking this button you clear Drupal's theme registry and thereby trigger this rescanning process. The highlighted templates above will then reflect the new state of your system." +msgstr "" + +msgid "Theming information (display)" +msgstr "" + +msgid "Back to !info." +msgstr "Повернутись до !info" + +msgid "theming information" +msgstr "Інформація для розробки тем" + +msgid "This display has no theming information" +msgstr "" + +msgid "This is the default theme template used for this display." +msgstr "" + +msgid "This is an alternative template for this display." +msgstr "" + +msgid "Theming information (style)" +msgstr "" + +msgid "This display has no style theming information" +msgstr "" + +msgid "This is the default theme template used for this style." +msgstr "" + +msgid "This is an alternative template for this style." +msgstr "" + +msgid "Theming information (row style)" +msgstr "" + +msgid "This display has no row style theming information" +msgstr "" + +msgid "This is the default theme template used for this row style." +msgstr "" + +msgid "This is an alternative template for this row style." +msgstr "" + +msgid "Put the exposed form in a block" +msgstr "" + +msgid "If set, any exposed widgets will not appear with this view. Instead, a block will be made available to the Drupal block administration system, and the exposed form will appear there. Note that this block must be enabled manually, Views will not enable it for you." +msgstr "" + +msgid "File found in folder @template-path" +msgstr "" + +msgid "(File not found, in folder @template-path)" +msgstr "" + +msgid "Status: using default values." +msgstr "" + +msgid "Update default display" +msgstr "Оновити базовий вид" + +msgid "Status: using overridden values." +msgstr "" + +msgid "Display \"@display\" uses fields but there are none defined for it or all are excluded." +msgstr "" + +msgid "Display \"@display\" uses a path but the path is undefined." +msgstr "" + +msgid "Display \"@display\" has an invalid style plugin." +msgstr "" + +msgid "Exposed form: @view-@display_id" +msgstr "Відображена форма: @view-@display_id" + +msgid "Attachment settings" +msgstr "Параметри вкладень" + +msgid "Inherit arguments" +msgstr "Залежність аргументів" + +msgid "Inherit exposed filters" +msgstr "Залежність відображених фільтрів" + +msgid "Multiple displays" +msgstr "Сукупність відображень" + +msgid "Should this display inherit its arguments from the parent display to which it is attached?" +msgstr "" + +msgid "Should this display inherit its exposed filter values from the parent display to which it is attached?" +msgstr "" + +msgid "Attach before or after the parent display?" +msgstr "" + +msgid "Select which display or displays this should attach to." +msgstr "" + +msgid "@view: @display" +msgstr "@view: @display" + +msgid "Block admin description" +msgstr "" + +msgid "Block caching type" +msgstr "" + +msgid "This sets the default status for Drupal's built-in block caching method; this requires that caching be turned on in block administration, and be careful because you have little control over when this cache is flushed." +msgstr "" + +msgid "Using the site name" +msgstr "" + +msgid "Use the site name for the title" +msgstr "" + +msgid "The feed icon will be available only to the selected displays." +msgstr "" + +msgid "This view will be displayed by visiting this path on your site. It is recommended that the path be something like \"path/%/%/feed\" or \"path/%/%/rss.xml\", putting one % in the path for each argument you have defined in the view." +msgstr "" + +msgid "No menu" +msgstr "Без меню" + +msgid "Normal: @title" +msgstr "Нормально: @title" + +msgid "Tab: @title" +msgstr "Закладка: @title" + +msgid "Change settings for the parent menu" +msgstr "" + +msgid "The menu path or URL of this view" +msgstr "" + +msgid "This view will be displayed by visiting this path on your site. You may use \"%\" in your URL to represent values that will be used for arguments: For example, \"node/%/feed\"." +msgstr "" + +msgid "Menu item entry" +msgstr "Пункт елемента меню" + +msgid "No menu entry" +msgstr "Без пункта меню" + +msgid "Normal menu entry" +msgstr "Нормальний пункт меню" + +msgid "Menu tab" +msgstr "Закладки меню" + +msgid "Default menu tab" +msgstr "Базові закладки меню" + +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "" + +msgid "If set to normal or tab, enter the text to use for the menu item's description." +msgstr "" + +msgid "Warning: Changing this item's menu will not work reliably in Drupal 6.4 or earlier. Please upgrade your copy of Drupal at !url." +msgstr "" + +msgid "Insert item into an available menu." +msgstr "" + +msgid "Menu selection requires the activation of menu module." +msgstr "" + +msgid "The lower the weight the higher/further left it will appear." +msgstr "" + +msgid "Default tab options" +msgstr "Базові параметри закладки" + +msgid "When providing a menu item as a 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>." +msgstr "" + +msgid "Already exists" +msgstr "Вже наявне" + +msgid "If creating a parent menu item, enter the title of the item." +msgstr "" + +msgid "If creating a parent menu item, enter the description of the item." +msgstr "" + +msgid "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." +msgstr "" + +msgid "\"$arg\" is no longer supported. Use % instead." +msgstr "" + +msgid "\"%\" may not be used for the first segment of a path." +msgstr "" + +msgid "Views cannot create normal menu items for paths with a % in them." +msgstr "" + +msgid "A display whose path ends with a % cannot be a tab." +msgstr "" + +msgid "Title is required for this menu type." +msgstr "" + +msgid "Display @display is set to use a menu but the menu title is not set." +msgstr "" + +msgid "Display @display is set to use a parent menu but the parent menu title is not set." +msgstr "" + +msgid "Inline fields" +msgstr "Поля без розділювачів" + +msgid "Inline fields will be displayed next to each other rather than one after another." +msgstr "" + +msgid "The separator may be placed between inline fields to keep them from squishing up next to each other. You can use HTML in this field." +msgstr "" + +msgid "Grouping field" +msgstr "Групуюче поле" + +msgid "You may optionally specify a field by which to group the records. Leave blank to not group." +msgstr "" + +msgid "Style @style requires a row style but the row plugin is invalid." +msgstr "" + +msgid "Horizontal alignment will place items starting in the upper left and moving right. Vertical alignment will place items starting in the upper left and moving down." +msgstr "" + +msgid "Use the site mission for the description" +msgstr "" + +msgid "RSS description" +msgstr "Опис RSS" + +msgid "This will appear in the RSS feed itself." +msgstr "" + +msgid "Display record count with link" +msgstr "" + +msgid "Override number of items to display" +msgstr "" + +msgid "Display items inline" +msgstr "Відображення елементів без розділювачів" + +msgid "You need at least one field before you can configure your table settings" +msgstr "" + +msgid "Override normal sorting if click sorting is used" +msgstr "" + +msgid "Enable Drupal style \"sticky\" table headers (Javascript)" +msgstr "" + +msgid "(Sticky header effects will not be active for preview below, only on live output.)" +msgstr "" + +msgid "If a default sort order is selected, what order should it use by default." +msgstr "" + +msgid "Place fields into columns; you may combine multiple fields into the same column. If you do, the separator in the column specified will be used to separate the fields. Check the sortable box to make that column click sortable, and check the default sort radio to determine which column will be sorted by default, if any. You may control column order and field labels in the fields section." +msgstr "" + +msgid "The style selected does not utilize fields." +msgstr "" + +msgid "None defined" +msgstr "Не зазначено" + +msgid "This view 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>." +msgstr "" + +msgid "New view" +msgstr "Новий вид" + +msgid "Changed view" +msgstr "Змінений вид" + +msgid "View %name, displaying items of type <strong>@base</strong>." +msgstr "" + +msgid "Live preview" +msgstr "Швидкий вид" + +msgid "<em>@type</em> @base view: <strong>@view</strong>" +msgstr "<em>@type</em> @base view: <strong>@view</strong>" + +msgid "Title: @title" +msgstr "Заголовок: @title" + +msgid "‹‹" +msgstr "‹‹" + +msgid "››" +msgstr "››" + +msgid "@current of @max" +msgstr "" + +msgid "There are no views to be exported at this time." +msgstr "Наразі відсутні види для експортування" + +msgid "Show only these tags" +msgstr "Показувати лише ці теги" + +msgid "name = @module Export Module\n" +msgstr "" + +msgid "description = Exports some views of @module\n" +msgstr "" + +msgid "Put this in @module.info in your modules/@module directory" +msgstr "" + +msgid "Put this in @module.module in your modules/@module directory" +msgstr "" + +msgid "Put this in @module.views_default.inc in your modules/@module directory or modules/@module/includes directory" +msgstr "" + +msgid "use views exporter" +msgstr "використання експорту видів" + +msgid "Bulk export" +msgstr "Масовий експорт" + +msgid "Views exporter" +msgstr "Експорт видів" + +msgid "Allows exporting multiple views at once." +msgstr "" + diff --git a/sites/all/modules/views/translations/views.pot b/sites/all/modules/views/translations/views.pot new file mode 100644 index 0000000000000000000000000000000000000000..3c1302545a3f2ca184516d9c71b40a230f2c8b57 --- /dev/null +++ b/sites/all/modules/views/translations/views.pot @@ -0,0 +1,4268 @@ +# $Id: views.pot,v 1.8.6.3 2010/07/27 21:51:39 merlinofchaos Exp $ +# +# LANGUAGE translation of Drupal (general) +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from files: +# views.module,v 1.317 2008/10/16 17:21:36 merlinofchaos +# admin.inc,v 1.146 2008/10/28 22:50:00 merlinofchaos +# views_ui.module,v 1.106 2008/10/07 22:05:28 merlinofchaos +# views_export.module,v 1.2 2008/06/25 21:42:20 merlinofchaos +# views.info,v 1.7 2007/08/12 06:52:14 merlinofchaos +# views_ui.info,v 1.10 2008/01/09 00:05:08 merlinofchaos +# views_export.info,v 1.1 2008/06/12 16:17:25 merlinofchaos +# plugins.inc,v 1.151 2008/10/28 19:23:50 merlinofchaos +# convert.inc,v 1.12 2008/10/08 00:14:01 merlinofchaos +# theme.inc,v 1.63 2008/10/28 17:46:14 merlinofchaos +# views.install,v 1.42 2008/10/14 19:51:55 merlinofchaos +# docs.php,v 1.10 2008/10/02 22:54:56 merlinofchaos +# views_handler_argument.inc,v 1.4 2008/10/08 00:14:00 merlinofchaos +# views_handler_relationship_translation.inc,v 1.1 2008/09/30 22:07:15 merlinofchaos +# comment.views.inc,v 1.25 2008/10/16 17:21:36 merlinofchaos +# node.views.inc,v 1.87 2008/10/16 17:09:52 merlinofchaos +# views_plugin_display.inc,v 1.16 2008/10/28 20:28:56 merlinofchaos +# views_plugin_display_page.inc,v 1.3 2008/10/08 22:59:59 merlinofchaos +# views_handler_field.inc,v 1.5 2008/10/16 19:38:52 merlinofchaos +# views_handler_filter.inc,v 1.4 2008/10/20 19:35:53 merlinofchaos +# views_handler_relationship.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos +# views_handler_sort.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos +# views_handler_argument_date.inc,v 1.2 2008/10/07 21:26:23 merlinofchaos +# views_handler_argument_many_to_one.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos +# views_handler_argument_numeric.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos +# views_handler_argument_string.inc,v 1.2 2008/09/25 00:09:08 merlinofchaos +# taxonomy.views.inc,v 1.49 2008/10/01 17:20:58 merlinofchaos +# views_handler_argument_null.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos +# views_handler_field_boolean.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos +# views_handler_filter_boolean_operator.inc,v 1.2 2008/09/10 01:08:06 merlinofchaos +# views_handler_filter_in_operator.inc,v 1.4 2008/09/24 22:28:06 merlinofchaos +# views_plugin_display_attachment.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_field_date.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos +# views_handler_field_numeric.inc,v 1.4 2008/10/23 01:04:24 merlinofchaos +# views_handler_field_prerender_list.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos +# views_plugin_row_node_rss.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_plugin_style_list.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_plugin_row_fields.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_plugin_style_summary_unformatted.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_field_url.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos +# views_handler_field_accesslog_path.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_filter_numeric.inc,v 1.6 2008/10/28 20:11:20 merlinofchaos +# views_handler_filter_string.inc,v 1.6 2008/10/28 20:13:34 merlinofchaos +# views_handler_filter_date.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos +# views_handler_filter_equality.inc,v 1.2 2008/09/10 01:08:06 merlinofchaos +# views_handler_filter_many_to_one.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos +# system.views.inc,v 1.7 2008/09/03 19:21:29 merlinofchaos +# views_plugin_access.inc,v 1.1 2008/09/08 22:50:17 merlinofchaos +# views_plugin_style_table.inc,v 1.5 2008/10/15 22:25:36 merlinofchaos +# views_handler_sort_date.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos +# views_handler_sort_formula.inc,v 1.1 2008/09/03 19:21:28 merlinofchaos +# view.inc,v 1.138 2008/10/29 19:09:49 merlinofchaos +# views_plugin_style.inc,v 1.4 2008/10/08 00:14:01 merlinofchaos +# user.views.inc,v 1.52 2008/10/08 20:56:02 merlinofchaos +# statistics.views.inc,v 1.9 2008/10/28 20:21:37 merlinofchaos +# upload.views.inc,v 1.14 2008/09/10 21:29:15 merlinofchaos +# views_plugin_display_block.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_plugin_display_feed.inc,v 1.3 2008/09/30 18:52:15 merlinofchaos +# book.views.inc,v 1.4 2008/07/02 17:42:57 merlinofchaos +# ajax.inc,v 1.19 2008/09/22 20:50:58 merlinofchaos +# analyze.inc,v 1.1 2008/10/28 22:50:00 merlinofchaos +# form.inc,v 1.10 2008/06/25 21:10:10 merlinofchaos +# handlers.inc,v 1.98 2008/10/28 17:47:49 merlinofchaos +# views_plugin_access_role.inc,v 1.1 2008/09/08 22:50:17 merlinofchaos +# views_plugin_access_perm.inc,v 1.2 2008/09/17 22:26:55 merlinofchaos +# ajax.js,v 1.23 2008/10/08 00:14:01 merlinofchaos +# ajax_view.js,v 1.12 2008/10/15 22:09:19 merlinofchaos +# tabs.js,v 1.3 2008/03/30 15:58:26 merlinofchaos +# views_handler_argument_term_node_tid_depth.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# translation.views.inc,v 1.2 2008/10/01 17:20:58 merlinofchaos +# poll.views.inc,v 1.2 2008/03/12 04:32:07 merlinofchaos +# profile.views.inc,v 1.9 2008/09/24 21:21:21 merlinofchaos +# search.views.inc,v 1.14 2008/09/25 00:39:18 merlinofchaos +# views_plugin_argument_validate_taxonomy_term.inc,v 1.2 2008/09/10 16:17:54 merlinofchaos +# views_handler_filter_term_node_tid.inc,v 1.5 2008/10/20 21:32:28 merlinofchaos +# views_handler_filter_node_language.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_filter_node_language.inc,v 1.1 2008/09/30 22:07:15 merlinofchaos +# views_handler_filter_upload_fid.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views.views.inc,v 1.5 2008/09/03 19:21:29 merlinofchaos +# views_handler_argument_comment_user_uid.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_argument_user_uid.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_field_comment.inc,v 1.2 2008/09/10 00:16:14 merlinofchaos +# views_handler_field_comment_link.inc,v 1.2 2008/09/10 00:16:14 merlinofchaos +# views_handler_field_node_link.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_field_user_link.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_field_comment_link_delete.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_field_node_link_delete.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_field_node_revision_link_delete.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_field_user_link_delete.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_field_comment_link_edit.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_field_node_link_edit.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_field_user_link_edit.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_field_comment_link_reply.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_field_comment_username.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_field_node_comment.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_filter_node_comment.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_field_node_new_comments.inc,v 1.2 2008/09/22 21:59:39 merlinofchaos +# views_plugin_row_comment_view.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_plugin_row_node_view.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_argument_dates_various.inc,v 1.2 2008/09/30 21:30:16 merlinofchaos +# views_handler_argument_node_language.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_argument_node_language.inc,v 1.1 2008/09/30 22:07:15 merlinofchaos +# views_handler_argument_node_type.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_field_history_user_timestamp.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_field_node.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_field_node_revision_link_revert.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_filter_node_type.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_plugin_argument_validate_node.inc,v 1.1 2008/09/03 19:21:29 merlinofchaos +# views_handler_filter_search.inc,v 1.2 2008/09/10 20:15:50 merlinofchaos +# views_plugin_row_search_view.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_argument_file_fid.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_field_file.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_field_upload_description.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_field_upload_fid.inc,v 1.2 2008/09/10 21:02:57 merlinofchaos +# views_handler_argument_taxonomy.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_argument_term_node_tid.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_argument_vocabulary_vid.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_field_taxonomy.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_field_term_node_tid.inc,v 1.2 2008/09/22 18:13:51 merlinofchaos +# views_handler_field_user.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_field_user_mail.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_filter_user_current.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_handler_filter_user_name.inc,v 1.2 2008/09/22 23:41:14 merlinofchaos +# views_plugin_argument_default_user.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_plugin_access_none.inc,v 1.1 2008/09/08 22:50:17 merlinofchaos +# views_plugin_argument_default.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_plugin_argument_default_php.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_plugin_argument_validate.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_plugin_argument_validate_php.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_plugin_style_summary.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_plugin_style_grid.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views_plugin_style_rss.inc,v 1.1 2008/09/03 19:21:30 merlinofchaos +# views-more.tpl.php,v 1.2 2008/04/11 08:46:26 merlinofchaos +# views-ui-edit-item.tpl.php,v 1.9 2008/08/08 16:57:44 merlinofchaos +# views-ui-edit-tab.tpl.php,v 1.11 2008/08/08 16:57:44 merlinofchaos +# views-ui-edit-view.tpl.php,v 1.9 2008/10/08 00:14:01 merlinofchaos +# views-ui-list-views.tpl.php,v 1.6 2008/10/28 18:11:43 merlinofchaos +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2008-11-06 21:18+0100\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" + +#: views.module:629 +msgid "Broken handler @table.@field" +msgstr "" + +#: views.module:747 +msgid "Skipping broken view @view" +msgstr "" + +#: views.module:794;834 includes/admin.inc:98;216;216;621 +msgid "Overridden" +msgstr "" + +#: views.module:797;830 views_ui.module:289 includes/admin.inc:97;215;215;588;766 +msgid "Default" +msgstr "" + +#: views.module:935 includes/admin.inc:295 views_export/views_export.module:116 +msgid "Apply" +msgstr "" + +#: views.module:151 views_ui.module:26 views.info:0;0 views_ui.info:0 views_export/views_export.info:0 +msgid "Views" +msgstr "" + +#: views.module:155 +msgid "Ajax callback for view loading." +msgstr "" + +#: views.module:0 +msgid "views" +msgstr "" + +#: views_ui.module:159 +msgid "The converter will make a best-effort attempt to convert a Views 1 view to Views 2. This conversion is not reliable; you will very likely have to make adjustments to your view to get it to match. You can import Views 1 views through the normal Import tab." +msgstr "" + +#: views_ui.module:265 +msgid "Changes cannot be made to a locked view." +msgstr "" + +#: views_ui.module:28 +msgid "Views are customized lists of content on your system; they are highly configurable and give you control over how lists of content are presented." +msgstr "" + +#: views_ui.module:32 includes/plugins.inc:135 +msgid "List" +msgstr "" + +#: views_ui.module:38 includes/admin.inc:1178;1178;2165 +msgid "Add" +msgstr "" + +#: views_ui.module:43 includes/admin.inc:724 +msgid "Import" +msgstr "" + +#: views_ui.module:49 +msgid "Tools" +msgstr "" + +#: views_ui.module:55 +msgid "Basic" +msgstr "" + +#: views_ui.module:63 includes/convert.inc:30 +msgid "Convert" +msgstr "" + +#: views_ui.module:64 +msgid "Convert stored Views 1 views." +msgstr "" + +#: views_ui.module:70;83;88 +msgid "Delete view" +msgstr "" + +#: views_ui.module:76 +msgid "Convert view" +msgstr "" + +#: views_ui.module:113 includes/admin.inc:93 theme/theme.inc:89 +msgid "Edit" +msgstr "" + +#: views_ui.module:0 +msgid "views_ui" +msgstr "" + +#: views.install:31 +msgid "Stores the general data for a view." +msgstr "" + +#: views.install:37 +msgid "The view ID of the field, defined by the database." +msgstr "" + +#: views.install:45 +msgid "The unique name of the view. This is the primary field views are loaded from, and is used so that views may be internal and not necessarily in the database. May only be alphanumeric characters plus underscores." +msgstr "" + +#: views.install:51 +msgid "A description of the view for the admin interface." +msgstr "" + +#: views.install:57 +msgid "A tag used to group/sort views in the admin interface" +msgstr "" + +#: views.install:61 +msgid "A chunk of PHP code that can be used to provide modifications to the view prior to building." +msgstr "" + +#: views.install:68 +msgid "What table this view is based on, such as node, user, comment, or term." +msgstr "" + +#: views.install:74 +msgid "A boolean to indicate whether or not this view may have its query cached." +msgstr "" + +#: views.install:82 +msgid "Stores information about each display attached to a view." +msgstr "" + +#: views.install:89 +msgid "The view this display is attached to." +msgstr "" + +#: views.install:97 +msgid "An identifier for this display; usually generated from the display_plugin, so should be something like page or page_1 or block_2, etc." +msgstr "" + +#: views.install:104 +msgid "The title of the display, viewable by the administrator." +msgstr "" + +#: views.install:111 +msgid "The type of the display. Usually page, block or embed, but is pluggable so may be other things." +msgstr "" + +#: views.install:116 +msgid "The order in which this display is loaded." +msgstr "" + +#: views.install:120 +msgid "A serialized array of options for this display; it contains options that are generally only pertinent to that display plugin type." +msgstr "" + +#: views.install:131 +msgid "A special cache used to store objects that are being edited; it serves to save state in an ordinarily stateless environment." +msgstr "" + +#: views.install:136 +msgid "The session ID this cache object belongs to." +msgstr "" + +#: views.install:141 +msgid "The name of the view this cache is attached to." +msgstr "" + +#: views.install:146 +msgid "The name of the object this cache is attached to; this essentially represents the owner so that several sub-systems can use this cache." +msgstr "" + +#: views.install:153 +msgid "The time this cache was created or updated." +msgstr "" + +#: views.install:157 +msgid "Serialized data being stored." +msgstr "" + +#: views.info:0 +msgid "Create customized lists and queries from your database." +msgstr "" + +#: views_ui.info:0 +msgid "Views UI" +msgstr "" + +#: views_ui.info:0 +msgid "Administrative interface to views. Without this module, you cannot create or edit your views." +msgstr "" + +#: docs/docs.php:127 +msgid "Emulates the default Drupal front page; you may set the default home page path to this view to make it your front page." +msgstr "" + +#: docs/docs.php:128 +msgid "default" +msgstr "" + +#: docs/docs.php:137 includes/plugins.inc:25 +msgid "Defaults" +msgstr "" + +#: docs/docs.php:226 includes/plugins.inc:39;47 +msgid "Page" +msgstr "" + +#: docs/docs.php:281 includes/plugins.inc:72;80 +msgid "Feed" +msgstr "" + +#: docs/docs.php:349 +msgid "Front page feed" +msgstr "" + +#: handlers/views_handler_argument.inc:102 modules/translation/views_handler_relationship_translation.inc:23 +msgid "All" +msgstr "" + +#: handlers/views_handler_argument.inc:119 includes/admin.inc:272;383 modules/comment.views.inc:44 modules/node.views.inc:85;413 plugins/views_plugin_display.inc:592 plugins/views_plugin_display_page.inc:285;348 +msgid "Title" +msgstr "" + +#: handlers/views_handler_argument.inc:121 +msgid "The title to use when this argument is present. It will override the title of the view and titles from previous arguments. You can use percent substitution here to replace with argument titles. Use \"%1\" for the first argument, \"%2\" for the second, etc." +msgstr "" + +#: handlers/views_handler_argument.inc:134 +msgid "Action to take if argument is not present" +msgstr "" + +#: handlers/views_handler_argument.inc:146 +msgid "Wildcard" +msgstr "" + +#: handlers/views_handler_argument.inc:149 +msgid "If this value is received as an argument, the argument will be ignored; i.e, \"all values\"" +msgstr "" + +#: handlers/views_handler_argument.inc:155 +msgid "Wildcard title" +msgstr "" + +#: handlers/views_handler_argument.inc:158 +msgid "The title to use for the wildcard in substitutions elsewhere." +msgstr "" + +#: handlers/views_handler_argument.inc:181 +msgid "Validator options" +msgstr "" + +#: handlers/views_handler_argument.inc:186 +msgid "Validator" +msgstr "" + +#: handlers/views_handler_argument.inc:190 +msgid "<Basic validation>" +msgstr "" + +#: handlers/views_handler_argument.inc:229 +msgid "Action to take if argument does not validate" +msgstr "" + +#: handlers/views_handler_argument.inc:248 +msgid "Display all values" +msgstr "" + +#: handlers/views_handler_argument.inc:253 +msgid "Hide view / Page not found (404)" +msgstr "" + +#: handlers/views_handler_argument.inc:258 +msgid "Display empty text" +msgstr "" + +#: handlers/views_handler_argument.inc:263 +msgid "Summary, sorted ascending" +msgstr "" + +#: handlers/views_handler_argument.inc:270 +msgid "Summary, sorted descending" +msgstr "" + +#: handlers/views_handler_argument.inc:277 +msgid "Provide default argument" +msgstr "" + +#: handlers/views_handler_argument.inc:310 +msgid "Provide default argument options" +msgstr "" + +#: handlers/views_handler_argument.inc:320 +msgid "Default argument type" +msgstr "" + +#: handlers/views_handler_argument.inc:708 handlers/views_handler_field.inc:227 handlers/views_handler_filter.inc:592 handlers/views_handler_relationship.inc:133 handlers/views_handler_sort.inc:66 +msgid "Broken/missing handler" +msgstr "" + +#: handlers/views_handler_argument.inc:716 handlers/views_handler_field.inc:235 handlers/views_handler_filter.inc:600 handlers/views_handler_relationship.inc:141 handlers/views_handler_sort.inc:74 +msgid "The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item." +msgstr "" + +#: handlers/views_handler_argument_date.inc:29 +msgid "Current date" +msgstr "" + +#: handlers/views_handler_argument_date.inc:30 +msgid "Current node's creation time" +msgstr "" + +#: handlers/views_handler_argument_date.inc:31 +msgid "Current node's update time" +msgstr "" + +#: handlers/views_handler_argument_many_to_one.inc:45 handlers/views_handler_argument_numeric.inc:30 +msgid "Allow multiple terms per argument." +msgstr "" + +#: handlers/views_handler_argument_many_to_one.inc:46 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 (for OR) or 1,2,3 (for AND)." +msgstr "" + +#: handlers/views_handler_argument_many_to_one.inc:53 handlers/views_handler_argument_string.inc:95 +msgid "Allow multiple arguments to work together." +msgstr "" + +#: handlers/views_handler_argument_many_to_one.inc:54 handlers/views_handler_argument_string.inc:96 +msgid "If selected, multiple instances of this argument can work together, as though multiple terms were supplied to the same argument. This setting is not compatible with the \"Reduce duplicates\" setting." +msgstr "" + +#: handlers/views_handler_argument_many_to_one.inc:60 handlers/views_handler_argument_string.inc:102 +msgid "Do not display items with no value in summary" +msgstr "" + +#: handlers/views_handler_argument_many_to_one.inc:95;109 handlers/views_handler_argument_numeric.inc:45;57 modules/taxonomy.views.inc:129;208;292 +msgid "Uncategorized" +msgstr "" + +#: handlers/views_handler_argument_many_to_one.inc:113 handlers/views_handler_argument_numeric.inc:61 +msgid "Invalid input" +msgstr "" + +#: handlers/views_handler_argument_null.inc:21 +msgid "Fail basic validation if any argument is given" +msgstr "" + +#: handlers/views_handler_argument_null.inc:23 +msgid "By checking this field, you can use this to make sure views with more arguments than necessary fail validation." +msgstr "" + +#: handlers/views_handler_argument_numeric.inc:31 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3 or 1,2,3." +msgstr "" + +#: handlers/views_handler_argument_numeric.inc:37 +msgid "Exclude the argument" +msgstr "" + +#: handlers/views_handler_argument_numeric.inc:38 +msgid "If selected, the numbers entered in the argument will be excluded rather than limiting the view." +msgstr "" + +#: handlers/views_handler_argument_string.inc:44 +msgid "Glossary mode" +msgstr "" + +#: handlers/views_handler_argument_string.inc:45 +msgid "Glossary mode applies a limit to the number of characters used in the argument, which allows the summary view to act as a glossary." +msgstr "" + +#: handlers/views_handler_argument_string.inc:51 +msgid "Character limit" +msgstr "" + +#: handlers/views_handler_argument_string.inc:52 +msgid "How many characters of the argument to filter against. If set to 1, all fields starting with the letter in the argument would be matched." +msgstr "" + +#: handlers/views_handler_argument_string.inc:60 +msgid "Case" +msgstr "" + +#: handlers/views_handler_argument_string.inc:61 +msgid "When printing the argument result, how to transform the case." +msgstr "" + +#: handlers/views_handler_argument_string.inc:63;77 +msgid "No transform" +msgstr "" + +#: handlers/views_handler_argument_string.inc:64;78 +msgid "Upper case" +msgstr "" + +#: handlers/views_handler_argument_string.inc:65;79 +msgid "Lower case" +msgstr "" + +#: handlers/views_handler_argument_string.inc:66;80 +msgid "Capitalize first letter" +msgstr "" + +#: handlers/views_handler_argument_string.inc:67;81 +msgid "Capitalize each word" +msgstr "" + +#: handlers/views_handler_argument_string.inc:74 +msgid "Case in path" +msgstr "" + +#: handlers/views_handler_argument_string.inc:75 +msgid "When printing url paths, how to transform the case of the argument. Do not use this unless with Postgres as it uses case sensitive comparisons." +msgstr "" + +#: handlers/views_handler_argument_string.inc:88 +msgid "Transform spaces to dashes in URL" +msgstr "" + +#: handlers/views_handler_field.inc:146 handlers/views_handler_filter.inc:322 handlers/views_handler_relationship.inc:78 +msgid "Label" +msgstr "" + +#: handlers/views_handler_field.inc:148 +msgid "The label for this field that will be displayed to end users if the style requires it." +msgstr "" + +#: handlers/views_handler_field.inc:152 +msgid "Exclude from display" +msgstr "" + +#: handlers/views_handler_field.inc:154 +msgid "Check this box to not display this field, but still load it in the view. Use this option to not show a grouping field in each record, or when doing advanced theming." +msgstr "" + +#: handlers/views_handler_field_boolean.inc:24 +msgid "Output format" +msgstr "" + +#: handlers/views_handler_field_boolean.inc:26 +msgid "Yes/No" +msgstr "" + +#: handlers/views_handler_field_boolean.inc:27 +msgid "True/False" +msgstr "" + +#: handlers/views_handler_field_boolean.inc:28 +msgid "On/Off" +msgstr "" + +#: handlers/views_handler_field_boolean.inc:34 +msgid "Reverse" +msgstr "" + +#: handlers/views_handler_field_boolean.inc:35 +msgid "If checked, true will be displayed as false." +msgstr "" + +#: handlers/views_handler_field_boolean.inc:49 handlers/views_handler_filter_boolean_operator.inc:47 handlers/views_handler_filter_in_operator.inc:25 plugins/views_plugin_display.inc:633;642;659;667;717;803;1207 plugins/views_plugin_display_attachment.inc:63;69 +msgid "Yes" +msgstr "" + +#: handlers/views_handler_field_boolean.inc:49 handlers/views_handler_filter_boolean_operator.inc:47 handlers/views_handler_filter_in_operator.inc:25 plugins/views_plugin_display.inc:633;642;659;667;717;803;811;1207 plugins/views_plugin_display_attachment.inc:63;69 +msgid "No" +msgstr "" + +#: handlers/views_handler_field_boolean.inc:51 handlers/views_handler_filter_boolean_operator.inc:16;61 +msgid "True" +msgstr "" + +#: handlers/views_handler_field_boolean.inc:51 handlers/views_handler_filter_boolean_operator.inc:61 +msgid "False" +msgstr "" + +#: handlers/views_handler_field_boolean.inc:53 +msgid "On" +msgstr "" + +#: handlers/views_handler_field_boolean.inc:53 +msgid "Off" +msgstr "" + +#: handlers/views_handler_field_date.inc:24 +msgid "Date format" +msgstr "" + +#: handlers/views_handler_field_date.inc:29 +msgid "Custom" +msgstr "" + +#: handlers/views_handler_field_date.inc:30 +msgid "Time ago" +msgstr "" + +#: handlers/views_handler_field_date.inc:36 +msgid "Custom date format" +msgstr "" + +#: handlers/views_handler_field_date.inc:37 +msgid "If \"Custom\", see <a href=\"http://us.php.net/manual/en/function.date.php\" target=\"_blank\">the PHP docs</a> for date formats. If \"Time ago\" this is the the number of different units to display, which defaults to two." +msgstr "" + +#: handlers/views_handler_field_date.inc:53 +msgid "%time ago" +msgstr "" + +#: handlers/views_handler_field_numeric.inc:32 +msgid "Round" +msgstr "" + +#: handlers/views_handler_field_numeric.inc:33 +msgid "If checked, the number will be rounded." +msgstr "" + +#: handlers/views_handler_field_numeric.inc:38 +msgid "Precision" +msgstr "" + +#: handlers/views_handler_field_numeric.inc:40 +msgid "Specify how many digits to print after the decimal point." +msgstr "" + +#: handlers/views_handler_field_numeric.inc:47 +msgid "Decimal point" +msgstr "" + +#: handlers/views_handler_field_numeric.inc:49 +msgid "What single character to use as a decimal point." +msgstr "" + +#: handlers/views_handler_field_numeric.inc:55 +msgid "Thousands separator" +msgstr "" + +#: handlers/views_handler_field_numeric.inc:57 +msgid "What single character to use as the thousands separator." +msgstr "" + +#: handlers/views_handler_field_numeric.inc:62 +msgid "Prefix" +msgstr "" + +#: handlers/views_handler_field_numeric.inc:64 +msgid "Text to put before the number, such as currency symbol." +msgstr "" + +#: handlers/views_handler_field_numeric.inc:68 +msgid "Suffix" +msgstr "" + +#: handlers/views_handler_field_numeric.inc:70 +msgid "Text to put after the number, such as currency symbol." +msgstr "" + +#: handlers/views_handler_field_prerender_list.inc:29 modules/node/views_plugin_row_node_rss.inc:24 +msgid "Display type" +msgstr "" + +#: handlers/views_handler_field_prerender_list.inc:31 plugins/views_plugin_style_list.inc:33 +msgid "Unordered list" +msgstr "" + +#: handlers/views_handler_field_prerender_list.inc:32 plugins/views_plugin_style_list.inc:33 +msgid "Ordered list" +msgstr "" + +#: handlers/views_handler_field_prerender_list.inc:33 +msgid "Simple separator" +msgstr "" + +#: handlers/views_handler_field_prerender_list.inc:40 includes/admin.inc:2974 plugins/views_plugin_row_fields.inc:47 plugins/views_plugin_style_summary_unformatted.inc:30 +msgid "Separator" +msgstr "" + +#: handlers/views_handler_field_prerender_list.inc:48 +msgid "Empty list text" +msgstr "" + +#: handlers/views_handler_field_prerender_list.inc:50 +msgid "If the list is empty, you may enter text here that will be displayed." +msgstr "" + +#: handlers/views_handler_field_url.inc:24 modules/statistics/views_handler_field_accesslog_path.inc:31 +msgid "Display as link" +msgstr "" + +#: handlers/views_handler_filter.inc:136 +msgid "Operator" +msgstr "" + +#: handlers/views_handler_filter.inc:201 +msgid "Expose" +msgstr "" + +#: handlers/views_handler_filter.inc:206 +msgid "This item is currently not exposed. If you <strong>expose</strong> it, users will be able to change the filter as they view it." +msgstr "" + +#: handlers/views_handler_filter.inc:213 +msgid "Hide" +msgstr "" + +#: handlers/views_handler_filter.inc:218 +msgid "This item is currently exposed. If you <strong>hide</strong> it, users will not be able to change the filter as they view it." +msgstr "" + +#: handlers/views_handler_filter.inc:289 +msgid "Unlock operator" +msgstr "" + +#: handlers/views_handler_filter.inc:290 +msgid "When checked, the operator will be exposed to the user" +msgstr "" + +#: handlers/views_handler_filter.inc:296 +msgid "Operator identifier" +msgstr "" + +#: handlers/views_handler_filter.inc:298 +msgid "This will appear in the URL after the ? to identify this operator." +msgstr "" + +#: handlers/views_handler_filter.inc:315 +msgid "Filter identifier" +msgstr "" + +#: handlers/views_handler_filter.inc:317 +msgid "This will appear in the URL after the ? to identify this filter. Cannot be blank." +msgstr "" + +#: handlers/views_handler_filter.inc:333 +msgid "Optional" +msgstr "" + +#: handlers/views_handler_filter.inc:334 +msgid "This exposed filter is optional and will have added options to allow it not to be set." +msgstr "" + +#: handlers/views_handler_filter.inc:340 +msgid "Force single" +msgstr "" + +#: handlers/views_handler_filter.inc:341 +msgid "Force this exposed filter to accept only one option." +msgstr "" + +#: handlers/views_handler_filter.inc:347 +msgid "Remember" +msgstr "" + +#: handlers/views_handler_filter.inc:348 +msgid "Remember the last setting the user gave this filter." +msgstr "" + +#: handlers/views_handler_filter.inc:359 +msgid "The identifier is required if the filter is exposed." +msgstr "" + +#: handlers/views_handler_filter.inc:364 +msgid "This identifier is not allowed." +msgstr "" + +#: handlers/views_handler_filter.inc:465 +msgid "<Any>" +msgstr "" + +#: handlers/views_handler_filter_boolean_operator.inc:58 handlers/views_handler_filter_in_operator.inc:175 handlers/views_handler_filter_numeric.inc:247 handlers/views_handler_filter_string.inc:111 +msgid "exposed" +msgstr "" + +#: handlers/views_handler_filter_date.inc:24 +msgid "Value type" +msgstr "" + +#: handlers/views_handler_filter_date.inc:26 +msgid "A date in any machine readable format. CCYY-MM-DD HH:MM:SS is preferred." +msgstr "" + +#: handlers/views_handler_filter_date.inc:27 +msgid "An offset from the current time such as \"+1 day\" or \"-2 hours -30 minutes\"" +msgstr "" + +#: handlers/views_handler_filter_date.inc:77;83;87 +msgid "Invalid date format." +msgstr "" + +#: handlers/views_handler_filter_equality.inc:15 handlers/views_handler_filter_numeric.inc:38 handlers/views_handler_filter_string.inc:28 +msgid "Is equal to" +msgstr "" + +#: handlers/views_handler_filter_equality.inc:16 handlers/views_handler_filter_numeric.inc:44 handlers/views_handler_filter_string.inc:34 +msgid "Is not equal to" +msgstr "" + +#: handlers/views_handler_filter_equality.inc:26 handlers/views_handler_filter_numeric.inc:148;163 handlers/views_handler_filter_string.inc:170 +msgid "Value" +msgstr "" + +#: handlers/views_handler_filter_in_operator.inc:15 +msgid "Options" +msgstr "" + +#: handlers/views_handler_filter_in_operator.inc:37 +msgid "Limit list to selected items" +msgstr "" + +#: handlers/views_handler_filter_in_operator.inc:38 +msgid "If checked, the selected items presented to the user will be the only ones selected here." +msgstr "" + +#: handlers/views_handler_filter_in_operator.inc:57 handlers/views_handler_filter_many_to_one.inc:32 +msgid "Is one of" +msgstr "" + +#: handlers/views_handler_filter_in_operator.inc:58 +msgid "Is not one of" +msgstr "" + +#: handlers/views_handler_filter_in_operator.inc:193 modules/system.views.inc:209 plugins/views_plugin_access.inc:55 +msgid "Unknown" +msgstr "" + +#: handlers/views_handler_filter_many_to_one.inc:33 +msgid "Is all of" +msgstr "" + +#: handlers/views_handler_filter_many_to_one.inc:34 +msgid "Is none of" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:26 +msgid "Is less than" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:28 +msgid "<" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:32 +msgid "Is less than or equal to" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:34 +msgid "<=" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:40 handlers/views_handler_filter_string.inc:29 +msgid "=" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:46 handlers/views_handler_filter_string.inc:35 +msgid "!=" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:50 +msgid "Is greater than or equal to" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:52 +msgid ">=" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:56 +msgid "Is greater than" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:58 +msgid ">" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:62 +msgid "Is between" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:64 +msgid "between" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:68 +msgid "Is not between" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:70 +msgid "not between" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:79 handlers/views_handler_filter_string.inc:80 +msgid "Is empty (NULL)" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:81 handlers/views_handler_filter_string.inc:82 +msgid "empty" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:85 handlers/views_handler_filter_string.inc:86 +msgid "Is not empty (NULL)" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:87 handlers/views_handler_filter_string.inc:88 +msgid "not empty" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:175 +msgid "Min" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:181 +msgid "And max" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:181 +msgid "And" +msgstr "" + +#: handlers/views_handler_filter_numeric.inc:253 +msgid "@min and @max" +msgstr "" + +#: handlers/views_handler_filter_string.inc:40 +msgid "Contains" +msgstr "" + +#: handlers/views_handler_filter_string.inc:41 +msgid "contains" +msgstr "" + +#: handlers/views_handler_filter_string.inc:46 +msgid "Contains any word" +msgstr "" + +#: handlers/views_handler_filter_string.inc:47 +msgid "has word" +msgstr "" + +#: handlers/views_handler_filter_string.inc:52 +msgid "Contains all words" +msgstr "" + +#: handlers/views_handler_filter_string.inc:53 +msgid "has all" +msgstr "" + +#: handlers/views_handler_filter_string.inc:58 +msgid "Starts with" +msgstr "" + +#: handlers/views_handler_filter_string.inc:59 +msgid "begins" +msgstr "" + +#: handlers/views_handler_filter_string.inc:64 +msgid "Ends with" +msgstr "" + +#: handlers/views_handler_filter_string.inc:65 +msgid "ends" +msgstr "" + +#: handlers/views_handler_filter_string.inc:70 +msgid "Does not contain" +msgstr "" + +#: handlers/views_handler_filter_string.inc:71 +msgid "!has" +msgstr "" + +#: handlers/views_handler_filter_string.inc:126 +msgid "Case sensitive" +msgstr "" + +#: handlers/views_handler_filter_string.inc:128 +msgid "Case sensitive filters may be faster. MySQL might ignore case sensitivity." +msgstr "" + +#: handlers/views_handler_relationship.inc:80 +msgid "The label for this relationship that will be displayed only administratively." +msgstr "" + +#: handlers/views_handler_relationship.inc:85 +msgid "Require this relationship" +msgstr "" + +#: handlers/views_handler_relationship.inc:86 +msgid "If required, items that do not contain this relationship will not appear." +msgstr "" + +#: handlers/views_handler_sort.inc:38 +msgid "asc" +msgstr "" + +#: handlers/views_handler_sort.inc:42 +msgid "desc" +msgstr "" + +#: handlers/views_handler_sort.inc:54 +msgid "Sort order" +msgstr "" + +#: handlers/views_handler_sort.inc:55 plugins/views_plugin_style_table.inc:149 +msgid "Ascending" +msgstr "" + +#: handlers/views_handler_sort.inc:55 plugins/views_plugin_style_table.inc:149 +msgid "Descending" +msgstr "" + +#: handlers/views_handler_sort_date.inc:26 +msgid "Granularity" +msgstr "" + +#: handlers/views_handler_sort_date.inc:28 +msgid "Second" +msgstr "" + +#: handlers/views_handler_sort_date.inc:29 +msgid "Minute" +msgstr "" + +#: handlers/views_handler_sort_date.inc:30 +msgid "Hour" +msgstr "" + +#: handlers/views_handler_sort_date.inc:31 +msgid "Day" +msgstr "" + +#: handlers/views_handler_sort_date.inc:32 +msgid "Month" +msgstr "" + +#: handlers/views_handler_sort_date.inc:33 +msgid "Year" +msgstr "" + +#: handlers/views_handler_sort_date.inc:35 +msgid "The granularity is the smallest unit to use when determining whether two dates are the same; for example, if the granularity is \"Year\" then all dates in 1999, regardless of when they fall in 1999, will be considered the same date." +msgstr "" + +#: handlers/views_handler_sort_formula.inc:24 +msgid "views_handler_sort_formula missing default: @formula" +msgstr "" + +#: includes/admin.inc:36 +msgid "If you <a href=\"@modules\">enable the advanced help module</a>, Views will provide more and better help. <a href=\"@hide\">Hide this message.</a>" +msgstr "" + +#: includes/admin.inc:39 +msgid "If you install the advanced help module from !href, Views will provide more and better help. <a href=\"@hide\">Hide this message.</a>" +msgstr "" + +#: includes/admin.inc:94;978 theme/theme.inc:96 views_export/views_export.module:128 +msgid "Export" +msgstr "" + +#: includes/admin.inc:95;983 theme/theme.inc:101 +msgid "Clone" +msgstr "" + +#: includes/admin.inc:98 +msgid "Revert" +msgstr "" + +#: includes/admin.inc:98;634;847 includes/convert.inc:35;108 +msgid "Delete" +msgstr "" + +#: includes/admin.inc:103 +msgid "Disable" +msgstr "" + +#: includes/admin.inc:106 +msgid "Enable" +msgstr "" + +#: includes/admin.inc:112 +msgid "Warning! Broken view!" +msgstr "" + +#: includes/admin.inc:127 includes/view.inc:1666 +msgid "Broken" +msgstr "" + +#: includes/admin.inc:189 +msgid "Install the advanced help module for the getting started" +msgstr "" + +#: includes/admin.inc:192 +msgid "Not sure what to do? Try the \"!getting-started\" page." +msgstr "" + +#: includes/admin.inc:206;213;2131 +msgid "<All>" +msgstr "" + +#: includes/admin.inc:207 plugins/views_plugin_style.inc:76 +msgid "<None>" +msgstr "" + +#: includes/admin.inc:211 +msgid "Storage" +msgstr "" + +#: includes/admin.inc:214;214 includes/view.inc:1165;1215 +msgid "Normal" +msgstr "" + +#: includes/admin.inc:228;275 modules/node.views.inc:140 plugins/views_plugin_display_page.inc:273 +msgid "Type" +msgstr "" + +#: includes/admin.inc:246;273;1063 views_export/views_export.module:146 +msgid "Tag" +msgstr "" + +#: includes/admin.inc:262 +msgid "Displays" +msgstr "" + +#: includes/admin.inc:269 +msgid "Sort by" +msgstr "" + +#: includes/admin.inc:271 modules/system.views.inc:69 modules/user.views.inc:59;79 plugins/views_plugin_display.inc:580 +msgid "Name" +msgstr "" + +#: includes/admin.inc:274;391 modules/statistics.views.inc:149 modules/system.views.inc:88 plugins/views_plugin_display_page.inc:202 +msgid "Path" +msgstr "" + +#: includes/admin.inc:276 includes/convert.inc:21 modules/upload.views.inc:56 views_export/views_export.module:146 +msgid "Description" +msgstr "" + +#: includes/admin.inc:283 +msgid "Order" +msgstr "" + +#: includes/admin.inc:285 +msgid "Up" +msgstr "" + +#: includes/admin.inc:286 +msgid "Down" +msgstr "" + +#: includes/admin.inc:370;401 +msgid "Query" +msgstr "" + +#: includes/admin.inc:372 +msgid "These queries were run during view rendering:" +msgstr "" + +#: includes/admin.inc:377 +msgid "[@time ms]" +msgstr "" + +#: includes/admin.inc:380 +msgid "Other queries" +msgstr "" + +#: includes/admin.inc:388 +msgid "This display has no path." +msgstr "" + +#: includes/admin.inc:393 +msgid "Query build time" +msgstr "" + +#: includes/admin.inc:393;394;395 +msgid "@time ms" +msgstr "" + +#: includes/admin.inc:394 +msgid "Query execute time" +msgstr "" + +#: includes/admin.inc:395 +msgid "View render time" +msgstr "" + +#: includes/admin.inc:401 +msgid "No query was run" +msgstr "" + +#: includes/admin.inc:408 +msgid "Unable to preview due to validation errors." +msgstr "" + +#: includes/admin.inc:459 +msgid "Display" +msgstr "" + +#: includes/admin.inc:467 includes/view.inc:1870 +msgid "Arguments" +msgstr "" + +#: includes/admin.inc:469 +msgid "Separate arguments with a / as though they were a URL path." +msgstr "" + +#: includes/admin.inc:475 +msgid "Preview" +msgstr "" + +#: includes/admin.inc:513 +msgid "Clone view %view" +msgstr "" + +#: includes/admin.inc:526;713 includes/convert.inc:20 +msgid "View name" +msgstr "" + +#: includes/admin.inc:527 +msgid "This is the unique name of the view. It must contain only alphanumeric characters and underscores; it is used to identify the view internally and to generate unique theming template names for this view. If overriding a module provided view, the name must not be changed or instead a new view will be created." +msgstr "" + +#: includes/admin.inc:535;1826 +msgid "View description" +msgstr "" + +#: includes/admin.inc:536;1827 +msgid "This description will appear on the Views administrative UI to tell you what the view is about." +msgstr "" + +#: includes/admin.inc:542;1833 +msgid "View tag" +msgstr "" + +#: includes/admin.inc:543;1834 +msgid "Enter an optional tag for this view; it is used only to help sort views on the administrative page." +msgstr "" + +#: includes/admin.inc:555 +msgid "View type" +msgstr "" + +#: includes/admin.inc:556 +msgid "The view type is the primary table for which information is being retrieved. The view type controls what arguments, fields, sort criteria and filters are available, so once this is set it <strong>cannot be changed</strong>." +msgstr "" + +#: includes/admin.inc:567 +msgid "Next" +msgstr "" + +#: includes/admin.inc:583;758 +msgid "View name must be alphanumeric or underscores only." +msgstr "" + +#: includes/admin.inc:589 +msgid "You must use a unique name for this view." +msgstr "" + +#: includes/admin.inc:622 +msgid "Are you sure you want to revert the view %name?" +msgstr "" + +#: includes/admin.inc:623 +msgid "Reverting the view will delete the view that is in the database, reverting it to the original default view. Any changes you have made will be lost and cannot be recovered." +msgstr "" + +#: includes/admin.inc:626 includes/convert.inc:105 +msgid "Are you sure you want to delete the view %name?" +msgstr "" + +#: includes/admin.inc:627 +msgid "Deleting a view cannot be undone." +msgstr "" + +#: includes/admin.inc:635;671;840;1329 includes/convert.inc:109 +msgid "Cancel" +msgstr "" + +#: includes/admin.inc:644 +msgid "The view has been deleted." +msgstr "" + +#: includes/admin.inc:656 +msgid "There is no lock on view %view to break." +msgstr "" + +#: includes/admin.inc:666 +msgid "Are you sure you want to break the lock on view %name?" +msgstr "" + +#: includes/admin.inc:669 +msgid "By breaking this lock, any unsaved changes made by !user will be lost!" +msgstr "" + +#: includes/admin.inc:670 +msgid "Break lock" +msgstr "" + +#: includes/admin.inc:680 +msgid "The lock has been broken and you may now edit this view." +msgstr "" + +#: includes/admin.inc:687 +msgid "Edit view %view" +msgstr "" + +#: includes/admin.inc:714 +msgid "Enter the name to use for this view if it is different from the source view. Leave blank to use the name of the view." +msgstr "" + +#: includes/admin.inc:719 +msgid "Paste view code here" +msgstr "" + +#: includes/admin.inc:741 +msgid "Unable to interpret view code." +msgstr "" + +#: includes/admin.inc:749 +msgid "You are importing a view created in Views version 1. You may need to adjust some parameters to work correctly in version 2." +msgstr "" + +#: includes/admin.inc:752 +msgid "That view is not compatible with this version of Views." +msgstr "" + +#: includes/admin.inc:767 +msgid "A view by that name already exists; please choose a different name" +msgstr "" + +#: includes/admin.inc:776 +msgid "Display plugin @plugin is not available." +msgstr "" + +#: includes/admin.inc:783 +msgid "Style plugin @plugin is not available." +msgstr "" + +#: includes/admin.inc:789 +msgid "Row plugin @plugin is not available." +msgstr "" + +#: includes/admin.inc:799 +msgid "@type handler @table.@field is not available." +msgstr "" + +#: includes/admin.inc:812 +msgid "Unable to import view." +msgstr "" + +#: includes/admin.inc:833;861 +msgid "Save" +msgstr "" + +#: includes/admin.inc:885 +msgid "The view has been saved." +msgstr "" + +#: includes/admin.inc:929 +msgid "Unknown or missing table name" +msgstr "" + +#: includes/admin.inc:934 +msgid "Click on an item to edit that item's details." +msgstr "" + +#: includes/admin.inc:937 +msgid "This view has a broken default display and cannot be used." +msgstr "" + +#: includes/admin.inc:979 theme/theme.inc:97 +msgid "Export this view" +msgstr "" + +#: includes/admin.inc:984 theme/theme.inc:102 +msgid "Create a copy of this view" +msgstr "" + +#: includes/admin.inc:995 +msgid "View \"!display\"" +msgstr "" + +#: includes/admin.inc:996 +msgid "Go to the real page for this display" +msgstr "" + +#: includes/admin.inc:1062;3008 includes/plugins.inc:218 plugins/views_plugin_display.inc:587;704;723 plugins/views_plugin_display_attachment.inc:90 plugins/views_plugin_display_block.inc:73 plugins/views_plugin_display_feed.inc:108 plugins/views_plugin_display_page.inc:193 +msgid "None" +msgstr "" + +#: includes/admin.inc:1140 +msgid "Invalid" +msgstr "" + +#: includes/admin.inc:1141 +msgid "Error: Display @display refers to a plugin named '@plugin', but that plugin doesn't exist!" +msgstr "" + +#: includes/admin.inc:1176;1176 +msgid "Rearrange" +msgstr "" + +#: includes/admin.inc:1216;2216;2391;2459;2544 +msgid "Error: handler for @table > @field doesn't exist!" +msgstr "" + +#: includes/admin.inc:1235;1235;1244 +msgid "Settings" +msgstr "" + +#: includes/admin.inc:1240 plugins/views_plugin_display.inc:598;616 +msgid "Missing style plugin" +msgstr "" + +#: includes/admin.inc:1244 plugins/views_plugin_display.inc:611;626 +msgid "Change settings for this style" +msgstr "" + +#: includes/admin.inc:1247 +msgid " Style: !style" +msgstr "" + +#: includes/admin.inc:1278 +msgid "Invalid display id found while regenerating tabs" +msgstr "" + +#: includes/admin.inc:1311 +msgid "Update" +msgstr "" + +#: includes/admin.inc:1329 +msgid "Ok" +msgstr "" + +#: includes/admin.inc:1600 +msgid "Unable to initialize default display" +msgstr "" + +#: includes/admin.inc:1632 +msgid "Add display" +msgstr "" + +#: includes/admin.inc:1672 +msgid "Remove display" +msgstr "" + +#: includes/admin.inc:1683 +msgid "Restore display" +msgstr "" + +#: includes/admin.inc:1755 +msgid "Analyze" +msgstr "" + +#: includes/admin.inc:1767 +msgid "View analysis" +msgstr "" + +#: includes/admin.inc:1821 +msgid "View details" +msgstr "" + +#: includes/admin.inc:1862;1916;1971;2117;2209;2384;2452;2537 +msgid "Invalid display id @display" +msgstr "" + +#: includes/admin.inc:1920 +msgid "Configure @type" +msgstr "" + +#: includes/admin.inc:1975 +msgid "Rearrange @type" +msgstr "" + +#: includes/admin.inc:2018 +msgid "Broken field @id" +msgstr "" + +#: includes/admin.inc:2058;2067;2300 +msgid "Remove" +msgstr "" + +#: includes/admin.inc:2058;2058 +msgid "Remove this item" +msgstr "" + +#: includes/admin.inc:2064 +msgid "No fields available." +msgstr "" + +#: includes/admin.inc:2067 modules/book.views.inc:57 modules/taxonomy.views.inc:135 modules/upload.views.inc:90 plugins/views_plugin_display_page.inc:312 +msgid "Weight" +msgstr "" + +#: includes/admin.inc:2123 +msgid "Add @type" +msgstr "" + +#: includes/admin.inc:2134 +msgid "Groups" +msgstr "" + +#: includes/admin.inc:2153 +msgid "!group: !field" +msgstr "" + +#: includes/admin.inc:2162 +msgid "There are no @types available to add." +msgstr "" + +#: includes/admin.inc:2259 +msgid "Do not use a relationship" +msgstr "" + +#: includes/admin.inc:2273 includes/view.inc:1894;1895 +msgid "Relationship" +msgstr "" + +#: includes/admin.inc:2286 +msgid "Configure @type %item" +msgstr "" + +#: includes/admin.inc:2399 +msgid "Configure extra settings for @type %item" +msgstr "" + +#: includes/admin.inc:2464 +msgid "Change summary style for @type %item" +msgstr "" + +#: includes/admin.inc:2487;2501 +msgid "Internal error: broken plugin." +msgstr "" + +#: includes/admin.inc:2551 +msgid "Configure summary style for @type %item" +msgstr "" + +#: includes/admin.inc:2643 +msgid "Clear Views' cache" +msgstr "" + +#: includes/admin.inc:2649 +msgid "Add Views signature to all SQL queries" +msgstr "" + +#: includes/admin.inc:2650 +msgid "All Views-generated queries will include a special 'VIEWS' = 'VIEWS' string in the WHERE clause. This makes identifying Views queries in database server logs simpler, but should only be used when troubleshooting." +msgstr "" + +#: includes/admin.inc:2656 +msgid "Disable views data caching" +msgstr "" + +#: includes/admin.inc:2657 +msgid "Views caches data about tables, modules and views available, to increase performance. By checking this box, Views will skip this cache and always rebuild this data when needed. This can have a serious performance impact on your site." +msgstr "" + +#: includes/admin.inc:2663 +msgid "Ignore missing advanced help module" +msgstr "" + +#: includes/admin.inc:2664 +msgid "Views uses the advanced help module to provide help text; if this module is not present Views will complain, unless this setting is checked." +msgstr "" + +#: includes/admin.inc:2670 +msgid "Show query above live preview" +msgstr "" + +#: includes/admin.inc:2671 +msgid "The live preview feature will show you the output of the view you're creating, as well as the view. Check here to show the query and other information above the view; leave this unchecked to show that information below the view." +msgstr "" + +#: includes/admin.inc:2677 +msgid "Show other queries run during render during live preview" +msgstr "" + +#: includes/admin.inc:2678 +msgid "Drupal has the potential to run many queries while a view is being rendered. Checking this box will display every query run during view render as part of the live preview." +msgstr "" + +#: includes/admin.inc:2684 +msgid "Do not show hover links over views" +msgstr "" + +#: includes/admin.inc:2685 +msgid "To make it easier to administrate your views, Views provides 'hover' links to take you to the edit and export screen of a view whenever the view is used. This can be distracting on some themes, though; if it is problematic, you can turn it off here." +msgstr "" + +#: includes/admin.inc:2691 +msgid "Enable views performance statistics via the Devel module" +msgstr "" + +#: includes/admin.inc:2692 +msgid "Check this to enable some Views query and performance statistics <em>if Devel is installed</em>." +msgstr "" + +#: includes/admin.inc:2698 +msgid "Disable javascript with Views" +msgstr "" + +#: includes/admin.inc:2699 +msgid "If you are having problems with the javascript, you can disable it here; the Views UI should degrade and still be usable without javascript, it just not as good." +msgstr "" + +#: includes/admin.inc:2707 +msgid "Page region to output performance statistics" +msgstr "" + +#: includes/admin.inc:2720 +msgid "The cache has been cleared." +msgstr "" + +#: includes/admin.inc:2886 +msgid "Error: missing @component" +msgstr "" + +#: includes/admin.inc:2972 includes/view.inc:1865 +msgid "Field" +msgstr "" + +#: includes/admin.inc:2973 +msgid "Column" +msgstr "" + +#: includes/admin.inc:2976 +msgid "Sortable" +msgstr "" + +#: includes/admin.inc:2980 +msgid "Default sort" +msgstr "" + +#: includes/ajax.inc:82 +msgid "Server reports invalid input error." +msgstr "" + +#: includes/ajax.inc:83 +msgid "Error" +msgstr "" + +#: includes/analyze.inc:38 +msgid "View analysis can find nothing to report." +msgstr "" + +#: includes/analyze.inc:104 +msgid "This view has only a default display and therefore will not be placed anywhere on your site; perhaps you want to add a page or a block display." +msgstr "" + +#: includes/convert.inc:14 +msgid "There are no Views 1 views stored in the database to convert." +msgstr "" + +#: includes/convert.inc:22 +msgid "Operations" +msgstr "" + +#: includes/convert.inc:33 +msgid "Converted" +msgstr "" + +#: includes/convert.inc:68 +msgid "The table below lists Views version 1 views that are stored in the database. You can either convert them to work in Views version 2, or delete them. The views are convertible only if there is no Views 2 view with the same name." +msgstr "" + +#: includes/convert.inc:79 +msgid "Unable to find view." +msgstr "" + +#: includes/convert.inc:89 +msgid "Unable to convert view." +msgstr "" + +#: includes/convert.inc:107 +msgid "This action cannot be undone." +msgstr "" + +#: includes/convert.inc:117 +msgid "The view has been deleted" +msgstr "" + +#: includes/form.inc:249 +msgid "Validation error, please try again. If this error persists, please contact the site administrator." +msgstr "" + +#: includes/handlers.inc:43 +msgid "Handler @handler include tried to loop infinitely!" +msgstr "" + +#: includes/handlers.inc:269 +msgid "!group: !title" +msgstr "" + +#: includes/handlers.inc:507 +msgid "Reduce duplicates" +msgstr "" + +#: includes/handlers.inc:508 +msgid "This filter can cause items that have more than one of the selected options to appear as duplicate results. If this filter causes duplicate results to occur, this checkbox can reduce those duplicates; however, the more terms it has to search for, the less performant the query will be, so use this with caution." +msgstr "" + +#: includes/plugins.inc:26 +msgid "Default settings for this view." +msgstr "" + +#: includes/plugins.inc:40 +msgid "Display the view as a page, with a URL and menu links." +msgstr "" + +#: includes/plugins.inc:51;60 +msgid "Block" +msgstr "" + +#: includes/plugins.inc:52 +msgid "Display the view as a block." +msgstr "" + +#: includes/plugins.inc:64 +msgid "Attachment" +msgstr "" + +#: includes/plugins.inc:65 +msgid "Attachments added to other displays to achieve multiple views in the same view." +msgstr "" + +#: includes/plugins.inc:73 +msgid "Display the view as a feed, such as an RSS feed." +msgstr "" + +#: includes/plugins.inc:93;144 +msgid "Unformatted" +msgstr "" + +#: includes/plugins.inc:94 +msgid "Displays rows one after another." +msgstr "" + +#: includes/plugins.inc:104 +msgid "HTML List" +msgstr "" + +#: includes/plugins.inc:105 +msgid "Displays rows as an HTML list." +msgstr "" + +#: includes/plugins.inc:114 +msgid "Grid" +msgstr "" + +#: includes/plugins.inc:115 +msgid "Displays rows in a grid." +msgstr "" + +#: includes/plugins.inc:124 +msgid "Table" +msgstr "" + +#: includes/plugins.inc:125 +msgid "Displays rows in a table." +msgstr "" + +#: includes/plugins.inc:136 +msgid "Displays the default summary as a list." +msgstr "" + +#: includes/plugins.inc:145 +msgid "Displays the summary unformatted, with option for one after another or inline." +msgstr "" + +#: includes/plugins.inc:154 +msgid "RSS Feed" +msgstr "" + +#: includes/plugins.inc:155 +msgid "Generates an RSS feed from a view." +msgstr "" + +#: includes/plugins.inc:173 includes/view.inc:1863 +msgid "Fields" +msgstr "" + +#: includes/plugins.inc:174 +msgid "Displays the fields with an optional template." +msgstr "" + +#: includes/plugins.inc:187 +msgid "Fixed entry" +msgstr "" + +#: includes/plugins.inc:191;203 +msgid "PHP Code" +msgstr "" + +#: includes/plugins.inc:207 +msgid "Numeric" +msgstr "" + +#: includes/plugins.inc:219 +msgid "Will be available to all users." +msgstr "" + +#: includes/plugins.inc:224 plugins/views_plugin_access_role.inc:40 +msgid "Role" +msgstr "" + +#: includes/plugins.inc:225 +msgid "Access will be granted to users with any of the specified roles." +msgstr "" + +#: includes/plugins.inc:231 plugins/views_plugin_access_perm.inc:35 +msgid "Permission" +msgstr "" + +#: includes/plugins.inc:232 +msgid "Access will be granted to users with the specified permission string." +msgstr "" + +#: includes/view.inc:261 +msgid "set_display() called with invalid display id @display." +msgstr "" + +#: includes/view.inc:1063 +msgid "Home" +msgstr "" + +#: includes/view.inc:1864 +msgid "fields" +msgstr "" + +#: includes/view.inc:1866 +msgid "field" +msgstr "" + +#: includes/view.inc:1871 +msgid "arguments" +msgstr "" + +#: includes/view.inc:1872;1873 +msgid "Argument" +msgstr "" + +#: includes/view.inc:1877 +msgid "Sort criteria" +msgstr "" + +#: includes/view.inc:1878 +msgid "sort criteria" +msgstr "" + +#: includes/view.inc:1879 +msgid "Sort criterion" +msgstr "" + +#: includes/view.inc:1880 +msgid "sort criterion" +msgstr "" + +#: includes/view.inc:1884 +msgid "Filters" +msgstr "" + +#: includes/view.inc:1885 +msgid "filters" +msgstr "" + +#: includes/view.inc:1886 +msgid "Filter" +msgstr "" + +#: includes/view.inc:1887 +msgid "filter" +msgstr "" + +#: includes/view.inc:1892 +msgid "Relationships" +msgstr "" + +#: includes/view.inc:1893 +msgid "relationships" +msgstr "" + +#: js/ajax.js:0;0;0;0;0;0;0 js/ajax_view.js:0;0;0 +msgid "An error occurred at @path." +msgstr "" + +#: js/tabs.js:0 +msgid "jQuery UI Tabs: Mismatching fragment identifier." +msgstr "" + +#: js/tabs.js:0 +msgid "jQuery UI Tabs: Not enough arguments to add tab." +msgstr "" + +#: modules/book.views.inc:21;36;46;99 +msgid "Book" +msgstr "" + +#: modules/book.views.inc:30 +msgid "Top level book" +msgstr "" + +#: modules/book.views.inc:31 +msgid "The book the node is in." +msgstr "" + +#: modules/book.views.inc:58 +msgid "The weight of the book page." +msgstr "" + +#: modules/book.views.inc:69 modules/comment.views.inc:202 modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:24 +msgid "Depth" +msgstr "" + +#: modules/book.views.inc:70 +msgid "The depth of the book page in the hierarchy; top level books have a depth of 1." +msgstr "" + +#: modules/book.views.inc:87 +msgid "Hierarchy" +msgstr "" + +#: modules/book.views.inc:88 +msgid "The order of pages in the book hierarchy. Remember to sort by weight too if you want exactly the right order." +msgstr "" + +#: modules/book.views.inc:110 modules/taxonomy.views.inc:259 +msgid "Parent" +msgstr "" + +#: modules/book.views.inc:111 +msgid "The parent book node." +msgstr "" + +#: modules/book.views.inc:116 +msgid "Book parent" +msgstr "" + +#: modules/comment.views.inc:22;26;384;395 +msgid "Comment" +msgstr "" + +#: modules/comment.views.inc:27 +msgid "Comments are responses to node content." +msgstr "" + +#: modules/comment.views.inc:45 +msgid "The title of the comment." +msgstr "" + +#: modules/comment.views.inc:63 modules/node.views.inc:358 +msgid "Body" +msgstr "" + +#: modules/comment.views.inc:64 +msgid "The text of the comment." +msgstr "" + +#: modules/comment.views.inc:76 +msgid "ID" +msgstr "" + +#: modules/comment.views.inc:77 +msgid "The comment ID of the field" +msgstr "" + +#: modules/comment.views.inc:95 +msgid "Author" +msgstr "" + +#: modules/comment.views.inc:96 +msgid "The name of the poster." +msgstr "" + +#: modules/comment.views.inc:114 +msgid "Author's website" +msgstr "" + +#: modules/comment.views.inc:115 +msgid "The website address of the comment's author. Can be a link. The homepage can also be linked with the Name field. Will be empty if posted by a registered user." +msgstr "" + +#: modules/comment.views.inc:133 modules/node.views.inc:108 +msgid "Post date" +msgstr "" + +#: modules/comment.views.inc:134 +msgid "Date and time of when the comment was posted." +msgstr "" + +#: modules/comment.views.inc:149 +msgid "In moderation" +msgstr "" + +#: modules/comment.views.inc:150 +msgid "Whether or not the comment is currently in moderation." +msgstr "" + +#: modules/comment.views.inc:157 modules/node.views.inc:204;213 +msgid "Moderated" +msgstr "" + +#: modules/comment.views.inc:167 +msgid "View link" +msgstr "" + +#: modules/comment.views.inc:168 +msgid "Provide a simple link to view the comment." +msgstr "" + +#: modules/comment.views.inc:176 modules/node.views.inc:250 modules/user.views.inc:202 +msgid "Edit link" +msgstr "" + +#: modules/comment.views.inc:177 +msgid "Provide a simple link to edit the comment." +msgstr "" + +#: modules/comment.views.inc:185 modules/node.views.inc:258;472 modules/user.views.inc:210 +msgid "Delete link" +msgstr "" + +#: modules/comment.views.inc:186 +msgid "Provide a simple link to delete the comment." +msgstr "" + +#: modules/comment.views.inc:194 +msgid "Reply-to link" +msgstr "" + +#: modules/comment.views.inc:195 +msgid "Provide a simple link to reply to the comment." +msgstr "" + +#: modules/comment.views.inc:203 +msgid "Display the depth of the comment if it is threaded." +msgstr "" + +#: modules/comment.views.inc:207 +msgid "Thread" +msgstr "" + +#: modules/comment.views.inc:208 +msgid "Sort by the threaded order. This will keep child comments together with their parents." +msgstr "" + +#: modules/comment.views.inc:214;220;255 modules/node.views.inc:24;29;90;357;372;484;616;627;639 modules/upload.views.inc:43 +msgid "Node" +msgstr "" + +#: modules/comment.views.inc:215 +msgid "The node the comment is a reply to." +msgstr "" + +#: modules/comment.views.inc:225;231 modules/node.views.inc:345 modules/statistics.views.inc:204 modules/user.views.inc:23;27;219 +msgid "User" +msgstr "" + +#: modules/comment.views.inc:226 +msgid "The user who wrote the comment." +msgstr "" + +#: modules/comment.views.inc:236 +msgid "Parent CID" +msgstr "" + +#: modules/comment.views.inc:237 +msgid "The Comment ID of the parent comment." +msgstr "" + +#: modules/comment.views.inc:242;247 +msgid "Parent comment" +msgstr "" + +#: modules/comment.views.inc:243 +msgid "The parent comment." +msgstr "" + +#: modules/comment.views.inc:268 +msgid "Last comment time" +msgstr "" + +#: modules/comment.views.inc:269 +msgid "Date and time of when the last comment was posted." +msgstr "" + +#: modules/comment.views.inc:284 +msgid "Last comment author" +msgstr "" + +#: modules/comment.views.inc:285 +msgid "The name of the author of the last posted comment." +msgstr "" + +#: modules/comment.views.inc:297 +msgid "Comment count" +msgstr "" + +#: modules/comment.views.inc:298 +msgid "The number of comments a node has." +msgstr "" + +#: modules/comment.views.inc:316 +msgid "Updated/commented date" +msgstr "" + +#: modules/comment.views.inc:317 +msgid "The most recent of last comment posted or node updated time." +msgstr "" + +#: modules/comment.views.inc:340 +msgid "New comments" +msgstr "" + +#: modules/comment.views.inc:341 +msgid "The number of new comments on the node." +msgstr "" + +#: modules/comment.views.inc:349 +msgid "Comment status" +msgstr "" + +#: modules/comment.views.inc:350 +msgid "Whether comments are enabled or disabled on the node." +msgstr "" + +#: modules/comment.views.inc:364 +msgid "User posted or commented" +msgstr "" + +#: modules/comment.views.inc:365 +msgid "Display comments only if a user posted the node or commented on the node." +msgstr "" + +#: modules/comment.views.inc:385 +msgid "Display the comment with standard comment view." +msgstr "" + +#: modules/comment.views.inc:396 +msgid "Display the comment as RSS." +msgstr "" + +#: modules/node.views.inc:30 +msgid "Nodes are a Drupal site's primary content." +msgstr "" + +#: modules/node.views.inc:57 +msgid "Nid" +msgstr "" + +#: modules/node.views.inc:58 +msgid "The node ID of the node." +msgstr "" + +#: modules/node.views.inc:86;414 +msgid "The title of the node." +msgstr "" + +#: modules/node.views.inc:109 +msgid "The date the node was posted." +msgstr "" + +#: modules/node.views.inc:124 +msgid "Updated date" +msgstr "" + +#: modules/node.views.inc:125 +msgid "The date the node was last updated." +msgstr "" + +#: modules/node.views.inc:141 +msgid "The type of a node (for example, \"blog entry\", \"forum post\", \"story\", etc)." +msgstr "" + +#: modules/node.views.inc:159;167;181 modules/translation.views.inc:106 modules/upload.views.inc:82 +msgid "Published" +msgstr "" + +#: modules/node.views.inc:160 +msgid "The published status of the node." +msgstr "" + +#: modules/node.views.inc:176 +msgid "Published or admin" +msgstr "" + +#: modules/node.views.inc:177 +msgid "Filters out unpublished nodes if the current user cannot view them." +msgstr "" + +#: modules/node.views.inc:187;195 +msgid "Promoted to front page" +msgstr "" + +#: modules/node.views.inc:188 +msgid "The front page of the node." +msgstr "" + +#: modules/node.views.inc:205 +msgid "Whether or not the node is moderated." +msgstr "" + +#: modules/node.views.inc:222;231 +msgid "Sticky" +msgstr "" + +#: modules/node.views.inc:223 +msgid "Whether or not the node is sticky." +msgstr "" + +#: modules/node.views.inc:242 +msgid "Link" +msgstr "" + +#: modules/node.views.inc:243 +msgid "Provide a simple link to the node." +msgstr "" + +#: modules/node.views.inc:251 +msgid "Provide a simple link to edit the node." +msgstr "" + +#: modules/node.views.inc:259 +msgid "Provide a simple link to delete the node." +msgstr "" + +#: modules/node.views.inc:267;448 modules/user.views.inc:123 +msgid "Created date" +msgstr "" + +#: modules/node.views.inc:268 +msgid "In the form of CCYYMMDD." +msgstr "" + +#: modules/node.views.inc:276 +msgid "Created year + month" +msgstr "" + +#: modules/node.views.inc:277 +msgid "In the form of YYYYMM." +msgstr "" + +#: modules/node.views.inc:285 +msgid "Created year" +msgstr "" + +#: modules/node.views.inc:286 +msgid "In the form of YYYY." +msgstr "" + +#: modules/node.views.inc:294 +msgid "Created month" +msgstr "" + +#: modules/node.views.inc:295 +msgid "In the form of MM (01 - 12)." +msgstr "" + +#: modules/node.views.inc:303 +msgid "Created day" +msgstr "" + +#: modules/node.views.inc:304 +msgid "In the form of DD (01 - 31)." +msgstr "" + +#: modules/node.views.inc:312 +msgid "Created week" +msgstr "" + +#: modules/node.views.inc:313 +msgid "In the form of WW (01 - 53)." +msgstr "" + +#: modules/node.views.inc:325;330 +msgid "Node revision" +msgstr "" + +#: modules/node.views.inc:331 +msgid "Node revisions are a history of changes to nodes." +msgstr "" + +#: modules/node.views.inc:346 +msgid "Relate a node revision to the user who created the revision." +msgstr "" + +#: modules/node.views.inc:351 +msgid "user" +msgstr "" + +#: modules/node.views.inc:359 +msgid "The actual, full data in the body field; this may not be valid data on all node types." +msgstr "" + +#: modules/node.views.inc:373 +msgid "Teaser" +msgstr "" + +#: modules/node.views.inc:374 +msgid "The stored teaser field. This may not be valid or useful data on all node types." +msgstr "" + +#: modules/node.views.inc:387 +msgid "Vid" +msgstr "" + +#: modules/node.views.inc:388 +msgid "The revision ID of the node revision." +msgstr "" + +#: modules/node.views.inc:434 +msgid "Log message" +msgstr "" + +#: modules/node.views.inc:435 +msgid "The log message entered when the revision was created." +msgstr "" + +#: modules/node.views.inc:449 +msgid "The date the node revision was created." +msgstr "" + +#: modules/node.views.inc:464 +msgid "Revert link" +msgstr "" + +#: modules/node.views.inc:465 +msgid "Provide a simple link to revert to the revision." +msgstr "" + +#: modules/node.views.inc:473 +msgid "Provide a simple link to delete the node revision." +msgstr "" + +#: modules/node.views.inc:500 +msgid "Has new content" +msgstr "" + +#: modules/node.views.inc:503 +msgid "Show a marker if the node has new or updated content." +msgstr "" + +#: modules/node.views.inc:506 +msgid "Show only nodes that have new content." +msgstr "" + +#: modules/node.views.inc:617;628 +msgid "Display the node with standard node view." +msgstr "" + +#: modules/node.views.inc:646 +msgid "Node ID from URL" +msgstr "" + +#: modules/node.views.inc:708 +msgid "Display %display has no access control but does not contain a filter for published nodes." +msgstr "" + +#: modules/poll.views.inc:23 +msgid "Poll" +msgstr "" + +#: modules/poll.views.inc:38;47 modules/user.views.inc:171;180 +msgid "Active" +msgstr "" + +#: modules/poll.views.inc:39 +msgid "Whether the poll is open for voting." +msgstr "" + +#: modules/profile.views.inc:20;40 +msgid "Profile" +msgstr "" + +#: modules/profile.views.inc:100 +msgid "@field-name" +msgstr "" + +#: modules/profile.views.inc:107 +msgid "Profile textfield" +msgstr "" + +#: modules/profile.views.inc:126 +msgid "Profile textarea" +msgstr "" + +#: modules/profile.views.inc:142 +msgid "Profile checkbox" +msgstr "" + +#: modules/profile.views.inc:159 +msgid "Profile URL" +msgstr "" + +#: modules/profile.views.inc:175 +msgid "Profile selection" +msgstr "" + +#: modules/profile.views.inc:195 +msgid "Profile freeform list %field-name." +msgstr "" + +#: modules/profile.views.inc:207 +msgid "Profile date %field-name." +msgstr "" + +#: modules/search.views.inc:23;77;88;106;163 +msgid "Search" +msgstr "" + +#: modules/search.views.inc:72 +msgid "Score" +msgstr "" + +#: modules/search.views.inc:73 +msgid "The score of the search item." +msgstr "" + +#: modules/search.views.inc:95 +msgid "Links from" +msgstr "" + +#: modules/search.views.inc:96 +msgid "Nodes that link from the node." +msgstr "" + +#: modules/search.views.inc:113 +msgid "Links to" +msgstr "" + +#: modules/search.views.inc:114 +msgid "Nodes that link to the node." +msgstr "" + +#: modules/search.views.inc:125 +msgid "Search Terms" +msgstr "" + +#: modules/search.views.inc:126 +msgid "The terms to search for." +msgstr "" + +#: modules/search.views.inc:164 +msgid "Display the results with standard search view." +msgstr "" + +#: modules/statistics.views.inc:24 +msgid "Node statistics" +msgstr "" + +#: modules/statistics.views.inc:36 +msgid "Total views" +msgstr "" + +#: modules/statistics.views.inc:37 +msgid "The total number of times the node has been viewed." +msgstr "" + +#: modules/statistics.views.inc:53 +msgid "Views today" +msgstr "" + +#: modules/statistics.views.inc:54 +msgid "The total number of times the node has been viewed today." +msgstr "" + +#: modules/statistics.views.inc:70 +msgid "Most recent view" +msgstr "" + +#: modules/statistics.views.inc:71 +msgid "The most recent time the node has been viewed." +msgstr "" + +#: modules/statistics.views.inc:89;94 +msgid "Access log" +msgstr "" + +#: modules/statistics.views.inc:95 +msgid "Stores site access information." +msgstr "" + +#: modules/statistics.views.inc:109 +msgid "Session ID" +msgstr "" + +#: modules/statistics.views.inc:110 +msgid "Browser session ID of user that visited page." +msgstr "" + +#: modules/statistics.views.inc:129 +msgid "Page title" +msgstr "" + +#: modules/statistics.views.inc:130 +msgid "Title of page visited." +msgstr "" + +#: modules/statistics.views.inc:150 +msgid "Internal path to page visited (relative to Drupal root.)" +msgstr "" + +#: modules/statistics.views.inc:169 +msgid "Referrer" +msgstr "" + +#: modules/statistics.views.inc:170 +msgid "Referrer URI." +msgstr "" + +#: modules/statistics.views.inc:185 +msgid "Hostname" +msgstr "" + +#: modules/statistics.views.inc:186 +msgid "Hostname of user that visited the page." +msgstr "" + +#: modules/statistics.views.inc:205 +msgid "The user who visited the site." +msgstr "" + +#: modules/statistics.views.inc:215 +msgid "Timer" +msgstr "" + +#: modules/statistics.views.inc:216 +msgid "Time in milliseconds that the page took to load." +msgstr "" + +#: modules/statistics.views.inc:231 +msgid "Timestamp" +msgstr "" + +#: modules/statistics.views.inc:232 +msgid "Timestamp of when the page was visited." +msgstr "" + +#: modules/system.views.inc:25;30 +msgid "File" +msgstr "" + +#: modules/system.views.inc:31 +msgid "Files maintained by Drupal and various modules." +msgstr "" + +#: modules/system.views.inc:49 +msgid "File ID" +msgstr "" + +#: modules/system.views.inc:50 +msgid "The ID of the file." +msgstr "" + +#: modules/system.views.inc:70 +msgid "The name of the file." +msgstr "" + +#: modules/system.views.inc:89 +msgid "The path of the file." +msgstr "" + +#: modules/system.views.inc:107 +msgid "Mime type" +msgstr "" + +#: modules/system.views.inc:108 +msgid "The mime type of the file." +msgstr "" + +#: modules/system.views.inc:126 +msgid "Size" +msgstr "" + +#: modules/system.views.inc:127 +msgid "The size of the file." +msgstr "" + +#: modules/system.views.inc:142 +msgid "Status" +msgstr "" + +#: modules/system.views.inc:143 +msgid "The status of the file." +msgstr "" + +#: modules/system.views.inc:158 +msgid "Upload date" +msgstr "" + +#: modules/system.views.inc:159 +msgid "The date the file was uploaded." +msgstr "" + +#: modules/system.views.inc:204 +msgid "Temporary" +msgstr "" + +#: modules/system.views.inc:205 +msgid "Permanent" +msgstr "" + +#: modules/taxonomy.views.inc:24;67;152;170;226;266;303;314 +msgid "Taxonomy" +msgstr "" + +#: modules/taxonomy.views.inc:48 +msgid "Vocabulary name" +msgstr "" + +#: modules/taxonomy.views.inc:50 +msgid "Name of the vocabulary a term is a member of. This will be the vocabulary that whichever term the \"Taxonomy: Term\" field is; and can similarly cause duplicates." +msgstr "" + +#: modules/taxonomy.views.inc:56 +msgid "Vocabulary ID" +msgstr "" + +#: modules/taxonomy.views.inc:57 +msgid "The taxonomy vocabulary ID" +msgstr "" + +#: modules/taxonomy.views.inc:70;116;213 +msgid "Term" +msgstr "" + +#: modules/taxonomy.views.inc:71 +msgid "Taxonomy terms are attached to nodes." +msgstr "" + +#: modules/taxonomy.views.inc:96;196 modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:35 +msgid "Term ID" +msgstr "" + +#: modules/taxonomy.views.inc:97;197 +msgid "The taxonomy term ID" +msgstr "" + +#: modules/taxonomy.views.inc:117 +msgid "Taxonomy terms. Note that using this can cause duplicate nodes to appear in views; you must add filters to reduce the result set." +msgstr "" + +#: modules/taxonomy.views.inc:127 +msgid "Taxonomy term name." +msgstr "" + +#: modules/taxonomy.views.inc:136 +msgid "The term weight field" +msgstr "" + +#: modules/taxonomy.views.inc:148 +msgid "Term description" +msgstr "" + +#: modules/taxonomy.views.inc:149 +msgid "The description associated with a taxonomy term." +msgstr "" + +#: modules/taxonomy.views.inc:160 modules/taxonomy/views_handler_filter_term_node_tid.inc:37 +msgid "Vocabulary" +msgstr "" + +#: modules/taxonomy.views.inc:161 +msgid "Filter the results of \"Taxonomy: Term\" to a particular vocabulary." +msgstr "" + +#: modules/taxonomy.views.inc:199 +msgid "All terms" +msgstr "" + +#: modules/taxonomy.views.inc:200 +msgid "Display all taxonomy terms associated with a node from specified vocabularies." +msgstr "" + +#: modules/taxonomy.views.inc:254 +msgid "Parent term" +msgstr "" + +#: modules/taxonomy.views.inc:255 +msgid "The parent term of the term. This can produce duplicate entries if you are using a vocabulary that allows multiple parents." +msgstr "" + +#: modules/taxonomy.views.inc:287 +msgid "Term synonym" +msgstr "" + +#: modules/taxonomy.views.inc:288 +msgid "Term synonyms may be used to find terms by alternate names." +msgstr "" + +#: modules/taxonomy.views.inc:304 +msgid "Term ID (with depth)" +msgstr "" + +#: modules/taxonomy.views.inc:305 +msgid "The depth filter is more complex, so provides fewer options." +msgstr "" + +#: modules/taxonomy.views.inc:315 +msgid "Term ID depth modifier" +msgstr "" + +#: modules/taxonomy.views.inc:316 +msgid "Allows the \"depth\" for Taxonomy: Term ID (with depth) to be modified via an additional argument." +msgstr "" + +#: modules/taxonomy.views.inc:372 +msgid "Taxonomy term" +msgstr "" + +#: modules/translation.views.inc:31;48;80;97 +msgid "Node translation" +msgstr "" + +#: modules/translation.views.inc:32 modules/node/views_handler_filter_node_language.inc:9 modules/translation/views_handler_filter_node_language.inc:9 +msgid "Language" +msgstr "" + +#: modules/translation.views.inc:33 +msgid "The language the content is in." +msgstr "" + +#: modules/translation.views.inc:49 +msgid "Translation set node ID" +msgstr "" + +#: modules/translation.views.inc:50 +msgid "The ID of the translation set the content belongs to." +msgstr "" + +#: modules/translation.views.inc:69;74 +msgid "Source translation" +msgstr "" + +#: modules/translation.views.inc:70 +msgid "The source that this content was translated from." +msgstr "" + +#: modules/translation.views.inc:81;84;91 +msgid "Translations" +msgstr "" + +#: modules/translation.views.inc:82;85 +msgid "Versions of content in different languages." +msgstr "" + +#: modules/translation.views.inc:98 +msgid "Translation status" +msgstr "" + +#: modules/translation.views.inc:99 +msgid "The translation status of the node--whether or not the translation needs to be updated." +msgstr "" + +#: modules/upload.views.inc:25;112 +msgid "Upload" +msgstr "" + +#: modules/upload.views.inc:44 +msgid "The node the uploaded file is attached to" +msgstr "" + +#: modules/upload.views.inc:46 +msgid "upload" +msgstr "" + +#: modules/upload.views.inc:57 +msgid "The description of the uploaded file." +msgstr "" + +#: modules/upload.views.inc:74 +msgid "Listed" +msgstr "" + +#: modules/upload.views.inc:75 +msgid "Whether or not the file is marked to be listed." +msgstr "" + +#: modules/upload.views.inc:91 +msgid "The weight, used for sorting." +msgstr "" + +#: modules/upload.views.inc:113;125 +msgid "Attached files" +msgstr "" + +#: modules/upload.views.inc:114 +msgid "All files attached to a node with upload.module." +msgstr "" + +#: modules/upload.views.inc:121 modules/upload/views_handler_filter_upload_fid.inc:10 +msgid "Has attached files" +msgstr "" + +#: modules/upload.views.inc:122 +msgid "Only display items with attached files. This can cause duplicates if there are multiple attached files." +msgstr "" + +#: modules/upload.views.inc:126 +msgid "Add a relationship to gain access to more file data for files uploaded by upload.module. Note that this relationship will cause duplicate nodes if there are multiple files attached to the node." +msgstr "" + +#: modules/upload.views.inc:132 +msgid "Files" +msgstr "" + +#: modules/user.views.inc:28 +msgid "Users who have created accounts on your site." +msgstr "" + +#: modules/user.views.inc:48 +msgid "Uid" +msgstr "" + +#: modules/user.views.inc:49 +msgid "The user ID" +msgstr "" + +#: modules/user.views.inc:70 +msgid "Current" +msgstr "" + +#: modules/user.views.inc:71 +msgid "Filter the view to the currently logged in user." +msgstr "" + +#: modules/user.views.inc:80 +msgid "The user or author name." +msgstr "" + +#: modules/user.views.inc:96 +msgid "E-mail" +msgstr "" + +#: modules/user.views.inc:97 +msgid "Email address for a given user. This field is not normally shown to users, so be cautious when using it." +msgstr "" + +#: modules/user.views.inc:112 +msgid "Picture" +msgstr "" + +#: modules/user.views.inc:113 +msgid "The user's picture, if allowed." +msgstr "" + +#: modules/user.views.inc:124 +msgid "The date the user was created." +msgstr "" + +#: modules/user.views.inc:139 +msgid "Last access" +msgstr "" + +#: modules/user.views.inc:140 +msgid "The user's last access date." +msgstr "" + +#: modules/user.views.inc:155 +msgid "Last login" +msgstr "" + +#: modules/user.views.inc:156 +msgid "The user's last login date." +msgstr "" + +#: modules/user.views.inc:172 +msgid "Whether a user is active or blocked." +msgstr "" + +#: modules/user.views.inc:189 +msgid "Signature" +msgstr "" + +#: modules/user.views.inc:190 +msgid "The user's signature." +msgstr "" + +#: modules/user.views.inc:203 +msgid "Provide a simple link to edit the user." +msgstr "" + +#: modules/user.views.inc:211 +msgid "Provide a simple link to delete the user." +msgstr "" + +#: modules/user.views.inc:240 +msgid "Roles" +msgstr "" + +#: modules/user.views.inc:241 +msgid "Roles that a user belongs to." +msgstr "" + +#: modules/user.views.inc:253 +msgid "No role" +msgstr "" + +#: modules/user.views.inc:296 +msgid "User ID from URL" +msgstr "" + +#: modules/user.views.inc:302 +msgid "User ID from logged in user" +msgstr "" + +#: modules/views.views.inc:18 +msgid "Global" +msgstr "" + +#: modules/views.views.inc:23 +msgid "Random" +msgstr "" + +#: modules/views.views.inc:24 +msgid "Randomize the display order." +msgstr "" + +#: modules/views.views.inc:31 +msgid "Null" +msgstr "" + +#: modules/views.views.inc:32 +msgid "Allow an argument to be ignored. The query will not be altered by this argument." +msgstr "" + +#: modules/comment/views_handler_argument_comment_user_uid.inc:11 modules/user/views_handler_argument_user_uid.inc:17 +msgid "Anonymous" +msgstr "" + +#: modules/comment/views_handler_argument_comment_user_uid.inc:17 +msgid "No user" +msgstr "" + +#: modules/comment/views_handler_field_comment.inc:30 +msgid "Link this field to its comment" +msgstr "" + +#: modules/comment/views_handler_field_comment_link.inc:23 modules/node/views_handler_field_node_link.inc:24 modules/user/views_handler_field_user_link.inc:22 +msgid "Text to display" +msgstr "" + +#: modules/comment/views_handler_field_comment_link.inc:34 modules/node/views_handler_field_node_link.inc:35 modules/user/views_handler_field_user_link.inc:38 +msgid "view" +msgstr "" + +#: modules/comment/views_handler_field_comment_link_delete.inc:12 modules/node/views_handler_field_node_link_delete.inc:26 modules/node/views_handler_field_node_revision_link_delete.inc:35 modules/user/views_handler_field_user_link_delete.inc:13 +msgid "delete" +msgstr "" + +#: modules/comment/views_handler_field_comment_link_edit.inc:21 modules/node/views_handler_field_node_link_edit.inc:26 modules/user/views_handler_field_user_link_edit.inc:13 +msgid "edit" +msgstr "" + +#: modules/comment/views_handler_field_comment_link_reply.inc:13 +msgid "reply" +msgstr "" + +#: modules/comment/views_handler_field_comment_username.inc:25 +msgid "Link this field to its user or an author's homepage" +msgstr "" + +#: modules/comment/views_handler_field_node_comment.inc:12 modules/comment/views_handler_filter_node_comment.inc:10 +msgid "Disabled" +msgstr "" + +#: modules/comment/views_handler_field_node_comment.inc:14 modules/comment/views_handler_filter_node_comment.inc:11 +msgid "Read only" +msgstr "" + +#: modules/comment/views_handler_field_node_comment.inc:16 modules/comment/views_handler_filter_node_comment.inc:12 +msgid "Read/Write" +msgstr "" + +#: modules/comment/views_handler_field_node_new_comments.inc:25 +msgid "Link this field to new comments" +msgstr "" + +#: modules/comment/views_handler_field_node_new_comments.inc:30 +msgid "Display nothing if no new comments" +msgstr "" + +#: modules/comment/views_plugin_row_comment_view.inc:21 modules/node/views_plugin_row_node_view.inc:32 +msgid "Display links" +msgstr "" + +#: modules/node/views_handler_argument_dates_various.inc:167 +msgid "Week @week" +msgstr "" + +#: modules/node/views_handler_argument_node_language.inc:29 modules/translation/views_handler_argument_node_language.inc:29 +msgid "Unknown language" +msgstr "" + +#: modules/node/views_handler_argument_node_type.inc:30 +msgid "Unknown node type" +msgstr "" + +#: modules/node/views_handler_field_history_user_timestamp.inc:32 +msgid "Check for new comments as well" +msgstr "" + +#: modules/node/views_handler_field_node.inc:32 +msgid "Link this field to its node" +msgstr "" + +#: modules/node/views_handler_field_node_revision_link_revert.inc:36 +msgid "revert" +msgstr "" + +#: modules/node/views_handler_filter_node_language.inc:10 modules/translation/views_handler_filter_node_language.inc:10 +msgid "Current user's language" +msgstr "" + +#: modules/node/views_handler_filter_node_language.inc:10 modules/translation/views_handler_filter_node_language.inc:10 +msgid "No language" +msgstr "" + +#: modules/node/views_handler_filter_node_type.inc:9 +msgid "Node type" +msgstr "" + +#: modules/node/views_plugin_argument_validate_node.inc:29 +msgid "Types" +msgstr "" + +#: modules/node/views_plugin_argument_validate_node.inc:32 +msgid "If you wish to validate for specific node types, check them; if none are checked, all nodes will pass." +msgstr "" + +#: modules/node/views_plugin_argument_validate_node.inc:39 +msgid "Validate user has access to the node" +msgstr "" + +#: modules/node/views_plugin_argument_validate_node.inc:47 modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:33 +msgid "Argument type" +msgstr "" + +#: modules/node/views_plugin_argument_validate_node.inc:49 +msgid "Node ID" +msgstr "" + +#: modules/node/views_plugin_argument_validate_node.inc:50 +msgid "Node IDs separated by , or +" +msgstr "" + +#: modules/node/views_plugin_row_node_rss.inc:26 +msgid "Full text" +msgstr "" + +#: modules/node/views_plugin_row_node_rss.inc:27 +msgid "Title plus teaser" +msgstr "" + +#: modules/node/views_plugin_row_node_rss.inc:28 +msgid "Title only" +msgstr "" + +#: modules/node/views_plugin_row_node_rss.inc:29 +msgid "Use default RSS settings" +msgstr "" + +#: modules/node/views_plugin_row_node_rss.inc:95 +msgid "read more" +msgstr "" + +#: modules/node/views_plugin_row_node_view.inc:27 +msgid "Display only teaser" +msgstr "" + +#: modules/node/views_plugin_row_node_view.inc:37 +msgid "Display node comments" +msgstr "" + +#: modules/search/views_handler_filter_search.inc:23 +msgid "On empty input" +msgstr "" + +#: modules/search/views_handler_filter_search.inc:26 +msgid "Show All" +msgstr "" + +#: modules/search/views_handler_filter_search.inc:27 +msgid "Show None" +msgstr "" + +#: modules/search/views_handler_filter_search.inc:42 +msgid "Enter the terms you wish to search for." +msgstr "" + +#: modules/search/views_handler_filter_search.inc:62 +msgid "You must include at least one positive keyword with @count characters or more." +msgstr "" + +#: modules/search/views_handler_filter_search.inc:66 +msgid "Search for either of the two terms with uppercase <strong>OR</strong>. For example, <strong>cats OR dogs</strong>." +msgstr "" + +#: modules/search/views_plugin_row_search_view.inc:23 +msgid "Display score" +msgstr "" + +#: modules/system/views_handler_argument_file_fid.inc:13 +msgid "No title" +msgstr "" + +#: modules/system/views_handler_field_file.inc:29 modules/upload/views_handler_field_upload_description.inc:24 modules/upload/views_handler_field_upload_fid.inc:21 +msgid "Link this field to download the file" +msgstr "" + +#: modules/taxonomy/views_handler_argument_taxonomy.inc:18 modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:125 +msgid "No name" +msgstr "" + +#: modules/taxonomy/views_handler_argument_term_node_tid.inc:17 modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:38 +msgid "Set the breadcrumb for the term parents" +msgstr "" + +#: modules/taxonomy/views_handler_argument_term_node_tid.inc:18 modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:39 +msgid "If selected, the breadcrumb trail will include all parent terms, each one linking to this view. Note that this only works if just one term was received." +msgstr "" + +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:26 +msgid "The depth will match nodes tagged with terms in the hierarchy. For example, if you have the term \"fruit\" and a child term \"apple\", with a depth of 1 (or higher) then filtering for the term \"fruit\" will get nodes that are tagged with \"apple\" as well as \"fruit\". If negative, the reverse is true; searching for \"apple\" will also pick up nodes tagged with \"fruit\" if depth is -1 (or lower)." +msgstr "" + +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:31 +msgid "Allow multiple terms per argument" +msgstr "" + +#: modules/taxonomy/views_handler_argument_term_node_tid_depth.inc:32 +msgid "If selected, users can enter multiple arguments in the form of 1+2+3. Due to the number of JOINs it would require, AND will be treated as OR with this argument." +msgstr "" + +#: modules/taxonomy/views_handler_argument_vocabulary_vid.inc:15 +msgid "No vocabulary" +msgstr "" + +#: modules/taxonomy/views_handler_field_taxonomy.inc:33 +msgid "Link this field to its taxonomy term page" +msgstr "" + +#: modules/taxonomy/views_handler_field_term_node_tid.inc:34 +msgid "Link this field to its term page" +msgstr "" + +#: modules/taxonomy/views_handler_field_term_node_tid.inc:41 +msgid "Limit terms by vocabulary" +msgstr "" + +#: modules/taxonomy/views_handler_field_term_node_tid.inc:55 modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:23 +msgid "Vocabularies" +msgstr "" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:39 +msgid "Select which vocabulary to show terms for in the regular options." +msgstr "" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:49 +msgid "Selection type" +msgstr "" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:50 +msgid "Dropdown" +msgstr "" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:50 +msgid "Autocomplete" +msgstr "" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:56 +msgid "Show hierarchy in dropdown" +msgstr "" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:73 +msgid "An invalid vocabulary is selected. Please change it in the options." +msgstr "" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:91;147 +msgid "Select terms from vocabulary @voc" +msgstr "" + +#: modules/taxonomy/views_handler_filter_term_node_tid.inc:255 +msgid "Unable to find term: @terms" +msgid_plural "Unable to find terms: @terms" +msgstr[0] "" +msgstr[1] "" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:26 +msgid "If you wish to validate for specific vocabularies, check them; if none are checked, all terms will pass." +msgstr "" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:36 +msgid "Term IDs separated by , or +" +msgstr "" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:37 +msgid "Term name or synonym" +msgstr "" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:38 +msgid "Term name/synonym converted to Term ID" +msgstr "" + +#: modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc:41 +msgid "Select the form of this argument; if using term name, it is generally more efficient to convert it to a term ID and use Taxonomy: Term ID rather than Taxonomy: Term Name\" as an argument." +msgstr "" + +#: modules/translation/views_handler_filter_node_language.inc:10 +msgid "Default site language" +msgstr "" + +#: modules/translation/views_handler_relationship_translation.inc:24 +msgid "Current language" +msgstr "" + +#: modules/translation/views_handler_relationship_translation.inc:25 +msgid "Default language" +msgstr "" + +#: modules/translation/views_handler_relationship_translation.inc:32 +msgid "Translation option" +msgstr "" + +#: modules/translation/views_handler_relationship_translation.inc:33 +msgid "The translation options allows you to select which translation or translations in a translation set join on. Select \"Current language\" or \"Default language\" to join on the translation in the current or default language respectively. Select a specific language to join on a translation in that language. If you select \"All\", each translation will create a new row, which may appear to cause duplicates." +msgstr "" + +#: modules/upload/views_handler_field_upload_fid.inc:27 +msgid "Only show \"listed\" file attachments" +msgstr "" + +#: modules/user/views_handler_field_user.inc:30 +msgid "Link this field to its user" +msgstr "" + +#: modules/user/views_handler_field_user_mail.inc:16 +msgid "Link this field" +msgstr "" + +#: modules/user/views_handler_field_user_mail.inc:19 +msgid "No link" +msgstr "" + +#: modules/user/views_handler_field_user_mail.inc:20 +msgid "To the user" +msgstr "" + +#: modules/user/views_handler_field_user_mail.inc:21 +msgid "With a mailto:" +msgstr "" + +#: modules/user/views_handler_filter_user_current.inc:10 +msgid "Is the logged in user" +msgstr "" + +#: modules/user/views_handler_filter_user_name.inc:28 +msgid "Usernames" +msgstr "" + +#: modules/user/views_handler_filter_user_name.inc:29 +msgid "Enter a comma separated list of user names." +msgstr "" + +#: modules/user/views_handler_filter_user_name.inc:112 +msgid "Unable to find user: @users" +msgid_plural "Unable to find users: @users" +msgstr[0] "" +msgstr[1] "" + +#: modules/user/views_plugin_argument_default_user.inc:17 +msgid "Also look for a node and use the node author" +msgstr "" + +#: plugins/views_plugin_access_none.inc:9 +msgid "Unrestricted" +msgstr "" + +#: plugins/views_plugin_access_perm.inc:37 +msgid "Only users with the selected permission flag will be able to access this display. Note that users with \"access all views\" can see any view, regardless of other permissions." +msgstr "" + +#: plugins/views_plugin_access_role.inc:21 +msgid "No role(s) selected" +msgstr "" + +#: plugins/views_plugin_access_role.inc:24 +msgid "Multiple roles" +msgstr "" + +#: plugins/views_plugin_access_role.inc:43 +msgid "Only the checked roles will be able to access this display. Note that users with \"access all views\" can see any view, regardless of role." +msgstr "" + +#: plugins/views_plugin_access_role.inc:49 +msgid "You must select at least one role if type is \"by role\"" +msgstr "" + +#: plugins/views_plugin_argument_default.inc:32 +msgid "Default argument" +msgstr "" + +#: plugins/views_plugin_argument_default.inc:54 +msgid "Note: you do not have permission to modify this. If you change the default argument type, this setting will be lost and you will NOT be able to get it back." +msgstr "" + +#: plugins/views_plugin_argument_default_php.inc:17 +msgid "PHP argument code" +msgstr "" + +#: plugins/views_plugin_argument_default_php.inc:20 +msgid "Enter PHP code that returns a value to use for this argument. Do not use <?php ?>. You must return only a single value for just this argument." +msgstr "" + +#: plugins/views_plugin_argument_validate.inc:43 +msgid "Note: you do not have permission to modify this. If you change the validator, this setting will be lost and you will NOT be able to get it back." +msgstr "" + +#: plugins/views_plugin_argument_validate_php.inc:19 +msgid "PHP validate code" +msgstr "" + +#: plugins/views_plugin_argument_validate_php.inc:21 +msgid "Enter PHP code that returns TRUE or FALSE. No return is the same as FALSE, so be SURE to return something if you do not want to declare the argument invalid. Do not use <?php ?>. The argument to validate will be \"$argument\" and the view will be \"$view\". You may change the argument by setting \"$handler->argument\"." +msgstr "" + +#: plugins/views_plugin_display.inc:558 +msgid "Broken field" +msgstr "" + +#: plugins/views_plugin_display.inc:575 +msgid "Basic settings" +msgstr "" + +#: plugins/views_plugin_display.inc:582 +msgid "Change the name of this display." +msgstr "" + +#: plugins/views_plugin_display.inc:594 +msgid "Change the title that this display will use." +msgstr "" + +#: plugins/views_plugin_display.inc:604 +msgid "Style" +msgstr "" + +#: plugins/views_plugin_display.inc:606 +msgid "Change the style plugin." +msgstr "" + +#: plugins/views_plugin_display.inc:620 +msgid "Row style" +msgstr "" + +#: plugins/views_plugin_display.inc:622 +msgid "Change the row plugin." +msgstr "" + +#: plugins/views_plugin_display.inc:632 +msgid "Use AJAX" +msgstr "" + +#: plugins/views_plugin_display.inc:634 +msgid "Change whether or not this display will use AJAX." +msgstr "" + +#: plugins/views_plugin_display.inc:641 +msgid "Use pager" +msgstr "" + +#: plugins/views_plugin_display.inc:642 +msgid "Mini" +msgstr "" + +#: plugins/views_plugin_display.inc:643 +msgid "Change this display's pager setting." +msgstr "" + +#: plugins/views_plugin_display.inc:650;822 +msgid "Items per page" +msgstr "" + +#: plugins/views_plugin_display.inc:650;822 plugins/views_plugin_style_summary.inc:43 +msgid "Items to display" +msgstr "" + +#: plugins/views_plugin_display.inc:651 +msgid "Unlimited" +msgstr "" + +#: plugins/views_plugin_display.inc:652 +msgid "Change how many items to display." +msgstr "" + +#: plugins/views_plugin_display.inc:658 +msgid "More link" +msgstr "" + +#: plugins/views_plugin_display.inc:660 +msgid "Specify whether this display will provide a \"more\" link." +msgstr "" + +#: plugins/views_plugin_display.inc:666;849 +msgid "Distinct" +msgstr "" + +#: plugins/views_plugin_display.inc:668;846 +msgid "Display only distinct items, without duplicates." +msgstr "" + +#: plugins/views_plugin_display.inc:681 +msgid "Access" +msgstr "" + +#: plugins/views_plugin_display.inc:683 +msgid "Specify access control type for this display." +msgstr "" + +#: plugins/views_plugin_display.inc:687 +msgid "Change settings for this access type." +msgstr "" + +#: plugins/views_plugin_display.inc:707 +msgid "Link display" +msgstr "" + +#: plugins/views_plugin_display.inc:709 +msgid "Specify which display this display will link to." +msgstr "" + +#: plugins/views_plugin_display.inc:716 +msgid "Exposed form in block" +msgstr "" + +#: plugins/views_plugin_display.inc:718 +msgid "Allow the exposed form to appear in a block instead of the view." +msgstr "" + +#: plugins/views_plugin_display.inc:721;897 +msgid "Header" +msgstr "" + +#: plugins/views_plugin_display.inc:721;913 +msgid "Footer" +msgstr "" + +#: plugins/views_plugin_display.inc:721;929 +msgid "Empty text" +msgstr "" + +#: plugins/views_plugin_display.inc:737 +msgid "Unknown/missing format" +msgstr "" + +#: plugins/views_plugin_display.inc:745 +msgid "Change this display's !name." +msgstr "" + +#: plugins/views_plugin_display.inc:751 +msgid "Theme" +msgstr "" + +#: plugins/views_plugin_display.inc:752 +msgid "Information" +msgstr "" + +#: plugins/views_plugin_display.inc:753 +msgid "Get information on how to theme this display" +msgstr "" + +#: plugins/views_plugin_display.inc:779 +msgid "The name of this display" +msgstr "" + +#: plugins/views_plugin_display.inc:782 +msgid "This title will appear only in the administrative interface for the View." +msgstr "" + +#: plugins/views_plugin_display.inc:787 +msgid "The title of this view" +msgstr "" + +#: plugins/views_plugin_display.inc:790 +msgid "This title will be displayed with the view, wherever titles are normally displayed; i.e, as the page title, block title, etc." +msgstr "" + +#: plugins/views_plugin_display.inc:795 +msgid "Use AJAX when available to load this view" +msgstr "" + +#: plugins/views_plugin_display.inc:799 +msgid "If set, this view will use an AJAX mechanism for paging, table sorting and exposed filters. This means the entire page will not refresh. It is not recommended that you use this if this view is the main content of the page as it will prevent deep linking to specific pages, but it is very useful for side content." +msgstr "" + +#: plugins/views_plugin_display.inc:808 +msgid "Use a pager for this view" +msgstr "" + +#: plugins/views_plugin_display.inc:811 +msgid "Full pager" +msgstr "" + +#: plugins/views_plugin_display.inc:811 +msgid "Mini pager" +msgstr "" + +#: plugins/views_plugin_display.inc:816 +msgid "Pager element" +msgstr "" + +#: plugins/views_plugin_display.inc:817 +msgid "Unless you're experiencing problems with pagers related to this view, you should leave this at 0. If using multiple pagers on one page you may need to set this number to a higher value so as not to conflict within the ?page= array. Large values will add a lot of commas to your URLs, so avoid if possible." +msgstr "" + +#: plugins/views_plugin_display.inc:826 +msgid "The number of items to display per page. Enter 0 for no limit." +msgstr "" + +#: plugins/views_plugin_display.inc:831 +msgid "Offset" +msgstr "" + +#: plugins/views_plugin_display.inc:832 +msgid "The number of items to skip. For example, if this field is 3, the first 3 items will be skipped and not displayed. Offset can not be used if items to display is 0; instead use a very large number there." +msgstr "" + +#: plugins/views_plugin_display.inc:837 +msgid "Add a more link to the bottom of the display." +msgstr "" + +#: plugins/views_plugin_display.inc:840 +msgid "Create more link" +msgstr "" + +#: plugins/views_plugin_display.inc:841 +msgid "This will add a more link to the bottom of this view, which will link to the page view. If you have more than one page view, the link will point to the display specified in 'Link display' above." +msgstr "" + +#: plugins/views_plugin_display.inc:850 +msgid "This will make the view display only distinct items. If there are multiple identical items, each will be displayed only once. You can use this to try and remove duplicates from a view, though it does not always work. Note that this can slow queries down, so use it with caution." +msgstr "" + +#: plugins/views_plugin_display.inc:855 +msgid "Access restrictions" +msgstr "" + +#: plugins/views_plugin_display.inc:874;954 +msgid "You may also adjust the !settings for the currently selected style by clicking on the icon." +msgstr "" + +#: plugins/views_plugin_display.inc:874;954;999 +msgid "settings" +msgstr "" + +#: plugins/views_plugin_display.inc:882 +msgid "Access options" +msgstr "" + +#: plugins/views_plugin_display.inc:900;916 +msgid "Display even if view has no result" +msgstr "" + +#: plugins/views_plugin_display.inc:907 +msgid "Text to display at the top of the view. May contain an explanation or links or whatever you like. Optional." +msgstr "" + +#: plugins/views_plugin_display.inc:923 +msgid "Text to display beneath the view. May contain an explanation or links or whatever you like. Optional." +msgstr "" + +#: plugins/views_plugin_display.inc:934 +msgid "Text to display if the view has no results. Optional." +msgstr "" + +#: plugins/views_plugin_display.inc:940 +msgid "How should this view be styled" +msgstr "" + +#: plugins/views_plugin_display.inc:946 +msgid "If the style you choose has settings, be sure to click the settings button that will appear next to it in the View summary." +msgstr "" + +#: plugins/views_plugin_display.inc:960 +msgid "Style options" +msgstr "" + +#: plugins/views_plugin_display.inc:971 +msgid "Row style options" +msgstr "" + +#: plugins/views_plugin_display.inc:986 +msgid "How should each row in this view be styled" +msgstr "" + +#: plugins/views_plugin_display.inc:999 +msgid "You may also adjust the !settings for the currently selected row style by clicking on the icon." +msgstr "" + +#: plugins/views_plugin_display.inc:1005 +msgid "Which display to use for path" +msgstr "" + +#: plugins/views_plugin_display.inc:1014 +msgid "Which display to use to get this display's path for things like summary links, rss feed links, more links, etc." +msgstr "" + +#: plugins/views_plugin_display.inc:1019 +msgid "Theming information" +msgstr "" + +#: plugins/views_plugin_display.inc:1027 +msgid "Display output" +msgstr "" + +#: plugins/views_plugin_display.inc:1031 +msgid "Alternative display output" +msgstr "" + +#: plugins/views_plugin_display.inc:1038 +msgid "Style output" +msgstr "" + +#: plugins/views_plugin_display.inc:1042 +msgid "Alternative style" +msgstr "" + +#: plugins/views_plugin_display.inc:1049 +msgid "Row style output" +msgstr "" + +#: plugins/views_plugin_display.inc:1053 +msgid "Alternative row style" +msgstr "" + +#: plugins/views_plugin_display.inc:1061 +msgid "Field @field (ID: @id)" +msgstr "" + +#: plugins/views_plugin_display.inc:1069 +msgid "This section lists all possible templates for the display plugin and for the style plugins, ordered roughly from the least specific to the most specific. The active template for each plugin -- which is the most specific template found on the system -- is highlighted in bold." +msgstr "" + +#: plugins/views_plugin_display.inc:1084 +msgid "Rescan template files" +msgstr "" + +#: plugins/views_plugin_display.inc:1090 +msgid "<strong>Important!</strong> When adding, removing, or renaming template files, it is necessary to make Drupal aware of the changes by making it rescan the files on your system. By clicking this button you clear Drupal's theme registry and thereby trigger this rescanning process. The highlighted templates above will then reflect the new state of your system." +msgstr "" + +#: plugins/views_plugin_display.inc:1096 +msgid "Theming information (display)" +msgstr "" + +#: plugins/views_plugin_display.inc:1097;1124;1153;1182 +msgid "Back to !info." +msgstr "" + +#: plugins/views_plugin_display.inc:1097;1124;1153;1182 +msgid "theming information" +msgstr "" + +#: plugins/views_plugin_display.inc:1100 +msgid "This display has no theming information" +msgstr "" + +#: plugins/views_plugin_display.inc:1103 +msgid "This is the default theme template used for this display." +msgstr "" + +#: plugins/views_plugin_display.inc:1109 +msgid "This is an alternative template for this display." +msgstr "" + +#: plugins/views_plugin_display.inc:1123 +msgid "Theming information (style)" +msgstr "" + +#: plugins/views_plugin_display.inc:1129 +msgid "This display has no style theming information" +msgstr "" + +#: plugins/views_plugin_display.inc:1132 +msgid "This is the default theme template used for this style." +msgstr "" + +#: plugins/views_plugin_display.inc:1138 +msgid "This is an alternative template for this style." +msgstr "" + +#: plugins/views_plugin_display.inc:1152;1181 +msgid "Theming information (row style)" +msgstr "" + +#: plugins/views_plugin_display.inc:1158 +msgid "This display has no row style theming information" +msgstr "" + +#: plugins/views_plugin_display.inc:1161;1184 +msgid "This is the default theme template used for this row style." +msgstr "" + +#: plugins/views_plugin_display.inc:1167 +msgid "This is an alternative template for this row style." +msgstr "" + +#: plugins/views_plugin_display.inc:1199 +msgid "Put the exposed form in a block" +msgstr "" + +#: plugins/views_plugin_display.inc:1203 +msgid "If set, any exposed widgets will not appear with this view. Instead, a block will be made available to the Drupal block administration system, and the exposed form will appear there. Note that this block must be enabled manually, Views will not enable it for you." +msgstr "" + +#: plugins/views_plugin_display.inc:1238 +msgid "File found in folder @template-path" +msgstr "" + +#: plugins/views_plugin_display.inc:1242 +msgid "(File not found, in folder @template-path)" +msgstr "" + +#: plugins/views_plugin_display.inc:1399 +msgid "Override" +msgstr "" + +#: plugins/views_plugin_display.inc:1404 +msgid "Status: using default values." +msgstr "" + +#: plugins/views_plugin_display.inc:1408 +msgid "Update default display" +msgstr "" + +#: plugins/views_plugin_display.inc:1413 +msgid "Use default" +msgstr "" + +#: plugins/views_plugin_display.inc:1418 +msgid "Status: using overridden values." +msgstr "" + +#: plugins/views_plugin_display.inc:1633 +msgid "Display \"@display\" uses fields but there are none defined for it or all are excluded." +msgstr "" + +#: plugins/views_plugin_display.inc:1638 +msgid "Display \"@display\" uses a path but the path is undefined." +msgstr "" + +#: plugins/views_plugin_display.inc:1643 +msgid "Display \"@display\" has an invalid style plugin." +msgstr "" + +#: plugins/views_plugin_display.inc:1659 +msgid "Exposed form: @view-@display_id" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:35 +msgid "Before" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:36 +msgid "After" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:37 +msgid "Both" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:57 +msgid "Attachment settings" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:62;109 +msgid "Inherit arguments" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:68;118 +msgid "Inherit exposed filters" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:74;127 +msgid "Position" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:80 plugins/views_plugin_display_feed.inc:98 +msgid "Multiple displays" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:95;136 plugins/views_plugin_display_feed.inc:113;140 +msgid "Attach to" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:112;121 +msgid "Inherit" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:113 +msgid "Should this display inherit its arguments from the parent display to which it is attached?" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:122 +msgid "Should this display inherit its exposed filter values from the parent display to which it is attached?" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:130 +msgid "Attach before or after the parent display?" +msgstr "" + +#: plugins/views_plugin_display_attachment.inc:145 +msgid "Select which display or displays this should attach to." +msgstr "" + +#: plugins/views_plugin_display_block.inc:68 +msgid "Block settings" +msgstr "" + +#: plugins/views_plugin_display_block.inc:82 +msgid "Admin" +msgstr "" + +#: plugins/views_plugin_display_block.inc:106 +msgid "Do not cache" +msgstr "" + +#: plugins/views_plugin_display_block.inc:107 +msgid "Cache once for everything (global)" +msgstr "" + +#: plugins/views_plugin_display_block.inc:108 +msgid "Per page" +msgstr "" + +#: plugins/views_plugin_display_block.inc:109 +msgid "Per role" +msgstr "" + +#: plugins/views_plugin_display_block.inc:110 +msgid "Per role per page" +msgstr "" + +#: plugins/views_plugin_display_block.inc:111 +msgid "Per user" +msgstr "" + +#: plugins/views_plugin_display_block.inc:112 +msgid "Per user per page" +msgstr "" + +#: plugins/views_plugin_display_block.inc:137 +msgid "Block admin description" +msgstr "" + +#: plugins/views_plugin_display_block.inc:140 +msgid "This will appear as the name of this block in administer >> site building >> blocks." +msgstr "" + +#: plugins/views_plugin_display_block.inc:145 +msgid "Block caching type" +msgstr "" + +#: plugins/views_plugin_display_block.inc:149 +msgid "This sets the default status for Drupal's built-in block caching method; this requires that caching be turned on in block administration, and be careful because you have little control over when this cache is flushed." +msgstr "" + +#: plugins/views_plugin_display_feed.inc:86 +msgid "Feed settings" +msgstr "" + +#: plugins/views_plugin_display_feed.inc:90 +msgid "Using the site name" +msgstr "" + +#: plugins/views_plugin_display_feed.inc:132 +msgid "Use the site name for the title" +msgstr "" + +#: plugins/views_plugin_display_feed.inc:149 +msgid "The feed icon will be available only to the selected displays." +msgstr "" + +#: plugins/views_plugin_display_feed.inc:155 +msgid "This view will be displayed by visiting this path on your site. It is recommended that the path be something like \"path/%/%/feed\" or \"path/%/%/rss.xml\", putting one % in the path for each argument you have defined in the view." +msgstr "" + +#: plugins/views_plugin_display_page.inc:188 +msgid "Page settings" +msgstr "" + +#: plugins/views_plugin_display_page.inc:213 +msgid "No menu" +msgstr "" + +#: plugins/views_plugin_display_page.inc:216 +msgid "Normal: @title" +msgstr "" + +#: plugins/views_plugin_display_page.inc:220 +msgid "Tab: @title" +msgstr "" + +#: plugins/views_plugin_display_page.inc:230;302 +msgid "Menu" +msgstr "" + +#: plugins/views_plugin_display_page.inc:236 +msgid "Change settings for the parent menu" +msgstr "" + +#: plugins/views_plugin_display_page.inc:249 +msgid "The menu path or URL of this view" +msgstr "" + +#: plugins/views_plugin_display_page.inc:253 +msgid "This view will be displayed by visiting this path on your site. You may use \"%\" in your URL to represent values that will be used for arguments: For example, \"node/%/feed\"." +msgstr "" + +#: plugins/views_plugin_display_page.inc:259 +msgid "Menu item entry" +msgstr "" + +#: plugins/views_plugin_display_page.inc:276 +msgid "No menu entry" +msgstr "" + +#: plugins/views_plugin_display_page.inc:277 +msgid "Normal menu entry" +msgstr "" + +#: plugins/views_plugin_display_page.inc:278;343 +msgid "Menu tab" +msgstr "" + +#: plugins/views_plugin_display_page.inc:279 +msgid "Default menu tab" +msgstr "" + +#: plugins/views_plugin_display_page.inc:288 +msgid "If set to normal or tab, enter the text to use for the menu item." +msgstr "" + +#: plugins/views_plugin_display_page.inc:295 +msgid "Warning: Changing this item's menu will not work reliably in Drupal 6.4 or earlier. Please upgrade your copy of Drupal at !url." +msgstr "" + +#: plugins/views_plugin_display_page.inc:306 +msgid "Insert item into an available menu." +msgstr "" + +#: plugins/views_plugin_display_page.inc:315 +msgid "The lower the weight the higher/further left it will appear." +msgstr "" + +#: plugins/views_plugin_display_page.inc:321 +msgid "Default tab options" +msgstr "" + +#: plugins/views_plugin_display_page.inc:330 +msgid "When providing a menu item as a 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>." +msgstr "" + +#: plugins/views_plugin_display_page.inc:341 +msgid "Parent menu item" +msgstr "" + +#: plugins/views_plugin_display_page.inc:343 +msgid "Already exists" +msgstr "" + +#: plugins/views_plugin_display_page.inc:343 +msgid "Normal menu item" +msgstr "" + +#: plugins/views_plugin_display_page.inc:351 +msgid "If creating a parent menu item, enter the title of the item." +msgstr "" + +#: plugins/views_plugin_display_page.inc:357 +msgid "Tab weight" +msgstr "" + +#: plugins/views_plugin_display_page.inc:361 +msgid "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." +msgstr "" + +#: plugins/views_plugin_display_page.inc:375 +msgid "\"$arg\" is no longer supported. Use % instead." +msgstr "" + +#: plugins/views_plugin_display_page.inc:379 +msgid "\"%\" may not be used for the first segment of a path." +msgstr "" + +#: plugins/views_plugin_display_page.inc:389 +msgid "Views cannot create normal menu items for paths with a % in them." +msgstr "" + +#: plugins/views_plugin_display_page.inc:396 +msgid "A display whose path ends with a % cannot be a tab." +msgstr "" + +#: plugins/views_plugin_display_page.inc:401 +msgid "Title is required for this menu type." +msgstr "" + +#: plugins/views_plugin_display_page.inc:432 +msgid "Display @display is set to use a menu but the menu title is not set." +msgstr "" + +#: plugins/views_plugin_display_page.inc:438 +msgid "Display @display is set to use a parent menu but the parent menu title is not set." +msgstr "" + +#: plugins/views_plugin_row_fields.inc:40 +msgid "Inline fields" +msgstr "" + +#: plugins/views_plugin_row_fields.inc:43 +msgid "Inline fields will be displayed next to each other rather than one after another." +msgstr "" + +#: plugins/views_plugin_row_fields.inc:51 +msgid "The separator may be placed between inline fields to keep them from squishing up next to each other. You can use HTML in this field." +msgstr "" + +#: plugins/views_plugin_style.inc:91 +msgid "Grouping field" +msgstr "" + +#: plugins/views_plugin_style.inc:94 +msgid "You may optionally specify a field by which to group the records. Leave blank to not group." +msgstr "" + +#: plugins/views_plugin_style.inc:191 +msgid "Style @style requires a row style but the row plugin is invalid." +msgstr "" + +#: plugins/views_plugin_style_grid.inc:33 +msgid "Number of columns" +msgstr "" + +#: plugins/views_plugin_style_grid.inc:38 +msgid "Alignment" +msgstr "" + +#: plugins/views_plugin_style_grid.inc:39 +msgid "Horizontal" +msgstr "" + +#: plugins/views_plugin_style_grid.inc:39 +msgid "Vertical" +msgstr "" + +#: plugins/views_plugin_style_grid.inc:41 +msgid "Horizontal alignment will place items starting in the upper left and moving right. Vertical alignment will place items starting in the upper left and moving down." +msgstr "" + +#: plugins/views_plugin_style_list.inc:32 +msgid "List type" +msgstr "" + +#: plugins/views_plugin_style_rss.inc:56 +msgid "Use the site mission for the description" +msgstr "" + +#: plugins/views_plugin_style_rss.inc:60 +msgid "RSS description" +msgstr "" + +#: plugins/views_plugin_style_rss.inc:62 +msgid "This will appear in the RSS feed itself." +msgstr "" + +#: plugins/views_plugin_style_summary.inc:34 +msgid "Display record count with link" +msgstr "" + +#: plugins/views_plugin_style_summary.inc:39 +msgid "Override number of items to display" +msgstr "" + +#: plugins/views_plugin_style_summary_unformatted.inc:26 +msgid "Display items inline" +msgstr "" + +#: plugins/views_plugin_style_table.inc:126 +msgid "You need at least one field before you can configure your table settings" +msgstr "" + +#: plugins/views_plugin_style_table.inc:135 +msgid "Override normal sorting if click sorting is used" +msgstr "" + +#: plugins/views_plugin_style_table.inc:141 +msgid "Enable Drupal style \"sticky\" table headers (Javascript)" +msgstr "" + +#: plugins/views_plugin_style_table.inc:143 +msgid "(Sticky header effects will not be active for preview below, only on live output.)" +msgstr "" + +#: plugins/views_plugin_style_table.inc:148 +msgid "Default sort order" +msgstr "" + +#: plugins/views_plugin_style_table.inc:151 +msgid "If a default sort order is selected, what order should it use by default." +msgstr "" + +#: plugins/views_plugin_style_table.inc:237 +msgid "Place fields into columns; you may combine multiple fields into the same column. If you do, the separator in the column specified will be used to separate the fields. Check the sortable box to make that column click sortable, and check the default sort radio to determine which column will be sorted by default, if any. You may control column order and field labels in the fields section." +msgstr "" + +#: theme/views-more.tpl.php:15 +msgid "more" +msgstr "" + +#: theme/views-ui-edit-item.tpl.php:32 +msgid "The style selected does not utilize fields." +msgstr "" + +#: theme/views-ui-edit-item.tpl.php:34 +msgid "None defined" +msgstr "" + +#: theme/views-ui-edit-tab.tpl.php:31 +msgid "View settings" +msgstr "" + +#: theme/views-ui-edit-view.tpl.php:11 +msgid "This view 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>." +msgstr "" + +#: theme/views-ui-edit-view.tpl.php:16 +msgid "New view" +msgstr "" + +#: theme/views-ui-edit-view.tpl.php:18 +msgid "Changed view" +msgstr "" + +#: theme/views-ui-edit-view.tpl.php:23 +msgid "View %name, displaying items of type <strong>@base</strong>." +msgstr "" + +#: theme/views-ui-edit-view.tpl.php:42 +msgid "Live preview" +msgstr "" + +#: theme/views-ui-list-views.tpl.php:17 +msgid "<em>@type</em> @base view: <strong>@view</strong>" +msgstr "" + +#: theme/views-ui-list-views.tpl.php:27 +msgid "Title: @title" +msgstr "" + +#: theme/views-ui-list-views.tpl.php:30 +msgid "Path: !path" +msgstr "" + +#: theme/theme.inc:90 +msgid "Edit this view" +msgstr "" + +#: theme/theme.inc:307 +msgid "sort by @s" +msgstr "" + +#: theme/theme.inc:559 +msgid "‹‹" +msgstr "" + +#: theme/theme.inc:560 +msgid "››" +msgstr "" + +#: theme/theme.inc:570 +msgid "@current of @max" +msgstr "" + +#: views_export/views_export.module:76 +msgid "There are no views to be exported at this time." +msgstr "" + +#: views_export/views_export.module:108 +msgid "Show only these tags" +msgstr "" + +#: views_export/views_export.module:122 +msgid "Module name" +msgstr "" + +#: views_export/views_export.module:123 +msgid "Enter the module name to export code to." +msgstr "" + +#: views_export/views_export.module:190 +msgid "Put this in @module.views_default.inc in your modules/@module directory or modules/@module/includes directory" +msgstr "" + +#: views_export/views_export.module:44 +msgid "use views exporter" +msgstr "" + +#: views_export/views_export.module:17 +msgid "Bulk export" +msgstr "" + +#: views_export/views_export.module:0 +msgid "views_export" +msgstr "" + +#: views_export/views_export.info:0 +msgid "Views exporter" +msgstr "" + +#: views_export/views_export.info:0 +msgid "Allows exporting multiple views at once." +msgstr "" + diff --git a/sites/all/modules/views/views.drush.inc b/sites/all/modules/views/views.drush.inc new file mode 100644 index 0000000000000000000000000000000000000000..1cb2db1a0c5df2071401067d4938603ad6b1c765 --- /dev/null +++ b/sites/all/modules/views/views.drush.inc @@ -0,0 +1,14 @@ +<?php +// $Id: views.drush.inc,v 1.1.6.2 2011/01/05 00:09:12 dereine Exp $ + +/** + * @file + * Drush integration of views. + */ + +/** + * Adds a cache clear option for views. + */ +function views_drush_cache_clear(&$types) { + $types['views'] = 'views_invalidate_cache'; +} \ No newline at end of file diff --git a/sites/all/modules/views/views.info b/sites/all/modules/views/views.info new file mode 100644 index 0000000000000000000000000000000000000000..5ff9437224a03d07fd53a8664f8f447887476496 --- /dev/null +++ b/sites/all/modules/views/views.info @@ -0,0 +1,272 @@ +; $Id: views.info,v 1.7.6.60 2011/01/05 21:34:52 dereine Exp $ +name = Views +description = Create customized lists and queries from your database. +package = Views +core = 7.x +php = 5.2 +files[] = views.module +dependencies[] = ctools +; Handlers +files[] = handlers/views_handler_area.inc +files[] = handlers/views_handler_area_text.inc +files[] = handlers/views_handler_argument.inc +files[] = handlers/views_handler_argument_date.inc +files[] = handlers/views_handler_argument_formula.inc +files[] = handlers/views_handler_argument_many_to_one.inc +files[] = handlers/views_handler_argument_null.inc +files[] = handlers/views_handler_argument_numeric.inc +files[] = handlers/views_handler_argument_string.inc +files[] = handlers/views_handler_argument_group_by_numeric.inc +files[] = handlers/views_handler_field.inc +files[] = handlers/views_handler_field_counter.inc +files[] = handlers/views_handler_field_group_by_numeric.inc +files[] = handlers/views_handler_field_boolean.inc +files[] = handlers/views_handler_field_custom.inc +files[] = handlers/views_handler_field_date.inc +files[] = handlers/views_handler_field_markup.inc +files[] = handlers/views_handler_field_math.inc +files[] = handlers/views_handler_field_numeric.inc +files[] = handlers/views_handler_field_prerender_list.inc +files[] = handlers/views_handler_field_url.inc +files[] = handlers/views_handler_filter.inc +files[] = handlers/views_handler_filter_group_by_numeric.inc +files[] = handlers/views_handler_filter_boolean_operator.inc +files[] = handlers/views_handler_filter_boolean_operator_string.inc +files[] = handlers/views_handler_filter_date.inc +files[] = handlers/views_handler_filter_equality.inc +files[] = handlers/views_handler_filter_in_operator.inc +files[] = handlers/views_handler_filter_many_to_one.inc +files[] = handlers/views_handler_filter_numeric.inc +files[] = handlers/views_handler_filter_string.inc +files[] = handlers/views_handler_relationship.inc +files[] = handlers/views_handler_sort.inc +files[] = handlers/views_handler_sort_group_by_numeric.inc +files[] = handlers/views_handler_sort_date.inc +files[] = handlers/views_handler_sort_formula.inc +files[] = handlers/views_handler_sort_menu_hierarchy.inc +files[] = handlers/views_handler_sort_random.inc +; Includes +files[] = includes/base.inc +files[] = includes/handlers.inc +files[] = includes/plugins.inc +files[] = includes/tabs.inc +files[] = includes/view.inc +; Modules +files[] = modules/aggregator/views_handler_argument_aggregator_fid.inc +files[] = modules/aggregator/views_handler_argument_aggregator_iid.inc +files[] = modules/aggregator/views_handler_argument_aggregator_category_cid.inc +files[] = modules/aggregator/views_handler_field_aggregator_title_link.inc +files[] = modules/aggregator/views_handler_field_aggregator_category.inc +files[] = modules/aggregator/views_handler_field_aggregator_item_description.inc +files[] = modules/aggregator/views_handler_field_aggregator_xss.inc +files[] = modules/aggregator/views_handler_filter_aggregator_category_cid.inc +files[] = modules/aggregator/views_plugin_row_aggregator_rss.inc +files[] = modules/comment/views_handler_argument_comment_user_uid.inc +files[] = modules/comment/views_handler_field_comment.inc +files[] = modules/comment/views_handler_field_comment_depth.inc +files[] = modules/comment/views_handler_field_comment_link.inc +files[] = modules/comment/views_handler_field_comment_link_delete.inc +files[] = modules/comment/views_handler_field_comment_link_edit.inc +files[] = modules/comment/views_handler_field_comment_link_reply.inc +files[] = modules/comment/views_handler_field_comment_node_link.inc +files[] = modules/comment/views_handler_field_comment_username.inc +files[] = modules/comment/views_handler_field_ncs_last_comment_name.inc +files[] = modules/comment/views_handler_field_ncs_last_updated.inc +files[] = modules/comment/views_handler_field_node_comment.inc +files[] = modules/comment/views_handler_field_node_new_comments.inc +files[] = modules/comment/views_handler_field_last_comment_timestamp.inc +files[] = modules/comment/views_handler_filter_comment_user_uid.inc +files[] = modules/comment/views_handler_filter_ncs_last_updated.inc +files[] = modules/comment/views_handler_filter_node_comment.inc +files[] = modules/comment/views_handler_sort_comment_thread.inc +files[] = modules/comment/views_handler_sort_ncs_last_comment_name.inc +files[] = modules/comment/views_handler_sort_ncs_last_updated.inc +files[] = modules/comment/views_plugin_row_comment_rss.inc +files[] = modules/comment/views_plugin_row_comment_view.inc +files[] = modules/contact/views_handler_field_contact_link.inc +files[] = modules/field/views_handler_field_field.inc +files[] = modules/field/views_handler_filter_field_list.inc +files[] = modules/filter/views_handler_field_filter_format_name.inc +files[] = modules/locale/views_handler_argument_locale_group.inc +files[] = modules/locale/views_handler_argument_locale_language.inc +files[] = modules/locale/views_handler_field_locale_group.inc +files[] = modules/locale/views_handler_field_locale_language.inc +files[] = modules/locale/views_handler_field_locale_link_edit.inc +files[] = modules/locale/views_handler_filter_locale_group.inc +files[] = modules/locale/views_handler_filter_locale_language.inc +files[] = modules/locale/views_handler_filter_locale_version.inc +files[] = modules/node/views_handler_argument_dates_various.inc +files[] = modules/node/views_handler_argument_node_language.inc +files[] = modules/node/views_handler_argument_node_nid.inc +files[] = modules/node/views_handler_argument_node_type.inc +files[] = modules/node/views_handler_argument_node_vid.inc +files[] = modules/node/views_handler_field_history_user_timestamp.inc +files[] = modules/node/views_handler_field_node.inc +files[] = modules/node/views_handler_field_node_link.inc +files[] = modules/node/views_handler_field_node_link_delete.inc +files[] = modules/node/views_handler_field_node_link_edit.inc +files[] = modules/node/views_handler_field_node_revision.inc +files[] = modules/node/views_handler_field_node_revision_link_delete.inc +files[] = modules/node/views_handler_field_node_revision_link_revert.inc +files[] = modules/node/views_handler_field_node_path.inc +files[] = modules/node/views_handler_field_node_type.inc +files[] = modules/node/views_handler_filter_history_user_timestamp.inc +files[] = modules/node/views_handler_filter_node_access.inc +files[] = modules/node/views_handler_filter_node_status.inc +files[] = modules/node/views_handler_filter_node_type.inc +files[] = modules/node/views_plugin_argument_default_node.inc +files[] = modules/node/views_plugin_argument_validate_node.inc +files[] = modules/node/views_plugin_row_node_rss.inc +files[] = modules/node/views_plugin_row_node_view.inc +files[] = modules/profile/views_handler_field_profile_date.inc +files[] = modules/profile/views_handler_field_profile_list.inc +files[] = modules/profile/views_handler_filter_profile_selection.inc +files[] = modules/search/views_handler_argument_search.inc +files[] = modules/search/views_handler_field_search_score.inc +files[] = modules/search/views_handler_filter_search.inc +files[] = modules/search/views_handler_sort_search_score.inc +files[] = modules/search/views_plugin_row_search_view.inc +files[] = modules/statistics/views_handler_field_accesslog_path.inc +files[] = modules/system/views_handler_argument_file_fid.inc +files[] = modules/system/views_handler_field_file.inc +files[] = modules/system/views_handler_field_file_extension.inc +files[] = modules/system/views_handler_field_file_filemime.inc +files[] = modules/system/views_handler_field_file_uri.inc +files[] = modules/system/views_handler_field_file_status.inc +files[] = modules/system/views_handler_filter_file_status.inc +files[] = modules/taxonomy/views_handler_argument_taxonomy.inc +files[] = modules/taxonomy/views_handler_argument_term_node_tid.inc +files[] = modules/taxonomy/views_handler_argument_term_node_tid_depth.inc +files[] = modules/taxonomy/views_handler_argument_term_node_tid_depth_modifier.inc +files[] = modules/taxonomy/views_handler_argument_vocabulary_vid.inc +files[] = modules/taxonomy/views_handler_field_taxonomy.inc +files[] = modules/taxonomy/views_handler_field_term_node_tid.inc +files[] = modules/taxonomy/views_handler_field_term_link_edit.inc +files[] = modules/taxonomy/views_handler_filter_term_node_tid.inc +files[] = modules/taxonomy/views_handler_filter_term_node_tid_depth.inc +files[] = modules/taxonomy/views_handler_filter_vocabulary_vid.inc +files[] = modules/taxonomy/views_handler_filter_vocabulary_machine_name.inc +files[] = modules/taxonomy/views_handler_relationship_node_term_data.inc +files[] = modules/taxonomy/views_plugin_argument_validate_taxonomy_term.inc +files[] = modules/taxonomy/views_plugin_argument_default_taxonomy_tid.inc +;files[] = modules/translation/views_handler_argument_node_language.inc +files[] = modules/translation/views_handler_argument_node_tnid.inc +files[] = modules/translation/views_handler_field_node_language.inc +files[] = modules/translation/views_handler_field_node_link_translate.inc +files[] = modules/translation/views_handler_field_node_translation_link.inc +files[] = modules/translation/views_handler_filter_node_language.inc +files[] = modules/translation/views_handler_filter_node_tnid.inc +files[] = modules/translation/views_handler_filter_node_tnid_child.inc +files[] = modules/translation/views_handler_relationship_translation.inc +files[] = modules/upload/views_handler_field_upload_description.inc +files[] = modules/upload/views_handler_field_upload_fid.inc +files[] = modules/upload/views_handler_filter_upload_fid.inc +files[] = modules/user/views_handler_argument_user_uid.inc +files[] = modules/user/views_handler_argument_users_roles_rid.inc +files[] = modules/user/views_handler_field_user.inc +files[] = modules/user/views_handler_field_user_language.inc +files[] = modules/user/views_handler_field_user_link.inc +files[] = modules/user/views_handler_field_user_link_delete.inc +files[] = modules/user/views_handler_field_user_link_edit.inc +files[] = modules/user/views_handler_field_user_mail.inc +files[] = modules/user/views_handler_field_user_name.inc +files[] = modules/user/views_handler_field_user_picture.inc +files[] = modules/user/views_handler_field_user_roles.inc +files[] = modules/user/views_handler_filter_user_current.inc +files[] = modules/user/views_handler_filter_user_name.inc +files[] = modules/user/views_handler_filter_user_roles.inc +files[] = modules/user/views_plugin_argument_default_current_user.inc +files[] = modules/user/views_plugin_argument_default_user.inc +files[] = modules/user/views_plugin_argument_validate_user.inc +; Plugins +files[] = plugins/views_plugin_access.inc +files[] = plugins/views_plugin_access_none.inc +files[] = plugins/views_plugin_access_perm.inc +files[] = plugins/views_plugin_access_role.inc +files[] = plugins/views_plugin_argument_default.inc +files[] = plugins/views_plugin_argument_default_php.inc +files[] = plugins/views_plugin_argument_default_fixed.inc +files[] = plugins/views_plugin_argument_validate.inc +files[] = plugins/views_plugin_argument_validate_numeric.inc +files[] = plugins/views_plugin_argument_validate_php.inc +files[] = plugins/views_plugin_cache.inc +files[] = plugins/views_plugin_cache_none.inc +files[] = plugins/views_plugin_cache_time.inc +files[] = plugins/views_plugin_display.inc +files[] = plugins/views_plugin_display_attachment.inc +files[] = plugins/views_plugin_display_block.inc +files[] = plugins/views_plugin_display_default.inc +files[] = plugins/views_plugin_display_feed.inc +files[] = plugins/views_plugin_exposed_form_basic.inc +files[] = plugins/views_plugin_exposed_form.inc +files[] = plugins/views_plugin_exposed_form_input_required.inc +files[] = plugins/views_plugin_display_page.inc +files[] = plugins/views_plugin_localization_core.inc +files[] = plugins/views_plugin_localization.inc +files[] = plugins/views_plugin_localization_none.inc +files[] = plugins/views_plugin_pager.inc +files[] = plugins/views_plugin_pager_full.inc +files[] = plugins/views_plugin_pager_mini.inc +files[] = plugins/views_plugin_pager_none.inc +files[] = plugins/views_plugin_pager_some.inc +files[] = plugins/views_plugin_query.inc +files[] = plugins/views_plugin_query_default.inc +files[] = plugins/views_plugin_row.inc +files[] = plugins/views_plugin_row_fields.inc +files[] = plugins/views_plugin_style.inc +files[] = plugins/views_plugin_style_default.inc +files[] = plugins/views_plugin_style_grid.inc +files[] = plugins/views_plugin_style_list.inc +files[] = plugins/views_plugin_style_jump_menu.inc +files[] = plugins/views_plugin_style_rss.inc +files[] = plugins/views_plugin_style_summary.inc +files[] = plugins/views_plugin_style_summary_jump_menu.inc +files[] = plugins/views_plugin_style_summary_unformatted.inc +files[] = plugins/views_plugin_style_table.inc + +; Tests +files[] = tests/handlers/views_handler_area_text.test +files[] = tests/handlers/views_handler_argument_null.test +files[] = tests/handlers/views_handler_field_boolean.test +files[] = tests/handlers/views_handler_field_custom.test +files[] = tests/handlers/views_handler_field_counter.test +files[] = tests/handlers/views_handler_field_date.test +files[] = tests/handlers/views_handler_field_file_size.test +files[] = tests/handlers/views_handler_field_math.test +files[] = tests/handlers/views_handler_field_url.test +files[] = tests/handlers/views_handler_field_xss.test +files[] = tests/handlers/views_handler_filter_date.test +files[] = tests/handlers/views_handler_filter_equality.test +files[] = tests/handlers/views_handler_filter_in_operator.test +files[] = tests/handlers/views_handler_filter_numeric.test +files[] = tests/handlers/views_handler_filter_string.test +files[] = tests/handlers/views_handler_sort_random.test +files[] = tests/handlers/views_handler_sort_date.test +files[] = tests/handlers/views_handler_sort.test +files[] = tests/test_plugins/views_test_plugin_access_test_dynamic.inc +files[] = tests/test_plugins/views_test_plugin_access_test_static.inc +files[] = tests/views_access.test +files[] = tests/views_analyze.test +files[] = tests/views_basic.test +files[] = tests/views_argument_default.test +files[] = tests/views_argument_validator.test +files[] = tests/views_exposed_form.test +files[] = tests/views_glossary.test +files[] = tests/views_groupby.test +files[] = tests/views_handlers.test +files[] = tests/views_module.test +files[] = tests/views_pager.test +files[] = tests/views_plugin_localization_test.inc +files[] = tests/views_translatable.test +files[] = tests/views_query.test +files[] = tests/views_test.views_default.inc +files[] = tests/user/views_user_argument_default.test +files[] = tests/user/views_user_argument_validate.test +files[] = tests/views_cache.test + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-3.0-alpha1" +core = "7.x" +project = "views" +datestamp = "1294276880" + diff --git a/sites/all/modules/views/views.install b/sites/all/modules/views/views.install new file mode 100644 index 0000000000000000000000000000000000000000..aad5092e861b2d8de71d0ec1cbeea5f9fcde9b00 --- /dev/null +++ b/sites/all/modules/views/views.install @@ -0,0 +1,562 @@ +<?php +// $Id: views.install,v 1.50.4.12 2011/01/01 23:51:28 dereine Exp $ +/** + * @file views.install + * Contains install and update functions for Views. + */ + +/** + * Implements hook_install(). + */ +function views_install() { + if (db_driver() == 'pgsql') { + db_query('CREATE OR REPLACE FUNCTION first(anyelement, anyelement) RETURNS anyelement AS \'SELECT COALESCE($1, $2);\' LANGUAGE \'sql\';'); + db_query("DROP AGGREGATE IF EXISTS first(anyelement)"); + db_query("CREATE AGGREGATE first(sfunc = first, basetype = anyelement, stype = anyelement);"); + } + db_query("UPDATE {system} SET weight = 10 WHERE name = 'views'"); +} + +/** + * Implements hook_schema(). + * + * Generate the current version of the database schema from + * the sequence of schema update functions. Uses a similar + * method to install.inc's drupal_get_schema_versions() to + * establish the update sequence. + * + * To change the schema, add a new views_schema_N() + * function to match the associated views_update_N() + * + * @param $caller_function + * The name of the function that called us. + * Used internally, if requesting a specific schema version. + */ +function views_schema($caller_function = FALSE) { + static $get_current; + static $schemas = array(); + + // If called with no arguments, get the latest version of the schema. + if (!isset($get_current)) { + $get_current = $caller_function ? FALSE : TRUE; + } + + // Generate a sorted list of available schema update functions. + if ($get_current || empty($schemas)) { + $get_current = FALSE; + $functions = get_defined_functions(); + foreach ($functions['user'] as $function) { + if (strpos($function, 'views_schema_') === 0) { + $version = substr($function, strlen('views_schema_')); + if (is_numeric($version)) { + $schemas[] = $version; + } + } + } + if ($schemas) { + sort($schemas, SORT_NUMERIC); + + // If a specific version was requested, drop any later + // updates from the sequence. + if ($caller_function) { + do { + $schema = array_pop($schemas); + } while ($schemas && $caller_function != 'views_schema_'. $schema); + } + } + } + + // Call views_schema_<n>, for the highest available <n>. + if ($schema = array_pop($schemas)) { + $function = 'views_schema_'. $schema; + return $function(); + } + + return array(); +} + +/** + * Views 2's initial schema. + * Called directly by views_update_6000() for updates from Drupal 5. + * + * Important: Do not edit this schema! + * + * Updates to the views schema must be provided as views_schema_6xxx() functions, + * which views_schema() automatically sees and applies. See below for examples. + * + * Please do document updates with comments in this function, however. + */ +function views_schema_6000() { + $schema['views_view'] = array( + 'description' => 'Stores the general data for a view.', + 'fields' => array( + 'vid' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The view ID of the field, defined by the database.', + 'no export' => TRUE, + ), + 'name' => array( + 'type' => 'varchar', + 'length' => '32', + 'default' => '', + 'not null' => TRUE, + 'description' => 'The unique name of the view. This is the primary field views are loaded from, and is used so that views may be internal and not necessarily in the database. May only be alphanumeric characters plus underscores.', + ), + 'description' => array( + 'type' => 'varchar', + 'length' => '255', + 'default' => '', + 'description' => 'A description of the view for the admin interface.', + ), + 'tag' => array( + 'type' => 'varchar', + 'length' => '255', + 'default' => '', + 'description' => 'A tag used to group/sort views in the admin interface', + ), + 'view_php' => array( + 'type' => 'blob', + 'description' => 'A chunk of PHP code that can be used to provide modifications to the view prior to building.', + ), + 'base_table' => array( + 'type' => 'varchar', + 'length' => '32', // Updated to '64' in views_schema_6005() + 'default' => '', + 'not null' => TRUE, + 'description' => 'What table this view is based on, such as node, user, comment, or term.', + ), + 'is_cacheable' => array( + 'type' => 'int', + 'default' => 0, + 'size' => 'tiny', + 'description' => 'A boolean to indicate whether or not this view may have its query cached.', + ), + ), + 'primary key' => array('vid'), + 'unique key' => array('name' => array('name')), // Updated to 'unique keys' in views_schema_6003() + ); + + $schema['views_display'] = array( + 'description' => 'Stores information about each display attached to a view.', + 'fields' => array( + 'vid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The view this display is attached to.', + 'no export' => TRUE, + ), + 'id' => array( + 'type' => 'varchar', + 'length' => '64', + 'default' => '', + 'not null' => TRUE, + 'description' => 'An identifier for this display; usually generated from the display_plugin, so should be something like page or page_1 or block_2, etc.', + ), + 'display_title' => array( + 'type' => 'varchar', + 'length' => '64', + 'default' => '', + 'not null' => TRUE, + 'description' => 'The title of the display, viewable by the administrator.', + ), + 'display_plugin' => array( + 'type' => 'varchar', + 'length' => '64', + 'default' => '', + 'not null' => TRUE, + 'description' => 'The type of the display. Usually page, block or embed, but is pluggable so may be other things.', + ), + 'position' => array( + 'type' => 'int', + 'default' => 0, + 'description' => 'The order in which this display is loaded.', + ), + 'display_options' => array( + // Type corrected in update 6009 + 'type' => 'blob', + 'description' => 'A serialized array of options for this display; it contains options that are generally only pertinent to that display plugin type.', + 'serialize' => TRUE, + 'serialized default' => 'a:0:{}', + ), + ), + // Added primary keys in views_schema_6008() + 'indexes' => array('vid' => array('vid', 'position')), + ); + + $schema['cache_views'] = drupal_get_schema_unprocessed('system', 'cache'); + + $schema['views_object_cache'] = array( + 'description' => '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', + 'description' => 'The session ID this cache object belongs to.', + ), + 'name' => array( + 'type' => 'varchar', + 'length' => '32', + 'description' => 'The name of the view this cache is attached to.', + ), + 'obj' => array( + 'type' => 'varchar', + 'length' => '32', + 'description' => 'The name 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' => 'blob', // Updated to 'text' (with size => 'big') in views_schema_6004() + 'description' => 'Serialized data being stored.', + 'serialize' => TRUE, + ), + ), + 'indexes' => array( + 'sid_obj_name' => array('sid', 'obj', 'name'), + 'updated' => array('updated'), + ), + ); + + // $schema['cache_views_data'] added in views_schema_6006() + + return $schema; +} + +/** + * Update a site to Drupal 6! Contains a bit of special code to detect + * if you've been running a beta version or something. + */ +function views_update_6000() { + $ret = array(); + if (db_table_exists('views_view')) { + return $ret; + } + + // This has the beneficial effect of wiping out any Views 1 cache at the + // same time; not wiping that cache could easily cause problems with Views 2. + if (db_table_exists('cache_views')) { + db_drop_table($ret, 'cache_views'); + } + + // This is mostly the same as drupal_install_schema, but it forces + // views_schema_6000() rather than the default views_schema(). + // This is important for processing subsequent table updates. + $schema = views_schema_6000(); + _drupal_initialize_schema('views', $schema); + + foreach ($schema as $name => $table) { + db_create_table($ret, $name, $table); + } + return $ret; +} + +/** + * Remove '$' symbol in special blocks, as it is invalid for theming. + */ +function views_update_6001() { + $ret = array(); + $result = db_query("SELECT * FROM {blocks} WHERE module = 'views' AND delta LIKE '\$exp%'"); + foreach ($result as $block) { + $new = strtr($block->delta, '$', '-'); + $ret[] = update_sql("UPDATE {blocks} SET delta = '" . db_escape_string($new) . "' WHERE module = 'views' AND delta = '" . db_escape_string($block->delta) . "'"); + } + $ret[] = update_sql("UPDATE {blocks} SET delta = CONCAT(delta, '-block_1') WHERE module = 'views'"); + + return $ret; +} + +// NOTE: Update 6002 removed because it did not always work. +// Update 6004 implements the change correctly. + +/** + * Add missing unique key. + */ +function views_schema_6003() { + $schema = views_schema(__FUNCTION__); + $schema['views_view']['unique keys'] = array('name' => array('name')); + unset($schema['views_view']['unique key']); + return $schema; +} +function views_update_6003() { + $ret = array(); + db_add_unique_key($ret, 'views_view', 'name', array('name')); + return $ret; +} + +/** + * Enlarge the views_object_cache.data column to prevent truncation and JS + * errors. + */ +function views_schema_6004() { + $schema = views_schema(__FUNCTION__); + $schema['views_object_cache']['fields']['data']['type'] = 'text'; + $schema['views_object_cache']['fields']['data']['size'] = 'big'; + return $schema; +} +function views_update_6004() { + $ret = array(); + + $new_field = array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'Serialized data being stored.', + 'serialize' => TRUE, + ); + + // Drop and re-add this field because there is a bug in + // db_change_field that causes this to fail when trying to cast the data. + db_drop_field($ret, 'views_object_cache', 'data'); + db_add_field($ret, 'views_object_cache', 'data', $new_field); + + return $ret; +} + +/** + * Enlarge the base_table column + */ +function views_schema_6005() { + $schema = views_schema(__FUNCTION__); + $schema['views_view']['fields']['base_table']['length'] = 64; + return $schema; +} +function views_update_6005() { + $ret = array(); + + $new_field = array( + 'type' => 'varchar', + 'length' => '64', + 'default' => '', + 'not null' => TRUE, + 'description' => 'What table this view is based on, such as node, user, comment, or term.', + ); + db_change_field($ret, 'views_view', 'base_table', 'base_table', $new_field); + return $ret; +} + +/** + * Add the cache_views_data table to support standard caching. + */ +function views_schema_6006() { + $schema = views_schema(__FUNCTION__); + $schema['cache_views_data'] = drupal_get_schema_unprocessed('system', 'cache'); + $schema['cache_views_data']['description'] = 'Cache table for views to store pre-rendered queries, results, and display output.'; + $schema['cache_views_data']['fields']['serialized']['default'] = 1; + return $schema; +} +function views_update_6006() { + $ret = array(); + + $table = drupal_get_schema_unprocessed('system', 'cache'); + $table['description'] = 'Cache table for views to store pre-rendered queries, results, and display output.'; + $table['fields']['serialized']['default'] = 1; + + db_create_table($ret, 'cache_views_data', $table); + + return $ret; +} + +/** + * Add aggregate function to PostgreSQL so GROUP BY can be used to force only + * one result to be returned for each item. + */ +function views_update_6007() { + $ret = array(); + if (db_driver() == 'pgsql') { + $ret[] = update_sql('CREATE OR REPLACE FUNCTION first(anyelement, anyelement) RETURNS anyelement AS \'SELECT COALESCE($1, $2);\' LANGUAGE \'sql\';'); + $ret[] = update_sql("DROP AGGREGATE IF EXISTS first(anyelement)"); + $ret[] = update_sql("CREATE AGGREGATE first(sfunc = first, basetype = anyelement, stype = anyelement);"); + } + return $ret; +} + +/** + * Add the primary key to views_display table. + */ +function views_schema_6008() { + $schema = views_schema(__FUNCTION__); + $schema['views_display']['primary key'] = array('vid', 'id'); + return $schema; +} + +/** + * Add the primary key to the views_display table. + */ +function views_update_6008() { + $ret = array(); + + db_add_primary_key($ret, 'views_display', array('vid', 'id')); + + return $ret; +} + +/** + * Enlarge the views_display.display_options field to accomodate a larger set + * of configurations (e. g. fields, filters, etc.) on a display. + */ +function views_schema_6009() { + $schema = views_schema(__FUNCTION__); + $schema['views_display']['fields']['display_options'] = array( + 'type' => 'text', + 'size' => 'big', + 'description' => 'A serialized array of options for this display; it contains options that are generally only pertinent to that display plugin type.', + 'serialize' => TRUE, + 'serialized default' => 'a:0:{}', + ); + return $schema; +} + +function views_update_6009() { + $ret = array(); + + $schema = views_schema_6009(); + + if ($GLOBALS['db_type'] == 'pgsql') { + $ret[] = update_sql('ALTER TABLE {views_display} RENAME "display_options" TO "display_options_old"'); + db_add_field($ret, 'views_display', 'display_options', $schema['views_display']['fields']['display_options']); + + $sql = "SELECT vid, id, display_options_old FROM {views_display}"; + $result = db_query($sql); + while ($row = db_fetch_array($result)) { + $row['display_options_old'] = db_decode_blob($row['display_options_old']); + $sql = "UPDATE {views_display} SET display_options = '%s' WHERE vid = %d AND id = '%s'"; + db_query($sql, $row['display_options_old'], $row['vid'], $row['id']); + } + + db_drop_field($ret, 'views_display', 'display_options_old'); + } + else { + db_change_field($ret, 'views_display', 'display_options', 'display_options', $schema['views_display']['fields']['display_options']); + } + + return $ret; +} + +/** + * Remove the view_php field + */ +function views_schema_6010() { + $schema = views_schema(__FUNCTION__); + unset($schema['views_view']['fields']['view_php']); + unset($schema['views_view']['fields']['is_cacheable']); + return $schema; +} + +/** + * Remove the view_php and is_cacheable field + */ +function views_update_6010() { + $ret = array(); + + db_drop_field($ret, 'views_view', 'view_php'); + db_drop_field($ret, 'views_view', 'is_cacheable'); + + + return $ret; +} + +/** + * Remove views_object_cache table and move the data to ctools_object_cache. + */ +function views_schema_6011() { + $schema = views_schema(__FUNCTION__); + unset($schema['views_object_cache']); + return $schema; +} + +/** + * Remove views_object_cache table and move the data to ctools_object_cache. + */ +function views_update_6011() { + $ret = array(); + + $caches = db_query("SELECT * FROM {views_object_cache}")->fetch(); + foreach ($caches as $item) { + drupal_write_record('ctools_object_cache', $item); + } + db_drop_table($ret, 'views_object_cache'); + + return $ret; +} + +/** + * Correct the cache setting for exposed filter blocks. + * + * @see http://drupal.org/node/910864 + */ +function views_update_6012() { + $ret = array(); + + // There is only one simple query to run. + $update = db_update('blocks') + ->condition('module', 'views') + ->condition('delta', db_like('-exp-') . '%', 'LIKE') + ->fields(array('cache' => DRUPAL_NO_CACHE)); + + return $ret; +} + + +/** + * Add a human readable name. + */ +function views_schema_6013() { + $schema = views_schema(__FUNCTION__); + $schema['views_view']['fields']['human_name'] = array( + 'type' => 'varchar', + 'length' => '255', + 'default' => '', + 'description' => 'A human readable name used to be displayed in the admin interface', + ); + return $schema; +} + +function views_update_6013() { + $ret = array(); + + $new_field = array( + 'type' => 'varchar', + 'length' => '255', + 'default' => '', + 'description' => 'A human readable name used to be displayed in the admin interface', + ); + + db_add_field('views_view', 'human_name', $new_field); + + return $ret; +} + +function views_schema_6014() { + $schema = views_schema(__FUNCTION__); + $schema['views_view']['fields']['core'] = array( + 'type' => 'int', + 'default' => 0, + 'description' => 'Stores the drupal core version of the view.', + ); + return $schema; +} + +/** + * Add a drupal core version field. + */ +function views_update_6014() { + $ret = array(); + $new_field = array( + 'type' => 'int', + 'default' => 0, + 'description' => 'Stores the drupal core version of the view.', + ); + + db_add_field('views_view', 'core', $new_field); + + return $ret; +} + diff --git a/sites/all/modules/views/views.module b/sites/all/modules/views/views.module new file mode 100644 index 0000000000000000000000000000000000000000..c943a3f7197e8d21fa262dc45a2ceecadfbc6682 --- /dev/null +++ b/sites/all/modules/views/views.module @@ -0,0 +1,1570 @@ +<?php +// $Id: views.module,v 1.341.4.53 2011/01/06 00:37:05 dereine Exp $ +/** + * @file + * Primarily Drupal hooks and global API functions to manipulate views. + * + * This is the main module file for Views. The main entry points into + * this module are views_page() and views_block(), where it handles + * incoming page and block requests. + */ + +/** + * Advertise the current views api version + */ +function views_api_version() { + return '3.0-alpha1'; +} + +/** + * Views will not load plugins advertising a version older than this. + */ +function views_api_minimum_version() { + return '2'; +} + +/** + * Implement hook_init(). + */ +function views_init() { + drupal_add_css(drupal_get_path('module', 'views') .'/css/views.css'); +} + +/** + * Implement hook_theme(). Register views theming functions. + */ +function views_theme($existing, $type, $theme, $path) { + $path = drupal_get_path('module', 'views'); + include_once $path . '/theme/theme.inc'; + + // Some quasi clever array merging here. + $base = array( + 'file' => 'theme.inc', + 'path' => $path . '/theme', + ); + + // Our extra version of pager from pager.inc + $hooks['views_mini_pager'] = $base + array( + 'variables' => array('tags' => array(), 'quantity' => 10, 'element' => 0, 'parameters' => array()), + 'pattern' => 'views_mini_pager__', + ); + + $arguments = array( + 'display' => array('view' => NULL), + 'style' => array('view' => NULL, 'options' => NULL, 'rows' => NULL, 'title' => NULL), + 'row' => array('view' => NULL, 'options' => NULL, 'row' => NULL, 'field_alias' => NULL), + ); + + // Default view themes + $hooks['views_view_field'] = $base + array( + 'pattern' => 'views_view_field__', + 'variables' => array('view' => NULL, 'field' => NULL, 'row' => NULL), + ); + + $plugins = views_fetch_plugin_data(); + + // Register theme functions for all style plugins + foreach ($plugins as $type => $info) { + foreach ($info as $plugin => $def) { + if (isset($def['theme'])) { + $hooks[$def['theme']] = array( + 'pattern' => $def['theme'] . '__', + 'file' => $def['theme file'], + 'path' => $def['theme path'], + 'variables' => $arguments[$type], + ); + + $include = DRUPAL_ROOT . '/' . $def['theme path'] . '/' . $def['theme file']; + if (file_exists($include)) { + require_once $include; + } + + if (!function_exists('theme_' . $def['theme'])) { + $hooks[$def['theme']]['template'] = drupal_clean_css_identifier($def['theme']); + } + } + if (isset($def['additional themes'])) { + foreach ($def['additional themes'] as $theme => $theme_type) { + if (empty($theme_type)) { + $theme = $theme_type; + $theme_type = $type; + } + + $hooks[$theme] = array( + 'pattern' => $theme . '__', + 'file' => $def['theme file'], + 'path' => $def['theme path'], + 'variables' => $arguments[$theme_type], + ); + + if (!function_exists('theme_' . $theme)) { + $hooks[$theme]['template'] = drupal_clean_css_identifier($theme); + } + } + } + } + } + + $hooks['views_exposed_form'] = $base + array( + 'template' => 'views-exposed-form', + 'pattern' => 'views_exposed_form__', + 'render element' => 'form', + ); + + $hooks['views_more'] = $base + array( + 'template' => 'views-more', + 'pattern' => 'views_more__', + 'variables' => array('more_url' => NULL, 'link_text' => 'more'), + ); + + // Add theme suggestions which are part of modules. + foreach (views_get_module_apis() as $info) { + if (isset($info['template path'])) { + $hooks += _views_find_module_templates($hooks, $info['template path']); + } + } + return $hooks; +} + +/** + * Scans a directory of a module for template files. + * + * @param $cache + * The existing cache of theme hooks to test against. + * @param $path + * The path to search. + * + * @see drupal_find_theme_templates + */ +function _views_find_module_templates($cache, $path) { + $regex = '/' . '\.tpl\.php' . '$' . '/'; + + // Because drupal_system_listing works the way it does, we check for real + // templates separately from checking for patterns. + $files = drupal_system_listing($regex, $path, 'name', 0); + foreach ($files as $template => $file) { + // Chop off the remaining extensions if there are any. $template already + // has the rightmost extension removed, but there might still be more, + // such as with .tpl.php, which still has .tpl in $template at this point. + if (($pos = strpos($template, '.')) !== FALSE) { + $template = substr($template, 0, $pos); + } + // Transform - in filenames to _ to match function naming scheme + // for the purposes of searching. + $hook = strtr($template, '-', '_'); + if (isset($cache[$hook])) { + $templates[$hook] = array( + 'template' => $template, + 'path' => dirname($file->filename), + 'includes' => isset($cache[$hook]['includes']) ? $cache[$hook]['includes'] : NULL, + ); + } + // Ensure that the pattern is maintained from base themes to its sub-themes. + // Each sub-theme will have their templates scanned so the pattern must be + // held for subsequent runs. + if (isset($cache[$hook]['pattern'])) { + $templates[$hook]['pattern'] = $cache[$hook]['pattern']; + } + } + + $patterns = array_keys($files); + + foreach ($cache as $hook => $info) { + if (!empty($info['pattern'])) { + // Transform _ in pattern to - to match file naming scheme + // for the purposes of searching. + $pattern = strtr($info['pattern'], '_', '-'); + + $matches = preg_grep('/^'. $pattern .'/', $patterns); + if ($matches) { + foreach ($matches as $match) { + $file = substr($match, 0, strpos($match, '.')); + // Put the underscores back in for the hook name and register this pattern. + $templates[strtr($file, '-', '_')] = array( + 'template' => $file, + 'path' => dirname($files[$match]->filename), + 'variables' => $info['variables'], + 'base hook' => $hook, + 'includes' => isset($info['includes']) ? $info['includes'] : NULL, + ); + } + } + } + } + + return $templates; +} + +/** + * A theme preprocess function to automatically allow view-based node + * templates if called from a view. + * + * The 'modules/node.views.inc' file is a better place for this, but + * we haven't got a chance to load that file before Drupal builds the + * node portion of the theme registry. + */ +function views_preprocess_node(&$vars) { + // The 'view' attribute of the node is added in template_preprocess_views_view_row_node() + if (!empty($vars['node']->view) && !empty($vars['node']->view->name)) { + $vars['view'] = &$vars['node']->view; + $vars['theme_hook_suggestions'][] = 'node__view__' . $vars['node']->view->name; + if (!empty($vars['node']->view->current_display)) { + $vars['theme_hook_suggestions'][] = 'node__view__' . $vars['node']->view->name . '__' . $vars['node']->view->current_display; + } + } +} + +/** + * A theme preprocess function to automatically allow view-based node + * templates if called from a view. + */ +function views_preprocess_comment(&$vars) { + // The 'view' attribute of the node is added in template_preprocess_views_view_row_comment() + if (!empty($vars['node']->view) && !empty($vars['node']->view->name)) { + $vars['view'] = &$vars['node']->view; + $vars['theme_hook_suggestions'][] = 'comment__view__' . $vars['node']->view->name; + if (!empty($vars['node']->view->current_display)) { + $vars['theme_hook_suggestions'][] = 'comment__view__' . $vars['node']->view->name . '__' . $vars['node']->view->current_display; + } + } +} + +/* + * Implement hook_permission(). + */ +function views_permission() { + return array( + 'administer views' => array( + 'title' => t('Administer views'), + 'description' => t('Access the views administration pages.'), + ), + 'access all views' => array( + 'title' => t('Access all views'), + 'description' => t('Bypass access control when accessing views.'), + ), + ); +} + +/** + * Implement hook_menu(). + */ +function views_menu() { + // Any event which causes a menu_rebuild could potentially mean that the + // Views data is updated -- module changes, profile changes, etc. + views_invalidate_cache(); + $items = array(); + $items['views/ajax'] = array( + 'title' => 'Views', + 'page callback' => 'views_ajax', + 'delivery callback' => 'ajax_deliver', + 'access callback' => TRUE, + 'description' => 'Ajax callback for view loading.', + 'type' => MENU_CALLBACK, + 'file' => 'includes/ajax.inc', + ); + // Path is not admin/structure/views due to menu complications with the wildcards from + // the generic ajax callback. + $items['admin/views/ajax/autocomplete/user'] = array( + 'page callback' => 'views_ajax_autocomplete_user', + 'access callback' => 'user_access', + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + 'file' => 'includes/ajax.inc', + ); + // Define another taxonomy autocomplete because the default one of drupal + // does not support a vid a argument anymore + $items['admin/views/ajax/autocomplete/taxonomy'] = array( + 'page callback' => 'views_ajax_autocomplete_taxonomy', + 'access callback' => 'user_access', + 'access arguments' => array('access content'), + 'type' => MENU_CALLBACK, + 'file' => 'includes/ajax.inc', + ); + return $items; +} + +/** + * Implement hook_menu_alter(). + */ +function views_menu_alter(&$callbacks) { + $our_paths = array(); + $views = views_get_applicable_views('uses hook menu'); + foreach ($views as $data) { + list($view, $display_id) = $data; + $result = $view->execute_hook_menu($display_id, $callbacks); + if (is_array($result)) { + // The menu system doesn't support having two otherwise + // identical paths with different placeholders. So we + // want to remove the existing items from the menu whose + // paths would conflict with ours. + + // First, we must find any existing menu items that may + // conflict. We use a regular expression because we don't + // know what placeholders they might use. Note that we + // first construct the regex itself by replacing %views_arg + // in the display path, then we use this constructed regex + // (which will be something like '#^(foo/%[^/]*/bar)$#') to + // search through the existing paths. + $regex = '#^(' . preg_replace('#%views_arg#', '%[^/]*', implode('|', array_keys($result))) . ')$#'; + $matches = preg_grep($regex, array_keys($callbacks)); + + // Remove any conflicting items that were found. + foreach ($matches as $path) { + // Don't remove the paths we just added! + if (!isset($our_paths[$path])) { + unset($callbacks[$path]); + } + } + foreach ($result as $path => $item) { + if (!isset($callbacks[$path])) { + // Add a new item, possibly replacing (and thus effectively + // overriding) one that we removed above. + $callbacks[$path] = $item; + } + else { + // This item already exists, so it must be one that we added. + // We change the various callback arguments to pass an array + // of possible display IDs instead of a single ID. + $callbacks[$path]['page arguments'][1] = (array)$callbacks[$path]['page arguments'][1]; + $callbacks[$path]['page arguments'][1][] = $display_id; + $callbacks[$path]['access arguments'][] = $item['access arguments'][0]; + $callbacks[$path]['load arguments'][1] = (array)$callbacks[$path]['load arguments'][1]; + $callbacks[$path]['load arguments'][1][] = $display_id; + } + $our_paths[$path] = TRUE; + } + } + } + + // Save memory: Destroy those views. + foreach ($views as $data) { + list($view, $display_id) = $data; + $view->destroy(); + } +} + +/** + * Helper function for menu loading. This will automatically be + * called in order to 'load' a views argument; primarily it + * will be used to perform validation. + * + * @param $value + * The actual value passed. + * @param $name + * The name of the view. This needs to be specified in the 'load function' + * of the menu entry. + * @param $display_id + * The display id that will be loaded for this menu item. + * @param $index + * The menu argument index. This counts from 1. + */ +function views_arg_load($value, $name, $display_id, $index) { + static $views = array(); + + // Make sure we haven't already loaded this views argument for a similar menu + // item elsewhere. + $key = $name . ':' . $display_id . ':' . $value . ':' . $index; + if (isset($views[$key])) { + return $views[$key]; + } + + if ($view = views_get_view($name)) { + $view->set_display($display_id); + $view->init_handlers(); + + $ids = array_keys($view->argument); + + $indexes = array(); + $path = explode('/', $view->get_path()); + + foreach ($path as $id => $piece) { + if ($piece == '%' && !empty($ids)) { + $indexes[$id] = array_shift($ids); + } + } + + if (isset($indexes[$index])) { + if (isset($view->argument[$indexes[$index]])) { + $arg = $view->argument[$indexes[$index]]->validate_argument($value) ? $value : FALSE; + $view->destroy(); + + // Store the output in case we load this same menu item again. + $views[$key] = $arg; + return $arg; + } + } + $view->destroy(); + } +} + +/** + * Page callback entry point; requires a view and a display id, then + * passes control to the display handler. + */ +function views_page() { + $args = func_get_args(); + $name = array_shift($args); + $display_id = array_shift($args); + + // Load the view + if ($view = views_get_view($name)) { + return $view->execute_display($display_id, $args); + } + + // Fallback; if we get here no view was found or handler was not valid. + return drupal_not_found(); +} + +/** + * Implement hook_block_info(). + */ +function views_block_info() { + // Try to avoid instantiating all the views just to get the blocks info. + views_include('cache'); + $cache = views_cache_get('views_block_items', TRUE); + if ($cache && is_array($cache->data)) { + return $cache->data; + } + + $items = array(); + $views = views_get_all_views(); + foreach ($views as $view) { + // disabled views get nothing. + if (!empty($view->disabled)) { + continue; + } + + $view->init_display(); + foreach ($view->display as $display_id => $display) { + + if (isset($display->handler) && !empty($display->handler->definition['uses hook block'])) { + $result = $display->handler->execute_hook_block_list(); + if (is_array($result)) { + $items = array_merge($items, $result); + } + } + + if (isset($display->handler) && $display->handler->get_option('exposed_block')) { + $result = $display->handler->get_special_blocks(); + if (is_array($result)) { + $items = array_merge($items, $result); + } + } + } + } + + // block.module has a delta length limit of 32, but our deltas can + // unfortunately be longer because view names can be 32 and display IDs + // can also be 32. So for very long deltas, change to md5 hashes. + $hashes = array(); + + // get the keys because we're modifying the array and we don't want to + // confuse PHP too much. + $keys = array_keys($items); + foreach ($keys as $delta) { + if (strlen($delta) >= 32) { + $hash = md5($delta); + $hashes[$hash] = $delta; + $items[$hash] = $items[$delta]; + unset($items[$delta]); + } + } + + // Only save hashes if they have changed. + $old_hashes = variable_get('views_block_hashes', array()); + if ($hashes != $old_hashes) { + variable_set('views_block_hashes', $hashes); + } + // Save memory: Destroy those views. + foreach ($views as $view) { + $view->destroy(); + } + + views_cache_set('views_block_items', $items, TRUE); + + return $items; +} + +/** + * Implement hook_block_view(). + */ +function views_block_view($delta) { + $start = microtime(TRUE); + // if this is 32, this should be an md5 hash. + if (strlen($delta) == 32) { + $hashes = variable_get('views_block_hashes', array()); + if (!empty($hashes[$delta])) { + $delta = $hashes[$delta]; + } + } + + // This indicates it's a special one. + if (substr($delta, 0, 1) == '-') { + list($nothing, $type, $name, $display_id) = explode('-', $delta); + // Put the - back on. + $type = '-' . $type; + if ($view = views_get_view($name)) { + if ($view->access($display_id)) { + $view->set_display($display_id); + if (isset($view->display_handler)) { + $output = $view->display_handler->view_special_blocks($type); + $view->destroy(); + return $output; + } + } + $view->destroy(); + } + } + + list($name, $display_id) = explode('-', $delta); + // Load the view + if ($view = views_get_view($name)) { + if ($view->access($display_id)) { + $output = $view->execute_display($display_id); + $view->destroy(); + return $output; + } + $view->destroy(); + } +} + +/** + * Implements hook_flush_caches(). + */ +function views_flush_caches() { + return array('cache_views', 'cache_views_data'); +} + +/** + * Implements hook_field_create_instance. + */ +function views_field_create_instance($instance) { + cache_clear_all('*', 'cache_views', TRUE); + cache_clear_all('*', 'cache_views_data', TRUE); +} + +/** + * Implements hook_field_update_instance. + */ +function views_field_update_instance($instance, $prior_instance) { + cache_clear_all('*', 'cache_views', TRUE); + cache_clear_all('*', 'cache_views_data', TRUE); +} + +/** + * Implements hook_field_delete_instance. + */ +function views_field_delete_instance($instance) { + cache_clear_all('*', 'cache_views', TRUE); + cache_clear_all('*', 'cache_views_data', TRUE); +} + +/** + * Invalidate the views cache, forcing a rebuild on the next grab of table data. + */ +function views_invalidate_cache() { + cache_clear_all('*', 'cache_views', TRUE); +} + +/** + * Access callback to determine if the user can import Views. + * + * View imports require an additional access check because they are PHP + * code and PHP is more locked down than administer views. + */ +function views_import_access() { + return user_access('administer views') && user_access('use PHP for settings'); +} + +/** + * Determine if the logged in user has access to a view. + * + * This function should only be called from a menu hook or some other + * embedded source. Each argument is the result of a call to + * views_plugin_access::get_access_callback() which is then used + * to determine if that display is accessible. If *any* argument + * is accessible, then the view is accessible. + */ +function views_access() { + $args = func_get_args(); + foreach ($args as $arg) { + if ($arg === TRUE) { + return TRUE; + } + + if (!is_array($arg)) { + continue; + } + + list($callback, $arguments) = $arg; + $arguments = $arguments ? $arguments : array(); + // Bring dynamic arguments to the access callback. + foreach ($arguments as $key => $value) { + if (is_int($value) && isset($args[$value])) { + $arguments[$key] = $args[$value]; + } + } + if (function_exists($callback) && call_user_func_array($callback, $arguments)) { + return TRUE; + } + } + + return FALSE; +} + +/** + * Access callback for the views_plugin_access_perm access plugin. + * + * Determine if the specified user has access to a view on the basis of + * permissions. If the $account argument is omitted, the current user + * is used. + */ +function views_check_perm($perm, $account = NULL) { + return user_access($perm, $account) || user_access('access all views', $account); +} + +/** + * Access callback for the views_plugin_access_role access plugin. + + * Determine if the specified user has access to a view on the basis of any of + * the requested roles. If the $account argument is omitted, the current user + * is used. + */ +function views_check_roles($rids, $account = NULL) { + global $user; + $account = isset($account) ? $account : $user; + $roles = array_keys($account->roles); + $roles[] = $account->uid ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID; + return user_access('access all views', $account) || array_intersect(array_filter($rids), $roles); +} +// ------------------------------------------------------------------ +// Functions to help identify views that are running or ran + +/** + * Set the current 'page view' that is being displayed so that it is easy + * for other modules or the theme to identify. + */ +function &views_set_page_view($view = NULL) { + static $cache = NULL; + if (isset($view)) { + $cache = $view; + } + + return $cache; +} + +/** + * Find out what, if any, page view is currently in use. Please note that + * this returns a reference, so be careful! You can unintentionally modify the + * $view object. + */ +function &views_get_page_view() { + return views_set_page_view(); +} + +/** + * Set the current 'current view' that is being built/rendered so that it is + * easy for other modules or items in drupal_eval to identify + */ +function &views_set_current_view($view = NULL) { + static $cache = NULL; + if (isset($view)) { + $cache = $view; + } + + return $cache; +} + +/** + * Find out what, if any, current view is currently in use. Please note that + * this returns a reference, so be careful! You can unintentionally modify the + * $view object. + */ +function &views_get_current_view() { + return views_set_current_view(); +} + +// ------------------------------------------------------------------ +// Include file helpers + +/** + * Include views .inc files as necessary. + */ +function views_include($file) { + module_load_include('inc', 'views', "includes/$file"); +} + +/** + * Load views files on behalf of modules. + */ +function views_module_include($file, $reset = FALSE) { + foreach (views_get_module_apis($reset) as $module => $info) { + if (file_exists(DRUPAL_ROOT . "/$info[path]/$module.$file")) { + require_once DRUPAL_ROOT . "/$info[path]/$module.$file"; + } + } +} + +/** + * Get a list of modules that support the current views API. + */ +function views_get_module_apis($reset = FALSE) { + static $cache = NULL; + if (!isset($cache) || $reset) { + $cache = array(); + foreach (module_implements('views_api') as $module) { + $info = module_invoke($module, 'views_api'); + if (version_compare($info['api'], views_api_minimum_version(), '>=') && + version_compare($info['api'], views_api_version(), '<=')) { + if (!isset($info['path'])) { + $info['path'] = drupal_get_path('module', $module); + } + $cache[$module] = $info; + } + } + } + + return $cache; +} + +/** + * Include views .css files. + */ +function views_add_css($file) { + // We set preprocess to FALSE because we are adding the files conditionally, + // and we don't want to generate duplicate cache files. + // TODO: at some point investigate adding some files unconditionally and + // allowing preprocess. + drupal_add_css(drupal_get_path('module', 'views') . "/css/$file.css", array('preprocess' => FALSE)); +} + +/** + * Include views .js files. + */ +function views_add_js($file) { + // If javascript has been disabled by the user, never add js files. + if (variable_get('views_no_javascript', FALSE)) { + return; + } + static $base = TRUE, $ajax = TRUE; + if ($base) { + drupal_add_js(drupal_get_path('module', 'views') . "/js/base.js"); + $base = FALSE; + } + if ($ajax && in_array($file, array('ajax', 'ajax_view'))) { + drupal_add_library('system', 'drupal.ajax'); + drupal_add_library('system', 'jquery.form'); + $ajax = FALSE; + } + ctools_add_js($file, 'views'); +} + +/** + * Load views files on behalf of modules. + */ +function views_include_handlers($reset = FALSE) { + static $finished = FALSE; + // Ensure this only gets run once. + if ($finished && !$reset) { + return; + } + + views_include('base'); + views_include('handlers'); + views_include('cache'); + views_include('plugins'); + _views_include_handlers(); + $finished = TRUE; +} + +/** + * Load default views files on behalf of modules. + */ +function views_include_default_views($reset = FALSE) { + static $finished = FALSE; + // Ensure this only gets run once. + if ($finished && !$reset) { + return; + } + + // Default views hooks may be in the normal handler file, + // or in a separate views_default file at the discretion of + // the module author. + views_include_handlers($reset); + + _views_include_default_views($reset); + $finished = TRUE; +} + +// ----------------------------------------------------------------------- +// Views handler functions + +/** + * Fetch a handler from the data cache. + * + * @param $table + * The name of the table this handler is from. + * @param $field + * The name of the field this handler is from. + * @param $key + * The type of handler. i.e, sort, field, argument, filter, relationship + * @param $override + * Override the actual handler object with this class. Used for + * aggregation when the handler is redirected to the aggregation + * handler. + * + * @return + * An instance of a handler object. May be views_handler_broken. + */ +function views_get_handler($table, $field, $key, $override = NULL) { + $data = views_fetch_data($table); + $handler = NULL; + + if (isset($data[$field][$key])) { + // Set up a default handler: + if (empty($data[$field][$key]['handler'])) { + $data[$field][$key]['handler'] = 'views_handler_' . $key; + } + + if ($override) { + $data[$field][$key]['override handler'] = $override; + } + + $handler = _views_prepare_handler($data[$field][$key], $data, $field); + } + + if ($handler) { + return $handler; + } + + // DEBUG -- identify missing handlers + debug("Missing handler: $table $field $key"); + $broken = array( + 'title' => t('Broken handler @table.@field', array('@table' => $table, '@field' => $field)), + 'handler' => 'views_handler_' . $key . '_broken', + 'table' => $table, + 'field' => $field, + ); + return _views_create_handler($broken); +} + +/** + * Fetch Views' data from the cache + */ +function views_fetch_data($table = NULL, $reset = FALSE) { + views_include('cache'); + return _views_fetch_data($table, $reset); +} + +// ----------------------------------------------------------------------- +// Views plugin functions + +/** + * Fetch the plugin data from cache. + */ +function views_fetch_plugin_data($type = NULL, $plugin = NULL, $reset = FALSE) { + views_include('cache'); + return _views_fetch_plugin_data($type, $plugin, $reset); +} + +/** + * Get a handler for a plugin + */ +function views_get_plugin($type, $plugin, $reset = FALSE) { + views_include('handlers'); + $definition = views_fetch_plugin_data($type, $plugin, $reset); + if (!empty($definition)) { + return _views_create_handler($definition, $type); + } +} + +// ----------------------------------------------------------------------- +// Views database functions + +/** + * Get a view from the default views defined by modules. + * + * Default views are cached per-language. This function will rescan the + * default_views hook if necessary. + * + * @param $view_name + * The name of the view to load. + * @return + * A view object or NULL if it is not available. + */ +function &views_get_default_view($view_name, $reset = FALSE) { + $null = NULL; + + // Attempt to load individually cached view from cache. + views_include('cache'); + if (!$reset) { + $data = views_cache_get("views_default:{$view_name}", TRUE); + if (isset($data->data) && is_object($data->data)) { + return $data->data; + } + } + + // Otherwise, allow entire cache to be rebuilt. + $cache = views_discover_default_views($reset); + if (isset($cache[$view_name])) { + return $cache[$view_name]; + } + return $null; +} + +/** + * Create an empty view to work with. + * + * @return + * A fully formed, empty $view object. This object must be populated before + * it can be successfully saved. + */ +function views_new_view() { + views_include('view'); + $view = new view(); + $view->vid = 'new'; + $view->add_display('default'); + + return $view; +} + +/** + * Scan all modules for default views and rebuild the default views cache. + * + * @return An associative array of all known default views. + */ +function views_discover_default_views($reset = FALSE) { + static $cache = array(); + + if (empty($cache) || $reset) { + views_include('cache'); + $cache = _views_discover_default_views($reset); + } + return $cache; +} + +/** + * Return a list of all views and display IDs that have a particular + * setting in their display's plugin settings. + * + * @return + * @code + * array( + * array($view, $display_id), + * array($view, $display_id), + * ); + * @endcode + */ +function views_get_applicable_views($type) { + // @todo: Use a smarter flagging system so that we don't have to + // load every view for this. + $result = array(); + $views = views_get_all_views(); + + foreach ($views as $view) { + // Skip disabled views. + if (!empty($view->disabled)) { + continue; + } + + if (empty($view->display)) { + // Skip this view as it is broken. + vsm(t("Skipping broken view @view", array('@view' => $view->name))); + continue; + } + + // Loop on array keys because something seems to muck with $view->display + // a bit in PHP4. + foreach (array_keys($view->display) as $id) { + $plugin = views_fetch_plugin_data('display', $view->display[$id]->display_plugin); + if (!empty($plugin[$type])) { + // This view uses hook menu. Clone it so that different handlers + // don't trip over each other, and add it to the list. + $v = $view->clone_view(); + if ($v->set_display($id)) { + $result[] = array($v, $id); + } + // In PHP 4.4.7 and presumably earlier, if we do not unset $v + // here, we will find that it actually overwrites references + // possibly due to shallow copying issues. + unset($v); + } + } + } + return $result; +} + +/** + * Return an array of all views as fully loaded $view objects. + * + * @param $reset + * If TRUE, reset the static cache forcing views to be reloaded. + */ +function views_get_all_views($reset = FALSE) { + static $views = array(); + + if (empty($views) || $reset) { + $views = array(); + + // First, get all applicable views. + views_include('view'); + $views = view::load_views(); + + // Get all default views. + $status = variable_get('views_defaults', array()); + + foreach (views_discover_default_views($reset) as $view) { + // Determine if default view is enabled or disabled. + if (isset($status[$view->name])) { + $view->disabled = $status[$view->name]; + } + + // If overridden, also say so. + if (!empty($views[$view->name])) { + $views[$view->name]->type = t('Overridden'); + } + else { + $view->type = t('Default'); + $views[$view->name] = $view; + } + } + + } + return $views; +} + +/** + * Get a view from the database or from default views. + * + * This function is just a static wrapper around views::load(). This function + * isn't called 'views_load()' primarily because it might get a view + * from the default views which aren't technically loaded from the database. + * + * @param $name + * The name of the view. + * @param $reset + * If TRUE, reset this entry in the load cache. + * @return $view + * A reference to the $view object. Use $reset if you're sure you want + * a fresh one. + */ +function views_get_view($name, $reset = FALSE) { + views_include('view'); + $view = view::load($name, $reset); + $default_view = views_get_default_view($name, $reset); + + // The view does not exist. + if (empty($view) && empty($default_view)) { + return; + } + // The view is defined in code. + elseif (empty($view) && !empty($default_view)) { + $status = variable_get('views_defaults', array()); + if (isset($status[$default_view->name])) { + $default_view->disabled = $status[$default_view->name]; + } + $default_view->type = t('Default'); + return $default_view->clone_view(); + } + // The view is overriden/defined in the database. + elseif (!empty($view) && !empty($default_view)) { + $view->type = t('Overridden'); + } + + return $view->clone_view(); +} + +// ------------------------------------------------------------------ +// Views debug helper functions + +/** + * Provide debug output for Views. This relies on devel.module + */ +function views_debug($message) { + if (module_exists('devel') && variable_get('views_devel_output', FALSE) && user_access('access devel information')) { + if (is_string($message)) { + $output = $message; + } + else { + $output = var_export($message, TRUE); + } + if (variable_get('views_devel_region', 'footer') != 'watchdog') { + drupal_set_content(variable_get('views_devel_region', 'footer'), '<pre>' . $output . '</pre>'); + } + else { + watchdog('views_logging', '<pre>' . $output . '</pre>'); + } + } +} + +/** + * Shortcut to views_debug() + */ +function vpr($message) { + views_debug($message); +} + +/** + * Debug messages + */ +function vsm($message) { + if (module_exists('devel')) { + dsm($message); + } +} + +function views_trace() { + $message = ''; + foreach (debug_backtrace() as $item) { + if (!empty($item['file']) && !in_array($item['function'], array('vsm_trace', 'vpr_trace', 'views_trace'))) { + $message .= basename($item['file']) . ": " . (empty($item['class']) ? '' : ($item['class'] . '->')) . "$item[function] line $item[line]" . "\n"; + } + } + return $message; +} + +function vsm_trace() { + vsm(views_trace()); +} + +function vpr_trace() { + dpr(views_trace()); +} + +// ------------------------------------------------------------------ +// Exposed widgets form + +/** + * Form builder for the exposed widgets form. + * + * Be sure that $view and $display are references. + */ +function views_exposed_form($form, &$form_state) { + // Don't show the form when batch operations are in progress. + if ($batch = batch_get() && isset($batch['current_set'])) { + return array( + // Set the theme callback to be nothing to avoid errors in template_preprocess_views_exposed_form(). + '#theme' => '', + ); + } + + // Make sure that we validate because this form might be submitted + // multiple times per page. + $form_state['must_validate'] = TRUE; + $view = &$form_state['view']; + $display = &$form_state['display']; + + $form_state['input'] = $view->get_exposed_input(); + + // Let form plugins know this is for exposed widgets. + $form_state['exposed'] = TRUE; + // Check if the form was already created + if ($cache = views_exposed_form_cache($view->name, $view->current_display)) { + return $cache; + } + + $form['#info'] = array(); + + if (!variable_get('clean_url', FALSE)) { + $form['q'] = array( + '#type' => 'hidden', + '#value' => $view->get_url(), + ); + } + + // Go through each handler and let it generate its exposed widget. + foreach ($view->display_handler->handlers as $type => $value) { + foreach ($view->$type as $id => $handler) { + if ($handler->can_expose() && $handler->is_exposed()) { + $handler->exposed_form($form, $form_state); + if ($info = $handler->exposed_info()) { + $form['#info']["$type-$id"] = $info; + } + } + } + } + + $form['submit'] = array( + '#name' => '', // prevent from showing up in $_GET. + '#type' => 'submit', + '#value' => t('Apply'), + '#id' => drupal_html_id('edit-submit-' . $view->name), + ); + + $form['#action'] = url($view->get_url()); + $form['#theme'] = views_theme_functions('views_exposed_form', $view, $display); + $form['#id'] = drupal_clean_css_identifier('views_exposed_form-' . check_plain($view->name) . '-' . check_plain($display->id)); +// $form['#attributes']['class'] = array('views-exposed-form'); + + // If using AJAX, we need the form plugin. + if ($view->use_ajax) { + drupal_add_library('system', 'jquery.form'); + } + ctools_include('dependent'); + + $exposed_form_plugin = $form_state['exposed_form_plugin']; + $exposed_form_plugin->exposed_form_alter($form, $form_state); + + // Save the form + views_exposed_form_cache($view->name, $view->current_display, $form); + + return $form; +} + +/** + * Validate handler for exposed filters + */ +function views_exposed_form_validate(&$form, &$form_state) { + foreach (array('field', 'filter') as $type) { + $handlers = &$form_state['view']->$type; + foreach ($handlers as $key => $handler) { + $handlers[$key]->exposed_validate($form, $form_state); + } + } + $exposed_form_plugin = $form_state['exposed_form_plugin']; + $exposed_form_plugin->exposed_form_validate($form, $form_state); +} + +/** + * Submit handler for exposed filters + */ +function views_exposed_form_submit(&$form, &$form_state) { + foreach (array('field', 'filter') as $type) { + $handlers = &$form_state['view']->$type; + foreach ($handlers as $key => $info) { + $handlers[$key]->exposed_submit($form, $form_state); + } + } + $form_state['view']->exposed_data = $form_state['values']; + $form_state['view']->exposed_raw_input = array(); + + + $exclude = array('q', 'submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', ''); + $exposed_form_plugin = $form_state['exposed_form_plugin']; + $exposed_form_plugin->exposed_form_submit($form, $form_state, $exclude); + + foreach ($form_state['values'] as $key => $value) { + if (!in_array($key, $exclude)) { + $form_state['view']->exposed_raw_input[$key] = $value; + } + } +} + +/** + * Save the Views exposed form for later use. + * + * @param $views_name + * String. The views name. + * @param $display_name + * String. The current view display name. + * @param $form_output + * Array (optional). The form structure. Only needed when inserting the value. + * @return + * Array. The form structure, if any. Otherwise, return FALSE. + */ +function views_exposed_form_cache($views_name, $display_name, $form_output = NULL) { + static $views_exposed; + + // Save the form output + if (!empty($form_output)) { + $views_exposed[$views_name][$display_name] = $form_output; + return; + } + + // Return the form output, if any + return empty($views_exposed[$views_name][$display_name]) ? FALSE : $views_exposed[$views_name][$display_name]; +} + +// ------------------------------------------------------------------ +// Misc helpers + +/** + * Build a list of theme function names for use most everywhere. + */ +function views_theme_functions($hook, $view, $display = NULL) { + require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'views') . "/theme/theme.inc"; + return _views_theme_functions($hook, $view, $display); +} + +/** + * Substitute current time; this works with cached queries. + */ +function views_views_query_substitutions($view) { + global $language_content; + return array( + '***CURRENT_VERSION***' => VERSION, + '***CURRENT_TIME***' => REQUEST_TIME, + '***CURRENT_LANGUAGE***' => $language_content->language, + '***DEFAULT_LANGUAGE***' => language_default('language'), + ); +} + +/** + * Implements hook_query_TAG_alter(). + * + * This is the hook_query_alter() for queries tagged by Views and is used to + * add in substitutions from hook_views_query_substitutions(). + */ +function views_query_views_alter(QueryAlterableInterface $query) { + $substitutions = $query->getMetaData('views_substitutions'); + $tables =& $query->getTables(); + $where =& $query->conditions(); + + // Replaces substitions in tables. + foreach ($tables as $table_name => $table_metadata) { + foreach ($table_metadata['arguments'] as $replacement_key => $value) { + if (isset($substitutions[$value])) { + $tables[$table_name]['arguments'][$replacement_key] = $substitutions[$value]; + } + } + } + + // Replaces substitions in filter criterias. + _views_query_tag_alter_condition($query, $where, $substitutions); +} + +/** + * Replaces the substitutions recursive foreach condition. + */ +function _views_query_tag_alter_condition(QueryAlterableInterface $query, &$conditions, $substitutions) { + foreach ($conditions as $condition_id => &$condition) { + if (is_numeric($condition_id)) { + if (is_string($condition['field'])) { + $condition['field'] = str_replace(array_keys($substitutions), array_values($substitutions), $condition['field']); + } + elseif (is_object($condition['field'])) { + $sub_conditions =& $condition['field']->conditions(); + _views_query_tag_alter_condition($query, $sub_conditions, $substitutions); + } + // $condition['value'] is a subquery so alter the subquery recursive. + // Therefore take sure to get the metadata of the main query. + if (is_object($condition['value'])) { + $subquery = $condition['value']; + $subquery->addMetaData('views_substitutions', $query->getMetaData('views_substitutions')); + views_query_views_alter($condition['value']); + } + elseif (isset($condition['value'])) { + $condition['value'] = str_replace(array_keys($substitutions), array_values($substitutions), $condition['value']); + } + } + } +} + +/** + * Embed a view using a PHP snippet. + * + * This function is meant to be called from PHP snippets, should one wish to + * embed a view in a node or something. It's meant to provide the simplest + * solution and doesn't really offer a lot of options, but breaking the function + * apart is pretty easy, and this provides a worthwhile guide to doing so. + * + * Note that this function does NOT display the title of the view. If you want + * to do that, you will need to do what this function does manually, by + * loading the view, getting the preview and then getting $view->get_title(). + * + * @param $name + * The name of the view to embed. + * @param $display_id + * The display id to embed. If unsure, use 'default', as it will always be + * valid. But things like 'page' or 'block' should work here. + * @param ... + * Any additional parameters will be passed as arguments. + */ +function views_embed_view($name, $display_id = 'default') { + $args = func_get_args(); + array_shift($args); // remove $name + if (count($args)) { + array_shift($args); // remove $display_id + } + + $view = views_get_view($name); + if (!$view || !$view->access($display_id)) { + return; + } + + return $view->preview($display_id, $args); +} + +/** +* Get the result of a view. +* +* @param string $name +* The name of the view to retrieve the data from. +* @param string $display_id +* The display id. On the edit page for the view in question, you'll find +* a list of displays at the left side of the control area. "Defaults" +* will be at the top of that list. Hover your cursor over the name of the +* display you want to use. An URL will appear in the status bar of your +* browser. This is usually at the bottom of the window, in the chrome. +* Everything after #views-tab- is the display ID, e.g. page_1. + * @param ... + * Any additional parameters will be passed as arguments. +* @return +* array +* An array containing an object for each view item. +*/ +function views_get_view_result($name, $display_id = NULL) { + $args = func_get_args(); + array_shift($args); // remove $name + if (count($args)) { + array_shift($args); // remove $display_id + } + + $view = views_get_view($name); + if (is_object($view)) { + if (is_array($args)) { + $view->set_arguments($args); + } + if (is_string($display_id)) { + $view->set_display($display_id); + } + else { + $view->init_display(); + } + $view->pre_execute(); + $view->execute(); + return $view->result; + } + else { + return array(); + } +} + +/** + * Export a field. + */ +function views_var_export($var, $prefix = '', $init = TRUE) { + if (is_array($var)) { + if (empty($var)) { + $output = 'array()'; + } + else { + $output = "array(\n"; + foreach ($var as $key => $value) { + $output .= " " . views_var_export($key, '', FALSE) . " => " . views_var_export($value, ' ', FALSE) . ",\n"; + } + $output .= ')'; + } + } + elseif (is_bool($var)) { + $output = $var ? 'TRUE' : 'FALSE'; + } + elseif (is_string($var) && strpos($var, "\n") !== FALSE) { + // Replace line breaks in strings with a token for replacement + // at the very end. This protects multi-line strings from + // unintentional indentation. + $var = str_replace("\n", "***BREAK***", $var); + $output = var_export($var, TRUE); + } + else { + $output = var_export($var, TRUE); + } + + if ($prefix) { + $output = str_replace("\n", "\n$prefix", $output); + } + + if ($init) { + $output = str_replace("***BREAK***", "\n", $output); + } + + return $output; +} + +/** + * Implement hook_views_exportables(). + */ +function views_views_exportables($op = 'list', $views = NULL, $name = 'foo') { + $all_views = views_get_all_views(); + if ($op == 'list') { + + foreach ($all_views as $name => $view) { + // in list, $views is a list of tags. + if (empty($views) || in_array($view->tag, $views)) { + $return[$name] = array( + 'name' => check_plain($name), + 'desc' => check_plain($view->description), + 'tag' => check_plain($view->tag) + ); + } + } + return $return; + } + + if ($op == 'export') { + $code = "/**\n"; + $code .= " * Implement hook_views_default_views().\n"; + $code .= " */\n"; + $code .= "function " . $name . "_views_default_views() {\n"; + foreach ($views as $view => $truth) { + $code .= " /*\n"; + $code .= " * View " . var_export($all_views[$view]->name, TRUE) . "\n"; + $code .= " */\n"; + $code .= $all_views[$view]->export(' '); + $code .= ' $views[$view->name] = $view;' . "\n\n"; + } + $code .= " return \$views;\n"; + $code .= "}\n"; + + return $code; + } +} + +/** + * #process callback to see if we need to check_plain() the options. + * + * Since FAPI is inconsistent, the #options are sanitized for you in all cases + * _except_ checkboxes. We have form elements that are sometimes 'select' and + * sometimes 'checkboxes', so we need decide late in the form rendering cycle + * if the options need to be sanitized before they're rendered. This callback + * inspects the type, and if it's still 'checkboxes', does the sanitation. + */ +function views_process_check_options($element, &$form_state) { + if ($element['#type'] == 'checkboxes' || $element['#type'] == 'checkbox') { + $element['#options'] = array_map('check_plain', $element['#options']); + } + return $element; +} + +/** + * Trim the field down to the specified length. + * + * @param $alter + * - max_length: Maximum lenght of the string, the rest gets truncated. + * - word_boundary: Trim only on a word boundary. + * - ellipsis: Trim only on a word boundary. + * - html: Take sure that the html is correct. + * + * @param $value + * The string which should be trimmed. + */ +function views_trim_text($alter, $value) { + if (drupal_strlen($value) > $alter['max_length']) { + $value = drupal_substr($value, 0, $alter['max_length']); + // TODO: replace this with cleanstring of ctools + if (!empty($alter['word_boundary'])) { + $regex = "(.*)\b.+"; + if (function_exists('mb_ereg')) { + mb_regex_encoding('UTF-8'); + $found = mb_ereg($regex, $value, $matches); + } + else { + $found = preg_match("/$regex/us", $value, $matches); + } + if ($found) { + $value = $matches[1]; + } + } + // Remove scraps of HTML entities from the end of a strings + $value = rtrim(preg_replace('/(?:<(?!.+>)|&(?!.+;)).*$/us', '', $value)); + + if (!empty($alter['ellipsis'])) { + $value .= '...'; + } + } + if (!empty($alter['html'])) { + $value = _filter_htmlcorrector($value); + } + + return $value; +} diff --git a/sites/all/modules/views/views2.doxy b/sites/all/modules/views/views2.doxy new file mode 100644 index 0000000000000000000000000000000000000000..7d95c1a0e524bed3e10dd8b1ef1f8f9bdc1f1a30 --- /dev/null +++ b/sites/all/modules/views/views2.doxy @@ -0,0 +1,1252 @@ +# Doxyfile 1.4.7 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Views + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 2.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = YES + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = YES + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 2 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command <command> <input-file>, where <command> is the value of +# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = NO + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.module *.inc *.php + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = NO + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/sites/all/modules/views/views3.doxy b/sites/all/modules/views/views3.doxy new file mode 100644 index 0000000000000000000000000000000000000000..7c38ae481caa4b8cba6ecf8f286d1daf4cc2cdad --- /dev/null +++ b/sites/all/modules/views/views3.doxy @@ -0,0 +1,1252 @@ +# Doxyfile 1.4.7 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Views + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 2.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = YES + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = YES + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 2 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command <command> <input-file>, where <command> is the value of +# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = NO + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = *.module *.inc *.php + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = NO + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/sites/all/modules/views/views_export/views_export.css b/sites/all/modules/views/views_export/views_export.css new file mode 100644 index 0000000000000000000000000000000000000000..87178e4cfc9d6548b58b0922f4714378de875a51 --- /dev/null +++ b/sites/all/modules/views/views_export/views_export.css @@ -0,0 +1,13 @@ +/* $Id: views_export.css,v 1.1 2008/06/12 16:17:25 merlinofchaos Exp $ */ + +div.export-container table input, +div.export-container table th, +div.export-container table td { + padding: 0 0 0 .5em; + margin: 0; + vertical-align: top; +} + +div.export-container table td input { + margin-top: .25em; +} diff --git a/sites/all/modules/views/views_export/views_export.info b/sites/all/modules/views/views_export/views_export.info new file mode 100644 index 0000000000000000000000000000000000000000..d1cc4934dfd84be005c4b1e9c379cf7e9d2d8051 --- /dev/null +++ b/sites/all/modules/views/views_export/views_export.info @@ -0,0 +1,14 @@ +; $Id: views_export.info,v 1.1.6.2 2010/12/23 17:52:53 dereine Exp $ + +name = Views exporter +description = Allows exporting multiple views at once. +package = "Views" +dependencies[] = views +core = 7.x + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-3.0-alpha1" +core = "7.x" +project = "views" +datestamp = "1294276880" + diff --git a/sites/all/modules/views/views_export/views_export.module b/sites/all/modules/views/views_export/views_export.module new file mode 100644 index 0000000000000000000000000000000000000000..e5ce65e8c1c9fe23f3a0736b388729f55a6046d7 --- /dev/null +++ b/sites/all/modules/views/views_export/views_export.module @@ -0,0 +1,279 @@ +<?php +// $Id: views_export.module,v 1.9.4.5 2010/12/01 20:29:24 dereine Exp $ + +/** + * @file views_export.module + * + * Provides functionality to export multiple items at once to make it easy to + * dump a set of views into code. + */ + +/** + * Implements hook_menu(). + */ +function views_export_menu() { + $items = array(); + $items['admin/structure/views/tools/export'] = array( + 'title' => 'Bulk export', + 'access arguments' => array('use views exporter'), + 'page callback' => 'views_export_export', + 'type' => MENU_LOCAL_TASK, + ); + + $items['admin/structure/views/tools/export/results'] = array( + 'access arguments' => array('use views exporter'), + 'page callback' => 'views_export_export', + 'type' => MENU_LOCAL_TASK, + ); + + return $items; +} +/** + * Implements hook_theme(). + */ +function views_export_theme() { + return array( + 'views_export_export_form' => array( + 'render element' => 'form', + ), + ); +} + +/** + * Implements hook_perm(). + */ +function views_export_permission() { + return array( + 'use views exporter' => array( + 'title' => t('Use Views exporter'), + 'description' => t('Use the Views exporter.'), + ), + ); +} + +/** + * Page callback to export views in bulk. + */ +function views_export_export() { + $tags = array(); + if (!empty($_GET['tags'])) { + $tags = explode(',', $_GET['tags']); + } + + $exportables = array(); + foreach (module_implements('views_exportables') as $module) { + $function = $module . '_views_exportables'; + $exportables[$module] = $function('list', $tags); + asort($exportables[$module]); + } + + if ($exportables) { + $form_state = array( + 'no_redirect' => TRUE, + 'exportables' => $exportables, + 'tags' => $tags, + 'build_info' => array( + 'args' => array(), + ), + ); + + $form = drupal_build_form('views_export_export_form', $form_state); + $output = drupal_render($form); + if ($form_state['submitted']) { + $output = $form_state['output']; + } + return $output; + } + else { + return t('There are no views to be exported at this time.'); + } +} + +/** + * Form to choose a group of views to export. + */ +function views_export_export_form($form, &$form_state) { + foreach ($form_state['exportables'] as $module => $views) { + foreach ($views as $name => $data) { + $options[$name] = $data['name']; + } + + $form['modules']['#tree'] = TRUE; + $form['modules'][$module] = array( + '#type' => 'checkboxes', + '#options' => $options, + '#default_value' => array(), + ); + } + + $tags = array(); + foreach (views_get_all_views() as $name => $view) { + if (!empty($view->tag)) { + $tags[$view->tag] = $view->tag; + } + } + + asort($tags); + + $form['tags'] = array( + '#type' => 'select', + '#title' => t('Show only these tags'), + '#options' => $tags, + '#default_value' => $form_state['tags'], + '#multiple' => TRUE, + ); + + $form['apply'] = array( + '#type' => 'submit', + '#value' => t('Apply'), + '#submit' => array('views_export_export_form_apply'), + ); + + $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/structure/views/tools/export/results'); + $form['#redirect'] = FALSE; + if (isset($form_state['exportables'])) { + $form['#exportables'] = $form_state['exportables']; + } + return $form; +} + +function theme_views_export_export_form(&$vars) { + $form = $vars['form']; + $output = ''; + // Get current list of modules. + $files = system_rebuild_module_data(); + + $exportables = $form['#exportables']; + $output .= drupal_render($form['tags']); + $output .= drupal_render($form['apply']); + $output .= '<div class="clearfix">'; + + foreach ($exportables as $module => $views) { + $header = array(theme('table_select_header_cell'), $files[$module]->info['name'], t('Tag'), t('Description')); + $rows = array(); + foreach ($views as $name => $view) { + $title = $form['modules'][$module][$name]['#title']; + unset($form['modules'][$module][$name]['#title']); + $rows[] = array(drupal_render($form['modules'][$module][$name]), $title, $view['tag'], '<div class="description">' . $view['desc'] . '</div>'); + } + $output .= '<div class="export-container">'; + $output .= theme('table', array( + 'header' => $header, + 'rows' => $rows + )); + $output .= "</div>\n"; + } + $output .= '</div>'; + $form['#attached']['css'] = array(drupal_add_css(drupal_get_path('module', 'views_export') . '/views_export.css')); + + $output .= drupal_render_children($form); + return $output; +} + +function views_export_export_form_apply(&$form, &$form_state) { + $tags = $form_state['values']['tags']; + if ($tags) { + drupal_goto('admin/structure/views/tools/export', array('tags' => implode(',', $tags))); + } + else { + drupal_goto('admin/structure/views/tools/export'); + } +} + +function views_export_export_form_submit(&$form, &$form_state) { + $code = ''; + if (empty($form_state['values']['name'])) { + $form_state['values']['name'] = 'foo'; + } + + foreach ($form_state['values']['modules'] as $module => $views) { + $views = array_filter($views); + asort($views); + if ($views) { + $code .= module_invoke($module, 'views_exportables', 'export', $views, $form_state['values']['name']) . "\n\n"; + } + } + + $lines = substr_count($code, "\n"); + + $types = system_element_info(); + + $info = '; $Id: views_export.module,v 1.9.4.5 2010/12/01 20:29:24 dereine Exp $'."\n"; + $info .= "\n"; + $info .= strtr("name = @module Export Module\n", array('@module' => $form_state['values']['name'])); + $info .= strtr("description = Exports some views of @module\n", array('@module' => $form_state['values']['name'])); + $info .= "dependencies[] = views\n"; + $info .= "core = 6.x\n"; + + + $element_info = array( + '#title' => t('Put this in @module.info in your modules/@module directory', array('@module' => $form_state['values']['name'])), + '#type' => 'textarea', + '#id' => 'export-info-textarea', + '#name' => 'export-info-textarea', + '#attributes' => array(), + '#rows' => 9, + '#cols' => 60, + '#value' => $info, + '#parents' => array('dummy'), + '#required' => FALSE, + ) + $types['textarea']; + + $api = "/**\n"; + $api .= " * Implements hook_views_api().\n"; + $api .= " */\n"; + $api .= "function @module_views_api() {\n"; + $api .= " return array(\n"; + $api .= " 'api' => '" . views_api_version() . "',\n"; + $api .= " 'path' => drupal_get_path('module', '@module'),\n"; + $api .= " //'path' => drupal_get_path('module', '@module') . '/includes',\n"; + $api .= " );\n"; + $api .= "}"; + + $api = strtr($api, array('@module' => check_plain($form_state['values']['name']))); + + $element_api = array( + '#title' => t('Put this in @module.module in your modules/@module directory', array('@module' => $form_state['values']['name'])), + '#type' => 'textarea', + '#id' => 'export-api-textarea', + '#name' => 'export-api-textarea', + '#attributes' => array( 'dir' => 'ltr' ), + '#rows' => 9, + '#cols' => 60, + '#value' => $api, + '#parents' => array('dummy'), + '#required' => FALSE, + ) + $types['textarea']; + + $element_hook = array( + '#title' => t('Put this in @module.views_default.inc in your modules/@module directory or modules/@module/includes directory', array('@module' => $form_state['values']['name'])), + '#type' => 'textarea', + '#id' => 'export-textarea', + '#name' => 'export-textarea', + '#attributes' => array( 'dir' => 'ltr' ), + '#rows' => min($lines, 150), + '#value' => $code, + '#parents' => array('dummy'), + '#required' => FALSE, + ) + $types['textarea']; + + + $form_state['output'] = theme('textarea', array( + 'element' => $element_info)); + $form_state['output'] .= theme('textarea', array( + 'element' => $element_api)); + $form_state['output'] .= theme('textarea', array( + 'element' => $element_hook)); +} + diff --git a/sites/all/modules/views/views_ui.info b/sites/all/modules/views/views_ui.info new file mode 100644 index 0000000000000000000000000000000000000000..c57b35bebe07e19c82dcc2d1d382438ba22466db --- /dev/null +++ b/sites/all/modules/views/views_ui.info @@ -0,0 +1,14 @@ +; $Id: views_ui.info,v 1.10.6.2 2010/12/24 08:29:52 dereine Exp $ +name = Views UI +description = Administrative interface to views. Without this module, you cannot create or edit your views. +package = Views +core = 7.x +configure = admin/structure/views +dependencies[] = views +files[] = views_ui.module +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-3.0-alpha1" +core = "7.x" +project = "views" +datestamp = "1294276880" + diff --git a/sites/all/modules/views/views_ui.module b/sites/all/modules/views/views_ui.module new file mode 100644 index 0000000000000000000000000000000000000000..beb3a50dc1e1567bae2df2d4b7e35a426a69c8f0 --- /dev/null +++ b/sites/all/modules/views/views_ui.module @@ -0,0 +1,422 @@ +<?php +// $Id: views_ui.module,v 1.109.6.18 2010/12/24 13:42:00 dereine Exp $ +/** + * @file views_ui.module + * Provide structure for the administrative interface to Views. + */ + +/* + * Implements hook_menu(). + */ +function views_ui_menu() { + $items = array(); + + // Minor code reduction technique + $base = array( + 'access callback' => 'user_access', + 'access arguments' => array('administer views'), + 'file' => 'includes/admin.inc', + ); + + $callback = $base + array('type' => MENU_CALLBACK); + + $convert = array('file' => 'includes/convert.inc') + $base; + + $items['admin/structure/views'] = $base + array( + 'title' => 'Views', + 'page callback' => 'views_ui_list_views', + 'description' => 'Views are customized lists of content on your system; they are highly configurable and give you control over how lists of content are presented.', + 'type' => MENU_NORMAL_ITEM + ); + $items['admin/structure/views/list'] = $base + array( + 'title' => 'List', + 'page callback' => 'views_ui_list_views', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => '-1' + ); + $items['admin/structure/views/add'] = $base + array( + 'title' => 'Add new view', + 'page callback' => 'views_ui_add_page', + 'type' => MENU_LOCAL_ACTION, + ); + $items['admin/structure/views/import'] = array( + 'title' => 'Import view from code', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('views_ui_import_page'), + 'access callback' => 'views_import_access', + 'type' => MENU_LOCAL_ACTION, + ) + $base; + $items['admin/structure/views/tools'] = $base + array( + 'title' => 'Tools', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('views_ui_admin_tools'), + 'type' => MENU_LOCAL_TASK + ); + $items['admin/structure/views/tools/basic'] = $base + array( + 'title' => 'Basic', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('views_ui_admin_tools'), + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ); + + $items['admin/structure/views/tools/convert'] = $convert + array( + 'title' => 'Convert', + 'description' => 'Convert stored Views 1 views.', + 'page callback' => 'views_ui_admin_convert', + 'type' => MENU_LOCAL_TASK, + 'weight' => 1, + ); + $items['admin/structure/views1/delete'] = $convert + array( + 'title' => 'Delete view', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('views_ui_delete1_confirm', 4), + 'type' => MENU_CALLBACK, + ); + $items['admin/structure/views1/convert'] = $convert + array( + 'title' => 'Convert view', + 'page callback' => 'views_ui_convert1', + 'page arguments' => array(4), + 'type' => MENU_CALLBACK, + ); + + $items['admin/structure/views/delete/%views_ui_cache'] = $callback + array( + 'title' => 'Delete view', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('views_ui_delete_confirm', 4), + ); + $items['admin/structure/views/break-lock/%views_ui_cache'] = $callback + array( + 'title' => 'Delete view', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('views_ui_break_lock_confirm', 4), + ); + $items['admin/structure/views/export/%views_ui_cache'] = $callback + array( + 'page callback' => 'drupal_get_form', + 'page arguments' => array('views_ui_export_page', 4), + 'type' => MENU_LOCAL_TASK + ); + $items['admin/structure/views/clone/%views_ui_cache'] = $callback + array( + 'page callback' => 'views_ui_clone_page', + 'page arguments' => array(4), + 'type' => MENU_LOCAL_TASK + ); + $items['admin/structure/views/enable/%views_ui_default'] = $callback + array( + 'page callback' => 'views_ui_enable_page', + 'page arguments' => array(4), + ); + $items['admin/structure/views/disable/%views_ui_default'] = $callback + array( + 'page callback' => 'views_ui_disable_page', + 'page arguments' => array(4), + ); + + // Many line items for editing a view. + $items['admin/structure/views/edit/%views_ui_cache'] = $base + array( + 'title' => 'Edit', + 'page callback' => 'views_ui_edit_page', + 'page arguments' => array(4), + 'type' => MENU_LOCAL_TASK + ); + $ajax_callbacks = array( + 'analyze' => 'views_ui_analyze_view', + 'add-display' => 'views_ui_add_display', + 'preview' => 'views_ui_preview', + 'reorder-displays' => 'views_ui_reorder_view', + ); + + foreach ($ajax_callbacks as $menu => $menu_callback) { + $items['admin/structure/views/nojs/' . $menu . '/%views_ui_cache'] = $callback + array( + 'page callback' => $menu_callback, + 'page arguments' => array(FALSE, 5), + ); + $items['admin/structure/views/ajax/' . $menu . '/%views_ui_cache'] = $callback + array( + 'page callback' => $menu_callback, + 'page arguments' => array(TRUE, 5), + 'delivery callback' => 'views_ui_ajax_deliver', + ); + } + + $items['admin/structure/views/nojs/human_name/%views_ui_cache'] = $callback + array( + 'page callback' => 'views_ui_edit_details', + 'page arguments' => array('human_name', FALSE, 5), + ); + $items['admin/structure/views/ajax/human_name/%views_ui_cache'] = $callback + array( + 'page callback' => 'views_ui_edit_details', + 'page arguments' => array('human_name', TRUE, 5), + 'delivery callback' => 'views_ui_ajax_deliver', + ); + $items['admin/structure/views/nojs/tag/%views_ui_cache'] = $callback + array( + 'page callback' => 'views_ui_edit_details', + 'page arguments' => array('tag', FALSE, 5), + ); + $items['admin/structure/views/ajax/tag/%views_ui_cache'] = $callback + array( + 'page callback' => 'views_ui_edit_details', + 'page arguments' => array('tag', TRUE, 5), + 'delivery callback' => 'views_ui_ajax_deliver', + ); + $items['admin/structure/views/nojs/description/%views_ui_cache'] = $callback + array( + 'page callback' => 'views_ui_edit_details', + 'page arguments' => array('description', FALSE, 5), + ); + $items['admin/structure/views/ajax/description/%views_ui_cache'] = $callback + array( + 'page callback' => 'views_ui_edit_details', + 'page arguments' => array('description', TRUE, 5), + 'delivery callback' => 'views_ui_ajax_deliver', + ); + + $items['admin/build/views/nojs/clone-display/%views_ui_cache'] = $callback + array( + 'page callback' => 'views_ui_clone_display', + 'page arguments' => array(FALSE, 5, 6), + ); + + $items['admin/build/views/ajax/clone-display/%views_ui_cache'] = $callback + array( + 'page callback' => 'views_ui_clone_display', + 'page arguments' => array(TRUE, 5, 6), + 'delivery callback' => 'views_ui_ajax_deliver', + ); + + $items['admin/structure/views/nojs/%/%views_ui_cache'] = $callback + array( + 'page callback' => 'views_ui_ajax_form', + 'page arguments' => array(FALSE, 4, 5), + ); + $items['admin/structure/views/ajax/%/%views_ui_cache'] = $callback + array( + 'page callback' => 'views_ui_ajax_form', + 'page arguments' => array(TRUE, 4, 5), + 'delivery callback' => 'views_ui_ajax_deliver', + ); + + // autocompletes for handlers and such + $items['admin/views/ajax/autocomplete/tag'] = $callback + array( + 'page callback' => 'views_ui_autocomplete_tag', + 'access arguments' => array('administer views'), + 'type' => MENU_CALLBACK, + 'file' => 'includes/admin.inc', + ); + + return $items; +} + +/* + * Implements hook_help(). + */ +function views_ui_help($path, $arg = '') { + switch ($path) { + case 'admin/structure/views/tools/convert': + return '<p>' . t('The converter will make a best-effort attempt to convert a Views 1 view to Views 2. This conversion is not reliable; you will very likely have to make adjustments to your view to get it to match. You can import Views 1 views through the normal Import tab.') . '</p>'; + } +} + +/* + * Implements hook_theme(). + */ +function views_ui_theme() { + $path = drupal_get_path('module', 'views'); + require_once DRUPAL_ROOT . "/$path/includes/admin.inc"; + + return array( + // edit a view + 'views_ui_edit_view' => array( + 'variables' => array('view' => NULL), + 'template' => 'views-ui-edit-view', + 'path' => "$path/theme", + ), + 'views_ui_edit_tab' => array( + 'variables' => array('view' => NULL, 'display' => NULL), + 'template' => 'views-ui-edit-tab', + 'path' => "$path/theme", + ), + 'views_ui_edit_item' => array( + 'variables' => array('type' => NULL, 'view' => NULL, 'display' => NULL, 'no_fields' => FALSE), + 'template' => 'views-ui-edit-item', + 'path' => "$path/theme", + ), + 'views_ui_rearrange_form' => array( + 'render element' => 'form', + ), + 'views_ui_rearrange_filter_form' => array( + 'render element' => 'form', + 'file' => 'includes/admin.inc', + ), + + // list views + 'views_ui_list_views' => array( + 'variables' => array( + 'views' => array(), + 'help' => '', + 'widgets' => '', + 'help_type_icon' => '', + ), + 'template' => 'views-ui-list-views', + 'path' => "$path/theme", + ), + + // tab themes + 'views_tabset' => array( + 'variables' => array('tabs' => NULL), + ), + 'views_tab' => array( + 'variables' => array('body' => NULL), + ), + 'views_ui_reorder_displays_form' => array( + 'render element' => 'form', + 'file' => 'includes/admin.inc', + ), + + + // On behalf of a plugin + 'views_ui_style_plugin_table' => array( + 'render element' => 'form', + ), + ); +} + +/** + * Specialized menu callback to load a view either out of the cache or just + * load it. + */ +function views_ui_cache_load($name) { + ctools_include('object-cache'); + views_include('view'); + $view = ctools_object_cache_get('view', $name); + + if (empty($view)) { + $view = views_get_view($name); + + if (!empty($view)) { + // Check to see if someone else is already editing this view. + $view->locked = ctools_object_cache_test('view', $view->name); + // Set a flag to indicate that this view is being edited. + // This flag will be used e.g. to determine whether strings + // should be localized. + $view->editing = TRUE; + } + } + + if (empty($view)) { + return FALSE; + } + + else { + return $view; + } +} + +/** + * Specialized cache function to add a flag to our view, include an appropriate + * include, and cache more easily. + */ +function views_ui_cache_set(&$view) { + if (!empty($view->locked)) { + drupal_set_message(t('Changes cannot be made to a locked view.'), 'error'); + return; + } + ctools_include('object-cache'); + $view->changed = TRUE; // let any future object know that this view has changed. + + // Unset handlers; we don't want to write these into the cache + unset($view->display_handler); + unset($view->current_display); + unset($view->default_display); + $view->query = NULL; + foreach (array_keys($view->display) as $id) { + unset($view->display[$id]->handler); + unset($view->display[$id]->default_display); + } + ctools_object_cache_set('view', $view->name, $view); +} + + +/** + * Specialized menu callback to load a view that is only a default + * view. + */ +function views_ui_default_load($name) { + $view = views_get_view($name); + if ($view->type == t('Default')) { + return $view; + } + + return FALSE; +} + +/** + * Package and send the result of a page callback to the browser as an AJAX + * response, and add the HTML. + * + * @param $page_callback_result + * The result of a page callback. Can be one of: + * - NULL: to indicate no content. + * - An integer menu status constant: to indicate an error condition. + * - A string of HTML content. + * - A renderable array of content. + */ +function views_ui_ajax_deliver($page_callback_result) { + $commands = array(); + $header = TRUE; + + if (!isset($page_callback_result)) { + // Simply delivering an empty commands array is sufficient. This results + // in the AJAX request being completed, but nothing being done to the page. + } + elseif (is_int($page_callback_result)) { + switch ($page_callback_result) { + case MENU_NOT_FOUND: + $commands[] = ajax_command_alert(t('The requested page could not be found.')); + break; + + case MENU_ACCESS_DENIED: + $commands[] = ajax_command_alert(t('You are not authorized to access this page.')); + break; + + case MENU_SITE_OFFLINE: + $commands[] = ajax_command_alert(filter_xss_admin(variable_get('maintenance_mode_message', + t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal')))))); + break; + } + } + elseif (is_array($page_callback_result) && isset($page_callback_result['#type']) && ($page_callback_result['#type'] == 'ajax')) { + // Complex AJAX callbacks can return a result that contains an error message + // or a specific set of commands to send to the browser. + $page_callback_result += element_info('ajax'); + $header = $page_callback_result['#header']; + $error = $page_callback_result['#error']; + if (isset($error) && $error !== FALSE) { + if ((empty($error) || $error === TRUE)) { + $error = t('An error occurred while handling the request: The server received invalid input.'); + } + $commands[] = ajax_command_alert($error); + } + else { + $commands = $page_callback_result['#commands']; + } + } + else { + // Like normal page callbacks, simple AJAX callbacks can return html + // content, as a string or renderable array, to replace what was previously + // there in the wrapper. In this case, in addition to the content, we want + // to add the status messages, but inside the new wrapper, so that they get + // replaced on subsequent AJAX calls for the same wrapper. + $html = is_string($page_callback_result) ? $page_callback_result : drupal_render($page_callback_result); + $commands[] = ajax_command_replace(NULL, $html); + $commands[] = ajax_command_prepend(NULL, theme('status_messages')); + } + + // This function needs to do the same thing that drupal_deliver_html_page() + // does: add any needed http headers, print rendered output, and perform + // end-of-request tasks. By default, $header=TRUE, and we add a + // 'text/javascript' header. The page callback can override $header by + // returning an 'ajax' element with a #header property. This can be set to + // FALSE to prevent the 'text/javascript' header from being output, necessary + // when outputting to an IFRAME. This can also be set to 'multipart', in which + // case, we don't output JSON, but JSON content wrapped in a textarea, making + // a 'text/javascript' header incorrect. + if ($header && $header !== 'multipart') { + drupal_add_http_header('Content-Type', 'text/javascript; charset=utf-8'); + } + $output = ajax_render($commands); + if ($header === 'multipart') { + // jQuery file uploads: http://malsup.com/jquery/form/#code-samples + $output = '<textarea>' . $output . '</textarea>'; + } + print $output; + ajax_footer(); +}