2

I am following a tutorial on wordpress dev, and I try to create a basic widget from the plugin,

So I have put those three files in my plugin directory:

main plugin file (zero.php):

<?php

/*
Plugin Name: Zero plugin
*/

class Zero_Plugin
{
  public function __construct()
  {
    //...
    include_once plugin_dir_path( __FILE__ ).'/newsletter.php';
    include_once plugin_dir_path( __FILE__ ).'/newsletterwidget.php';
    new Zero_Newsletter();
   }
}

newsletterwidget.php:

<?php
class Zero_Newsletter_Widget extends WP_Widget
{
    public function __construct()
    {
        parent::__construct('zero_newsletter', 'Newsletter', array('description' => 'Un formulaire d\'inscription à la newsletter.'));
    }
    public function widget($args, $instance)
    {
        echo 'widget newsletter';
    }
}

newsletter.php:

<?php
include_once plugin_dir_path( __FILE__ ).'/newsletterwidget.php';
class Zero_Newsletter
{
    public function __construct()
    {
        add_action('widgets_init', function(){register_widget('Zero_Newsletter_Widget');});
    }
}

So, when I go on my admin panel, activate the plugin then go in appearance -> widgets I don't find the widget called "Newsletter".

I am stuck here, anyone can help ?

Cheers

  • this is a horriblw code, if you do not understand how to do OOP code, just write functional instead of adding all the pointless clutter. Now to the problems, where do you create a Zero_Plugin object? – Mark Kaplun Aug 26 '17 at 16:01
  • 3
    @MarkKaplun be nice, this is a learning opportunity! Everybody starts out somewhere – Tom J Nowell Aug 26 '17 at 18:28
  • @Henn If I've answered your question to it's fullest extent, could you mark my answer as the accepted solution? Thanks. – Michael Ecklund Oct 12 '17 at 15:40
4

1

In your main plugin file (zero.php), you have invalid instantiation of your plugin object. You're trying to create an object inside an object which doesn't exist yet.

Note: It is possible to create objects within objects, however, you must first create the initial object from the "outside world" (so to speak -- or A/K/A outside of the class).

You can make a pretty simple adjustment to your main plugin file to create your main plugin object. Notice in my version of zero.php, the class is instantiated from the outside?

2

Again, in your main plugin file (zero.php), you're loading both the newsletter (newsletter.php) and the newsletter widget (newsletterwidget.php) . Once your newsletter (newsletter.php) has been loaded, you're loading the newsletter widget (newsletterwidget.php) AGAIN a second time (Redundant and unnecessary). Please observe the file loading and class instantiation changes in my versions of newsletter.php and newsletter-widget.php.

3

Look at your newsletter.php constructor. You really should avoid using anonymous functions (unless you absolutely need to). In this case, it's totally unnecessary to use an anonymous function.


That being said, please see my adjustments and commentary below. Good luck with your innovative plugin idea.


Please pay attention to what the Zero_Plugin class does. It's responsibility is to load the Newsletter file (newsletter.php), instantiate it, and set a property of `newsletter'.

Contents of ./wp-content/plugins/zero/zero.php:

<?php

/*
Plugin Name: Zero plugin
*/


/**
 * Class Zero_Plugin
 *
 * Main plugin file to do whatever it is that your plugin does.
 *
 * @author Michael Ecklund
 * @author_url https://www.michaelbrentecklund.com
 *
 */
class Zero_Plugin {

    /**
     * @var null
     */
    public $newsletter = null;

    /**
     * Zero_Plugin constructor.
     *
     * Load the newsletter functionality.
     *
     * @author Michael Ecklund
     * @author_url https://www.michaelbrentecklund.com
     *
     */
    public function __construct() {

        $this->load_newsletter();

    }

    /**
     * Load the Newsletter file, then instantiate the newsletter class, and assign it a property of this class.
     *
     * @author Michael Ecklund
     * @author_url https://www.michaelbrentecklund.com
     *
     * @return bool
     *
     */
    private function load_newsletter() {

        require_once( plugin_dir_path( __FILE__ ) . '/newsletter.php' );
        $this->newsletter = new Zero_Newsletter();

        return true;

    }

}

# Instantiate the main Plugin class and assign it a variable for reference elsewhere. This creates your plugin object.
$zero_plugin = new Zero_Plugin();

//print_r( $zero_plugin );

?>

Now that the file newsletter.php has been loaded, and the class Zero_Newsletter has been instantiated.

Pay attention to what the Zero_Newsletter class does. It's responsibility is to load the Newsletter Widget file (newsletter-widget.php), instantiate it and set a property of widget.

Contents of ./wp-content/plugins/zero/newsletter.php:

<?php

/**
 * Class Zero_Newsletter
 *
 * Tell WordPress that your plugin has a widget.
 *
 * @author Michael Ecklund
 * @author_url https://www.michaelbrentecklund.com
 *
 */
class Zero_Newsletter {

    /**
     * @var null
     */
    public $widget = null;

    /**
     * Zero_Newsletter constructor.
     *
     * Make sure you have your widget with you, while you stand in line to apply for widget registration with WordPress.
     *
     * @author Michael Ecklund
     * @author_url https://www.michaelbrentecklund.com
     *
     */
    public function __construct() {

        $this->load_newsletter_widget();

        add_action( 'widgets_init', array( $this, 'register_widget' ) );

    }

    /**
     * Load the widget file, then instantiate the widget class, and assign it a property of this class.
     *
     * @author Michael Ecklund
     * @author_url https://www.michaelbrentecklund.com
     *
     * @return bool
     *
     */
    public function load_newsletter_widget() {

        require_once( plugin_dir_path( __FILE__ ) . '/newsletter-widget.php' );
        $this->widget = new Zero_Newsletter_Widget();

        return true;

    }

    /**
     * Tell WordPress about your Widget.
     *
     * @author Michael Ecklund
     * @author_url https://www.michaelbrentecklund.com
     *
     * @return bool
     *
     */
    public function register_widget() {

        if ( ! $this->widget ) {
            return false;
        }

        register_widget( 'Zero_Newsletter_Widget' );

        return true;

    }

}

?>

Now that the file newsletter-widget.php has been loaded, and the class Zero_Newsletter_Widget has been instantiated. You must now apply with WordPress to list your Widget. If you filled adequate information on your registration application with WordPress, then WordPress will approve your application to register your plugin's Widget with it's ecosystem.

Contents of ./wp-content/plugins/zero/newsletter-widget.php:

<?php

/**
 * Class Zero_Newsletter_Widget
 *
 * Tell WordPress about your Plugin's widget.
 *
 * @author Michael Ecklund
 * @author_url https://www.michaelbrentecklund.com
 *
 */
class Zero_Newsletter_Widget extends WP_Widget {

    /**
     * Zero_Newsletter_Widget constructor.
     *
     * Registration application with WordPress. WordPress will either accept or reject your registration application
     * based on the contents of your constructor.
     *
     * @author Michael Ecklund
     * @author_url https://www.michaelbrentecklund.com
     *
     */
    public function __construct() {

        parent::__construct(
            'zero_newsletter',
            'Newsletter',
            array( 'description' => 'Un formulaire d\'inscription à la newsletter.' )
        );

    }

    /**
     * Output the contents of the widget.
     *
     * @author Michael Ecklund
     * @author_url https://www.michaelbrentecklund.com
     *
     * @param array $args
     * @param array $instance
     *
     * @return bool|void
     */
    public function widget( $args, $instance ) {

        echo 'widget newsletter';

        return true;

    }

}

?>

This is the produced structure of your Plugin Object:

Zero_Plugin Object
(
    [newsletter] => Zero_Newsletter Object
        (
            [widget] => Zero_Newsletter_Widget Object
                (
                    [id_base] => zero_newsletter
                    [name] => Newsletter
                    [option_name] => widget_zero_newsletter
                    [alt_option_name] => 
                    [widget_options] => Array
                        (
                            [classname] => widget_zero_newsletter
                            [customize_selective_refresh] => 
                            [description] => Un formulaire d'inscription à la newsletter.
                        )

                    [control_options] => Array
                        (
                            [id_base] => zero_newsletter
                        )

                    [number] => 
                    [id] => 
                    [updated] => 
                )

        )

)

Personally, I'm not much of a fan of pure OOP plugins. I think it's a good idea to use OOP, but only where appropriate. You're going to eventually run into inconsistencies and potential roadblocks doing it this way down the road.

You should mix procedural code with OOP. Only create objects when necessary. Everything doesn't need to be an object inside an object inside an object.

I tested this code and it works. Hope you learned a little bit about OOP and WordPress Development.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.