diff --git a/mollom.module b/mollom.module index 0113c5f..41af870 100644 --- a/mollom.module +++ b/mollom.module @@ -1464,7 +1464,9 @@ function _mollom_status($reset = FALSE) { * Outputs a warning message about enabled testing mode (once). */ function _mollom_testing_mode_warning() { - $warned = &drupal_static(__FUNCTION__); + // drupal_set_message() starts a session and disables page caching, which + // breaks cache-related tests. Thus, tests set the verbose variable to TRUE. + $warned = &drupal_static(__FUNCTION__, variable_get('mollom_testing_mode_omit_warning', NULL)); if (isset($warned)) { return; } diff --git a/tests/mollom.test b/tests/mollom.test index fa77fda..4240a55 100644 --- a/tests/mollom.test +++ b/tests/mollom.test @@ -125,6 +125,9 @@ class MollomWebTestCase extends DrupalWebTestCase { // automatically create testing API keys. variable_set('mollom_testing_create_keys', $this->createKeys); + // Disable testing mode warnings. + variable_set('mollom_testing_mode_omit_warning', TRUE); + // D7's new default theme Bartik is bogus in various locations, which leads // to failing tests. // @todo Remove this override. @@ -384,6 +387,34 @@ class MollomWebTestCase extends DrupalWebTestCase { } /** + * Saves a mollom_form entity to protect a given form with Mollom. + * + * @param string $form_id + * The form id to protect. + * @param int $mode + * The protection mode. Defaults to MOLLOM_MODE_ANALYSIS. + * @param array $values + * (optional) An associative array of properties to additionally set on the + * mollom_form entity. + * + * @return int + * The save status, as returned by mollom_form_save(). + */ + protected function setProtection($form_id, $mode = MOLLOM_MODE_ANALYSIS, $values = array()) { + if (!$mollom_form = mollom_form_load($form_id)) { + $mollom_form = mollom_form_new($form_id); + } + $mollom_form['mode'] = $mode; + if ($values) { + foreach ($values as $property => $value) { + $mollom_form[$property] = $value; + } + } + $status = mollom_form_save($mollom_form); + return $status; + } + + /** * Configure Mollom protection for a given form. * * @param $form_id @@ -398,7 +429,7 @@ class MollomWebTestCase extends DrupalWebTestCase { * (optional) An array of POST data to pass through to drupalPost() when * configuring the form's protection. */ - protected function setProtection($form_id, $mode = MOLLOM_MODE_ANALYSIS, $fields = NULL, $edit = array()) { + protected function setProtectionUI($form_id, $mode = MOLLOM_MODE_ANALYSIS, $fields = NULL, $edit = array()) { // Always start from overview page, also to make debugging easier. $this->drupalGet('admin/config/content/mollom'); // Determine whether the form is already protected. @@ -911,6 +942,17 @@ class MollomWebTestCase extends DrupalWebTestCase { )); $this->assertNotEqual($first, $second, $message); } + + /** + * Enables aggressive page caching options to resemble reverse-proxies. + */ + protected function enablePageCache() { + variable_set('cache', 1); + variable_set('page_cache_maximum_age', 180); + // A minimum cache lifetime causes cache_clear_all() to start a session. + //variable_set('cache_lifetime', 60); + } + } /** @@ -941,6 +983,9 @@ class MollomTestingModeTestCase extends MollomWebTestCase { function setUp() { parent::setUp(array('mollom', 'mollom_test')); + // Enable testing mode warnings. + variable_del('mollom_testing_mode_omit_warning'); + $this->admin_user = $this->drupalCreateUser(array( 'access administration pages', 'administer mollom', @@ -954,7 +999,7 @@ class MollomTestingModeTestCase extends MollomWebTestCase { $this->drupalLogin($this->admin_user); // Protect mollom_test_form. - $this->setProtection('mollom_test_form', MOLLOM_MODE_ANALYSIS); + $this->setProtectionUI('mollom_test_form', MOLLOM_MODE_ANALYSIS); // Setup production API keys. They must be retained. $publicKey = 'the-invalid-mollom-api-key-value'; @@ -1683,7 +1728,7 @@ class MollomBypassAccessTestCase extends MollomWebTestCase { */ function testBypassAccess() { $this->drupalLogin($this->admin_user); - $this->setProtection('comment_node_article_form'); + $this->setProtectionUI('comment_node_article_form'); $this->drupalLogout(); $node = $this->drupalCreateNode(array('body' => array(LANGUAGE_NONE => array(array('value' => 'node body'))), 'type' => 'article')); @@ -1771,7 +1816,7 @@ class MollomFallbackModeTestCase extends MollomWebTestCase { function testBlock() { // Enable Mollom for the request password form. $this->drupalLogin($this->admin_user); - $this->setProtection('user_pass', MOLLOM_MODE_CAPTCHA); + $this->setProtectionUI('user_pass', MOLLOM_MODE_CAPTCHA); $this->drupalLogout(); // Set the fallback strategy to 'blocking mode'. @@ -1799,7 +1844,7 @@ class MollomFallbackModeTestCase extends MollomWebTestCase { function testAccept() { // Enable Mollom for the request password form. $this->drupalLogin($this->admin_user); - $this->setProtection('user_pass', MOLLOM_MODE_CAPTCHA); + $this->setProtectionUI('user_pass', MOLLOM_MODE_CAPTCHA); $this->drupalLogout(); // Set the fallback strategy to 'accept mode'. @@ -1819,7 +1864,7 @@ class MollomFallbackModeTestCase extends MollomWebTestCase { */ function testFailover() { $this->drupalLogin($this->admin_user); - $this->setProtection('user_pass', MOLLOM_MODE_CAPTCHA); + $this->setProtectionUI('user_pass', MOLLOM_MODE_CAPTCHA); $this->drupalLogout(); // Set the fallback strategy to 'blocking mode', so that if the failover @@ -2089,7 +2134,7 @@ class MollomProfanityTestCase extends MollomWebTestCase { 'mollom[checks][spam]' => TRUE, 'mollom[checks][profanity]' => FALSE, ); - $this->setProtection('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, $edit_config); + $this->setProtectionUI('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, $edit_config); $this->drupalLogout(); // Assert that the profanity filter is disabled. @@ -2107,7 +2152,7 @@ class MollomProfanityTestCase extends MollomWebTestCase { 'mollom[checks][spam]' => FALSE, 'mollom[checks][profanity]' => TRUE, ); - $this->setProtection('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, $edit_config); + $this->setProtectionUI('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, $edit_config); $this->drupalLogout(); // Verify that the profanity filter now blocks this content. @@ -2133,7 +2178,7 @@ class MollomProfanityTestCase extends MollomWebTestCase { 'mollom[checks][profanity]' => TRUE, 'mollom[checks][spam]' => TRUE, ); - $this->setProtection('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, $edit_config); + $this->setProtectionUI('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, $edit_config); $this->drupalLogout(); // Sequence: Post profanity (ham), remove profanity (still ham), and expect @@ -2455,7 +2500,7 @@ class MollomFormConfigurationTestCase extends MollomWebTestCase { function testFormAlter() { // Enable CAPTCHA-only protection for request user password form. $this->drupalLogin($this->admin_user); - $this->setProtection('user_pass', MOLLOM_MODE_CAPTCHA); + $this->setProtectionUI('user_pass', MOLLOM_MODE_CAPTCHA); $this->drupalLogout(); // Verify regular form protection. @@ -2489,7 +2534,7 @@ class MollomUserFormsTestCase extends MollomWebTestCase { // Verify that the protection mode defaults to CAPTCHA. $this->drupalGet('admin/config/content/mollom/add/user_pass'); $this->assertFieldByName('mollom[mode]', MOLLOM_MODE_CAPTCHA); - $this->setProtection('user_pass', MOLLOM_MODE_CAPTCHA); + $this->setProtectionUI('user_pass', MOLLOM_MODE_CAPTCHA); $this->drupalLogout(); // Create a new user. @@ -2517,7 +2562,7 @@ class MollomUserFormsTestCase extends MollomWebTestCase { // Verify that the protection mode defaults to CAPTCHA. $this->drupalGet('admin/config/content/mollom/add/user_register_form'); $this->assertFieldByName('mollom[mode]', MOLLOM_MODE_CAPTCHA); - $this->setProtection('user_register_form', MOLLOM_MODE_CAPTCHA); + $this->setProtectionUI('user_register_form', MOLLOM_MODE_CAPTCHA); $this->drupalLogout(); // Retrieve initial count of registered users. @@ -2576,7 +2621,7 @@ class MollomUserFormsTestCase extends MollomWebTestCase { variable_set('user_register', USER_REGISTER_VISITORS); $this->drupalLogin($this->admin_user); - $this->setProtection('user_register_form', MOLLOM_MODE_ANALYSIS); + $this->setProtectionUI('user_register_form', MOLLOM_MODE_ANALYSIS); $this->drupalLogout(); // Retrieve initial count of registered users. @@ -2627,7 +2672,7 @@ class MollomUserFormsTestCase extends MollomWebTestCase { variable_set('user_register', USER_REGISTER_VISITORS); $this->drupalLogin($this->admin_user); - $this->setProtection('user_register_form', MOLLOM_MODE_ANALYSIS, array(), array( + $this->setProtectionUI('user_register_form', MOLLOM_MODE_ANALYSIS, array(), array( 'mollom[unsure]' => 'moderate', )); $this->drupalLogout(); @@ -2726,7 +2771,7 @@ class MollomProfileFormsTestCase extends MollomWebTestCase { } // Enable text analysis protection for user registration form. - $this->setProtection('user_register_form', MOLLOM_MODE_ANALYSIS); + $this->setProtectionUI('user_register_form', MOLLOM_MODE_ANALYSIS); $this->drupalLogout(); // Test each supported field separately. @@ -2788,7 +2833,7 @@ class MollomNodeFormTestCase extends MollomWebTestCase { function testData() { // Enable Mollom CAPTCHA protection for Article nodes. $this->drupalLogin($this->admin_user); - $this->setProtection('article_node_form', MOLLOM_MODE_CAPTCHA); + $this->setProtectionUI('article_node_form', MOLLOM_MODE_CAPTCHA); $this->drupalLogout(); // Login and submit a node. @@ -2810,7 +2855,7 @@ class MollomNodeFormTestCase extends MollomWebTestCase { */ function testRetain() { $this->drupalLogin($this->admin_user); - $this->setProtection('article_node_form', MOLLOM_MODE_ANALYSIS, NULL, array( + $this->setProtectionUI('article_node_form', MOLLOM_MODE_ANALYSIS, NULL, array( 'mollom[checks][profanity]' => TRUE, 'mollom[discard]' => 0, )); @@ -2844,7 +2889,7 @@ class MollomNodeFormTestCase extends MollomWebTestCase { // Protect the article node type. $this->drupalLogin($this->admin_user); - $this->setProtection('article_node_form', MOLLOM_MODE_ANALYSIS); + $this->setProtectionUI('article_node_form', MOLLOM_MODE_ANALYSIS); $this->drupalLogout(); // Login and submit a protected article node. @@ -2942,7 +2987,7 @@ class MollomCommentFormTestCase extends MollomWebTestCase { function testCaptchaProtectedCommentForm() { // Enable Mollom CAPTCHA protection for comments. $this->drupalLogin($this->admin_user); - $this->setProtection('comment_node_article_form', MOLLOM_MODE_CAPTCHA); + $this->setProtectionUI('comment_node_article_form', MOLLOM_MODE_CAPTCHA); $this->drupalLogout(); // Request the comment reply form. There should be a CAPTCHA form. @@ -2995,7 +3040,7 @@ class MollomCommentFormTestCase extends MollomWebTestCase { function testTextAnalysisProtectedCommentForm() { // Enable Mollom text-classification for comments. $this->drupalLogin($this->admin_user); - $this->setProtection('comment_node_article_form'); + $this->setProtectionUI('comment_node_article_form'); $this->drupalLogout(); // Request the comment reply form. Initially, there should be no CAPTCHA. @@ -3117,7 +3162,7 @@ class MollomContactFormTestCase extends MollomWebTestCase { function testProtectContactUserForm() { // Enable Mollom for the contact form. $this->drupalLogin($this->admin_user); - $this->setProtection('contact_personal_form'); + $this->setProtectionUI('contact_personal_form'); $this->drupalLogout(); $this->drupalLogin($this->web_user); @@ -3147,7 +3192,7 @@ class MollomContactFormTestCase extends MollomWebTestCase { function testProtectContactSiteForm() { // Enable Mollom for the contact form. $this->drupalLogin($this->admin_user); - $this->setProtection('contact_site_form'); + $this->setProtectionUI('contact_site_form'); $this->drupalLogout(); // Add some fields to the contact form so that it is active. @@ -3428,7 +3473,7 @@ class MollomDataTestCase extends MollomWebTestCase { */ function testFormButtonValues() { $this->drupalLogin($this->admin_user); - $this->setProtection('mollom_test_form'); + $this->setProtectionUI('mollom_test_form'); $this->drupalLogout(); // Verify that neither the "Submit" nor the "Add" button value is contained @@ -3463,7 +3508,7 @@ class MollomDataTestCase extends MollomWebTestCase { $this->resetAll(); $this->drupalLogin($this->admin_user); - $this->setProtection('comment_node_article_form'); + $this->setProtectionUI('comment_node_article_form'); // Create a node we can comment on. $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1)); @@ -3558,7 +3603,7 @@ class MollomDataTestCase extends MollomWebTestCase { function testHoneypot() { // Enable protection for mollom_test_form. $this->drupalLogin($this->admin_user); - $this->setProtection('mollom_test_form'); + $this->setProtectionUI('mollom_test_form'); $this->drupalLogout(); // Verify that the hidden honeypot field is output. @@ -3588,7 +3633,7 @@ class MollomDataTestCase extends MollomWebTestCase { // Change form protection to CAPTCHA only. $this->drupalLogin($this->admin_user); - $this->setProtection('mollom_test_form', MOLLOM_MODE_CAPTCHA); + $this->setProtectionUI('mollom_test_form', MOLLOM_MODE_CAPTCHA); $this->drupalLogout(); $this->resetServerRecords(); @@ -3624,7 +3669,7 @@ class MollomDataTestCase extends MollomWebTestCase { function testPostIdMapping() { // Enable protection for mollom_test_form. $this->drupalLogin($this->admin_user); - $this->setProtection('mollom_test_form'); + $this->setProtectionUI('mollom_test_form'); $this->drupalLogout(); // Submit a mollom_test thingy. @@ -3803,7 +3848,7 @@ class MollomAnalysisTestCase extends MollomWebTestCase { */ function testUnsureBinary() { $this->drupalLogin($this->admin_user); - $this->setProtection('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, array( + $this->setProtectionUI('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, array( 'mollom[unsure]' => 'binary', )); $this->drupalLogout(); @@ -3852,12 +3897,12 @@ class MollomAnalysisTestCase extends MollomWebTestCase { $this->drupalLogin($this->admin_user); // Verify that mollom_basic_elements_test_form cannot be configured to put // posts into moderation queue. - $this->setProtection('mollom_basic_elements_test_form'); + $this->setProtectionUI('mollom_basic_elements_test_form'); $this->drupalGet('admin/config/content/mollom/manage/mollom_basic_elements_test_form'); $this->assertNoFieldByName('mollom[unsure]'); // Configure mollom_test_form to retain unsure posts. - $this->setProtection('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, array( + $this->setProtectionUI('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, array( 'mollom[unsure]' => 'moderate', )); $this->drupalLogout(); @@ -3913,12 +3958,12 @@ class MollomAnalysisTestCase extends MollomWebTestCase { $this->drupalLogin($this->admin_user); // Verify that mollom_basic_test_form cannot be configured to put posts into // moderation queue. - $this->setProtection('mollom_basic_elements_test_form'); + $this->setProtectionUI('mollom_basic_elements_test_form'); $this->drupalGet('admin/config/content/mollom/manage/mollom_basic_elements_test_form'); $this->assertNoFieldByName('mollom[discard]'); // Configure mollom_test_form to accept bad posts. - $this->setProtection('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, array( + $this->setProtectionUI('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, array( 'mollom[checks][profanity]' => TRUE, 'mollom[discard]' => 0, )); @@ -4018,6 +4063,63 @@ class MollomAnalysisTestCase extends MollomWebTestCase { } /** + * Tests basic text analysis functionality with enabled caching. + */ +class MollomAnalysisPageCacheTestCase extends MollomWebTestCase { + + protected $disableDefaultSetup = TRUE; + + public static function getInfo() { + return array( + 'name' => 'Text analysis with caching', + 'description' => 'Tests basic text analysis functionality with enabled caching.', + 'group' => 'Mollom', + ); + } + + function setUp() { + parent::setUp(array('mollom', 'mollom_test')); + $this->setKeys(); + $this->assertValidKeys(); + $this->enablePageCache(); + } + + /** + * Tests text analysis. + */ + function testAnalysis() { + $this->setProtection('mollom_test_form'); + // Prime the form + page cache. + $this->drupalGet('mollom-test/form'); + $this->assertText('Views: 1'); + $this->drupalGet('mollom-test/form'); + $this->assertText('Views: 1'); + $this->assertUnsureSubmit(NULL, array('title'), array(), 'Submit'); + + $this->drupalGet('mollom-test/form'); + $this->assertText('Views: 1'); + $this->assertUnsureSubmit(NULL, array('title'), array(), 'Submit'); + + $this->drupalGet('mollom-test/form'); + $this->assertText('Views: 1'); + $this->assertSpamSubmit(NULL, array('title'), array(), 'Submit'); + + $this->drupalGet('mollom-test/form'); + $this->assertText('Views: 1'); + $this->assertHamSubmit(NULL, array('title'), array(), 'Submit'); + } + + /** + * Tests text analysis with additionally enabled Form API cache. + */ + function testAnalysisFormCache() { + variable_set('mollom_test.form.cache', TRUE); + $this->testAnalysis(); + } + +} + +/** * Tests CAPTCHA functionality. */ class MollomCaptchaTestCase extends MollomWebTestCase { @@ -4046,7 +4148,7 @@ class MollomCaptchaTestCase extends MollomWebTestCase { $this->web_user = $this->drupalCreateUser(array()); $this->drupalLogin($this->admin_user); - $this->setProtection('mollom_test_form', MOLLOM_MODE_CAPTCHA); + $this->setProtectionUI('mollom_test_form', MOLLOM_MODE_CAPTCHA); $this->drupalLogout(); } @@ -4189,7 +4291,7 @@ class MollomReportTestCase extends MollomWebTestCase { */ function testReportComment() { $this->drupalLogin($this->admin_user); - $this->setProtection('comment_node_article_form'); + $this->setProtectionUI('comment_node_article_form'); $this->drupalLogout(); $this->node = $this->drupalCreateNode(array('type' => 'article')); @@ -4226,7 +4328,7 @@ class MollomReportTestCase extends MollomWebTestCase { */ function testMassReportComments() { $this->drupalLogin($this->admin_user); - $this->setProtection('comment_node_article_form'); + $this->setProtectionUI('comment_node_article_form'); $this->drupalLogout(); $this->node = $this->drupalCreateNode(array('type' => 'article')); @@ -4292,7 +4394,7 @@ class MollomModerateUserTestCase extends MollomWebTestCase { parent::setUp(); $this->drupalLogin($this->admin_user); - $this->setProtection('user_register_form', MOLLOM_MODE_CAPTCHA); + $this->setProtectionUI('user_register_form', MOLLOM_MODE_CAPTCHA); $this->drupalLogout(); // Allow visitors to register. @@ -4414,7 +4516,7 @@ class MollomModerationIntegrationTestCase extends MollomWebTestCase { parent::setUp(array('mollom_test')); $this->drupalLogin($this->admin_user); - $this->setProtection('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, array( + $this->setProtectionUI('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, array( 'mollom[discard]' => 0, 'mollom[moderation]' => 1, )); @@ -4583,7 +4685,7 @@ class MollomModerationIntegrationTestCase extends MollomWebTestCase { // Test no Mollom moderation access with disabled integration. $this->drupalLogin($this->admin_user); - $this->setProtection('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, array( + $this->setProtectionUI('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, array( 'mollom[moderation]' => FALSE, )); @@ -4593,7 +4695,7 @@ class MollomModerationIntegrationTestCase extends MollomWebTestCase { $record = mollom_test_load($data->id); $this->assertTrue(!empty($record) && $record->status == 0, 'Test post still exists.'); - $this->setProtection('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, array( + $this->setProtectionUI('mollom_test_form', MOLLOM_MODE_ANALYSIS, NULL, array( 'mollom[moderation]' => 1, )); $this->drupalLogout(); @@ -4716,12 +4818,12 @@ class MollomModerationIntegrationTestCase extends MollomWebTestCase { user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('create article content', 'view own unpublished content')); $this->drupalLogin($this->admin_user); - $this->setProtection('user_register_form', MOLLOM_MODE_ANALYSIS, NULL, array( + $this->setProtectionUI('user_register_form', MOLLOM_MODE_ANALYSIS, NULL, array( 'mollom[unsure]' => 'moderate', 'mollom[discard]' => 0, 'mollom[moderation]' => 1, )); - $this->setProtection('article_node_form', MOLLOM_MODE_ANALYSIS, NULL, array( + $this->setProtectionUI('article_node_form', MOLLOM_MODE_ANALYSIS, NULL, array( 'mollom[unsure]' => 'moderate', 'mollom[discard]' => 0, 'mollom[moderation]' => 1, diff --git a/tests/mollom_test.module b/tests/mollom_test.module index 22e34ff..2c6333a 100644 --- a/tests/mollom_test.module +++ b/tests/mollom_test.module @@ -46,6 +46,11 @@ function mollom_test_menu() { 'page arguments' => array('mollom_test_delete_form', 2), 'access callback' => TRUE, ); + $items['mollom-test/form/views/reset'] = array( + 'page callback' => 'mollom_test_views_reset', + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); return $items; } @@ -115,6 +120,15 @@ function mollom_test_mollom_form_info($form_id) { } /** + * Page callback; Resets the mollom_test_form() [page] view counter. + */ +function mollom_test_views_reset() { + variable_del('mollom_test.form.views'); + cache_clear_all(); + drupal_goto(); +} + +/** * Form builder for Mollom test form. */ function mollom_test_form($form, &$form_state, $mid = NULL) { @@ -137,6 +151,19 @@ function mollom_test_form($form, &$form_state, $mid = NULL) { // Always add an empty field the user can submit. $form_state['storage']['field']['new'] = ''; + // Output a page view counter for page/form cache testing purposes. + $count = variable_get('mollom_test.form.views', 1); + $reset_link = l('Reset', 'mollom-test/form/views/reset', array('query' => drupal_get_destination())); + $form['views'] = array( + '#markup' => '

' . 'Views: ' . $count++ . ' ' . $reset_link . '

', + ); + variable_set('mollom_test.form.views', $count); + + // Conditionally enable form caching. + if (variable_get('mollom_test.form.cache', FALSE)) { + $form_state['cache'] = TRUE; + } + $form['#tree'] = TRUE; $form['mid'] = array( '#type' => 'hidden', diff --git a/tests/mollom_test_server.module b/tests/mollom_test_server.module index 7135726..8c54c27 100644 --- a/tests/mollom_test_server.module +++ b/tests/mollom_test_server.module @@ -97,6 +97,9 @@ function mollom_test_server_rest_get_auth_header() { * Delivery callback for REST API endpoints. */ function mollom_test_server_rest_deliver($page_callback_result) { + // All fake-server responses are not cached. + drupal_page_is_cacheable(FALSE); + drupal_add_http_header('Content-Type', 'application/xml; charset=utf-8'); $xml = new DOMDocument('1.0', 'utf-8'); -- 1.7.11.msysgit.1