Index: captcha.admin.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/captcha/captcha.admin.inc,v retrieving revision 1.41 diff -u -p -r1.41 captcha.admin.inc --- captcha.admin.inc 31 Dec 2010 01:45:49 -0000 1.41 +++ captcha.admin.inc 15 Jan 2011 01:43:42 -0000 @@ -66,10 +66,11 @@ function captcha_admin_settings() { ); $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'] = array(); $captcha_type_options = _captcha_available_challenge_types(); - $result = db_select('captcha_points', 'cp')->fields('cp')->orderBy('form_id')->execute(); - foreach ($result as $captcha_point) { - $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'][$captcha_point->form_id] = array(); - $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'][$captcha_point->form_id]['form_id'] = array( + + $captcha_points = captcha_get_captcha_points(); + foreach ($captcha_points as $captcha_point) { + $elem = array(); + $elem['form_id'] = array( '#markup' => $captcha_point->form_id, ); // Select widget for CAPTCHA type. @@ -82,17 +83,25 @@ function captcha_admin_settings() { else { $captcha_type = 'none'; } - $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'][$captcha_point->form_id]['captcha_type'] = array( + $elem['captcha_type'] = array( '#type' => 'select', '#default_value' => $captcha_type, '#options' => $captcha_type_options, ); - // Additional operations. - $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'][$captcha_point->form_id]['operations'] = array( - '#markup' => implode(", ", array( - l(t('delete'), "admin/config/people/captcha/captcha/captcha_point/{$captcha_point->form_id}/delete"), - )) - ); + + $ops = array(); + if (module_exists('ctools') && $captcha_point->export_type & EXPORT_IN_CODE) { + if ($captcha_point->export_type & EXPORT_IN_DATABASE) { + $ops[] = l(t('revert'), "admin/config/people/captcha/captcha/captcha_point/{$captcha_point->form_id}/delete"); + } + // TODO Disable exported points. + } + else { + $ops[] = l(t('delete'), "admin/config/people/captcha/captcha/captcha_point/{$captcha_point->form_id}/delete"); + } + $elem['operations'] = array('#markup' => implode(", ", $ops)); + + $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'][$captcha_point->form_id] = $elem; } // Form items for new form_id. @@ -269,7 +278,30 @@ function captcha_admin_settings_submit($ // Process CAPTCHA points if (isset($form_state['values']['captcha_form_id_overview']['captcha_captcha_points'])) { + // Load existing data. + $captcha_points = captcha_get_captcha_points(); + + foreach ($form_state['values']['captcha_form_id_overview']['captcha_captcha_points'] as $captcha_point_form_id => $data) { + + // If this is an in-code captcha point and its settings are unchanged, + // don't save to the database. + if (module_exists('ctools') && isset($captcha_points[$captcha_point_form_id])) { + // Parse module and captcha_type from submitted values. + if (is_string($data['captcha_type']) && substr_count($data['captcha_type'], '/') == 1) { + list($module, $captcha_type) = explode('/', $data['captcha_type']); + } + else { + $module = ''; + $captcha_type = $data['captcha_type']; + } + + $point = $captcha_points[$captcha_point_form_id]; + if ($point->export_type & EXPORT_IN_CODE && !($point->export_type & EXPORT_IN_DATABASE) && $point->module == $module && $point->captcha_type == $captcha_type) { + continue; + } + } + captcha_set_form_id_setting($captcha_point_form_id, $data['captcha_type']); } } Index: captcha.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/captcha/captcha.inc,v retrieving revision 1.19 diff -u -p -r1.19 captcha.inc --- captcha.inc 31 Dec 2010 01:45:49 -0000 1.19 +++ captcha.inc 15 Jan 2011 01:43:43 -0000 @@ -70,9 +70,16 @@ function captcha_set_form_id_setting($fo * or in the form 'captcha/Math'. */ function captcha_get_form_id_setting($form_id, $symbolic=FALSE) { - $result = db_query("SELECT module, captcha_type FROM {captcha_points} WHERE form_id = :form_id", - array(':form_id' => $form_id)); - $captcha_point = $result->fetchObject(); + if (module_exists('ctools')) { + ctools_include('export'); + $obj = ctools_export_load_object('captcha_points', 'names', array($form_id)); + $captcha_point = array_pop($obj); + } + else { + $result = db_query("SELECT module, captcha_type FROM {captcha_points} WHERE form_id = :form_id", + array(':form_id' => $form_id)); + $captcha_point = $result->fetchObject(); + } if (!$captcha_point) { $captcha_point = NULL; } @@ -95,7 +101,25 @@ function captcha_get_form_id_setting($fo return $captcha_point; } - +/** + * Helper function to load all captcha points. + * + * @return array of all captcha_points + */ +function captcha_get_captcha_points() { + if (module_exists('ctools')) { + ctools_include('export'); + $captcha_points = ctools_export_load_object('captcha_points', 'all'); + } + else { + $captcha_points = array(); + $result = db_select('captcha_points', 'cp')->fields('cp')->orderBy('form_id')->execute(); + foreach ($result as $captcha_point) { + $captcha_points[] = $captcha_point; + } + } + return $captcha_points; +} /** * Helper function for generating a new CAPTCHA session. * Index: captcha.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/captcha/captcha.install,v retrieving revision 1.22 diff -u -p -r1.22 captcha.install --- captcha.install 30 Dec 2010 23:59:07 -0000 1.22 +++ captcha.install 15 Jan 2011 01:43:43 -0000 @@ -13,6 +13,18 @@ function captcha_schema() { // Table for positions and types of the challenges. $schema['captcha_points'] = array( 'description' => 'This table describes which challenges should be added to which forms.', + 'export' => array( + 'key' => 'form_id', + 'identifier' => 'captcha', + 'default hook' => 'captcha_default_points', // Function hook name. + 'status' => 'mark_status', + 'api' => array( + 'owner' => 'captcha', + 'api' => 'captcha', // Base name for api include files. + 'minimum_version' => 1, + 'current_version' => 1, + ), + ), 'fields' => array( 'form_id' => array( 'description' => 'The form_id of the form to add a CAPTCHA to.', @@ -134,25 +146,6 @@ function captcha_requirements($phase) { */ function captcha_install() { $t = get_t(); - // Insert some default CAPTCHA points. - $form_ids = array( - 'contact_site_form', 'contact_personal_form', - 'user_register_form', 'user_pass', 'user_login', 'user_login_block', - 'forum_node_form' - ); - // Add form_ids of all currently known node types too. - foreach (node_type_get_names() as $type => $name) { - $form_ids[] = 'comment_node_' . $type . '_form'; - } - foreach ($form_ids as $form_id) { - db_insert('captcha_points') - ->fields(array( - 'form_id' => $form_id, - 'module' => NULL, - 'captcha_type' => NULL, - )) - ->execute(); - } // Be friendly to your users: what to do after install? drupal_set_message($t('You can now configure the CAPTCHA module for your site.', Index: captcha.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/captcha/captcha.module,v retrieving revision 1.121 diff -u -p -r1.121 captcha.module --- captcha.module 30 Dec 2010 00:29:15 -0000 1.121 +++ captcha.module 15 Jan 2011 01:43:43 -0000 @@ -287,6 +287,53 @@ function captcha_element_process($elemen return $element; } +/** + * Implementation of hook_captcha_default_points_alter(). + * + * Provide some default captchas only if defaults are not already + * provided by other modules. + */ +function captcha_captcha_default_points_alter(&$items) { + $modules = array( + 'comment' => array( + ), + 'contact' => array( + 'contact_site_form', + 'contact_personal_form' + ), + 'forum' => array( + 'forum_node_form', + ), + 'user' => array( + 'user_register_form', + 'user_pass', + 'user_login', + 'user_login_block', + ), + ); + // Add comment form_ids of all currently known node types. + foreach (node_type_get_names() as $type => $name) { + $modules['comment'][] = 'comment_node_' . $type . '_form'; + } + + foreach ($modules as $module => $form_ids) { + // Only give defaults if the module exists. + if (module_exists($module)) { + foreach ($form_ids as $form_id) { + // Ensure a default has not been provided already. + if (!isset($items[$form_id])) { + $captcha = new stdClass; + $captcha->disabled = FALSE; + $captcha->api_version = 1; + $captcha->form_id = $form_id; + $captcha->module = ''; + $captcha->captcha_type = 'default'; + $items[$form_id] = $captcha; + } + } + } + } +} /** * Theme function for a CAPTCHA element.