Completed
Branch BUG-11137-domain-base (fa6779)
by
unknown
35:25 queued 23:29
created

EE_Addon::domain()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
use EventEspresso\core\domain\DomainInterface;
4
use EventEspresso\core\domain\RequiresDependencyMapInterface;
5
use EventEspresso\core\domain\RequiresDomainInterface;
6
7
defined('EVENT_ESPRESSO_VERSION') || exit('No direct access allowed.');
8
9
/**
10
 * Class EE_Addon
11
 * Abstract Parent class for all classes that want to function as EE Addons
12
 *
13
 * @package               Event Espresso
14
 * @subpackage            core
15
 * @author                Michael Nelson, Brent Christensen
16
 */
17
abstract class EE_Addon extends EE_Configurable implements RequiresDependencyMapInterface, RequiresDomainInterface
18
{
19
20
21
    /**
22
     * prefix to be added onto an addon's plugin slug to make a wp option name
23
     * which will be used to store the plugin's activation history
24
     */
25
    const ee_addon_version_history_option_prefix = 'ee_version_history_';
26
27
    /**
28
     * @var $_version
29
     * @type string
30
     */
31
    protected $_version = '';
32
33
    /**
34
     * @var $_min_core_version
35
     * @type string
36
     */
37
    protected $_min_core_version = '';
38
39
    /**
40
     * derived from plugin 'main_file_path using plugin_basename()
41
     *
42
     * @type string $_plugin_basename
43
     */
44
    protected $_plugin_basename = '';
45
46
    /**
47
     * A non-internationalized name to identify this addon for use in URLs, etc
48
     *
49
     * @type string $_plugin_slug
50
     */
51
    protected $_plugin_slug = '';
52
53
    /**
54
     * A non-internationalized name to identify this addon. Eg 'Calendar','MailChimp',etc/
55
     *
56
     * @type string _addon_name
57
     */
58
    protected $_addon_name = '';
59
60
    /**
61
     * one of the EE_System::req_type_* constants
62
     *
63
     * @type int $_req_type
64
     */
65
    protected $_req_type;
66
67
    /**
68
     * page slug to be used when generating the "Settings" link on the WP plugin page
69
     *
70
     * @type string $_plugin_action_slug
71
     */
72
    protected $_plugin_action_slug = '';
73
74
    /**
75
     * if not empty, inserts a new table row after this plugin's row on the WP Plugins page
76
     * that can be used for adding upgrading/marketing info
77
     *
78
     * @type array $_plugins_page_row
79
     */
80
    protected $_plugins_page_row = array();
81
82
83
84
    /**
85
     *    filepath to the main file, which can be used for register_activation_hook, register_deactivation_hook, etc.
86
     *
87
     * @type string
88
     */
89
    protected $_main_plugin_file;
90
91
92
    /**
93
     * @var EE_Dependency_Map $dependency_map
94
     */
95
    private $dependency_map;
96
97
98
    /**
99
     * @var DomainInterface $domain
100
     */
101
    private $domain;
102
103
104
    /**
105
     * @param DomainInterface   $domain
106
     * @param EE_Dependency_Map $dependency_map
107
     */
108
    public function __construct(EE_Dependency_Map $dependency_map, DomainInterface $domain = null)
109
    {
110
        $this->setDependencyMap($dependency_map);
111
        $this->setDomain($domain);
112
        add_action('AHEE__EE_System__load_controllers__load_admin_controllers', array($this, 'admin_init'));
113
    }
114
115
116
    /**
117
     * @param EE_Dependency_Map $dependency_map
118
     */
119
    public function setDependencyMap($dependency_map)
120
    {
121
        $this->dependency_map = $dependency_map;
122
    }
123
124
125
    /**
126
     * @return EE_Dependency_Map
127
     */
128
    public function dependencyMap()
129
    {
130
        return $this->dependency_map;
131
    }
132
133
134
    /**
135
     * @param DomainInterface $domain
136
     */
137
    public function setDomain(DomainInterface $domain = null)
138
    {
139
        $this->domain = $domain;
140
    }
141
142
    /**
143
     * @return DomainInterface
144
     */
145
    public function domain()
146
    {
147
        return $this->domain;
148
    }
149
150
151
    /**
152
     * @param mixed $version
153
     */
154
    public function set_version($version = null)
155
    {
156
        $this->_version = $version;
157
    }
158
159
160
    /**
161
     * get__version
162
     *
163
     * @return string
164
     */
165
    public function version()
166
    {
167
        return $this->_version;
168
    }
169
170
171
    /**
172
     * @param mixed $min_core_version
173
     */
174
    public function set_min_core_version($min_core_version = null)
175
    {
176
        $this->_min_core_version = $min_core_version;
177
    }
178
179
180
    /**
181
     * get__min_core_version
182
     *
183
     * @return string
184
     */
185
    public function min_core_version()
186
    {
187
        return $this->_min_core_version;
188
    }
189
190
191
    /**
192
     * Sets addon_name
193
     *
194
     * @param string $addon_name
195
     * @return boolean
196
     */
197
    public function set_name($addon_name)
198
    {
199
        return $this->_addon_name = $addon_name;
200
    }
201
202
203
    /**
204
     * Gets addon_name
205
     *
206
     * @return string
207
     */
208
    public function name()
209
    {
210
        return $this->_addon_name;
211
    }
212
213
214
    /**
215
     * @return string
216
     */
217
    public function plugin_basename()
218
    {
219
220
        return $this->_plugin_basename;
221
    }
222
223
224
    /**
225
     * @param string $plugin_basename
226
     */
227
    public function set_plugin_basename($plugin_basename)
228
    {
229
230
        $this->_plugin_basename = $plugin_basename;
231
    }
232
233
234
    /**
235
     * @return string
236
     */
237
    public function plugin_slug()
238
    {
239
240
        return $this->_plugin_slug;
241
    }
242
243
244
    /**
245
     * @param string $plugin_slug
246
     */
247
    public function set_plugin_slug($plugin_slug)
248
    {
249
250
        $this->_plugin_slug = $plugin_slug;
251
    }
252
253
254
    /**
255
     * @return string
256
     */
257
    public function plugin_action_slug()
258
    {
259
260
        return $this->_plugin_action_slug;
261
    }
262
263
264
    /**
265
     * @param string $plugin_action_slug
266
     */
267
    public function set_plugin_action_slug($plugin_action_slug)
268
    {
269
270
        $this->_plugin_action_slug = $plugin_action_slug;
271
    }
272
273
274
    /**
275
     * @return array
276
     */
277
    public function get_plugins_page_row()
278
    {
279
280
        return $this->_plugins_page_row;
281
    }
282
283
284
    /**
285
     * @param array $plugins_page_row
286
     */
287
    public function set_plugins_page_row($plugins_page_row = array())
288
    {
289
        // sigh.... check for example content that I stupidly merged to master and remove it if found
290
        if (! is_array($plugins_page_row)
291
            && strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
292
        ) {
293
            $plugins_page_row = array();
294
        }
295
        $this->_plugins_page_row = (array) $plugins_page_row;
296
    }
297
298
299
    /**
300
     * Called when EE core detects this addon has been activated for the first time.
301
     * If the site isn't in maintenance mode, should setup the addon's database
302
     *
303
     * @return void
304
     */
305 View Code Duplication
    public function new_install()
306
    {
307
        $classname = get_class($this);
308
        do_action("AHEE__{$classname}__new_install");
309
        do_action('AHEE__EE_Addon__new_install', $this);
310
        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
311
        add_action(
312
            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
313
            array($this, 'initialize_db_if_no_migrations_required')
314
        );
315
    }
316
317
318
    /**
319
     * Called when EE core detects this addon has been reactivated. When this happens,
320
     * it's good to just check that your data is still intact
321
     *
322
     * @return void
323
     */
324 View Code Duplication
    public function reactivation()
325
    {
326
        $classname = get_class($this);
327
        do_action("AHEE__{$classname}__reactivation");
328
        do_action('AHEE__EE_Addon__reactivation', $this);
329
        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
330
        add_action(
331
            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
332
            array($this, 'initialize_db_if_no_migrations_required')
333
        );
334
    }
335
336
337
    /**
338
     * Called when the registered deactivation hook for this addon fires.
339
     * @throws EE_Error
340
     */
341
    public function deactivation()
342
    {
343
        $classname = get_class($this);
344
        do_action("AHEE__{$classname}__deactivation");
345
        do_action('AHEE__EE_Addon__deactivation', $this);
346
        //check if the site no longer needs to be in maintenance mode
347
        EE_Register_Addon::deregister($this->name());
348
        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
349
    }
350
351
352
    /**
353
     * Takes care of double-checking that we're not in maintenance mode, and then
354
     * initializing this addon's necessary initial data. This is called by default on new activations
355
     * and reactivations.
356
     *
357
     * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data.
358
     *                               This is a resource-intensive job so we prefer to only do it when necessary
359
     * @return void
360
     * @throws \EE_Error
361
     */
362
    public function initialize_db_if_no_migrations_required($verify_schema = true)
363
    {
364
        if ($verify_schema === '') {
365
            //wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name
366
            //(ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it
367
            //calls them with an argument of an empty string (ie ""), which evaluates to false
368
            //so we need to treat the empty string as if nothing had been passed, and should instead use the default
369
            $verify_schema = true;
370
        }
371
        if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
372
            if ($verify_schema) {
373
                $this->initialize_db();
374
            }
375
            $this->initialize_default_data();
376
            //@todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe
377
            EE_Data_Migration_Manager::instance()->update_current_database_state_to(
378
                array(
379
                    'slug'    => $this->name(),
380
                    'version' => $this->version(),
381
                )
382
            );
383
            /* make sure core's data is a-ok
384
             * (at the time of writing, we especially want to verify all the caps are present
385
             * because payment method type capabilities are added dynamically, and it's
386
             * possible this addon added a payment method. But it's also possible
387
             * other data needs to be verified)
388
             */
389
            EEH_Activation::initialize_db_content();
390
            update_option('ee_flush_rewrite_rules', true);
391
            //in case there are lots of addons being activated at once, let's force garbage collection
392
            //to help avoid memory limit errors
393
            //EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true );
394
            gc_collect_cycles();
395
        } else {
396
            //ask the data migration manager to init this addon's data
397
            //when migrations are finished because we can't do it now
398
            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name());
399
        }
400
    }
401
402
403
    /**
404
     * Used to setup this addon's database tables, but not necessarily any default
405
     * data in them. The default is to actually use the most up-to-date data migration script
406
     * for this addon, and just use its schema_changes_before_migration() and schema_changes_after_migration()
407
     * methods to setup the db.
408
     */
409
    public function initialize_db()
410
    {
411
        //find the migration script that sets the database to be compatible with the code
412
        $current_dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms($this->name());
413
        if ($current_dms_name) {
414
            $current_data_migration_script = EE_Registry::instance()->load_dms($current_dms_name);
415
            $current_data_migration_script->set_migrating(false);
416
            $current_data_migration_script->schema_changes_before_migration();
417
            $current_data_migration_script->schema_changes_after_migration();
418
            if ($current_data_migration_script->get_errors()) {
419
                foreach ($current_data_migration_script->get_errors() as $error) {
420
                    EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
421
                }
422
            }
423
        }
424
        //if not DMS was found that should be ok. This addon just doesn't require any database changes
425
        EE_Data_Migration_Manager::instance()->update_current_database_state_to(
426
            array(
427
                'slug'    => $this->name(),
428
                'version' => $this->version(),
429
            )
430
        );
431
    }
432
433
434
    /**
435
     * If you want to setup default data for the addon, override this method, and call
436
     * parent::initialize_default_data() from within it. This is normally called
437
     * from EE_Addon::initialize_db_if_no_migrations_required(), just after EE_Addon::initialize_db()
438
     * and should verify default data is present (but this is also called
439
     * on reactivations and just after migrations, so please verify you actually want
440
     * to ADD default data, because it may already be present).
441
     * However, please call this parent (currently it just fires a hook which other
442
     * addons may be depending on)
443
     */
444
    public function initialize_default_data()
445
    {
446
        /**
447
         * Called when an addon is ensuring its default data is set (possibly called
448
         * on a reactivation, so first check for the absence of other data before setting
449
         * default data)
450
         *
451
         * @param EE_Addon $addon the addon that called this
452
         */
453
        do_action('AHEE__EE_Addon__initialize_default_data__begin', $this);
454
        //override to insert default data. It is safe to use the models here
455
        //because the site should not be in maintenance mode
456
    }
457
458
459
    /**
460
     * EE Core detected that this addon has been upgraded. We should check if there
461
     * are any new migration scripts, and if so put the site into maintenance mode until
462
     * they're ran
463
     *
464
     * @return void
465
     */
466 View Code Duplication
    public function upgrade()
467
    {
468
        $classname = get_class($this);
469
        do_action("AHEE__{$classname}__upgrade");
470
        do_action('AHEE__EE_Addon__upgrade', $this);
471
        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
472
        //also it's possible there is new default data that needs to be added
473
        add_action(
474
            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
475
            array($this, 'initialize_db_if_no_migrations_required')
476
        );
477
    }
478
479
480
    /**
481
     * If Core detects this addon has been downgraded, you may want to invoke some special logic here.
482
     */
483
    public function downgrade()
484
    {
485
        $classname = get_class($this);
486
        do_action("AHEE__{$classname}__downgrade");
487
        do_action('AHEE__EE_Addon__downgrade', $this);
488
        //it's possible there's old default data that needs to be double-checked
489
        add_action(
490
            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
491
            array($this, 'initialize_db_if_no_migrations_required')
492
        );
493
    }
494
495
496
    /**
497
     * set_db_update_option_name
498
     * Until we do something better, we'll just check for migration scripts upon
499
     * plugin activation only. In the future, we'll want to do it on plugin updates too
500
     *
501
     * @return bool
502
     */
503
    public function set_db_update_option_name()
504
    {
505
        EE_Error::doing_it_wrong(
506
            __FUNCTION__,
507
            esc_html__(
508
                'EE_Addon::set_db_update_option_name was renamed to EE_Addon::set_activation_indicator_option',
509
                'event_espresso'
510
            ),
511
            '4.3.0.alpha.016'
512
        );
513
        //let's just handle this on the next request, ok? right now we're just not really ready
514
        return $this->set_activation_indicator_option();
515
    }
516
517
518
    /**
519
     * Returns the name of the activation indicator option
520
     * (an option which is set temporarily to indicate that this addon was just activated)
521
     *
522
     * @deprecated since version 4.3.0.alpha.016
523
     * @return string
524
     */
525
    public function get_db_update_option_name()
526
    {
527
        EE_Error::doing_it_wrong(
528
            __FUNCTION__,
529
            esc_html__(
530
                'EE_Addon::get_db_update_option was renamed to EE_Addon::get_activation_indicator_option_name',
531
                'event_espresso'
532
            ),
533
            '4.3.0.alpha.016'
534
        );
535
        return $this->get_activation_indicator_option_name();
536
    }
537
538
539
    /**
540
     * When the addon is activated, this should be called to set a wordpress option that
541
     * indicates it was activated. This is especially useful for detecting reactivations.
542
     *
543
     * @return bool
544
     */
545
    public function set_activation_indicator_option()
546
    {
547
        // let's just handle this on the next request, ok? right now we're just not really ready
548
        return update_option($this->get_activation_indicator_option_name(), true);
549
    }
550
551
552
    /**
553
     * Gets the name of the wp option which is used to temporarily indicate that this addon was activated
554
     *
555
     * @return string
556
     */
557
    public function get_activation_indicator_option_name()
558
    {
559
        return 'ee_activation_' . $this->name();
560
    }
561
562
563
    /**
564
     * Used by EE_System to set the request type of this addon. Should not be used by addon developers
565
     *
566
     * @param int $req_type
567
     */
568
    public function set_req_type($req_type)
569
    {
570
        $this->_req_type = $req_type;
571
    }
572
573
574
    /**
575
     * Returns the request type of this addon (ie, EE_System::req_type_normal, EE_System::req_type_new_activation,
576
     * EE_System::req_type_reactivation, EE_System::req_type_upgrade, or EE_System::req_type_downgrade). This is set by
577
     * EE_System when it is checking for new install or upgrades of addons
578
     */
579
    public function detect_req_type()
580
    {
581
        if (! $this->_req_type) {
582
            $this->detect_activation_or_upgrade();
583
        }
584
        return $this->_req_type;
585
    }
586
587
588
    /**
589
     * Detects the request type for this addon (whether it was just activated, upgrades, a normal request, etc.)
590
     * Should only be called once per request
591
     *
592
     * @return void
593
     */
594
    public function detect_activation_or_upgrade()
595
    {
596
        $activation_history_for_addon = $this->get_activation_history();
597
//		d($activation_history_for_addon);
598
        $request_type = EE_System::detect_req_type_given_activation_history(
599
            $activation_history_for_addon,
600
            $this->get_activation_indicator_option_name(),
601
            $this->version()
602
        );
603
        $this->set_req_type($request_type);
604
        $classname = get_class($this);
605
        switch ($request_type) {
606
            case EE_System::req_type_new_activation:
607
                do_action("AHEE__{$classname}__detect_activations_or_upgrades__new_activation");
608
                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__new_activation', $this);
609
                $this->new_install();
610
                $this->update_list_of_installed_versions($activation_history_for_addon);
611
                break;
612
            case EE_System::req_type_reactivation:
613
                do_action("AHEE__{$classname}__detect_activations_or_upgrades__reactivation");
614
                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__reactivation', $this);
615
                $this->reactivation();
616
                $this->update_list_of_installed_versions($activation_history_for_addon);
617
                break;
618
            case EE_System::req_type_upgrade:
619
                do_action("AHEE__{$classname}__detect_activations_or_upgrades__upgrade");
620
                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__upgrade', $this);
621
                $this->upgrade();
622
                $this->update_list_of_installed_versions($activation_history_for_addon);
623
                break;
624
            case EE_System::req_type_downgrade:
625
                do_action("AHEE__{$classname}__detect_activations_or_upgrades__downgrade");
626
                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__downgrade', $this);
627
                $this->downgrade();
628
                $this->update_list_of_installed_versions($activation_history_for_addon);
629
                break;
630
            case EE_System::req_type_normal:
631
            default:
632
//				$this->_maybe_redirect_to_ee_about();
633
                break;
634
        }
635
636
        do_action("AHEE__{$classname}__detect_if_activation_or_upgrade__complete");
637
    }
638
639
    /**
640
     * Updates the version history for this addon
641
     *
642
     * @param array  $version_history
643
     * @param string $current_version_to_add
644
     * @return boolean success
645
     */
646
    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
647
    {
648
        if (! $version_history) {
649
            $version_history = $this->get_activation_history();
650
        }
651
        if ($current_version_to_add === null) {
652
            $current_version_to_add = $this->version();
653
        }
654
        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
655
        // resave
656
//		echo "updating list of installed versions:".$this->get_activation_history_option_name();d($version_history);
657
        return update_option($this->get_activation_history_option_name(), $version_history);
658
    }
659
660
    /**
661
     * Gets the name of the wp option that stores the activation history
662
     * of this addon
663
     *
664
     * @return string
665
     */
666
    public function get_activation_history_option_name()
667
    {
668
        return self::ee_addon_version_history_option_prefix . $this->name();
669
    }
670
671
672
    /**
673
     * Gets the wp option which stores the activation history for this addon
674
     *
675
     * @return array
676
     */
677
    public function get_activation_history()
678
    {
679
        return get_option($this->get_activation_history_option_name(), null);
680
    }
681
682
683
    /**
684
     * @param string $config_section
685
     */
686
    public function set_config_section($config_section = '')
687
    {
688
        $this->_config_section = ! empty($config_section) ? $config_section : 'addons';
689
    }
690
691
    /**
692
     * Sets the filepath to the main plugin file
693
     *
694
     * @param string $filepath
695
     */
696
    public function set_main_plugin_file($filepath)
697
    {
698
        $this->_main_plugin_file = $filepath;
699
    }
700
701
    /**
702
     * gets the filepath to teh main file
703
     *
704
     * @return string
705
     */
706
    public function get_main_plugin_file()
707
    {
708
        return $this->_main_plugin_file;
709
    }
710
711
    /**
712
     * Gets the filename (no path) of the main file (the main file loaded
713
     * by WP)
714
     *
715
     * @return string
716
     */
717
    public function get_main_plugin_file_basename()
718
    {
719
        return plugin_basename($this->get_main_plugin_file());
720
    }
721
722
    /**
723
     * Gets the folder name which contains the main plugin file
724
     *
725
     * @return string
726
     */
727
    public function get_main_plugin_file_dirname()
728
    {
729
        return dirname($this->get_main_plugin_file());
730
    }
731
732
733
    /**
734
     * sets hooks used in the admin
735
     *
736
     * @return void
737
     */
738
    public function admin_init()
739
    {
740
        // is admin and not in M-Mode ?
741
        if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
742
            add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
743
            add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
744
        }
745
    }
746
747
748
    /**
749
     * plugin_actions
750
     * Add a settings link to the Plugins page, so people can go straight from the plugin page to the settings page.
751
     *
752
     * @param $links
753
     * @param $file
754
     * @return array
755
     */
756
    public function plugin_action_links($links, $file)
757
    {
758
        if ($file === $this->plugin_basename() && $this->plugin_action_slug() !== '') {
759
            // before other links
760
            array_unshift(
761
                $links,
762
                '<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
763
                . esc_html__('Settings', 'event_espresso')
764
                . '</a>'
765
            );
766
        }
767
        return $links;
768
    }
769
770
771
    /**
772
     * after_plugin_row
773
     * Add additional content to the plugins page plugin row
774
     * Inserts another row
775
     *
776
     * @param $plugin_file
777
     * @param $plugin_data
778
     * @param $status
779
     * @return void
780
     */
781
    public function after_plugin_row($plugin_file, $plugin_data, $status)
782
    {
783
        $after_plugin_row = '';
784
        $plugins_page_row = $this->get_plugins_page_row();
785
        if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
786
            $class            = $status ? 'active' : 'inactive';
787
            $link_text        = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
788
            $link_url         = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
789
            $description      = isset($plugins_page_row['description'])
790
                ? $plugins_page_row['description']
791
                : '';
792
            if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
793
                $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
794
                $after_plugin_row .= '<th class="check-column" scope="row"></th>';
795
                $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
796
                $after_plugin_row .= '<style>
797
.ee-button,
798
.ee-button:active,
799
.ee-button:visited {
800
	box-sizing: border-box;
801
	display: inline-block;
802
	position: relative;
803
	top: -1px;
804
	padding:.5em 1em;
805
	margin: 0;
806
	background: #00B1CA -webkit-linear-gradient( #4EBFDE, #00B1CA ); /* For Safari 5.1 to 6.0 */
807
	background: #00B1CA -o-linear-gradient( #4EBFDE, #00B1CA ); /* For Opera 11.1 to 12.0 */
808
	background: #00B1CA -moz-linear-gradient( #4EBFDE, #00B1CA ); /* For Firefox 3.6 to 15 */
809
	background: #00B1CA linear-gradient( #4EBFDE, #00B1CA ); /* Standard syntax */
810
	border: 1px solid rgba(0,0,0,0.1) !important;
811
	border-top: 1px solid rgba(255,255,255,0.5) !important;
812
	border-bottom: 2px solid rgba(0,0,0,0.25) !important;
813
	font-weight: normal;
814
	cursor: pointer;
815
	color: #fff !important;
816
	text-decoration: none !important;
817
	text-align: center;
818
	line-height: 1em;
819
/*	line-height: 1;*/
820
	-moz-border-radius: 3px;
821
	-webkit-border-radius: 3px;
822
	border-radius: 3px;
823
	-moz-box-shadow: none;
824
	-webkit-box-shadow: none;
825
	box-shadow: none;
826
}
827
.ee-button:hover {
828
	color: #fff !important;
829
	background: #4EBFDE;
830
}
831
.ee-button:active { top:0; }
832
</style>';
833
                $after_plugin_row .= '
834
<p class="ee-addon-upsell-info-dv">
835
	<a class="ee-button" href="' . $link_url . '">'
836
                . $link_text
837
                . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
838
                . '</a>
839
</p>';
840
                $after_plugin_row .= '</td>';
841
                $after_plugin_row .= '<td class="ee-addon-upsell-info-desc-td column-description desc">';
842
                $after_plugin_row .= $description;
843
                $after_plugin_row .= '</td>';
844
                $after_plugin_row .= '</tr>';
845
            } else {
846
                $after_plugin_row .= $description;
847
            }
848
        }
849
850
        echo $after_plugin_row;
851
    }
852
853
854
    /**
855
     * A safe space for addons to add additional logic like setting hooks that need to be set early in the request.
856
     * Child classes that have logic like that to run can override this method declaration.  This was not made abstract
857
     * for back compat reasons.
858
     *
859
     * This will fire on the `AHEE__EE_System__load_espresso_addons__complete` hook at priority 999.
860
     *
861
     * It is recommended, if client code is `de-registering` an add-on, then do it on the
862
     * `AHEE__EE_System__load_espresso_addons__complete` hook before priority 999 so as to ensure any code logic in this
863
     * callback does not get run/set in that request.
864
     *
865
     * Also, keep in mind that if a registered add-on happens to be deactivated via
866
     * EE_System::_deactivate_incompatible_addons() because its incompatible, any code executed in this method
867
     * (including setting hooks etc) will have executed before the plugin was deactivated.  If you use
868
     * `after_registration` to set any filter and/or action hooks and want to ensure they are removed on this add-on's
869
     * deactivation, you can override `EE_Addon::deactivation` and unset your hooks and filters there.  Just remember
870
     * to call `parent::deactivation`.
871
     *
872
     * @since 4.9.26
873
     */
874
    public function after_registration()
875
    {
876
        // cricket chirp... cricket chirp...
877
    }
878
}
879