Completed
Branch BUG/fatal-with-paypal-debug-li... (3a6198)
by
unknown
17:52 queued 09:26
created

EE_Addon::new_install()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 8
Ratio 72.73 %

Importance

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