WordPress.org

Make WordPress Core

Opened 22 months ago

Closed 22 months ago

Last modified 22 months ago

#24770 closed defect (bug) (invalid)

Function "do_items" calls "do_item" with an unexpected parameter

Reported by: riccardo.raneri Owned by:
Milestone: Priority: normal
Severity: normal Version: 2.8
Component: General Keywords: needs-patch 2nd-opinion needs-testing
Focuses: Cc:

Description

file: wp-includes/class.wp-dependencies.php - LINE 49

do_items( $handles = false, $group = false ) calls do_item:

				if ( $this->do_item( $handle, $group ) )
					$this->done[] = $handle;

but do_item( $handle ) wants a single argument:

	function do_item( $handle ) {
		return isset($this->registered[$handle]);
	}

This seems to cause problems with wp_enqueue_script, in fact I can't add already registered libraries (jquery-ui and their plugins), and I encountered a number of users that reported the same problem, eg: http://wordpress.stackexchange.com/questions/73883/why-is-wp-enqueue-script-not-loading-included-jquery-ui-scripts

Removing $group from the parameters seems to fix the problem:

				if ( $this->do_item( $handle ) )
					$this->done[] = $handle;

Change History (5)

comment:1 @ocean9022 months ago

  • Cc azaozz added
  • Severity changed from major to normal
  • Version changed from 3.5.2 to 2.8

Introduced in [10357].

comment:2 follow-up: @azaozz22 months ago

  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed

This is simple class inheritance. The do_item() method in class.wp-dependencies.php is a placeholder meant to be overwritten when extending the class. When handling scripts WP_Dependencies is extended with WP_Scripts. So $this->do_item() executes the do_item() method of WP_Scripts that expects the second argument. (The WP_Dependencies::do_item() is still used in WP_Scripts but note how it's called with parent::do_item($handle).)

Not sure what exactly you're trying to do but enqueueing 'jquery-ui-core' works as expected. It outputs jquery.js, jquery-migrate.js (in 3.6 only), and jquery.ui.core.min.js. However jQuery UI core by itself wouldn't do anything, it's a common component/requirement for the other UI components. For example if you want to use UI accordion, you'll need to also add UI core and widget.

In WordPress this is handled by wp_enqueue_script(). To use accordion you only need to enqueue 'jquery-ui-accordion'. All other scripts that accordion depends on will be added automatically.

comment:3 in reply to: ↑ 2 @riccardo.raneri22 months ago

Replying to azaozz:

This is simple class inheritance. The do_item() method in class.wp-dependencies.php is a placeholder meant to be overwritten when extending the class. When handling scripts WP_Dependencies is extended with WP_Scripts. So $this->do_item() executes the do_item() method of WP_Scripts that expects the second argument. (The WP_Dependencies::do_item() is still used in WP_Scripts but note how it's called with parent::do_item($handle).)

Not sure what exactly you're trying to do but enqueueing 'jquery-ui-core' works as expected. It outputs jquery.js, jquery-migrate.js (in 3.6 only), and jquery.ui.core.min.js. However jQuery UI core by itself wouldn't do anything, it's a common component/requirement for the other UI components. For example if you want to use UI accordion, you'll need to also add UI core and widget.

In WordPress this is handled by wp_enqueue_script(). To use accordion you only need to enqueue 'jquery-ui-accordion'. All other scripts that accordion depends on will be added automatically.

Hi, thank you so much for your answer.

I didn't know about WP_Scripts inheritance of WP_Dependencies, now I see that $group is supported by the do_item() in WP_Scripts.
Anyway, it still doesn't work as expected:

		if ( 0 === $group && $this->groups[$handle] > 0 ) {
			$this->in_footer[] = $handle;
			return false;
		}

This piece of code (line 81-84 in class.wp-scripts.php) makes do_item() return false, so the two scripts that I'm trying to add to the queue aren't added to the HTML page. My theme is a child of twentytwelve, with these lines in its functions.php:

function my_scripts() {
  wp_enqueue_script( 'jquery-ui-core' );
  wp_enqueue_script( 'jquery-ui-datepicker' );
  wp_enqueue_script( 'jquery-ui-i18n-it', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/i18n/jquery.ui.datepicker-it.min.js' );
  
  wp_register_style('jquery-ui', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css');
  wp_enqueue_style( 'jquery-ui' );   
}
add_action( 'wp_enqueue_scripts', 'my_scripts' );

If I remove $group from the parameters in class.wp-dependencies.php, as I described in my first message, everything works. As soon as I restore the original version, every script and css that I'm trying to enqueue disappear.

Sorry, I admit that I'm not deeply experienced with WP core files to understand where the problem is, but this is my experience :)

Version 0, edited 22 months ago by riccardo.raneri (next)

comment:4 follow-up: @azaozz22 months ago

How exactly does this fail for you? Your example code works here. Can see all scripts in the HTML source.

Some notes:

  • Don't need to enqueue jquery-ui-core, it is a dependency of jquery-ui-datepicker so it's enqueued automatically.
  • Can enqueue jquery-ui-datepicker separately or make jquery-ui-i18n-it depend on it. Then it will be handled automatically too.
  • Always a good idea to add scripts in the footer (set the last arg to true).
  • No need of wp_register_style() followed by wp_enqueue_style(). These work the same way as for scripts.

So the example can be reduced to:

  wp_enqueue_script( 'jquery-ui-i18n-it', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/i18n/jquery.ui.datepicker-it.min.js', array('jquery-ui-datepicker'), '1.2.3', true );
  wp_enqueue_style( 'jquery-ui', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css' );

comment:5 in reply to: ↑ 4 @riccardo.raneri22 months ago

Finally, I found my answer: I was using a theme without <?php wp_footer(); ?> in footer.php, so wp_enqueue_script() was called but not inserted into the resulting HTML. I tried to deactivate every plugin, but I didn't think about the theme.
Shame on me!

Azaozz thank you so much for you help, I can confirm that this is not a bug in WP :)

Note: See TracTickets for help on using tickets.