12

I am using namespaces.

I try to create a WordPress widget (http://codex.wordpress.org/Widgets_API)

With namespaces the following gives an error because the arguments can not be passed (and without namespaces it obviously works like usual)

 namespace a\b\c;
 class whatever extends \WP_Widget {
   function whatever() {
     parent::WP_Widget('name1', 'name2');
   }
 // .. other functions left out
 }
 add_action('widgets_init',
 create_function('', 'return register_widget("a\b\c\whatever");'));

uhm... what is the correct syntax for 'parent::WP_Widget' using namespaces?

(the COMPLETE error message is:

Warning: Missing argument 2 for WP_Widget::__construct(), called in 
C:\xampp\htdocs\wp2\wp-includes\widgets.php on line 324 and defined in 
C:\xampp\htdocs\wp2\wp-includes\widgets.php on line 93

)

And the debugger shows nothing has been passed:

Variables in local scope (#14)
$control_options = Undefined
$id_base = boolean false 
$name = Undefined
$widget_options =  Undefined

(only the $name is required)

3
  • 1
    Post exact error message here. From looking at the code it does not look like there is anything wrong. Also why do you use parent and not just $this->WP_Widget? And lastly, is WP_Widget a constructor of the WP_Widget class? Why does the function have the same name as the class? If its a constructor, then better use __construct() Commented Mar 9, 2011 at 14:39
  • no: there is, the widget factory is part of WordPress since 2.8 : if you click in Eclipse on WP_Widget you get the definition it is in ... core.svn.wordpress.org/trunk/wp-includes/widgets it SHOULD be overwritten and not by _construct, see source code (cant help it did not write it) Commented Mar 9, 2011 at 14:46
  • @dmitri: both parent::WP_Widget and $this->WP_Widget deliver the same error, both variant are used around the web. WP_Widget is the function that should be overwritten according to the CODEX. Commented Mar 9, 2011 at 14:50

6 Answers 6

22

Looking at the documentation located here it seems that only the name is required but the way PHP works your have to have the pre variables defined as well.

You have two ways of creating the class:

  • A:
    • WP_Widget __construct ([string $id_base = false], string $name, [array $widget_options = array()], [array $control_options = array()])
  • B:
    • WP_Widget WP_Widget ([ $id_base = false], $name, [ $widget_options = array()], [ $control_options = array()])

By preference you should always use the __construct method to initialize your object, i would rewrite you code like so:

namespace a\b\c;

class whatever extends \WP_Widget
{
    function __construct()
    {
        parent::__construct('name1', 'name2');
    }

    /*
         * Other methods!
    */
}

The WP_Widget::WP_Widget(..) method is for PHP4 only, and should not be used in PHP 5 or higher.

Now it seems that your using PHP 5.3 as your using name spaces so you can do the following:

add_action('widgets_init', function() {
    return register_widget(new a\b\c\whatever);
});
Sign up to request clarification or add additional context in comments.

5 Comments

the function __construct did the trick thanks, the answer was just a minute later than berry so i marked berry as the answer.
the regiser_widget addition does not work with the \a\b\c\ in it since it is in the namespace scope. If I remove the namespace part it gives "Warning: Illegal offset type in C:\xampp\htdocs\wp2\wp-includes\widgets.php on line 324" so... i use the code in the question for now and will check later on how to do this. thanks.
Just encapsulate the a\b\c\whatever within a string and remove the new keyword, it may be down to the way Wordpress uses the value.
yes that works: add_action('widgets_init',function(){ return register_widget('a\b\c\whatever'); }); thanks
There is a problem with passing false for $id_base (as of WordPress 3.3.1). In wp-admin/includes/widgets.php, $id_base is used as part of a regular expression (line 118), and the backslashes from the namespace will cause problems. I suggest changing your examples to always give an $id_base explicitl, and note it should not contain regular expression meta-characters. In particular, it should not contain dots, which though they may not cause problems as RE meta-characters, will cause problems when converted to underscores in form processing.
3

It seems to me your problem is not in the namespaces, the following code works like a charm:

<?php
namespace Foo;

class Bar {
    function __construct( $foo ) {
        echo "$foo\n";
    }
}

namespace Foo\Bar;

class Foo extends \Foo\Bar {
    function __construct( ) {
        parent::__construct( "This should work." );
    }
}

$foo = new \Foo\Bar\Foo( );

If you get an error message, it might be helpful to state what it says.

4 Comments

@berry-langerak: Good to know its not my syntax GRIN. Then... what is it? The parent class is default: core.svn.wordpress.org/trunk/wp-includes/widgets
It seems Wordpress has a proxy method for the old PHP 4 type constructors (yugh). You might want to consider using parent::__construct( ) instead. Also, when calling __construct( ), be sure to call it with at least two parameters.
Why would you mark an answer as correct when its not even a direct answer to your question, if the comments lead to the resolving of the error, please update your post.
@RobertPitt the code in the answer is the correct code: i needed the function _construct and then in there the parent::_construct as in the answer as opposed to the documentation code here: codex.wordpress.org/Widgets_API
3

You want to call a parent method? Simply use parent::MethodName();

If you want to call the parent constructor, use parent::__construct() - if your constructor is named like the class, rename it to __construct which is the preferred name for a constructor for years...

1 Comment

thanks, i must be missing something im already using parent::WP_Widget() already but im probably overlooking something?
2

This worked fine for me:

add_action('widgets_init', function() {                 
    register_widget('\a\b\c\whatever');
});

1 Comment

register_widget accepts both class name and instance. If you need to use a class name, use \a\b\c\whatever::class instead.
0

You could also use PHP's native get_class method, which will return any class instantiation's name as a string.

https://www.php.net/manual/en/function.get-class.php

register_widget(get_class(new \UCI\Wordpress\Widget\Footer()));

Comments

-1

I don't use Wordpress, but from looking at this it looks like its due to a very bad design of Wordpress. They seem to use static function WP_Widget which serves as a factory but shares the same name as class name. They should have called it factory if it really is just a factory.

Also, from what you posted in your comment, maybe you need to create a static function WP_Widget() in your subclass and then don't even call the parent. If the script really wants you to override the WP_Widget then this is what you should do.

But again, I have never used Wordpress, it's hard to tell without looking at the script.

You should post the exact error code here.

1 Comment

I have posted the complete exact error code, i can add the stack trace?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.