2
\$\begingroup\$

I am creating tooltips that I will use throughout my site.

Each individual tooltip is created as an object, all of these tooltips need to be ingested with these rules:

  1. I should be able to hold an array with all the tooltips.

  2. Given my array, I should be able to loop through each and call a method to output that tooltip as simple HTML.

Here's how I create a tooltip:

interface Tooltip_Interface {
    public function get_attribute( $attribute );
}

class Tooltip implements Tooltip_Interface {

    public $data;

    public $is_data_processed = false;


    public function __construct( array $data ) {
        $this->data = $data;
    }

    protected function process_data() {

        if( $this->is_data_processed ) {
            return;
        }

        $this->is_data_processed = true;

        $this->data = array_merge([
                'id'        => '',
                'title'     => '',
                'body'      => '',
                'meta'      => ''
        ], $this->data);

        $this->data['id'] = stripslashes($this->data['id']);
        $this->data['title'] = stripcslashes($this->data['title']);
        $this->data['body']  = stripslashes($this->data['body']);
        $this->data['meta']  = stripslashes($this->data['meta']);
    }

    public function get_attribute( $attribute ) {
        $this->process_data();
        return $this->data[$attribute];
    }
}

interface Tooltip_Style_Interface {
    public function get_markup();
}

class Style_1 implements Tooltip_Style_interface {

    public $tooltip;

    public function __construct( Tooltip_Interface $tooltip ){
        $this->tooltip = $tooltip;
    }

    public function get_markup() {
        return sprintf(
            '<div class="nice-tooltip" id=%s><div class="main-body"><h4>%s</h4>%s</div></div><!--%s-->',
            $this->tooltip->get_attribute('id'),
            $this->tooltip->get_attribute('title'),
            $this->tooltip->get_attribute('body'),
            $this->tooltip->get_attribute('meta')
        );
    }
}

Which, in order to output the HTML, I need to call the get_markup method:

echo (new Style_Video
    (
        new Tooltip_Video([
            'id' => 'instagram-help',
            'title' => 'Need help with Instagram?',
            'body' => 'See Our Instagram Help Support Articles.',
            'video'=> 'https://www.youtube.com/watch?v=_Jc-Xcw1nJI',
            'meta' => 'Last update: last year'
        ])
    )
)->get_markup();

But this is somewhat hard-coded. I decided then to turn this into a singleton due to the need to have the shared array of tooltips (shared resource) at hand:

class Tooltip_Register {

    protected $tooltips = [];

    private static $instance;

    private function __construct() {
    }

    public static function get_instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    final function register_tooltip( Tooltip_Style_Interface $tooltip ) {
        $this->tooltips[] = $tooltip;
    }
}

And then have a handler to output all of the tooltips:

final class Tooltip_Handler extends Tooltip_Register {

    public $is_render_finished = false;

    public function __construct() {
    }

    final public function render_tooltips() {
        if( $this->is_render_finished ) {
            return;
        }

        foreach( parent::get_instance()->tooltips as $tooltip ) {
            echo $tooltip->get_markup();
        }

        $this->is_render_finished = true;
    }
}

Which now allows me to add as many Tooltips as I want with this piece of code:

Tooltip_Register::get_instance()->register_tooltip(
    ( new Style_1
        (
            new Tooltip([
                'id' => 'instagram-help',
                'title' => 'This widget is not working?',
                'body' => 'See Our Widgets Videos',
                'meta' => 'Last update: last year'
            ])
        )
    ) 

My problems are that I have to use a singleton which doesn't fare well with dynamicism due to its nature.

Concretely, how can I rewrite this so that I:

  1. Have a nice way to register a tooltip just as I did with Tooltip_Register::get_instance()->register_tooltip().

  2. Have "shared variables" such as Tooltip_Register's $this->tooltips.

\$\endgroup\$
  • \$\begingroup\$ How do you render the template in your application? Do you use a template engine at any point? When exactly is the render_tooltips method called? \$\endgroup\$ – insertusernamehere Mar 9 '18 at 7:53
  • \$\begingroup\$ @insertusernamehere Merely with an echo. The "render tooltips" is the last call of the whole miriad of classes. \$\endgroup\$ – Josh Collins Mar 9 '18 at 13:17
  • \$\begingroup\$ @insertusernamehere pastebin.com/bs0k0caM This is the full code, just for reference. Can ignore "load scripts" and add_action (they're just hooks within WordPress). \$\endgroup\$ – Josh Collins Mar 9 '18 at 16:55

Your Answer

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

Browse other questions tagged or ask your own question.