Skip to content

Commit ce57101

Browse files
Code Modernization: Remove xml_set_object() in AtomParser::parse().
The XML Parser extension still supports a quite dated mechanism for method based callbacks, where the object is first set via `xml_set_object()` and the callbacks are then set by passing only the name of the method to the relevant parameters on any of the `xml_set_*_handler()` functions. {{{ xml_set_object( $parser, $my_obj ); xml_set_character_data_handler( $parser, 'method_name_on_my_obj' ); }}} Passing proper callables to the `xml_set_*_handler()` functions has been supported for the longest time and is cross-version compatible. So the above code is 100% equivalent to: {{{ xml_set_character_data_handler( $parser, [$my_obj, 'method_name_on_my_obj'] ); }}} The mechanism of setting the callbacks with `xml_set_object()` has now been deprecated as of PHP 8.4, in favour of passing proper callables to the `xml_set_*_handler()` functions. This is also means that calling the `xml_set_object()` function is deprecated as well. This commit fixes this deprecation for the `AtomParser::parse()` method. This change is safeguarded via the new `AtomParser_Parse_Test` class. Notes: * Though this is "officially" an external library, this package is no longer externally maintained. The code style of the fix in the source file is in line with the existing code style for the file. * It appears that this class is not actually used by WP Core itself, so it could be considered to deprecate the class. However, as the class is not currently deprecated, safeguarding the change with a test seemed prudent. * The fixture used for the test reuses a fixture from the original package: https://code.google.com/archive/p/phpatomlib/source/default/source * The new test class follows the recommended test format (naming convention of the class, `@covers` tag at class level, only testing one method) as per Trac tickets 62004 / 53010. Refs: * https://wiki.php.net/rfc/deprecations_php_8_4#xml_set_object_and_xml_set_handler_with_string_method_names * https://www.php.net/manual/en/function.xml-set-object.php * https://www.php.net/manual/en/ref.xml.php Follow-up to [5951]. Props jrf. See #62061. git-svn-id: https://develop.svn.wordpress.org/trunk@59062 602fd350-edb4-49c9-b593-d223f7449a82
1 parent f9f19c7 commit ce57101

File tree

3 files changed

+134
-6
lines changed

3 files changed

+134
-6
lines changed

Diff for: src/wp-includes/atomlib.php

+5-6
Original file line numberDiff line numberDiff line change
@@ -157,14 +157,13 @@ function parse() {
157157
}
158158

159159
$parser = xml_parser_create_ns();
160-
xml_set_object($parser, $this);
161-
xml_set_element_handler($parser, "start_element", "end_element");
160+
xml_set_element_handler($parser, array($this, "start_element"), array($this, "end_element"));
162161
xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
163162
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
164-
xml_set_character_data_handler($parser, "cdata");
165-
xml_set_default_handler($parser, "_default");
166-
xml_set_start_namespace_decl_handler($parser, "start_ns");
167-
xml_set_end_namespace_decl_handler($parser, "end_ns");
163+
xml_set_character_data_handler($parser, array($this, "cdata"));
164+
xml_set_default_handler($parser, array($this, "_default"));
165+
xml_set_start_namespace_decl_handler($parser, array($this, "start_ns"));
166+
xml_set_end_namespace_decl_handler($parser, array($this, "end_ns"));
168167

169168
$this->content = '';
170169

Diff for: tests/phpunit/data/feed/AtomParser_Parse_Test.xml

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
Author: Sam Ruby <[email protected]>
4+
-->
5+
6+
<!--
7+
Description: No errors should be produced by the extensive feed
8+
Expect: !Error
9+
-->
10+
11+
<feed xmlns="http://www.w3.org/2005/Atom">
12+
<title type="text">dive into mark</title>
13+
<subtitle type="html">
14+
A &lt;em&gt;lot&lt;/em&gt; of effort
15+
went into making this effortless
16+
</subtitle>
17+
<updated>2005-07-11T12:29:29Z</updated>
18+
<id>tag:example.org,2003:3</id>
19+
<link rel="alternate" type="text/html"
20+
hreflang="en" href="http://example.org/"/>
21+
<link rel="self" type="application/atom+xml"
22+
href="http://example.org/feed.atom"/>
23+
<rights>Copyright (c) 2003, Mark Pilgrim</rights>
24+
<generator uri="http://www.example.com/" version="1.0">
25+
Example Toolkit
26+
</generator>
27+
<entry>
28+
<title>Atom draft-07 snapshot</title>
29+
<link rel="alternate" type="text/html"
30+
href="http://example.org/2005/04/02/atom"/>
31+
<link rel="enclosure" type="audio/mpeg" length="1337"
32+
href="http://example.org/audio/ph34r_my_podcast.mp3"/>
33+
<id>tag:example.org,2003:3.2397</id>
34+
<updated>2005-07-11T12:29:29Z</updated>
35+
<published>2003-12-13T08:29:29-04:00</published>
36+
<author>
37+
<name>Mark Pilgrim</name>
38+
<uri>http://example.org/</uri>
39+
<email>[email protected]</email>
40+
</author>
41+
<contributor>
42+
<name>Sam Ruby</name>
43+
</contributor>
44+
<contributor>
45+
<name>Joe Gregorio</name>
46+
</contributor>
47+
<content type="xhtml" xml:lang="en"
48+
xml:base="http://diveintomark.org/">
49+
<div xmlns="http://www.w3.org/1999/xhtml">
50+
<p><i>[Update: The Atom draft is finished.]</i></p>
51+
</div>
52+
</content>
53+
</entry>
54+
</feed>
+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
/**
3+
* Unit tests covering AtomParser functionality.
4+
*
5+
* @package WordPress
6+
* @subpackage AtomLib
7+
*/
8+
9+
/**
10+
* Test Atom Syndication Format.
11+
*
12+
* @requires extension xml
13+
*
14+
* @covers AtomParser::parse
15+
*/
16+
final class AtomParser_Parse_Test extends WP_UnitTestCase {
17+
18+
/**
19+
* Ensure the class being tested is loaded.
20+
*/
21+
public function set_up() {
22+
require_once dirname( __DIR__, 4 ) . '/src/wp-includes/atomlib.php';
23+
}
24+
25+
/**
26+
* Test that the `AtomParser::parse()` method correctly sets callback functions to handle certain parts of the XML.
27+
*
28+
* Safeguards handling of the PHP 8.4 deprecation of `xml_set_object()`.
29+
*/
30+
public function test_parse_sets_handlers() {
31+
$atom = new class() extends AtomParser {
32+
public $start_element_call_counter = 0;
33+
public $end_element_call_counter = 0;
34+
public $start_ns_call_counter = 0;
35+
public $end_ns_call_counter = 0;
36+
public $cdata_call_counter = 0;
37+
public $default_call_counter = 0;
38+
39+
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.PropertyNotSnakeCase -- Overloading property of upstream class.
40+
public $FILE = __DIR__ . '/../../data/feed/AtomParser_Parse_Test.xml';
41+
42+
public function start_element( $parser, $name, $attrs ) {
43+
++$this->start_element_call_counter;
44+
}
45+
public function end_element( $parser, $name ) {
46+
++$this->end_element_call_counter;
47+
}
48+
public function start_ns( $parser, $prefix, $uri ) {
49+
++$this->start_ns_call_counter;
50+
}
51+
public function end_ns( $parser, $prefix ) {
52+
++$this->end_ns_call_counter;
53+
}
54+
public function cdata( $parser, $data ) {
55+
++$this->cdata_call_counter;
56+
}
57+
public function _default( $parser, $data ) {
58+
++$this->default_call_counter;
59+
}
60+
};
61+
62+
$this->assertTrue( $atom->parse(), 'Parsing of XML file failed' );
63+
64+
// Ensure no errors were logged.
65+
$this->assertNull( $atom->error, 'Unexpected errors encountered' );
66+
67+
$msg = '%s() handler did not get called expected nr of times';
68+
$this->assertSame( 28, $atom->start_element_call_counter, sprintf( $msg, 'start_element' ) );
69+
$this->assertSame( 28, $atom->end_element_call_counter, sprintf( $msg, 'end_element' ) );
70+
$this->assertSame( 2, $atom->start_ns_call_counter, sprintf( $msg, 'start_ns' ) );
71+
$this->assertSame( 0, $atom->end_ns_call_counter, sprintf( $msg, 'end_ns' ) );
72+
$this->assertSame( 57, $atom->cdata_call_counter, sprintf( $msg, 'cdata' ) );
73+
$this->assertSame( 2, $atom->default_call_counter, sprintf( $msg, '_default' ) );
74+
}
75+
}

0 commit comments

Comments
 (0)