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:
I should be able to hold an array with all the tooltips.
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:
Have a nice way to register a tooltip just as I did with
Tooltip_Register::get_instance()->register_tooltip()
.Have "shared variables" such as
Tooltip_Register
's$this->tooltips
.
render_tooltips
method called? \$\endgroup\$echo
. The "render tooltips" is the last call of the whole miriad of classes. \$\endgroup\$add_action
(they're just hooks within WordPress). \$\endgroup\$