diff --git a/README.txt b/README.txt index 358d8ca1a02fd9be445c094a14e1f10fed9b5bf2..56d3e5eb50358f648db4b4b1a70efc918f446ea4 100644 --- a/README.txt +++ b/README.txt @@ -1,11 +1,3 @@ - -Examples modules - -This set of modules is intended to show how to use various Drupal features. -It's intended only for developers. - -If you find a problem, bad comment, poor usage, out-of-date API usage, -etc., please post an issue in the issue queue at -http://drupal.org/project/examples. - - +The master branch of Examples is intentionally empty. Please clone a proper +version branch like '7.x-1.x' or '6.x-1.x'. For instructions see the project's +Git tab at http://drupal.org/node/594964/git-instructions. diff --git a/action_example/CHANGELOG.txt b/action_example/CHANGELOG.txt deleted file mode 100644 index 8b137891791fe96927ad78e64b0aad7bded08bdc..0000000000000000000000000000000000000000 --- a/action_example/CHANGELOG.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/action_example/action_example.info b/action_example/action_example.info deleted file mode 100644 index a1fa2378ec0490bcc295727c0ad1902fecf897ba..0000000000000000000000000000000000000000 --- a/action_example/action_example.info +++ /dev/null @@ -1,6 +0,0 @@ -name = Action example -description = Demonstrates providing actions that can be associated to triggers. -package = Example modules -core = 7.x -dependencies[] = trigger -files[] = action_example.test diff --git a/action_example/action_example.module b/action_example/action_example.module deleted file mode 100644 index e802cc7d39ca6444934353f981c1448b5fd44495..0000000000000000000000000000000000000000 --- a/action_example/action_example.module +++ /dev/null @@ -1,360 +0,0 @@ - array( - 'label' => t('Action Example: A basic example action that does nothing'), - 'type' => 'system', - 'configurable' => FALSE, - 'triggers' => array('any'), - ), - 'action_example_unblock_user_action' => array( - 'label' => t('Action Example: Unblock a user'), - 'type' => 'user', - 'configurable' => FALSE, - 'triggers' => array('any'), - ), - 'action_example_node_sticky_action' => array( - 'type' => 'node', - 'label' => t('Action Example: Promote to frontpage and sticky on top any content created by :'), - 'configurable' => TRUE, - 'behavior' => array('changes_property'), - 'triggers' => array('node_presave', 'node_insert', 'node_update'), - ), - ); -} - - - -/** - * Implements hook_menu(). - * - * Simply provide a menu entry which explains what the module does. - */ -function action_example_menu() { - $items['examples/action_example'] = array( - 'title' => 'Action Example', - 'description' => 'Provides a basic information page.', - 'page callback' => '_action_example_page', - 'access callback' => TRUE, - ); - return $items; -} - - -/** - * A simple page to explain to the developer what to do. - */ -function _action_example_page() { - return t("The Action Example provides three example actions which can be configured on the Actions configuration page and assigned to triggers on the Triggers configuration page.", array('@actions_url' => url('admin/config/system/actions'), '@triggers_url' => url('admin/structure/trigger/node'))); -} - -/* - * Most basic action. - * - * This action is not expecting any type of entity object, and can be used with - * any trigger type or any event. - */ - -/** - * Basic example action. - * - * @param $entity - * An optional entity object. - * @param array $context - * Array with parameters for this action: depends on the trigger. - * - * @ingroup actions - */ -function action_example_basic_action(&$entity, $context = array()) { - // - // In this case we are ignoring the entity and the context. This case of - // action is useful when your action does not depend on the context, and - // the function must do something regardless the scope of the trigger. - // Simply announces that the action was executed using a messages. - - drupal_set_message(t('action_example_basic_action fired')); - watchdog('action_example', 'action_example_basic_action fired.'); -} - -// --------------------------------------------------------------------------- -/* - * A complex action for different trigger types. - * - * This action is expecting an entity object user, node or comment. If none of - * the above is provided (because it was not called from an user/node/comment - * trigger event, then the action will be taken on the current logged in user. - * - */ - -/** - * Unblock an user. This action can be fired from different trigger types: - * - User trigger: this user will be unblocked. - * - Node/Comment trigger: the author of the node or comment will be unblocked. - * - Other: (including system or custom defined types), current user will be - * unblocked. (Yes, this seems like an incomprehensible use-case.) - * - * @param $entity - * An optional user object (could be a user, or an author if context is - * node or comment) - * @param array $context - * Array with parameters for this action: depends on the trigger. The context - * is not used in this example. - * - * @ingroup actions - */ -function action_example_unblock_user_action(&$entity, $context = array()) { - - // First we check that entity is a user object. If this is the case, then this - // is a user-type trigger. - if (isset($entity->uid)) { - $uid = $entity->uid; - } - elseif (isset($context['uid'])) { - $uid = $context['uid']; - } - // If neither of those are valid, then block the current user. - else { - $uid = $GLOBALS['user']->uid; - } - $account = user_load($uid); - $account = user_save($account, array('status' => 1)); - watchdog('action_example', 'Unblocked user %name.', array('%name' => $account->name)); - drupal_set_message(t('Unblocked user %name', array('%name' => $account->name))); -} - -// --------------------------------------------------------------------------- -/* - * A complex action using customization. - * - * The next action requires a configuration form to create/configure the action. - * In Drupal these are called 'advanced actions', because they must be - * customized to define their functionality. - * - * The 'action_example_node_sticky_action' allows creating rules to promote and - * set sticky content created by selected users on certain events. A form is - * used to configure which user is affected by this action, and this form - * includes the stanard _validate and _submit hooks. - */ - - -/** - * Generates settings form for action_example_node_sticky_action(). - * - * @param array $context - * An array of options of this action (in case it is being edited) - * @return array $form - * - */ -function action_example_node_sticky_action_form($context) { - /* - * We return a configuration form to set the requirements that will - * match this action before being executed. This is a regular Drupal form and - * may include any type of information you want, but all the fields of the - * form will be saved into the $context variable. - * - * In this case we are promoting all content types submited by this user, but - * it is possible to extend these conditions providing more options in the - * settings form. - */ - $form['author'] = array( - '#title' => t('Author name'), - '#type' => 'textfield', - '#description' => t('Any content created, presaved or updated by this user will be promoted to front page and set as sticky.'), - '#default_value' => isset($context['author']) ? $context['author'] : '', - ); - // Verify user permissions and provide an easier way to fill this field. - if (user_access('access user profiles')) { - $form['author']['#autocomplete_path'] = 'user/autocomplete'; - } - // No more options, return the form. - return $form; -} - -/** - * Validate settings form for action_example_node_sticky_action(). - * Verify that user exists before continuing. - */ -function action_example_node_sticky_action_validate($form, $form_state) { - if (! $account = user_load_by_name($form_state['values']['author']) ) { - form_set_error('author', t('Please, provide a valid username')); - } -} - -/** - * Submit handler for action_example_node_sticky_action. - * - * Returns an associative array of values which will be available in the - * $context when an action is executed. - */ -function action_example_node_sticky_action_submit($form, $form_state) { - return array('author' => $form_state['values']['author']); -} - -/** - * Promote and set sticky flag action. This is the special action that has been - * customized using the configuration form. - * - * @param $node - * A node object provided by the associated trigger. - * @param $context - * Array with the following elements: - * - 'author': username of the author's content this function will promote and - * set as sticky. - * - * @ingroup actions - */ -function action_example_node_sticky_action($node, $context) { - if (function_exists('dsm')) { - dsm($node, 'action_example_node_sticky_action is firing. Here is the $node'); - dsm($context, 'action_example_node_sticky_action is firing. Here is the $context'); - } - // Get the user configured for this special action. - $account = user_load_by_name($context['author']); - // Is the node created by this user? then promote and set as sticky. - if ($account->uid == $node->uid) { - $node->promote = NODE_PROMOTED; - $node->sticky = NODE_STICKY; - watchdog('action', 'Set @type %title to sticky and promoted by special action for user %username.', array('@type' => node_type_get_name($node), '%title' => $node->title, '%username' => $account->name)); - drupal_set_message(t('Set @type %title to sticky and promoted by special action for user %username.', array('@type' => node_type_get_name($node), '%title' => $node->title, '%username' => $account->name))); - } -} diff --git a/action_example/action_example.test b/action_example/action_example.test deleted file mode 100644 index 875f003a588b31f1b1cca92e9536766d8c0586f0..0000000000000000000000000000000000000000 --- a/action_example/action_example.test +++ /dev/null @@ -1,83 +0,0 @@ - 'Action example', - 'description' => 'Perform various tests on action_example module.' , - 'group' => 'Examples', - ); - } - - function setUp() { - parent::setUp('trigger', 'action_example'); - } - - /** - * Test Action Example. - * - * 1. action_example_basic_action: Configure a action_example_basic_action to - * happen when user logs in. - * 2. action_example_unblock_user_action: When a user's profile is being - * viewed, unblock that user. - * 3. action_example_node_sticky_action: Create a user, configure that user - * to always be stickied using advanced configuration. Have the user - * create content; verify that it gets stickied. - */ - function testActionExample() { - // Create an administrative user. - $admin_user = $this->drupalCreateUser(array('administer actions', 'access comments', 'access content', 'post comments', 'skip comment approval', 'create article content', 'access user profiles', 'administer users')); - $this->drupalLogin($admin_user); - - // 1. Assign basic action; then logout and login user and see if it puts - // the message on the screen. - $hash = drupal_hash_base64('action_example_basic_action'); - $edit = array('aid' => $hash); - $this->drupalPost('admin/structure/trigger/user', $edit, t('Assign'), array(), array(), 'trigger-user-login-assign-form'); - - $this->drupalLogout(); - $this->drupalLogin($admin_user); - $this->assertText(t('action_example_basic_action fired')); - - // 2. Unblock: When a user's profile is being viewed, unblock. - $normal_user = $this->drupalCreateUser(); - user_save($normal_user, array('status' => 0)); // Blocked user. - $normal_user = user_load($normal_user->uid, TRUE); - $this->assertFalse($normal_user->status, t('Normal user status has been set to blocked')); - - $hash = drupal_hash_base64('action_example_unblock_user_action'); - $edit = array('aid' => $hash); - $this->drupalPost('admin/structure/trigger/user', $edit, t('Assign'), array(), array(), 'trigger-user-view-assign-form'); - - $this->drupalGet("user/$normal_user->uid"); - $normal_user = user_load($normal_user->uid, TRUE); - $this->assertTrue($normal_user->status, t('Normal user status has been set to unblocked')); - $this->assertRaw(t('Unblocked user %name', array('%name' => $normal_user->name))); - - // 3. Create a user whose posts are always to be stickied. - $sticky_user = $this->drupalCreateUser(array('access comments', 'access content', 'post comments', 'skip comment approval', 'create article content')); - - $action_label = $this->randomName(); - $edit = array( - 'actions_label' => $action_label, - 'author' => $sticky_user -> name, - ); - $aid = $this->configureAdvancedAction('action_example_node_sticky_action', $edit); - $edit = array('aid' => drupal_hash_base64($aid)); - $this->drupalPost('admin/structure/trigger/node', $edit, t('Assign'), array(), array(), 'trigger-node-insert-assign-form'); - // Now create a node and verify that it gets stickied. - $this->drupalLogout(); - $this->drupalLogin($sticky_user); - $node = $this->drupalCreateNode(); - $this->assertTrue($node->sticky, t('Node was set to sticky on creation')); - } -} diff --git a/ajax_example/ajax_example.css b/ajax_example/ajax_example.css deleted file mode 100644 index 5de6e70e68eac719249f232b60f7edec2ad52c23..0000000000000000000000000000000000000000 --- a/ajax_example/ajax_example.css +++ /dev/null @@ -1,20 +0,0 @@ - -/* - * @file ajax_example.css - * CSS for ajax_example. - * - * See @link ajax_example_dependent_dropdown_degrades @endlink for - * details on what this file does. It is not used in any other example. - */ - -/* hide the next button when not degrading to non-javascript browser */ -html.js .next-button { - display: none; -} - -/* Make the next/choose button align to the right of the select control */ -.form-item-dropdown-first, .form-item-question-type-select { - display: inline-block; -} - - diff --git a/ajax_example/ajax_example.info b/ajax_example/ajax_example.info deleted file mode 100644 index 359fe946b8c2556f37add24c9e13996d45db0d6b..0000000000000000000000000000000000000000 --- a/ajax_example/ajax_example.info +++ /dev/null @@ -1,5 +0,0 @@ - -name = AJAX Example -description = An example module showing how to use Drupal AJAX forms -core = 7.x -package = Example modules diff --git a/ajax_example/ajax_example.js b/ajax_example/ajax_example.js deleted file mode 100644 index ce5b88a1b18d2e9a5149335bbbefd8287dfa817e..0000000000000000000000000000000000000000 --- a/ajax_example/ajax_example.js +++ /dev/null @@ -1,31 +0,0 @@ - -/* - * @file ajax_example.js - * JavaScript for ajax_example. - * - * See @link ajax_example_dependent_dropdown_degrades @endlink for - * details on what this file does. It is not used in any other example. - * - */ - -(function($) { - - // Re-enable form elements that are disabled for non-ajax situations. - Drupal.behaviors.enableFormItemsForAjaxForms = { - attach: function() { - // If ajax is enabled. - if (Drupal.ajax) { - $('.enabled-for-ajax').removeAttr('disabled'); - } - - // Below is only for the demo case of showing with js turned off. - // It overrides the behavior of the CSS that would normally turn off - // the 'ok' button when JS is enabled. Here, for demonstration purposes, - // we have AJAX disabled but JS turned on, so use this to simulate. - if (!Drupal.ajax) { - $('html.js .next-button').show(); - } - } - }; - -})(jQuery); diff --git a/ajax_example/ajax_example.module b/ajax_example/ajax_example.module deleted file mode 100644 index 0b29ad093c5ec88acb323143f4e26e1eda7d907a..0000000000000000000000000000000000000000 --- a/ajax_example/ajax_example.module +++ /dev/null @@ -1,549 +0,0 @@ - 'AJAX Example', - 'page callback' => 'ajax_example_intro', - 'access callback' => TRUE, - 'expanded' => TRUE, - ); - - // Change the description of a form element. - $items['examples/ajax_example/simplest'] = array( - 'title' => 'Simplest AJAX Example', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_simplest'), - 'access callback' => TRUE, - 'weight' => 0, - ); - // Generate a changing number of checkboxes. - $items['examples/ajax_example/autocheckboxes'] = array( - 'title' => 'Generate checkboxes', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_autocheckboxes'), - 'access callback' => TRUE, - 'weight' => 1, - ); - // Generate different textfields based on form state. - $items['examples/ajax_example/autotextfields'] = array( - 'title' => 'Generate textfields', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_autotextfields'), - 'access callback' => TRUE, - 'weight' => 2, - ); - - // Submit a form without a page reload. - $items['examples/ajax_example/submit_driven_ajax'] = array( - 'title' => 'Submit-driven AJAX', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_submit_driven_ajax'), - 'access callback' => TRUE, - 'weight' => 3, - ); - - // Repopulate a dropdown based on form state. - $items['examples/ajax_example/dependent_dropdown'] = array( - 'title' => 'Dependent dropdown', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_dependent_dropdown'), - 'access callback' => TRUE, - 'weight' => 4, - ); - // Repopulate a dropdown, but this time with graceful degredation. - // See ajax_example_graceful_degradation.inc. - $items['examples/ajax_example/dependent_dropdown_degrades'] = array( - 'title' => 'Dependent dropdown (with graceful degradation)', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_dependent_dropdown_degrades'), - 'access callback' => TRUE, - 'weight' => 5, - 'file' => 'ajax_example_graceful_degradation.inc', - ); - // The above example as it appears to users with no javascript. - $items['examples/ajax_example/dependent_dropdown_degrades_no_js'] = array( - 'title' => 'Dependent dropdown with javascript off', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_dependent_dropdown_degrades', TRUE), - 'access callback' => TRUE, - 'file' => 'ajax_example_graceful_degradation.inc', - 'weight' => 5, - ); - - // Populate a form section based on input in another element. - $items['examples/ajax_example/dynamic_sections'] = array( - 'title' => 'Dynamic Sections (with graceful degradation)', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_dynamic_sections'), - 'access callback' => TRUE, - 'weight' => 6, - 'file' => 'ajax_example_graceful_degradation.inc', - ); - // The above example as it appears to users with no javascript. - $items['ajax_example/dynamic_sections_no_js'] = array( - 'title' => 'Dynamic Sections w/JS turned off', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_dynamic_sections', TRUE), - 'access callback' => TRUE, - 'weight' => 6, - 'file' => 'ajax_example_graceful_degradation.inc', - ); - - // A classic multi-step wizard, but with no page reloads. - // See ajax_example_graceful_degradation.inc. - $items['examples/ajax_example/wizard'] = array( - 'title' => 'Wizard (with graceful degradation)', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_wizard'), - 'access callback' => TRUE, - 'file' => 'ajax_example_graceful_degradation.inc', - 'weight' => 7, - ); - // The above example as it appears to users with no javascript. - $items['examples/ajax_example/wizard_no_js'] = array( - 'title' => 'Wizard w/JS turned off', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_wizard', TRUE), - 'access callback' => TRUE, - 'file' => 'ajax_example_graceful_degradation.inc', - 'weight' => 7, - ); - - // Add-more button that creates additional form elements. - // See ajax_example_graceful_degradation.inc. - $items['examples/ajax_example/add_more'] = array( - 'title' => 'Add-more button (with graceful degradation)', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_add_more'), - 'access callback' => TRUE, - 'file' => 'ajax_example_graceful_degradation.inc', - 'weight' => 8, - ); - // The above example as it appears to users with no javascript. - $items['examples/ajax_example/add_more_no_js'] = array( - 'title' => 'Add-more button w/JS turned off', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_add_more', TRUE), - 'access callback' => TRUE, - 'file' => 'ajax_example_graceful_degradation.inc', - 'weight' => 8, - ); - - // Use the AJAX framework outside the context of a form using the use-ajax - // class. See ajax_example_misc.inc. - $items['examples/ajax_example/ajax_link'] = array( - 'title' => 'Ajax Link ("use-ajax" class)', - 'page callback' => 'ajax_example_render_link', - 'access callback' => TRUE, - 'file' => 'ajax_example_misc.inc', - 'weight' => 9, - ); - // Use the AJAX framework outside the context of a form using a renderable - // array of type link with the #ajax property. See ajax_example_misc.inc. - $items['examples/ajax_example/ajax_link_renderable'] = array( - 'title' => 'Ajax Link (Renderable Array)', - 'page callback' => 'ajax_example_render_link_ra', - 'access callback' => TRUE, - 'file' => 'ajax_example_misc.inc', - 'weight' => 9, - ); - // A menu callback is required when using ajax outside of the Form API. - $items['ajax_link_callback'] = array( - 'page callback' => 'ajax_link_response', - 'access callback' => 'user_access', - 'access arguments' => array('access content'), - 'type' => MENU_CALLBACK, - 'file' => 'ajax_example_misc.inc', - ); - - // Use AJAX framework commands outside of the #ajax form property. - // See ajax_example_advanced.inc. - $items['examples/ajax_example/advanced_commands'] = array( - 'title' => 'AJAX framework commands', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ajax_example_advanced_commands'), - 'access callback' => TRUE, - 'file' => 'ajax_example_advanced.inc', - 'weight' => 10, - ); - - return $items; -} - -function ajax_example_intro() { - $markup = t('The AJAX example module provides many examples of AJAX including forms, links, and AJAX commands.'); - return $markup; -} - -/** - * @ingroup ajax_examples - * @{ - */ - -/** - * Simple form whose ajax-enabled 'changethis' member causes a text change - * in the description of the 'replace_textfield' member. - * See @link http://drupal.org/node/262422 Form API Tutorial @endlink - */ -function ajax_example_simplest($form, &$form_state) { - $form = array(); - $form['changethis'] = array( - '#title' => t("Choose something and explain why"), - '#type' => 'select', - '#options' => array( - 'one' => 'one', - 'two' => 'two', - 'three' => 'three', - ), - '#ajax' => array( - // #ajax has two required keys: callback and wrapper. - // 'callback' is a function that will be called when this element changes. - 'callback' => 'ajax_example_simplest_callback', - // 'wrapper' is the HTML id of the page element that will be replaced. - 'wrapper' => 'replace_textfield_div', - // There are also several optional keys - see ajax_example_autocheckboxes - // below for details on 'method', 'effect' and 'speed' and - // ajax_example_dependent_dropdown for 'event'. - ), - ); - - // This entire form element will be replaced whenever 'changethis' is updated. - $form['replace_textfield'] = array( - '#type' => 'textfield', - '#title' => t("Why"), - // The prefix/suffix provide the div that we're replacing, named by - // #ajax['wrapper'] above. - '#prefix' => '
', - '#suffix' => '
', - ); - - // An AJAX request calls the form builder function for every change. - // We can change how we build the form based on $form_state. - if (!empty($form_state['values']['changethis'])) { - $form['replace_textfield']['#description'] = t("Say why you chose") . " '{$form_state['values']['changethis']}'"; - } - return $form; -} - -/** - * Callback for ajax_example_simplest. - * - * On an ajax submit, the form builder function is called again, then the $form - * and $form_state are passed to this callback function so it can select which - * portion of the form to send on to the client. - * - * @return renderable array (the textfield element) - */ -function ajax_example_simplest_callback($form, $form_state) { - // The form has already been submitted and updated. We can return the replaced - // item as it is. - return $form['replace_textfield']; -} - -/** - * AJAX-enabled select element causes replacement of a set of checkboxes - * based on the selection. - */ -function ajax_example_autocheckboxes($form, &$form_state) { - // Since the form builder is called after every AJAX request, we rebuild - // the form based on $form_state. - $num_checkboxes = !empty($form_state['values']['howmany_select']) ? $form_state['values']['howmany_select'] : 1; - - $form['howmany_select'] = array( - '#title' => t('How many checkboxes do you want?'), - '#type' => 'select', - '#options' => array(1 => 1, 2 => 2, 3 => 3, 4 => 4), - '#default_value' => $num_checkboxes, - '#ajax' => array( - 'callback' => 'ajax_example_autocheckboxes_callback', - 'wrapper' => 'checkboxes-div', - //'method' defaults to replaceWith, but valid values also include - // append, prepend, before and after. - // 'method' => 'replaceWith', - // 'effect' defaults to none. Other valid values are 'fade' and 'slide'. - // See ajax_example_autotextfields for an example of 'fade'. - 'effect' => 'slide', - // 'speed' defaults to 'slow'. You can also use 'fast' - // or a number of milliseconds for the animation to last. - // 'speed' => 'slow', - // Don't show any throbber... - 'progress' => array('type' => 'none'), - ), - ); - - - $form['checkboxes_fieldset'] = array( - '#title' => t("Generated Checkboxes"), - // The prefix/suffix provide the div that we're replacing, named by - // #ajax['wrapper'] above. - '#prefix' => '
', - '#suffix' => '
', - '#type' => 'fieldset', - '#description' => t('This is where we get automatically generated checkboxes'), - ); - - for ($i = 1; $i <= $num_checkboxes; $i++) { - $form['checkboxes_fieldset']["checkbox$i"] = array( - '#type' => 'checkbox', - '#title' => "Checkbox $i", - ); - } - - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Submit'), - ); - - return $form; -} - -/** - * Callback element needs only select the portion of the form to be updated. - * Since #ajax['callback'] return can be HTML or a renderable array (or an - * array of commands), we can just return a piece of the form. - * See @link ajax_example_advanced.inc AJAX Advanced Commands for more details - * on AJAX framework commands. - * - * @return renderable array (the checkboxes fieldset) - */ -function ajax_example_autocheckboxes_callback($form, $form_state) { - return $form['checkboxes_fieldset']; -} - - -/** - * Show/hide textfields based on AJAX-enabled checkbox clicks. - */ -function ajax_example_autotextfields($form, &$form_state) { - - $form['ask_first_name'] = array( - '#type' => 'checkbox', - '#title' => t('Ask me my first name'), - '#ajax' => array( - 'callback' => 'ajax_example_autotextfields_callback', - 'wrapper' => 'textfields', - 'effect' => 'fade', - ) - ); - $form['ask_last_name'] = array( - '#type' => 'checkbox', - '#title' => t('Ask me my last name'), - '#ajax' => array( - 'callback' => 'ajax_example_autotextfields_callback', - 'wrapper' => 'textfields', - 'effect' => 'fade', - ), - ); - - $form['textfields'] = array( - '#title' => t("Generated text fields for first and last name"), - '#prefix' => '
', - '#suffix' => '
', - '#type' => 'fieldset', - '#description' => t('This is where we put automatically generated textfields'), - ); - - // Since checkboxes return TRUE or FALSE, we have to check that - // $form_state has been filled as well as what it contains. - if (!empty($form_state['values']['ask_first_name']) && $form_state['values']['ask_first_name']) { - $form['textfields']['first_name'] = array( - '#type' => 'textfield', - '#title' => t('First Name'), - ); - } - if (!empty($form_state['values']['ask_last_name']) && $form_state['values']['ask_last_name']) { - $form['textfields']['last_name'] = array( - '#type' => 'textfield', - '#title' => t('Last Name'), - ); - } - - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Click Me'), - ); - - return $form; -} - -/** - * Selects the piece of the form we want to use as replacement text and returns - * it as a form (renderable array). - * - * @return renderable array (the textfields element) - */ -function ajax_example_autotextfields_callback($form, $form_state) { - return $form['textfields']; -} - - -/** - * A very basic form which with an AJAX-enabled submit. - * - * On submit, the markup in the #markup element is updated. - */ -function ajax_example_submit_driven_ajax($form, &$form_state) { - $form['box'] = array( - '#type' => 'markup', - '#prefix' => '
', - '#suffix' => '
', - '#markup' => '

Initial markup for box

', - ); - - $form['submit'] = array( - '#type' => 'submit', - '#ajax' => array( - 'callback' => 'ajax_example_submit_driven_callback', - 'wrapper' => 'box', - 'name' => 'submit1', - ), - '#value' => t('Submit'), - ); - - return $form; -} - -/** - * Select the 'box' element, change the markup in it, and return it as a - * renderable array. - * - * @return renderable array (the box element) - */ -function ajax_example_submit_driven_callback($form, $form_state) { - // In most cases, it is recomended that you put this logic in form generation - // rather than the callback. Submit driven forms are an exception, because - // you may not want to return the form at all. - $element = $form['box']; - $element['#markup'] = "Clicked submit ({$form_state['values']['op']}): " . date('c'); - return $element; -} - - -/** - * A form with a dropdown whose options are dependent on a - * choice made in a previous dropdown. - * - * On changing the first dropdown, the options in the second - * are updated. - */ -function ajax_example_dependent_dropdown($form, &$form_state) { - // Get the list of options to populate the first dropdown. - $options_first = _ajax_example_get_first_dropdown_options(); - // If we have a value for the first dropdown from $form_state['values'] we use - // this both as the default value for the first dropdown and also as a - // parameter to pass to the function that retrieves the options for the - // second dropdown. - $selected = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first); - - $form['dropdown_first'] = array( - '#type' => 'select', - '#title' => 'Instrument Type', - '#options' => $options_first, - '#default_value' => $selected, - // Bind an ajax callback to the change event (which is the default for the - // select form type) of the first dropdown. It will replace the second - // dropdown when rebuilt - '#ajax' => array( - // When 'event' occurs, Drupal will perform an ajax request in the - // background. Usually the default value is sufficient (eg. change for - // select elements), but valid values include any jQuery event, - // most notably 'mousedown', 'blur', and 'submit'. - // 'event' => 'change', - 'callback' => 'ajax_example_dependent_dropdown_callback', - 'wrapper' => 'dropdown-second-replace', - ), - ); - - $form['dropdown_second'] = array( - '#type' => 'select', - '#title' => $options_first[$selected] . ' ' . t('Instruments'), - // The entire enclosing div created here gets replaced when dropdown_first - // is changed. - '#prefix' => '', - // when the form is rebuilt during ajax processing, the $selected variable - // will now have the new value and so the options will change - '#options' => _ajax_example_get_second_dropdown_options($selected), - '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '', - ); - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Submit'), - ); - return $form; -} - -/** - * Selects just the second dropdown to be returned for re-rendering - * - * Since the controlling logic for populating the form is in the form builder - * function, all we do here is select the element and return it to be updated. - * - * @return renderable array (the second dropdown) - */ -function ajax_example_dependent_dropdown_callback($form, $form_state) { - return $form['dropdown_second']; -} - -/** - * Helper function to populate the first dropdown. This would normally be - * pulling data from the database. - * - * @return array of options - */ -function _ajax_example_get_first_dropdown_options() { - // drupal_map_assoc() just makes an array('String' => 'String'...). - return drupal_map_assoc(array(t('String'), t('Woodwind'), t('Brass'), t('Percussion'))); -} - -/** - * Helper function to populate the second dropdown. This would normally be - * pulling data from the database. - * - * @param key. This will determine which set of options is returned. - * - * @return array of options - */ -function _ajax_example_get_second_dropdown_options($key = '') { - $options = array( - t('String') => drupal_map_assoc(array(t('Violin'), t('Viola'), t('Cello'), t('Double Bass'))), - t('Woodwind') => drupal_map_assoc(array(t('Flute'), t('Clarinet'), t('Oboe'), t('Bassoon'))), - t('Brass') => drupal_map_assoc(array(t('Trumpet'), t('Trombone'), t('French Horn'), t('Euphonium'))), - t('Percussion') => drupal_map_assoc(array(t('Bass Drum'), t('Timpani'), t('Snare Drum'), t('Tambourine'))), - ); - if (isset($options[$key])) { - return $options[$key]; - } - else { - return array(); - } -} - diff --git a/ajax_example/ajax_example_advanced.inc b/ajax_example/ajax_example_advanced.inc deleted file mode 100644 index 8b12c711237ad910a0d92a5254050c015a78cebd..0000000000000000000000000000000000000000 --- a/ajax_example/ajax_example_advanced.inc +++ /dev/null @@ -1,388 +0,0 @@ - 'markup', - '#markup' => t("
Demonstrates how AJAX commands can be used.
"), - ); - - // Shows the 'after' command with a callback generating commands. - $form['after_command_example_fieldset'] = array( - '#type' => 'fieldset', - '#title' => t("This shows the Ajax 'after' command. Click to put something below the div that says 'Something can be inserted after this'") - ); - - $form['after_command_example_fieldset']['after_command_example'] = array( - '#value' => t("AJAX 'After': Click to put something after the div"), - '#type' => 'submit', - '#ajax' => array( - 'callback' => 'ajax_example_advanced_commands_after_callback', - ), - '#suffix' => "
Something can be inserted after this
-
'After' Command Status: Unknown
", - ); - - // Shows the 'alert' command. - $form['alert_command_example_fieldset'] = array( - '#type' => 'fieldset', - '#title' => t("Demonstrates the AJAX 'alert' command. Click the button."), - ); - $form['alert_command_example_fieldset']['alert_command_example'] = array( - '#value' => t("AJAX 'Alert': Click to alert"), - '#type' => 'submit', - '#ajax' => array( - 'callback' => 'ajax_example_advanced_commands_alert_callback', - ), - ); - - // Shows the 'append' command. - $form['append_command_example_fieldset'] = array( - '#type' => 'fieldset', - '#title' => t("This shows the Ajax 'append' command. Click to put something below the div that says 'Something can be inserted after this'") - ); - - $form['append_command_example_fieldset']['append_command_example'] = array( - '#value' => t("AJAX 'Append': Click to append something"), - '#type' => 'submit', - '#ajax' => array( - 'callback' => 'ajax_example_advanced_commands_append_callback', - ), - '#suffix' => "
Something can be appended inside this div...
-
'After' Command Status: Unknown
" - ); - - - // Shows the 'before' command. - $form['before_command_example_fieldset'] = array( - '#type' => 'fieldset', - '#title' => t("This shows the Ajax 'before' command.") - ); - - $form['before_command_example_fieldset']['before_command_example'] = array( - '#value' => t("AJAX 'before': Click to put something before the div"), - '#type' => 'submit', - '#ajax' => array( - 'callback' => 'ajax_example_advanced_commands_before_callback', - ), - '#suffix' => "
Something can be inserted before this
-
'before' Command Status: Unknown
" - ); - - // Shows the 'changed' command. - $form['changed_command_example_fieldset'] = array( - '#type' => 'fieldset', - '#title' => t("Demonstrates the AJAX 'changed' command. If region is 'changed', it is marked with CSS. This example also puts an asterisk by changed content."), - ); - - $form['changed_command_example_fieldset']['changed_command_example'] = array( - '#title' => t("AJAX changed: If checked, div is marked as changed."), - '#type' => 'checkbox', - '#default_value' => FALSE, - '#ajax' => array( - 'callback' => 'ajax_example_advanced_commands_changed_callback', - ), - '#suffix' => "
This div can be marked as changed or not.
-
Status: Unknown
" - ); - - // Shows the AJAX 'css' command. - $form['css_command_example_fieldset'] = array( - '#type' => 'fieldset', - '#title' => t("Demonstrates the AJAX 'css' command."), - ); - - $form['css_command_example_fieldset']['css_command_example'] = array( - '#title' => t("AJAX CSS: Choose the color you'd like the '#box' div to be."), - '#type' => 'select', - // '#default_value' => 'green', - '#options' => array('green' => 'green', 'blue' => 'blue'), - '#ajax' => array( - 'callback' => 'ajax_example_advanced_commands_css_callback', - ), - '#suffix' => "
box
-
Status: Unknown
" - ); - - // Shows the AJAX 'data' command. But there is no use of this information, - // as this would require a javascript client to use the data. - $form['data_command_example_fieldset'] = array( - '#type' => 'fieldset', - '#title' => t("Demonstrates the AJAX 'data' command."), - ); - - $form['data_command_example_fieldset']['data_command_example'] = array( - '#title' => t("AJAX data: Set a key/value pair on a selector."), - '#type' => 'textfield', - '#default_value' => 'color=green', - '#ajax' => array( - 'callback' => 'ajax_example_advanced_commands_data_callback', - ), - '#suffix' => "
This div should have key='time'/value='a time string' attached.
-
Status: Unknown
" - ); - - // Shows the AJAX 'html' command. - $form['html_command_example_fieldset'] = array( - '#type' => 'fieldset', - '#title' => t("Demonstrates the AJAX 'html' command."), - ); - - $form['html_command_example_fieldset']['html_command_example'] = array( - '#title' => t("AJAX html: Replace the HTML in a selector."), - '#type' => 'textfield', - '#default_value' => 'new value', - '#ajax' => array( - 'callback' => 'ajax_example_advanced_commands_html_callback', - ), - '#suffix' => "
Original contents
-
Status: Unknown
" - ); - - // Shows the AJAX 'prepend' command. - $form['prepend_command_example_fieldset'] = array( - '#type' => 'fieldset', - '#title' => t("This shows the AJAX 'prepend' command. Click to put something below the div that says 'Something can be inserted after this'") - ); - - $form['prepend_command_example_fieldset']['prepend_command_example'] = array( - '#value' => t("AJAX 'prepend': Click to prepend something"), - '#type' => 'submit', - '#ajax' => array( - 'callback' => 'ajax_example_advanced_commands_prepend_callback', - ), - '#suffix' => "
Something can be prepended to this div...
-
'After' Command Status: Unknown
" - ); - - // Shows the AJAX 'remove' command. - $form['remove_command_example_fieldset'] = array( - '#type' => 'fieldset', - '#title' => t("Shows the Ajax 'remove' command.") - ); - - $form['remove_command_example_fieldset']['remove_command_example'] = array( - '#title' => t("AJAX 'remove': Check to remove text. Uncheck to add it back."), - '#type' => 'checkbox', - '#default_value' => FALSE, - '#ajax' => array( - 'callback' => 'ajax_example_advanced_commands_remove_callback', - ), - '#suffix' => "
text to be removed
-
'After' Command Status: Unknown
" - ); - - // Show off the AJAX 'restripe' command. Also shows classic AJAX replacement - // on the "how many rows" processing. - $form['restripe_command_example_fieldset'] = array( - '#type' => 'fieldset', - '#title' => t("Demonstrates the Ajax 'restripe' command.") - ); - - $form['restripe_command_example_fieldset']['restripe_num_rows'] = array( - '#type' => 'select', - '#default_value' => !empty($form_state['values']['restripe_num_rows']) ? $form_state['values']['restripe_num_rows'] : 1, - '#options' => drupal_map_assoc(array(1,2,3,4,5,6,7,8,9,10)), - '#ajax' => array( - 'callback' => 'ajax_example_advanced_commands_restripe_num_rows', - 'method' => 'replace', - 'wrapper' => 'restripe_table', - ), - ); - $form['restripe_command_example_fieldset']['restripe_restripe'] = array( - '#type' => 'submit', - '#value' => t("Restripe the table"), - '#ajax' => array( - 'callback' => 'ajax_example_advanced_commands_restripe_callback', - ), - '#suffix' => "
- - -
first row
-
-
'Restripe' Command Status: Unknown
", - - ); - - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Submit'), - ); - - return $form; -} - -/** - * 'after' callback. - * @see ajax_command_after() - */ -function ajax_example_advanced_commands_after_callback($form, $form_state) { - $selector = '#after_div'; - - $commands = array(); - $commands[] = ajax_command_after($selector, "New 'after'..."); - $commands[] = ajax_command_replace("#after_status", "
Updated after_command_example " . date('r') . "
"); - return array('#type' => 'ajax', '#commands' => $commands); -} - -/** - * 'alert' callback. - * @see ajax_command_alert() - */ -function ajax_example_advanced_commands_alert_callback($form, $form_state) { - $commands = array(); - $commands[] = ajax_command_alert("Alert requested at " . date('r')); - return array('#type' => 'ajax', '#commands' => $commands); -} - -/** - * 'append' callback. - * @see ajax_command_append() - */ -function ajax_example_advanced_commands_append_callback($form, $form_state) { - $selector = '#append_div'; - - $commands = array(); - $commands[] = ajax_command_append($selector, "Stuff..."); - $commands[] = ajax_command_replace("#append_status", "
Updated append_command_example " . date('r') . "
"); - return array('#type' => 'ajax', '#commands' => $commands); -} - -/** - * 'before' callback. - * @see ajax_command_before() - */ -function ajax_example_advanced_commands_before_callback($form, $form_state) { - $selector = '#before_div'; - - $commands = array(); - $commands[] = ajax_command_before($selector, "New 'before'..."); - $commands[] = ajax_command_replace("#before_status", "
Updated before_command_example " . date('r') . "
"); - return array('#type' => 'ajax', '#commands' => $commands); -} - -/** - * 'changed' callback. - * @see ajax_command_changed() - */ -function ajax_example_advanced_commands_changed_callback($form, $form_state) { - $checkbox_value = $form_state['values']['changed_command_example']; - $checkbox_value_string = $checkbox_value ? "TRUE" : "FALSE"; - $commands = array(); - if ($checkbox_value) { - $commands[] = ajax_command_changed( '#changed_div', '#changed_div_mark_this'); - } else { - $commands[] = ajax_command_replace('#changed_div', "
This div can be marked as changed or not.
"); - } - $commands[] = ajax_command_replace("#changed_status", "
Updated changed_command_example to $checkbox_value_string: " . date('r') . "
"); - return array('#type' => 'ajax', '#commands' => $commands); -} - -/** - * 'css' callback. - * @see ajax_command_css() - */ -function ajax_example_advanced_commands_css_callback($form, $form_state) { - $selector = '#css_div'; - $color = $form_state['values']['css_command_example']; - - $commands = array(); - $commands[] = ajax_command_css($selector, array('background-color' => $color)); - $commands[] = ajax_command_replace("#css_status", "
Updated css_command_example to '{$color}' " . date('r') . "
"); - return array('#type' => 'ajax', '#commands' => $commands); -} - -/** - * 'data' callback. - * @see ajax_command_data() - */ -function ajax_example_advanced_commands_data_callback($form, $form_state) { - $selector = '#data_div'; - $text = $form_state['values']['data_command_example']; - list($key, $value) = preg_split('/=/', $text); - - $commands = array(); - $commands[] = ajax_command_data($selector, $key, $value); - $commands[] = ajax_command_replace("#data_status", "
Updated data_command_example with key=$key, value=$value; " . date('r') . "
"); - return array('#type' => 'ajax', '#commands' => $commands); -} - -/** - * 'html' callback. - * @see ajax_command_html() - */ -function ajax_example_advanced_commands_html_callback($form, $form_state) { - $text = $form_state['values']['html_command_example']; - - $commands = array(); - $commands[] = ajax_command_html('#html_div', $text); - $commands[] = ajax_command_replace("#html_status", "
Updated html_command_example with text=$text; " . date('r') . "
"); - return array('#type' => 'ajax', '#commands' => $commands); -} - -/** - * 'prepend' callback. - * @see ajax_command_prepend() - */ -function ajax_example_advanced_commands_prepend_callback($form, $form_state) { - $commands = array(); - $commands[] = ajax_command_prepend('#prepend_div', "Prepended Stuff..."); - $commands[] = ajax_command_replace("#prepend_status", "
Updated prepend_command_example " . date('r') . "
"); - return array('#type' => 'ajax', '#commands' => $commands); -} - -/** - * 'remove' callback. - * @see ajax_command_remove() - */ -function ajax_example_advanced_commands_remove_callback($form, $form_state) { - $commands = array(); - $should_remove = $form_state['values']['remove_command_example']; - $should_remove_string = $should_remove ? 'TRUE' : 'FALSE'; - if ($should_remove) { - $commands[] = ajax_command_remove('#remove_text'); - } else { - $commands[] = ajax_command_html('#remove_div', "
text to be removed
"); - } - $commands[] = ajax_command_replace("#remove_status", "
Updated remove_command_example (value={$should_remove_string} " . date('r') . "
"); - return array('#type' => 'ajax', '#commands' => $commands); -} - -/** - * 'restripe' rows callback. - * Rebuilds the table with the selected number of rows. - */ -function ajax_example_advanced_commands_restripe_num_rows($form, $form_state) { - $num_rows = $form_state['values']['restripe_num_rows']; - $output = ""; - for ($i=1; $i<=$num_rows; $i++) { - $output .= ""; - } - $output .= "
Row $i
"; - return $output; -} - -/** - * 'restripe' callback. - * @see ajax_command_restripe() - */ -function ajax_example_advanced_commands_restripe_callback($form, $form_state) { - $commands = array(); - $commands[] = ajax_command_restripe('#restripe_table'); - $commands[] = ajax_command_replace("#restripe_status", "
Restriped table " . date('r') . "
"); - return array('#type' => 'ajax', '#commands' => $commands); -} diff --git a/ajax_example/ajax_example_graceful_degradation.inc b/ajax_example/ajax_example_graceful_degradation.inc deleted file mode 100644 index 6bc0f19d6203bbbe04486fb45d12d35ca32fa15b..0000000000000000000000000000000000000000 --- a/ajax_example/ajax_example_graceful_degradation.inc +++ /dev/null @@ -1,640 +0,0 @@ - 'fieldset', - ); - $form['dropdown_first_fieldset']['dropdown_first'] = array( - '#type' => 'select', - '#title' => 'Instrument Type', - '#options' => $options_first, - '#attributes' => array('class' => array('enabled-for-ajax')), - - // The '#ajax' property allows us to bind a callback to the server whenever this - // form element changes. See ajax_example_autocheckboxes and - // ajax_example_dependent_dropdown in ajax_example.module for more details. - '#ajax' => array( - 'callback' => 'ajax_example_dependent_dropdown_degrades_first_callback', - 'wrapper' => 'dropdown-second-replace', - ), - ); - - // This simply allows us to demonstrate no-javascript use without - // actually turning off javascript in the browser. Removing the #ajax - // element turns off AJAX behaviors on that element and as a result - // ajax.js doesn't get loaded. This is for demonstration purposes only. - if ($no_js_use) { - unset($form['dropdown_first_fieldset']['dropdown_first']['#ajax']); - } - - // Since we don't know if the user has js or not, we always need to output - // this element, then hide it with with css if javascript is enabled. - $form['dropdown_first_fieldset']['continue_to_second'] = array( - '#type' => 'submit', - '#value' => t('Choose'), - '#attributes' => array('class' => array('next-button')), - ); - - $form['dropdown_second_fieldset'] = array( - '#type' => 'fieldset', - ); - $form['dropdown_second_fieldset']['dropdown_second'] = array( - '#type' => 'select', - '#title' => $options_first[$selected] . ' ' . t('Instruments'), - '#prefix' => '', - '#attributes' => array('class' => array('enabled-for-ajax')), - // When the form is rebuilt during processing (either AJAX or multistep), - // the $selected variable will now have the new value and so the options - // will change. - '#options' => _ajax_example_get_second_dropdown_options($selected), - ); - $form['dropdown_second_fieldset']['submit'] = array( - '#type' => 'submit', - '#value' => t('OK'), - // This class allows attached js file to override the disabled attribute, - // since it's not necessary in ajax-enabled form. - '#attributes' => array('class' => array('enabled-for-ajax')), - ); - - // Disable dropdown_second if a selection has not been made on dropdown_first. - if (empty($form_state['values']['dropdown_first'])) { - $form['dropdown_second_fieldset']['dropdown_second']['#disabled'] = TRUE; - $form['dropdown_second_fieldset']['dropdown_second']['#description'] = t('You must make your choice on the first dropdown before changing this second one.'); - $form['dropdown_second_fieldset']['submit']['#disabled'] = TRUE; - } - - return $form; -} - -/** - * Submit function for ajax_example_dependent_dropdown_degrades(). - */ -function ajax_example_dependent_dropdown_degrades_submit($form, &$form_state) { - - // Now handle the case of the next, previous, and submit buttons. - // only submit will result in actual submission, all others rebuild. - switch($form_state['triggering_element']['#value']) { - case t('OK'): // Submit: We're done. - drupal_set_message(t('Your values have been submitted. dropdown_first=@first, dropdown_second=@second', array('@first' => $form_state['values']['dropdown_first'], '@second' => $form_state['values']['dropdown_second']))); - return; - } - // 'Choose' or anything else will cause rebuild of the form and present - // it again. - $form_state['rebuild'] = TRUE; -} - -/** - * Selects just the second dropdown to be returned for re-rendering - * - * @return renderable array (the second dropdown) - */ -function ajax_example_dependent_dropdown_degrades_first_callback($form, $form_state) { - return $form['dropdown_second_fieldset']['dropdown_second']; -} - - -/** - * Example of a form with portions dynamically enabled or disabled, but - * with graceful degradation in the case of no javascript. - * - * The idea here is that certain parts of the form don't need to be displayed - * unless a given option is selected, but then they should be displayed and - * configured. - * - * The third $no_js_use argument is strictly for demonstrating operation - * without javascript, without making the user/developer turn off javascript. - * - * @ingroup ajax_examples - * @ingroup ajax_degradation_examples - */ - -function ajax_example_dynamic_sections($form, &$form_state, $no_js_use = FALSE) { - - // Attach the CSS and JS we need to show this with and without javascript. - // Without javascript we need an extra "Choose" button, and this is - // hidden when we have javascript enabled. - $form['#attached']['css'] = array( - drupal_get_path('module', 'ajax_example') . '/ajax_example.css', - ); - $form['#attached']['js'] = array( - drupal_get_path('module', 'ajax_example') . '/ajax_example.js', - ); - $form['description'] = array( - '#type' => 'markup', - '#markup' => '
' . t('This example demonstrates a form which dynamically creates various sections based on the configuration in the form. - It deliberately allows graceful degradation to a non-javascript environment. - In a javascript environment, the "Choose" button next to the select control - if displayed; in a non-js environment it is hidden by the module CSS. -

The basic idea here is that the form is built up based on - the selection in the question_type_select field, and it is built the same - whether we are in a javascript/AJAX environment or not. -

- Try the AJAX version and the simulated-non-AJAX version. - ', array('!ajax_link' => url('ajax_example/dynamic_sections'), '!non_ajax_link' => url('ajax_example/dynamic_sections_no_js') )) . '
', - ); - $form['question_type_select'] = array( - '#type' => 'select', - '#title' => t('Question style'), - '#options' => drupal_map_assoc(array(t('Choose question style'), t('Multiple Choice'), t('True/False'), t('Fill-in-the-blanks'))), - '#ajax' => array( - 'wrapper' => 'questions-fieldset-wrapper', - 'callback' => 'ajax_example_dynamic_sections_select_callback', - ), - ); - // The CSS for this module hides this next button if JS is enabled. - $form['question_type_submit'] = array( - '#type' => 'submit', - '#value' => t('Choose'), - '#attributes' => array('class' => array('next-button')), - '#limit_validation_errors' => array(), // No need to validate when submitting this. - '#validate' => array(), - ); - - // This simply allows us to demonstrate no-javascript use without - // actually turning off javascript in the browser. Removing the #ajax - // element turns off AJAX behaviors on that element and as a result - // ajax.js doesn't get loaded. - if ($no_js_use) { - // Remove the #ajax from the above, so ajax.js won't be loaded. - unset($form['question_type_select']['#ajax']); - } - - // This fieldset just serves as a container for the part of the form - // that gets rebuilt. - $form['questions_fieldset'] = array( - '#type' => 'fieldset', - // These provide the wrapper referred to in #ajax['wrapper'] above. - '#prefix' => '
', - '#suffix' => '
', - ); - if (!empty($form_state['values']['question_type_select'])) { - - $form['questions_fieldset']['question'] = array( - '#markup' => t('Who was the first president of the U.S.?'), - ); - $question_type = $form_state['values']['question_type_select']; - - switch ($question_type) { - case t('Multiple Choice'): - $form['questions_fieldset']['question'] = array( - '#type' => 'radios', - '#title' => t('Who was the first president of the United States'), - '#options' => drupal_map_assoc(array(t('George Bush'), t('Adam McGuire'), t('Abraham Lincoln'), t('George Washington'))), - ); - break; - - case t('True/False'): - $form['questions_fieldset']['question'] = array( - '#type' => 'radios', - '#title' => t('Was George Washington the first president of the United States?'), - '#options' => array(t('George Washington') => t("True"), 0 => t("False")), - '#description' => t('Click "True" if you think George Washington was the first president of the United States.'), - ); - break; - - case t('Fill-in-the-blanks'): - $form['questions_fieldset']['question'] = array( - '#type' => 'textfield', - '#title' => t('Who was the first president of the United States'), - '#description' => t('Please type the correct answer to the question.'), - ); - break; - } - - $form['questions_fieldset']['submit'] = array( - '#type' => 'submit', - '#value' => t('Submit your answer'), - ); - } - return $form; -} - -/** - * Validation function for ajax_example_dynamic_sections(). - */ -function ajax_example_dynamic_sections_validate($form, &$form_state) { - $answer = $form_state['values']['question']; - if ($answer !== t('George Washington')) { - form_set_error('question', t('Wrong answer. Try again. (Hint: The right answer is "George Washington".)')); - } -} - -/** - * Submit function for ajax_example_dynamic_sections(). - */ -function ajax_example_dynamic_sections_submit($form, &$form_state) { - // This is only executed when a button is pressed, not when the AJAXified - // select is changed. - // Now handle the case of the next, previous, and submit buttons. - // Only submit will result in actual submission, all others rebuild. - switch($form_state['triggering_element']['#value']) { - case t('Submit your answer'): // Submit: We're done. - $form_state['rebuild'] = FALSE; - $answer = $form_state['values']['question']; - - // Special handling for the checkbox. - if ($answer == 1 && $form['questions_fieldset']['question']['#type'] == 'checkbox') { - $answer = $form['questions_fieldset']['question']['#title']; - } - if ($answer === t('George Washington')) { - drupal_set_message(t('You got the right answer: @answer', array('@answer' => $answer))); - } - else { - drupal_set_message(t('Sorry, your answer (@answer) is wrong', array('@answer' => $answer))); - } - $form_state['rebuild'] = FALSE; - return; - } - - // Any other form element will cause rebuild of the form and present - // it again. - $form_state['rebuild'] = TRUE; -} - -/** - * Callback for the select element. - * - * This just selects and returns the questions_fieldset. - */ -function ajax_example_dynamic_sections_select_callback($form, $form_state) { - return $form['questions_fieldset']; -} - - -/** - * This example is a classic wizard, where a different and sequential form - * is presented on each step of the form. - * - * In the AJAX version, the form is replaced for each wizard section. In the - * multistep version, it causes a new page load. - * - * @param $form - * @param $form_state - * @param $no_js_use - * Used for this demonstration only. If true means that the form should be - * built using a simulated no-javascript approach (ajax.js will not be - * loaded.) - * - * @ingroup ajax_examples - * @ingroup ajax_degradation_examples - * - */ -function ajax_example_wizard($form, &$form_state, $no_js_use = FALSE) { - - // Provide a wrapper around the entire form, since we'll replace the whole - // thing with each submit. - $form['#prefix'] = '
'; - $form['#suffix'] = '
'; - $form['#tree'] = TRUE; // We want to deal with hierarchical form values. - - $form['description'] = array( - '#markup' => '
' . t('This example is a step-by-step wizard. The AJAX version does it without page reloads; the multistep version is the same code but simulates a non-javascript environment, showing it with page reloads.', - array('!ajax' => url('ajax_example/wizard'), '!multistep' => url('ajax_example/wizard_no_js'))) - . '
', - ); - - // $form_state['storage'] has no specific drupal meaning, but it is - // traditional to keep variables for multistep forms there. - $step = empty($form_state['storage']['step']) ? 1 : $form_state['storage']['step']; - $form_state['storage']['step'] = $step; - - switch ($step) { - case 1: - $form['step1'] = array( - '#type' => 'fieldset', - '#title' => t('Step 1: Personal details'), - ); - $form['step1']['name'] = array( - '#type' => 'textfield', - '#title' => t('Your name'), - '#default_value' => empty($form_state['values']['step1']['name']) ? '' : $form_state['values']['step1']['name'], - '#required' => TRUE, - ); - break; - - case 2: - $form['step2'] = array( - '#type' => 'fieldset', - '#title' => t('Step 2: Street address info'), - ); - $form['step2']['address'] = array( - '#type' => 'textfield', - '#title' => t('Your street address'), - '#default_value' => empty($form_state['values']['step2']['address']) ? '' : $form_state['values']['step2']['address'], - '#required' => TRUE, - ); - break; - - case 3: - $form['step3'] = array( - '#type' => 'fieldset', - '#title' => t('Step 3: City info'), - ); - $form['step3']['city'] = array( - '#type' => 'textfield', - '#title' => t('Your city'), - '#default_value' => empty($form_state['values']['step3']['city']) ? '' : $form_state['values']['step3']['city'], - '#required' => TRUE, - ); - break; - } - if ($step == 3) { - $form['submit'] = array( - '#type' => 'submit', - '#value' => t("Submit your information"), - ); - } - if ($step < 3) { - $form['next'] = array( - '#type' => 'submit', - '#value' => t('Next step'), - '#ajax' => array( - 'wrapper' => 'wizard-form-wrapper', - 'callback' => 'ajax_example_wizard_callback', - ), - ); - } - if ($step > 1) { - $form['prev'] = array( - '#type' => 'submit', - '#value' => t("Previous step"), - - // Since all info will be discarded, don't validate on 'prev'. - '#limit_validation_errors' => array(), - // #submit is required to use #limit_validation_errors - '#submit' => array('ajax_example_wizard_submit'), - '#ajax' => array( - 'wrapper' => 'wizard-form-wrapper', - 'callback' => 'ajax_example_wizard_callback', - ), - ); - } - - // This simply allows us to demonstrate no-javascript use without - // actually turning off javascript in the browser. Removing the #ajax - // element turns off AJAX behaviors on that element and as a result - // ajax.js doesn't get loaded. - // For demonstration only! You don't need this. - if ($no_js_use) { - // Remove the #ajax from the above, so ajax.js won't be loaded. - // For demonstration only. - unset($form['next']['#ajax']); - unset($form['prev']['#ajax']); - } - - return $form; -} - -function ajax_example_wizard_callback($form, $form_state) { - return $form; -} - -/** - * Submit function for ajax_example_wizard. - * - * In AJAX this is only submitted when the final submit button is clicked, - * but in the non-javascript situation, it is submitted with every - * button click. - * - */ -function ajax_example_wizard_submit($form, &$form_state) { - - // Save away the current information. - $current_step = 'step' . $form_state['storage']['step']; - if (!empty($form_state['values'][$current_step])) { - $form_state['storage']['values'][$current_step] = $form_state['values'][$current_step]; - } - - // Increment or decrement the step as needed. Recover values if they exist. - if ($form_state['triggering_element']['#value'] == t('Next step')) { - $form_state['storage']['step']++; - // If values have already been entered for this step, recover them from - // $form_state['storage'] to pre-populate them. - $step_name = 'step' . $form_state['storage']['step']; - if (!empty($form_state['storage']['values'][$step_name])) { - $form_state['values'][$step_name] = $form_state['storage']['values'][$step_name]; - } - } - if ($form_state['triggering_element']['#value'] == t('Previous step')) { - $form_state['storage']['step']--; - // Recover our values from $form_state['storage'] to pre-populate them. - $step_name = 'step' . $form_state['storage']['step']; - $form_state['values'][$step_name] = $form_state['storage']['values'][$step_name]; - } - - // If they're done, submit. - if ($form_state['triggering_element']['#value'] == t('Submit your information')) { - $value_message = t("Your information has been submitted: "); - foreach ($form_state['storage']['values'] as $step => $values) { - $value_message .= "$step: "; - foreach ($values as $key => $value) { - $value_message .= "$key=$value, "; - } - } - drupal_set_message($value_message); - $form_state['rebuild'] = FALSE; - return; - } - - // Otherwise, we still have work to do. - $form_state['rebuild'] = TRUE; -} - - -/** - * This example shows a button to "add more" - add another textfield, and - * the corresponding "remove" button. - * - * It works equivalently with javascript or not, and does the same basic steps - * either way. - * - * The basic idea is that we build the form based on the setting of - * $form_state['num_names']. The custom submit functions for the "add-one" - * and "remove-one" buttons increment and decrement $form_state['num_names'] - * and then force a rebuild of the form. - * - * The $no_js_use argument is simply for demonstration: When set, it prevents - * '#ajax' from being set, thus making the example behave as if javascript - * were disabled in the browser. - * - * @ingroup ajax_examples - * @ingroup ajax_degradation_examples - */ - -function ajax_example_add_more($form, &$form_state, $no_js_use = FALSE) { - $form['description'] = array( - '#markup' => '
' . t('This example shows an add-more and a remove-last button. The AJAX version does it without page reloads; the non-js version is the same code but simulates a non-javascript environment, showing it with page reloads.', - array('!ajax' => url('examples/ajax_example/add_more'), '!multistep' => url('examples/ajax_example/add_more_no_js'))) - . '
', - ); - - // Because we have many fields with the same values, we have to set - // #tree to be able to access them. - $form['#tree'] = TRUE; - $form['names_fieldset'] = array( - '#type' => 'fieldset', - '#title' => t('People coming to the picnic'), - // Set up the wrapper so that AJAX will be able to replace the fieldset. - '#prefix' => '
', - '#suffix' => '
', - ); - - // Build the fieldset with the proper number of names. We'll use - // $form_state['num_names'] to determine the number of textfields to build. - if (empty($form_state['num_names'])) { - $form_state['num_names'] = 1; - } - for ($i = 0; $i < $form_state['num_names']; $i++) { - $form['names_fieldset']['name'][$i] = array( - '#type' => 'textfield', - '#title' => t('Name'), - ); - } - $form['names_fieldset']['add_name'] = array( - '#type' => 'submit', - '#value' => t('Add one more'), - '#submit' => array('ajax_example_add_more_add_one'), - // See the examples in ajax_example.module for more details on the - // properties of #ajax. - '#ajax' => array( - 'callback' => 'ajax_example_add_more_callback', - 'wrapper' => 'names-fieldset-wrapper', - ), - ); - if ($form_state['num_names'] > 1) { - $form['names_fieldset']['remove_name'] = array( - '#type' => 'submit', - '#value' => t('Remove one'), - '#submit' => array('ajax_example_add_more_remove_one'), - '#ajax' => array( - 'callback' => 'ajax_example_add_more_callback', - 'wrapper' => 'names-fieldset-wrapper', - ), - ); - } - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Submit'), - ); - - // This simply allows us to demonstrate no-javascript use without - // actually turning off javascript in the browser. Removing the #ajax - // element turns off AJAX behaviors on that element and as a result - // ajax.js doesn't get loaded. - // For demonstration only! You don't need this. - if ($no_js_use) { - // Remove the #ajax from the above, so ajax.js won't be loaded. - if (!empty($form['names_fieldset']['remove_name']['#ajax'])) { - unset($form['names_fieldset']['remove_name']['#ajax']); - } - unset($form['names_fieldset']['add_name']['#ajax']); - } - - return $form; -} - -/** - * Callback for both ajax-enabled buttons. - * - * This simply selects and returns the fieldset with the names in it. - */ -function ajax_example_add_more_callback($form, $form_state) { - return $form['names_fieldset']; -} - -/** - * Submit handler for the "add-one-more" button. - * - * It just increments the max counter and causes a rebuild. - */ -function ajax_example_add_more_add_one($form, &$form_state) { - $form_state['num_names']++; - $form_state['rebuild'] = TRUE; -} - -/** - * Submit handler for the "remove one" button. - * - * Decrements the max counter and causes a form rebuild. - */ -function ajax_example_add_more_remove_one($form, &$form_state) { - if ($form_state['num_names'] > 1) { - $form_state['num_names']--; - } - $form_state['rebuild'] = TRUE; -} - -/** - * Final submit handler. - * - * Reports what values were finally set. - */ -function ajax_example_add_more_submit($form, &$form_state) { - $output = t('These people are coming to the picnic: @names', - array('@names' => implode(', ', $form_state['values']['names_fieldset']['name'])) ); - drupal_set_message($output); -} \ No newline at end of file diff --git a/ajax_example/ajax_example_misc.inc b/ajax_example/ajax_example_misc.inc deleted file mode 100644 index e0deb07f41ef64526a83819a864215f516fe7af2..0000000000000000000000000000000000000000 --- a/ajax_example/ajax_example_misc.inc +++ /dev/null @@ -1,108 +0,0 @@ -use-ajax class applied to it, so if -javascript is enabled, ajax.js will try to submit it via an AJAX call instead -of a normal page load. The URL also contains the '/nojs/' magic string, which -is stripped if javascript is enabled, allowing the server code to tell by the -URL whether JS was enabled or not, letting it do different things based on that."; - $output = "
" . t($explanation) ."
"; - // The use-ajax class is special, so that the link will call without causing - // a page reload. Note the /nojs portion of the path - if javascript is - // enabled, this part will be stripped from the path before it is called. - $link = l(t('Click here'), 'ajax_link_callback/nojs/', array('attributes' => array('class' => array('use-ajax')))); - $output .= "
$link
"; - return $output; -} - -/** - * Demonstrates a clickable AJAX-enabled link using a renderable array with the - * #ajax property. - * - * A link that is constructed as a renderable array can have the #ajax property, - * which ensures that the link submission is done without a page refresh. The href - * of the link is used as the ajax callback, but it degrades gracefully without - * JavaScript because if the 'nojs' portion of the href is not stripped out by js, - * the callback will return content as required for a full page reload. - * - * The necessary JavaScript file, ajax.js, will be included on the page - * automatically. - * @return unknown_type - */ -function ajax_example_render_link_ra() { - $explanation = " -The link below has been rendered as an element with the #ajax property, so if -javascript is enabled, ajax.js will try to submit it via an AJAX call instead -of a normal page load. The URL also contains the '/nojs/' magic string, which -is stripped if javascript is enabled, allowing the server code to tell by the -URL whether JS was enabled or not, letting it do different things based on that."; - $build['my_div'] = array( - '#markup' => $explanation .'
', - ); - $build['ajax_link'] = array( - '#type' => 'link', - '#title' => t('Click here'), - // Note the /nojs portion of the href - if javascript is enabled, - // this part will be stripped from the path before it is called. - '#href' => 'ajax_link_callback/nojs/', - '#id' => 'ajax_link', - '#ajax' => array( - 'wrapper' => 'myDiv', - 'method' => 'html', - ), - ); - - return $build; -} - -/** - * Callback for link example. - * - * Takes different logic paths based on whether Javascript was enabled. - * If $type == 'ajax', it tells this function that ajax.js has rewritten - * the URL and thus we are doing an AJAX and can return an array of commands. - * @param $type - * Either 'ajax' or 'nojs. Type is simply the normal URL argument to this - * URL. - * @return - * If $type == 'ajax', returns an array of AJAX Commands. - * Otherwise, just returns the content, which will end up being a page. - * @see ajax - */ -function ajax_link_response($type = 'ajax') { - if ($type == 'ajax') { - $output = t("This is some content delivered via AJAX"); - $commands = array(); - // See ajax_example_advanced.inc for more details on the available commands - // and how to use them. - $commands[] = ajax_command_append('#myDiv', $output); - $page = array('#type' => 'ajax', '#commands' => $commands); - ajax_deliver($page); - } - else { - $output = t("This is some content delivered via a page load."); - return $output; - } -} diff --git a/batch_example/batch_example.info b/batch_example/batch_example.info deleted file mode 100644 index 5c5ce792953e3e8c41c1a9c1da326210ae86da48..0000000000000000000000000000000000000000 --- a/batch_example/batch_example.info +++ /dev/null @@ -1,6 +0,0 @@ - -name = Batch example -description = An example outlining how a module can define batch operations. -package = Example modules -core = 7.x -files[] = batch_example.test diff --git a/batch_example/batch_example.install b/batch_example/batch_example.install deleted file mode 100644 index ec8e60c65acfb334ca2332cd82901ef99153d3e4..0000000000000000000000000000000000000000 --- a/batch_example/batch_example.install +++ /dev/null @@ -1,79 +0,0 @@ -fetchField(); - // A place to store messages during the run. - $sandbox['messages'] = array(); - $sandbox['current_node'] = -1; // Last node read via the query. - } - - // Process nodes by groups of 10 (arbitrary value). - // When a group is processed, the batch update engine determines - // whether it should continue processing in the same request or provide - // progress feedback to the user and wait for the next request. - $limit = 10; - - // Retrieve the next group of nids. - $result = db_select('node', 'n') - ->fields('n', array('nid')) - ->orderBy('n.nid', 'ASC') - ->where('n.nid > :nid', array(':nid' => $sandbox['current_node'])) - ->extend('PagerDefault') - ->limit($limit) - ->execute(); - foreach ($result as $row) { - // Here we actually perform a dummy 'update' on the current node. - $node = db_query('SELECT nid FROM {node} WHERE nid = :nid', array(':nid' => $row->nid))->fetchField(); - - // Update our progress information. - $sandbox['progress']++; - $sandbox['current_node'] = $row->nid; - } - - // Set the "finished" status, to tell batch engine whether this function - // needs to run again. - $sandbox['#finished'] = ($sandbox['progress'] >= $sandbox['max']); - - // Set up a per-run message; Make a copy of $sandbox so we can change it. - // This is simply a debugging stanza to illustrate how to capture status - // from each pass through hook_update_N(). - $sandbox_status = $sandbox; - unset($sandbox_status['messages']); // Don't want them in the output. - $sandbox['messages'][] = t('$sandbox=') . print_r($sandbox_status, TRUE); - - if ($sandbox['#finished']) { - // hook_update_N() may optionally return a string which will be displayed - // to the user. - $final_message = '"; - return t('The batch_example demonstration update did what it was supposed to do: ') . $final_message; - } -} diff --git a/batch_example/batch_example.module b/batch_example/batch_example.module deleted file mode 100644 index d5752b34eacdce2b5218fb493ebd6bcee928cd39..0000000000000000000000000000000000000000 --- a/batch_example/batch_example.module +++ /dev/null @@ -1,264 +0,0 @@ - 'Batch example', - 'description' => t("Example of Drupal batch processing"), - 'page callback' => 'drupal_get_form', - 'page arguments' => array('batch_example_simple_form'), - 'access callback' => TRUE, - ); - - return $items; -} - -/** - * Form builder function to allow choice of which batch to run. - */ -function batch_example_simple_form() { - $form['description'] = array( - '#type' => 'markup', - '#markup' => t('This example offers two different batches. The first does 1000 identical operations, each completed in on run; the second does 20 operations, but each takes more than one run to operate if there are more than 5 nodes.'), - ); - $form['batch'] = array( - '#type' => 'select', - '#title' => 'Choose batch', - '#options' => array( - 'batch_1' => t('batch 1 - 1000 operations, each loading the same node'), - 'batch_2' => t('batch 2 - 20 operations. each one loads all nodes 5 at a time'), - ), - ); - $form['submit'] = array( - '#type' => 'submit', - '#value' => 'Go', - ); - - // If no nodes, prevent submission. - // Find out if we have a node to work with. Otherwise it won't work. - $nid = batch_example_lowest_nid(); - if (empty($nid)) { - drupal_set_message(t("You don't currently have any nodes, and this example requires a node to work with. As a result, this form is disabled.")); - $form['submit']['#disabled'] = TRUE; - } - return $form; -} - -function batch_example_simple_form_submit($form, &$form_state) { - $function = 'batch_example_' . $form_state['values']['batch']; - - $_SESSION['http_request_count'] = 0; // reset counter for debug information. - - // Execute the function named batch_example_1 or batch_example_2. - $batch = $function(); - batch_set($batch); -} - - -/** - * @defgroup batch_definitions Example batch definitions - * @{ - * Definitions of the batches used in this module. - */ - -/** - * Batch 1 definition: Load the node with the lowest nid 1000 times. - * This creates an operations array defining what batch 1 should do, including - * what it should do when it's finished. In this case, each operation is the - * same and by chance even has the same $nid to operate on, but we could have - * a mix of different types of operations in the operations array. - */ -function batch_example_batch_1() { - $nid = batch_example_lowest_nid(); - $num_operations = 1000; - drupal_set_message(t('Creating an array of @num operations', array('@num' => $num_operations))); - - $operations = array(); - // Set up an operations array with 1000 elements, each doing function - // batch_example_op_1. - // Each operation in the operations array means at least one new HTTP request, - // running Drupal from scratch to accomplish the operation. If the operation - // returns with $context['finished'] != TRUE, then it will be called again. - // In this example, $context['finished'] is always TRUE. - for ($i = 0; $i<$num_operations; $i++) { - - // Each operation is an array consisting of - // - the function to call - // - An array of arguments to that function - $operations[] = array('batch_example_op_1', array($nid, t('(Operation @operation)', array('@operation' => $i)))); - } - $batch = array( - 'operations' => $operations, - 'finished' => 'batch_example_finished', - ); - return $batch; -} - -/** - * Batch operation for batch 1: load a node. - * This is the function that is called on each operation in batch 1. - */ -function batch_example_op_1($nid, $operation_details, &$context) { - $node = node_load($nid, NULL, TRUE); - - // Store some result for post-processing in the finished callback. - $context['results'][] = $node->nid . ' : ' . check_plain($node->title); - - // Optional message displayed under the progressbar. - $context['message'] = t('Loading node "@title"', array('@title' => $node->title)) . ' ' . $operation_details; - - _batch_example_update_http_requests(); -} - -/** - * Batch 2 : Prepare a batch definition that will load all nodes 20 times. - */ -function batch_example_batch_2() { - $num_operations = 20; - - // Give helpful information about how many nodes are being operated on. - $node_count = db_query('SELECT COUNT(DISTINCT nid) FROM {node}')->fetchField(); - drupal_set_message(t('There are @node_count nodes so each of the @num operations will require @count HTTP requests.', array('@node_count' => $node_count, '@num' => $num_operations, '@count' => ceil($node_count / 5)))); - - $operations = array(); - // 20 operations, each one loads all nodes. - for ($i = 0; $i < $num_operations; $i++) { - $operations[] = array('batch_example_op_2', array(t('(Operation @operation)', array('@operation' => $i)))); - } - $batch = array( - 'operations' => $operations, - 'finished' => 'batch_example_finished', - // We can define custom messages instead of the default ones. - 'title' => t('Processing batch 2'), - 'init_message' => t('Batch 2 is starting.'), - 'progress_message' => t('Processed @current out of @total.'), - 'error_message' => t('Batch 2 has encountered an error.'), - ); - return $batch; -} - -/** - * Batch operation for batch 2 : load all nodes, 5 by five - * After each group of 5 control is returned to the batch API for later - * continuation. - */ -function batch_example_op_2($operation_details, &$context) { - // Use the $context['sandbox'] at your convenience to store the - // information needed to track progression between successive calls. - if (empty($context['sandbox'])) { - $context['sandbox'] = array(); - $context['sandbox']['progress'] = 0; - $context['sandbox']['current_node'] = 0; - - // Save node count for the termination message. - $context['sandbox']['max'] = db_query('SELECT COUNT(DISTINCT nid) FROM {node}')->fetchField(); - } - - // Process nodes by groups of 5 (arbitrary value). - // When a group of five is processed, the batch update engine determines - // whether it should continue processing in the same request or provide - // progress feedback to the user and wait for the next request. - // That way even though we're already processing at the operation level - // the operation itself is interruptible. - $limit = 5; - - // Retrieve the next group of nids. - $result = db_select('node', 'n') - ->fields('n', array('nid')) - ->orderBy('n.nid', 'ASC') - ->where('n.nid > :nid', array(':nid' => $context['sandbox']['current_node'])) - ->extend('PagerDefault') - ->limit($limit) - ->execute(); - foreach ($result as $row) { - // Here we actually perform our dummy 'processing' on the current node. - $node = node_load($row->nid, NULL, TRUE); - - // Store some result for post-processing in the finished callback. - $context['results'][] = $node->nid . ' : ' . check_plain($node->title) . ' ' . $operation_details; - - // Update our progress information. - $context['sandbox']['progress']++; - $context['sandbox']['current_node'] = $node->nid; - $context['message'] = check_plain($node->title); - } - - // Inform the batch engine that we are not finished, - // and provide an estimation of the completion level we reached. - if ($context['sandbox']['progress'] != $context['sandbox']['max']) { - $context['finished'] = ($context['sandbox']['progress'] >= $context['sandbox']['max']); - } - _batch_example_update_http_requests(); -} - -/** - * Batch 'finished' callback used by both batch 1 and batch 2. - */ -function batch_example_finished($success, $results, $operations) { - if ($success) { - // Here we could do something meaningful with the results. - // We just display the number of nodes we processed... - drupal_set_message(t('@count results processed in @requests HTTP requests.', array('@count' => count($results), '@requests' => _batch_example_get_http_requests()))); - drupal_set_message(t('The final result was "%final"', array('%final' => end($results)))); - } - else { - // An error occurred. - // $operations contains the operations that remained unprocessed. - $error_operation = reset($operations); - drupal_set_message(t('An error occurred while processing @operation with arguments : @args', array('@operation' => $error_operation[0], '@args' => print_r($error_operation[0], TRUE)))); - } -} - -/** - * Utility function - simply queries and loads the lowest nid. - * @return A nid or NULL if there are no nodes. - */ -function batch_example_lowest_nid() { - $select = db_select('node', 'n') - ->fields('n', array('nid')) - ->orderBy('n.nid', 'ASC') - ->extend('PagerDefault') - ->limit(1); - $nid = $select->execute()->fetchField(); - return $nid; -} -/** - * @} End of "defgroup batch_definitions". - */ - -/** - * Utility function to count the HTTP requests in a session variable. - */ -function _batch_example_update_http_requests() { - $_SESSION['http_request_count']++; -} - -function _batch_example_get_http_requests() { - return !empty($_SESSION['http_request_count']) ? $_SESSION['http_request_count'] : 0; -} \ No newline at end of file diff --git a/batch_example/batch_example.test b/batch_example/batch_example.test deleted file mode 100644 index 70198fd81be777e927d07f9788e62ddcab2b2054..0000000000000000000000000000000000000000 --- a/batch_example/batch_example.test +++ /dev/null @@ -1,53 +0,0 @@ - 'Batch example functionality', - 'description' => 'Verify the defined batches.', - 'group' => 'Examples', - ); - } - - /** - * Enable modules and create user with specific permissions. - */ - function setUp() { - parent::setUp('batch_example'); - // Create user. - $this->web_user = $this->drupalCreateUser(); - } - - /** - * Login user, create 30 nodes and test both batch examples. - */ - function testBatchExampleBasic() { - // Login the admin user. - $this->drupalLogin($this->web_user); - - // Create 30 nodes - for ($count = 0; $count < 30; $count++) { - $node = $this->drupalCreateNode(); - } - - // Launch Batch 1 - $result = $this->drupalPost('examples/batch_example', array('batch' => 'batch_1'), t('Go')); - // Check that 1000 operations were performed. - $this->assertText('1000 results processed'); - - // Launch Batch 2 - $result = $this->drupalPost('examples/batch_example', array('batch' => 'batch_2'), t('Go')); - // Check that 600 operations were performed. - $this->assertText('600 results processed'); - } -} diff --git a/block_example/block_example.info b/block_example/block_example.info deleted file mode 100644 index 44f7abf38c583c6ae0eb42de03c899be2c547b54..0000000000000000000000000000000000000000 --- a/block_example/block_example.info +++ /dev/null @@ -1,6 +0,0 @@ - -name = Block Example -description = An example outlining how a module can define blocks. -package = Example modules -core = 7.x -files[] = block_example.test diff --git a/block_example/block_example.install b/block_example/block_example.install deleted file mode 100644 index 13a9df8a58f52da325812d43b72cdac19251e637..0000000000000000000000000000000000000000 --- a/block_example/block_example.install +++ /dev/null @@ -1,13 +0,0 @@ - 'block_example_page', - 'access callback' => TRUE, - 'title' => 'Block Example', - ); - return $items; -} - -/** - * Simple page function to explain what the block example is about. - */ -function block_example_page() { - $page = array( - '#type' => 'markup', - '#markup' => t('The Block Example provides two sample blocks which demonstrate the various block APIs. To experiment with the blocks, enable and configure them on the block admin page.', array('@url' => url('admin/structure/block'))), - ); - return $page; -} -/** - * Implements hook_block_info(). - * - * This hook declares what blocks are provided by the module. - */ -function block_example_block_info() { - // This hook returns an array, each component of which is an array of block - // information. The array keys are the 'delta' values used in other block - // hooks. - - // The required block information is a block description, which is shown - // to the site administrator in the list of possible blocks. You can also - // provide initial settings for block weight, status, etc. - - // Many options are defined in hook_block_info(): - $blocks['example_configurable_text'] = array( - // info: The name of the block. - 'info' => t('Example: configurable text string'), - // Block caching options (per role, per user, etc.) - 'cache' => DRUPAL_CACHE_PER_ROLE, // default - ); - - // This sample shows how to provide default settings. In this case we'll - // enable the block in the first sidebar and make it visible only on - // 'node/*' pages. See the hook_block_info() documentation for these. - $blocks['example_empty'] = array( - 'info' => t('Example: empty block'), - 'status' => TRUE, - 'region' => 'sidebar_first', // Not usually provided. - 'visibility' => 1, // Not usually provided. - 'pages' => 'node/*', // Not usually provided here. - ); - - return $blocks; -} - -/** - * Implements hook_block_configure(). - * - * This hook declares configuration options for blocks provided by this module. - */ -function block_example_block_configure($delta = '') { - // The $delta parameter tells us which block is being configured. - // In this example, we'll allow the administrator to customize - // the text of the 'configurable text string' block defined in this module. - - $form = array(); - if ($delta == 'example_configurable_text') { - // All we need to provide is the specific configuration options for our - // block. Drupal will take care of the standard block configuration options - // (block title, page visibility, etc.) and the save button. - $form['block_example_string'] = array( - '#type' => 'textfield', - '#title' => t('Block contents'), - '#size' => 60, - '#description' => t('This text will appear in the example block.'), - '#default_value' => variable_get('block_example_string', t('Some example content.')), - ); - } - return $form; -} - -/** - * Implements hook_block_save(). - * - * This hook declares how the configured options for a block - * provided by this module are saved. - */ -function block_example_block_save($delta = '', $edit = array()) { - // We need to save settings from the configuration form. - // We need to check $delta to make sure we are saving the right block. - if ($delta == 'example_configurable_text') { - // Have Drupal save the string to the database. - variable_set('block_example_string', $edit['block_example_string']); - } - return; -} - -/** - * Implements hook_block_view(). - * - * This hook generates the contents of the blocks themselves. - */ -function block_example_block_view($delta = '') { - //The $delta parameter tells us which block is being requested. - switch ($delta) { - case 'example_configurable_text': - // The subject is displayed at the top of the block. Note that it - // should be passed through t() for translation. The title configured - // for the block using Drupal UI supercedes this one. - $block['subject'] = t('Title of first block (example_configurable_text)'); - // The content of the block is typically generated by calling a custom - // function. - $block['content'] = block_example_contents($delta); - break; - case 'example_empty': - $block['subject'] = t('Title of second block (example_empty)'); - $block['content'] = block_example_contents($delta); - break; - } - return $block; -} - -/** - * A module-defined block content function. - */ -function block_example_contents($which_block) { - switch ($which_block) { - case 'example_configurable_text': - // Modules would typically perform some database queries to fetch the - // content for their blocks. Here, we'll just use the variable set in the - // block configuration or, if none has set, a default value. - // Block content can be returned in two formats: renderable arrays - // (as here) are preferred though a simple string will work as well. - return array('#markup' => variable_get('block_example_string', t('A default value. This block was created at %time', array('%time' => date('c'))))); - case 'example_empty': - // It is possible that a block not have any content, since it is - // probably dynamically constructed. In this case, Drupal will not display - // the block at all. This block will not be displayed. - return; - } -} - -/* - * The following hooks can be used to alter blocks - * provided by your own or other modules. - */ - -/** - * Implements hook_block_list_alter(). - * - * This hook allows you to add, remove or modify blocks in the block list. The - * block list contains the block definitions. This example requires - * search module and the search block enabled - * to see how this hook implementation works. - * - * You may also be interested in hook_block_info_alter(), which allows changes - * to the behavior of blocks. - */ -function block_example_block_list_alter(&$blocks) { - // We are going to make the search block sticky on bottom of regions. For - // this example, we will modify the block list and append the search block at - // the end of the list, so even if the administrator configures the block to - // be on the top of the region, it will demote to bottom again. - foreach ($blocks as $bid => $block) { - if (($block->module == 'search') && ($block->delta == 'form')) { - // Remove the block from the list and append to the end. - unset($blocks[$bid]); - $blocks[$bid] = $block; - break; - } - } -} - -/** - * Implements hook_block_view_alter(). - * - * This hook allows you to modify the output of any block in the system. - * - * In addition, instead of hook_block_view_alter(), which is called for all - * blocks, you can also use hook_block_view_MODULE_DELTA_alter() to alter a - * specific block. - * - * We are going to uppercase the title of any block if the string "magic string" - * is encountered in the content. If we were changing only our block using - * hook_block_view_MODULE_DELTA_alter to do this, we would have used the - * function: - * block_example_block_view_block_example_example_configurable_text_alter() - * - * To demonstrate the effect of this hook, you can use the - * 'configurable_text_string' block created by this module and add the - * text 'magic string' into the configuration. - */ -function block_example_block_view_alter(&$data, $block) { - // Verify the we have raw text content - if (!isset($data['content']) || !is_string($data['content'])) { - return; - } - - // If the content contains the string: 'magic string', uppercase the title. - if (strstr($data['content'], 'magic string')) { - $data['subject'] = isset($data['subject']) ? drupal_strtoupper($data['subject']) : ''; - } -} diff --git a/block_example/block_example.test b/block_example/block_example.test deleted file mode 100644 index cfbd9982efa1223999c3fc45a31e6039c4fb7252..0000000000000000000000000000000000000000 --- a/block_example/block_example.test +++ /dev/null @@ -1,92 +0,0 @@ - 'Block example functionality', - 'description' => 'Test the configuration options and block created by Block Example module.', - 'group' => 'Examples', - ); - } - - /** - * Enable modules and create user with specific permissions. - */ - function setUp() { - parent::setUp('block_example', 'search'); - // Create user. Search content permission granted for the search block to - // be shown. - $this->web_user = $this->drupalCreateUser(array('administer blocks', 'search content', 'access contextual links')); - } - - /** - * Login user, create an example node, and test block functionality through - * the admin and user interfaces. - */ - function testBlockExampleBasic() { - // Login the admin user. - $this->drupalLogin($this->web_user); - - // Find the blocks in the settings page. - $this->drupalGet('admin/structure/block'); - $this->assertRaw(t('Example: configurable text string'), t('Block configurable-string found.')); - $this->assertRaw(t('Example: empty block'), t('Block empty-block found.')); - - // Verify the default settings for block are processed. - $this->assertFieldByName('blocks[block_example_example_empty][region]', 'sidebar_first', t('Empty block is enabled in first sidebar successfully verified.') ); - $this->assertFieldByName('blocks[block_example_example_configurable_text][region]', -1, t('Configurable text block is disabled in first sidebar successfully verified.') ); - - // Verify that blocks are not shown - $this->drupalGet('/'); - $this->assertNoRaw( t('Title of first block (example_configurable_text)'), t('Block configurable test not found.')); - $this->assertNoRaw( t('Title of second block (example_empty)'), t('Block empty not found.')); - - // Enable the Configurable text block and verify - $this->drupalPost('admin/structure/block', array('blocks[block_example_example_configurable_text][region]' => 'sidebar_first'), t('Save blocks')); - $this->assertFieldByName('blocks[block_example_example_configurable_text][region]', 'sidebar_first', t('Configurable text block is enabled in first sidebar successfully verified.') ); - - // Verify that blocks are there. Empty block will not be shown, because it is empty - $this->drupalGet('/'); - $this->assertRaw( t('Title of first block (example_configurable_text)'), t('Block configurable text found.')); - - // Change content of configurable text block - $string = $this->randomName(); - $this->drupalPost('admin/structure/block/manage/block_example/example_configurable_text/configure', array('block_example_string' => $string), t('Save block')); - - // Verify that new content is shown - $this->drupalGet('/'); - $this->assertRaw( $string, t('Content of configurable text block successfully verified.')); - - // Verify the view_alter hook implementation. Change content of our block - // to be 'magic string' - $string = 'there is a magic string in content'; - $this->drupalPost('admin/structure/block/manage/block_example/example_configurable_text/configure', array('block_example_string' => $string), t('Save block')); - - // Verify that new content is shown and the title is uppercase - $this->drupalGet('/'); - $this->assertRaw( $string, t('Content of configurable text block successfully verified.')); - $this->assertText(t('Title of first block (example_configurable_text)'), t('hook_block_view_alter implementation successfully verified.')); - - // Verify that search block is at the bottom of the region. - - // Enable the search block on top of sidebar_first. - $block_options = array( - 'blocks[search_form][region]' => 'sidebar_first', - 'blocks[search_form][weight]' => -9, - ); - $this->drupalPost('admin/structure/block', $block_options, t('Save blocks')); - - // The first 'configure block' link should be from our configurable block, - // the second from the Navigation menu, and the third (#2) from search block - // if it was successfully pushed to the bottom. - $this->drupalGet('/'); - $this->clickLink('Configure block', 2); - $this->assertText(t("'@search' block", array('@search' => t('Search form'))), t('hook_block_info_alter successfully verified.') ); - } -} diff --git a/dbtng_example/dbtng_example.info b/dbtng_example/dbtng_example.info deleted file mode 100644 index 7d7acb7ba959b7dbb12c64f3a69fffcc40bd8e71..0000000000000000000000000000000000000000 --- a/dbtng_example/dbtng_example.info +++ /dev/null @@ -1,6 +0,0 @@ - -name = DBTNG example -description = An example module showing how use the database API: DBTNG. -package = Example modules -core = 7.x -files[] = dbtng_example.test diff --git a/dbtng_example/dbtng_example.install b/dbtng_example/dbtng_example.install deleted file mode 100644 index 5f314b3636efcb23d9b48af4c54b847b54d4ddcb..0000000000000000000000000000000000000000 --- a/dbtng_example/dbtng_example.install +++ /dev/null @@ -1,115 +0,0 @@ - 'John', - 'surname' => 'Doe', - 'age' => 0, - ); - db_insert('dbtng_example') - ->fields($fields) - ->execute(); - - // Add another entry. - $fields = array( - 'name' => 'John', - 'surname' => 'Roe', - 'age' => 100, - 'uid' => 1, - ); - db_insert('dbtng_example') - ->fields($fields) - ->execute(); - -} - -/** - * Implements hook_uninstall(). - * - * As in hook_install, there is no need to uninstall schema, Drupal will do it - * for us. - * - * @see hook_uninstall() - */ -function dbtng_example_uninstall() { -} - - -/** - * Implements hook_schema(). - * - * Define the database tables used by this module. - * Remember that the easiest way to create the code for hook_schema is with - * the schema module: - * @link http://drupal.org/project/schema @endlink - * - * @see hook_schema() - */ -function dbtng_example_schema() { - - $schema['dbtng_example'] = array( - 'description' => 'Stores example person entries for demonstration purposes.', - 'fields' => array( - 'pid' => array( - 'type' => 'serial', - 'not null' => TRUE, - 'description' => 'Primary Key: Unique person ID.', - ), - 'uid' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => "Creator user's {users}.uid", - ), - 'name' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Name of the person.', - ), - 'surname' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Surname of the person.', - ), - 'age' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'size' => 'tiny', - 'description' => 'The age of the person in years.', - ) - ), - 'primary key' => array('pid'), - 'indexes' => array( - 'name' => array('name'), - 'surname' => array('surname'), - 'age' => array('age'), - ), - ); - - return $schema; -} diff --git a/dbtng_example/dbtng_example.module b/dbtng_example/dbtng_example.module deleted file mode 100644 index 6aee7acfc92089edda64e33f81f0c80bea201a2d..0000000000000000000000000000000000000000 --- a/dbtng_example/dbtng_example.module +++ /dev/null @@ -1,571 +0,0 @@ -fields(array('name' => 'John', 'surname' => 'Doe')) - * ->execute(); - * @endcode - * - * db_update() example: - * @code - * // UPDATE {dbtng_example} SET name = 'Jane' WHERE name = 'John' - * db_update('dbtng_example') - * ->fields(array('name' => 'Jane')) - * ->condition('name', 'John') - * ->execute(); - * @endcode - * - * db_delete() example: - * @code - * // DELETE FROM {dbtng_example} WHERE name = 'Jane' - * db_delete('dbtng_example') - * ->condition('name', 'Jane') - * ->execute(); - * @endcode - * - * See @link database Database Abstraction Layer @endlink - * @see db_insert() - * @see db_update() - * @see db_delete() - * @see drupal_write_record() - * @} -*/ - -/** - * Save an entry in the database. - * - * The underlying DBTNG function is db_insert(). - * - * In Drupal 6, this would have been: - * @code - * db_query( - * "INSERT INTO {dbtng_example} (name, surname, age) - * VALUES ('%s', '%s', '%d')", - * $entry['name'], - * $entry['surname'], - * $entry['age'] - * ); - * @endcode - * - * Exception handling is shown in this example. It could be simplified - * without the try/catch blocks, but since an insert will throw an exception - * and terminate your application if the exception is not handled, it is best - * to employ try/catch. - * - * @param $entry - * An array containing all the fields of the database record. - * - * @ingroup database_examples - * @see db_insert() - */ -function dbtng_example_entry_insert($entry) { - $return_value = NULL; - try { - $return_value = db_insert('dbtng_example') - ->fields($entry) - ->execute(); - } - catch (Exception $e) { - drupal_set_message(t('db_insert failed. Message = %message, query= %query', - array('%message' => $e->getMessage(), '%query' => $e->query_string)), 'error'); - } - return $return_value; -} - -/** - * Update an entry in the database. - * - * The former, deprecated techniques used db_query() or drupal_write_record(): - * @code - * drupal_write_record('dbtng_example', $entry, $entry['pid']); - * @endcode - * - * @code - * db_query( - * "UPDATE {dbtng_example} - * SET name = '%s', surname = '%s', age = '%d' - * WHERE pid = %d", - * $entry['pid'] - * ); - * @endcode - * - * @param $entry - * An array containing all the fields of the item to be updated. - * - * @ingroup database_examples - * @see db_update() - */ -function dbtng_example_entry_update($entry) { - try { - // db_update()...->execute() returns the number of rows updated. - $count = db_update('dbtng_example') - ->fields($entry) - ->condition('pid', $entry['pid']) - ->execute(); - } - catch(Exception $e) { - drupal_set_message(t('db_update failed. Message = %message, query= %query', - array('%message' => $e->getMessage(), '%query' => $e->query_string)), 'error'); - } - return $count; -} - -/** - * Delete an entry from the database. - * - * The usage of db_query is deprecated except for static queries. - * Formerly, a deletion might have been accomplished like this: - * @code - * db_query("DELETE FROM {dbtng_example} WHERE pid = %d", $entry['pid]); - * @endcode - * - * @param $entry - * An array containing at least the person identifier 'pid' element of the - * entry to delete. - * - * @ingroup database_examples - * @see db_delete() - */ -function dbtng_example_entry_delete($entry) { - db_delete('dbtng_example') - ->condition('pid', $entry['pid']) - ->execute(); - -} - - -/** - * Read from the database using a filter array. - * - * In Drupal 6, the standard function to perform reads was db_query(), and - * for static queries, it still is. - * - * db_query() used an SQL query with placeholders and arguments as parameters. - * - * @code - * // Old way - * $query = "SELECT * FROM {dbtng_example} n WHERE n.uid = %d AND name = '%s'"; - * $result = db_query($query, $uid, $name); - * @endcode - * - * Drupal 7 DBTNG provides an abstracted interface that will work with a wide - * variety of database engines. - * - * db_query() is deprecated except when doing a static query. The following is - * perfectly acceptable in Drupal 7. See - * @link http://drupal.org/node/310072 the handbook page on static queries @endlink - * - * @code - * // SELECT * FROM {dbtng_example} WHERE uid = 0 AND name = 'John' - * db_query( - * "SELECT * FROM {dbtng_example} WHERE uid = :uid and name = :name", - * array(':uid' => 0, ':name' => 'John') - * )->execute(); - * @endcode - * - * But for more dynamic queries, Drupal provides the db_select() - * API method, so there are several ways to perform the same SQL query. - * See the @link http://drupal.org/node/310075 handbook page on dynamic queries. @endlink - * - * @code - * // SELECT * FROM {dbtng_example} WHERE uid = 0 AND name = 'John' - * db_select('dbtng_example') - * ->fields('dbtng_example') - * ->condition('uid', 0) - * ->condition('name', 'John') - * ->execute(); - * @endcode - * - * Here is db_select with named placeholders: - * @code - * // SELECT * FROM {dbtng_example} WHERE uid = 0 AND name = 'John' - * $arguments = array(':name' => 'John', ':uid' => 0); - * db_select('dbtng_example') - * ->fields('dbtng_example') - * ->where('uid = :uid AND name = :name', $arguments) - * ->execute(); - * @endcode - * - * Conditions are stacked and evaluated as AND and OR depending on the type of - * query. For more information, read the conditional queries handbook page at: - * http://drupal.org/node/310086 - * - * The condition argument is an 'equal' evaluation by default, but this can be - * altered: - * @code - * // SELECT * FROM {dbtng_example} WHERE age > 18 - * db_select('dbtng_example') - * ->fields('dbtng_example') - * ->condition('age', 18, '>') - * ->execute(); - * @endcode - * - * @param $entry - * An array containing all the fields used to search the entries in the table. - * @return - * An object containing the loaded entries if found. - * - * @ingroup database_examples - * @see db_select() - * @see db_query() - * @see http://drupal.org/node/310072 - * @see http://drupal.org/node/310075 - * - */ -function dbtng_example_entry_load($entry = array()) { - // Read all fields from the dbtng_example table. - $select = db_select('dbtng_example', 'example'); - $select->fields('example'); - - // Add each field and value as a condition to this query. - foreach ($entry as $field => $value) { - $select->condition($field, $value); - } - // Return the result in object format. - return $select->execute()->fetchAll(); -} - -/** - * Render a filtered list of entries in the database. - * - * DBTNG also helps processing queries that return several rows, providing the - * found objects in the same query execution call. - * - * This function queries the database using a JOIN between users table and the - * example entries, to provide the username that created the entry, and creates - * a table with the results, processing each row. - * - * SELECT - * e.pid as pid, e.name as name, e.surname as surname, e.age as age - * u.name as username - * FROM - * {dbtng_example} e - * JOIN - * users u ON e.uid = u.uid - * WHERE - * e.name = 'John' AND e.age > 18 - * - * @see db_select() - * @seeW http://drupal.org/node/310075 - */ -function dbtng_example_advanced_list() { - $output = ''; - - $select = db_select('dbtng_example', 'e'); - // Join the users table, so we can get the entry creator's username. - $select->join('users', 'u', 'e.uid = u.uid'); - // Select these specific fields for the output. - $select->addField('e', 'pid'); - $select->addField('u', 'name', 'username'); - $select->addField('e', 'name'); - $select->addField('e', 'surname'); - $select->addField('e', 'age'); - // Filter only persons named "John". - $select->condition('e.name', 'John'); - // Filter only persons older than 18 years. - $select->condition('e.age', 18, '>'); - // Make sure we only get items 0-49, for scalability reasons. - $select->range(0, 50); - - // Now, loop all these entries and show them in a table. Note that there is no - // db_fetch_* object or array function being called here. Also note that the - // following line could have been written as - // $entries = $select->execute()->fetchAll() which would return each selected - // record as an object instead of an array. - $entries = $select->execute()->fetchAll(PDO::FETCH_ASSOC); - if (!empty($entries)) { - $rows = array(); - foreach ($entries as $entry) { - // Sanitize the data before handing it off to the theme layer. - $rows[] = array_map('check_plain', $entry); - } - // Make a table for them. - $header = array(t('Id'), t('Created by'), t('Name'), t('Surname'), t('Age')); - $output .= theme('table', array('header' => $header, 'rows' => $rows)); - } - else { - drupal_set_message(t('No entries meet the filter criteria (Name = "John" and Age > 18).')); - } - return $output; -} - -//// Helper functions //// - -/** - * Implements hook_help(). - * - * Show some help on each form provided by this module. - */ -function dbtng_example_help($path) { - $output = ''; - switch ($path) { - case 'examples/dbtng': - $output = t('Generate a list of all entries in the database. There is no filter in the query.'); - break; - case 'examples/dbtng/advanced': - $output = t('A more complex list of entries in the database. '); - $output .= t('Only the entries with name = "John" and age older than 18 years are shown, the username of the person who created the entry is also shown.'); - break; - case 'examples/dbtng/update': - $output = t('Demonstrates a database update operation.'); - break; - case 'examples/dbtng/add': - $output = t('Add an entry to the dbtng_example table.'); - break; - } - return $output; -} - -/** - * Implements hook_menu(). - * - * Set up calls to drupal_get_form() for all our example cases. - */ -function dbtng_example_menu() { - $items = array(); - - $items['examples/dbtng'] = array( - 'title' => 'DBTNG Example', - 'page callback' => 'dbtng_example_list', - 'access callback' => TRUE, - ); - $items['examples/dbtng/list'] = array( - 'title' => 'List', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => -10, - ); - $items['examples/dbtng/add'] = array( - 'title' => 'Add entry', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('dbtng_example_form_add'), - 'access callback' => TRUE, - 'type' => MENU_LOCAL_TASK, - 'weight' => -9, - ); - $items['examples/dbtng/update'] = array( - 'title' => 'Update entry', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('dbtng_example_form_update'), - 'type' => MENU_LOCAL_TASK, - 'access callback' => TRUE, - 'weight' => -5, - ); - $items['examples/dbtng/advanced'] = array( - 'title' => 'Advanced list', - 'page callback' => 'dbtng_example_advanced_list', - 'access callback' => TRUE, - 'type' => MENU_LOCAL_TASK, - ); - - return $items; -} - -/** - * Render a list of entries in the database. - */ -function dbtng_example_list() { - $output = ''; - - // Get all entries in the dbtng_example table. - if ($entries = dbtng_example_entry_load()) { - $rows = array(); - foreach ($entries as $entry) { - // Sanitize the data before handing it off to the theme layer. - $rows[] = array_map('check_plain', (array) $entry); - } - // Make a table for them. - $header = array(t('Id'), t('uid'), t('Name'), t('Surname'), t('Age')); - $output .= theme('table', array('header' => $header, 'rows' => $rows)); - } - else { - drupal_set_message(t('No entries have been added yet.')); - } - return $output; -} - -/** - * Prepare a simple form to add an entry, with all the interesting fields. - */ -function dbtng_example_form_add($form, &$form_state) { - $form = array(); - - $form['add'] = array( - '#type' => 'fieldset', - '#title' => t('Add a person entry'), - ); - $form['add']['name'] = array( - '#type' => 'textfield', - '#title' => t('Name'), - '#size' => 15, - ); - $form['add']['surname'] = array( - '#type' => 'textfield', - '#title' => t('Surname'), - '#size' => 15, - ); - $form['add']['age'] = array( - '#type' => 'textfield', - '#title' => t('Age'), - '#size' => 5, - '#description' => t("Values greater than 127 will cause an exception. Try it - it's a great example why exception handling is needed with DTBNG."), - ); - $form['add']['submit'] = array( - '#type' => 'submit', - '#value' => t('Add'), - ); - - return $form; -} - -/** - * Submit handler for 'add entry' form. - */ -function dbtng_example_form_add_submit($form, $form_state){ - global $user; - - // Save the submitted entry. - $entry = array( - 'name' => $form_state['values']['name'], - 'surname' => $form_state['values']['surname'], - 'age' => $form_state['values']['age'], - 'uid' => $user->uid, - ); - $return = dbtng_example_entry_insert($entry); - if ($return) { - drupal_set_message(t("Created entry @entry", array('@entry' => print_r($entry, TRUE)))); - } -} - -/** - * Sample UI to update a record. - */ -function dbtng_example_form_update($form, &$form_state) { - $form = array( - '#prefix' => '
', - '#suffix' => '
', - ); - - $entries = dbtng_example_entry_load(); - $keyed_entries = array(); - if (empty($entries)) { - $form['no_values'] = array( - '#value' => t("No entries exist in the table dbtng_example table."), - ); - return $form; - } - - foreach ($entries as $entry) { - $options[$entry->pid] = t("@pid: @name @surname (@age)", array('@pid' => $entry->pid, '@name' => $entry->name, '@surname' => $entry->surname, '@age' => $entry->age)); - $keyed_entries[$entry->pid] = $entry; - } - $default_entry = !empty($form_state['values']['pid']) ? $keyed_entries[$form_state['values']['pid']] : $entries[0]; - - $form_state['entries'] = $keyed_entries; - - $form['pid'] = array( - '#type' => 'select', - '#options' => $options, - '#title' => t('Choose entry to update'), - '#default_value' => $default_entry->pid, - '#ajax' => array( - 'wrapper' => 'updateform', - 'callback' => 'dbtng_example_form_update_callback', - ), - ); - - $form['name'] = array( - '#type' => 'textfield', - '#title' => t('Updated first name'), - '#size' => 15, - '#default_value' => $default_entry->name, - ); - - $form['surname'] = array( - '#type' => 'textfield', - '#title' => t('Updated last name'), - '#size' => 15, - '#default_value' => $default_entry->surname, - ); - $form['age'] = array( - '#type' => 'textfield', - '#title' => t('Updated age'), - '#size' => 4, - '#default_value' => $default_entry->age, - '#description' => t("Values greater than 127 will cause an exception"), - ); - - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Update'), - ); - return $form; -} - -/** - * AJAX callback handler for the pid select. - * - * When the pid changes, populates the defaults from the database in the form. - */ -function dbtng_example_form_update_callback($form, $form_state) { - $entry = $form_state['entries'][$form_state['values']['pid']]; - // Setting the #value of items is the only way I was able to figure out - // to get replaced defaults on these items. #default_value will not do it - // and shouldn't. - foreach (array('name', 'surname', 'age') as $item) { - $form[$item]['#value'] = $entry->$item; - } - return $form; -} - -/** - * Submit handler for 'update entry' form. - */ -function dbtng_example_form_update_submit($form, $form_state){ - global $user; - - // Save the submitted entry. - $entry = array( - 'pid' => $form_state['values']['pid'], - 'name' => $form_state['values']['name'], - 'surname' => $form_state['values']['surname'], - 'age' => $form_state['values']['age'], - 'uid' => $user->uid, - ); - $count = dbtng_example_entry_update($entry); - drupal_set_message(t("Updated entry @entry (@count row updated)", array('@count' => $count, '@entry' => print_r($entry, TRUE)))); -} diff --git a/dbtng_example/dbtng_example.test b/dbtng_example/dbtng_example.test deleted file mode 100644 index ab732d3e2f17002eb9d40add975e3cce60ce4eb2..0000000000000000000000000000000000000000 --- a/dbtng_example/dbtng_example.test +++ /dev/null @@ -1,181 +0,0 @@ - 'DBTNG example unit and UI tests', - 'description' => 'Various unit tests on the dbtng example module.' , - 'group' => 'Examples', - ); - } - - function setUp() { - parent::setUp('dbtng_example'); - } - - /** - * Test default module installation, two entries in the database table. - */ - function testInstall() { - $result = dbtng_example_entry_load(); - $this->assertEqual( - count($result), - 2, - t('Found two entries in the table after installing the module.') - ); - } - - - /** - * Test the UI. - */ - function testUI() { - // Test the basic list. - $this->drupalGet('examples/dbtng'); - $this->assertPattern("/John[td\/<>\w]+Doe/", t("Text 'John Doe' found in table")); - - //Test the add tab. - // Add the new entry. - $this->drupalPost('examples/dbtng/add', - array('name' => 'Some', 'surname' => 'Anonymous', 'age' => 33), t('Add')); - // Now find the new entry. - $this->drupalGet('examples/dbtng'); - $this->assertPattern("/Some[td\/<>\w]+Anonymous/", t("Text 'Some Anonymous' found in table")); - - - // Try the update tab. - // Find out the pid of our "anonymous" guy. - $result = dbtng_example_entry_load(array('surname' => 'Anonymous')); - $this->drupalGet("examples/dbtng"); - $this->assertEqual( - count($result), - 1, - t('Found one entry in the table with surname = "Anonymous".') - ); - $entry = $result[0]; - unset($entry->uid); - $entry->name = 'NewFirstName'; - $this->drupalPost('examples/dbtng/update', - (array)$entry, t('Update')); - // Now find the new entry. - $this->drupalGet('examples/dbtng'); - $this->assertPattern("/NewFirstName[td\/<>\w]+Anonymous/", t("Text 'NewFirstName Anonymous' found in table")); - - // Try the advanced tab. - $this->drupalGet('examples/dbtng/advanced'); - $rows = $this->xpath("//*[@id='block-system-main']/div/table[1]/tbody/tr"); - $this->assertEqual(count($rows), 1, t("One row found in advanced view")); - $this->assertFieldByXPath("//*[@id='block-system-main']/div/table[1]/tbody/tr/td[4]", "Roe", "Name 'Roe' Exists in advanced list"); - } - - /** - * Test several combinations, adding entries, updating and deleting. - */ - function testAPIExamples() { - // Create a new entry. - $entry = array( - 'name' => 'James', - 'surname' => 'Doe', - 'age' => 23, - ); - dbtng_example_entry_insert($entry); - - // Save another entry - $entry = array( - 'name' => 'Jane', - 'surname' => 'NotDoe', - 'age' => 19, - ); - dbtng_example_entry_insert($entry); - - // Verify that 4 records are found in the database - $result = dbtng_example_entry_load(); - $this->assertEqual( - count($result), - 4, - t('Found a total of four entries in the table after creating two additional entries.') - ); - - // Verify 2 of these records have 'Doe' as surname - $result = dbtng_example_entry_load(array('surname' => 'Doe')); - $this->assertEqual( - count($result), - 2, - t('Found two entries in the table with surname = "Doe".') - ); - - // Now find our not-Doe entry. - $result = dbtng_example_entry_load(array('surname' => 'NotDoe')); - $this->assertEqual( - count($result), - 1, - t('Found one entry in the table with surname "NotDoe')); - // Our NotDoe will be changed to "NowDoe". - $entry = $result[0]; - $entry->surname = "NowDoe"; - dbtng_example_entry_update((array)$entry); - - $result = dbtng_example_entry_load(array('surname' => 'NowDoe')); - $this->assertEqual( - count($result), - 1, - t("Found renamed 'NowDoe' surname")); - - // Read only John Doe entry. - $result = dbtng_example_entry_load(array('name' => 'John', 'surname' => 'Doe')); - $this->assertEqual( - count($result), - 1, - t('Found one entry for John Doe.') - ); - // Get the entry - $entry = (array) end($result); - // Change age to 45 - $entry['age'] = 45; - // Update entry in database - dbtng_example_entry_update((array)$entry); - - // Find entries with age = 45 - // Read only John Doe entry. - $result = dbtng_example_entry_load(array('surname' => 'NowDoe')); - $this->assertEqual( - count($result), - 1, - t('Found one entry with surname = Nowdoe.') - ); - - // Verify it is Jane NowDoe. - $entry = (array) end($result); - $this->assertEqual( - $entry['name'], - 'Jane', - t('The name Jane is found in the entry') - ); - $this->assertEqual( - $entry['surname'], - 'NowDoe', - t('The surname NowDoe is found in the entry') - ); - - // Delete the entry. - dbtng_example_entry_delete($entry); - - // Verify that now there are only 3 records - $result = dbtng_example_entry_load(); - $this->assertEqual( - count($result), - 3, - t('Found only three records, a record was deleted.') - ); - } -} - diff --git a/email_example/CHANGELOG.txt b/email_example/CHANGELOG.txt deleted file mode 100755 index 0e9bee8769234af0a699f1c3cd1a64f158a5e12f..0000000000000000000000000000000000000000 --- a/email_example/CHANGELOG.txt +++ /dev/null @@ -1,2 +0,0 @@ - -#730984 by rfay: Email example (D7) needs to check_plain() on user text. \ No newline at end of file diff --git a/email_example/email_example.info b/email_example/email_example.info deleted file mode 100644 index 4f19e4e5121e2ffbfac859e35a52e71b0b6af02a..0000000000000000000000000000000000000000 --- a/email_example/email_example.info +++ /dev/null @@ -1,6 +0,0 @@ - -name = E-mail Example -description = Demonstrate Drupal's e-mail APIs. -package = Example modules -core = 7.x -files[] = email_example.test diff --git a/email_example/email_example.module b/email_example/email_example.module deleted file mode 100644 index e5ab92a135ac4f719064e5a7cf72f9aeec4a1c54..0000000000000000000000000000000000000000 --- a/email_example/email_example.module +++ /dev/null @@ -1,201 +0,0 @@ - $message['language']->language, - ); - - switch ($key) { - // Send a simple message from the contact form. - case 'contact_message': - $message['subject'] = t('E-mail sent from @site-name', array('@site-name' => variable_get('site_name', 'Drupal')), $options); - // Note that the message body is an array, not a string. - $message['body'][] = t('@name sent you the following message:', array('@name' => $user->name), $options); - // Because this is just user-entered text, we do not need to translate it. - - // Since user-entered text may have unintentional HTML entities in it like - // '<' or '>', we need to make sure these entities are properly escaped, - // as the body will later be transformed from HTML to text, meaning - // that a normal use of '<' will result in truncation of the message. - $message['body'][] = check_plain($params['message']); - break; - } -} - -/** - * Send an e-mail. - * - * @param $form_values - * An array of values from the contact form fields that were submitted. - * There are just two relevant items: $form_values['email'] and - * $form_values['message']. - */ -function email_example_mail_send($form_values) { - // All system mails need to specify the module and template key (mirrored from - // hook_mail()) that the message they want to send comes from. - $module = 'email_example'; - $key = 'contact_message'; - - // Specify 'to' and 'from' addresses. - $to = $form_values['email']; - $from = variable_get('site_mail', 'admin@example.com'); - - // "params" loads in additional context for email content completion in - // hook_mail(). In this case, we want to pass in the values the user entered - // into the form, which include the message body in $form_values['message']. - $params = $form_values; - - // The language of the e-mail. This will one of three values: - // * user_preferred_language(): Used for sending mail to a particular website - // user, so that the mail appears in their preferred language. - // * global $language: Used when sending a mail back to the user currently - // viewing the site. This will send it in the language they're currently - // using. - // * language_default(): Used when sending mail to a pre-existing, 'neutral' - // address, such as the system e-mail address, or when you're unsure of the - // language preferences of the intended recipient. - // - // Since in our case, we are sending a message to a random e-mail address that - // is not necessarily tied to a user account, we will use the site's default - // language. - $language = language_default(); - - // Whether or not to automatically send the mail when drupal_mail() is - // called. This defaults to TRUE, and is normally what you want unless you - // need to do additional processing before drupal_mail_send() is called. - $send = TRUE; - // Send the mail, and check for success. Note that this does not guarantee - // message delivery; only that there were no PHP-related issues encountered - // while sending. - $result = drupal_mail($module, $key, $to, $language, $params, $from, $send); - if ($result['result'] == TRUE) { - drupal_set_message(t('Your message has been sent.')); - } - else { - drupal_set_message(t('There was a problem sending your message and it was not sent.'), 'error'); - } - -} - -/** - * Implement hook_mail_alter(). - * - * This function is not required to send an email using Drupal's mail system. - * - * Hook_mail_alter() provides an interface to alter any aspect of email sent by - * Drupal. You can use this hook to add a common site footer to all outgoing - * email, add extra header fields, and/or modify the email in anyway. HTML-izing - * the outgoing email is one possibility. - */ -function email_example_mail_alter(&$message) { - // For the purpose of this example, modify all the outgoing messages and - // attach a site signature. The signature will be translated to the language - // in which message was built. - $options = array( - 'langcode' => $message['language']->language, - ); - - $signature = t("\n--\nMail altered by email_example module.", array(), $options); - if (is_array($message['body'])) { - $message['body'][] = $signature; - } - else { // Some modules use the body as a string, erroneously. - $message['body'] .= $signature; - } -} - -///// Supporting functions //// - -/** - * Implement hook_menu(). - * - * Set up a page with an e-mail contact form on it. - */ -function email_example_menu() { - $items['example/email_example'] = array( - 'title' => 'E-mail Example: contact form', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('email_example_form'), - 'access arguments' => array('access content'), - ); - - return $items; -} - -/** - * The contact form. - */ -function email_example_form() { - $form['intro'] = array( - '#markup' => t('Use this form to send a message to an e-mail address. No spamming!'), - ); - $form['email'] = array( - '#type' => 'textfield', - '#title' => t('E-mail address'), - '#required' => TRUE, - ); - $form['message'] = array( - '#type' => 'textarea', - '#title' => t('Message'), - '#required' => TRUE, - ); - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Submit'), - ); - - return $form; -} - -/** - * Form validation logic for the contact form. - */ -function email_example_form_validate($form, &$form_state) { - if (!valid_email_address($form_state['values']['email'])) { - form_set_error('email', t('That e-mail address is not valid.')); - } -} - -/** - * Form submission logic for the contact form. - */ -function email_example_form_submit($form, &$form_state) { - email_example_mail_send($form_state['values']); -} diff --git a/email_example/email_example.test b/email_example/email_example.test deleted file mode 100644 index b673670787949783e48eb84404274e6104d5c11c..0000000000000000000000000000000000000000 --- a/email_example/email_example.test +++ /dev/null @@ -1,98 +0,0 @@ - 'Email example', - 'description' => 'Verify the email submission using the contact form.', - 'group' => 'Examples', - ); - } - - function setUp() { - // Enable the email_example module. - parent::setUp('email_example'); - } - - /** - * Verify the functionality of the example module. - */ - function testContactForm() { - // Create and login user. - $account = $this->drupalCreateUser(); - $this->drupalLogin($account); - - // Set default language for t() translations - $t_options = array( - 'langcode' => language_default()->language, - ); - - // First try to send to an invalid email address. - $email_options = array( - 'email' => $this->randomName(), - 'message' => $this->randomName(128), - ); - $result = $this->drupalPost('example/email_example', $email_options, t('Submit')); - - // Verify that email address is invalid and email was not sent. - $this->assertText(t('That e-mail address is not valid.'), t('Options were validated and form submitted.')); - $this->assertTrue(!count($this->drupalGetMails()), t('No email was sent.')); - - // Now try with a valid email address. - $email_options['email'] = $this->randomName() . '@' . $this->randomName() . '.drupal'; - $result = $this->drupalPost('example/email_example', $email_options, t('Submit')); - - // Verify that email address is valid and email was sent. - // $this->assertText(t('Your message has been sent.'), t('Options were validated and form submitted.')); - $this->assertTrue(count($this->drupalGetMails()), t('An email has been sent.')); - - // Validate sent email. - $email = $this->drupalGetMails(); - // Grab the first entry. - $email = $email[0]; - - // Verify email recipient. - $this->assertEqual( - $email['to'], - $email_options['email'], - t('Email recipient successfully verified.') - ); - - // Verify email subject. - $this->assertEqual( - $email['subject'], - t('E-mail sent from @site-name', array('@site-name' => variable_get('site_name', 'Drupal')), $t_options), - t('Email subject successfully verified.') - ); - - // Verify email body. - $this->assertTrue( - strstr( - $email['body'], - t('@name sent you the following message:', array('@name' => $account->name), $t_options) - ), - t('Email body successfully verified.') - ); - - // Verify that signature is attached. - $this->assertTrue( - strstr( - $email['body'], - t("--\nMail altered by email_example module.", array(), $t_options) - ), - t('Email signature successfully verified.') - ); - } -} - diff --git a/examples.index.php b/examples.index.php deleted file mode 100644 index beab81a5e5beb58196d6028f98110b457d562e45..0000000000000000000000000000000000000000 --- a/examples.index.php +++ /dev/null @@ -1,31 +0,0 @@ - array('type' => 'varchar', 'length' => 7, 'not null' => FALSE), - ); - $indexes = array( - 'rgb' => array('rgb'), - ); - return array( - 'columns' => $columns, - 'indexes' => $indexes, - ); -} diff --git a/field_example/field_example.js b/field_example/field_example.js deleted file mode 100644 index a03454f10f482a1c2d030479665b9ddb5e642541..0000000000000000000000000000000000000000 --- a/field_example/field_example.js +++ /dev/null @@ -1,26 +0,0 @@ - -/** - * @file - * Javascript for Field Example. - */ - -/** - * Provide a farbtastic colorpicker for the fancier widget. - */ -(function ($) { - Drupal.behaviors.field_example_colorpicker = { - attach: function(context) { - $(".edit-field-example-colorpicker").live("focus", function(event) { - var edit_field = this; - var picker = $(this).closest('tr').find(".field-example-colorpicker"); - - // Hide all color pickers except this one. - $(".field-example-colorpicker").hide(); - $(picker).show(); - $.farbtastic(picker, function(color) { - edit_field.value = color; - }).setColor(edit_field.value); - }); - } - } -})(jQuery); diff --git a/field_example/field_example.module b/field_example/field_example.module deleted file mode 100644 index 6451d0eb5f7ba4051db34e486b0c771f9941a0fc..0000000000000000000000000000000000000000 --- a/field_example/field_example.module +++ /dev/null @@ -1,320 +0,0 @@ - array( - 'label' => t('Example Color RGB'), - 'description' => t('Demonstrates a field composed of an RGB color.'), - 'default_widget' => 'field_example_3text', - 'default_formatter' => 'field_example_simple_text', - ), - ); -} - -/** - * Implements hook_field_validate(). - * - * Verifies that the RGB field as combined is valid - * (6 hex digits with a # at the beginning). - */ -function field_example_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) { - foreach ($items as $delta => $item) { - if (!empty($item['rgb'])) { - if (! preg_match('@^#[0-9a-f]{6}$@', $item['rgb'])) { - $errors[$field['field_name']][$langcode][$delta][] = array( - 'error' => 'field_example_invalid', - 'message' => t('Color must be in the HTML format #abcdef.'), - ); - } - } - } -} - - -/** - * Implements hook_field_is_empty(). - */ -function field_example_field_is_empty($item, $field) { - return empty($item['rgb']); -} - -/*********************************************************************** - * Field Type API: Formatter - * - * These are the api hooks that present formatted (themed) output to the - * user. - **********************************************************************/ - -/** - * Implements hook_field_formatter_info(). - */ -function field_example_field_formatter_info() { - return array( - // This formatter just displays the hex value in the color indicated. - 'field_example_simple_text' => array( - 'label' => t('Simple text-based formatter'), - 'field types' => array('field_example_rgb'), - ), - // This formatter changes the background color of the content region. - 'field_example_color_background' => array( - 'label' => t('Change the background of the output text'), - 'field types' => array('field_example_rgb'), - ), - ); -} - -/** - * Implements hook_field_formatter_view(). - * - * Two formatters are implemented. - * - field_example_simple_text just outputs markup indicating the color that - * was entered and uses an inline style to set the text color to that value. - * - field_example_color_background does the same but also changes the - * background color of div.region-content. - */ -function field_example_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { - $element = array(); - - switch ($display['type']) { - // This formatter simply outputs the field as text and with a color. - case 'field_example_simple_text': - foreach ($items as $delta => $item) { - $element[$delta]['#markup'] = '

' . t('The color code in this field is @code', array('@code' => $item['rgb'])) . '

'; - } - break; - - // This formatter adds css to the page changing the '.region-content' area's - // background color. If there are many fields, the last one will win. - case 'field_example_color_background': - foreach ($items as $delta => $item) { - drupal_add_css('div.region-content { background-color:' . $item['rgb'] . ';}', array('type' => 'inline') ); - $element[$delta]['#markup'] = '

' . t('The content area color has been changed to @code', array('@code' => $item['rgb'])) . '

'; - } - break; - } - - return $element; -} - - -/************************************************************************** - * Field Type API: Widget - * - * The widget is the form element used to receive input from the user - * when the field is being populated. - **************************************************************************/ - -/** - * Implements hook_field_widget_info(). - * - * Three widgets are provided. - * - A simple text-only widget where the user enters the '#ffffff'. - * - A 3-textfield widget that gathers the red, green, and blue values - * separately. - * - A farbtastic colorpicker widget that chooses the value graphically. - */ -function field_example_field_widget_info() { - return array( - 'field_example_text' => array( - 'label' => t('RGB value as #ffffff'), - 'field types' => array('field_example_rgb'), - ), - 'field_example_3text' => array( - 'label' => t('RGB text field'), - 'field types' => array('field_example_rgb'), - ), - 'field_example_colorpicker' => array( - 'label' => t('Color Picker'), - 'field types' => array('field_example_rgb'), - ), - ); -} - -/** - * Implements hook_field_widget_form(). - * - * Three different forms are provided, for the three widget types. - * - * The 'field_example_colorpicker' and 'field_example_text' are essentially - * the same, but field_example_colorpicker adds a javascript colorpicker - * helper. - * - * field_example_3text displays three text fields, one each for red, green, - * and blue. However, the field type defines a single text column, - * rgb, which needs an HTML color spec. Define an element validate - * handler that converts our r, g, and b fields into a simulated single - * 'rgb' form element. - */ -function field_example_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { - $value = isset($items[$delta]['rgb']) ? $items[$delta]['rgb'] : ''; - $element += array( - '#delta' => $delta, - ); - $element['rgb'] = array(); - - switch ($instance['widget']['type']) { - - case 'field_example_colorpicker': - $element['rgb'] += array( - '#suffix' => '
', - '#attributes' => array('class' => array('edit-field-example-colorpicker')), - '#attached' => array( - // Add Farbtastic color picker. - 'library' => array( - array('system', 'farbtastic'), - ), - // Add javascript to trigger the colorpicker. - 'js' => array(drupal_get_path('module', 'field_example') . '/field_example.js'), - ), - ); - - // DELIBERATE fall-through: From here on the field_example_text and - // field_example_colorpicker are exactly the same. - case 'field_example_text': - $element['rgb'] += array( - '#type' => 'textfield', - '#default_value' => $value, - // Allow a slightly larger size that the field length to allow for some - // configurations where all characters won't fit in input field. - '#size' => 7, - '#maxlength' => 7, - ); - break; - - case 'field_example_3text': - // Convert rgb value into r, g, and b for #default_value. - if (isset($items[$delta]['rgb'])) { - preg_match_all('@..@', substr($items[$delta]['rgb'], 1), $match); - } - else { - $match = array(array()); - } - - // A fieldset to hold the three text fields. - $element += array( - '#type' => 'fieldset', - '#element_validate' => array('field_example_3text_validate'), - - // The following is set so that the validation function will be able - // to access external value information which otherwise would be - // unavailable. - '#delta' => $delta, - '#attached' => array( - 'css' => array(drupal_get_path('module', 'field_example') . '/field_example.css'), - ), - ); - - // Create a textfield for saturation values for Red, Green, and Blue. - foreach (array('r' => t('Red'), 'g' => t('Green'), 'b' => t('Blue')) as $key => $title) { - $element[$key] = array( - '#type' => 'textfield', - '#title' => $title, - '#size' => 2, - '#default_value' => array_shift($match[0]), - '#attributes' => array('class' => array('rgb-entry')), - // '#description' => t('The 2-digit hexadecimal representation of the @color saturation, like "a1" or "ff"', array('@color' => $title)), - ); - } - break; - - } - return $element; -} - - -/** - * Validate the individual fields and then convert them into a single HTML RGB - * value as text. - */ -function field_example_3text_validate($element, &$form_state) { - $delta = $element['#delta']; // TODO: Isn't there a better way to find out which element? - $field = $form_state['field'][$element['#field_name']][$element['#language']]['field']; - $field_name = $field['field_name']; - if (isset($form_state['values'][$field_name][$element['#language']][$delta])) { - $values = $form_state['values'][$field_name][$element['#language']][$delta]; - foreach (array('r', 'g', 'b') as $colorfield) { - $val = hexdec($values[$colorfield]); - // If they left any empty, we'll set the value empty and quit. - if (strlen($values[$colorfield]) == 0) { - form_set_value($element, array('rgb' => NULL), $form_state); - return; - } - // If they gave us anything that's not hex, reject it. - if ( (strlen($values[$colorfield]) != 2) || $val < 0 || $val > 255) { - form_error($element[$colorfield], t("Saturation value must be a 2-digit hexadecimal value between 00 and ff.")); - } - } - - $value = sprintf('#%02s%02s%02s', $values['r'], $values['g'], $values['b']); - form_set_value($element, array('rgb' => $value), $form_state); - } -} - -/** - * Implements hook_field_widget_error(). - */ -function field_example_field_widget_error($element, $error, $form, &$form_state) { - switch ($error['error']) { - case 'field_example_invalid': - form_error($element, $error['message']); - break; - } -} - - -/** - * Implements hook_menu(). - * - * Provides a simple user interface that tells the developer where to go. - */ -function field_example_menu() { - $items['examples/field_example'] = array( - 'title' => 'Field Example', - 'page callback' => '_field_example_page', - 'access callback' => TRUE, - ); - return $items; -} - -/** - * A simple page to explain to the developer what to do. - */ -function _field_example_page() { - return t("The Field Example provides a field composed of an HTML RGB value, like #ff00ff. To use it, add the field to a content type."); -} diff --git a/field_example/field_example.test b/field_example/field_example.test deleted file mode 100644 index a138fbd43ed39d7126993a6dd061cf803ab47bca..0000000000000000000000000000000000000000 --- a/field_example/field_example.test +++ /dev/null @@ -1,144 +0,0 @@ - 'Field Example', - 'description' => 'Create a content type with example_field_rgb fields, create a node, check for correct values.', - 'group' => 'Examples', - ); - } - function setUp() { - // Enable the email_example module. - parent::setUp(array('field_ui', 'field_example')); - } - - /** - * Test basic functionality of the example field. - * - * - Creates a content type. - * - Adds a single-valued field_example_rgb to it. - * - Adds a multivalued field_example_rgb to it. - * - Creates a node of the new type. - * - Populates the single-valued field. - * - Populates the multivalued field with two items. - * - Tests the result. - */ - function testExampleFieldBasic() { - $content_type_friendly = $this->randomName(20); - $content_type_machine = strtolower($this->randomName(10)); - $title = $this->randomName(20); - - // Create and login user. - $account = $this->drupalCreateUser(array('administer content types')); - $this->drupalLogin($account); - - $this->drupalGet('admin/structure/types'); - - // Create the content type. - $this->clickLink(t('Add content type')); - - $single_field_name_friendly = $this->randomName(20); - $single_field_name_machine = strtolower($this->randomName(10)); - - $edit = array ( - 'name' => $content_type_friendly, - 'type' => $content_type_machine, - ); - $this->drupalPost(NULL, $edit, t('Save and add fields')); - $this->assertText(t('The content type @name has been added.', array('@name' => $content_type_friendly))); - - // Now add a singleton field. - $edit = array ( - 'fields[_add_new_field][label]' => $single_field_name_friendly, - 'fields[_add_new_field][field_name]' => $single_field_name_machine, - 'fields[_add_new_field][type]' => 'field_example_rgb', - 'fields[_add_new_field][widget_type]' => 'field_example_3text', - - ); - $this->drupalPost(NULL, $edit, t('Save')); - - // There are no settings for this, so just press the button. - $this->drupalPost(NULL, array(), t('Save field settings')); - - // Using all the default settings, so press the button. - $this->drupalPost(NULL, array(), t('Save settings')); - $this->assertText(t('Saved @name configuration.', array('@name' => $single_field_name_friendly))); - - // Now we're back on the field-add page. - // Now add a multivalued field. - $multivalue_field_name_friendly = $this->randomName(20); - $multivalue_field_name_machine = strtolower($this->randomName(10)); - $edit = array ( - 'fields[_add_new_field][label]' => $multivalue_field_name_friendly, - 'fields[_add_new_field][field_name]' => $multivalue_field_name_machine, - 'fields[_add_new_field][type]' => 'field_example_rgb', - 'fields[_add_new_field][widget_type]' => 'field_example_3text', - ); - $this->drupalPost(NULL, $edit, t('Save')); - - $this->drupalPost(NULL, array(), t('Save field settings')); - - $edit = array('field[cardinality]' => (string)(-1)); - $this->drupalPost(NULL, $edit, t('Save settings')); - - $this->assertText(t('Saved @name configuration.', array('@name' => $multivalue_field_name_friendly))); - - $this->drupalPost(NULL, array(), t('Save')); - - // Somehow clicking "save" isn't enough, and we have to do a - // node_types_rebuild(). - node_types_rebuild(); - menu_rebuild(); - $type_exists = db_query('SELECT 1 FROM {node_type} WHERE type = :type', array(':type' => $content_type_machine))->fetchField(); - $this->assertTrue($type_exists, 'The new content type has been created in the database.'); - - $permission = 'create ' . $content_type_machine . ' content'; - // Reset the permissions cache. - $this->checkPermissions(array($permission), TRUE); - - // Now that we have a new content type, create a user that has privileges - // on the content type. - $account = $this->drupalCreateUser(array($permission)); - $this->drupalLogin($account); - - $this->drupalGet('node/add/' . $content_type_machine); - - // Add a node. - $edit = array( - 'title' => $title, - 'field_' . $single_field_name_machine . '[und][0][r]' => 'ff', - 'field_' . $single_field_name_machine . '[und][0][g]' => '00', - 'field_' . $single_field_name_machine . '[und][0][b]' => '00', - - 'field_' . $multivalue_field_name_machine . '[und][0][r]' => '00', - 'field_' . $multivalue_field_name_machine . '[und][0][g]' => 'ff', - 'field_' . $multivalue_field_name_machine . '[und][0][b]' => '00', - - ); - // We want to add a 2nd item in the multivalue field, so hit "add another". - $this->drupalPost(NULL, $edit, t('Add another item')); - - $edit = array( - 'field_' . $multivalue_field_name_machine . '[und][1][r]' => '00', - 'field_' . $multivalue_field_name_machine . '[und][1][g]' => '00', - 'field_' . $multivalue_field_name_machine . '[und][1][b]' => 'ff', - ); - // Now we can fill in the second item in the multivalue field and save. - $this->drupalPost(NULL, $edit, t('Save')); - $this->assertText(t('@content_type_friendly @title has been created', array('@content_type_friendly' => $content_type_friendly, '@title' => $title))); - - - $output_strings = $this->xpath("//div[contains(@class,'field-type-field-example-rgb')]/div/div/p/text()"); - - $this->assertEqual((string)$output_strings[0], t("The color code in this field is #ff0000"), t('Found first color code #ff0000')); - $this->assertEqual((string)$output_strings[1], t("The color code in this field is #00ff00"), t('Found second color code #00ff00')); - $this->assertEqual((string)$output_strings[2], t("The color code in this field is #0000ff"), t('Found third color code #0000ff')); - } -} diff --git a/file_example/file_example.info b/file_example/file_example.info deleted file mode 100644 index acdca71e50f20671fdf897e72a0db9851b9b8f7e..0000000000000000000000000000000000000000 --- a/file_example/file_example.info +++ /dev/null @@ -1,6 +0,0 @@ -name = File example -description = Examples of using the Drupal File API and Stream Wrappers. -package = Example modules -core = 7.x -files[] = file_example_session_streams.inc -files[] = file_example.test diff --git a/file_example/file_example.module b/file_example/file_example.module deleted file mode 100644 index c7e0224560653b7fa7cfb5d58467f4331ad9e4ce..0000000000000000000000000000000000000000 --- a/file_example/file_example.module +++ /dev/null @@ -1,522 +0,0 @@ - 'File Example', - 'page callback' => 'file_example_intro', - 'access callback' => TRUE, - 'expanded' => TRUE, - ); - $items['examples/file_example/fileapi'] = array( - 'title' => 'Use File API to read/write a file', - 'page callback' => 'drupal_get_form', - 'access arguments' => array('use file example'), - 'page arguments' => array('file_example_readwrite'), - ); - $items['examples/file_example/access_session'] = array( - 'page callback' => 'file_example_session_contents', - 'access arguments' => array('use file example'), - 'type' => MENU_CALLBACK, - ); - return $items; -} - - -/** - * Implements hook_permission(). - */ -function file_example_permission() { - return array( - 'use file example' => array( - 'title' => t('Use the examples in the File Example module'), - ), - ); -} - - -/** - * Form builder function for the file example readwrite and directory creation - * example. - * - * A simple form that allows creation of a file, managed or unmanaged. It - * also allows reading/deleting a file and creation of a directory. - * @ingroup file_example - */ -function file_example_readwrite($form, &$form_state) { - if (empty($_SESSION['file_example_default_file'])) { - $_SESSION['file_example_default_file'] = 'public://drupal.txt'; - } - $default_file = $_SESSION['file_example_default_file']; - if (empty($_SESSION['file_example_default_directory'])) { - $_SESSION['file_example_default_directory'] = 'public://directory1'; - } - $default_directory = $_SESSION['file_example_default_directory']; - - $form['write_file'] = array( - '#type' => 'fieldset', - '#title' => t('Write to a file'), - ); - $form['write_file']['write_contents'] = array( - '#type' => 'textfield', - '#title' => t('Enter something you would like to write to a file') . ' ' . date('m'), - '#default_value' => t('Put some text here or just use this text'), - ); - - $form['write_file']['destination'] = array( - '#type' => 'textfield', - '#default_value' => $default_file, - '#title' => t('Optional: Enter the streamwrapper saying where it should be written'), - '#description' => t('This may be public://some_dir/test_file.txt or private://another_dir/some_file.txt, for example. If you include a directory, it must already exist. The default is "public://". Since this example supports session://, you can also use something like session://somefile.txt.'), - ); - - $form['write_file']['managed_submit'] = array( - '#type' => 'submit', - '#value' => t('Write managed file'), - '#submit' => array('file_example_managed_write_submit'), - ); - $form['write_file']['unmanaged_submit'] = array( - '#type' => 'submit', - '#value' => t('Write unmanaged file'), - '#submit' => array('file_example_unmanaged_write_submit'), - ); - $form['write_file']['unmanaged_php'] = array( - '#type' => 'submit', - '#value' => t('Unmanaged using PHP'), - '#submit' => array('file_example_unmanaged_php_submit'), - ); - - $form['fileops'] = array( - '#type' => 'fieldset', - '#title' => t('Read from a file'), - ); - $form['fileops']['fileops_file'] = array( - '#type' => 'textfield', - '#default_value' => $default_file, - '#title' => t('Enter the URI of a file'), - '#description' => t('This must be a stream-type description like public://some_file.txt or http://drupal.org or private://another_file.txt or (for this example) session://yet_another_file.txt.'), - ); - $form['fileops']['read_submit'] = array( - '#type' => 'submit', - '#value' => t('Read the file and store it locally'), - '#submit' => array('file_example_read_submit'), - ); - $form['fileops']['delete_submit'] = array( - '#type' => 'submit', - '#value' => t('Delete file'), - '#submit' => array('file_example_delete_submit'), - ); - $form['fileops']['check_submit'] = array( - '#type' => 'submit', - '#value' => t('Check to see if file exists'), - '#submit' => array('file_example_file_check_exists_submit'), - ); - - $form['directory'] = array( - '#type' => 'fieldset', - '#title' => t('Create or prepare a directory'), - ); - - $form['directory']['directory_name'] = array( - '#type' => 'textfield', - '#title' => t('Directory to create/prepare/delete'), - '#default_value' => $default_directory, - '#description' => t('This is a directory as in public://some/directory or private://another/dir.'), - ); - $form['directory']['create_directory'] = array( - '#type' => 'submit', - '#value' => t('Create directory'), - '#submit' => array('file_example_create_directory_submit'), - ); - $form['directory']['delete_directory'] = array( - '#type' => 'submit', - '#value' => t('Delete directory'), - '#submit' => array('file_example_delete_directory_submit'), - ); - $form['directory']['check_directory'] = array( - '#type' => 'submit', - '#value' => t('Check to see if directory exists'), - '#submit' => array('file_example_check_directory_submit'), - ); - - $form['debug'] = array( - '#type' => 'fieldset', - '#title' => t('Debugging'), - ); - $form['debug']['show_session'] = array( - '#type' => 'submit', - '#value' => t('Show $_SESSION contents'), - '#submit' => array('file_example_show_session_contents_submit'), - ); - $form['debug']['show_raw_session'] = array( - '#type' => 'submit', - '#value' => t('Show raw $_SESSION contents'), - '#submit' => array('file_example_show_session_contents_submit'), - ); - - return $form; -} - -/** - * Submit handler to write a managed file. - * - * The key functions used here are: - * - file_save_data(), which takes a buffer and saves it to a named file and - * also creates a tracking record in the database and returns a file object. - * In this function we use FILE_EXISTS_RENAME (the default) as the argument, - * which means that if there's an existing file, create a new non-colliding - * filename and use it. - * - file_create_url(), which converts a URI in the form public://junk.txt or - * private://something/test.txt into a URL like - * http://example.com/sites/default/files/junk.txt. - * @ingroup file_example - */ -function file_example_managed_write_submit($form, &$form_state) { - $data = $form_state['values']['write_contents']; - $uri = !empty($form_state['values']['destination']) ? $form_state['values']['destination'] : NULL; - - // Managed operations work with a file object. - $file_object = file_save_data($data, $uri, FILE_EXISTS_RENAME); - if (!empty($file_object)) { - $url = file_create_url($file_object->uri); - $_SESSION['file_example_default_file'] = $file_object->uri; - drupal_set_message(t('Saved managed file: %file to destination %destination (accessible via !url, actual uri=@uri)', array('%file' => print_r($file_object, TRUE), '%destination' => $uri, '@uri' => $file_object->uri, '!url' => l(t('this URL'), $url)))); - } - else { - drupal_set_message(t('Failed to save the managed file'), 'error'); - } -} - -/** - * Submit handler to write an unmanaged file. - * - * The key functions used here are: - * - file_unmanaged_save_data(), which takes a buffer and saves it to a named - * file, but does not create any kind of tracking record in the database. - * This example uses FILE_EXISTS_REPLACE for the third argument, meaning - * that if there's an existing file at this location, it should be replaced. - * - file_create_url(), which converts a URI in the form public://junk.txt or - * private://something/test.txt into a URL like - * http://example.com/sites/default/files/junk.txt. - * @ingroup file_example - */ - -function file_example_unmanaged_write_submit($form, &$form_state) { - $data = $form_state['values']['write_contents']; - $destination = !empty($form_state['values']['destination']) ? $form_state['values']['destination'] : NULL; - - // With the unmanaged file we just get a filename back. - $filename = file_unmanaged_save_data($data, $destination, FILE_EXISTS_REPLACE); - if ($filename) { - $url = file_create_url($filename); - $_SESSION['file_example_default_file'] = $filename; - drupal_set_message(t('Saved file as %filename (accessible via !url, uri=@uri)', array('%filename' => $filename, '@uri' => $filename, '!url' => l(t('this URL'), $url)))); - } - else { - drupal_set_message(t('Failed to save the file'), 'error'); - } -} - - - -/** - * Submit handler to write an unmanaged file using plain PHP functions. - * - * The key functions used here are: - * - file_unmanaged_save_data(), which takes a buffer and saves it to a named - * file, but does not create any kind of tracking record in the database. - * - file_create_url(), which converts a URI in the form public://junk.txt or - * private://something/test.txt into a URL like - * http://example.com/sites/default/files/junk.txt. - * - drupal_tempnam() generates a temporary filename for use. - * @ingroup file_example - */ - -function file_example_unmanaged_php_submit($form, &$form_state) { - $data = $form_state['values']['write_contents']; - $destination = !empty($form_state['values']['destination']) ? $form_state['values']['destination'] : NULL; - - if (empty($destination)) { - // If no destination has been provided, use a generated name. - $destination = drupal_tempnam('public://', 'file'); - } - - // With all traditional PHP functions we can use the stream wrapper notation - // for a file as well. - $fp = fopen($destination, 'w'); - - // To demonstrate the fact that everything is based on streams, we'll do - // multiple 5-character writes to put this to the file. We could easily - // (and far more conveniently) write it in a single statement with - // fwrite($fp, $data). - $length = strlen($data); - $write_size = 5; - for ($i=0; $i < $length; $i += $write_size) { - $result = fwrite($fp, substr($data, $i, $write_size)); - if ($result === FALSE) { - drupal_set_message(t('Failed writing to the file; '), 'error'); - fclose($fp); - return; - } - } - $url = file_create_url($destination); - $_SESSION['file_example_default_file'] = $destination; - drupal_set_message(t('Saved file as %filename (accessible via !url, uri=@uri)', array('%filename' => $destination, '@uri' => $destination, '!url' => l(t('this URL'), $url)))); -} - -/** - * Submit handler for reading a stream wrapper. - * - * Drupal now has full support for PHP's stream wrappers, which means that - * instead of the traditional use of all the file functions - * ($fp = fopen("/tmp/some_file.txt");) far more sophisticated and generalized - * (and extensible) things can be opened as if they were files. Drupal itself - * provides the public:// and private:// schemes for handling public and - * private files. PHP provides file:// (the default) and http://, so that a - * URL can be read or written (as in a POST) as if it were a file. In addition, - * new schemes can be provided for custom applications, as will be demonstrated - * below. - * - * Here we take the stream wrapper provided in the form. We grab the - * contents with file_get_contents(). Notice that's it's as simple as that: - * file_get_contents("http://example.com") or - * file_get_contents("public://somefile.txt") just works. Although it's - * not necessary, we use file_unmanaged_save_data() to save this file locally - * and then find a local URL for it by using file_create_url(). - * @ingroup file_example - */ -function file_example_read_submit($form, &$form_state) { - $uri = $form_state['values']['fileops_file']; - - if (!is_file($uri)) { - drupal_set_message(t('The file %uri does not exist', array('%uri' => $uri)), 'error'); - return; - } - - // Make a working filename to save this by stripping off the (possible) - // file portion of the streamwrapper. If it's an evil file extension, - // file_munge_filename() will neuter it. - $filename = file_munge_filename(preg_replace('@^.*/@', '', $uri), '', TRUE); - $buffer = file_get_contents($uri); - - if ($buffer) { - $sourcename = file_unmanaged_save_data($buffer, 'public://' . $filename); - if ($sourcename) { - $url = file_create_url($sourcename); - $_SESSION['file_example_default_file'] = $sourcename; - drupal_set_message(t('The file was read and copied to %filename which is accessible at !url', array('%filename' => $sourcename, '!url' => l($url, $url)))); - } - else { - drupal_set_message(t('Failed to save the file')); - } - } - else { // We failed to get the contents of the requested file - drupal_set_message(t('Failed to retrieve the file %file', array('%file' => $uri))); - } -} - -/** - * Submit handler to delete a file. - */ -function file_example_delete_submit($form, &$form_state) { - - $uri = $form_state['values']['fileops_file']; - - // Since we don't know if the file is managed or not, look in the database - // to see. Normally, code would be working with either managed or unmanaged - // files, so this is not a typical situation. - $file_object = file_example_get_managed_file($uri); - - // If a managed file, use file_delete(). - if (!empty($file_object)) { - $result = file_delete($file_object); - if ($result !== TRUE) { - drupal_set_message(t('Failed deleting managed file %uri. Result was %result', array('%uri' => $uri, '%result' => print_r($result, TRUE))), 'error'); - } - else { - drupal_set_message(t('Successfully deleted managed file %uri', array('%uri' => $uri))); - $_SESSION['file_example_default_file'] = $uri; - } - } - // else use file_unmanaged_delete(). - else { - $result = file_unmanaged_delete($uri); - if ($result !== TRUE) { - drupal_set_message(t('Failed deleting unmanaged file %uri', array('%uri' => $uri, 'error'))); - } - else { - drupal_set_message(t('Successfully deleted unmanaged file %uri', array('%uri' => $uri))); - $_SESSION['file_example_default_file'] = $uri; - } - } -} - -/** - * Submit handler to check existence of a file. - */ -function file_example_file_check_exists_submit($form, &$form_state) { - $uri = $form_state['values']['fileops_file']; - if (is_file($uri)) { - drupal_set_message(t('The file %uri exists.', array('%uri' => $uri))); - } - else { - drupal_set_message(t('The file %uri does not exist.', array('%uri' => $uri))); - } - -} -/** - * Submit handler for directory creation. - * Here we create a directory and set proper permissions on it using - * file_prepare_directory(). - * @ingroup file_example - */ -function file_example_create_directory_submit($form, &$form_state) { - $directory = $form_state['values']['directory_name']; - - // The options passed to file_prepare_directory are a bitmask, so we can - // specify either FILE_MODIFY_PERMISSIONS (set permissions on the directory), - // FILE_CREATE_DIRECTORY, or both together: - // FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY. - // FILE_MODIFY_PERMISSIONS will set the permissions of the directory by - // by default to 0755, or to the value of the variable 'file_chmod_directory'. - if (!file_prepare_directory($directory, FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY)) { - drupal_set_message(t('Failed to create %directory.', array('%directory' => $directory)), 'error'); - } - else { - $result = is_dir($directory); - drupal_set_message(t('Directory %directory is ready for use.', array('%directory' => $directory))); - $_SESSION['file_example_default_directory'] = $directory; - } -} - -/** - * Submit handler for directory deletion. - * - * @see file_unmanaged_delete_recursive() - * - * @ingroup file_example - */ -function file_example_delete_directory_submit($form, &$form_state) { - $directory = $form_state['values']['directory_name']; - - $result = file_unmanaged_delete_recursive($directory); - if (!$result) { - drupal_set_message(t('Failed to delete %directory.', array('%directory' => $directory)), 'error'); - } - else { - drupal_set_message(t('Recursively deleted directory %directory.', array('%directory' => $directory))); - $_SESSION['file_example_default_directory'] = $directory; - } -} - -/** - * Submit handler to test directory existence. - * This actually just checks to see if the directory is writable - * @param unknown_type $form - * @param unknown_type $form_state - */ -function file_example_check_directory_submit($form, &$form_state) { - $directory = $form_state['values']['directory_name']; - $result = is_dir($directory); - if (!$result) { - drupal_set_message(t('Directory %directory does not exist.', array('%directory' => $directory))); - } - else { - drupal_set_message(t('Directory %directory exists.', array('%directory' => $directory))); - } -} - -/** - * Utility submit function for debugging: Show $_SESSION. - */ -function file_example_show_session_contents_submit($form, &$form_state) { - if ($form_state['triggering_element']['#value'] == t('Show raw $_SESSION contents')) { - drupal_set_message('
' . print_r($_SESSION['file_example'], TRUE) . '
'); - } - else { - return file_example_session_contents(NULL); - } -} - -/** - * Utility function to check for and return a managed file. - * In this demonstration code we don't necessarily know if a file is managed - * or not, so often need to check to do the correct behavior. Normal code - * would not have to do this, as it would be working with either managed or - * unmanaged files. - * - * @param $uri - * The URI of the file, like public://test.txt. - */ -function file_example_get_managed_file($uri) { - $fid = db_query('SELECT fid FROM {file_managed} WHERE uri = :uri', array(':uri' => $uri))->fetchField(); - if (!empty($fid)) { - $file_object = file_load($fid); - return $file_object; - } - return FALSE; -} - -/** - * Implements hook_stream_wrappers(). - * hook_stream_wrappers() is Drupal's way of exposing the class that PHP will - * use to provide a new stream wrapper class. In this case, we'll expose the - * 'session' scheme, so a file reference like "session://example/example.txt" - * is readable and writable as a location in the $_SESSION variable. - * - * @see FileExampleSessionStreamWrapper - * - * defgroup streamwrapper_example Stream Wrapper Example - */ -function file_example_stream_wrappers() { - $wrappers = array( - 'session' => array( - 'name' => t('Example: $_SESSION variable storage'), - 'class' => 'FileExampleSessionStreamWrapper', - 'description' => t('Store files in the $_SESSION variable as an example.'), - ), - ); - return $wrappers; -} - -/** - * A utility function to allow us to see what is in a session "file". - * - * @param $session_path - * The path, as in 'example/some/thing.txt'. This actually is a $_SESSION - * key. example/some/thing.txt would be - * $_SESSION['file_example']['some']['thing.txt'] - */ -function file_example_session_contents() { - if (module_exists('devel')) { - dsm($_SESSION['file_example'], t('Entire $_SESSION["file_example"]')); - } - $path_components = func_get_args(); - $session_path = join('/', $path_components); - $content = file_get_contents('session://' . $session_path); - return t('Contents of ') . check_plain($session_path) . ': ' . print_r($content, TRUE); -} - diff --git a/file_example/file_example.test b/file_example/file_example.test deleted file mode 100644 index b9cbcaf764e94841aa90e84aa519969452582a0f..0000000000000000000000000000000000000000 --- a/file_example/file_example.test +++ /dev/null @@ -1,123 +0,0 @@ - 'File Example Functionality', - 'description' => 'Test File Example features and sample streamwrapper.', - 'group' => 'Examples', - ); - } - function setUp() { - parent::setUp(array('file_example')); - $privileged_user = $this->drupalCreateUser(array('use file example')); - $this->drupalLogin($privileged_user); - } - - /** - * Test the basic File Example UI. - * - Create a directory to work with - * - Foreach scheme create and read files using each of the three methods. - */ - function testFileExampleBasic() { - - $expected_text = array( - t('Write managed file') => t('Saved managed file'), - t('Write unmanaged file') => t('Saved file as'), - t('Unmanaged using PHP') => t('Saved file as'), - ); - // For each of the three buttons == three write types - foreach (array(t('Write managed file'), t('Write unmanaged file'), t('Unmanaged using PHP')) as $button) { - // For each scheme supported by Drupal + the session:// wrapper - foreach (array('public', 'private', 'temporary', 'session') as $scheme) { - // Create a directory for use. - $dirname = $scheme . '://' . $this->randomName(10); - - // Directory does not yet exist; assert that. - $edit = array( - 'directory_name' => $dirname, - ); - $this->drupalPost('examples/file_example/fileapi', $edit, t('Check to see if directory exists')); - $this->assertRaw(t('Directory %dirname does not exist', array('%dirname' => $dirname)), t('Verify that directory does not exist.')); - - $this->drupalPost('examples/file_example/fileapi', $edit, t('Create directory')); - $this->assertRaw(t('Directory %dirname is ready for use', array('%dirname' => $dirname))); - - $this->drupalPost('examples/file_example/fileapi', $edit, t('Check to see if directory exists')); - $this->assertRaw(t('Directory %dirname exists', array('%dirname' => $dirname)), t('Verify that directory now does exist.')); - - // Create a file in the directory we created. - $content = $this->randomName(30); - $filename = $dirname . '/' . $this->randomName(30) . '.txt'; - - // Assert that the file we're about to create does not yet exist. - $edit = array( - 'fileops_file' => $filename, - ); - $this->drupalPost('examples/file_example/fileapi', $edit, t('Check to see if file exists')); - $this->assertRaw(t('The file %filename does not exist', array('%filename' => $filename)), t('Verify that file does not yet exist.')); - - debug(t('Processing button=%button, scheme=%scheme, dir=%dirname, file=%filename', array('%button' => $button, '%scheme' => $scheme, '%filename' => $filename, '%dirname' => $dirname))); - $edit = array( - 'write_contents' => $content, - 'destination' => $filename, - ); - $this->drupalPost('examples/file_example/fileapi', $edit, $button); - $this->assertText($expected_text[$button]); - - - // Capture the name of the output file, as it might have changed due - // to file renaming. - $element = $this->xpath('//span[@id="uri"]'); - $output_filename = (string)$element[0]; - debug($output_filename, 'Name of output file'); - - // Click the link provided that is an easy way to get the data for - // checking and make sure that the data we put in is what we get out. - if (!in_array($scheme, array('private', 'temporary'))) { - $this->clickLink(t('this URL')); - $this->assertText($content); - } - - // Verify that the file exists. - $edit = array( - 'fileops_file' => $filename, - ); - $this->drupalPost('examples/file_example/fileapi', $edit, t('Check to see if file exists')); - $this->assertRaw(t('The file %filename exists', array('%filename' => $filename)), t('Verify that file now exists.')); - - // Now read the file that got written above and verify that we can use - // the writing tools. - $edit = array( - 'fileops_file' => $output_filename, - ); - $this->drupalPost('examples/file_example/fileapi', $edit, t('Read the file and store it locally')); - - $this->assertText(t('The file was read and copied')); - - $edit = array( - 'fileops_file' => $filename, - ); - $this->drupalPost('examples/file_example/fileapi', $edit, t('Delete file')); - $this->assertText(t('Successfully deleted')); - $this->drupalPost('examples/file_example/fileapi', $edit, t('Check to see if file exists')); - $this->assertRaw(t('The file %filename does not exist', array('%filename' => $filename)), t('Verify file has been deleted.')); - - $edit = array( - 'directory_name' => $dirname, - ); - $this->drupalPost('examples/file_example/fileapi', $edit, t('Delete directory')); - $this->drupalPost('examples/file_example/fileapi', $edit, t('Check to see if directory exists')); - $this->assertRaw(t('Directory %dirname does not exist', array('%dirname' => $dirname)), t('Verify that directory does not exist after deletion.')); - } - } - } -} diff --git a/file_example/file_example_session_streams.inc b/file_example/file_example_session_streams.inc deleted file mode 100644 index 4c2e1f69d16f44e927d2d74150bb5891aacc3715..0000000000000000000000000000000000000000 --- a/file_example/file_example_session_streams.inc +++ /dev/null @@ -1,678 +0,0 @@ -uri = $uri; - } - - /** - * Implements getUri(). - */ - function getUri() { - return $this->uri; - } - - /** - * Implements getTarget(). - * The "target" is the portion of the URI to the right of the scheme. - * So in session://example/test.txt, the target is 'example/test.txt'. - */ - function getTarget($uri = NULL) { - if (!isset($uri)) { - $uri = $this->uri; - } - - list($scheme, $target) = explode('://', $uri, 2); - - // Remove erroneous leading or trailing, forward-slashes and backslashes. - // In the session:// scheme, there is never a leading slash on the target. - return trim($target, '\/'); - } - - /** - * Implements getMimeType(). - */ - static function getMimeType($uri, $mapping = NULL) { - if (!isset($mapping)) { - // The default file map, defined in file.mimetypes.inc is quite big. - // We only load it when necessary. - include_once DRUPAL_ROOT . '/includes/file.mimetypes.inc'; - $mapping = file_mimetype_mapping(); - } - - $extension = ''; - $file_parts = explode('.', basename($uri)); - - // Remove the first part: a full filename should not match an extension. - array_shift($file_parts); - - // Iterate over the file parts, trying to find a match. - // For my.awesome.image.jpeg, we try: - // - jpeg - // - image.jpeg, and - // - awesome.image.jpeg - while ($additional_part = array_pop($file_parts)) { - $extension = strtolower($additional_part . ($extension ? '.' . $extension : '')); - if (isset($mapping['extensions'][$extension])) { - return $mapping['mimetypes'][$mapping['extensions'][$extension]]; - } - } - - return 'application/octet-stream'; - } - - /** - * Implements getDirectoryPath(). - * In this case there is no directory string, so return an empty string. - */ - public function getDirectoryPath() { - return ''; - } - - /** - * Overrides getExternalUrl(). - * We have set up a helper function and menu entry to provide access to this - * key via HTTP; normally it would be accessible some other way. - */ - function getExternalUrl() { - $path = $this->getLocalPath(); - $url = url('examples/file_example/access_session/' . $path, array('absolute' => TRUE)); - return $url; - } - - /** - * We have no concept of chmod, so just return TRUE. - */ - function chmod($mode) { - return TRUE; - } - - /** - * Implements realpath(). - */ - function realpath() { - return 'session://' . $this->getLocalPath(); - } - - /** - * Returns the local path. - * Here we aren't doing anything but stashing the "file" in a key in the - * $_SESSION variable, so there's not much to do but to create a "path" - * which is really just a key in the $_SESSION variable. So something - * like 'session://one/two/three.txt' becomes - * $_SESSION['file_example']['one']['two']['three.txt'] and the actual path - * is "one/two/three.txt". - * - * @param $uri - * Optional URI, supplied when doing a move or rename. - */ - protected function getLocalPath($uri = NULL) { - if (!isset($uri)) { - $uri = $this->uri; - } - - $path = str_replace('session://', '', $uri); - $path = trim($path, '/'); - return $path; - } - - /** - * Opens a stream, as for fopen(), file_get_contents(), file_put_contents() - * - * @param $uri - * A string containing the URI to the file to open. - * @param $mode - * The file mode ("r", "wb" etc.). - * @param $options - * A bit mask of STREAM_USE_PATH and STREAM_REPORT_ERRORS. - * @param &$opened_path - * A string containing the path actually opened. - * - * @return - * Returns TRUE if file was opened successfully. (Always returns TRUE). - * - * @see http://php.net/manual/en/streamwrapper.stream-open.php - */ - public function stream_open($uri, $mode, $options, &$opened_path) { - $this->uri = $uri; - - // We make $session_content a reference to the appropriate key in the - // $_SESSION variable. So if the local path were - // /example/test.txt it $session_content would now be a - // reference to $_SESSION['file_example']['example']['test.txt']. - $this->session_content = &$this->uri_to_session_key($uri); - - // Reset the stream pointer since this is an open. - $this->stream_pointer = 0; - return TRUE; - } - - /** - * Return a reference to the correct $_SESSION key. - * @param $uri - * The uri: session://something - * @param $create - * If TRUE, create the key - * - * @return - * TRUE if the key exists (which it will if $create was set) - */ - protected function &uri_to_session_key($uri, $create = TRUE) { - $path = $this->getLocalPath($uri); - $path_components = preg_split('/\//', $path); - $fail = FALSE; - $var = &$_SESSION['file_example']; - // Handle case of just session://. - if (strlen($path) == 0) { - return $var; - } - foreach ($path_components as $component) { - if ($create || isset($var[$component])) { - $var = &$var[$component]; - } - else { - return $fail; - } - } - return $var; - } - /** - * Support for flock(). - * The $_SESSION variable has no locking capability, so return TRUE. - * - * @param $operation - * One of the following: - * - LOCK_SH to acquire a shared lock (reader). - * - LOCK_EX to acquire an exclusive lock (writer). - * - LOCK_UN to release a lock (shared or exclusive). - * - LOCK_NB if you don't want flock() to block while locking (not - * supported on Windows). - * - * @return - * Always returns TRUE at the present time. (no support) - * - * @see http://php.net/manual/en/streamwrapper.stream-lock.php - */ - public function stream_lock($operation) { - return TRUE; - } - - /** - * Support for fread(), file_get_contents() etc. - * - * @param $count - * Maximum number of bytes to be read. - * - * @return - * The string that was read, or FALSE in case of an error. - * - * @see http://php.net/manual/en/streamwrapper.stream-read.php - */ - public function stream_read($count) { - if (is_string($this->session_content)) { - $remaining_chars = strlen($this->session_content) - $this->stream_pointer; - $number_to_read = min($count, $remaining_chars); - if ($remaining_chars > 0) { - $buffer = substr($this->session_content, $this->stream_pointer, $number_to_read); - $this->stream_pointer += $number_to_read; - return $buffer; - } - } - return FALSE; - } - - /** - * Support for fwrite(), file_put_contents() etc. - * - * @param $data - * The string to be written. - * - * @return - * The number of bytes written (integer). - * - * @see http://php.net/manual/en/streamwrapper.stream-write.php - */ - public function stream_write($data) { - // Sanitize the data in a simple way since we're putting it into the - // session variable. - $data = check_plain($data); - $this->session_content = substr_replace($this->session_content, $data, $this->stream_pointer); - $this->stream_pointer += strlen($data); - return strlen($data); - } - - /** - * Support for feof(). - * - * @return - * TRUE if end-of-file has been reached. - * - * @see http://php.net/manual/en/streamwrapper.stream-eof.php - */ - public function stream_eof() { - return FALSE; - } - - /** - * Support for fseek(). - * - * @param $offset - * The byte offset to got to. - * @param $whence - * SEEK_SET, SEEK_CUR, or SEEK_END. - * - * @return - * TRUE on success. - * - * @see http://php.net/manual/en/streamwrapper.stream-seek.php - */ - public function stream_seek($offset, $whence) { - if (strlen($this->session_content) >= $offset) { - $this->stream_pointer = $offset; - return TRUE; - } - return FALSE; - } - - /** - * Support for fflush(). - * - * @return - * TRUE if data was successfully stored (or there was no data to store). - * This always returns TRUE, as this example provides and needs no - * flush support. - * - * @see http://php.net/manual/en/streamwrapper.stream-flush.php - */ - public function stream_flush() { - return TRUE; - } - - /** - * Support for ftell(). - * - * @return - * The current offset in bytes from the beginning of file. - * - * @see http://php.net/manual/en/streamwrapper.stream-tell.php - */ - public function stream_tell() { - return $this->stream_pointer; - } - - /** - * Support for fstat(). - * - * @return - * An array with file status, or FALSE in case of an error - see fstat() - * for a description of this array. - * - * @see http://php.net/manual/en/streamwrapper.stream-stat.php - */ - public function stream_stat() { - return array( - 'size' => drupal_strlen($this->session_content), - ); - } - - /** - * Support for fclose(). - * - * @return - * TRUE if stream was successfully closed. - * - * @see http://php.net/manual/en/streamwrapper.stream-close.php - */ - public function stream_close() { - $this->stream_pointer = 0; - unset($this->session_content); // Unassign the reference. - return TRUE; - } - - /** - * Support for unlink(). - * - * @param $uri - * A string containing the uri to the resource to delete. - * - * @return - * TRUE if resource was successfully deleted. - * - * @see http://php.net/manual/en/streamwrapper.unlink.php - */ - public function unlink($uri) { - $path = $this->getLocalPath($uri); - $path_components = preg_split('/\//', $path); - $fail = FALSE; - $unset = '$_SESSION[\'file_example\']'; - foreach ($path_components as $component) { - $unset .= '[\'' . $component . '\']'; - } - // TODO: Is there a better way to delete from an array? - // drupal_array_get_nested_value() doesn't work because it only returns - // a reference; unsetting a reference only unsets the reference. - eval("unset($unset);"); - return TRUE; - } - - /** - * Support for rename(). - * - * @param $from_uri, - * The uri to the file to rename. - * @param $to_uri - * The new uri for file. - * - * @return - * TRUE if file was successfully renamed. - * - * @see http://php.net/manual/en/streamwrapper.rename.php - */ - public function rename($from_uri, $to_uri) { - $from_key = &$this->uri_to_session_key($from_uri); - $to_key = &$this->uri_to_session_key($to_uri); - if (is_dir($to_key) || is_file($to_key)) { - return FALSE; - } - $to_key = $from_key; - unset($from_key); - return TRUE; - } - - /** - * Gets the name of the directory from a given path. - * - * @param $uri - * A URI. - * - * @return - * A string containing the directory name. - * - * @see drupal_dirname() - */ - public function dirname($uri = NULL) { - list($scheme, $target) = explode('://', $uri, 2); - $target = $this->getTarget($uri); - if (strpos($target, '/')) { - $dirname = preg_replace('@/[^/]*$@', '', $target); - } - else - { - $dirname = ''; - } - return $scheme . '://' . $dirname; - } - - /** - * Support for mkdir(). - * - * @param $uri - * A string containing the URI to the directory to create. - * @param $mode - * Permission flags - see mkdir(). - * @param $options - * A bit mask of STREAM_REPORT_ERRORS and STREAM_MKDIR_RECURSIVE. - * - * @return - * TRUE if directory was successfully created. - * - * @see http://php.net/manual/en/streamwrapper.mkdir.php - */ - public function mkdir($uri, $mode, $options) { - // If this already exists, then we can't mkdir. - if (is_dir($uri) || is_file($uri)) { - return FALSE; - } - - // Create the key in $_SESSION; - $this->uri_to_session_key($uri, TRUE); - - // Place a magic file inside it to differentiate this from an empty file. - $marker_uri = $uri . '/.isadir.txt'; - $this->uri_to_session_key($marker_uri, TRUE); - return TRUE; - } - - /** - * Support for rmdir(). - * - * @param $uri - * A string containing the URI to the directory to delete. - * @param $options - * A bit mask of STREAM_REPORT_ERRORS. - * - * @return - * TRUE if directory was successfully removed. - * - * @see http://php.net/manual/en/streamwrapper.rmdir.php - */ - public function rmdir($uri, $options) { - $path = $this->getLocalPath($uri); - $path_components = preg_split('/\//', $path); - $fail = FALSE; - $unset = '$_SESSION[\'file_example\']'; - foreach ($path_components as $component) { - $unset .= '[\'' . $component . '\']'; - } - // TODO: I really don't like this eval. - debug($unset, 'array element to be unset'); - eval("unset($unset);"); - - return TRUE; - } - - /** - * Support for stat(). - * This important function goes back to the Unix way of doing things. - * In this example almost the entire stat array is irrelevant, but the - * mode is very important. It tells PHP whether we have a file or a - * directory and what the permissions are. All that is packed up in a - * bitmask. This is not normal PHP fodder. - * - * @param $uri - * A string containing the URI to get information about. - * @param $flags - * A bit mask of STREAM_URL_STAT_LINK and STREAM_URL_STAT_QUIET. - * - * @return - * An array with file status, or FALSE in case of an error - see fstat() - * for a description of this array. - * - * @see http://php.net/manual/en/streamwrapper.url-stat.php - */ - public function url_stat($uri, $flags) { - - // PHP does not necessarily construct the object before all operations, - // so here we make sure that the startup work is done. - $this->__construct(); - - $key = $this->uri_to_session_key($uri, FALSE); - $return = FALSE; // Default to fail. - $mode = 0; - - // We will call an array a directory and the root is always an array. - if (is_array($key) && array_key_exists('.isadir.txt', $key)) { - $mode = 0040000; // S_IFDIR means it's a directory. - } - else if ($key !== FALSE) { - $mode = 0100000; // S_IFREG, means it's a file. - } - - if ($mode) { - $size = 0; - if ($mode == 0100000) { - $size = drupal_strlen($key); - } - - $mode |= 0777; // There are no protections on this, so all writable. - $return = array( - 'dev' => 0, - 'ino' => 0, - 'mode' => $mode, - 'nlink' => 0, - 'uid' => 0, - 'gid' => 0, - 'rdev' => 0, - 'size' => $size, - 'atime' => 0, - 'mtime' => 0, - 'ctime' => 0, - 'blksize' => 0, - 'blocks' => 0, - ); - } - return $return; - } - - /** - * Support for opendir(). - * - * @param $uri - * A string containing the URI to the directory to open. - * @param $options - * Unknown (parameter is not documented in PHP Manual). - * - * @return - * TRUE on success. - * - * @see http://php.net/manual/en/streamwrapper.dir-opendir.php - */ - public function dir_opendir($uri, $options) { - $var = &$this->uri_to_session_key($uri, FALSE); - if ($var === FALSE || !array_key_exists('.isadir.txt', $var)) { - return FALSE; - } - - // We grab the list of key names, flip it so that .isadir.txt can easily - // be removed, then flip it back so we can easily walk it as a list. - $this->directory_keys = array_flip(array_keys($var)); - unset($this->directory_keys['.isadir.txt']); - $this->directory_keys = array_keys($this->directory_keys); - $this->directory_pointer = 0; - return TRUE; - } - - /** - * Support for readdir(). - * - * @return - * The next filename, or FALSE if there are no more files in the directory. - * - * @see http://php.net/manual/en/streamwrapper.dir-readdir.php - */ - public function dir_readdir() { - if ($this->directory_pointer < count($this->directory_keys)) { - $next = $this->directory_keys[$this->directory_pointer]; - $this->directory_pointer++; - return $next; - } - return FALSE; - } - - /** - * Support for rewinddir(). - * - * @return - * TRUE on success. - * - * @see http://php.net/manual/en/streamwrapper.dir-rewinddir.php - */ - public function dir_rewinddir() { - $this->directory_pointer = 0; - } - - /** - * Support for closedir(). - * - * @return - * TRUE on success. - * - * @see http://php.net/manual/en/streamwrapper.dir-closedir.php - */ - public function dir_closedir() { - $this->directory_pointer = 0; - unset($this->directory_keys); - return TRUE; - } -} diff --git a/filter_example/filter_example.info b/filter_example/filter_example.info deleted file mode 100755 index 888ee7399112430f7bde4cd64bfa689da8ce2840..0000000000000000000000000000000000000000 --- a/filter_example/filter_example.info +++ /dev/null @@ -1,6 +0,0 @@ - -name = Filter example -description = An example module showing how to define a custom filter. -package = Example modules -core = 7.x -files[] = filter_example.test diff --git a/filter_example/filter_example.module b/filter_example/filter_example.module deleted file mode 100755 index bbf0296cfd2990fa7d6294f27124167d2a54b805..0000000000000000000000000000000000000000 --- a/filter_example/filter_example.module +++ /dev/null @@ -1,176 +0,0 @@ -, and - * replace it by the current time. - */ - -/** - * Implements hook_menu(). - */ -function filter_example_menu() { - $items['examples/filter_example'] = array( - 'title' => 'Filter Example', - 'page callback' => '_filter_example_information', - 'access callback' => TRUE, - ); - return $items; -} - -/** - * Implements hook_filter_info(). - * - * Here we define the diferent filters provided by the module. For this example, - * time_filter is a very static and simple replacement, but it requires some - * preparation of the string because of the special html tags < and >. The - * foo_filter is more complex, including its own settings and inline tips. - */ -function filter_example_filter_info() { - $filters['filter_foo'] = array( - 'title' => t('Foo filter'), - 'description' => t('Every instance of "foo" in the input text will be replaced with a preconfigured replacement.'), - 'process callback' => '_filter_example_filter_foo_process', - 'default settings' => array( - 'filter_example_foo' => 'bar', - ), - 'settings callback' => '_filter_example_filter_foo_settings', - 'tips callback' => '_filter_example_filter_foo_tips', - ); - $filters['filter_time'] = array( - 'title' => t('Time tag'), - 'description' => t('Every instance of the special <time /> tag will be replaced with the current date and time in the user\'s specified time zone.'), - 'prepare callback' => '_filter_example_filter_time_prepare', - 'process callback' => '_filter_example_filter_time_process', - 'tips callback' => '_filter_example_filter_time_tips', - ); - return $filters; -} - -/* - * Foo filter - * - * Drupal has several content formats (they are not filters), and in our example - * the foo replacement can be configured for each one of them, allowing an html - * or php replacement, so the module includes a settings callback, with options - * to configure that replacements. Also, a Tips callback will help showing the - * current replacement for the content type being edited. - */ - -/** - * Simply returns a little bit of information about the example. - */ -function _filter_example_information() { - return t( - "There are two filters in this example. The first (foo filter) just replaces - 'foo' with a configurable replacement. The second replaces the string - '