Completed
Branch BUG/escape-localized-variables (bce518)
by
unknown
09:04 queued 36s
created
core/domain/values/assets/Asset.php 1 patch
Indentation   +164 added lines, -164 removed lines patch added patch discarded remove patch
@@ -16,168 +16,168 @@
 block discarded – undo
16 16
 abstract class Asset
17 17
 {
18 18
 
19
-    /**
20
-     * indicates the file extension for a build distribution CSS file
21
-     */
22
-    const FILE_EXTENSION_DISTRIBUTION_CSS = '.dist.css';
23
-
24
-    /**
25
-     * indicates the file extension for a build distribution JS file
26
-     */
27
-    const FILE_EXTENSION_DISTRIBUTION_JS = '.dist.js';
28
-
29
-    /**
30
-     * Indicates the file extension for a build distribution dependencies json file.
31
-     */
32
-    const FILE_EXTENSION_DISTRIBUTION_DEPS = '.dist.deps.php';
33
-
34
-    /**
35
-     * indicates a Cascading Style Sheet asset
36
-     */
37
-    const TYPE_CSS = 'css';
38
-
39
-    /**
40
-     * indicates a Javascript asset
41
-     */
42
-    const TYPE_JS = 'js';
43
-
44
-    /**
45
-     * indicates a JSON asset
46
-     */
47
-    CONST TYPE_JSON = 'json';
48
-    /**
49
-     * indicates a PHP asset
50
-     */
51
-    CONST TYPE_PHP = 'php';
52
-
53
-    /**
54
-     * indicates a Javascript manifest file
55
-     */
56
-    const TYPE_MANIFEST = 'manifest';
57
-
58
-    /**
59
-     * @var DomainInterface $domain
60
-     */
61
-    protected $domain;
62
-
63
-    /**
64
-     * @var string $type
65
-     */
66
-    private $type;
67
-
68
-    /**
69
-     * @var string $handle
70
-     */
71
-    private $handle;
72
-
73
-    /**
74
-     * @var bool $registered
75
-     */
76
-    private $registered = false;
77
-
78
-
79
-    /**
80
-     * Asset constructor.
81
-     *
82
-     * @param                 $type
83
-     * @param string          $handle
84
-     * @param DomainInterface $domain
85
-     * @throws InvalidDataTypeException
86
-     */
87
-    public function __construct($type, $handle, DomainInterface $domain)
88
-    {
89
-        $this->domain = $domain;
90
-        $this->setType($type);
91
-        $this->setHandle($handle);
92
-    }
93
-
94
-
95
-    /**
96
-     * @return array
97
-     */
98
-    public function validAssetTypes()
99
-    {
100
-        return array(
101
-            Asset::TYPE_CSS,
102
-            Asset::TYPE_JS,
103
-            Asset::TYPE_MANIFEST,
104
-        );
105
-    }
106
-
107
-
108
-    /**
109
-     * @param string $type
110
-     * @throws InvalidDataTypeException
111
-     */
112
-    private function setType($type)
113
-    {
114
-        if (! in_array($type, $this->validAssetTypes(), true)) {
115
-            throw new InvalidDataTypeException(
116
-                'Asset::$type',
117
-                $type,
118
-                'one of the TYPE_* class constants on \EventEspresso\core\domain\values\Asset is required'
119
-            );
120
-        }
121
-        $this->type = $type;
122
-    }
123
-
124
-
125
-    /**
126
-     * @param string $handle
127
-     * @throws InvalidDataTypeException
128
-     */
129
-    private function setHandle($handle)
130
-    {
131
-        if (! is_string($handle)) {
132
-            throw new InvalidDataTypeException(
133
-                '$handle',
134
-                $handle,
135
-                'string'
136
-            );
137
-        }
138
-        $this->handle = $handle;
139
-    }
140
-
141
-
142
-    /**
143
-     * @return string
144
-     */
145
-    public function assetNamespace()
146
-    {
147
-        return $this->domain->assetNamespace();
148
-    }
149
-
150
-
151
-    /**
152
-     * @return string
153
-     */
154
-    public function type()
155
-    {
156
-        return $this->type;
157
-    }
158
-
159
-
160
-    /**
161
-     * @return string
162
-     */
163
-    public function handle()
164
-    {
165
-        return $this->handle;
166
-    }
167
-
168
-    /**
169
-     * @return bool
170
-     */
171
-    public function isRegistered()
172
-    {
173
-        return $this->registered;
174
-    }
175
-
176
-    /**
177
-     * @param bool $registered
178
-     */
179
-    public function setRegistered($registered = true)
180
-    {
181
-        $this->registered = filter_var($registered, FILTER_VALIDATE_BOOLEAN);
182
-    }
19
+	/**
20
+	 * indicates the file extension for a build distribution CSS file
21
+	 */
22
+	const FILE_EXTENSION_DISTRIBUTION_CSS = '.dist.css';
23
+
24
+	/**
25
+	 * indicates the file extension for a build distribution JS file
26
+	 */
27
+	const FILE_EXTENSION_DISTRIBUTION_JS = '.dist.js';
28
+
29
+	/**
30
+	 * Indicates the file extension for a build distribution dependencies json file.
31
+	 */
32
+	const FILE_EXTENSION_DISTRIBUTION_DEPS = '.dist.deps.php';
33
+
34
+	/**
35
+	 * indicates a Cascading Style Sheet asset
36
+	 */
37
+	const TYPE_CSS = 'css';
38
+
39
+	/**
40
+	 * indicates a Javascript asset
41
+	 */
42
+	const TYPE_JS = 'js';
43
+
44
+	/**
45
+	 * indicates a JSON asset
46
+	 */
47
+	CONST TYPE_JSON = 'json';
48
+	/**
49
+	 * indicates a PHP asset
50
+	 */
51
+	CONST TYPE_PHP = 'php';
52
+
53
+	/**
54
+	 * indicates a Javascript manifest file
55
+	 */
56
+	const TYPE_MANIFEST = 'manifest';
57
+
58
+	/**
59
+	 * @var DomainInterface $domain
60
+	 */
61
+	protected $domain;
62
+
63
+	/**
64
+	 * @var string $type
65
+	 */
66
+	private $type;
67
+
68
+	/**
69
+	 * @var string $handle
70
+	 */
71
+	private $handle;
72
+
73
+	/**
74
+	 * @var bool $registered
75
+	 */
76
+	private $registered = false;
77
+
78
+
79
+	/**
80
+	 * Asset constructor.
81
+	 *
82
+	 * @param                 $type
83
+	 * @param string          $handle
84
+	 * @param DomainInterface $domain
85
+	 * @throws InvalidDataTypeException
86
+	 */
87
+	public function __construct($type, $handle, DomainInterface $domain)
88
+	{
89
+		$this->domain = $domain;
90
+		$this->setType($type);
91
+		$this->setHandle($handle);
92
+	}
93
+
94
+
95
+	/**
96
+	 * @return array
97
+	 */
98
+	public function validAssetTypes()
99
+	{
100
+		return array(
101
+			Asset::TYPE_CSS,
102
+			Asset::TYPE_JS,
103
+			Asset::TYPE_MANIFEST,
104
+		);
105
+	}
106
+
107
+
108
+	/**
109
+	 * @param string $type
110
+	 * @throws InvalidDataTypeException
111
+	 */
112
+	private function setType($type)
113
+	{
114
+		if (! in_array($type, $this->validAssetTypes(), true)) {
115
+			throw new InvalidDataTypeException(
116
+				'Asset::$type',
117
+				$type,
118
+				'one of the TYPE_* class constants on \EventEspresso\core\domain\values\Asset is required'
119
+			);
120
+		}
121
+		$this->type = $type;
122
+	}
123
+
124
+
125
+	/**
126
+	 * @param string $handle
127
+	 * @throws InvalidDataTypeException
128
+	 */
129
+	private function setHandle($handle)
130
+	{
131
+		if (! is_string($handle)) {
132
+			throw new InvalidDataTypeException(
133
+				'$handle',
134
+				$handle,
135
+				'string'
136
+			);
137
+		}
138
+		$this->handle = $handle;
139
+	}
140
+
141
+
142
+	/**
143
+	 * @return string
144
+	 */
145
+	public function assetNamespace()
146
+	{
147
+		return $this->domain->assetNamespace();
148
+	}
149
+
150
+
151
+	/**
152
+	 * @return string
153
+	 */
154
+	public function type()
155
+	{
156
+		return $this->type;
157
+	}
158
+
159
+
160
+	/**
161
+	 * @return string
162
+	 */
163
+	public function handle()
164
+	{
165
+		return $this->handle;
166
+	}
167
+
168
+	/**
169
+	 * @return bool
170
+	 */
171
+	public function isRegistered()
172
+	{
173
+		return $this->registered;
174
+	}
175
+
176
+	/**
177
+	 * @param bool $registered
178
+	 */
179
+	public function setRegistered($registered = true)
180
+	{
181
+		$this->registered = filter_var($registered, FILTER_VALIDATE_BOOLEAN);
182
+	}
183 183
 }
Please login to merge, or discard this patch.
core/domain/values/assets/BrowserAsset.php 2 patches
Indentation   +144 added lines, -144 removed lines patch added patch discarded remove patch
@@ -17,148 +17,148 @@
 block discarded – undo
17 17
 abstract class BrowserAsset extends Asset
18 18
 {
19 19
 
20
-    /**
21
-     * @var string $source
22
-     */
23
-    private $source;
24
-
25
-    /**
26
-     * @var array $dependencies
27
-     */
28
-    private $dependencies;
29
-
30
-    /**
31
-     * @var string $version
32
-     */
33
-    private $version;
34
-
35
-
36
-    /**
37
-     * Asset constructor.
38
-     *
39
-     * @param string          $type
40
-     * @param string          $handle
41
-     * @param string          $source
42
-     * @param array           $dependencies
43
-     * @param DomainInterface $domain
44
-     * @param string          $version
45
-     * @throws DomainException
46
-     * @throws InvalidDataTypeException
47
-     */
48
-    public function __construct($type, $handle, $source, array $dependencies, DomainInterface $domain, $version = '')
49
-    {
50
-        parent::__construct($type, $handle, $domain);
51
-        $this->setSource($source);
52
-        $this->setDependencies($dependencies);
53
-        $this->setVersion($version, false);
54
-    }
55
-
56
-
57
-    /**
58
-     * @since 4.9.62.p
59
-     */
60
-    abstract public function enqueueAsset();
61
-
62
-
63
-    /**
64
-     * @return array
65
-     */
66
-    public function dependencies()
67
-    {
68
-        return $this->dependencies;
69
-    }
70
-
71
-
72
-    /**
73
-     * @param array $dependencies
74
-     */
75
-    private function setDependencies(array $dependencies)
76
-    {
77
-        $this->dependencies = $dependencies;
78
-    }
79
-
80
-
81
-    /**
82
-     * @since 4.9.62.p
83
-     * @return bool
84
-     */
85
-    public function hasDependencies()
86
-    {
87
-        return count($this->dependencies) > 0;
88
-    }
89
-
90
-
91
-    /**
92
-     * @return string
93
-     */
94
-    public function source()
95
-    {
96
-        return $this->source;
97
-    }
98
-
99
-
100
-    /**
101
-     * @param string $source
102
-     * @throws InvalidDataTypeException
103
-     */
104
-    private function setSource($source)
105
-    {
106
-        if (! is_string($source)) {
107
-            throw new InvalidDataTypeException(
108
-                '$source',
109
-                $source,
110
-                'string'
111
-            );
112
-        }
113
-        $this->source = $source;
114
-    }
115
-
116
-
117
-    /**
118
-     * @return string
119
-     * @throws InvalidDataTypeException
120
-     * @throws DomainException
121
-     */
122
-    public function version()
123
-    {
124
-        return $this->version;
125
-    }
126
-
127
-
128
-    /**
129
-     * @param string $version
130
-     * @param bool   $fluent
131
-     * @return BrowserAsset|null
132
-     * @throws DomainException
133
-     * @throws InvalidDataTypeException
134
-     */
135
-    public function setVersion($version, $fluent = true)
136
-    {
137
-        // if version is NOT set and this asset was NOT built for distribution,
138
-        // then set the version equal to the EE core plugin version
139
-        if (empty($version) && ! $this->isBuiltDistributionSource()) {
140
-            $version = $this->domain->version();
141
-        }
142
-        if (! is_string($version)) {
143
-            throw new InvalidDataTypeException(
144
-                '$version',
145
-                $version,
146
-                'string'
147
-            );
148
-        }
149
-        $this->version = $version;
150
-        if ($fluent) {
151
-            return $this;
152
-        }
153
-        return null;
154
-    }
155
-
156
-
157
-    /**
158
-     * @return bool
159
-     */
160
-    public function isBuiltDistributionSource() {
161
-        return substr($this->source, -8) === Asset::FILE_EXTENSION_DISTRIBUTION_JS
162
-               || substr($this->source, -9) === Asset::FILE_EXTENSION_DISTRIBUTION_CSS;
163
-    }
20
+	/**
21
+	 * @var string $source
22
+	 */
23
+	private $source;
24
+
25
+	/**
26
+	 * @var array $dependencies
27
+	 */
28
+	private $dependencies;
29
+
30
+	/**
31
+	 * @var string $version
32
+	 */
33
+	private $version;
34
+
35
+
36
+	/**
37
+	 * Asset constructor.
38
+	 *
39
+	 * @param string          $type
40
+	 * @param string          $handle
41
+	 * @param string          $source
42
+	 * @param array           $dependencies
43
+	 * @param DomainInterface $domain
44
+	 * @param string          $version
45
+	 * @throws DomainException
46
+	 * @throws InvalidDataTypeException
47
+	 */
48
+	public function __construct($type, $handle, $source, array $dependencies, DomainInterface $domain, $version = '')
49
+	{
50
+		parent::__construct($type, $handle, $domain);
51
+		$this->setSource($source);
52
+		$this->setDependencies($dependencies);
53
+		$this->setVersion($version, false);
54
+	}
55
+
56
+
57
+	/**
58
+	 * @since 4.9.62.p
59
+	 */
60
+	abstract public function enqueueAsset();
61
+
62
+
63
+	/**
64
+	 * @return array
65
+	 */
66
+	public function dependencies()
67
+	{
68
+		return $this->dependencies;
69
+	}
70
+
71
+
72
+	/**
73
+	 * @param array $dependencies
74
+	 */
75
+	private function setDependencies(array $dependencies)
76
+	{
77
+		$this->dependencies = $dependencies;
78
+	}
79
+
80
+
81
+	/**
82
+	 * @since 4.9.62.p
83
+	 * @return bool
84
+	 */
85
+	public function hasDependencies()
86
+	{
87
+		return count($this->dependencies) > 0;
88
+	}
89
+
90
+
91
+	/**
92
+	 * @return string
93
+	 */
94
+	public function source()
95
+	{
96
+		return $this->source;
97
+	}
98
+
99
+
100
+	/**
101
+	 * @param string $source
102
+	 * @throws InvalidDataTypeException
103
+	 */
104
+	private function setSource($source)
105
+	{
106
+		if (! is_string($source)) {
107
+			throw new InvalidDataTypeException(
108
+				'$source',
109
+				$source,
110
+				'string'
111
+			);
112
+		}
113
+		$this->source = $source;
114
+	}
115
+
116
+
117
+	/**
118
+	 * @return string
119
+	 * @throws InvalidDataTypeException
120
+	 * @throws DomainException
121
+	 */
122
+	public function version()
123
+	{
124
+		return $this->version;
125
+	}
126
+
127
+
128
+	/**
129
+	 * @param string $version
130
+	 * @param bool   $fluent
131
+	 * @return BrowserAsset|null
132
+	 * @throws DomainException
133
+	 * @throws InvalidDataTypeException
134
+	 */
135
+	public function setVersion($version, $fluent = true)
136
+	{
137
+		// if version is NOT set and this asset was NOT built for distribution,
138
+		// then set the version equal to the EE core plugin version
139
+		if (empty($version) && ! $this->isBuiltDistributionSource()) {
140
+			$version = $this->domain->version();
141
+		}
142
+		if (! is_string($version)) {
143
+			throw new InvalidDataTypeException(
144
+				'$version',
145
+				$version,
146
+				'string'
147
+			);
148
+		}
149
+		$this->version = $version;
150
+		if ($fluent) {
151
+			return $this;
152
+		}
153
+		return null;
154
+	}
155
+
156
+
157
+	/**
158
+	 * @return bool
159
+	 */
160
+	public function isBuiltDistributionSource() {
161
+		return substr($this->source, -8) === Asset::FILE_EXTENSION_DISTRIBUTION_JS
162
+			   || substr($this->source, -9) === Asset::FILE_EXTENSION_DISTRIBUTION_CSS;
163
+	}
164 164
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
      */
104 104
     private function setSource($source)
105 105
     {
106
-        if (! is_string($source)) {
106
+        if ( ! is_string($source)) {
107 107
             throw new InvalidDataTypeException(
108 108
                 '$source',
109 109
                 $source,
@@ -139,7 +139,7 @@  discard block
 block discarded – undo
139 139
         if (empty($version) && ! $this->isBuiltDistributionSource()) {
140 140
             $version = $this->domain->version();
141 141
         }
142
-        if (! is_string($version)) {
142
+        if ( ! is_string($version)) {
143 143
             throw new InvalidDataTypeException(
144 144
                 '$version',
145 145
                 $version,
Please login to merge, or discard this patch.
core/domain/values/assets/StylesheetAsset.php 1 patch
Indentation   +56 added lines, -56 removed lines patch added patch discarded remove patch
@@ -17,68 +17,68 @@
 block discarded – undo
17 17
 class StylesheetAsset extends BrowserAsset
18 18
 {
19 19
 
20
-    /**
21
-     * @var string $media
22
-     */
23
-    private $media;
20
+	/**
21
+	 * @var string $media
22
+	 */
23
+	private $media;
24 24
 
25 25
 
26
-    /**
27
-     * CssFile constructor.
28
-     *
29
-     * @param                 $handle
30
-     * @param string          $source
31
-     * @param array           $dependencies
32
-     * @param DomainInterface $domain
33
-     * @param string          $media
34
-     * @param string          $version
35
-     * @throws InvalidDataTypeException
36
-     * @throws DomainException
37
-     */
38
-    public function __construct(
39
-        $handle,
40
-        $source,
41
-        array $dependencies,
42
-        DomainInterface $domain,
43
-        $media = 'all',
44
-        $version = ''
45
-    ) {
46
-        parent::__construct(Asset::TYPE_CSS, $handle, $source, $dependencies, $domain, $version);
47
-        $this->setMedia($media);
48
-    }
26
+	/**
27
+	 * CssFile constructor.
28
+	 *
29
+	 * @param                 $handle
30
+	 * @param string          $source
31
+	 * @param array           $dependencies
32
+	 * @param DomainInterface $domain
33
+	 * @param string          $media
34
+	 * @param string          $version
35
+	 * @throws InvalidDataTypeException
36
+	 * @throws DomainException
37
+	 */
38
+	public function __construct(
39
+		$handle,
40
+		$source,
41
+		array $dependencies,
42
+		DomainInterface $domain,
43
+		$media = 'all',
44
+		$version = ''
45
+	) {
46
+		parent::__construct(Asset::TYPE_CSS, $handle, $source, $dependencies, $domain, $version);
47
+		$this->setMedia($media);
48
+	}
49 49
 
50 50
 
51
-    /**
52
-     * @return string
53
-     */
54
-    public function media()
55
-    {
56
-        return $this->media;
57
-    }
51
+	/**
52
+	 * @return string
53
+	 */
54
+	public function media()
55
+	{
56
+		return $this->media;
57
+	}
58 58
 
59 59
 
60
-    /**
61
-     * @param string $media
62
-     * @throws InvalidDataTypeException
63
-     */
64
-    private function setMedia($media)
65
-    {
66
-        if (! is_string($media)) {
67
-            throw new InvalidDataTypeException(
68
-                '$media',
69
-                $media,
70
-                'string'
71
-            );
72
-        }
73
-        $this->media = $media;
74
-    }
60
+	/**
61
+	 * @param string $media
62
+	 * @throws InvalidDataTypeException
63
+	 */
64
+	private function setMedia($media)
65
+	{
66
+		if (! is_string($media)) {
67
+			throw new InvalidDataTypeException(
68
+				'$media',
69
+				$media,
70
+				'string'
71
+			);
72
+		}
73
+		$this->media = $media;
74
+	}
75 75
 
76 76
 
77
-    /**
78
-     * @since 4.9.62.p
79
-     */
80
-    public function enqueueAsset()
81
-    {
82
-        wp_enqueue_style($this->handle());
83
-    }
77
+	/**
78
+	 * @since 4.9.62.p
79
+	 */
80
+	public function enqueueAsset()
81
+	{
82
+		wp_enqueue_style($this->handle());
83
+	}
84 84
 }
Please login to merge, or discard this patch.
core/domain/values/assets/JavascriptAsset.php 1 patch
Indentation   +141 added lines, -141 removed lines patch added patch discarded remove patch
@@ -18,145 +18,145 @@
 block discarded – undo
18 18
 class JavascriptAsset extends BrowserAsset
19 19
 {
20 20
 
21
-    /**
22
-     * @var boolean $load_in_footer
23
-     */
24
-    private $load_in_footer = false;
25
-
26
-    /**
27
-     * @var boolean $requires_translation
28
-     */
29
-    private $requires_translation = false;
30
-
31
-    /**
32
-     * @var boolean $has_inline_data
33
-     */
34
-    private $has_inline_data = false;
35
-
36
-    /**
37
-     * @var Closure $inline_data_callback
38
-     */
39
-    private $inline_data_callback;
40
-
41
-
42
-    /**
43
-     * Asset constructor.
44
-     *
45
-     * @param string          $handle
46
-     * @param string          $source
47
-     * @param array           $dependencies
48
-     * @param bool            $load_in_footer
49
-     * @param DomainInterface $domain
50
-     * @param string          $version
51
-     * @throws InvalidDataTypeException
52
-     * @throws DomainException
53
-     */
54
-    public function __construct(
55
-        $handle,
56
-        $source,
57
-        array $dependencies,
58
-        $load_in_footer,
59
-        DomainInterface $domain,
60
-        $version = ''
61
-    ) {
62
-        parent::__construct(Asset::TYPE_JS, $handle, $source, $dependencies, $domain, $version);
63
-        $this->setLoadInFooter($load_in_footer);
64
-    }
65
-
66
-
67
-    /**
68
-     * @return bool
69
-     */
70
-    public function loadInFooter()
71
-    {
72
-        return $this->load_in_footer;
73
-    }
74
-
75
-
76
-    /**
77
-     * @param bool $load_in_footer
78
-     */
79
-    private function setLoadInFooter($load_in_footer = true)
80
-    {
81
-        $this->load_in_footer = filter_var($load_in_footer, FILTER_VALIDATE_BOOLEAN);
82
-    }
83
-
84
-
85
-    /**
86
-     * @return bool
87
-     */
88
-    public function requiresTranslation()
89
-    {
90
-        return $this->requires_translation;
91
-    }
92
-
93
-
94
-    /**
95
-     * @param bool $requires_translation
96
-     * @return JavascriptAsset
97
-     */
98
-    public function setRequiresTranslation($requires_translation = true)
99
-    {
100
-        $this->requires_translation = filter_var($requires_translation, FILTER_VALIDATE_BOOLEAN);
101
-        return $this;
102
-    }
103
-
104
-
105
-    /**
106
-     * @return bool
107
-     */
108
-    public function hasInlineData()
109
-    {
110
-        return $this->has_inline_data;
111
-    }
112
-
113
-
114
-    /**
115
-     * @param bool $has_inline_data
116
-     * @return JavascriptAsset
117
-     */
118
-    public function setHasInlineData($has_inline_data = true)
119
-    {
120
-        $this->has_inline_data = filter_var($has_inline_data, FILTER_VALIDATE_BOOLEAN);
121
-        return $this;
122
-    }
123
-
124
-
125
-    /**
126
-     * @return Closure
127
-     */
128
-    public function inlineDataCallback()
129
-    {
130
-        return $this->inline_data_callback;
131
-    }
132
-
133
-
134
-    /**
135
-     * @return bool
136
-     */
137
-    public function hasInlineDataCallback()
138
-    {
139
-        return $this->inline_data_callback instanceof Closure;
140
-    }
141
-
142
-
143
-    /**
144
-     * @param Closure $inline_data_callback
145
-     * @return JavascriptAsset
146
-     */
147
-    public function setInlineDataCallback(Closure $inline_data_callback)
148
-    {
149
-        $this->inline_data_callback = $inline_data_callback;
150
-        $this->setHasInlineData();
151
-        return $this;
152
-    }
153
-
154
-
155
-    /**
156
-     * @since 4.9.62.p
157
-     */
158
-    public function enqueueAsset()
159
-    {
160
-        wp_enqueue_script($this->handle());
161
-    }
21
+	/**
22
+	 * @var boolean $load_in_footer
23
+	 */
24
+	private $load_in_footer = false;
25
+
26
+	/**
27
+	 * @var boolean $requires_translation
28
+	 */
29
+	private $requires_translation = false;
30
+
31
+	/**
32
+	 * @var boolean $has_inline_data
33
+	 */
34
+	private $has_inline_data = false;
35
+
36
+	/**
37
+	 * @var Closure $inline_data_callback
38
+	 */
39
+	private $inline_data_callback;
40
+
41
+
42
+	/**
43
+	 * Asset constructor.
44
+	 *
45
+	 * @param string          $handle
46
+	 * @param string          $source
47
+	 * @param array           $dependencies
48
+	 * @param bool            $load_in_footer
49
+	 * @param DomainInterface $domain
50
+	 * @param string          $version
51
+	 * @throws InvalidDataTypeException
52
+	 * @throws DomainException
53
+	 */
54
+	public function __construct(
55
+		$handle,
56
+		$source,
57
+		array $dependencies,
58
+		$load_in_footer,
59
+		DomainInterface $domain,
60
+		$version = ''
61
+	) {
62
+		parent::__construct(Asset::TYPE_JS, $handle, $source, $dependencies, $domain, $version);
63
+		$this->setLoadInFooter($load_in_footer);
64
+	}
65
+
66
+
67
+	/**
68
+	 * @return bool
69
+	 */
70
+	public function loadInFooter()
71
+	{
72
+		return $this->load_in_footer;
73
+	}
74
+
75
+
76
+	/**
77
+	 * @param bool $load_in_footer
78
+	 */
79
+	private function setLoadInFooter($load_in_footer = true)
80
+	{
81
+		$this->load_in_footer = filter_var($load_in_footer, FILTER_VALIDATE_BOOLEAN);
82
+	}
83
+
84
+
85
+	/**
86
+	 * @return bool
87
+	 */
88
+	public function requiresTranslation()
89
+	{
90
+		return $this->requires_translation;
91
+	}
92
+
93
+
94
+	/**
95
+	 * @param bool $requires_translation
96
+	 * @return JavascriptAsset
97
+	 */
98
+	public function setRequiresTranslation($requires_translation = true)
99
+	{
100
+		$this->requires_translation = filter_var($requires_translation, FILTER_VALIDATE_BOOLEAN);
101
+		return $this;
102
+	}
103
+
104
+
105
+	/**
106
+	 * @return bool
107
+	 */
108
+	public function hasInlineData()
109
+	{
110
+		return $this->has_inline_data;
111
+	}
112
+
113
+
114
+	/**
115
+	 * @param bool $has_inline_data
116
+	 * @return JavascriptAsset
117
+	 */
118
+	public function setHasInlineData($has_inline_data = true)
119
+	{
120
+		$this->has_inline_data = filter_var($has_inline_data, FILTER_VALIDATE_BOOLEAN);
121
+		return $this;
122
+	}
123
+
124
+
125
+	/**
126
+	 * @return Closure
127
+	 */
128
+	public function inlineDataCallback()
129
+	{
130
+		return $this->inline_data_callback;
131
+	}
132
+
133
+
134
+	/**
135
+	 * @return bool
136
+	 */
137
+	public function hasInlineDataCallback()
138
+	{
139
+		return $this->inline_data_callback instanceof Closure;
140
+	}
141
+
142
+
143
+	/**
144
+	 * @param Closure $inline_data_callback
145
+	 * @return JavascriptAsset
146
+	 */
147
+	public function setInlineDataCallback(Closure $inline_data_callback)
148
+	{
149
+		$this->inline_data_callback = $inline_data_callback;
150
+		$this->setHasInlineData();
151
+		return $this;
152
+	}
153
+
154
+
155
+	/**
156
+	 * @since 4.9.62.p
157
+	 */
158
+	public function enqueueAsset()
159
+	{
160
+		wp_enqueue_script($this->handle());
161
+	}
162 162
 }
Please login to merge, or discard this patch.
core/domain/services/assets/CoreAssetManager.php 2 patches
Indentation   +438 added lines, -438 removed lines patch added patch discarded remove patch
@@ -32,461 +32,461 @@
 block discarded – undo
32 32
 class CoreAssetManager extends AssetManager
33 33
 {
34 34
 
35
-    // WordPress core / Third party JS asset handles
36
-    const JS_HANDLE_JQUERY = 'jquery';
35
+	// WordPress core / Third party JS asset handles
36
+	const JS_HANDLE_JQUERY = 'jquery';
37 37
 
38
-    const JS_HANDLE_JQUERY_VALIDATE = 'jquery-validate';
38
+	const JS_HANDLE_JQUERY_VALIDATE = 'jquery-validate';
39 39
 
40
-    const JS_HANDLE_JQUERY_VALIDATE_EXTRA = 'jquery-validate-extra-methods';
40
+	const JS_HANDLE_JQUERY_VALIDATE_EXTRA = 'jquery-validate-extra-methods';
41 41
 
42
-    const JS_HANDLE_UNDERSCORE = 'underscore';
42
+	const JS_HANDLE_UNDERSCORE = 'underscore';
43 43
 
44
-    const JS_HANDLE_ACCOUNTING_CORE = 'ee-accounting-core';
44
+	const JS_HANDLE_ACCOUNTING_CORE = 'ee-accounting-core';
45 45
 
46
-    /**
47
-     * @since 4.9.71.p
48
-     */
49
-    const JS_HANDLE_REACT = 'react';
46
+	/**
47
+	 * @since 4.9.71.p
48
+	 */
49
+	const JS_HANDLE_REACT = 'react';
50 50
 
51
-    /**
52
-     * @since 4.9.71.p
53
-     */
54
-    const JS_HANDLE_REACT_DOM = 'react-dom';
51
+	/**
52
+	 * @since 4.9.71.p
53
+	 */
54
+	const JS_HANDLE_REACT_DOM = 'react-dom';
55 55
 
56
-    /**
57
-     * @since 4.9.71.p
58
-     */
59
-    const JS_HANDLE_LODASH = 'lodash';
56
+	/**
57
+	 * @since 4.9.71.p
58
+	 */
59
+	const JS_HANDLE_LODASH = 'lodash';
60 60
 
61
-    const JS_HANDLE_JS_CORE = 'eejs-core';
61
+	const JS_HANDLE_JS_CORE = 'eejs-core';
62 62
 
63
-    const JS_HANDLE_VENDOR = 'eventespresso-vendor';
63
+	const JS_HANDLE_VENDOR = 'eventespresso-vendor';
64 64
 
65
-    const JS_HANDLE_DATA_STORES = 'eventespresso-data-stores';
65
+	const JS_HANDLE_DATA_STORES = 'eventespresso-data-stores';
66 66
 
67
-    const JS_HANDLE_HELPERS = 'eventespresso-helpers';
67
+	const JS_HANDLE_HELPERS = 'eventespresso-helpers';
68 68
 
69
-    const JS_HANDLE_MODEL = 'eventespresso-model';
69
+	const JS_HANDLE_MODEL = 'eventespresso-model';
70 70
 
71
-    const JS_HANDLE_VALUE_OBJECTS = 'eventespresso-value-objects';
71
+	const JS_HANDLE_VALUE_OBJECTS = 'eventespresso-value-objects';
72 72
 
73
-    const JS_HANDLE_HOCS = 'eventespresso-hocs';
73
+	const JS_HANDLE_HOCS = 'eventespresso-hocs';
74 74
 
75
-    const JS_HANDLE_COMPONENTS = 'eventespresso-components';
75
+	const JS_HANDLE_COMPONENTS = 'eventespresso-components';
76 76
 
77
-    const JS_HANDLE_EDITOR_HOCS = 'eventespresso-editor-hocs';
78
-
79
-    const JS_HANDLE_VALIDATORS = 'eventespresso-validators';
77
+	const JS_HANDLE_EDITOR_HOCS = 'eventespresso-editor-hocs';
78
+
79
+	const JS_HANDLE_VALIDATORS = 'eventespresso-validators';
80 80
 
81
-    const JS_HANDLE_CORE = 'espresso_core';
81
+	const JS_HANDLE_CORE = 'espresso_core';
82 82
 
83
-    const JS_HANDLE_I18N = 'eei18n';
83
+	const JS_HANDLE_I18N = 'eei18n';
84 84
 
85
-    const JS_HANDLE_ACCOUNTING = 'ee-accounting';
86
-
87
-    const JS_HANDLE_WP_PLUGINS_PAGE = 'ee-wp-plugins-page';
88
-
89
-    // EE CSS assets handles
90
-    const CSS_HANDLE_DEFAULT = 'espresso_default';
91
-
92
-    const CSS_HANDLE_CUSTOM = 'espresso_custom_css';
93
-
94
-    const CSS_HANDLE_COMPONENTS = 'eventespresso-components';
95
-
96
-    const CSS_HANDLE_CORE_CSS_DEFAULT = 'eventespresso-core-css-default';
97
-
98
-    /**
99
-     * @var EE_Currency_Config $currency_config
100
-     */
101
-    protected $currency_config;
102
-
103
-    /**
104
-     * @var EE_Template_Config $template_config
105
-     */
106
-    protected $template_config;
107
-
108
-
109
-    /**
110
-     * CoreAssetRegister constructor.
111
-     *
112
-     * @param AssetCollection    $assets
113
-     * @param EE_Currency_Config $currency_config
114
-     * @param EE_Template_Config $template_config
115
-     * @param DomainInterface    $domain
116
-     * @param Registry           $registry
117
-     */
118
-    public function __construct(
119
-        AssetCollection $assets,
120
-        EE_Currency_Config $currency_config,
121
-        EE_Template_Config $template_config,
122
-        DomainInterface $domain,
123
-        Registry $registry
124
-    ) {
125
-        $this->currency_config = $currency_config;
126
-        $this->template_config = $template_config;
127
-        parent::__construct($domain, $assets, $registry);
128
-    }
129
-
130
-
131
-    /**
132
-     * @since 4.9.62.p
133
-     * @throws DomainException
134
-     * @throws DuplicateCollectionIdentifierException
135
-     * @throws InvalidArgumentException
136
-     * @throws InvalidDataTypeException
137
-     * @throws InvalidEntityException
138
-     * @throws InvalidInterfaceException
139
-     */
140
-    public function addAssets()
141
-    {
142
-        $this->addJavascriptFiles();
143
-        $this->addStylesheetFiles();
144
-    }
145
-
146
-
147
-    /**
148
-     * @since 4.9.62.p
149
-     * @throws DomainException
150
-     * @throws DuplicateCollectionIdentifierException
151
-     * @throws InvalidArgumentException
152
-     * @throws InvalidDataTypeException
153
-     * @throws InvalidEntityException
154
-     * @throws InvalidInterfaceException
155
-     */
156
-    public function addJavascriptFiles()
157
-    {
158
-        $this->loadCoreJs();
159
-        $this->loadJqueryValidate();
160
-        $this->loadAccountingJs();
161
-        add_action(
162
-            'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script',
163
-            array($this, 'loadQtipJs')
164
-        );
165
-        $this->registerAdminAssets();
166
-    }
167
-
168
-
169
-    /**
170
-     * @throws DuplicateCollectionIdentifierException
171
-     * @throws InvalidDataTypeException
172
-     * @throws InvalidEntityException
173
-     * @throws DomainException
174
-     * @since 4.9.62.p
175
-     */
176
-    public function addStylesheetFiles()
177
-    {
178
-        $this->loadCoreCss();
179
-    }
180
-
181
-
182
-    /**
183
-     * core default javascript
184
-     *
185
-     * @since 4.9.62.p
186
-     * @throws DomainException
187
-     * @throws DuplicateCollectionIdentifierException
188
-     * @throws InvalidArgumentException
189
-     * @throws InvalidDataTypeException
190
-     * @throws InvalidEntityException
191
-     * @throws InvalidInterfaceException
192
-     */
193
-    private function loadCoreJs()
194
-    {
195
-        // conditionally load third-party libraries that WP core MIGHT have.
196
-        $this->registerWpAssets();
197
-
198
-        $this->addJs(self::JS_HANDLE_JS_CORE)->setHasInlineData();
199
-        $this->addJs(self::JS_HANDLE_VENDOR);
200
-        $this->addJs(self::JS_HANDLE_VALIDATORS)->setRequiresTranslation();
201
-        $this->addJs(self::JS_HANDLE_HELPERS)->setRequiresTranslation();
202
-        $this->addJs(self::JS_HANDLE_MODEL)->setRequiresTranslation();
203
-        $this->addJs(self::JS_HANDLE_VALUE_OBJECTS)->setRequiresTranslation();
204
-        $this->addJs(self::JS_HANDLE_DATA_STORES)->setRequiresTranslation()->setInlineDataCallback(
205
-            static function () {
206
-                wp_add_inline_script(
207
-                    CoreAssetManager::JS_HANDLE_DATA_STORES,
208
-                    is_admin()
209
-                        ? 'wp.apiFetch.use( eejs.middleWares.apiFetch.capsMiddleware( eejs.middleWares.apiFetch.CONTEXT_CAPS_EDIT ) )'
210
-                        : 'wp.apiFetch.use( eejs.middleWares.apiFetch.capsMiddleware )'
211
-                );
212
-            }
213
-        );
214
-        $this->addJs(self::JS_HANDLE_HOCS, [self::JS_HANDLE_DATA_STORES])->setRequiresTranslation();
215
-        $this->addJs(self::JS_HANDLE_COMPONENTS, [self::JS_HANDLE_DATA_STORES])->setRequiresTranslation();
216
-        $this->addJs(self::JS_HANDLE_EDITOR_HOCS)->setRequiresTranslation();
217
-
218
-        $this->registry->addData('eejs_api_nonce', wp_create_nonce('wp_rest'));
219
-        $this->registry->addData(
220
-            'paths',
221
-            array(
222
-                'base_rest_route' => rest_url(),
223
-                'rest_route' => rest_url('ee/v4.8.36/'),
224
-                'collection_endpoints' => EED_Core_Rest_Api::getCollectionRoutesIndexedByModelName(),
225
-                'primary_keys' => EED_Core_Rest_Api::getPrimaryKeyNamesIndexedByModelName(),
226
-                'site_url' => site_url('/'),
227
-                'admin_url' => admin_url('/'),
228
-            )
229
-        );
230
-        // Event Espresso brand name
231
-        $this->registry->addData('brandName', Domain::brandName());
232
-        /** site formatting values **/
233
-        $this->registry->addData(
234
-            'site_formats',
235
-            array(
236
-                'date_formats' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats()
237
-            )
238
-        );
239
-        /** currency data **/
240
-        $this->registry->addData(
241
-            'currency_config',
242
-            $this->getCurrencySettings()
243
-        );
244
-        /** site timezone */
245
-        $this->registry->addData(
246
-            'default_timezone',
247
-            array(
248
-                'pretty' => EEH_DTT_Helper::get_timezone_string_for_display(),
249
-                'string' => get_option('timezone_string'),
250
-                'offset' => EEH_DTT_Helper::get_site_timezone_gmt_offset(),
251
-            )
252
-        );
253
-        /** site locale (user locale if user logged in) */
254
-        $this->registry->addData(
255
-            'locale',
256
-            array(
257
-                'user' => get_user_locale(),
258
-                'site' => get_locale()
259
-            )
260
-        );
261
-
262
-        $this->addJavascript(
263
-            CoreAssetManager::JS_HANDLE_CORE,
264
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
265
-            array(CoreAssetManager::JS_HANDLE_JQUERY)
266
-        )
267
-        ->setInlineDataCallback(
268
-            static function () {
269
-                wp_localize_script(
270
-                    CoreAssetManager::JS_HANDLE_CORE,
271
-                    CoreAssetManager::JS_HANDLE_I18N,
272
-                    EE_Registry::$i18n_js_strings
273
-                );
274
-            }
275
-        );
276
-    }
277
-
278
-
279
-    /**
280
-     * Registers vendor files that are bundled with a later version WP but might not be for the current version of
281
-     * WordPress in the running environment.
282
-     *
283
-     * @throws DuplicateCollectionIdentifierException
284
-     * @throws InvalidDataTypeException
285
-     * @throws InvalidEntityException
286
-     * @throws DomainException
287
-     * @since 4.9.71.p
288
-     */
289
-    private function registerWpAssets()
290
-    {
291
-        global $wp_version;
292
-        if (version_compare($wp_version, '5.0.beta', '>=')) {
293
-            return;
294
-        }
295
-        $this->addVendorJavascript(CoreAssetManager::JS_HANDLE_REACT, [], true, '16.6.0');
296
-        $this->addVendorJavascript(
297
-            CoreAssetManager::JS_HANDLE_REACT_DOM,
298
-            array(CoreAssetManager::JS_HANDLE_REACT),
299
-            true,
300
-            '16.6.0'
301
-        );
302
-        $this->addVendorJavascript(CoreAssetManager::JS_HANDLE_LODASH, [], true, '4.17.11')
303
-            ->setInlineDataCallback(
304
-                static function() {
305
-                    wp_add_inline_script(
306
-                        CoreAssetManager::JS_HANDLE_LODASH,
307
-                        'window.lodash = _.noConflict();'
308
-                    );
309
-                }
310
-            );
311
-    }
312
-
313
-
314
-    /**
315
-     * Returns configuration data for the accounting-js library.
316
-     * @since 4.9.71.p
317
-     * @return array
318
-     */
319
-    private function getAccountingSettings() {
320
-        return array(
321
-            'currency' => array(
322
-                'symbol'    => $this->currency_config->sign,
323
-                'format'    => array(
324
-                    'pos'  => $this->currency_config->sign_b4 ? '%s%v' : '%v%s',
325
-                    'neg'  => $this->currency_config->sign_b4 ? '- %s%v' : '- %v%s',
326
-                    'zero' => $this->currency_config->sign_b4 ? '%s--' : '--%s',
327
-                ),
328
-                'decimal'   => $this->currency_config->dec_mrk,
329
-                'thousand'  => $this->currency_config->thsnds,
330
-                'precision' => $this->currency_config->dec_plc,
331
-            ),
332
-            'number'   => array(
333
-                'precision' => $this->currency_config->dec_plc,
334
-                'thousand'  => $this->currency_config->thsnds,
335
-                'decimal'   => $this->currency_config->dec_mrk,
336
-            ),
337
-        );
338
-    }
339
-
340
-
341
-    /**
342
-     * Returns configuration data for the js Currency VO.
343
-     * @since 4.9.71.p
344
-     * @return array
345
-     */
346
-    private function getCurrencySettings()
347
-    {
348
-        return array(
349
-            'code' => $this->currency_config->code,
350
-            'singularLabel' => $this->currency_config->name,
351
-            'pluralLabel' => $this->currency_config->plural,
352
-            'sign' => $this->currency_config->sign,
353
-            'signB4' => $this->currency_config->sign_b4,
354
-            'decimalPlaces' => $this->currency_config->dec_plc,
355
-            'decimalMark' => $this->currency_config->dec_mrk,
356
-            'thousandsSeparator' => $this->currency_config->thsnds,
357
-        );
358
-    }
359
-
360
-
361
-    /**
362
-     * @throws DuplicateCollectionIdentifierException
363
-     * @throws InvalidDataTypeException
364
-     * @throws InvalidEntityException
365
-     * @throws DomainException
366
-     * @since 4.9.62.p
367
-     */
368
-    private function loadCoreCss()
369
-    {
370
-        if ($this->template_config->enable_default_style && ! is_admin()) {
371
-            $this->addStylesheet(
372
-                CoreAssetManager::CSS_HANDLE_DEFAULT,
373
-                is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
374
-                    ? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css'
375
-                    : EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
376
-                array('dashicons')
377
-            );
378
-            //Load custom style sheet if available
379
-            if ($this->template_config->custom_style_sheet !== null) {
380
-                $this->addStylesheet(
381
-                    CoreAssetManager::CSS_HANDLE_CUSTOM,
382
-                    EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
383
-                    array(CoreAssetManager::CSS_HANDLE_DEFAULT)
384
-                );
385
-            }
386
-        }
387
-        $this->addCss(self::CSS_HANDLE_CORE_CSS_DEFAULT, ['dashicons']);
388
-        $this->addCss(self::CSS_HANDLE_COMPONENTS, [self::CSS_HANDLE_CORE_CSS_DEFAULT]);
389
-    }
390
-
391
-
392
-    /**
393
-     * jQuery Validate for form validation
394
-     *
395
-     * @since 4.9.62.p
396
-     * @throws DomainException
397
-     * @throws DuplicateCollectionIdentifierException
398
-     * @throws InvalidDataTypeException
399
-     * @throws InvalidEntityException
400
-     */
401
-    private function loadJqueryValidate()
402
-    {
403
-        $this->addJavascript(
404
-            CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE,
405
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
406
-            array(CoreAssetManager::JS_HANDLE_JQUERY),
407
-            true,
408
-            '1.15.0'
409
-        );
410
-
411
-        $this->addJavascript(
412
-            CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE_EXTRA,
413
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
414
-            array(CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE),
415
-            true,
416
-            '1.15.0'
417
-        );
418
-    }
419
-
420
-
421
-    /**
422
-     * accounting.js for performing client-side calculations
423
-     *
424
-     * @since 4.9.62.p
425
-     * @throws DomainException
426
-     * @throws DuplicateCollectionIdentifierException
427
-     * @throws InvalidDataTypeException
428
-     * @throws InvalidEntityException
429
-     */
430
-    private function loadAccountingJs()
431
-    {
432
-        //accounting.js library
433
-        // @link http://josscrowcroft.github.io/accounting.js/
434
-        $this->addJavascript(
435
-            CoreAssetManager::JS_HANDLE_ACCOUNTING_CORE,
436
-            EE_THIRD_PARTY_URL . 'accounting/accounting.js',
437
-            array(CoreAssetManager::JS_HANDLE_UNDERSCORE),
438
-            true,
439
-            '0.3.2'
440
-        );
441
-
442
-        $this->addJavascript(
443
-            CoreAssetManager::JS_HANDLE_ACCOUNTING,
444
-            EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js',
445
-            array(CoreAssetManager::JS_HANDLE_ACCOUNTING_CORE)
446
-        )
447
-        ->setInlineDataCallback(
448
-            function () {
449
-                 wp_localize_script(
450
-                     CoreAssetManager::JS_HANDLE_ACCOUNTING,
451
-                     'EE_ACCOUNTING_CFG',
452
-                     $this->getAccountingSettings()
453
-                 );
454
-            }
455
-        );
456
-    }
457
-
458
-
459
-    /**
460
-     * registers assets for cleaning your ears
461
-     *
462
-     * @param JavascriptAsset $script
463
-     */
464
-    public function loadQtipJs(JavascriptAsset $script)
465
-    {
466
-        // qtip is turned OFF by default, but prior to the wp_enqueue_scripts hook,
467
-        // can be turned back on again via: add_filter('FHEE_load_qtip', '__return_true' );
468
-        if (
469
-            $script->handle() === CoreAssetManager::JS_HANDLE_WP_PLUGINS_PAGE
470
-            && apply_filters('FHEE_load_qtip', false)
471
-        ) {
472
-            EEH_Qtip_Loader::instance()->register_and_enqueue();
473
-        }
474
-    }
475
-
476
-
477
-    /**
478
-     * assets that are used in the WordPress admin
479
-     *
480
-     * @throws DuplicateCollectionIdentifierException
481
-     * @throws InvalidDataTypeException
482
-     * @throws InvalidEntityException
483
-     * @throws DomainException
484
-     * @since 4.9.62.p
485
-     */
486
-    private function registerAdminAssets()
487
-    {
488
-        $this->addJs(self::JS_HANDLE_WP_PLUGINS_PAGE)->setRequiresTranslation();
489
-        // note usage of the "JS_HANDLE.." constant is intentional here because css uses the same handle.
490
-        $this->addCss(self::JS_HANDLE_WP_PLUGINS_PAGE);
491
-    }
85
+	const JS_HANDLE_ACCOUNTING = 'ee-accounting';
86
+
87
+	const JS_HANDLE_WP_PLUGINS_PAGE = 'ee-wp-plugins-page';
88
+
89
+	// EE CSS assets handles
90
+	const CSS_HANDLE_DEFAULT = 'espresso_default';
91
+
92
+	const CSS_HANDLE_CUSTOM = 'espresso_custom_css';
93
+
94
+	const CSS_HANDLE_COMPONENTS = 'eventespresso-components';
95
+
96
+	const CSS_HANDLE_CORE_CSS_DEFAULT = 'eventespresso-core-css-default';
97
+
98
+	/**
99
+	 * @var EE_Currency_Config $currency_config
100
+	 */
101
+	protected $currency_config;
102
+
103
+	/**
104
+	 * @var EE_Template_Config $template_config
105
+	 */
106
+	protected $template_config;
107
+
108
+
109
+	/**
110
+	 * CoreAssetRegister constructor.
111
+	 *
112
+	 * @param AssetCollection    $assets
113
+	 * @param EE_Currency_Config $currency_config
114
+	 * @param EE_Template_Config $template_config
115
+	 * @param DomainInterface    $domain
116
+	 * @param Registry           $registry
117
+	 */
118
+	public function __construct(
119
+		AssetCollection $assets,
120
+		EE_Currency_Config $currency_config,
121
+		EE_Template_Config $template_config,
122
+		DomainInterface $domain,
123
+		Registry $registry
124
+	) {
125
+		$this->currency_config = $currency_config;
126
+		$this->template_config = $template_config;
127
+		parent::__construct($domain, $assets, $registry);
128
+	}
129
+
130
+
131
+	/**
132
+	 * @since 4.9.62.p
133
+	 * @throws DomainException
134
+	 * @throws DuplicateCollectionIdentifierException
135
+	 * @throws InvalidArgumentException
136
+	 * @throws InvalidDataTypeException
137
+	 * @throws InvalidEntityException
138
+	 * @throws InvalidInterfaceException
139
+	 */
140
+	public function addAssets()
141
+	{
142
+		$this->addJavascriptFiles();
143
+		$this->addStylesheetFiles();
144
+	}
145
+
146
+
147
+	/**
148
+	 * @since 4.9.62.p
149
+	 * @throws DomainException
150
+	 * @throws DuplicateCollectionIdentifierException
151
+	 * @throws InvalidArgumentException
152
+	 * @throws InvalidDataTypeException
153
+	 * @throws InvalidEntityException
154
+	 * @throws InvalidInterfaceException
155
+	 */
156
+	public function addJavascriptFiles()
157
+	{
158
+		$this->loadCoreJs();
159
+		$this->loadJqueryValidate();
160
+		$this->loadAccountingJs();
161
+		add_action(
162
+			'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script',
163
+			array($this, 'loadQtipJs')
164
+		);
165
+		$this->registerAdminAssets();
166
+	}
167
+
168
+
169
+	/**
170
+	 * @throws DuplicateCollectionIdentifierException
171
+	 * @throws InvalidDataTypeException
172
+	 * @throws InvalidEntityException
173
+	 * @throws DomainException
174
+	 * @since 4.9.62.p
175
+	 */
176
+	public function addStylesheetFiles()
177
+	{
178
+		$this->loadCoreCss();
179
+	}
180
+
181
+
182
+	/**
183
+	 * core default javascript
184
+	 *
185
+	 * @since 4.9.62.p
186
+	 * @throws DomainException
187
+	 * @throws DuplicateCollectionIdentifierException
188
+	 * @throws InvalidArgumentException
189
+	 * @throws InvalidDataTypeException
190
+	 * @throws InvalidEntityException
191
+	 * @throws InvalidInterfaceException
192
+	 */
193
+	private function loadCoreJs()
194
+	{
195
+		// conditionally load third-party libraries that WP core MIGHT have.
196
+		$this->registerWpAssets();
197
+
198
+		$this->addJs(self::JS_HANDLE_JS_CORE)->setHasInlineData();
199
+		$this->addJs(self::JS_HANDLE_VENDOR);
200
+		$this->addJs(self::JS_HANDLE_VALIDATORS)->setRequiresTranslation();
201
+		$this->addJs(self::JS_HANDLE_HELPERS)->setRequiresTranslation();
202
+		$this->addJs(self::JS_HANDLE_MODEL)->setRequiresTranslation();
203
+		$this->addJs(self::JS_HANDLE_VALUE_OBJECTS)->setRequiresTranslation();
204
+		$this->addJs(self::JS_HANDLE_DATA_STORES)->setRequiresTranslation()->setInlineDataCallback(
205
+			static function () {
206
+				wp_add_inline_script(
207
+					CoreAssetManager::JS_HANDLE_DATA_STORES,
208
+					is_admin()
209
+						? 'wp.apiFetch.use( eejs.middleWares.apiFetch.capsMiddleware( eejs.middleWares.apiFetch.CONTEXT_CAPS_EDIT ) )'
210
+						: 'wp.apiFetch.use( eejs.middleWares.apiFetch.capsMiddleware )'
211
+				);
212
+			}
213
+		);
214
+		$this->addJs(self::JS_HANDLE_HOCS, [self::JS_HANDLE_DATA_STORES])->setRequiresTranslation();
215
+		$this->addJs(self::JS_HANDLE_COMPONENTS, [self::JS_HANDLE_DATA_STORES])->setRequiresTranslation();
216
+		$this->addJs(self::JS_HANDLE_EDITOR_HOCS)->setRequiresTranslation();
217
+
218
+		$this->registry->addData('eejs_api_nonce', wp_create_nonce('wp_rest'));
219
+		$this->registry->addData(
220
+			'paths',
221
+			array(
222
+				'base_rest_route' => rest_url(),
223
+				'rest_route' => rest_url('ee/v4.8.36/'),
224
+				'collection_endpoints' => EED_Core_Rest_Api::getCollectionRoutesIndexedByModelName(),
225
+				'primary_keys' => EED_Core_Rest_Api::getPrimaryKeyNamesIndexedByModelName(),
226
+				'site_url' => site_url('/'),
227
+				'admin_url' => admin_url('/'),
228
+			)
229
+		);
230
+		// Event Espresso brand name
231
+		$this->registry->addData('brandName', Domain::brandName());
232
+		/** site formatting values **/
233
+		$this->registry->addData(
234
+			'site_formats',
235
+			array(
236
+				'date_formats' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats()
237
+			)
238
+		);
239
+		/** currency data **/
240
+		$this->registry->addData(
241
+			'currency_config',
242
+			$this->getCurrencySettings()
243
+		);
244
+		/** site timezone */
245
+		$this->registry->addData(
246
+			'default_timezone',
247
+			array(
248
+				'pretty' => EEH_DTT_Helper::get_timezone_string_for_display(),
249
+				'string' => get_option('timezone_string'),
250
+				'offset' => EEH_DTT_Helper::get_site_timezone_gmt_offset(),
251
+			)
252
+		);
253
+		/** site locale (user locale if user logged in) */
254
+		$this->registry->addData(
255
+			'locale',
256
+			array(
257
+				'user' => get_user_locale(),
258
+				'site' => get_locale()
259
+			)
260
+		);
261
+
262
+		$this->addJavascript(
263
+			CoreAssetManager::JS_HANDLE_CORE,
264
+			EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
265
+			array(CoreAssetManager::JS_HANDLE_JQUERY)
266
+		)
267
+		->setInlineDataCallback(
268
+			static function () {
269
+				wp_localize_script(
270
+					CoreAssetManager::JS_HANDLE_CORE,
271
+					CoreAssetManager::JS_HANDLE_I18N,
272
+					EE_Registry::$i18n_js_strings
273
+				);
274
+			}
275
+		);
276
+	}
277
+
278
+
279
+	/**
280
+	 * Registers vendor files that are bundled with a later version WP but might not be for the current version of
281
+	 * WordPress in the running environment.
282
+	 *
283
+	 * @throws DuplicateCollectionIdentifierException
284
+	 * @throws InvalidDataTypeException
285
+	 * @throws InvalidEntityException
286
+	 * @throws DomainException
287
+	 * @since 4.9.71.p
288
+	 */
289
+	private function registerWpAssets()
290
+	{
291
+		global $wp_version;
292
+		if (version_compare($wp_version, '5.0.beta', '>=')) {
293
+			return;
294
+		}
295
+		$this->addVendorJavascript(CoreAssetManager::JS_HANDLE_REACT, [], true, '16.6.0');
296
+		$this->addVendorJavascript(
297
+			CoreAssetManager::JS_HANDLE_REACT_DOM,
298
+			array(CoreAssetManager::JS_HANDLE_REACT),
299
+			true,
300
+			'16.6.0'
301
+		);
302
+		$this->addVendorJavascript(CoreAssetManager::JS_HANDLE_LODASH, [], true, '4.17.11')
303
+			->setInlineDataCallback(
304
+				static function() {
305
+					wp_add_inline_script(
306
+						CoreAssetManager::JS_HANDLE_LODASH,
307
+						'window.lodash = _.noConflict();'
308
+					);
309
+				}
310
+			);
311
+	}
312
+
313
+
314
+	/**
315
+	 * Returns configuration data for the accounting-js library.
316
+	 * @since 4.9.71.p
317
+	 * @return array
318
+	 */
319
+	private function getAccountingSettings() {
320
+		return array(
321
+			'currency' => array(
322
+				'symbol'    => $this->currency_config->sign,
323
+				'format'    => array(
324
+					'pos'  => $this->currency_config->sign_b4 ? '%s%v' : '%v%s',
325
+					'neg'  => $this->currency_config->sign_b4 ? '- %s%v' : '- %v%s',
326
+					'zero' => $this->currency_config->sign_b4 ? '%s--' : '--%s',
327
+				),
328
+				'decimal'   => $this->currency_config->dec_mrk,
329
+				'thousand'  => $this->currency_config->thsnds,
330
+				'precision' => $this->currency_config->dec_plc,
331
+			),
332
+			'number'   => array(
333
+				'precision' => $this->currency_config->dec_plc,
334
+				'thousand'  => $this->currency_config->thsnds,
335
+				'decimal'   => $this->currency_config->dec_mrk,
336
+			),
337
+		);
338
+	}
339
+
340
+
341
+	/**
342
+	 * Returns configuration data for the js Currency VO.
343
+	 * @since 4.9.71.p
344
+	 * @return array
345
+	 */
346
+	private function getCurrencySettings()
347
+	{
348
+		return array(
349
+			'code' => $this->currency_config->code,
350
+			'singularLabel' => $this->currency_config->name,
351
+			'pluralLabel' => $this->currency_config->plural,
352
+			'sign' => $this->currency_config->sign,
353
+			'signB4' => $this->currency_config->sign_b4,
354
+			'decimalPlaces' => $this->currency_config->dec_plc,
355
+			'decimalMark' => $this->currency_config->dec_mrk,
356
+			'thousandsSeparator' => $this->currency_config->thsnds,
357
+		);
358
+	}
359
+
360
+
361
+	/**
362
+	 * @throws DuplicateCollectionIdentifierException
363
+	 * @throws InvalidDataTypeException
364
+	 * @throws InvalidEntityException
365
+	 * @throws DomainException
366
+	 * @since 4.9.62.p
367
+	 */
368
+	private function loadCoreCss()
369
+	{
370
+		if ($this->template_config->enable_default_style && ! is_admin()) {
371
+			$this->addStylesheet(
372
+				CoreAssetManager::CSS_HANDLE_DEFAULT,
373
+				is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
374
+					? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css'
375
+					: EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
376
+				array('dashicons')
377
+			);
378
+			//Load custom style sheet if available
379
+			if ($this->template_config->custom_style_sheet !== null) {
380
+				$this->addStylesheet(
381
+					CoreAssetManager::CSS_HANDLE_CUSTOM,
382
+					EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
383
+					array(CoreAssetManager::CSS_HANDLE_DEFAULT)
384
+				);
385
+			}
386
+		}
387
+		$this->addCss(self::CSS_HANDLE_CORE_CSS_DEFAULT, ['dashicons']);
388
+		$this->addCss(self::CSS_HANDLE_COMPONENTS, [self::CSS_HANDLE_CORE_CSS_DEFAULT]);
389
+	}
390
+
391
+
392
+	/**
393
+	 * jQuery Validate for form validation
394
+	 *
395
+	 * @since 4.9.62.p
396
+	 * @throws DomainException
397
+	 * @throws DuplicateCollectionIdentifierException
398
+	 * @throws InvalidDataTypeException
399
+	 * @throws InvalidEntityException
400
+	 */
401
+	private function loadJqueryValidate()
402
+	{
403
+		$this->addJavascript(
404
+			CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE,
405
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
406
+			array(CoreAssetManager::JS_HANDLE_JQUERY),
407
+			true,
408
+			'1.15.0'
409
+		);
410
+
411
+		$this->addJavascript(
412
+			CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE_EXTRA,
413
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
414
+			array(CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE),
415
+			true,
416
+			'1.15.0'
417
+		);
418
+	}
419
+
420
+
421
+	/**
422
+	 * accounting.js for performing client-side calculations
423
+	 *
424
+	 * @since 4.9.62.p
425
+	 * @throws DomainException
426
+	 * @throws DuplicateCollectionIdentifierException
427
+	 * @throws InvalidDataTypeException
428
+	 * @throws InvalidEntityException
429
+	 */
430
+	private function loadAccountingJs()
431
+	{
432
+		//accounting.js library
433
+		// @link http://josscrowcroft.github.io/accounting.js/
434
+		$this->addJavascript(
435
+			CoreAssetManager::JS_HANDLE_ACCOUNTING_CORE,
436
+			EE_THIRD_PARTY_URL . 'accounting/accounting.js',
437
+			array(CoreAssetManager::JS_HANDLE_UNDERSCORE),
438
+			true,
439
+			'0.3.2'
440
+		);
441
+
442
+		$this->addJavascript(
443
+			CoreAssetManager::JS_HANDLE_ACCOUNTING,
444
+			EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js',
445
+			array(CoreAssetManager::JS_HANDLE_ACCOUNTING_CORE)
446
+		)
447
+		->setInlineDataCallback(
448
+			function () {
449
+				 wp_localize_script(
450
+					 CoreAssetManager::JS_HANDLE_ACCOUNTING,
451
+					 'EE_ACCOUNTING_CFG',
452
+					 $this->getAccountingSettings()
453
+				 );
454
+			}
455
+		);
456
+	}
457
+
458
+
459
+	/**
460
+	 * registers assets for cleaning your ears
461
+	 *
462
+	 * @param JavascriptAsset $script
463
+	 */
464
+	public function loadQtipJs(JavascriptAsset $script)
465
+	{
466
+		// qtip is turned OFF by default, but prior to the wp_enqueue_scripts hook,
467
+		// can be turned back on again via: add_filter('FHEE_load_qtip', '__return_true' );
468
+		if (
469
+			$script->handle() === CoreAssetManager::JS_HANDLE_WP_PLUGINS_PAGE
470
+			&& apply_filters('FHEE_load_qtip', false)
471
+		) {
472
+			EEH_Qtip_Loader::instance()->register_and_enqueue();
473
+		}
474
+	}
475
+
476
+
477
+	/**
478
+	 * assets that are used in the WordPress admin
479
+	 *
480
+	 * @throws DuplicateCollectionIdentifierException
481
+	 * @throws InvalidDataTypeException
482
+	 * @throws InvalidEntityException
483
+	 * @throws DomainException
484
+	 * @since 4.9.62.p
485
+	 */
486
+	private function registerAdminAssets()
487
+	{
488
+		$this->addJs(self::JS_HANDLE_WP_PLUGINS_PAGE)->setRequiresTranslation();
489
+		// note usage of the "JS_HANDLE.." constant is intentional here because css uses the same handle.
490
+		$this->addCss(self::JS_HANDLE_WP_PLUGINS_PAGE);
491
+	}
492 492
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -202,7 +202,7 @@  discard block
 block discarded – undo
202 202
         $this->addJs(self::JS_HANDLE_MODEL)->setRequiresTranslation();
203 203
         $this->addJs(self::JS_HANDLE_VALUE_OBJECTS)->setRequiresTranslation();
204 204
         $this->addJs(self::JS_HANDLE_DATA_STORES)->setRequiresTranslation()->setInlineDataCallback(
205
-            static function () {
205
+            static function() {
206 206
                 wp_add_inline_script(
207 207
                     CoreAssetManager::JS_HANDLE_DATA_STORES,
208 208
                     is_admin()
@@ -261,11 +261,11 @@  discard block
 block discarded – undo
261 261
 
262 262
         $this->addJavascript(
263 263
             CoreAssetManager::JS_HANDLE_CORE,
264
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
264
+            EE_GLOBAL_ASSETS_URL.'scripts/espresso_core.js',
265 265
             array(CoreAssetManager::JS_HANDLE_JQUERY)
266 266
         )
267 267
         ->setInlineDataCallback(
268
-            static function () {
268
+            static function() {
269 269
                 wp_localize_script(
270 270
                     CoreAssetManager::JS_HANDLE_CORE,
271 271
                     CoreAssetManager::JS_HANDLE_I18N,
@@ -370,16 +370,16 @@  discard block
 block discarded – undo
370 370
         if ($this->template_config->enable_default_style && ! is_admin()) {
371 371
             $this->addStylesheet(
372 372
                 CoreAssetManager::CSS_HANDLE_DEFAULT,
373
-                is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
373
+                is_readable(EVENT_ESPRESSO_UPLOAD_DIR.'css/style.css')
374 374
                     ? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css'
375
-                    : EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
375
+                    : EE_GLOBAL_ASSETS_URL.'css/espresso_default.css',
376 376
                 array('dashicons')
377 377
             );
378 378
             //Load custom style sheet if available
379 379
             if ($this->template_config->custom_style_sheet !== null) {
380 380
                 $this->addStylesheet(
381 381
                     CoreAssetManager::CSS_HANDLE_CUSTOM,
382
-                    EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
382
+                    EVENT_ESPRESSO_UPLOAD_URL.'css/'.$this->template_config->custom_style_sheet,
383 383
                     array(CoreAssetManager::CSS_HANDLE_DEFAULT)
384 384
                 );
385 385
             }
@@ -402,7 +402,7 @@  discard block
 block discarded – undo
402 402
     {
403 403
         $this->addJavascript(
404 404
             CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE,
405
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
405
+            EE_GLOBAL_ASSETS_URL.'scripts/jquery.validate.min.js',
406 406
             array(CoreAssetManager::JS_HANDLE_JQUERY),
407 407
             true,
408 408
             '1.15.0'
@@ -410,7 +410,7 @@  discard block
 block discarded – undo
410 410
 
411 411
         $this->addJavascript(
412 412
             CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE_EXTRA,
413
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
413
+            EE_GLOBAL_ASSETS_URL.'scripts/jquery.validate.additional-methods.min.js',
414 414
             array(CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE),
415 415
             true,
416 416
             '1.15.0'
@@ -433,7 +433,7 @@  discard block
 block discarded – undo
433 433
         // @link http://josscrowcroft.github.io/accounting.js/
434 434
         $this->addJavascript(
435 435
             CoreAssetManager::JS_HANDLE_ACCOUNTING_CORE,
436
-            EE_THIRD_PARTY_URL . 'accounting/accounting.js',
436
+            EE_THIRD_PARTY_URL.'accounting/accounting.js',
437 437
             array(CoreAssetManager::JS_HANDLE_UNDERSCORE),
438 438
             true,
439 439
             '0.3.2'
@@ -441,11 +441,11 @@  discard block
 block discarded – undo
441 441
 
442 442
         $this->addJavascript(
443 443
             CoreAssetManager::JS_HANDLE_ACCOUNTING,
444
-            EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js',
444
+            EE_GLOBAL_ASSETS_URL.'scripts/ee-accounting-config.js',
445 445
             array(CoreAssetManager::JS_HANDLE_ACCOUNTING_CORE)
446 446
         )
447 447
         ->setInlineDataCallback(
448
-            function () {
448
+            function() {
449 449
                  wp_localize_script(
450 450
                      CoreAssetManager::JS_HANDLE_ACCOUNTING,
451 451
                      'EE_ACCOUNTING_CFG',
Please login to merge, or discard this patch.
core/domain/Domain.php 1 patch
Indentation   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -15,66 +15,66 @@
 block discarded – undo
15 15
  */
16 16
 class Domain extends DomainBase implements CaffeinatedInterface
17 17
 {
18
-    /**
19
-     * URL path component used to denote an API request
20
-     */
21
-    const API_NAMESPACE = 'ee/v';
18
+	/**
19
+	 * URL path component used to denote an API request
20
+	 */
21
+	const API_NAMESPACE = 'ee/v';
22 22
 
23
-    /**
24
-     * Slug used for the context where a registration status is changed from a manual trigger in the Registration Admin
25
-     * Page ui.
26
-     */
27
-    const CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN
28
-        = 'manual_registration_status_change_from_registration_admin';
23
+	/**
24
+	 * Slug used for the context where a registration status is changed from a manual trigger in the Registration Admin
25
+	 * Page ui.
26
+	 */
27
+	const CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN
28
+		= 'manual_registration_status_change_from_registration_admin';
29 29
 
30
-    const CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
31
-        = 'manual_registration_status_change_from_registration_admin_and_notify';
30
+	const CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
31
+		= 'manual_registration_status_change_from_registration_admin_and_notify';
32 32
 
33 33
 
34
-    /**
35
-     * Whether or not EE core is the full premium version.
36
-     * @since 4.9.59.p
37
-     * @var bool
38
-     */
39
-    private $caffeinated;
34
+	/**
35
+	 * Whether or not EE core is the full premium version.
36
+	 * @since 4.9.59.p
37
+	 * @var bool
38
+	 */
39
+	private $caffeinated;
40 40
 
41 41
 
42
-    public function __construct(FilePath $plugin_file, Version $version)
43
-    {
44
-        parent::__construct($plugin_file, $version);
45
-        $this->setCaffeinated();
46
-    }
42
+	public function __construct(FilePath $plugin_file, Version $version)
43
+	{
44
+		parent::__construct($plugin_file, $version);
45
+		$this->setCaffeinated();
46
+	}
47 47
 
48
-    /**
49
-     * Whether or not EE core is the full premium version.
50
-     * @since 4.9.59.p
51
-     * @return bool
52
-     */
53
-    public function isCaffeinated()
54
-    {
55
-        return $this->caffeinated;
56
-    }
48
+	/**
49
+	 * Whether or not EE core is the full premium version.
50
+	 * @since 4.9.59.p
51
+	 * @return bool
52
+	 */
53
+	public function isCaffeinated()
54
+	{
55
+		return $this->caffeinated;
56
+	}
57 57
 
58 58
 
59
-    /**
60
-     * Setter for $is_caffeinated property.
61
-     * @since 4.9.59.p
62
-     */
63
-    private function setCaffeinated()
64
-    {
65
-        $this->caffeinated = (! defined('EE_DECAF') || EE_DECAF !== true)
66
-            && is_readable($this->pluginPath() . 'caffeinated/brewing_regular.php');
67
-    }
59
+	/**
60
+	 * Setter for $is_caffeinated property.
61
+	 * @since 4.9.59.p
62
+	 */
63
+	private function setCaffeinated()
64
+	{
65
+		$this->caffeinated = (! defined('EE_DECAF') || EE_DECAF !== true)
66
+			&& is_readable($this->pluginPath() . 'caffeinated/brewing_regular.php');
67
+	}
68 68
 
69 69
 
70
-    /**
71
-     * This should be used everywhere the Event Espresso brand name is referenced in public facing interfaces
72
-     * to allow for filtering the brand.
73
-     *
74
-     * @return string
75
-     */
76
-    public static function brandName()
77
-    {
78
-        return (string) apply_filters('FHEE__EventEspresso_core_domain_Domain__brandName', 'Event Espresso');
79
-    }
70
+	/**
71
+	 * This should be used everywhere the Event Espresso brand name is referenced in public facing interfaces
72
+	 * to allow for filtering the brand.
73
+	 *
74
+	 * @return string
75
+	 */
76
+	public static function brandName()
77
+	{
78
+		return (string) apply_filters('FHEE__EventEspresso_core_domain_Domain__brandName', 'Event Espresso');
79
+	}
80 80
 }
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -38,103 +38,103 @@
 block discarded – undo
38 38
  * @since           4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 } else {
64
-    define('EE_MIN_PHP_VER_REQUIRED', '5.4.0');
65
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
-        /**
67
-         * espresso_minimum_php_version_error
68
-         *
69
-         * @return void
70
-         */
71
-        function espresso_minimum_php_version_error()
72
-        {
73
-            ?>
64
+	define('EE_MIN_PHP_VER_REQUIRED', '5.4.0');
65
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
+		/**
67
+		 * espresso_minimum_php_version_error
68
+		 *
69
+		 * @return void
70
+		 */
71
+		function espresso_minimum_php_version_error()
72
+		{
73
+			?>
74 74
             <div class="error">
75 75
                 <p>
76 76
                     <?php
77
-                    printf(
78
-                        esc_html__(
79
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
-                            'event_espresso'
81
-                        ),
82
-                        EE_MIN_PHP_VER_REQUIRED,
83
-                        PHP_VERSION,
84
-                        '<br/>',
85
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
-                    );
87
-                    ?>
77
+					printf(
78
+						esc_html__(
79
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
+							'event_espresso'
81
+						),
82
+						EE_MIN_PHP_VER_REQUIRED,
83
+						PHP_VERSION,
84
+						'<br/>',
85
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
+					);
87
+					?>
88 88
                 </p>
89 89
             </div>
90 90
             <?php
91
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
92
-        }
91
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
92
+		}
93 93
 
94
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
-    } else {
96
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
-        /**
98
-         * espresso_version
99
-         * Returns the plugin version
100
-         *
101
-         * @return string
102
-         */
103
-        function espresso_version()
104
-        {
105
-            return apply_filters('FHEE__espresso__espresso_version', '4.10.2.rc.083');
106
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
+		/**
98
+		 * espresso_version
99
+		 * Returns the plugin version
100
+		 *
101
+		 * @return string
102
+		 */
103
+		function espresso_version()
104
+		{
105
+			return apply_filters('FHEE__espresso__espresso_version', '4.10.2.rc.083');
106
+		}
107 107
 
108
-        /**
109
-         * espresso_plugin_activation
110
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
-         */
112
-        function espresso_plugin_activation()
113
-        {
114
-            update_option('ee_espresso_activation', true);
115
-        }
108
+		/**
109
+		 * espresso_plugin_activation
110
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
+		 */
112
+		function espresso_plugin_activation()
113
+		{
114
+			update_option('ee_espresso_activation', true);
115
+		}
116 116
 
117
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
117
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
118 118
 
119
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
120
-        bootstrap_espresso();
121
-    }
119
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
120
+		bootstrap_espresso();
121
+	}
122 122
 }
123 123
 if (! function_exists('espresso_deactivate_plugin')) {
124
-    /**
125
-     *    deactivate_plugin
126
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
-     *
128
-     * @access public
129
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
-     * @return    void
131
-     */
132
-    function espresso_deactivate_plugin($plugin_basename = '')
133
-    {
134
-        if (! function_exists('deactivate_plugins')) {
135
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
-        }
137
-        unset($_GET['activate'], $_REQUEST['activate']);
138
-        deactivate_plugins($plugin_basename);
139
-    }
124
+	/**
125
+	 *    deactivate_plugin
126
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
+	 *
128
+	 * @access public
129
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
+	 * @return    void
131
+	 */
132
+	function espresso_deactivate_plugin($plugin_basename = '')
133
+	{
134
+		if (! function_exists('deactivate_plugins')) {
135
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
+		}
137
+		unset($_GET['activate'], $_REQUEST['activate']);
138
+		deactivate_plugins($plugin_basename);
139
+	}
140 140
 }
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page.core.php 1 patch
Indentation   +4056 added lines, -4056 removed lines patch added patch discarded remove patch
@@ -17,4123 +17,4123 @@
 block discarded – undo
17 17
 abstract class EE_Admin_Page extends EE_Base implements InterminableInterface
18 18
 {
19 19
 
20
-    /**
21
-     * @var LoaderInterface $loader
22
-     */
23
-    protected $loader;
20
+	/**
21
+	 * @var LoaderInterface $loader
22
+	 */
23
+	protected $loader;
24 24
 
25
-    // set in _init_page_props()
26
-    public $page_slug;
25
+	// set in _init_page_props()
26
+	public $page_slug;
27 27
 
28
-    public $page_label;
28
+	public $page_label;
29 29
 
30
-    public $page_folder;
30
+	public $page_folder;
31 31
 
32
-    // set in define_page_props()
33
-    protected $_admin_base_url;
32
+	// set in define_page_props()
33
+	protected $_admin_base_url;
34 34
 
35
-    protected $_admin_base_path;
35
+	protected $_admin_base_path;
36 36
 
37
-    protected $_admin_page_title;
37
+	protected $_admin_page_title;
38 38
 
39
-    protected $_labels;
39
+	protected $_labels;
40 40
 
41 41
 
42
-    // set early within EE_Admin_Init
43
-    protected $_wp_page_slug;
42
+	// set early within EE_Admin_Init
43
+	protected $_wp_page_slug;
44 44
 
45
-    // navtabs
46
-    protected $_nav_tabs;
45
+	// navtabs
46
+	protected $_nav_tabs;
47 47
 
48
-    protected $_default_nav_tab_name;
48
+	protected $_default_nav_tab_name;
49 49
 
50
-    /**
51
-     * @var array $_help_tour
52
-     */
53
-    protected $_help_tour = array();
50
+	/**
51
+	 * @var array $_help_tour
52
+	 */
53
+	protected $_help_tour = array();
54 54
 
55 55
 
56
-    // template variables (used by templates)
57
-    protected $_template_path;
56
+	// template variables (used by templates)
57
+	protected $_template_path;
58 58
 
59
-    protected $_column_template_path;
59
+	protected $_column_template_path;
60 60
 
61
-    /**
62
-     * @var array $_template_args
63
-     */
64
-    protected $_template_args = array();
61
+	/**
62
+	 * @var array $_template_args
63
+	 */
64
+	protected $_template_args = array();
65 65
 
66
-    /**
67
-     * this will hold the list table object for a given view.
68
-     *
69
-     * @var EE_Admin_List_Table $_list_table_object
70
-     */
71
-    protected $_list_table_object;
66
+	/**
67
+	 * this will hold the list table object for a given view.
68
+	 *
69
+	 * @var EE_Admin_List_Table $_list_table_object
70
+	 */
71
+	protected $_list_table_object;
72 72
 
73
-    // bools
74
-    protected $_is_UI_request = null; // this starts at null so we can have no header routes progress through two states.
73
+	// bools
74
+	protected $_is_UI_request = null; // this starts at null so we can have no header routes progress through two states.
75 75
 
76
-    protected $_routing;
76
+	protected $_routing;
77 77
 
78
-    // list table args
79
-    protected $_view;
78
+	// list table args
79
+	protected $_view;
80 80
 
81
-    protected $_views;
81
+	protected $_views;
82 82
 
83 83
 
84
-    // action => method pairs used for routing incoming requests
85
-    protected $_page_routes;
84
+	// action => method pairs used for routing incoming requests
85
+	protected $_page_routes;
86 86
 
87
-    /**
88
-     * @var array $_page_config
89
-     */
90
-    protected $_page_config;
87
+	/**
88
+	 * @var array $_page_config
89
+	 */
90
+	protected $_page_config;
91 91
 
92
-    /**
93
-     * the current page route and route config
94
-     *
95
-     * @var string $_route
96
-     */
97
-    protected $_route;
92
+	/**
93
+	 * the current page route and route config
94
+	 *
95
+	 * @var string $_route
96
+	 */
97
+	protected $_route;
98 98
 
99
-    /**
100
-     * @var string $_cpt_route
101
-     */
102
-    protected $_cpt_route;
99
+	/**
100
+	 * @var string $_cpt_route
101
+	 */
102
+	protected $_cpt_route;
103 103
 
104
-    /**
105
-     * @var array $_route_config
106
-     */
107
-    protected $_route_config;
108
-
109
-    /**
110
-     * Used to hold default query args for list table routes to help preserve stickiness of filters for carried out
111
-     * actions.
112
-     *
113
-     * @since 4.6.x
114
-     * @var array.
115
-     */
116
-    protected $_default_route_query_args;
117
-
118
-    // set via request page and action args.
119
-    protected $_current_page;
120
-
121
-    protected $_current_view;
122
-
123
-    protected $_current_page_view_url;
124
-
125
-    // sanitized request action (and nonce)
126
-
127
-    /**
128
-     * @var string $_req_action
129
-     */
130
-    protected $_req_action;
131
-
132
-    /**
133
-     * @var string $_req_nonce
134
-     */
135
-    protected $_req_nonce;
136
-
137
-    // search related
138
-    protected $_search_btn_label;
139
-
140
-    protected $_search_box_callback;
141
-
142
-    /**
143
-     * WP Current Screen object
144
-     *
145
-     * @var WP_Screen
146
-     */
147
-    protected $_current_screen;
148
-
149
-    // for holding EE_Admin_Hooks object when needed (set via set_hook_object())
150
-    protected $_hook_obj;
151
-
152
-    // for holding incoming request data
153
-    protected $_req_data;
154
-
155
-    // yes / no array for admin form fields
156
-    protected $_yes_no_values = array();
157
-
158
-    // some default things shared by all child classes
159
-    protected $_default_espresso_metaboxes;
160
-
161
-    /**
162
-     *    EE_Registry Object
163
-     *
164
-     * @var    EE_Registry
165
-     */
166
-    protected $EE = null;
167
-
168
-
169
-    /**
170
-     * This is just a property that flags whether the given route is a caffeinated route or not.
171
-     *
172
-     * @var boolean
173
-     */
174
-    protected $_is_caf = false;
175
-
176
-
177
-    /**
178
-     * @Constructor
179
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
180
-     * @throws EE_Error
181
-     * @throws InvalidArgumentException
182
-     * @throws ReflectionException
183
-     * @throws InvalidDataTypeException
184
-     * @throws InvalidInterfaceException
185
-     */
186
-    public function __construct($routing = true)
187
-    {
188
-        $this->loader = LoaderFactory::getLoader();
189
-        if (strpos($this->_get_dir(), 'caffeinated') !== false) {
190
-            $this->_is_caf = true;
191
-        }
192
-        $this->_yes_no_values = array(
193
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
194
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
195
-        );
196
-        // set the _req_data property.
197
-        $this->_req_data = array_merge($_GET, $_POST);
198
-        // routing enabled?
199
-        $this->_routing = $routing;
200
-        // set initial page props (child method)
201
-        $this->_init_page_props();
202
-        // set global defaults
203
-        $this->_set_defaults();
204
-        // set early because incoming requests could be ajax related and we need to register those hooks.
205
-        $this->_global_ajax_hooks();
206
-        $this->_ajax_hooks();
207
-        // other_page_hooks have to be early too.
208
-        $this->_do_other_page_hooks();
209
-        // This just allows us to have extending classes do something specific
210
-        // before the parent constructor runs _page_setup().
211
-        if (method_exists($this, '_before_page_setup')) {
212
-            $this->_before_page_setup();
213
-        }
214
-        // set up page dependencies
215
-        $this->_page_setup();
216
-    }
217
-
218
-
219
-    /**
220
-     * _init_page_props
221
-     * Child classes use to set at least the following properties:
222
-     * $page_slug.
223
-     * $page_label.
224
-     *
225
-     * @abstract
226
-     * @return void
227
-     */
228
-    abstract protected function _init_page_props();
229
-
230
-
231
-    /**
232
-     * _ajax_hooks
233
-     * child classes put all their add_action('wp_ajax_{name_of_hook}') hooks in here.
234
-     * Note: within the ajax callback methods.
235
-     *
236
-     * @abstract
237
-     * @return void
238
-     */
239
-    abstract protected function _ajax_hooks();
240
-
241
-
242
-    /**
243
-     * _define_page_props
244
-     * child classes define page properties in here.  Must include at least:
245
-     * $_admin_base_url = base_url for all admin pages
246
-     * $_admin_page_title = default admin_page_title for admin pages
247
-     * $_labels = array of default labels for various automatically generated elements:
248
-     *    array(
249
-     *        'buttons' => array(
250
-     *            'add' => esc_html__('label for add new button'),
251
-     *            'edit' => esc_html__('label for edit button'),
252
-     *            'delete' => esc_html__('label for delete button')
253
-     *            )
254
-     *        )
255
-     *
256
-     * @abstract
257
-     * @return void
258
-     */
259
-    abstract protected function _define_page_props();
260
-
261
-
262
-    /**
263
-     * _set_page_routes
264
-     * child classes use this to define the page routes for all subpages handled by the class.  Page routes are
265
-     * assigned to a action => method pairs in an array and to the $_page_routes property.  Each page route must also
266
-     * have a 'default' route. Here's the format
267
-     * $this->_page_routes = array(
268
-     *        'default' => array(
269
-     *            'func' => '_default_method_handling_route',
270
-     *            'args' => array('array','of','args'),
271
-     *            'noheader' => true, //add this in if this page route is processed before any headers are loaded (i.e.
272
-     *            ajax request, backend processing)
273
-     *            'headers_sent_route'=>'headers_route_reference', //add this if noheader=>true, and you want to load a
274
-     *            headers route after.  The string you enter here should match the defined route reference for a
275
-     *            headers sent route.
276
-     *            'capability' => 'route_capability', //indicate a string for minimum capability required to access
277
-     *            this route.
278
-     *            'obj_id' => 10 // if this route has an object id, then this can include it (used for capability
279
-     *            checks).
280
-     *        ),
281
-     *        'insert_item' => '_method_for_handling_insert_item' //this can be used if all we need to have is a
282
-     *        handling method.
283
-     *        )
284
-     * )
285
-     *
286
-     * @abstract
287
-     * @return void
288
-     */
289
-    abstract protected function _set_page_routes();
290
-
291
-
292
-    /**
293
-     * _set_page_config
294
-     * child classes use this to define the _page_config array for all subpages handled by the class. Each key in the
295
-     * array corresponds to the page_route for the loaded page. Format:
296
-     * $this->_page_config = array(
297
-     *        'default' => array(
298
-     *            'labels' => array(
299
-     *                'buttons' => array(
300
-     *                    'add' => esc_html__('label for adding item'),
301
-     *                    'edit' => esc_html__('label for editing item'),
302
-     *                    'delete' => esc_html__('label for deleting item')
303
-     *                ),
304
-     *                'publishbox' => esc_html__('Localized Title for Publish metabox', 'event_espresso')
305
-     *            ), //optional an array of custom labels for various automatically generated elements to use on the
306
-     *            page. If this isn't present then the defaults will be used as set for the $this->_labels in
307
-     *            _define_page_props() method
308
-     *            'nav' => array(
309
-     *                'label' => esc_html__('Label for Tab', 'event_espresso').
310
-     *                'url' => 'http://someurl', //automatically generated UNLESS you define
311
-     *                'css_class' => 'css-class', //automatically generated UNLESS you define
312
-     *                'order' => 10, //required to indicate tab position.
313
-     *                'persistent' => false //if you want the nav tab to ONLY display when the specific route is
314
-     *                displayed then add this parameter.
315
-     *            'list_table' => 'name_of_list_table' //string for list table class to be loaded for this admin_page.
316
-     *            'metaboxes' => array('metabox1', 'metabox2'), //if present this key indicates we want to load
317
-     *            metaboxes set for eventespresso admin pages.
318
-     *            'has_metaboxes' => true, //this boolean flag can simply be used to indicate if the route will have
319
-     *            metaboxes.  Typically this is used if the 'metaboxes' index is not used because metaboxes are added
320
-     *            later.  We just use this flag to make sure the necessary js gets enqueued on page load.
321
-     *            'has_help_popups' => false //defaults(true) //this boolean flag can simply be used to indicate if the
322
-     *            given route has help popups setup and if it does then we need to make sure thickbox is enqueued.
323
-     *            'columns' => array(4, 2), //this key triggers the setup of a page that uses columns (metaboxes).  The
324
-     *            array indicates the max number of columns (4) and the default number of columns on page load (2).
325
-     *            There is an option in the "screen_options" dropdown that is setup so users can pick what columns they
326
-     *            want to display.
327
-     *            'help_tabs' => array( //this is used for adding help tabs to a page
328
-     *                'tab_id' => array(
329
-     *                    'title' => 'tab_title',
330
-     *                    'filename' => 'name_of_file_containing_content', //this is the primary method for setting
331
-     *                    help tab content.  The fallback if it isn't present is to try a the callback.  Filename
332
-     *                    should match a file in the admin folder's "help_tabs" dir (ie..
333
-     *                    events/help_tabs/name_of_file_containing_content.help_tab.php)
334
-     *                    'callback' => 'callback_method_for_content', //if 'filename' isn't present then system will
335
-     *                    attempt to use the callback which should match the name of a method in the class
336
-     *                    ),
337
-     *                'tab2_id' => array(
338
-     *                    'title' => 'tab2 title',
339
-     *                    'filename' => 'file_name_2'
340
-     *                    'callback' => 'callback_method_for_content',
341
-     *                 ),
342
-     *            'help_sidebar' => 'callback_for_sidebar_content', //this is used for setting up the sidebar in the
343
-     *            help tab area on an admin page. @link
344
-     *            http://make.wordpress.org/core/2011/12/06/help-and-screen-api-changes-in-3-3/
345
-     *            'help_tour' => array(
346
-     *                'name_of_help_tour_class', //all help tours shoudl be a child class of EE_Help_Tour and located
347
-     *                in a folder for this admin page named "help_tours", a file name matching the key given here
348
-     *                (name_of_help_tour_class.class.php), and class matching key given here (name_of_help_tour_class)
349
-     *            ),
350
-     *            'require_nonce' => TRUE //this is used if you want to set a route to NOT require a nonce (default is
351
-     *            true if it isn't present).  To remove the requirement for a nonce check when this route is visited
352
-     *            just set
353
-     *            'require_nonce' to FALSE
354
-     *            )
355
-     * )
356
-     *
357
-     * @abstract
358
-     * @return void
359
-     */
360
-    abstract protected function _set_page_config();
361
-
362
-
363
-
364
-
365
-
366
-    /** end sample help_tour methods **/
367
-    /**
368
-     * _add_screen_options
369
-     * Child classes can add any extra wp_screen_options within this method using built-in WP functions/methods for
370
-     * doing so. Note child classes can also define _add_screen_options_($this->_current_view) to limit screen options
371
-     * to a particular view.
372
-     *
373
-     * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
374
-     *         see also WP_Screen object documents...
375
-     * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
376
-     * @abstract
377
-     * @return void
378
-     */
379
-    abstract protected function _add_screen_options();
380
-
381
-
382
-    /**
383
-     * _add_feature_pointers
384
-     * Child classes should use this method for implementing any "feature pointers" (using built-in WP styling js).
385
-     * Note child classes can also define _add_feature_pointers_($this->_current_view) to limit screen options to a
386
-     * particular view. Note: this is just a placeholder for now.  Implementation will come down the road See:
387
-     * WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
388
-     * extended) also see:
389
-     *
390
-     * @link   http://eamann.com/tech/wordpress-portland/
391
-     * @abstract
392
-     * @return void
393
-     */
394
-    abstract protected function _add_feature_pointers();
395
-
396
-
397
-    /**
398
-     * load_scripts_styles
399
-     * child classes put their wp_enqueue_script and wp_enqueue_style hooks in here for anything they need loaded for
400
-     * their pages/subpages.  Note this is for all pages/subpages of the system.  You can also load only specific
401
-     * scripts/styles per view by putting them in a dynamic function in this format
402
-     * (load_scripts_styles_{$this->_current_view}) which matches your page route (action request arg)
403
-     *
404
-     * @abstract
405
-     * @return void
406
-     */
407
-    abstract public function load_scripts_styles();
408
-
409
-
410
-    /**
411
-     * admin_init
412
-     * Anything that should be set/executed at 'admin_init' WP hook runtime should be put in here.  This will apply to
413
-     * all pages/views loaded by child class.
414
-     *
415
-     * @abstract
416
-     * @return void
417
-     */
418
-    abstract public function admin_init();
419
-
420
-
421
-    /**
422
-     * admin_notices
423
-     * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply to
424
-     * all pages/views loaded by child class.
425
-     *
426
-     * @abstract
427
-     * @return void
428
-     */
429
-    abstract public function admin_notices();
430
-
431
-
432
-    /**
433
-     * admin_footer_scripts
434
-     * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
435
-     * will apply to all pages/views loaded by child class.
436
-     *
437
-     * @return void
438
-     */
439
-    abstract public function admin_footer_scripts();
440
-
441
-
442
-    /**
443
-     * admin_footer
444
-     * anything triggered by the 'admin_footer' WP action hook should be added to here. This particular method will
445
-     * apply to all pages/views loaded by child class.
446
-     *
447
-     * @return void
448
-     */
449
-    public function admin_footer()
450
-    {
451
-    }
452
-
453
-
454
-    /**
455
-     * _global_ajax_hooks
456
-     * all global add_action('wp_ajax_{name_of_hook}') hooks in here.
457
-     * Note: within the ajax callback methods.
458
-     *
459
-     * @abstract
460
-     * @return void
461
-     */
462
-    protected function _global_ajax_hooks()
463
-    {
464
-        // for lazy loading of metabox content
465
-        add_action('wp_ajax_espresso-ajax-content', array($this, 'ajax_metabox_content'), 10);
466
-    }
467
-
468
-
469
-    public function ajax_metabox_content()
470
-    {
471
-        $contentid = isset($this->_req_data['contentid']) ? $this->_req_data['contentid'] : '';
472
-        $url = isset($this->_req_data['contenturl']) ? $this->_req_data['contenturl'] : '';
473
-        self::cached_rss_display($contentid, $url);
474
-        wp_die();
475
-    }
476
-
477
-
478
-    /**
479
-     * _page_setup
480
-     * Makes sure any things that need to be loaded early get handled.  We also escape early here if the page requested
481
-     * doesn't match the object.
482
-     *
483
-     * @final
484
-     * @return void
485
-     * @throws EE_Error
486
-     * @throws InvalidArgumentException
487
-     * @throws ReflectionException
488
-     * @throws InvalidDataTypeException
489
-     * @throws InvalidInterfaceException
490
-     */
491
-    final protected function _page_setup()
492
-    {
493
-        // requires?
494
-        // admin_init stuff - global - we're setting this REALLY early so if EE_Admin pages have to hook into other WP pages they can.  But keep in mind, not everything is available from the EE_Admin Page object at this point.
495
-        add_action('admin_init', array($this, 'admin_init_global'), 5);
496
-        // next verify if we need to load anything...
497
-        $this->_current_page = ! empty($_GET['page']) ? sanitize_key($_GET['page']) : '';
498
-        $this->page_folder = strtolower(
499
-            str_replace(array('_Admin_Page', 'Extend_'), '', get_class($this))
500
-        );
501
-        global $ee_menu_slugs;
502
-        $ee_menu_slugs = (array) $ee_menu_slugs;
503
-        if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[ $this->_current_page ]))) {
504
-            return;
505
-        }
506
-        // becuz WP List tables have two duplicate select inputs for choosing bulk actions, we need to copy the action from the second to the first
507
-        if (isset($this->_req_data['action2']) && $this->_req_data['action'] === '-1') {
508
-            $this->_req_data['action'] = ! empty($this->_req_data['action2']) && $this->_req_data['action2'] !== '-1'
509
-                ? $this->_req_data['action2']
510
-                : $this->_req_data['action'];
511
-        }
512
-        // then set blank or -1 action values to 'default'
513
-        $this->_req_action = isset($this->_req_data['action'])
514
-                             && ! empty($this->_req_data['action'])
515
-                             && $this->_req_data['action'] !== '-1'
516
-            ? sanitize_key($this->_req_data['action'])
517
-            : 'default';
518
-        // if action is 'default' after the above BUT we have  'route' var set, then let's use the route as the action.
519
-        //  This covers cases where we're coming in from a list table that isn't on the default route.
520
-        $this->_req_action = $this->_req_action === 'default' && isset($this->_req_data['route'])
521
-            ? $this->_req_data['route'] : $this->_req_action;
522
-        // however if we are doing_ajax and we've got a 'route' set then that's what the req_action will be
523
-        $this->_req_action = defined('DOING_AJAX') && isset($this->_req_data['route'])
524
-            ? $this->_req_data['route']
525
-            : $this->_req_action;
526
-        $this->_current_view = $this->_req_action;
527
-        $this->_req_nonce = $this->_req_action . '_nonce';
528
-        $this->_define_page_props();
529
-        $this->_current_page_view_url = add_query_arg(
530
-            array('page' => $this->_current_page, 'action' => $this->_current_view),
531
-            $this->_admin_base_url
532
-        );
533
-        // default things
534
-        $this->_default_espresso_metaboxes = array(
535
-            '_espresso_news_post_box',
536
-            '_espresso_links_post_box',
537
-            '_espresso_ratings_request',
538
-            '_espresso_sponsors_post_box',
539
-        );
540
-        // set page configs
541
-        $this->_set_page_routes();
542
-        $this->_set_page_config();
543
-        // let's include any referrer data in our default_query_args for this route for "stickiness".
544
-        if (isset($this->_req_data['wp_referer'])) {
545
-            $this->_default_route_query_args['wp_referer'] = $this->_req_data['wp_referer'];
546
-        }
547
-        // for caffeinated and other extended functionality.
548
-        //  If there is a _extend_page_config method
549
-        // then let's run that to modify the all the various page configuration arrays
550
-        if (method_exists($this, '_extend_page_config')) {
551
-            $this->_extend_page_config();
552
-        }
553
-        // for CPT and other extended functionality.
554
-        // If there is an _extend_page_config_for_cpt
555
-        // then let's run that to modify all the various page configuration arrays.
556
-        if (method_exists($this, '_extend_page_config_for_cpt')) {
557
-            $this->_extend_page_config_for_cpt();
558
-        }
559
-        // filter routes and page_config so addons can add their stuff. Filtering done per class
560
-        $this->_page_routes = apply_filters(
561
-            'FHEE__' . get_class($this) . '__page_setup__page_routes',
562
-            $this->_page_routes,
563
-            $this
564
-        );
565
-        $this->_page_config = apply_filters(
566
-            'FHEE__' . get_class($this) . '__page_setup__page_config',
567
-            $this->_page_config,
568
-            $this
569
-        );
570
-        // if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present
571
-        // then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action
572
-        if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)) {
573
-            add_action(
574
-                'AHEE__EE_Admin_Page__route_admin_request',
575
-                array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view),
576
-                10,
577
-                2
578
-            );
579
-        }
580
-        // next route only if routing enabled
581
-        if ($this->_routing && ! defined('DOING_AJAX')) {
582
-            $this->_verify_routes();
583
-            // next let's just check user_access and kill if no access
584
-            $this->check_user_access();
585
-            if ($this->_is_UI_request) {
586
-                // admin_init stuff - global, all views for this page class, specific view
587
-                add_action('admin_init', array($this, 'admin_init'), 10);
588
-                if (method_exists($this, 'admin_init_' . $this->_current_view)) {
589
-                    add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15);
590
-                }
591
-            } else {
592
-                // hijack regular WP loading and route admin request immediately
593
-                @ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
594
-                $this->route_admin_request();
595
-            }
596
-        }
597
-    }
598
-
599
-
600
-    /**
601
-     * Provides a way for related child admin pages to load stuff on the loaded admin page.
602
-     *
603
-     * @return void
604
-     * @throws ReflectionException
605
-     * @throws EE_Error
606
-     */
607
-    private function _do_other_page_hooks()
608
-    {
609
-        $registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array());
610
-        foreach ($registered_pages as $page) {
611
-            // now let's setup the file name and class that should be present
612
-            $classname = str_replace('.class.php', '', $page);
613
-            // autoloaders should take care of loading file
614
-            if (! class_exists($classname)) {
615
-                $error_msg[] = sprintf(
616
-                    esc_html__(
617
-                        'Something went wrong with loading the %s admin hooks page.',
618
-                        'event_espresso'
619
-                    ),
620
-                    $page
621
-                );
622
-                $error_msg[] = $error_msg[0]
623
-                               . "\r\n"
624
-                               . sprintf(
625
-                                   esc_html__(
626
-                                       'There is no class in place for the %1$s admin hooks page.%2$sMake sure you have %3$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
627
-                                       'event_espresso'
628
-                                   ),
629
-                                   $page,
630
-                                   '<br />',
631
-                                   '<strong>' . $classname . '</strong>'
632
-                               );
633
-                throw new EE_Error(implode('||', $error_msg));
634
-            }
635
-            $a = new ReflectionClass($classname);
636
-            // notice we are passing the instance of this class to the hook object.
637
-            $hookobj[] = $a->newInstance($this);
638
-        }
639
-    }
640
-
641
-
642
-    public function load_page_dependencies()
643
-    {
644
-        try {
645
-            $this->_load_page_dependencies();
646
-        } catch (EE_Error $e) {
647
-            $e->get_error();
648
-        }
649
-    }
650
-
651
-
652
-    /**
653
-     * load_page_dependencies
654
-     * loads things specific to this page class when its loaded.  Really helps with efficiency.
655
-     *
656
-     * @return void
657
-     * @throws DomainException
658
-     * @throws EE_Error
659
-     * @throws InvalidArgumentException
660
-     * @throws InvalidDataTypeException
661
-     * @throws InvalidInterfaceException
662
-     * @throws ReflectionException
663
-     */
664
-    protected function _load_page_dependencies()
665
-    {
666
-        // let's set the current_screen and screen options to override what WP set
667
-        $this->_current_screen = get_current_screen();
668
-        // load admin_notices - global, page class, and view specific
669
-        add_action('admin_notices', array($this, 'admin_notices_global'), 5);
670
-        add_action('admin_notices', array($this, 'admin_notices'), 10);
671
-        if (method_exists($this, 'admin_notices_' . $this->_current_view)) {
672
-            add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15);
673
-        }
674
-        // load network admin_notices - global, page class, and view specific
675
-        add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5);
676
-        if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) {
677
-            add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view));
678
-        }
679
-        // this will save any per_page screen options if they are present
680
-        $this->_set_per_page_screen_options();
681
-        // setup list table properties
682
-        $this->_set_list_table();
683
-        // child classes can "register" a metabox to be automatically handled via the _page_config array property.
684
-        // However in some cases the metaboxes will need to be added within a route handling callback.
685
-        $this->_add_registered_meta_boxes();
686
-        $this->_add_screen_columns();
687
-        // add screen options - global, page child class, and view specific
688
-        $this->_add_global_screen_options();
689
-        $this->_add_screen_options();
690
-        $add_screen_options = "_add_screen_options_{$this->_current_view}";
691
-        if (method_exists($this, $add_screen_options)) {
692
-            $this->{$add_screen_options}();
693
-        }
694
-        // add help tab(s) and tours- set via page_config and qtips.
695
-        $this->_add_help_tour();
696
-        $this->_add_help_tabs();
697
-        $this->_add_qtips();
698
-        // add feature_pointers - global, page child class, and view specific
699
-        $this->_add_feature_pointers();
700
-        $this->_add_global_feature_pointers();
701
-        $add_feature_pointer = "_add_feature_pointer_{$this->_current_view}";
702
-        if (method_exists($this, $add_feature_pointer)) {
703
-            $this->{$add_feature_pointer}();
704
-        }
705
-        // enqueue scripts/styles - global, page class, and view specific
706
-        add_action('admin_enqueue_scripts', array($this, 'load_global_scripts_styles'), 5);
707
-        add_action('admin_enqueue_scripts', array($this, 'load_scripts_styles'), 10);
708
-        if (method_exists($this, "load_scripts_styles_{$this->_current_view}")) {
709
-            add_action('admin_enqueue_scripts', array($this, "load_scripts_styles_{$this->_current_view}"), 15);
710
-        }
711
-        add_action('admin_enqueue_scripts', array($this, 'admin_footer_scripts_eei18n_js_strings'), 100);
712
-        // admin_print_footer_scripts - global, page child class, and view specific.
713
-        // NOTE, despite the name, whenever possible, scripts should NOT be loaded using this.
714
-        // In most cases that's doing_it_wrong().  But adding hidden container elements etc.
715
-        // is a good use case. Notice the late priority we're giving these
716
-        add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts_global'), 99);
717
-        add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts'), 100);
718
-        if (method_exists($this, "admin_footer_scripts_{$this->_current_view}")) {
719
-            add_action('admin_print_footer_scripts', array($this, "admin_footer_scripts_{$this->_current_view}"), 101);
720
-        }
721
-        // admin footer scripts
722
-        add_action('admin_footer', array($this, 'admin_footer_global'), 99);
723
-        add_action('admin_footer', array($this, 'admin_footer'), 100);
724
-        if (method_exists($this, "admin_footer_{$this->_current_view}")) {
725
-            add_action('admin_footer', array($this, "admin_footer_{$this->_current_view}"), 101);
726
-        }
727
-        do_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', $this->page_slug);
728
-        // targeted hook
729
-        do_action(
730
-            "FHEE__EE_Admin_Page___load_page_dependencies__after_load__{$this->page_slug}__{$this->_req_action}"
731
-        );
732
-    }
733
-
734
-
735
-    /**
736
-     * _set_defaults
737
-     * This sets some global defaults for class properties.
738
-     */
739
-    private function _set_defaults()
740
-    {
741
-        $this->_current_screen = $this->_admin_page_title = $this->_req_action = $this->_req_nonce = null;
742
-        $this->_event = $this->_template_path = $this->_column_template_path = null;
743
-        $this->_nav_tabs = $this->_views = $this->_page_routes = array();
744
-        $this->_page_config = $this->_default_route_query_args = array();
745
-        $this->_default_nav_tab_name = 'overview';
746
-        // init template args
747
-        $this->_template_args = array(
748
-            'admin_page_header'  => '',
749
-            'admin_page_content' => '',
750
-            'post_body_content'  => '',
751
-            'before_list_table'  => '',
752
-            'after_list_table'   => '',
753
-        );
754
-    }
755
-
756
-
757
-    /**
758
-     * route_admin_request
759
-     *
760
-     * @see    _route_admin_request()
761
-     * @return exception|void error
762
-     * @throws InvalidArgumentException
763
-     * @throws InvalidInterfaceException
764
-     * @throws InvalidDataTypeException
765
-     * @throws EE_Error
766
-     * @throws ReflectionException
767
-     */
768
-    public function route_admin_request()
769
-    {
770
-        try {
771
-            $this->_route_admin_request();
772
-        } catch (EE_Error $e) {
773
-            $e->get_error();
774
-        }
775
-    }
776
-
777
-
778
-    public function set_wp_page_slug($wp_page_slug)
779
-    {
780
-        $this->_wp_page_slug = $wp_page_slug;
781
-        // if in network admin then we need to append "-network" to the page slug. Why? Because that's how WP rolls...
782
-        if (is_network_admin()) {
783
-            $this->_wp_page_slug .= '-network';
784
-        }
785
-    }
786
-
787
-
788
-    /**
789
-     * _verify_routes
790
-     * All this method does is verify the incoming request and make sure that routes exist for it.  We do this early so
791
-     * we know if we need to drop out.
792
-     *
793
-     * @return bool
794
-     * @throws EE_Error
795
-     */
796
-    protected function _verify_routes()
797
-    {
798
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
799
-        if (! $this->_current_page && ! defined('DOING_AJAX')) {
800
-            return false;
801
-        }
802
-        $this->_route = false;
803
-        // check that the page_routes array is not empty
804
-        if (empty($this->_page_routes)) {
805
-            // user error msg
806
-            $error_msg = sprintf(
807
-                esc_html__('No page routes have been set for the %s admin page.', 'event_espresso'),
808
-                $this->_admin_page_title
809
-            );
810
-            // developer error msg
811
-            $error_msg .= '||' . $error_msg
812
-                          . esc_html__(
813
-                              ' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.',
814
-                              'event_espresso'
815
-                          );
816
-            throw new EE_Error($error_msg);
817
-        }
818
-        // and that the requested page route exists
819
-        if (array_key_exists($this->_req_action, $this->_page_routes)) {
820
-            $this->_route = $this->_page_routes[ $this->_req_action ];
821
-            $this->_route_config = isset($this->_page_config[ $this->_req_action ])
822
-                ? $this->_page_config[ $this->_req_action ] : array();
823
-        } else {
824
-            // user error msg
825
-            $error_msg = sprintf(
826
-                esc_html__(
827
-                    'The requested page route does not exist for the %s admin page.',
828
-                    'event_espresso'
829
-                ),
830
-                $this->_admin_page_title
831
-            );
832
-            // developer error msg
833
-            $error_msg .= '||' . $error_msg
834
-                          . sprintf(
835
-                              esc_html__(
836
-                                  ' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.',
837
-                                  'event_espresso'
838
-                              ),
839
-                              $this->_req_action
840
-                          );
841
-            throw new EE_Error($error_msg);
842
-        }
843
-        // and that a default route exists
844
-        if (! array_key_exists('default', $this->_page_routes)) {
845
-            // user error msg
846
-            $error_msg = sprintf(
847
-                esc_html__(
848
-                    'A default page route has not been set for the % admin page.',
849
-                    'event_espresso'
850
-                ),
851
-                $this->_admin_page_title
852
-            );
853
-            // developer error msg
854
-            $error_msg .= '||' . $error_msg
855
-                          . esc_html__(
856
-                              ' Create a key in the "_page_routes" array named "default" and set its value to your default page method.',
857
-                              'event_espresso'
858
-                          );
859
-            throw new EE_Error($error_msg);
860
-        }
861
-        // first lets' catch if the UI request has EVER been set.
862
-        if ($this->_is_UI_request === null) {
863
-            // lets set if this is a UI request or not.
864
-            $this->_is_UI_request = ! isset($this->_req_data['noheader']) || $this->_req_data['noheader'] !== true;
865
-            // wait a minute... we might have a noheader in the route array
866
-            $this->_is_UI_request = is_array($this->_route)
867
-                                    && isset($this->_route['noheader'])
868
-                                    && $this->_route['noheader'] ? false : $this->_is_UI_request;
869
-        }
870
-        $this->_set_current_labels();
871
-        return true;
872
-    }
873
-
874
-
875
-    /**
876
-     * this method simply verifies a given route and makes sure its an actual route available for the loaded page
877
-     *
878
-     * @param  string $route the route name we're verifying
879
-     * @return mixed (bool|Exception)      we'll throw an exception if this isn't a valid route.
880
-     * @throws EE_Error
881
-     */
882
-    protected function _verify_route($route)
883
-    {
884
-        if (array_key_exists($this->_req_action, $this->_page_routes)) {
885
-            return true;
886
-        }
887
-        // user error msg
888
-        $error_msg = sprintf(
889
-            esc_html__('The given page route does not exist for the %s admin page.', 'event_espresso'),
890
-            $this->_admin_page_title
891
-        );
892
-        // developer error msg
893
-        $error_msg .= '||' . $error_msg
894
-                      . sprintf(
895
-                          esc_html__(
896
-                              ' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property',
897
-                              'event_espresso'
898
-                          ),
899
-                          $route
900
-                      );
901
-        throw new EE_Error($error_msg);
902
-    }
903
-
904
-
905
-    /**
906
-     * perform nonce verification
907
-     * This method has be encapsulated here so that any ajax requests that bypass normal routes can verify their nonces
908
-     * using this method (and save retyping!)
909
-     *
910
-     * @param  string $nonce     The nonce sent
911
-     * @param  string $nonce_ref The nonce reference string (name0)
912
-     * @return void
913
-     * @throws EE_Error
914
-     */
915
-    protected function _verify_nonce($nonce, $nonce_ref)
916
-    {
917
-        // verify nonce against expected value
918
-        if (! wp_verify_nonce($nonce, $nonce_ref)) {
919
-            // these are not the droids you are looking for !!!
920
-            $msg = sprintf(
921
-                esc_html__('%sNonce Fail.%s', 'event_espresso'),
922
-                '<a href="http://www.youtube.com/watch?v=56_S0WeTkzs">',
923
-                '</a>'
924
-            );
925
-            if (WP_DEBUG) {
926
-                $msg .= "\n  "
927
-                        . sprintf(
928
-                            esc_html__(
929
-                                'In order to dynamically generate nonces for your actions, use the %s::add_query_args_and_nonce() method. May the Nonce be with you!',
930
-                                'event_espresso'
931
-                            ),
932
-                            __CLASS__
933
-                        );
934
-            }
935
-            if (! defined('DOING_AJAX')) {
936
-                wp_die($msg);
937
-            } else {
938
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
939
-                $this->_return_json();
940
-            }
941
-        }
942
-    }
943
-
944
-
945
-    /**
946
-     * _route_admin_request()
947
-     * Meat and potatoes of the class.  Basically, this dude checks out what's being requested and sees if theres are
948
-     * some doodads to work the magic and handle the flingjangy. Translation:  Checks if the requested action is listed
949
-     * in the page routes and then will try to load the corresponding method.
950
-     *
951
-     * @return void
952
-     * @throws EE_Error
953
-     * @throws InvalidArgumentException
954
-     * @throws InvalidDataTypeException
955
-     * @throws InvalidInterfaceException
956
-     * @throws ReflectionException
957
-     */
958
-    protected function _route_admin_request()
959
-    {
960
-        if (! $this->_is_UI_request) {
961
-            $this->_verify_routes();
962
-        }
963
-        $nonce_check = isset($this->_route_config['require_nonce'])
964
-            ? $this->_route_config['require_nonce']
965
-            : true;
966
-        if ($this->_req_action !== 'default' && $nonce_check) {
967
-            // set nonce from post data
968
-            $nonce = isset($this->_req_data[ $this->_req_nonce ])
969
-                ? sanitize_text_field($this->_req_data[ $this->_req_nonce ])
970
-                : '';
971
-            $this->_verify_nonce($nonce, $this->_req_nonce);
972
-        }
973
-        // set the nav_tabs array but ONLY if this is  UI_request
974
-        if ($this->_is_UI_request) {
975
-            $this->_set_nav_tabs();
976
-        }
977
-        // grab callback function
978
-        $func = is_array($this->_route) ? $this->_route['func'] : $this->_route;
979
-        // check if callback has args
980
-        $args = is_array($this->_route) && isset($this->_route['args']) ? $this->_route['args'] : array();
981
-        $error_msg = '';
982
-        // action right before calling route
983
-        // (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request')
984
-        if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
985
-            do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this);
986
-        }
987
-        // right before calling the route, let's remove _wp_http_referer from the
988
-        // $_SERVER[REQUEST_URI] global (its now in _req_data for route processing).
989
-        $_SERVER['REQUEST_URI'] = remove_query_arg(
990
-            '_wp_http_referer',
991
-            wp_unslash($_SERVER['REQUEST_URI'])
992
-        );
993
-        if (! empty($func)) {
994
-            if (is_array($func)) {
995
-                list($class, $method) = $func;
996
-            } elseif (strpos($func, '::') !== false) {
997
-                list($class, $method) = explode('::', $func);
998
-            } else {
999
-                $class = $this;
1000
-                $method = $func;
1001
-            }
1002
-            if (! (is_object($class) && $class === $this)) {
1003
-                // send along this admin page object for access by addons.
1004
-                $args['admin_page_object'] = $this;
1005
-            }
1006
-            if (// is it a method on a class that doesn't work?
1007
-                (
1008
-                    (
1009
-                        method_exists($class, $method)
1010
-                        && call_user_func_array(array($class, $method), $args) === false
1011
-                    )
1012
-                    && (
1013
-                        // is it a standalone function that doesn't work?
1014
-                        function_exists($method)
1015
-                        && call_user_func_array(
1016
-                            $func,
1017
-                            array_merge(array('admin_page_object' => $this), $args)
1018
-                        ) === false
1019
-                    )
1020
-                )
1021
-                || (
1022
-                    // is it neither a class method NOR a standalone function?
1023
-                    ! method_exists($class, $method)
1024
-                    && ! function_exists($method)
1025
-                )
1026
-            ) {
1027
-                // user error msg
1028
-                $error_msg = esc_html__(
1029
-                    'An error occurred. The  requested page route could not be found.',
1030
-                    'event_espresso'
1031
-                );
1032
-                // developer error msg
1033
-                $error_msg .= '||';
1034
-                $error_msg .= sprintf(
1035
-                    esc_html__(
1036
-                        'Page route "%s" could not be called. Check that the spelling for method names and actions in the "_page_routes" array are all correct.',
1037
-                        'event_espresso'
1038
-                    ),
1039
-                    $method
1040
-                );
1041
-            }
1042
-            if (! empty($error_msg)) {
1043
-                throw new EE_Error($error_msg);
1044
-            }
1045
-        }
1046
-        // if we've routed and this route has a no headers route AND a sent_headers_route,
1047
-        // then we need to reset the routing properties to the new route.
1048
-        // now if UI request is FALSE and noheader is true AND we have a headers_sent_route in the route array then let's set UI_request to true because the no header route has a second func after headers have been sent.
1049
-        if ($this->_is_UI_request === false
1050
-            && is_array($this->_route)
1051
-            && ! empty($this->_route['headers_sent_route'])
1052
-        ) {
1053
-            $this->_reset_routing_properties($this->_route['headers_sent_route']);
1054
-        }
1055
-    }
1056
-
1057
-
1058
-    /**
1059
-     * This method just allows the resetting of page properties in the case where a no headers
1060
-     * route redirects to a headers route in its route config.
1061
-     *
1062
-     * @since   4.3.0
1063
-     * @param  string $new_route New (non header) route to redirect to.
1064
-     * @return   void
1065
-     * @throws ReflectionException
1066
-     * @throws InvalidArgumentException
1067
-     * @throws InvalidInterfaceException
1068
-     * @throws InvalidDataTypeException
1069
-     * @throws EE_Error
1070
-     */
1071
-    protected function _reset_routing_properties($new_route)
1072
-    {
1073
-        $this->_is_UI_request = true;
1074
-        // now we set the current route to whatever the headers_sent_route is set at
1075
-        $this->_req_data['action'] = $new_route;
1076
-        // rerun page setup
1077
-        $this->_page_setup();
1078
-    }
1079
-
1080
-
1081
-    /**
1082
-     * _add_query_arg
1083
-     * adds nonce to array of arguments then calls WP add_query_arg function
1084
-     *(internally just uses EEH_URL's function with the same name)
1085
-     *
1086
-     * @param array  $args
1087
-     * @param string $url
1088
-     * @param bool   $sticky                  if true, then the existing Request params will be appended to the
1089
-     *                                        generated url in an associative array indexed by the key 'wp_referer';
1090
-     *                                        Example usage: If the current page is:
1091
-     *                                        http://mydomain.com/wp-admin/admin.php?page=espresso_registrations
1092
-     *                                        &action=default&event_id=20&month_range=March%202015
1093
-     *                                        &_wpnonce=5467821
1094
-     *                                        and you call:
1095
-     *                                        EE_Admin_Page::add_query_args_and_nonce(
1096
-     *                                        array(
1097
-     *                                        'action' => 'resend_something',
1098
-     *                                        'page=>espresso_registrations'
1099
-     *                                        ),
1100
-     *                                        $some_url,
1101
-     *                                        true
1102
-     *                                        );
1103
-     *                                        It will produce a url in this structure:
1104
-     *                                        http://{$some_url}/?page=espresso_registrations&action=resend_something
1105
-     *                                        &wp_referer[action]=default&wp_referer[event_id]=20&wpreferer[
1106
-     *                                        month_range]=March%202015
1107
-     * @param   bool $exclude_nonce           If true, the the nonce will be excluded from the generated nonce.
1108
-     * @return string
1109
-     */
1110
-    public static function add_query_args_and_nonce(
1111
-        $args = array(),
1112
-        $url = false,
1113
-        $sticky = false,
1114
-        $exclude_nonce = false
1115
-    ) {
1116
-        // if there is a _wp_http_referer include the values from the request but only if sticky = true
1117
-        if ($sticky) {
1118
-            $request = $_REQUEST;
1119
-            unset($request['_wp_http_referer']);
1120
-            unset($request['wp_referer']);
1121
-            foreach ($request as $key => $value) {
1122
-                // do not add nonces
1123
-                if (strpos($key, 'nonce') !== false) {
1124
-                    continue;
1125
-                }
1126
-                $args[ 'wp_referer[' . $key . ']' ] = $value;
1127
-            }
1128
-        }
1129
-        return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce);
1130
-    }
1131
-
1132
-
1133
-    /**
1134
-     * This returns a generated link that will load the related help tab.
1135
-     *
1136
-     * @param  string $help_tab_id the id for the connected help tab
1137
-     * @param  string $icon_style  (optional) include css class for the style you want to use for the help icon.
1138
-     * @param  string $help_text   (optional) send help text you want to use for the link if default not to be used
1139
-     * @uses EEH_Template::get_help_tab_link()
1140
-     * @return string              generated link
1141
-     */
1142
-    protected function _get_help_tab_link($help_tab_id, $icon_style = '', $help_text = '')
1143
-    {
1144
-        return EEH_Template::get_help_tab_link(
1145
-            $help_tab_id,
1146
-            $this->page_slug,
1147
-            $this->_req_action,
1148
-            $icon_style,
1149
-            $help_text
1150
-        );
1151
-    }
1152
-
1153
-
1154
-    /**
1155
-     * _add_help_tabs
1156
-     * Note child classes define their help tabs within the page_config array.
1157
-     *
1158
-     * @link   http://codex.wordpress.org/Function_Reference/add_help_tab
1159
-     * @return void
1160
-     * @throws DomainException
1161
-     * @throws EE_Error
1162
-     */
1163
-    protected function _add_help_tabs()
1164
-    {
1165
-        $tour_buttons = '';
1166
-        if (isset($this->_page_config[ $this->_req_action ])) {
1167
-            $config = $this->_page_config[ $this->_req_action ];
1168
-            // is there a help tour for the current route?  if there is let's setup the tour buttons
1169
-            if (isset($this->_help_tour[ $this->_req_action ])) {
1170
-                $tb = array();
1171
-                $tour_buttons = '<div class="ee-abs-container"><div class="ee-help-tour-restart-buttons">';
1172
-                foreach ($this->_help_tour['tours'] as $tour) {
1173
-                    // if this is the end tour then we don't need to setup a button
1174
-                    if ($tour instanceof EE_Help_Tour_final_stop || ! $tour instanceof EE_Help_Tour) {
1175
-                        continue;
1176
-                    }
1177
-                    $tb[] = '<button id="trigger-tour-'
1178
-                            . $tour->get_slug()
1179
-                            . '" class="button-primary trigger-ee-help-tour">'
1180
-                            . $tour->get_label()
1181
-                            . '</button>';
1182
-                }
1183
-                $tour_buttons .= implode('<br />', $tb);
1184
-                $tour_buttons .= '</div></div>';
1185
-            }
1186
-            // let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well.
1187
-            if (is_array($config) && isset($config['help_sidebar'])) {
1188
-                // check that the callback given is valid
1189
-                if (! method_exists($this, $config['help_sidebar'])) {
1190
-                    throw new EE_Error(
1191
-                        sprintf(
1192
-                            esc_html__(
1193
-                                'The _page_config array has a callback set for the "help_sidebar" option.  However the callback given (%s) is not a valid callback.  Doublecheck the spelling and make sure this method exists for the class %s',
1194
-                                'event_espresso'
1195
-                            ),
1196
-                            $config['help_sidebar'],
1197
-                            get_class($this)
1198
-                        )
1199
-                    );
1200
-                }
1201
-                $content = apply_filters(
1202
-                    'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar',
1203
-                    $this->{$config['help_sidebar']}()
1204
-                );
1205
-                $content .= $tour_buttons; // add help tour buttons.
1206
-                // do we have any help tours setup?  Cause if we do we want to add the buttons
1207
-                $this->_current_screen->set_help_sidebar($content);
1208
-            }
1209
-            // if we DON'T have config help sidebar and there ARE tour buttons then we'll just add the tour buttons to the sidebar.
1210
-            if (! isset($config['help_sidebar']) && ! empty($tour_buttons)) {
1211
-                $this->_current_screen->set_help_sidebar($tour_buttons);
1212
-            }
1213
-            // handle if no help_tabs are set so the sidebar will still show for the help tour buttons
1214
-            if (! isset($config['help_tabs']) && ! empty($tour_buttons)) {
1215
-                $_ht['id'] = $this->page_slug;
1216
-                $_ht['title'] = esc_html__('Help Tours', 'event_espresso');
1217
-                $_ht['content'] = '<p>'
1218
-                                  . esc_html__(
1219
-                                      'The buttons to the right allow you to start/restart any help tours available for this page',
1220
-                                      'event_espresso'
1221
-                                  ) . '</p>';
1222
-                $this->_current_screen->add_help_tab($_ht);
1223
-            }
1224
-            if (! isset($config['help_tabs'])) {
1225
-                return;
1226
-            } //no help tabs for this route
1227
-            foreach ((array) $config['help_tabs'] as $tab_id => $cfg) {
1228
-                // we're here so there ARE help tabs!
1229
-                // make sure we've got what we need
1230
-                if (! isset($cfg['title'])) {
1231
-                    throw new EE_Error(
1232
-                        esc_html__(
1233
-                            'The _page_config array is not set up properly for help tabs.  It is missing a title',
1234
-                            'event_espresso'
1235
-                        )
1236
-                    );
1237
-                }
1238
-                if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1239
-                    throw new EE_Error(
1240
-                        esc_html__(
1241
-                            'The _page_config array is not setup properly for help tabs. It is missing a either a filename reference, or a callback reference or a content reference so there is no way to know the content for the help tab',
1242
-                            'event_espresso'
1243
-                        )
1244
-                    );
1245
-                }
1246
-                // first priority goes to content.
1247
-                if (! empty($cfg['content'])) {
1248
-                    $content = ! empty($cfg['content']) ? $cfg['content'] : null;
1249
-                    // second priority goes to filename
1250
-                } elseif (! empty($cfg['filename'])) {
1251
-                    $file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php';
1252
-                    // it's possible that the file is located on decaf route (and above sets up for caf route, if this is the case then lets check decaf route too)
1253
-                    $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1254
-                                                             . basename($this->_get_dir())
1255
-                                                             . '/help_tabs/'
1256
-                                                             . $cfg['filename']
1257
-                                                             . '.help_tab.php' : $file_path;
1258
-                    // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1259
-                    if (! isset($cfg['callback']) && ! is_readable($file_path)) {
1260
-                        EE_Error::add_error(
1261
-                            sprintf(
1262
-                                esc_html__(
1263
-                                    'The filename given for the help tab %s is not a valid file and there is no other configuration for the tab content.  Please check that the string you set for the help tab on this route (%s) is the correct spelling.  The file should be in %s',
1264
-                                    'event_espresso'
1265
-                                ),
1266
-                                $tab_id,
1267
-                                key($config),
1268
-                                $file_path
1269
-                            ),
1270
-                            __FILE__,
1271
-                            __FUNCTION__,
1272
-                            __LINE__
1273
-                        );
1274
-                        return;
1275
-                    }
1276
-                    $template_args['admin_page_obj'] = $this;
1277
-                    $content = EEH_Template::display_template(
1278
-                        $file_path,
1279
-                        $template_args,
1280
-                        true
1281
-                    );
1282
-                } else {
1283
-                    $content = '';
1284
-                }
1285
-                // check if callback is valid
1286
-                if (empty($content) && (
1287
-                        ! isset($cfg['callback']) || ! method_exists($this, $cfg['callback'])
1288
-                    )
1289
-                ) {
1290
-                    EE_Error::add_error(
1291
-                        sprintf(
1292
-                            esc_html__(
1293
-                                'The callback given for a %s help tab on this page does not content OR a corresponding method for generating the content.  Check the spelling or make sure the method is present.',
1294
-                                'event_espresso'
1295
-                            ),
1296
-                            $cfg['title']
1297
-                        ),
1298
-                        __FILE__,
1299
-                        __FUNCTION__,
1300
-                        __LINE__
1301
-                    );
1302
-                    return;
1303
-                }
1304
-                // setup config array for help tab method
1305
-                $id = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id;
1306
-                $_ht = array(
1307
-                    'id'       => $id,
1308
-                    'title'    => $cfg['title'],
1309
-                    'callback' => isset($cfg['callback']) && empty($content) ? array($this, $cfg['callback']) : null,
1310
-                    'content'  => $content,
1311
-                );
1312
-                $this->_current_screen->add_help_tab($_ht);
1313
-            }
1314
-        }
1315
-    }
1316
-
1317
-
1318
-    /**
1319
-     * This basically checks loaded $_page_config property to see if there are any help_tours defined.  "help_tours" is
1320
-     * an array with properties for setting up usage of the joyride plugin
1321
-     *
1322
-     * @link   http://zurb.com/playground/jquery-joyride-feature-tour-plugin
1323
-     * @see    instructions regarding the format and construction of the "help_tour" array element is found in the
1324
-     *         _set_page_config() comments
1325
-     * @return void
1326
-     * @throws EE_Error
1327
-     * @throws InvalidArgumentException
1328
-     * @throws InvalidDataTypeException
1329
-     * @throws InvalidInterfaceException
1330
-     */
1331
-    protected function _add_help_tour()
1332
-    {
1333
-        $tours = array();
1334
-        $this->_help_tour = array();
1335
-        // exit early if help tours are turned off globally
1336
-        if ((defined('EE_DISABLE_HELP_TOURS') && EE_DISABLE_HELP_TOURS)
1337
-            || ! EE_Registry::instance()->CFG->admin->help_tour_activation
1338
-        ) {
1339
-            return;
1340
-        }
1341
-        // loop through _page_config to find any help_tour defined
1342
-        foreach ($this->_page_config as $route => $config) {
1343
-            // we're only going to set things up for this route
1344
-            if ($route !== $this->_req_action) {
1345
-                continue;
1346
-            }
1347
-            if (isset($config['help_tour'])) {
1348
-                foreach ($config['help_tour'] as $tour) {
1349
-                    $file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php';
1350
-                    // let's see if we can get that file...
1351
-                    // if not its possible this is a decaf route not set in caffeinated
1352
-                    // so lets try and get the caffeinated equivalent
1353
-                    $file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1354
-                                                             . basename($this->_get_dir())
1355
-                                                             . '/help_tours/'
1356
-                                                             . $tour
1357
-                                                             . '.class.php' : $file_path;
1358
-                    // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1359
-                    if (! is_readable($file_path)) {
1360
-                        EE_Error::add_error(
1361
-                            sprintf(
1362
-                                esc_html__(
1363
-                                    'The file path given for the help tour (%s) is not a valid path.  Please check that the string you set for the help tour on this route (%s) is the correct spelling',
1364
-                                    'event_espresso'
1365
-                                ),
1366
-                                $file_path,
1367
-                                $tour
1368
-                            ),
1369
-                            __FILE__,
1370
-                            __FUNCTION__,
1371
-                            __LINE__
1372
-                        );
1373
-                        return;
1374
-                    }
1375
-                    require_once $file_path;
1376
-                    if (! class_exists($tour)) {
1377
-                        $error_msg[] = sprintf(
1378
-                            esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'),
1379
-                            $tour
1380
-                        );
1381
-                        $error_msg[] = $error_msg[0] . "\r\n"
1382
-                                       . sprintf(
1383
-                                           esc_html__(
1384
-                                               'There is no class in place for the %s help tour.%s Make sure you have <strong>%s</strong> defined in the "help_tour" array for the %s route of the % admin page.',
1385
-                                               'event_espresso'
1386
-                                           ),
1387
-                                           $tour,
1388
-                                           '<br />',
1389
-                                           $tour,
1390
-                                           $this->_req_action,
1391
-                                           get_class($this)
1392
-                                       );
1393
-                        throw new EE_Error(implode('||', $error_msg));
1394
-                    }
1395
-                    $tour_obj = new $tour($this->_is_caf);
1396
-                    $tours[] = $tour_obj;
1397
-                    $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($tour_obj);
1398
-                }
1399
-                // let's inject the end tour stop element common to all pages... this will only get seen once per machine.
1400
-                $end_stop_tour = new EE_Help_Tour_final_stop($this->_is_caf);
1401
-                $tours[] = $end_stop_tour;
1402
-                $this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($end_stop_tour);
1403
-            }
1404
-        }
1405
-
1406
-        if (! empty($tours)) {
1407
-            $this->_help_tour['tours'] = $tours;
1408
-        }
1409
-        // that's it!  Now that the $_help_tours property is set (or not)
1410
-        // the scripts and html should be taken care of automatically.
1411
-
1412
-        /**
1413
-         * Allow extending the help tours variable.
1414
-         *
1415
-         * @param Array $_help_tour The array containing all help tour information to be displayed.
1416
-         */
1417
-        $this->_help_tour = apply_filters('FHEE__EE_Admin_Page___add_help_tour___help_tour', $this->_help_tour);
1418
-    }
1419
-
1420
-
1421
-    /**
1422
-     * This simply sets up any qtips that have been defined in the page config
1423
-     *
1424
-     * @return void
1425
-     */
1426
-    protected function _add_qtips()
1427
-    {
1428
-        if (isset($this->_route_config['qtips'])) {
1429
-            $qtips = (array) $this->_route_config['qtips'];
1430
-            // load qtip loader
1431
-            $path = array(
1432
-                $this->_get_dir() . '/qtips/',
1433
-                EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/',
1434
-            );
1435
-            EEH_Qtip_Loader::instance()->register($qtips, $path);
1436
-        }
1437
-    }
1438
-
1439
-
1440
-    /**
1441
-     * _set_nav_tabs
1442
-     * This sets up the nav tabs from the page_routes array.  This method can be overwritten by child classes if you
1443
-     * wish to add additional tabs or modify accordingly.
1444
-     *
1445
-     * @return void
1446
-     * @throws InvalidArgumentException
1447
-     * @throws InvalidInterfaceException
1448
-     * @throws InvalidDataTypeException
1449
-     */
1450
-    protected function _set_nav_tabs()
1451
-    {
1452
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1453
-        $i = 0;
1454
-        foreach ($this->_page_config as $slug => $config) {
1455
-            if (! is_array($config)
1456
-                || (
1457
-                    is_array($config)
1458
-                    && (
1459
-                        (isset($config['nav']) && ! $config['nav'])
1460
-                        || ! isset($config['nav'])
1461
-                    )
1462
-                )
1463
-            ) {
1464
-                continue;
1465
-            }
1466
-            // no nav tab for this config
1467
-            // check for persistent flag
1468
-            if ($slug !== $this->_req_action && isset($config['nav']['persistent']) && ! $config['nav']['persistent']) {
1469
-                // nav tab is only to appear when route requested.
1470
-                continue;
1471
-            }
1472
-            if (! $this->check_user_access($slug, true)) {
1473
-                // no nav tab because current user does not have access.
1474
-                continue;
1475
-            }
1476
-            $css_class = isset($config['css_class']) ? $config['css_class'] . ' ' : '';
1477
-            $this->_nav_tabs[ $slug ] = array(
1478
-                'url'       => isset($config['nav']['url'])
1479
-                    ? $config['nav']['url']
1480
-                    : self::add_query_args_and_nonce(
1481
-                        array('action' => $slug),
1482
-                        $this->_admin_base_url
1483
-                    ),
1484
-                'link_text' => isset($config['nav']['label'])
1485
-                    ? $config['nav']['label']
1486
-                    : ucwords(
1487
-                        str_replace('_', ' ', $slug)
1488
-                    ),
1489
-                'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class,
1490
-                'order'     => isset($config['nav']['order']) ? $config['nav']['order'] : $i,
1491
-            );
1492
-            $i++;
1493
-        }
1494
-        // if $this->_nav_tabs is empty then lets set the default
1495
-        if (empty($this->_nav_tabs)) {
1496
-            $this->_nav_tabs[ $this->_default_nav_tab_name ] = array(
1497
-                'url'       => $this->_admin_base_url,
1498
-                'link_text' => ucwords(str_replace('_', ' ', $this->_default_nav_tab_name)),
1499
-                'css_class' => 'nav-tab-active',
1500
-                'order'     => 10,
1501
-            );
1502
-        }
1503
-        // now let's sort the tabs according to order
1504
-        usort($this->_nav_tabs, array($this, '_sort_nav_tabs'));
1505
-    }
1506
-
1507
-
1508
-    /**
1509
-     * _set_current_labels
1510
-     * This method modifies the _labels property with any optional specific labels indicated in the _page_routes
1511
-     * property array
1512
-     *
1513
-     * @return void
1514
-     */
1515
-    private function _set_current_labels()
1516
-    {
1517
-        if (is_array($this->_route_config) && isset($this->_route_config['labels'])) {
1518
-            foreach ($this->_route_config['labels'] as $label => $text) {
1519
-                if (is_array($text)) {
1520
-                    foreach ($text as $sublabel => $subtext) {
1521
-                        $this->_labels[ $label ][ $sublabel ] = $subtext;
1522
-                    }
1523
-                } else {
1524
-                    $this->_labels[ $label ] = $text;
1525
-                }
1526
-            }
1527
-        }
1528
-    }
1529
-
1530
-
1531
-    /**
1532
-     *        verifies user access for this admin page
1533
-     *
1534
-     * @param string $route_to_check if present then the capability for the route matching this string is checked.
1535
-     * @param bool   $verify_only    Default is FALSE which means if user check fails then wp_die().  Otherwise just
1536
-     *                               return false if verify fail.
1537
-     * @return bool
1538
-     * @throws InvalidArgumentException
1539
-     * @throws InvalidDataTypeException
1540
-     * @throws InvalidInterfaceException
1541
-     */
1542
-    public function check_user_access($route_to_check = '', $verify_only = false)
1543
-    {
1544
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1545
-        $route_to_check = empty($route_to_check) ? $this->_req_action : $route_to_check;
1546
-        $capability = ! empty($route_to_check) && isset($this->_page_routes[ $route_to_check ])
1547
-                      && is_array(
1548
-                          $this->_page_routes[ $route_to_check ]
1549
-                      )
1550
-                      && ! empty($this->_page_routes[ $route_to_check ]['capability'])
1551
-            ? $this->_page_routes[ $route_to_check ]['capability'] : null;
1552
-        if (empty($capability) && empty($route_to_check)) {
1553
-            $capability = is_array($this->_route) && empty($this->_route['capability']) ? 'manage_options'
1554
-                : $this->_route['capability'];
1555
-        } else {
1556
-            $capability = empty($capability) ? 'manage_options' : $capability;
1557
-        }
1558
-        $id = is_array($this->_route) && ! empty($this->_route['obj_id']) ? $this->_route['obj_id'] : 0;
1559
-        if (! defined('DOING_AJAX')
1560
-            && (
1561
-                ! function_exists('is_admin')
1562
-                || ! EE_Registry::instance()->CAP->current_user_can(
1563
-                    $capability,
1564
-                    $this->page_slug
1565
-                    . '_'
1566
-                    . $route_to_check,
1567
-                    $id
1568
-                )
1569
-            )
1570
-        ) {
1571
-            if ($verify_only) {
1572
-                return false;
1573
-            }
1574
-            if (is_user_logged_in()) {
1575
-                wp_die(__('You do not have access to this route.', 'event_espresso'));
1576
-            } else {
1577
-                return false;
1578
-            }
1579
-        }
1580
-        return true;
1581
-    }
1582
-
1583
-
1584
-    /**
1585
-     * admin_init_global
1586
-     * This runs all the code that we want executed within the WP admin_init hook.
1587
-     * This method executes for ALL EE Admin pages.
1588
-     *
1589
-     * @return void
1590
-     */
1591
-    public function admin_init_global()
1592
-    {
1593
-    }
1594
-
1595
-
1596
-    /**
1597
-     * wp_loaded_global
1598
-     * This runs all the code that we want executed within the WP wp_loaded hook.  This method is optional for an
1599
-     * EE_Admin page and will execute on every EE Admin Page load
1600
-     *
1601
-     * @return void
1602
-     */
1603
-    public function wp_loaded()
1604
-    {
1605
-    }
1606
-
1607
-
1608
-    /**
1609
-     * admin_notices
1610
-     * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply on
1611
-     * ALL EE_Admin pages.
1612
-     *
1613
-     * @return void
1614
-     */
1615
-    public function admin_notices_global()
1616
-    {
1617
-        $this->_display_no_javascript_warning();
1618
-        $this->_display_espresso_notices();
1619
-    }
1620
-
1621
-
1622
-    public function network_admin_notices_global()
1623
-    {
1624
-        $this->_display_no_javascript_warning();
1625
-        $this->_display_espresso_notices();
1626
-    }
1627
-
1628
-
1629
-    /**
1630
-     * admin_footer_scripts_global
1631
-     * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
1632
-     * will apply on ALL EE_Admin pages.
1633
-     *
1634
-     * @return void
1635
-     */
1636
-    public function admin_footer_scripts_global()
1637
-    {
1638
-        $this->_add_admin_page_ajax_loading_img();
1639
-        $this->_add_admin_page_overlay();
1640
-        // if metaboxes are present we need to add the nonce field
1641
-        if (isset($this->_route_config['metaboxes'])
1642
-            || isset($this->_route_config['list_table'])
1643
-            || (isset($this->_route_config['has_metaboxes']) && $this->_route_config['has_metaboxes'])
1644
-        ) {
1645
-            wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false);
1646
-            wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false);
1647
-        }
1648
-    }
1649
-
1650
-
1651
-    /**
1652
-     * admin_footer_global
1653
-     * Anything triggered by the wp 'admin_footer' wp hook should be put in here. This particular method will apply on
1654
-     * ALL EE_Admin Pages.
1655
-     *
1656
-     * @return void
1657
-     * @throws EE_Error
1658
-     */
1659
-    public function admin_footer_global()
1660
-    {
1661
-        // dialog container for dialog helper
1662
-        $d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n";
1663
-        $d_cont .= '<div class="ee-notices"></div>';
1664
-        $d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>';
1665
-        $d_cont .= '</div>';
1666
-        echo $d_cont;
1667
-        // help tour stuff?
1668
-        if (isset($this->_help_tour[ $this->_req_action ])) {
1669
-            echo implode('<br />', $this->_help_tour[ $this->_req_action ]);
1670
-        }
1671
-        // current set timezone for timezone js
1672
-        echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>';
1673
-    }
1674
-
1675
-
1676
-    /**
1677
-     * This function sees if there is a method for help popup content existing for the given route.  If there is then
1678
-     * we'll use the retrieved array to output the content using the template. For child classes: If you want to have
1679
-     * help popups then in your templates or your content you set "triggers" for the content using the
1680
-     * "_set_help_trigger('help_trigger_id')" where "help_trigger_id" is what you will use later in your custom method
1681
-     * for the help popup content on that page. Then in your Child_Admin_Page class you need to define a help popup
1682
-     * method for the content in the format "_help_popup_content_{route_name}()"  So if you are setting help content
1683
-     * for the
1684
-     * 'edit_event' route you should have a method named "_help_popup_content_edit_route". In your defined
1685
-     * "help_popup_content_..." method.  You must prepare and return an array in the following format array(
1686
-     *    'help_trigger_id' => array(
1687
-     *        'title' => esc_html__('localized title for popup', 'event_espresso'),
1688
-     *        'content' => esc_html__('localized content for popup', 'event_espresso')
1689
-     *    )
1690
-     * );
1691
-     * Then the EE_Admin_Parent will take care of making sure that is setup properly on the correct route.
1692
-     *
1693
-     * @param array $help_array
1694
-     * @param bool  $display
1695
-     * @return string content
1696
-     * @throws DomainException
1697
-     * @throws EE_Error
1698
-     */
1699
-    protected function _set_help_popup_content($help_array = array(), $display = false)
1700
-    {
1701
-        $content = '';
1702
-        $help_array = empty($help_array) ? $this->_get_help_content() : $help_array;
1703
-        // loop through the array and setup content
1704
-        foreach ($help_array as $trigger => $help) {
1705
-            // make sure the array is setup properly
1706
-            if (! isset($help['title']) || ! isset($help['content'])) {
1707
-                throw new EE_Error(
1708
-                    esc_html__(
1709
-                        'Does not look like the popup content array has been setup correctly.  Might want to double check that.  Read the comments for the _get_help_popup_content method found in "EE_Admin_Page" class',
1710
-                        'event_espresso'
1711
-                    )
1712
-                );
1713
-            }
1714
-            // we're good so let'd setup the template vars and then assign parsed template content to our content.
1715
-            $template_args = array(
1716
-                'help_popup_id'      => $trigger,
1717
-                'help_popup_title'   => $help['title'],
1718
-                'help_popup_content' => $help['content'],
1719
-            );
1720
-            $content .= EEH_Template::display_template(
1721
-                EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php',
1722
-                $template_args,
1723
-                true
1724
-            );
1725
-        }
1726
-        if ($display) {
1727
-            echo $content;
1728
-            return '';
1729
-        }
1730
-        return $content;
1731
-    }
1732
-
1733
-
1734
-    /**
1735
-     * All this does is retrieve the help content array if set by the EE_Admin_Page child
1736
-     *
1737
-     * @return array properly formatted array for help popup content
1738
-     * @throws EE_Error
1739
-     */
1740
-    private function _get_help_content()
1741
-    {
1742
-        // what is the method we're looking for?
1743
-        $method_name = '_help_popup_content_' . $this->_req_action;
1744
-        // if method doesn't exist let's get out.
1745
-        if (! method_exists($this, $method_name)) {
1746
-            return array();
1747
-        }
1748
-        // k we're good to go let's retrieve the help array
1749
-        $help_array = call_user_func(array($this, $method_name));
1750
-        // make sure we've got an array!
1751
-        if (! is_array($help_array)) {
1752
-            throw new EE_Error(
1753
-                esc_html__(
1754
-                    'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.',
1755
-                    'event_espresso'
1756
-                )
1757
-            );
1758
-        }
1759
-        return $help_array;
1760
-    }
1761
-
1762
-
1763
-    /**
1764
-     * EE Admin Pages can use this to set a properly formatted trigger for a help popup.
1765
-     * By default the trigger html is printed.  Otherwise it can be returned if the $display flag is set "false"
1766
-     * See comments made on the _set_help_content method for understanding other parts to the help popup tool.
1767
-     *
1768
-     * @param string  $trigger_id reference for retrieving the trigger content for the popup
1769
-     * @param boolean $display    if false then we return the trigger string
1770
-     * @param array   $dimensions an array of dimensions for the box (array(h,w))
1771
-     * @return string
1772
-     * @throws DomainException
1773
-     * @throws EE_Error
1774
-     */
1775
-    protected function _set_help_trigger($trigger_id, $display = true, $dimensions = array('400', '640'))
1776
-    {
1777
-        if (defined('DOING_AJAX')) {
1778
-            return '';
1779
-        }
1780
-        // let's check and see if there is any content set for this popup.  If there isn't then we'll include a default title and content so that developers know something needs to be corrected
1781
-        $help_array = $this->_get_help_content();
1782
-        $help_content = '';
1783
-        if (empty($help_array) || ! isset($help_array[ $trigger_id ])) {
1784
-            $help_array[ $trigger_id ] = array(
1785
-                'title'   => esc_html__('Missing Content', 'event_espresso'),
1786
-                'content' => esc_html__(
1787
-                    'A trigger has been set that doesn\'t have any corresponding content. Make sure you have set the help content. (see the "_set_help_popup_content" method in the EE_Admin_Page for instructions.)',
1788
-                    'event_espresso'
1789
-                ),
1790
-            );
1791
-            $help_content = $this->_set_help_popup_content($help_array, false);
1792
-        }
1793
-        // let's setup the trigger
1794
-        $content = '<a class="ee-dialog" href="?height='
1795
-                   . $dimensions[0]
1796
-                   . '&width='
1797
-                   . $dimensions[1]
1798
-                   . '&inlineId='
1799
-                   . $trigger_id
1800
-                   . '" target="_blank"><span class="question ee-help-popup-question"></span></a>';
1801
-        $content .= $help_content;
1802
-        if ($display) {
1803
-            echo $content;
1804
-            return '';
1805
-        }
1806
-        return $content;
1807
-    }
1808
-
1809
-
1810
-    /**
1811
-     * _add_global_screen_options
1812
-     * Add any extra wp_screen_options within this method using built-in WP functions/methods for doing so.
1813
-     * This particular method will add_screen_options on ALL EE_Admin Pages
1814
-     *
1815
-     * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
1816
-     *         see also WP_Screen object documents...
1817
-     * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
1818
-     * @abstract
1819
-     * @return void
1820
-     */
1821
-    private function _add_global_screen_options()
1822
-    {
1823
-    }
1824
-
1825
-
1826
-    /**
1827
-     * _add_global_feature_pointers
1828
-     * This method is used for implementing any "feature pointers" (using built-in WP styling js).
1829
-     * This particular method will implement feature pointers for ALL EE_Admin pages.
1830
-     * Note: this is just a placeholder for now.  Implementation will come down the road
1831
-     *
1832
-     * @see    WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
1833
-     *         extended) also see:
1834
-     * @link   http://eamann.com/tech/wordpress-portland/
1835
-     * @abstract
1836
-     * @return void
1837
-     */
1838
-    private function _add_global_feature_pointers()
1839
-    {
1840
-    }
1841
-
1842
-
1843
-    /**
1844
-     * load_global_scripts_styles
1845
-     * The scripts and styles enqueued in here will be loaded on every EE Admin page
1846
-     *
1847
-     * @return void
1848
-     * @throws EE_Error
1849
-     */
1850
-    public function load_global_scripts_styles()
1851
-    {
1852
-        /** STYLES **/
1853
-        // add debugging styles
1854
-        if (WP_DEBUG) {
1855
-            add_action('admin_head', array($this, 'add_xdebug_style'));
1856
-        }
1857
-        // register all styles
1858
-        wp_register_style(
1859
-            'espresso-ui-theme',
1860
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1861
-            array(),
1862
-            EVENT_ESPRESSO_VERSION
1863
-        );
1864
-        wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1865
-        // helpers styles
1866
-        wp_register_style(
1867
-            'ee-text-links',
1868
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css',
1869
-            array(),
1870
-            EVENT_ESPRESSO_VERSION
1871
-        );
1872
-        /** SCRIPTS **/
1873
-        // register all scripts
1874
-        wp_register_script(
1875
-            'ee-dialog',
1876
-            EE_ADMIN_URL . 'assets/ee-dialog-helper.js',
1877
-            array('jquery', 'jquery-ui-draggable'),
1878
-            EVENT_ESPRESSO_VERSION,
1879
-            true
1880
-        );
1881
-        wp_register_script(
1882
-            'ee_admin_js',
1883
-            EE_ADMIN_URL . 'assets/ee-admin-page.js',
1884
-            array('espresso_core', 'ee-parse-uri', 'ee-dialog'),
1885
-            EVENT_ESPRESSO_VERSION,
1886
-            true
1887
-        );
1888
-        wp_register_script(
1889
-            'jquery-ui-timepicker-addon',
1890
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js',
1891
-            array('jquery-ui-datepicker', 'jquery-ui-slider'),
1892
-            EVENT_ESPRESSO_VERSION,
1893
-            true
1894
-        );
1895
-        if (EE_Registry::instance()->CFG->admin->help_tour_activation) {
1896
-            add_filter('FHEE_load_joyride', '__return_true');
1897
-        }
1898
-        // script for sorting tables
1899
-        wp_register_script(
1900
-            'espresso_ajax_table_sorting',
1901
-            EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js',
1902
-            array('ee_admin_js', 'jquery-ui-sortable'),
1903
-            EVENT_ESPRESSO_VERSION,
1904
-            true
1905
-        );
1906
-        // script for parsing uri's
1907
-        wp_register_script(
1908
-            'ee-parse-uri',
1909
-            EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js',
1910
-            array(),
1911
-            EVENT_ESPRESSO_VERSION,
1912
-            true
1913
-        );
1914
-        // and parsing associative serialized form elements
1915
-        wp_register_script(
1916
-            'ee-serialize-full-array',
1917
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js',
1918
-            array('jquery'),
1919
-            EVENT_ESPRESSO_VERSION,
1920
-            true
1921
-        );
1922
-        // helpers scripts
1923
-        wp_register_script(
1924
-            'ee-text-links',
1925
-            EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js',
1926
-            array('jquery'),
1927
-            EVENT_ESPRESSO_VERSION,
1928
-            true
1929
-        );
1930
-        wp_register_script(
1931
-            'ee-moment-core',
1932
-            EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js',
1933
-            array(),
1934
-            EVENT_ESPRESSO_VERSION,
1935
-            true
1936
-        );
1937
-        wp_register_script(
1938
-            'ee-moment',
1939
-            EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js',
1940
-            array('ee-moment-core'),
1941
-            EVENT_ESPRESSO_VERSION,
1942
-            true
1943
-        );
1944
-        wp_register_script(
1945
-            'ee-datepicker',
1946
-            EE_ADMIN_URL . 'assets/ee-datepicker.js',
1947
-            array('jquery-ui-timepicker-addon', 'ee-moment'),
1948
-            EVENT_ESPRESSO_VERSION,
1949
-            true
1950
-        );
1951
-        // google charts
1952
-        wp_register_script(
1953
-            'google-charts',
1954
-            'https://www.gstatic.com/charts/loader.js',
1955
-            array(),
1956
-            EVENT_ESPRESSO_VERSION,
1957
-            false
1958
-        );
1959
-        // ENQUEUE ALL BASICS BY DEFAULT
1960
-        wp_enqueue_style('ee-admin-css');
1961
-        wp_enqueue_script('ee_admin_js');
1962
-        wp_enqueue_script('ee-accounting');
1963
-        wp_enqueue_script('jquery-validate');
1964
-        // taking care of metaboxes
1965
-        if (empty($this->_cpt_route)
1966
-            && (isset($this->_route_config['metaboxes']) || isset($this->_route_config['has_metaboxes']))
1967
-        ) {
1968
-            wp_enqueue_script('dashboard');
1969
-        }
1970
-        // LOCALIZED DATA
1971
-        // localize script for ajax lazy loading
1972
-        $lazy_loader_container_ids = apply_filters(
1973
-            'FHEE__EE_Admin_Page_Core__load_global_scripts_styles__loader_containers',
1974
-            array('espresso_news_post_box_content')
1975
-        );
1976
-        wp_localize_script('ee_admin_js', 'eeLazyLoadingContainers', $lazy_loader_container_ids);
1977
-        /**
1978
-         * help tour stuff
1979
-         */
1980
-        if (! empty($this->_help_tour)) {
1981
-            // register the js for kicking things off
1982
-            wp_enqueue_script(
1983
-                'ee-help-tour',
1984
-                EE_ADMIN_URL . 'assets/ee-help-tour.js',
1985
-                array('jquery-joyride'),
1986
-                EVENT_ESPRESSO_VERSION,
1987
-                true
1988
-            );
1989
-            $tours = array();
1990
-            // setup tours for the js tour object
1991
-            foreach ($this->_help_tour['tours'] as $tour) {
1992
-                if ($tour instanceof EE_Help_Tour) {
1993
-                    $tours[] = array(
1994
-                        'id'      => $tour->get_slug(),
1995
-                        'options' => $tour->get_options(),
1996
-                    );
1997
-                }
1998
-            }
1999
-            wp_localize_script('ee-help-tour', 'EE_HELP_TOUR', array('tours' => $tours));
2000
-            // admin_footer_global will take care of making sure our help_tour skeleton gets printed via the info stored in $this->_help_tour
2001
-        }
2002
-    }
2003
-
2004
-
2005
-    /**
2006
-     *        admin_footer_scripts_eei18n_js_strings
2007
-     *
2008
-     * @return        void
2009
-     */
2010
-    public function admin_footer_scripts_eei18n_js_strings()
2011
-    {
2012
-        EE_Registry::$i18n_js_strings['ajax_url'] = WP_AJAX_URL;
2013
-        EE_Registry::$i18n_js_strings['confirm_delete'] = wp_strip_all_tags(
2014
-            __(
2015
-                'Are you absolutely sure you want to delete this item?\nThis action will delete ALL DATA associated with this item!!!\nThis can NOT be undone!!!',
2016
-                'event_espresso'
2017
-            )
2018
-        );
2019
-        EE_Registry::$i18n_js_strings['January'] = wp_strip_all_tags(__('January', 'event_espresso'));
2020
-        EE_Registry::$i18n_js_strings['February'] = wp_strip_all_tags(__('February', 'event_espresso'));
2021
-        EE_Registry::$i18n_js_strings['March'] = wp_strip_all_tags(__('March', 'event_espresso'));
2022
-        EE_Registry::$i18n_js_strings['April'] = wp_strip_all_tags(__('April', 'event_espresso'));
2023
-        EE_Registry::$i18n_js_strings['May'] = wp_strip_all_tags(__('May', 'event_espresso'));
2024
-        EE_Registry::$i18n_js_strings['June'] = wp_strip_all_tags(__('June', 'event_espresso'));
2025
-        EE_Registry::$i18n_js_strings['July'] = wp_strip_all_tags(__('July', 'event_espresso'));
2026
-        EE_Registry::$i18n_js_strings['August'] = wp_strip_all_tags(__('August', 'event_espresso'));
2027
-        EE_Registry::$i18n_js_strings['September'] = wp_strip_all_tags(__('September', 'event_espresso'));
2028
-        EE_Registry::$i18n_js_strings['October'] = wp_strip_all_tags(__('October', 'event_espresso'));
2029
-        EE_Registry::$i18n_js_strings['November'] = wp_strip_all_tags(__('November', 'event_espresso'));
2030
-        EE_Registry::$i18n_js_strings['December'] = wp_strip_all_tags(__('December', 'event_espresso'));
2031
-        EE_Registry::$i18n_js_strings['Jan'] = wp_strip_all_tags(__('Jan', 'event_espresso'));
2032
-        EE_Registry::$i18n_js_strings['Feb'] = wp_strip_all_tags(__('Feb', 'event_espresso'));
2033
-        EE_Registry::$i18n_js_strings['Mar'] = wp_strip_all_tags(__('Mar', 'event_espresso'));
2034
-        EE_Registry::$i18n_js_strings['Apr'] = wp_strip_all_tags(__('Apr', 'event_espresso'));
2035
-        EE_Registry::$i18n_js_strings['May'] = wp_strip_all_tags(__('May', 'event_espresso'));
2036
-        EE_Registry::$i18n_js_strings['Jun'] = wp_strip_all_tags(__('Jun', 'event_espresso'));
2037
-        EE_Registry::$i18n_js_strings['Jul'] = wp_strip_all_tags(__('Jul', 'event_espresso'));
2038
-        EE_Registry::$i18n_js_strings['Aug'] = wp_strip_all_tags(__('Aug', 'event_espresso'));
2039
-        EE_Registry::$i18n_js_strings['Sep'] = wp_strip_all_tags(__('Sep', 'event_espresso'));
2040
-        EE_Registry::$i18n_js_strings['Oct'] = wp_strip_all_tags(__('Oct', 'event_espresso'));
2041
-        EE_Registry::$i18n_js_strings['Nov'] = wp_strip_all_tags(__('Nov', 'event_espresso'));
2042
-        EE_Registry::$i18n_js_strings['Dec'] = wp_strip_all_tags(__('Dec', 'event_espresso'));
2043
-        EE_Registry::$i18n_js_strings['Sunday'] = wp_strip_all_tags(__('Sunday', 'event_espresso'));
2044
-        EE_Registry::$i18n_js_strings['Monday'] = wp_strip_all_tags(__('Monday', 'event_espresso'));
2045
-        EE_Registry::$i18n_js_strings['Tuesday'] = wp_strip_all_tags(__('Tuesday', 'event_espresso'));
2046
-        EE_Registry::$i18n_js_strings['Wednesday'] = wp_strip_all_tags(__('Wednesday', 'event_espresso'));
2047
-        EE_Registry::$i18n_js_strings['Thursday'] = wp_strip_all_tags(__('Thursday', 'event_espresso'));
2048
-        EE_Registry::$i18n_js_strings['Friday'] = wp_strip_all_tags(__('Friday', 'event_espresso'));
2049
-        EE_Registry::$i18n_js_strings['Saturday'] = wp_strip_all_tags(__('Saturday', 'event_espresso'));
2050
-        EE_Registry::$i18n_js_strings['Sun'] = wp_strip_all_tags(__('Sun', 'event_espresso'));
2051
-        EE_Registry::$i18n_js_strings['Mon'] = wp_strip_all_tags(__('Mon', 'event_espresso'));
2052
-        EE_Registry::$i18n_js_strings['Tue'] = wp_strip_all_tags(__('Tue', 'event_espresso'));
2053
-        EE_Registry::$i18n_js_strings['Wed'] = wp_strip_all_tags(__('Wed', 'event_espresso'));
2054
-        EE_Registry::$i18n_js_strings['Thu'] = wp_strip_all_tags(__('Thu', 'event_espresso'));
2055
-        EE_Registry::$i18n_js_strings['Fri'] = wp_strip_all_tags(__('Fri', 'event_espresso'));
2056
-        EE_Registry::$i18n_js_strings['Sat'] = wp_strip_all_tags(__('Sat', 'event_espresso'));
2057
-    }
2058
-
2059
-
2060
-    /**
2061
-     *        load enhanced xdebug styles for ppl with failing eyesight
2062
-     *
2063
-     * @return        void
2064
-     */
2065
-    public function add_xdebug_style()
2066
-    {
2067
-        echo '<style>.xdebug-error { font-size:1.5em; }</style>';
2068
-    }
2069
-
2070
-
2071
-    /************************/
2072
-    /** LIST TABLE METHODS **/
2073
-    /************************/
2074
-    /**
2075
-     * this sets up the list table if the current view requires it.
2076
-     *
2077
-     * @return void
2078
-     * @throws EE_Error
2079
-     */
2080
-    protected function _set_list_table()
2081
-    {
2082
-        // first is this a list_table view?
2083
-        if (! isset($this->_route_config['list_table'])) {
2084
-            return;
2085
-        } //not a list_table view so get out.
2086
-        // list table functions are per view specific (because some admin pages might have more than one list table!)
2087
-        $list_table_view = '_set_list_table_views_' . $this->_req_action;
2088
-        if (! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) {
2089
-            // user error msg
2090
-            $error_msg = esc_html__(
2091
-                'An error occurred. The requested list table views could not be found.',
2092
-                'event_espresso'
2093
-            );
2094
-            // developer error msg
2095
-            $error_msg .= '||'
2096
-                          . sprintf(
2097
-                              esc_html__(
2098
-                                  'List table views for "%s" route could not be setup. Check that you have the corresponding method, "%s" set up for defining list_table_views for this route.',
2099
-                                  'event_espresso'
2100
-                              ),
2101
-                              $this->_req_action,
2102
-                              $list_table_view
2103
-                          );
2104
-            throw new EE_Error($error_msg);
2105
-        }
2106
-        // let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally
2107
-        $this->_views = apply_filters(
2108
-            'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action,
2109
-            $this->_views
2110
-        );
2111
-        $this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views);
2112
-        $this->_views = apply_filters('FHEE_list_table_views', $this->_views);
2113
-        $this->_set_list_table_view();
2114
-        $this->_set_list_table_object();
2115
-    }
2116
-
2117
-
2118
-    /**
2119
-     * set current view for List Table
2120
-     *
2121
-     * @return void
2122
-     */
2123
-    protected function _set_list_table_view()
2124
-    {
2125
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2126
-        // looking at active items or dumpster diving ?
2127
-        if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2128
-            $this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all';
2129
-        } else {
2130
-            $this->_view = sanitize_key($this->_req_data['status']);
2131
-        }
2132
-    }
2133
-
2134
-
2135
-    /**
2136
-     * _set_list_table_object
2137
-     * WP_List_Table objects need to be loaded fairly early so automatic stuff WP does is taken care of.
2138
-     *
2139
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2140
-     * @throws \InvalidArgumentException
2141
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2142
-     * @throws EE_Error
2143
-     * @throws InvalidInterfaceException
2144
-     */
2145
-    protected function _set_list_table_object()
2146
-    {
2147
-        if (isset($this->_route_config['list_table'])) {
2148
-            if (! class_exists($this->_route_config['list_table'])) {
2149
-                throw new EE_Error(
2150
-                    sprintf(
2151
-                        esc_html__(
2152
-                            'The %s class defined for the list table does not exist.  Please check the spelling of the class ref in the $_page_config property on %s.',
2153
-                            'event_espresso'
2154
-                        ),
2155
-                        $this->_route_config['list_table'],
2156
-                        get_class($this)
2157
-                    )
2158
-                );
2159
-            }
2160
-            $this->_list_table_object = $this->loader->getShared(
2161
-                $this->_route_config['list_table'],
2162
-                array($this)
2163
-            );
2164
-        }
2165
-    }
2166
-
2167
-
2168
-    /**
2169
-     * get_list_table_view_RLs - get it? View RL ?? VU-RL???  URL ??
2170
-     *
2171
-     * @param array $extra_query_args                     Optional. An array of extra query args to add to the generated
2172
-     *                                                    urls.  The array should be indexed by the view it is being
2173
-     *                                                    added to.
2174
-     * @return array
2175
-     */
2176
-    public function get_list_table_view_RLs($extra_query_args = array())
2177
-    {
2178
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2179
-        if (empty($this->_views)) {
2180
-            $this->_views = array();
2181
-        }
2182
-        // cycle thru views
2183
-        foreach ($this->_views as $key => $view) {
2184
-            $query_args = array();
2185
-            // check for current view
2186
-            $this->_views[ $key ]['class'] = $this->_view === $view['slug'] ? 'current' : '';
2187
-            $query_args['action'] = $this->_req_action;
2188
-            $query_args[ $this->_req_action . '_nonce' ] = wp_create_nonce($query_args['action'] . '_nonce');
2189
-            $query_args['status'] = $view['slug'];
2190
-            // merge any other arguments sent in.
2191
-            if (isset($extra_query_args[ $view['slug'] ])) {
2192
-                $query_args = array_merge($query_args, $extra_query_args[ $view['slug'] ]);
2193
-            }
2194
-            $this->_views[ $key ]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2195
-        }
2196
-        return $this->_views;
2197
-    }
2198
-
2199
-
2200
-    /**
2201
-     * _entries_per_page_dropdown
2202
-     * generates a drop down box for selecting the number of visible rows in an admin page list table
2203
-     *
2204
-     * @todo   : Note: ideally this should be added to the screen options dropdown as that would be consistent with how
2205
-     *         WP does it.
2206
-     * @param int $max_entries total number of rows in the table
2207
-     * @return string
2208
-     */
2209
-    protected function _entries_per_page_dropdown($max_entries = 0)
2210
-    {
2211
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2212
-        $values = array(10, 25, 50, 100);
2213
-        $per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2214
-        if ($max_entries) {
2215
-            $values[] = $max_entries;
2216
-            sort($values);
2217
-        }
2218
-        $entries_per_page_dropdown = '
104
+	/**
105
+	 * @var array $_route_config
106
+	 */
107
+	protected $_route_config;
108
+
109
+	/**
110
+	 * Used to hold default query args for list table routes to help preserve stickiness of filters for carried out
111
+	 * actions.
112
+	 *
113
+	 * @since 4.6.x
114
+	 * @var array.
115
+	 */
116
+	protected $_default_route_query_args;
117
+
118
+	// set via request page and action args.
119
+	protected $_current_page;
120
+
121
+	protected $_current_view;
122
+
123
+	protected $_current_page_view_url;
124
+
125
+	// sanitized request action (and nonce)
126
+
127
+	/**
128
+	 * @var string $_req_action
129
+	 */
130
+	protected $_req_action;
131
+
132
+	/**
133
+	 * @var string $_req_nonce
134
+	 */
135
+	protected $_req_nonce;
136
+
137
+	// search related
138
+	protected $_search_btn_label;
139
+
140
+	protected $_search_box_callback;
141
+
142
+	/**
143
+	 * WP Current Screen object
144
+	 *
145
+	 * @var WP_Screen
146
+	 */
147
+	protected $_current_screen;
148
+
149
+	// for holding EE_Admin_Hooks object when needed (set via set_hook_object())
150
+	protected $_hook_obj;
151
+
152
+	// for holding incoming request data
153
+	protected $_req_data;
154
+
155
+	// yes / no array for admin form fields
156
+	protected $_yes_no_values = array();
157
+
158
+	// some default things shared by all child classes
159
+	protected $_default_espresso_metaboxes;
160
+
161
+	/**
162
+	 *    EE_Registry Object
163
+	 *
164
+	 * @var    EE_Registry
165
+	 */
166
+	protected $EE = null;
167
+
168
+
169
+	/**
170
+	 * This is just a property that flags whether the given route is a caffeinated route or not.
171
+	 *
172
+	 * @var boolean
173
+	 */
174
+	protected $_is_caf = false;
175
+
176
+
177
+	/**
178
+	 * @Constructor
179
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
180
+	 * @throws EE_Error
181
+	 * @throws InvalidArgumentException
182
+	 * @throws ReflectionException
183
+	 * @throws InvalidDataTypeException
184
+	 * @throws InvalidInterfaceException
185
+	 */
186
+	public function __construct($routing = true)
187
+	{
188
+		$this->loader = LoaderFactory::getLoader();
189
+		if (strpos($this->_get_dir(), 'caffeinated') !== false) {
190
+			$this->_is_caf = true;
191
+		}
192
+		$this->_yes_no_values = array(
193
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
194
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
195
+		);
196
+		// set the _req_data property.
197
+		$this->_req_data = array_merge($_GET, $_POST);
198
+		// routing enabled?
199
+		$this->_routing = $routing;
200
+		// set initial page props (child method)
201
+		$this->_init_page_props();
202
+		// set global defaults
203
+		$this->_set_defaults();
204
+		// set early because incoming requests could be ajax related and we need to register those hooks.
205
+		$this->_global_ajax_hooks();
206
+		$this->_ajax_hooks();
207
+		// other_page_hooks have to be early too.
208
+		$this->_do_other_page_hooks();
209
+		// This just allows us to have extending classes do something specific
210
+		// before the parent constructor runs _page_setup().
211
+		if (method_exists($this, '_before_page_setup')) {
212
+			$this->_before_page_setup();
213
+		}
214
+		// set up page dependencies
215
+		$this->_page_setup();
216
+	}
217
+
218
+
219
+	/**
220
+	 * _init_page_props
221
+	 * Child classes use to set at least the following properties:
222
+	 * $page_slug.
223
+	 * $page_label.
224
+	 *
225
+	 * @abstract
226
+	 * @return void
227
+	 */
228
+	abstract protected function _init_page_props();
229
+
230
+
231
+	/**
232
+	 * _ajax_hooks
233
+	 * child classes put all their add_action('wp_ajax_{name_of_hook}') hooks in here.
234
+	 * Note: within the ajax callback methods.
235
+	 *
236
+	 * @abstract
237
+	 * @return void
238
+	 */
239
+	abstract protected function _ajax_hooks();
240
+
241
+
242
+	/**
243
+	 * _define_page_props
244
+	 * child classes define page properties in here.  Must include at least:
245
+	 * $_admin_base_url = base_url for all admin pages
246
+	 * $_admin_page_title = default admin_page_title for admin pages
247
+	 * $_labels = array of default labels for various automatically generated elements:
248
+	 *    array(
249
+	 *        'buttons' => array(
250
+	 *            'add' => esc_html__('label for add new button'),
251
+	 *            'edit' => esc_html__('label for edit button'),
252
+	 *            'delete' => esc_html__('label for delete button')
253
+	 *            )
254
+	 *        )
255
+	 *
256
+	 * @abstract
257
+	 * @return void
258
+	 */
259
+	abstract protected function _define_page_props();
260
+
261
+
262
+	/**
263
+	 * _set_page_routes
264
+	 * child classes use this to define the page routes for all subpages handled by the class.  Page routes are
265
+	 * assigned to a action => method pairs in an array and to the $_page_routes property.  Each page route must also
266
+	 * have a 'default' route. Here's the format
267
+	 * $this->_page_routes = array(
268
+	 *        'default' => array(
269
+	 *            'func' => '_default_method_handling_route',
270
+	 *            'args' => array('array','of','args'),
271
+	 *            'noheader' => true, //add this in if this page route is processed before any headers are loaded (i.e.
272
+	 *            ajax request, backend processing)
273
+	 *            'headers_sent_route'=>'headers_route_reference', //add this if noheader=>true, and you want to load a
274
+	 *            headers route after.  The string you enter here should match the defined route reference for a
275
+	 *            headers sent route.
276
+	 *            'capability' => 'route_capability', //indicate a string for minimum capability required to access
277
+	 *            this route.
278
+	 *            'obj_id' => 10 // if this route has an object id, then this can include it (used for capability
279
+	 *            checks).
280
+	 *        ),
281
+	 *        'insert_item' => '_method_for_handling_insert_item' //this can be used if all we need to have is a
282
+	 *        handling method.
283
+	 *        )
284
+	 * )
285
+	 *
286
+	 * @abstract
287
+	 * @return void
288
+	 */
289
+	abstract protected function _set_page_routes();
290
+
291
+
292
+	/**
293
+	 * _set_page_config
294
+	 * child classes use this to define the _page_config array for all subpages handled by the class. Each key in the
295
+	 * array corresponds to the page_route for the loaded page. Format:
296
+	 * $this->_page_config = array(
297
+	 *        'default' => array(
298
+	 *            'labels' => array(
299
+	 *                'buttons' => array(
300
+	 *                    'add' => esc_html__('label for adding item'),
301
+	 *                    'edit' => esc_html__('label for editing item'),
302
+	 *                    'delete' => esc_html__('label for deleting item')
303
+	 *                ),
304
+	 *                'publishbox' => esc_html__('Localized Title for Publish metabox', 'event_espresso')
305
+	 *            ), //optional an array of custom labels for various automatically generated elements to use on the
306
+	 *            page. If this isn't present then the defaults will be used as set for the $this->_labels in
307
+	 *            _define_page_props() method
308
+	 *            'nav' => array(
309
+	 *                'label' => esc_html__('Label for Tab', 'event_espresso').
310
+	 *                'url' => 'http://someurl', //automatically generated UNLESS you define
311
+	 *                'css_class' => 'css-class', //automatically generated UNLESS you define
312
+	 *                'order' => 10, //required to indicate tab position.
313
+	 *                'persistent' => false //if you want the nav tab to ONLY display when the specific route is
314
+	 *                displayed then add this parameter.
315
+	 *            'list_table' => 'name_of_list_table' //string for list table class to be loaded for this admin_page.
316
+	 *            'metaboxes' => array('metabox1', 'metabox2'), //if present this key indicates we want to load
317
+	 *            metaboxes set for eventespresso admin pages.
318
+	 *            'has_metaboxes' => true, //this boolean flag can simply be used to indicate if the route will have
319
+	 *            metaboxes.  Typically this is used if the 'metaboxes' index is not used because metaboxes are added
320
+	 *            later.  We just use this flag to make sure the necessary js gets enqueued on page load.
321
+	 *            'has_help_popups' => false //defaults(true) //this boolean flag can simply be used to indicate if the
322
+	 *            given route has help popups setup and if it does then we need to make sure thickbox is enqueued.
323
+	 *            'columns' => array(4, 2), //this key triggers the setup of a page that uses columns (metaboxes).  The
324
+	 *            array indicates the max number of columns (4) and the default number of columns on page load (2).
325
+	 *            There is an option in the "screen_options" dropdown that is setup so users can pick what columns they
326
+	 *            want to display.
327
+	 *            'help_tabs' => array( //this is used for adding help tabs to a page
328
+	 *                'tab_id' => array(
329
+	 *                    'title' => 'tab_title',
330
+	 *                    'filename' => 'name_of_file_containing_content', //this is the primary method for setting
331
+	 *                    help tab content.  The fallback if it isn't present is to try a the callback.  Filename
332
+	 *                    should match a file in the admin folder's "help_tabs" dir (ie..
333
+	 *                    events/help_tabs/name_of_file_containing_content.help_tab.php)
334
+	 *                    'callback' => 'callback_method_for_content', //if 'filename' isn't present then system will
335
+	 *                    attempt to use the callback which should match the name of a method in the class
336
+	 *                    ),
337
+	 *                'tab2_id' => array(
338
+	 *                    'title' => 'tab2 title',
339
+	 *                    'filename' => 'file_name_2'
340
+	 *                    'callback' => 'callback_method_for_content',
341
+	 *                 ),
342
+	 *            'help_sidebar' => 'callback_for_sidebar_content', //this is used for setting up the sidebar in the
343
+	 *            help tab area on an admin page. @link
344
+	 *            http://make.wordpress.org/core/2011/12/06/help-and-screen-api-changes-in-3-3/
345
+	 *            'help_tour' => array(
346
+	 *                'name_of_help_tour_class', //all help tours shoudl be a child class of EE_Help_Tour and located
347
+	 *                in a folder for this admin page named "help_tours", a file name matching the key given here
348
+	 *                (name_of_help_tour_class.class.php), and class matching key given here (name_of_help_tour_class)
349
+	 *            ),
350
+	 *            'require_nonce' => TRUE //this is used if you want to set a route to NOT require a nonce (default is
351
+	 *            true if it isn't present).  To remove the requirement for a nonce check when this route is visited
352
+	 *            just set
353
+	 *            'require_nonce' to FALSE
354
+	 *            )
355
+	 * )
356
+	 *
357
+	 * @abstract
358
+	 * @return void
359
+	 */
360
+	abstract protected function _set_page_config();
361
+
362
+
363
+
364
+
365
+
366
+	/** end sample help_tour methods **/
367
+	/**
368
+	 * _add_screen_options
369
+	 * Child classes can add any extra wp_screen_options within this method using built-in WP functions/methods for
370
+	 * doing so. Note child classes can also define _add_screen_options_($this->_current_view) to limit screen options
371
+	 * to a particular view.
372
+	 *
373
+	 * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
374
+	 *         see also WP_Screen object documents...
375
+	 * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
376
+	 * @abstract
377
+	 * @return void
378
+	 */
379
+	abstract protected function _add_screen_options();
380
+
381
+
382
+	/**
383
+	 * _add_feature_pointers
384
+	 * Child classes should use this method for implementing any "feature pointers" (using built-in WP styling js).
385
+	 * Note child classes can also define _add_feature_pointers_($this->_current_view) to limit screen options to a
386
+	 * particular view. Note: this is just a placeholder for now.  Implementation will come down the road See:
387
+	 * WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
388
+	 * extended) also see:
389
+	 *
390
+	 * @link   http://eamann.com/tech/wordpress-portland/
391
+	 * @abstract
392
+	 * @return void
393
+	 */
394
+	abstract protected function _add_feature_pointers();
395
+
396
+
397
+	/**
398
+	 * load_scripts_styles
399
+	 * child classes put their wp_enqueue_script and wp_enqueue_style hooks in here for anything they need loaded for
400
+	 * their pages/subpages.  Note this is for all pages/subpages of the system.  You can also load only specific
401
+	 * scripts/styles per view by putting them in a dynamic function in this format
402
+	 * (load_scripts_styles_{$this->_current_view}) which matches your page route (action request arg)
403
+	 *
404
+	 * @abstract
405
+	 * @return void
406
+	 */
407
+	abstract public function load_scripts_styles();
408
+
409
+
410
+	/**
411
+	 * admin_init
412
+	 * Anything that should be set/executed at 'admin_init' WP hook runtime should be put in here.  This will apply to
413
+	 * all pages/views loaded by child class.
414
+	 *
415
+	 * @abstract
416
+	 * @return void
417
+	 */
418
+	abstract public function admin_init();
419
+
420
+
421
+	/**
422
+	 * admin_notices
423
+	 * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply to
424
+	 * all pages/views loaded by child class.
425
+	 *
426
+	 * @abstract
427
+	 * @return void
428
+	 */
429
+	abstract public function admin_notices();
430
+
431
+
432
+	/**
433
+	 * admin_footer_scripts
434
+	 * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
435
+	 * will apply to all pages/views loaded by child class.
436
+	 *
437
+	 * @return void
438
+	 */
439
+	abstract public function admin_footer_scripts();
440
+
441
+
442
+	/**
443
+	 * admin_footer
444
+	 * anything triggered by the 'admin_footer' WP action hook should be added to here. This particular method will
445
+	 * apply to all pages/views loaded by child class.
446
+	 *
447
+	 * @return void
448
+	 */
449
+	public function admin_footer()
450
+	{
451
+	}
452
+
453
+
454
+	/**
455
+	 * _global_ajax_hooks
456
+	 * all global add_action('wp_ajax_{name_of_hook}') hooks in here.
457
+	 * Note: within the ajax callback methods.
458
+	 *
459
+	 * @abstract
460
+	 * @return void
461
+	 */
462
+	protected function _global_ajax_hooks()
463
+	{
464
+		// for lazy loading of metabox content
465
+		add_action('wp_ajax_espresso-ajax-content', array($this, 'ajax_metabox_content'), 10);
466
+	}
467
+
468
+
469
+	public function ajax_metabox_content()
470
+	{
471
+		$contentid = isset($this->_req_data['contentid']) ? $this->_req_data['contentid'] : '';
472
+		$url = isset($this->_req_data['contenturl']) ? $this->_req_data['contenturl'] : '';
473
+		self::cached_rss_display($contentid, $url);
474
+		wp_die();
475
+	}
476
+
477
+
478
+	/**
479
+	 * _page_setup
480
+	 * Makes sure any things that need to be loaded early get handled.  We also escape early here if the page requested
481
+	 * doesn't match the object.
482
+	 *
483
+	 * @final
484
+	 * @return void
485
+	 * @throws EE_Error
486
+	 * @throws InvalidArgumentException
487
+	 * @throws ReflectionException
488
+	 * @throws InvalidDataTypeException
489
+	 * @throws InvalidInterfaceException
490
+	 */
491
+	final protected function _page_setup()
492
+	{
493
+		// requires?
494
+		// admin_init stuff - global - we're setting this REALLY early so if EE_Admin pages have to hook into other WP pages they can.  But keep in mind, not everything is available from the EE_Admin Page object at this point.
495
+		add_action('admin_init', array($this, 'admin_init_global'), 5);
496
+		// next verify if we need to load anything...
497
+		$this->_current_page = ! empty($_GET['page']) ? sanitize_key($_GET['page']) : '';
498
+		$this->page_folder = strtolower(
499
+			str_replace(array('_Admin_Page', 'Extend_'), '', get_class($this))
500
+		);
501
+		global $ee_menu_slugs;
502
+		$ee_menu_slugs = (array) $ee_menu_slugs;
503
+		if (! defined('DOING_AJAX') && (! $this->_current_page || ! isset($ee_menu_slugs[ $this->_current_page ]))) {
504
+			return;
505
+		}
506
+		// becuz WP List tables have two duplicate select inputs for choosing bulk actions, we need to copy the action from the second to the first
507
+		if (isset($this->_req_data['action2']) && $this->_req_data['action'] === '-1') {
508
+			$this->_req_data['action'] = ! empty($this->_req_data['action2']) && $this->_req_data['action2'] !== '-1'
509
+				? $this->_req_data['action2']
510
+				: $this->_req_data['action'];
511
+		}
512
+		// then set blank or -1 action values to 'default'
513
+		$this->_req_action = isset($this->_req_data['action'])
514
+							 && ! empty($this->_req_data['action'])
515
+							 && $this->_req_data['action'] !== '-1'
516
+			? sanitize_key($this->_req_data['action'])
517
+			: 'default';
518
+		// if action is 'default' after the above BUT we have  'route' var set, then let's use the route as the action.
519
+		//  This covers cases where we're coming in from a list table that isn't on the default route.
520
+		$this->_req_action = $this->_req_action === 'default' && isset($this->_req_data['route'])
521
+			? $this->_req_data['route'] : $this->_req_action;
522
+		// however if we are doing_ajax and we've got a 'route' set then that's what the req_action will be
523
+		$this->_req_action = defined('DOING_AJAX') && isset($this->_req_data['route'])
524
+			? $this->_req_data['route']
525
+			: $this->_req_action;
526
+		$this->_current_view = $this->_req_action;
527
+		$this->_req_nonce = $this->_req_action . '_nonce';
528
+		$this->_define_page_props();
529
+		$this->_current_page_view_url = add_query_arg(
530
+			array('page' => $this->_current_page, 'action' => $this->_current_view),
531
+			$this->_admin_base_url
532
+		);
533
+		// default things
534
+		$this->_default_espresso_metaboxes = array(
535
+			'_espresso_news_post_box',
536
+			'_espresso_links_post_box',
537
+			'_espresso_ratings_request',
538
+			'_espresso_sponsors_post_box',
539
+		);
540
+		// set page configs
541
+		$this->_set_page_routes();
542
+		$this->_set_page_config();
543
+		// let's include any referrer data in our default_query_args for this route for "stickiness".
544
+		if (isset($this->_req_data['wp_referer'])) {
545
+			$this->_default_route_query_args['wp_referer'] = $this->_req_data['wp_referer'];
546
+		}
547
+		// for caffeinated and other extended functionality.
548
+		//  If there is a _extend_page_config method
549
+		// then let's run that to modify the all the various page configuration arrays
550
+		if (method_exists($this, '_extend_page_config')) {
551
+			$this->_extend_page_config();
552
+		}
553
+		// for CPT and other extended functionality.
554
+		// If there is an _extend_page_config_for_cpt
555
+		// then let's run that to modify all the various page configuration arrays.
556
+		if (method_exists($this, '_extend_page_config_for_cpt')) {
557
+			$this->_extend_page_config_for_cpt();
558
+		}
559
+		// filter routes and page_config so addons can add their stuff. Filtering done per class
560
+		$this->_page_routes = apply_filters(
561
+			'FHEE__' . get_class($this) . '__page_setup__page_routes',
562
+			$this->_page_routes,
563
+			$this
564
+		);
565
+		$this->_page_config = apply_filters(
566
+			'FHEE__' . get_class($this) . '__page_setup__page_config',
567
+			$this->_page_config,
568
+			$this
569
+		);
570
+		// if AHEE__EE_Admin_Page__route_admin_request_$this->_current_view method is present
571
+		// then we call it hooked into the AHEE__EE_Admin_Page__route_admin_request action
572
+		if (method_exists($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view)) {
573
+			add_action(
574
+				'AHEE__EE_Admin_Page__route_admin_request',
575
+				array($this, 'AHEE__EE_Admin_Page__route_admin_request_' . $this->_current_view),
576
+				10,
577
+				2
578
+			);
579
+		}
580
+		// next route only if routing enabled
581
+		if ($this->_routing && ! defined('DOING_AJAX')) {
582
+			$this->_verify_routes();
583
+			// next let's just check user_access and kill if no access
584
+			$this->check_user_access();
585
+			if ($this->_is_UI_request) {
586
+				// admin_init stuff - global, all views for this page class, specific view
587
+				add_action('admin_init', array($this, 'admin_init'), 10);
588
+				if (method_exists($this, 'admin_init_' . $this->_current_view)) {
589
+					add_action('admin_init', array($this, 'admin_init_' . $this->_current_view), 15);
590
+				}
591
+			} else {
592
+				// hijack regular WP loading and route admin request immediately
593
+				@ini_set('memory_limit', apply_filters('admin_memory_limit', WP_MAX_MEMORY_LIMIT));
594
+				$this->route_admin_request();
595
+			}
596
+		}
597
+	}
598
+
599
+
600
+	/**
601
+	 * Provides a way for related child admin pages to load stuff on the loaded admin page.
602
+	 *
603
+	 * @return void
604
+	 * @throws ReflectionException
605
+	 * @throws EE_Error
606
+	 */
607
+	private function _do_other_page_hooks()
608
+	{
609
+		$registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, array());
610
+		foreach ($registered_pages as $page) {
611
+			// now let's setup the file name and class that should be present
612
+			$classname = str_replace('.class.php', '', $page);
613
+			// autoloaders should take care of loading file
614
+			if (! class_exists($classname)) {
615
+				$error_msg[] = sprintf(
616
+					esc_html__(
617
+						'Something went wrong with loading the %s admin hooks page.',
618
+						'event_espresso'
619
+					),
620
+					$page
621
+				);
622
+				$error_msg[] = $error_msg[0]
623
+							   . "\r\n"
624
+							   . sprintf(
625
+								   esc_html__(
626
+									   'There is no class in place for the %1$s admin hooks page.%2$sMake sure you have %3$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
627
+									   'event_espresso'
628
+								   ),
629
+								   $page,
630
+								   '<br />',
631
+								   '<strong>' . $classname . '</strong>'
632
+							   );
633
+				throw new EE_Error(implode('||', $error_msg));
634
+			}
635
+			$a = new ReflectionClass($classname);
636
+			// notice we are passing the instance of this class to the hook object.
637
+			$hookobj[] = $a->newInstance($this);
638
+		}
639
+	}
640
+
641
+
642
+	public function load_page_dependencies()
643
+	{
644
+		try {
645
+			$this->_load_page_dependencies();
646
+		} catch (EE_Error $e) {
647
+			$e->get_error();
648
+		}
649
+	}
650
+
651
+
652
+	/**
653
+	 * load_page_dependencies
654
+	 * loads things specific to this page class when its loaded.  Really helps with efficiency.
655
+	 *
656
+	 * @return void
657
+	 * @throws DomainException
658
+	 * @throws EE_Error
659
+	 * @throws InvalidArgumentException
660
+	 * @throws InvalidDataTypeException
661
+	 * @throws InvalidInterfaceException
662
+	 * @throws ReflectionException
663
+	 */
664
+	protected function _load_page_dependencies()
665
+	{
666
+		// let's set the current_screen and screen options to override what WP set
667
+		$this->_current_screen = get_current_screen();
668
+		// load admin_notices - global, page class, and view specific
669
+		add_action('admin_notices', array($this, 'admin_notices_global'), 5);
670
+		add_action('admin_notices', array($this, 'admin_notices'), 10);
671
+		if (method_exists($this, 'admin_notices_' . $this->_current_view)) {
672
+			add_action('admin_notices', array($this, 'admin_notices_' . $this->_current_view), 15);
673
+		}
674
+		// load network admin_notices - global, page class, and view specific
675
+		add_action('network_admin_notices', array($this, 'network_admin_notices_global'), 5);
676
+		if (method_exists($this, 'network_admin_notices_' . $this->_current_view)) {
677
+			add_action('network_admin_notices', array($this, 'network_admin_notices_' . $this->_current_view));
678
+		}
679
+		// this will save any per_page screen options if they are present
680
+		$this->_set_per_page_screen_options();
681
+		// setup list table properties
682
+		$this->_set_list_table();
683
+		// child classes can "register" a metabox to be automatically handled via the _page_config array property.
684
+		// However in some cases the metaboxes will need to be added within a route handling callback.
685
+		$this->_add_registered_meta_boxes();
686
+		$this->_add_screen_columns();
687
+		// add screen options - global, page child class, and view specific
688
+		$this->_add_global_screen_options();
689
+		$this->_add_screen_options();
690
+		$add_screen_options = "_add_screen_options_{$this->_current_view}";
691
+		if (method_exists($this, $add_screen_options)) {
692
+			$this->{$add_screen_options}();
693
+		}
694
+		// add help tab(s) and tours- set via page_config and qtips.
695
+		$this->_add_help_tour();
696
+		$this->_add_help_tabs();
697
+		$this->_add_qtips();
698
+		// add feature_pointers - global, page child class, and view specific
699
+		$this->_add_feature_pointers();
700
+		$this->_add_global_feature_pointers();
701
+		$add_feature_pointer = "_add_feature_pointer_{$this->_current_view}";
702
+		if (method_exists($this, $add_feature_pointer)) {
703
+			$this->{$add_feature_pointer}();
704
+		}
705
+		// enqueue scripts/styles - global, page class, and view specific
706
+		add_action('admin_enqueue_scripts', array($this, 'load_global_scripts_styles'), 5);
707
+		add_action('admin_enqueue_scripts', array($this, 'load_scripts_styles'), 10);
708
+		if (method_exists($this, "load_scripts_styles_{$this->_current_view}")) {
709
+			add_action('admin_enqueue_scripts', array($this, "load_scripts_styles_{$this->_current_view}"), 15);
710
+		}
711
+		add_action('admin_enqueue_scripts', array($this, 'admin_footer_scripts_eei18n_js_strings'), 100);
712
+		// admin_print_footer_scripts - global, page child class, and view specific.
713
+		// NOTE, despite the name, whenever possible, scripts should NOT be loaded using this.
714
+		// In most cases that's doing_it_wrong().  But adding hidden container elements etc.
715
+		// is a good use case. Notice the late priority we're giving these
716
+		add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts_global'), 99);
717
+		add_action('admin_print_footer_scripts', array($this, 'admin_footer_scripts'), 100);
718
+		if (method_exists($this, "admin_footer_scripts_{$this->_current_view}")) {
719
+			add_action('admin_print_footer_scripts', array($this, "admin_footer_scripts_{$this->_current_view}"), 101);
720
+		}
721
+		// admin footer scripts
722
+		add_action('admin_footer', array($this, 'admin_footer_global'), 99);
723
+		add_action('admin_footer', array($this, 'admin_footer'), 100);
724
+		if (method_exists($this, "admin_footer_{$this->_current_view}")) {
725
+			add_action('admin_footer', array($this, "admin_footer_{$this->_current_view}"), 101);
726
+		}
727
+		do_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', $this->page_slug);
728
+		// targeted hook
729
+		do_action(
730
+			"FHEE__EE_Admin_Page___load_page_dependencies__after_load__{$this->page_slug}__{$this->_req_action}"
731
+		);
732
+	}
733
+
734
+
735
+	/**
736
+	 * _set_defaults
737
+	 * This sets some global defaults for class properties.
738
+	 */
739
+	private function _set_defaults()
740
+	{
741
+		$this->_current_screen = $this->_admin_page_title = $this->_req_action = $this->_req_nonce = null;
742
+		$this->_event = $this->_template_path = $this->_column_template_path = null;
743
+		$this->_nav_tabs = $this->_views = $this->_page_routes = array();
744
+		$this->_page_config = $this->_default_route_query_args = array();
745
+		$this->_default_nav_tab_name = 'overview';
746
+		// init template args
747
+		$this->_template_args = array(
748
+			'admin_page_header'  => '',
749
+			'admin_page_content' => '',
750
+			'post_body_content'  => '',
751
+			'before_list_table'  => '',
752
+			'after_list_table'   => '',
753
+		);
754
+	}
755
+
756
+
757
+	/**
758
+	 * route_admin_request
759
+	 *
760
+	 * @see    _route_admin_request()
761
+	 * @return exception|void error
762
+	 * @throws InvalidArgumentException
763
+	 * @throws InvalidInterfaceException
764
+	 * @throws InvalidDataTypeException
765
+	 * @throws EE_Error
766
+	 * @throws ReflectionException
767
+	 */
768
+	public function route_admin_request()
769
+	{
770
+		try {
771
+			$this->_route_admin_request();
772
+		} catch (EE_Error $e) {
773
+			$e->get_error();
774
+		}
775
+	}
776
+
777
+
778
+	public function set_wp_page_slug($wp_page_slug)
779
+	{
780
+		$this->_wp_page_slug = $wp_page_slug;
781
+		// if in network admin then we need to append "-network" to the page slug. Why? Because that's how WP rolls...
782
+		if (is_network_admin()) {
783
+			$this->_wp_page_slug .= '-network';
784
+		}
785
+	}
786
+
787
+
788
+	/**
789
+	 * _verify_routes
790
+	 * All this method does is verify the incoming request and make sure that routes exist for it.  We do this early so
791
+	 * we know if we need to drop out.
792
+	 *
793
+	 * @return bool
794
+	 * @throws EE_Error
795
+	 */
796
+	protected function _verify_routes()
797
+	{
798
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
799
+		if (! $this->_current_page && ! defined('DOING_AJAX')) {
800
+			return false;
801
+		}
802
+		$this->_route = false;
803
+		// check that the page_routes array is not empty
804
+		if (empty($this->_page_routes)) {
805
+			// user error msg
806
+			$error_msg = sprintf(
807
+				esc_html__('No page routes have been set for the %s admin page.', 'event_espresso'),
808
+				$this->_admin_page_title
809
+			);
810
+			// developer error msg
811
+			$error_msg .= '||' . $error_msg
812
+						  . esc_html__(
813
+							  ' Make sure the "set_page_routes()" method exists, and is setting the "_page_routes" array properly.',
814
+							  'event_espresso'
815
+						  );
816
+			throw new EE_Error($error_msg);
817
+		}
818
+		// and that the requested page route exists
819
+		if (array_key_exists($this->_req_action, $this->_page_routes)) {
820
+			$this->_route = $this->_page_routes[ $this->_req_action ];
821
+			$this->_route_config = isset($this->_page_config[ $this->_req_action ])
822
+				? $this->_page_config[ $this->_req_action ] : array();
823
+		} else {
824
+			// user error msg
825
+			$error_msg = sprintf(
826
+				esc_html__(
827
+					'The requested page route does not exist for the %s admin page.',
828
+					'event_espresso'
829
+				),
830
+				$this->_admin_page_title
831
+			);
832
+			// developer error msg
833
+			$error_msg .= '||' . $error_msg
834
+						  . sprintf(
835
+							  esc_html__(
836
+								  ' Create a key in the "_page_routes" array named "%s" and set its value to the appropriate method.',
837
+								  'event_espresso'
838
+							  ),
839
+							  $this->_req_action
840
+						  );
841
+			throw new EE_Error($error_msg);
842
+		}
843
+		// and that a default route exists
844
+		if (! array_key_exists('default', $this->_page_routes)) {
845
+			// user error msg
846
+			$error_msg = sprintf(
847
+				esc_html__(
848
+					'A default page route has not been set for the % admin page.',
849
+					'event_espresso'
850
+				),
851
+				$this->_admin_page_title
852
+			);
853
+			// developer error msg
854
+			$error_msg .= '||' . $error_msg
855
+						  . esc_html__(
856
+							  ' Create a key in the "_page_routes" array named "default" and set its value to your default page method.',
857
+							  'event_espresso'
858
+						  );
859
+			throw new EE_Error($error_msg);
860
+		}
861
+		// first lets' catch if the UI request has EVER been set.
862
+		if ($this->_is_UI_request === null) {
863
+			// lets set if this is a UI request or not.
864
+			$this->_is_UI_request = ! isset($this->_req_data['noheader']) || $this->_req_data['noheader'] !== true;
865
+			// wait a minute... we might have a noheader in the route array
866
+			$this->_is_UI_request = is_array($this->_route)
867
+									&& isset($this->_route['noheader'])
868
+									&& $this->_route['noheader'] ? false : $this->_is_UI_request;
869
+		}
870
+		$this->_set_current_labels();
871
+		return true;
872
+	}
873
+
874
+
875
+	/**
876
+	 * this method simply verifies a given route and makes sure its an actual route available for the loaded page
877
+	 *
878
+	 * @param  string $route the route name we're verifying
879
+	 * @return mixed (bool|Exception)      we'll throw an exception if this isn't a valid route.
880
+	 * @throws EE_Error
881
+	 */
882
+	protected function _verify_route($route)
883
+	{
884
+		if (array_key_exists($this->_req_action, $this->_page_routes)) {
885
+			return true;
886
+		}
887
+		// user error msg
888
+		$error_msg = sprintf(
889
+			esc_html__('The given page route does not exist for the %s admin page.', 'event_espresso'),
890
+			$this->_admin_page_title
891
+		);
892
+		// developer error msg
893
+		$error_msg .= '||' . $error_msg
894
+					  . sprintf(
895
+						  esc_html__(
896
+							  ' Check the route you are using in your method (%s) and make sure it matches a route set in your "_page_routes" array property',
897
+							  'event_espresso'
898
+						  ),
899
+						  $route
900
+					  );
901
+		throw new EE_Error($error_msg);
902
+	}
903
+
904
+
905
+	/**
906
+	 * perform nonce verification
907
+	 * This method has be encapsulated here so that any ajax requests that bypass normal routes can verify their nonces
908
+	 * using this method (and save retyping!)
909
+	 *
910
+	 * @param  string $nonce     The nonce sent
911
+	 * @param  string $nonce_ref The nonce reference string (name0)
912
+	 * @return void
913
+	 * @throws EE_Error
914
+	 */
915
+	protected function _verify_nonce($nonce, $nonce_ref)
916
+	{
917
+		// verify nonce against expected value
918
+		if (! wp_verify_nonce($nonce, $nonce_ref)) {
919
+			// these are not the droids you are looking for !!!
920
+			$msg = sprintf(
921
+				esc_html__('%sNonce Fail.%s', 'event_espresso'),
922
+				'<a href="http://www.youtube.com/watch?v=56_S0WeTkzs">',
923
+				'</a>'
924
+			);
925
+			if (WP_DEBUG) {
926
+				$msg .= "\n  "
927
+						. sprintf(
928
+							esc_html__(
929
+								'In order to dynamically generate nonces for your actions, use the %s::add_query_args_and_nonce() method. May the Nonce be with you!',
930
+								'event_espresso'
931
+							),
932
+							__CLASS__
933
+						);
934
+			}
935
+			if (! defined('DOING_AJAX')) {
936
+				wp_die($msg);
937
+			} else {
938
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
939
+				$this->_return_json();
940
+			}
941
+		}
942
+	}
943
+
944
+
945
+	/**
946
+	 * _route_admin_request()
947
+	 * Meat and potatoes of the class.  Basically, this dude checks out what's being requested and sees if theres are
948
+	 * some doodads to work the magic and handle the flingjangy. Translation:  Checks if the requested action is listed
949
+	 * in the page routes and then will try to load the corresponding method.
950
+	 *
951
+	 * @return void
952
+	 * @throws EE_Error
953
+	 * @throws InvalidArgumentException
954
+	 * @throws InvalidDataTypeException
955
+	 * @throws InvalidInterfaceException
956
+	 * @throws ReflectionException
957
+	 */
958
+	protected function _route_admin_request()
959
+	{
960
+		if (! $this->_is_UI_request) {
961
+			$this->_verify_routes();
962
+		}
963
+		$nonce_check = isset($this->_route_config['require_nonce'])
964
+			? $this->_route_config['require_nonce']
965
+			: true;
966
+		if ($this->_req_action !== 'default' && $nonce_check) {
967
+			// set nonce from post data
968
+			$nonce = isset($this->_req_data[ $this->_req_nonce ])
969
+				? sanitize_text_field($this->_req_data[ $this->_req_nonce ])
970
+				: '';
971
+			$this->_verify_nonce($nonce, $this->_req_nonce);
972
+		}
973
+		// set the nav_tabs array but ONLY if this is  UI_request
974
+		if ($this->_is_UI_request) {
975
+			$this->_set_nav_tabs();
976
+		}
977
+		// grab callback function
978
+		$func = is_array($this->_route) ? $this->_route['func'] : $this->_route;
979
+		// check if callback has args
980
+		$args = is_array($this->_route) && isset($this->_route['args']) ? $this->_route['args'] : array();
981
+		$error_msg = '';
982
+		// action right before calling route
983
+		// (hook is something like 'AHEE__Registrations_Admin_Page__route_admin_request')
984
+		if (! did_action('AHEE__EE_Admin_Page__route_admin_request')) {
985
+			do_action('AHEE__EE_Admin_Page__route_admin_request', $this->_current_view, $this);
986
+		}
987
+		// right before calling the route, let's remove _wp_http_referer from the
988
+		// $_SERVER[REQUEST_URI] global (its now in _req_data for route processing).
989
+		$_SERVER['REQUEST_URI'] = remove_query_arg(
990
+			'_wp_http_referer',
991
+			wp_unslash($_SERVER['REQUEST_URI'])
992
+		);
993
+		if (! empty($func)) {
994
+			if (is_array($func)) {
995
+				list($class, $method) = $func;
996
+			} elseif (strpos($func, '::') !== false) {
997
+				list($class, $method) = explode('::', $func);
998
+			} else {
999
+				$class = $this;
1000
+				$method = $func;
1001
+			}
1002
+			if (! (is_object($class) && $class === $this)) {
1003
+				// send along this admin page object for access by addons.
1004
+				$args['admin_page_object'] = $this;
1005
+			}
1006
+			if (// is it a method on a class that doesn't work?
1007
+				(
1008
+					(
1009
+						method_exists($class, $method)
1010
+						&& call_user_func_array(array($class, $method), $args) === false
1011
+					)
1012
+					&& (
1013
+						// is it a standalone function that doesn't work?
1014
+						function_exists($method)
1015
+						&& call_user_func_array(
1016
+							$func,
1017
+							array_merge(array('admin_page_object' => $this), $args)
1018
+						) === false
1019
+					)
1020
+				)
1021
+				|| (
1022
+					// is it neither a class method NOR a standalone function?
1023
+					! method_exists($class, $method)
1024
+					&& ! function_exists($method)
1025
+				)
1026
+			) {
1027
+				// user error msg
1028
+				$error_msg = esc_html__(
1029
+					'An error occurred. The  requested page route could not be found.',
1030
+					'event_espresso'
1031
+				);
1032
+				// developer error msg
1033
+				$error_msg .= '||';
1034
+				$error_msg .= sprintf(
1035
+					esc_html__(
1036
+						'Page route "%s" could not be called. Check that the spelling for method names and actions in the "_page_routes" array are all correct.',
1037
+						'event_espresso'
1038
+					),
1039
+					$method
1040
+				);
1041
+			}
1042
+			if (! empty($error_msg)) {
1043
+				throw new EE_Error($error_msg);
1044
+			}
1045
+		}
1046
+		// if we've routed and this route has a no headers route AND a sent_headers_route,
1047
+		// then we need to reset the routing properties to the new route.
1048
+		// now if UI request is FALSE and noheader is true AND we have a headers_sent_route in the route array then let's set UI_request to true because the no header route has a second func after headers have been sent.
1049
+		if ($this->_is_UI_request === false
1050
+			&& is_array($this->_route)
1051
+			&& ! empty($this->_route['headers_sent_route'])
1052
+		) {
1053
+			$this->_reset_routing_properties($this->_route['headers_sent_route']);
1054
+		}
1055
+	}
1056
+
1057
+
1058
+	/**
1059
+	 * This method just allows the resetting of page properties in the case where a no headers
1060
+	 * route redirects to a headers route in its route config.
1061
+	 *
1062
+	 * @since   4.3.0
1063
+	 * @param  string $new_route New (non header) route to redirect to.
1064
+	 * @return   void
1065
+	 * @throws ReflectionException
1066
+	 * @throws InvalidArgumentException
1067
+	 * @throws InvalidInterfaceException
1068
+	 * @throws InvalidDataTypeException
1069
+	 * @throws EE_Error
1070
+	 */
1071
+	protected function _reset_routing_properties($new_route)
1072
+	{
1073
+		$this->_is_UI_request = true;
1074
+		// now we set the current route to whatever the headers_sent_route is set at
1075
+		$this->_req_data['action'] = $new_route;
1076
+		// rerun page setup
1077
+		$this->_page_setup();
1078
+	}
1079
+
1080
+
1081
+	/**
1082
+	 * _add_query_arg
1083
+	 * adds nonce to array of arguments then calls WP add_query_arg function
1084
+	 *(internally just uses EEH_URL's function with the same name)
1085
+	 *
1086
+	 * @param array  $args
1087
+	 * @param string $url
1088
+	 * @param bool   $sticky                  if true, then the existing Request params will be appended to the
1089
+	 *                                        generated url in an associative array indexed by the key 'wp_referer';
1090
+	 *                                        Example usage: If the current page is:
1091
+	 *                                        http://mydomain.com/wp-admin/admin.php?page=espresso_registrations
1092
+	 *                                        &action=default&event_id=20&month_range=March%202015
1093
+	 *                                        &_wpnonce=5467821
1094
+	 *                                        and you call:
1095
+	 *                                        EE_Admin_Page::add_query_args_and_nonce(
1096
+	 *                                        array(
1097
+	 *                                        'action' => 'resend_something',
1098
+	 *                                        'page=>espresso_registrations'
1099
+	 *                                        ),
1100
+	 *                                        $some_url,
1101
+	 *                                        true
1102
+	 *                                        );
1103
+	 *                                        It will produce a url in this structure:
1104
+	 *                                        http://{$some_url}/?page=espresso_registrations&action=resend_something
1105
+	 *                                        &wp_referer[action]=default&wp_referer[event_id]=20&wpreferer[
1106
+	 *                                        month_range]=March%202015
1107
+	 * @param   bool $exclude_nonce           If true, the the nonce will be excluded from the generated nonce.
1108
+	 * @return string
1109
+	 */
1110
+	public static function add_query_args_and_nonce(
1111
+		$args = array(),
1112
+		$url = false,
1113
+		$sticky = false,
1114
+		$exclude_nonce = false
1115
+	) {
1116
+		// if there is a _wp_http_referer include the values from the request but only if sticky = true
1117
+		if ($sticky) {
1118
+			$request = $_REQUEST;
1119
+			unset($request['_wp_http_referer']);
1120
+			unset($request['wp_referer']);
1121
+			foreach ($request as $key => $value) {
1122
+				// do not add nonces
1123
+				if (strpos($key, 'nonce') !== false) {
1124
+					continue;
1125
+				}
1126
+				$args[ 'wp_referer[' . $key . ']' ] = $value;
1127
+			}
1128
+		}
1129
+		return EEH_URL::add_query_args_and_nonce($args, $url, $exclude_nonce);
1130
+	}
1131
+
1132
+
1133
+	/**
1134
+	 * This returns a generated link that will load the related help tab.
1135
+	 *
1136
+	 * @param  string $help_tab_id the id for the connected help tab
1137
+	 * @param  string $icon_style  (optional) include css class for the style you want to use for the help icon.
1138
+	 * @param  string $help_text   (optional) send help text you want to use for the link if default not to be used
1139
+	 * @uses EEH_Template::get_help_tab_link()
1140
+	 * @return string              generated link
1141
+	 */
1142
+	protected function _get_help_tab_link($help_tab_id, $icon_style = '', $help_text = '')
1143
+	{
1144
+		return EEH_Template::get_help_tab_link(
1145
+			$help_tab_id,
1146
+			$this->page_slug,
1147
+			$this->_req_action,
1148
+			$icon_style,
1149
+			$help_text
1150
+		);
1151
+	}
1152
+
1153
+
1154
+	/**
1155
+	 * _add_help_tabs
1156
+	 * Note child classes define their help tabs within the page_config array.
1157
+	 *
1158
+	 * @link   http://codex.wordpress.org/Function_Reference/add_help_tab
1159
+	 * @return void
1160
+	 * @throws DomainException
1161
+	 * @throws EE_Error
1162
+	 */
1163
+	protected function _add_help_tabs()
1164
+	{
1165
+		$tour_buttons = '';
1166
+		if (isset($this->_page_config[ $this->_req_action ])) {
1167
+			$config = $this->_page_config[ $this->_req_action ];
1168
+			// is there a help tour for the current route?  if there is let's setup the tour buttons
1169
+			if (isset($this->_help_tour[ $this->_req_action ])) {
1170
+				$tb = array();
1171
+				$tour_buttons = '<div class="ee-abs-container"><div class="ee-help-tour-restart-buttons">';
1172
+				foreach ($this->_help_tour['tours'] as $tour) {
1173
+					// if this is the end tour then we don't need to setup a button
1174
+					if ($tour instanceof EE_Help_Tour_final_stop || ! $tour instanceof EE_Help_Tour) {
1175
+						continue;
1176
+					}
1177
+					$tb[] = '<button id="trigger-tour-'
1178
+							. $tour->get_slug()
1179
+							. '" class="button-primary trigger-ee-help-tour">'
1180
+							. $tour->get_label()
1181
+							. '</button>';
1182
+				}
1183
+				$tour_buttons .= implode('<br />', $tb);
1184
+				$tour_buttons .= '</div></div>';
1185
+			}
1186
+			// let's see if there is a help_sidebar set for the current route and we'll set that up for usage as well.
1187
+			if (is_array($config) && isset($config['help_sidebar'])) {
1188
+				// check that the callback given is valid
1189
+				if (! method_exists($this, $config['help_sidebar'])) {
1190
+					throw new EE_Error(
1191
+						sprintf(
1192
+							esc_html__(
1193
+								'The _page_config array has a callback set for the "help_sidebar" option.  However the callback given (%s) is not a valid callback.  Doublecheck the spelling and make sure this method exists for the class %s',
1194
+								'event_espresso'
1195
+							),
1196
+							$config['help_sidebar'],
1197
+							get_class($this)
1198
+						)
1199
+					);
1200
+				}
1201
+				$content = apply_filters(
1202
+					'FHEE__' . get_class($this) . '__add_help_tabs__help_sidebar',
1203
+					$this->{$config['help_sidebar']}()
1204
+				);
1205
+				$content .= $tour_buttons; // add help tour buttons.
1206
+				// do we have any help tours setup?  Cause if we do we want to add the buttons
1207
+				$this->_current_screen->set_help_sidebar($content);
1208
+			}
1209
+			// if we DON'T have config help sidebar and there ARE tour buttons then we'll just add the tour buttons to the sidebar.
1210
+			if (! isset($config['help_sidebar']) && ! empty($tour_buttons)) {
1211
+				$this->_current_screen->set_help_sidebar($tour_buttons);
1212
+			}
1213
+			// handle if no help_tabs are set so the sidebar will still show for the help tour buttons
1214
+			if (! isset($config['help_tabs']) && ! empty($tour_buttons)) {
1215
+				$_ht['id'] = $this->page_slug;
1216
+				$_ht['title'] = esc_html__('Help Tours', 'event_espresso');
1217
+				$_ht['content'] = '<p>'
1218
+								  . esc_html__(
1219
+									  'The buttons to the right allow you to start/restart any help tours available for this page',
1220
+									  'event_espresso'
1221
+								  ) . '</p>';
1222
+				$this->_current_screen->add_help_tab($_ht);
1223
+			}
1224
+			if (! isset($config['help_tabs'])) {
1225
+				return;
1226
+			} //no help tabs for this route
1227
+			foreach ((array) $config['help_tabs'] as $tab_id => $cfg) {
1228
+				// we're here so there ARE help tabs!
1229
+				// make sure we've got what we need
1230
+				if (! isset($cfg['title'])) {
1231
+					throw new EE_Error(
1232
+						esc_html__(
1233
+							'The _page_config array is not set up properly for help tabs.  It is missing a title',
1234
+							'event_espresso'
1235
+						)
1236
+					);
1237
+				}
1238
+				if (! isset($cfg['filename']) && ! isset($cfg['callback']) && ! isset($cfg['content'])) {
1239
+					throw new EE_Error(
1240
+						esc_html__(
1241
+							'The _page_config array is not setup properly for help tabs. It is missing a either a filename reference, or a callback reference or a content reference so there is no way to know the content for the help tab',
1242
+							'event_espresso'
1243
+						)
1244
+					);
1245
+				}
1246
+				// first priority goes to content.
1247
+				if (! empty($cfg['content'])) {
1248
+					$content = ! empty($cfg['content']) ? $cfg['content'] : null;
1249
+					// second priority goes to filename
1250
+				} elseif (! empty($cfg['filename'])) {
1251
+					$file_path = $this->_get_dir() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php';
1252
+					// it's possible that the file is located on decaf route (and above sets up for caf route, if this is the case then lets check decaf route too)
1253
+					$file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1254
+															 . basename($this->_get_dir())
1255
+															 . '/help_tabs/'
1256
+															 . $cfg['filename']
1257
+															 . '.help_tab.php' : $file_path;
1258
+					// if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1259
+					if (! isset($cfg['callback']) && ! is_readable($file_path)) {
1260
+						EE_Error::add_error(
1261
+							sprintf(
1262
+								esc_html__(
1263
+									'The filename given for the help tab %s is not a valid file and there is no other configuration for the tab content.  Please check that the string you set for the help tab on this route (%s) is the correct spelling.  The file should be in %s',
1264
+									'event_espresso'
1265
+								),
1266
+								$tab_id,
1267
+								key($config),
1268
+								$file_path
1269
+							),
1270
+							__FILE__,
1271
+							__FUNCTION__,
1272
+							__LINE__
1273
+						);
1274
+						return;
1275
+					}
1276
+					$template_args['admin_page_obj'] = $this;
1277
+					$content = EEH_Template::display_template(
1278
+						$file_path,
1279
+						$template_args,
1280
+						true
1281
+					);
1282
+				} else {
1283
+					$content = '';
1284
+				}
1285
+				// check if callback is valid
1286
+				if (empty($content) && (
1287
+						! isset($cfg['callback']) || ! method_exists($this, $cfg['callback'])
1288
+					)
1289
+				) {
1290
+					EE_Error::add_error(
1291
+						sprintf(
1292
+							esc_html__(
1293
+								'The callback given for a %s help tab on this page does not content OR a corresponding method for generating the content.  Check the spelling or make sure the method is present.',
1294
+								'event_espresso'
1295
+							),
1296
+							$cfg['title']
1297
+						),
1298
+						__FILE__,
1299
+						__FUNCTION__,
1300
+						__LINE__
1301
+					);
1302
+					return;
1303
+				}
1304
+				// setup config array for help tab method
1305
+				$id = $this->page_slug . '-' . $this->_req_action . '-' . $tab_id;
1306
+				$_ht = array(
1307
+					'id'       => $id,
1308
+					'title'    => $cfg['title'],
1309
+					'callback' => isset($cfg['callback']) && empty($content) ? array($this, $cfg['callback']) : null,
1310
+					'content'  => $content,
1311
+				);
1312
+				$this->_current_screen->add_help_tab($_ht);
1313
+			}
1314
+		}
1315
+	}
1316
+
1317
+
1318
+	/**
1319
+	 * This basically checks loaded $_page_config property to see if there are any help_tours defined.  "help_tours" is
1320
+	 * an array with properties for setting up usage of the joyride plugin
1321
+	 *
1322
+	 * @link   http://zurb.com/playground/jquery-joyride-feature-tour-plugin
1323
+	 * @see    instructions regarding the format and construction of the "help_tour" array element is found in the
1324
+	 *         _set_page_config() comments
1325
+	 * @return void
1326
+	 * @throws EE_Error
1327
+	 * @throws InvalidArgumentException
1328
+	 * @throws InvalidDataTypeException
1329
+	 * @throws InvalidInterfaceException
1330
+	 */
1331
+	protected function _add_help_tour()
1332
+	{
1333
+		$tours = array();
1334
+		$this->_help_tour = array();
1335
+		// exit early if help tours are turned off globally
1336
+		if ((defined('EE_DISABLE_HELP_TOURS') && EE_DISABLE_HELP_TOURS)
1337
+			|| ! EE_Registry::instance()->CFG->admin->help_tour_activation
1338
+		) {
1339
+			return;
1340
+		}
1341
+		// loop through _page_config to find any help_tour defined
1342
+		foreach ($this->_page_config as $route => $config) {
1343
+			// we're only going to set things up for this route
1344
+			if ($route !== $this->_req_action) {
1345
+				continue;
1346
+			}
1347
+			if (isset($config['help_tour'])) {
1348
+				foreach ($config['help_tour'] as $tour) {
1349
+					$file_path = $this->_get_dir() . '/help_tours/' . $tour . '.class.php';
1350
+					// let's see if we can get that file...
1351
+					// if not its possible this is a decaf route not set in caffeinated
1352
+					// so lets try and get the caffeinated equivalent
1353
+					$file_path = ! is_readable($file_path) ? EE_ADMIN_PAGES
1354
+															 . basename($this->_get_dir())
1355
+															 . '/help_tours/'
1356
+															 . $tour
1357
+															 . '.class.php' : $file_path;
1358
+					// if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error.
1359
+					if (! is_readable($file_path)) {
1360
+						EE_Error::add_error(
1361
+							sprintf(
1362
+								esc_html__(
1363
+									'The file path given for the help tour (%s) is not a valid path.  Please check that the string you set for the help tour on this route (%s) is the correct spelling',
1364
+									'event_espresso'
1365
+								),
1366
+								$file_path,
1367
+								$tour
1368
+							),
1369
+							__FILE__,
1370
+							__FUNCTION__,
1371
+							__LINE__
1372
+						);
1373
+						return;
1374
+					}
1375
+					require_once $file_path;
1376
+					if (! class_exists($tour)) {
1377
+						$error_msg[] = sprintf(
1378
+							esc_html__('Something went wrong with loading the %s Help Tour Class.', 'event_espresso'),
1379
+							$tour
1380
+						);
1381
+						$error_msg[] = $error_msg[0] . "\r\n"
1382
+									   . sprintf(
1383
+										   esc_html__(
1384
+											   'There is no class in place for the %s help tour.%s Make sure you have <strong>%s</strong> defined in the "help_tour" array for the %s route of the % admin page.',
1385
+											   'event_espresso'
1386
+										   ),
1387
+										   $tour,
1388
+										   '<br />',
1389
+										   $tour,
1390
+										   $this->_req_action,
1391
+										   get_class($this)
1392
+									   );
1393
+						throw new EE_Error(implode('||', $error_msg));
1394
+					}
1395
+					$tour_obj = new $tour($this->_is_caf);
1396
+					$tours[] = $tour_obj;
1397
+					$this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($tour_obj);
1398
+				}
1399
+				// let's inject the end tour stop element common to all pages... this will only get seen once per machine.
1400
+				$end_stop_tour = new EE_Help_Tour_final_stop($this->_is_caf);
1401
+				$tours[] = $end_stop_tour;
1402
+				$this->_help_tour[ $route ][] = EEH_Template::help_tour_stops_generator($end_stop_tour);
1403
+			}
1404
+		}
1405
+
1406
+		if (! empty($tours)) {
1407
+			$this->_help_tour['tours'] = $tours;
1408
+		}
1409
+		// that's it!  Now that the $_help_tours property is set (or not)
1410
+		// the scripts and html should be taken care of automatically.
1411
+
1412
+		/**
1413
+		 * Allow extending the help tours variable.
1414
+		 *
1415
+		 * @param Array $_help_tour The array containing all help tour information to be displayed.
1416
+		 */
1417
+		$this->_help_tour = apply_filters('FHEE__EE_Admin_Page___add_help_tour___help_tour', $this->_help_tour);
1418
+	}
1419
+
1420
+
1421
+	/**
1422
+	 * This simply sets up any qtips that have been defined in the page config
1423
+	 *
1424
+	 * @return void
1425
+	 */
1426
+	protected function _add_qtips()
1427
+	{
1428
+		if (isset($this->_route_config['qtips'])) {
1429
+			$qtips = (array) $this->_route_config['qtips'];
1430
+			// load qtip loader
1431
+			$path = array(
1432
+				$this->_get_dir() . '/qtips/',
1433
+				EE_ADMIN_PAGES . basename($this->_get_dir()) . '/qtips/',
1434
+			);
1435
+			EEH_Qtip_Loader::instance()->register($qtips, $path);
1436
+		}
1437
+	}
1438
+
1439
+
1440
+	/**
1441
+	 * _set_nav_tabs
1442
+	 * This sets up the nav tabs from the page_routes array.  This method can be overwritten by child classes if you
1443
+	 * wish to add additional tabs or modify accordingly.
1444
+	 *
1445
+	 * @return void
1446
+	 * @throws InvalidArgumentException
1447
+	 * @throws InvalidInterfaceException
1448
+	 * @throws InvalidDataTypeException
1449
+	 */
1450
+	protected function _set_nav_tabs()
1451
+	{
1452
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1453
+		$i = 0;
1454
+		foreach ($this->_page_config as $slug => $config) {
1455
+			if (! is_array($config)
1456
+				|| (
1457
+					is_array($config)
1458
+					&& (
1459
+						(isset($config['nav']) && ! $config['nav'])
1460
+						|| ! isset($config['nav'])
1461
+					)
1462
+				)
1463
+			) {
1464
+				continue;
1465
+			}
1466
+			// no nav tab for this config
1467
+			// check for persistent flag
1468
+			if ($slug !== $this->_req_action && isset($config['nav']['persistent']) && ! $config['nav']['persistent']) {
1469
+				// nav tab is only to appear when route requested.
1470
+				continue;
1471
+			}
1472
+			if (! $this->check_user_access($slug, true)) {
1473
+				// no nav tab because current user does not have access.
1474
+				continue;
1475
+			}
1476
+			$css_class = isset($config['css_class']) ? $config['css_class'] . ' ' : '';
1477
+			$this->_nav_tabs[ $slug ] = array(
1478
+				'url'       => isset($config['nav']['url'])
1479
+					? $config['nav']['url']
1480
+					: self::add_query_args_and_nonce(
1481
+						array('action' => $slug),
1482
+						$this->_admin_base_url
1483
+					),
1484
+				'link_text' => isset($config['nav']['label'])
1485
+					? $config['nav']['label']
1486
+					: ucwords(
1487
+						str_replace('_', ' ', $slug)
1488
+					),
1489
+				'css_class' => $this->_req_action === $slug ? $css_class . 'nav-tab-active' : $css_class,
1490
+				'order'     => isset($config['nav']['order']) ? $config['nav']['order'] : $i,
1491
+			);
1492
+			$i++;
1493
+		}
1494
+		// if $this->_nav_tabs is empty then lets set the default
1495
+		if (empty($this->_nav_tabs)) {
1496
+			$this->_nav_tabs[ $this->_default_nav_tab_name ] = array(
1497
+				'url'       => $this->_admin_base_url,
1498
+				'link_text' => ucwords(str_replace('_', ' ', $this->_default_nav_tab_name)),
1499
+				'css_class' => 'nav-tab-active',
1500
+				'order'     => 10,
1501
+			);
1502
+		}
1503
+		// now let's sort the tabs according to order
1504
+		usort($this->_nav_tabs, array($this, '_sort_nav_tabs'));
1505
+	}
1506
+
1507
+
1508
+	/**
1509
+	 * _set_current_labels
1510
+	 * This method modifies the _labels property with any optional specific labels indicated in the _page_routes
1511
+	 * property array
1512
+	 *
1513
+	 * @return void
1514
+	 */
1515
+	private function _set_current_labels()
1516
+	{
1517
+		if (is_array($this->_route_config) && isset($this->_route_config['labels'])) {
1518
+			foreach ($this->_route_config['labels'] as $label => $text) {
1519
+				if (is_array($text)) {
1520
+					foreach ($text as $sublabel => $subtext) {
1521
+						$this->_labels[ $label ][ $sublabel ] = $subtext;
1522
+					}
1523
+				} else {
1524
+					$this->_labels[ $label ] = $text;
1525
+				}
1526
+			}
1527
+		}
1528
+	}
1529
+
1530
+
1531
+	/**
1532
+	 *        verifies user access for this admin page
1533
+	 *
1534
+	 * @param string $route_to_check if present then the capability for the route matching this string is checked.
1535
+	 * @param bool   $verify_only    Default is FALSE which means if user check fails then wp_die().  Otherwise just
1536
+	 *                               return false if verify fail.
1537
+	 * @return bool
1538
+	 * @throws InvalidArgumentException
1539
+	 * @throws InvalidDataTypeException
1540
+	 * @throws InvalidInterfaceException
1541
+	 */
1542
+	public function check_user_access($route_to_check = '', $verify_only = false)
1543
+	{
1544
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1545
+		$route_to_check = empty($route_to_check) ? $this->_req_action : $route_to_check;
1546
+		$capability = ! empty($route_to_check) && isset($this->_page_routes[ $route_to_check ])
1547
+					  && is_array(
1548
+						  $this->_page_routes[ $route_to_check ]
1549
+					  )
1550
+					  && ! empty($this->_page_routes[ $route_to_check ]['capability'])
1551
+			? $this->_page_routes[ $route_to_check ]['capability'] : null;
1552
+		if (empty($capability) && empty($route_to_check)) {
1553
+			$capability = is_array($this->_route) && empty($this->_route['capability']) ? 'manage_options'
1554
+				: $this->_route['capability'];
1555
+		} else {
1556
+			$capability = empty($capability) ? 'manage_options' : $capability;
1557
+		}
1558
+		$id = is_array($this->_route) && ! empty($this->_route['obj_id']) ? $this->_route['obj_id'] : 0;
1559
+		if (! defined('DOING_AJAX')
1560
+			&& (
1561
+				! function_exists('is_admin')
1562
+				|| ! EE_Registry::instance()->CAP->current_user_can(
1563
+					$capability,
1564
+					$this->page_slug
1565
+					. '_'
1566
+					. $route_to_check,
1567
+					$id
1568
+				)
1569
+			)
1570
+		) {
1571
+			if ($verify_only) {
1572
+				return false;
1573
+			}
1574
+			if (is_user_logged_in()) {
1575
+				wp_die(__('You do not have access to this route.', 'event_espresso'));
1576
+			} else {
1577
+				return false;
1578
+			}
1579
+		}
1580
+		return true;
1581
+	}
1582
+
1583
+
1584
+	/**
1585
+	 * admin_init_global
1586
+	 * This runs all the code that we want executed within the WP admin_init hook.
1587
+	 * This method executes for ALL EE Admin pages.
1588
+	 *
1589
+	 * @return void
1590
+	 */
1591
+	public function admin_init_global()
1592
+	{
1593
+	}
1594
+
1595
+
1596
+	/**
1597
+	 * wp_loaded_global
1598
+	 * This runs all the code that we want executed within the WP wp_loaded hook.  This method is optional for an
1599
+	 * EE_Admin page and will execute on every EE Admin Page load
1600
+	 *
1601
+	 * @return void
1602
+	 */
1603
+	public function wp_loaded()
1604
+	{
1605
+	}
1606
+
1607
+
1608
+	/**
1609
+	 * admin_notices
1610
+	 * Anything triggered by the 'admin_notices' WP hook should be put in here.  This particular method will apply on
1611
+	 * ALL EE_Admin pages.
1612
+	 *
1613
+	 * @return void
1614
+	 */
1615
+	public function admin_notices_global()
1616
+	{
1617
+		$this->_display_no_javascript_warning();
1618
+		$this->_display_espresso_notices();
1619
+	}
1620
+
1621
+
1622
+	public function network_admin_notices_global()
1623
+	{
1624
+		$this->_display_no_javascript_warning();
1625
+		$this->_display_espresso_notices();
1626
+	}
1627
+
1628
+
1629
+	/**
1630
+	 * admin_footer_scripts_global
1631
+	 * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
1632
+	 * will apply on ALL EE_Admin pages.
1633
+	 *
1634
+	 * @return void
1635
+	 */
1636
+	public function admin_footer_scripts_global()
1637
+	{
1638
+		$this->_add_admin_page_ajax_loading_img();
1639
+		$this->_add_admin_page_overlay();
1640
+		// if metaboxes are present we need to add the nonce field
1641
+		if (isset($this->_route_config['metaboxes'])
1642
+			|| isset($this->_route_config['list_table'])
1643
+			|| (isset($this->_route_config['has_metaboxes']) && $this->_route_config['has_metaboxes'])
1644
+		) {
1645
+			wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false);
1646
+			wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false);
1647
+		}
1648
+	}
1649
+
1650
+
1651
+	/**
1652
+	 * admin_footer_global
1653
+	 * Anything triggered by the wp 'admin_footer' wp hook should be put in here. This particular method will apply on
1654
+	 * ALL EE_Admin Pages.
1655
+	 *
1656
+	 * @return void
1657
+	 * @throws EE_Error
1658
+	 */
1659
+	public function admin_footer_global()
1660
+	{
1661
+		// dialog container for dialog helper
1662
+		$d_cont = '<div class="ee-admin-dialog-container auto-hide hidden">' . "\n";
1663
+		$d_cont .= '<div class="ee-notices"></div>';
1664
+		$d_cont .= '<div class="ee-admin-dialog-container-inner-content"></div>';
1665
+		$d_cont .= '</div>';
1666
+		echo $d_cont;
1667
+		// help tour stuff?
1668
+		if (isset($this->_help_tour[ $this->_req_action ])) {
1669
+			echo implode('<br />', $this->_help_tour[ $this->_req_action ]);
1670
+		}
1671
+		// current set timezone for timezone js
1672
+		echo '<span id="current_timezone" class="hidden">' . EEH_DTT_Helper::get_timezone() . '</span>';
1673
+	}
1674
+
1675
+
1676
+	/**
1677
+	 * This function sees if there is a method for help popup content existing for the given route.  If there is then
1678
+	 * we'll use the retrieved array to output the content using the template. For child classes: If you want to have
1679
+	 * help popups then in your templates or your content you set "triggers" for the content using the
1680
+	 * "_set_help_trigger('help_trigger_id')" where "help_trigger_id" is what you will use later in your custom method
1681
+	 * for the help popup content on that page. Then in your Child_Admin_Page class you need to define a help popup
1682
+	 * method for the content in the format "_help_popup_content_{route_name}()"  So if you are setting help content
1683
+	 * for the
1684
+	 * 'edit_event' route you should have a method named "_help_popup_content_edit_route". In your defined
1685
+	 * "help_popup_content_..." method.  You must prepare and return an array in the following format array(
1686
+	 *    'help_trigger_id' => array(
1687
+	 *        'title' => esc_html__('localized title for popup', 'event_espresso'),
1688
+	 *        'content' => esc_html__('localized content for popup', 'event_espresso')
1689
+	 *    )
1690
+	 * );
1691
+	 * Then the EE_Admin_Parent will take care of making sure that is setup properly on the correct route.
1692
+	 *
1693
+	 * @param array $help_array
1694
+	 * @param bool  $display
1695
+	 * @return string content
1696
+	 * @throws DomainException
1697
+	 * @throws EE_Error
1698
+	 */
1699
+	protected function _set_help_popup_content($help_array = array(), $display = false)
1700
+	{
1701
+		$content = '';
1702
+		$help_array = empty($help_array) ? $this->_get_help_content() : $help_array;
1703
+		// loop through the array and setup content
1704
+		foreach ($help_array as $trigger => $help) {
1705
+			// make sure the array is setup properly
1706
+			if (! isset($help['title']) || ! isset($help['content'])) {
1707
+				throw new EE_Error(
1708
+					esc_html__(
1709
+						'Does not look like the popup content array has been setup correctly.  Might want to double check that.  Read the comments for the _get_help_popup_content method found in "EE_Admin_Page" class',
1710
+						'event_espresso'
1711
+					)
1712
+				);
1713
+			}
1714
+			// we're good so let'd setup the template vars and then assign parsed template content to our content.
1715
+			$template_args = array(
1716
+				'help_popup_id'      => $trigger,
1717
+				'help_popup_title'   => $help['title'],
1718
+				'help_popup_content' => $help['content'],
1719
+			);
1720
+			$content .= EEH_Template::display_template(
1721
+				EE_ADMIN_TEMPLATE . 'admin_help_popup.template.php',
1722
+				$template_args,
1723
+				true
1724
+			);
1725
+		}
1726
+		if ($display) {
1727
+			echo $content;
1728
+			return '';
1729
+		}
1730
+		return $content;
1731
+	}
1732
+
1733
+
1734
+	/**
1735
+	 * All this does is retrieve the help content array if set by the EE_Admin_Page child
1736
+	 *
1737
+	 * @return array properly formatted array for help popup content
1738
+	 * @throws EE_Error
1739
+	 */
1740
+	private function _get_help_content()
1741
+	{
1742
+		// what is the method we're looking for?
1743
+		$method_name = '_help_popup_content_' . $this->_req_action;
1744
+		// if method doesn't exist let's get out.
1745
+		if (! method_exists($this, $method_name)) {
1746
+			return array();
1747
+		}
1748
+		// k we're good to go let's retrieve the help array
1749
+		$help_array = call_user_func(array($this, $method_name));
1750
+		// make sure we've got an array!
1751
+		if (! is_array($help_array)) {
1752
+			throw new EE_Error(
1753
+				esc_html__(
1754
+					'Something went wrong with help popup content generation. Expecting an array and well, this ain\'t no array bub.',
1755
+					'event_espresso'
1756
+				)
1757
+			);
1758
+		}
1759
+		return $help_array;
1760
+	}
1761
+
1762
+
1763
+	/**
1764
+	 * EE Admin Pages can use this to set a properly formatted trigger for a help popup.
1765
+	 * By default the trigger html is printed.  Otherwise it can be returned if the $display flag is set "false"
1766
+	 * See comments made on the _set_help_content method for understanding other parts to the help popup tool.
1767
+	 *
1768
+	 * @param string  $trigger_id reference for retrieving the trigger content for the popup
1769
+	 * @param boolean $display    if false then we return the trigger string
1770
+	 * @param array   $dimensions an array of dimensions for the box (array(h,w))
1771
+	 * @return string
1772
+	 * @throws DomainException
1773
+	 * @throws EE_Error
1774
+	 */
1775
+	protected function _set_help_trigger($trigger_id, $display = true, $dimensions = array('400', '640'))
1776
+	{
1777
+		if (defined('DOING_AJAX')) {
1778
+			return '';
1779
+		}
1780
+		// let's check and see if there is any content set for this popup.  If there isn't then we'll include a default title and content so that developers know something needs to be corrected
1781
+		$help_array = $this->_get_help_content();
1782
+		$help_content = '';
1783
+		if (empty($help_array) || ! isset($help_array[ $trigger_id ])) {
1784
+			$help_array[ $trigger_id ] = array(
1785
+				'title'   => esc_html__('Missing Content', 'event_espresso'),
1786
+				'content' => esc_html__(
1787
+					'A trigger has been set that doesn\'t have any corresponding content. Make sure you have set the help content. (see the "_set_help_popup_content" method in the EE_Admin_Page for instructions.)',
1788
+					'event_espresso'
1789
+				),
1790
+			);
1791
+			$help_content = $this->_set_help_popup_content($help_array, false);
1792
+		}
1793
+		// let's setup the trigger
1794
+		$content = '<a class="ee-dialog" href="?height='
1795
+				   . $dimensions[0]
1796
+				   . '&width='
1797
+				   . $dimensions[1]
1798
+				   . '&inlineId='
1799
+				   . $trigger_id
1800
+				   . '" target="_blank"><span class="question ee-help-popup-question"></span></a>';
1801
+		$content .= $help_content;
1802
+		if ($display) {
1803
+			echo $content;
1804
+			return '';
1805
+		}
1806
+		return $content;
1807
+	}
1808
+
1809
+
1810
+	/**
1811
+	 * _add_global_screen_options
1812
+	 * Add any extra wp_screen_options within this method using built-in WP functions/methods for doing so.
1813
+	 * This particular method will add_screen_options on ALL EE_Admin Pages
1814
+	 *
1815
+	 * @link   http://chrismarslender.com/wp-tutorials/wordpress-screen-options-tutorial/
1816
+	 *         see also WP_Screen object documents...
1817
+	 * @link   http://codex.wordpress.org/Class_Reference/WP_Screen
1818
+	 * @abstract
1819
+	 * @return void
1820
+	 */
1821
+	private function _add_global_screen_options()
1822
+	{
1823
+	}
1824
+
1825
+
1826
+	/**
1827
+	 * _add_global_feature_pointers
1828
+	 * This method is used for implementing any "feature pointers" (using built-in WP styling js).
1829
+	 * This particular method will implement feature pointers for ALL EE_Admin pages.
1830
+	 * Note: this is just a placeholder for now.  Implementation will come down the road
1831
+	 *
1832
+	 * @see    WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be
1833
+	 *         extended) also see:
1834
+	 * @link   http://eamann.com/tech/wordpress-portland/
1835
+	 * @abstract
1836
+	 * @return void
1837
+	 */
1838
+	private function _add_global_feature_pointers()
1839
+	{
1840
+	}
1841
+
1842
+
1843
+	/**
1844
+	 * load_global_scripts_styles
1845
+	 * The scripts and styles enqueued in here will be loaded on every EE Admin page
1846
+	 *
1847
+	 * @return void
1848
+	 * @throws EE_Error
1849
+	 */
1850
+	public function load_global_scripts_styles()
1851
+	{
1852
+		/** STYLES **/
1853
+		// add debugging styles
1854
+		if (WP_DEBUG) {
1855
+			add_action('admin_head', array($this, 'add_xdebug_style'));
1856
+		}
1857
+		// register all styles
1858
+		wp_register_style(
1859
+			'espresso-ui-theme',
1860
+			EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1861
+			array(),
1862
+			EVENT_ESPRESSO_VERSION
1863
+		);
1864
+		wp_register_style('ee-admin-css', EE_ADMIN_URL . 'assets/ee-admin-page.css', array(), EVENT_ESPRESSO_VERSION);
1865
+		// helpers styles
1866
+		wp_register_style(
1867
+			'ee-text-links',
1868
+			EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.css',
1869
+			array(),
1870
+			EVENT_ESPRESSO_VERSION
1871
+		);
1872
+		/** SCRIPTS **/
1873
+		// register all scripts
1874
+		wp_register_script(
1875
+			'ee-dialog',
1876
+			EE_ADMIN_URL . 'assets/ee-dialog-helper.js',
1877
+			array('jquery', 'jquery-ui-draggable'),
1878
+			EVENT_ESPRESSO_VERSION,
1879
+			true
1880
+		);
1881
+		wp_register_script(
1882
+			'ee_admin_js',
1883
+			EE_ADMIN_URL . 'assets/ee-admin-page.js',
1884
+			array('espresso_core', 'ee-parse-uri', 'ee-dialog'),
1885
+			EVENT_ESPRESSO_VERSION,
1886
+			true
1887
+		);
1888
+		wp_register_script(
1889
+			'jquery-ui-timepicker-addon',
1890
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery-ui-timepicker-addon.js',
1891
+			array('jquery-ui-datepicker', 'jquery-ui-slider'),
1892
+			EVENT_ESPRESSO_VERSION,
1893
+			true
1894
+		);
1895
+		if (EE_Registry::instance()->CFG->admin->help_tour_activation) {
1896
+			add_filter('FHEE_load_joyride', '__return_true');
1897
+		}
1898
+		// script for sorting tables
1899
+		wp_register_script(
1900
+			'espresso_ajax_table_sorting',
1901
+			EE_ADMIN_URL . 'assets/espresso_ajax_table_sorting.js',
1902
+			array('ee_admin_js', 'jquery-ui-sortable'),
1903
+			EVENT_ESPRESSO_VERSION,
1904
+			true
1905
+		);
1906
+		// script for parsing uri's
1907
+		wp_register_script(
1908
+			'ee-parse-uri',
1909
+			EE_GLOBAL_ASSETS_URL . 'scripts/parseuri.js',
1910
+			array(),
1911
+			EVENT_ESPRESSO_VERSION,
1912
+			true
1913
+		);
1914
+		// and parsing associative serialized form elements
1915
+		wp_register_script(
1916
+			'ee-serialize-full-array',
1917
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.serializefullarray.js',
1918
+			array('jquery'),
1919
+			EVENT_ESPRESSO_VERSION,
1920
+			true
1921
+		);
1922
+		// helpers scripts
1923
+		wp_register_script(
1924
+			'ee-text-links',
1925
+			EE_PLUGIN_DIR_URL . 'core/helpers/assets/ee_text_list_helper.js',
1926
+			array('jquery'),
1927
+			EVENT_ESPRESSO_VERSION,
1928
+			true
1929
+		);
1930
+		wp_register_script(
1931
+			'ee-moment-core',
1932
+			EE_THIRD_PARTY_URL . 'moment/moment-with-locales.min.js',
1933
+			array(),
1934
+			EVENT_ESPRESSO_VERSION,
1935
+			true
1936
+		);
1937
+		wp_register_script(
1938
+			'ee-moment',
1939
+			EE_THIRD_PARTY_URL . 'moment/moment-timezone-with-data.min.js',
1940
+			array('ee-moment-core'),
1941
+			EVENT_ESPRESSO_VERSION,
1942
+			true
1943
+		);
1944
+		wp_register_script(
1945
+			'ee-datepicker',
1946
+			EE_ADMIN_URL . 'assets/ee-datepicker.js',
1947
+			array('jquery-ui-timepicker-addon', 'ee-moment'),
1948
+			EVENT_ESPRESSO_VERSION,
1949
+			true
1950
+		);
1951
+		// google charts
1952
+		wp_register_script(
1953
+			'google-charts',
1954
+			'https://www.gstatic.com/charts/loader.js',
1955
+			array(),
1956
+			EVENT_ESPRESSO_VERSION,
1957
+			false
1958
+		);
1959
+		// ENQUEUE ALL BASICS BY DEFAULT
1960
+		wp_enqueue_style('ee-admin-css');
1961
+		wp_enqueue_script('ee_admin_js');
1962
+		wp_enqueue_script('ee-accounting');
1963
+		wp_enqueue_script('jquery-validate');
1964
+		// taking care of metaboxes
1965
+		if (empty($this->_cpt_route)
1966
+			&& (isset($this->_route_config['metaboxes']) || isset($this->_route_config['has_metaboxes']))
1967
+		) {
1968
+			wp_enqueue_script('dashboard');
1969
+		}
1970
+		// LOCALIZED DATA
1971
+		// localize script for ajax lazy loading
1972
+		$lazy_loader_container_ids = apply_filters(
1973
+			'FHEE__EE_Admin_Page_Core__load_global_scripts_styles__loader_containers',
1974
+			array('espresso_news_post_box_content')
1975
+		);
1976
+		wp_localize_script('ee_admin_js', 'eeLazyLoadingContainers', $lazy_loader_container_ids);
1977
+		/**
1978
+		 * help tour stuff
1979
+		 */
1980
+		if (! empty($this->_help_tour)) {
1981
+			// register the js for kicking things off
1982
+			wp_enqueue_script(
1983
+				'ee-help-tour',
1984
+				EE_ADMIN_URL . 'assets/ee-help-tour.js',
1985
+				array('jquery-joyride'),
1986
+				EVENT_ESPRESSO_VERSION,
1987
+				true
1988
+			);
1989
+			$tours = array();
1990
+			// setup tours for the js tour object
1991
+			foreach ($this->_help_tour['tours'] as $tour) {
1992
+				if ($tour instanceof EE_Help_Tour) {
1993
+					$tours[] = array(
1994
+						'id'      => $tour->get_slug(),
1995
+						'options' => $tour->get_options(),
1996
+					);
1997
+				}
1998
+			}
1999
+			wp_localize_script('ee-help-tour', 'EE_HELP_TOUR', array('tours' => $tours));
2000
+			// admin_footer_global will take care of making sure our help_tour skeleton gets printed via the info stored in $this->_help_tour
2001
+		}
2002
+	}
2003
+
2004
+
2005
+	/**
2006
+	 *        admin_footer_scripts_eei18n_js_strings
2007
+	 *
2008
+	 * @return        void
2009
+	 */
2010
+	public function admin_footer_scripts_eei18n_js_strings()
2011
+	{
2012
+		EE_Registry::$i18n_js_strings['ajax_url'] = WP_AJAX_URL;
2013
+		EE_Registry::$i18n_js_strings['confirm_delete'] = wp_strip_all_tags(
2014
+			__(
2015
+				'Are you absolutely sure you want to delete this item?\nThis action will delete ALL DATA associated with this item!!!\nThis can NOT be undone!!!',
2016
+				'event_espresso'
2017
+			)
2018
+		);
2019
+		EE_Registry::$i18n_js_strings['January'] = wp_strip_all_tags(__('January', 'event_espresso'));
2020
+		EE_Registry::$i18n_js_strings['February'] = wp_strip_all_tags(__('February', 'event_espresso'));
2021
+		EE_Registry::$i18n_js_strings['March'] = wp_strip_all_tags(__('March', 'event_espresso'));
2022
+		EE_Registry::$i18n_js_strings['April'] = wp_strip_all_tags(__('April', 'event_espresso'));
2023
+		EE_Registry::$i18n_js_strings['May'] = wp_strip_all_tags(__('May', 'event_espresso'));
2024
+		EE_Registry::$i18n_js_strings['June'] = wp_strip_all_tags(__('June', 'event_espresso'));
2025
+		EE_Registry::$i18n_js_strings['July'] = wp_strip_all_tags(__('July', 'event_espresso'));
2026
+		EE_Registry::$i18n_js_strings['August'] = wp_strip_all_tags(__('August', 'event_espresso'));
2027
+		EE_Registry::$i18n_js_strings['September'] = wp_strip_all_tags(__('September', 'event_espresso'));
2028
+		EE_Registry::$i18n_js_strings['October'] = wp_strip_all_tags(__('October', 'event_espresso'));
2029
+		EE_Registry::$i18n_js_strings['November'] = wp_strip_all_tags(__('November', 'event_espresso'));
2030
+		EE_Registry::$i18n_js_strings['December'] = wp_strip_all_tags(__('December', 'event_espresso'));
2031
+		EE_Registry::$i18n_js_strings['Jan'] = wp_strip_all_tags(__('Jan', 'event_espresso'));
2032
+		EE_Registry::$i18n_js_strings['Feb'] = wp_strip_all_tags(__('Feb', 'event_espresso'));
2033
+		EE_Registry::$i18n_js_strings['Mar'] = wp_strip_all_tags(__('Mar', 'event_espresso'));
2034
+		EE_Registry::$i18n_js_strings['Apr'] = wp_strip_all_tags(__('Apr', 'event_espresso'));
2035
+		EE_Registry::$i18n_js_strings['May'] = wp_strip_all_tags(__('May', 'event_espresso'));
2036
+		EE_Registry::$i18n_js_strings['Jun'] = wp_strip_all_tags(__('Jun', 'event_espresso'));
2037
+		EE_Registry::$i18n_js_strings['Jul'] = wp_strip_all_tags(__('Jul', 'event_espresso'));
2038
+		EE_Registry::$i18n_js_strings['Aug'] = wp_strip_all_tags(__('Aug', 'event_espresso'));
2039
+		EE_Registry::$i18n_js_strings['Sep'] = wp_strip_all_tags(__('Sep', 'event_espresso'));
2040
+		EE_Registry::$i18n_js_strings['Oct'] = wp_strip_all_tags(__('Oct', 'event_espresso'));
2041
+		EE_Registry::$i18n_js_strings['Nov'] = wp_strip_all_tags(__('Nov', 'event_espresso'));
2042
+		EE_Registry::$i18n_js_strings['Dec'] = wp_strip_all_tags(__('Dec', 'event_espresso'));
2043
+		EE_Registry::$i18n_js_strings['Sunday'] = wp_strip_all_tags(__('Sunday', 'event_espresso'));
2044
+		EE_Registry::$i18n_js_strings['Monday'] = wp_strip_all_tags(__('Monday', 'event_espresso'));
2045
+		EE_Registry::$i18n_js_strings['Tuesday'] = wp_strip_all_tags(__('Tuesday', 'event_espresso'));
2046
+		EE_Registry::$i18n_js_strings['Wednesday'] = wp_strip_all_tags(__('Wednesday', 'event_espresso'));
2047
+		EE_Registry::$i18n_js_strings['Thursday'] = wp_strip_all_tags(__('Thursday', 'event_espresso'));
2048
+		EE_Registry::$i18n_js_strings['Friday'] = wp_strip_all_tags(__('Friday', 'event_espresso'));
2049
+		EE_Registry::$i18n_js_strings['Saturday'] = wp_strip_all_tags(__('Saturday', 'event_espresso'));
2050
+		EE_Registry::$i18n_js_strings['Sun'] = wp_strip_all_tags(__('Sun', 'event_espresso'));
2051
+		EE_Registry::$i18n_js_strings['Mon'] = wp_strip_all_tags(__('Mon', 'event_espresso'));
2052
+		EE_Registry::$i18n_js_strings['Tue'] = wp_strip_all_tags(__('Tue', 'event_espresso'));
2053
+		EE_Registry::$i18n_js_strings['Wed'] = wp_strip_all_tags(__('Wed', 'event_espresso'));
2054
+		EE_Registry::$i18n_js_strings['Thu'] = wp_strip_all_tags(__('Thu', 'event_espresso'));
2055
+		EE_Registry::$i18n_js_strings['Fri'] = wp_strip_all_tags(__('Fri', 'event_espresso'));
2056
+		EE_Registry::$i18n_js_strings['Sat'] = wp_strip_all_tags(__('Sat', 'event_espresso'));
2057
+	}
2058
+
2059
+
2060
+	/**
2061
+	 *        load enhanced xdebug styles for ppl with failing eyesight
2062
+	 *
2063
+	 * @return        void
2064
+	 */
2065
+	public function add_xdebug_style()
2066
+	{
2067
+		echo '<style>.xdebug-error { font-size:1.5em; }</style>';
2068
+	}
2069
+
2070
+
2071
+	/************************/
2072
+	/** LIST TABLE METHODS **/
2073
+	/************************/
2074
+	/**
2075
+	 * this sets up the list table if the current view requires it.
2076
+	 *
2077
+	 * @return void
2078
+	 * @throws EE_Error
2079
+	 */
2080
+	protected function _set_list_table()
2081
+	{
2082
+		// first is this a list_table view?
2083
+		if (! isset($this->_route_config['list_table'])) {
2084
+			return;
2085
+		} //not a list_table view so get out.
2086
+		// list table functions are per view specific (because some admin pages might have more than one list table!)
2087
+		$list_table_view = '_set_list_table_views_' . $this->_req_action;
2088
+		if (! method_exists($this, $list_table_view) || $this->{$list_table_view}() === false) {
2089
+			// user error msg
2090
+			$error_msg = esc_html__(
2091
+				'An error occurred. The requested list table views could not be found.',
2092
+				'event_espresso'
2093
+			);
2094
+			// developer error msg
2095
+			$error_msg .= '||'
2096
+						  . sprintf(
2097
+							  esc_html__(
2098
+								  'List table views for "%s" route could not be setup. Check that you have the corresponding method, "%s" set up for defining list_table_views for this route.',
2099
+								  'event_espresso'
2100
+							  ),
2101
+							  $this->_req_action,
2102
+							  $list_table_view
2103
+						  );
2104
+			throw new EE_Error($error_msg);
2105
+		}
2106
+		// let's provide the ability to filter the views per PAGE AND ROUTE, per PAGE, and globally
2107
+		$this->_views = apply_filters(
2108
+			'FHEE_list_table_views_' . $this->page_slug . '_' . $this->_req_action,
2109
+			$this->_views
2110
+		);
2111
+		$this->_views = apply_filters('FHEE_list_table_views_' . $this->page_slug, $this->_views);
2112
+		$this->_views = apply_filters('FHEE_list_table_views', $this->_views);
2113
+		$this->_set_list_table_view();
2114
+		$this->_set_list_table_object();
2115
+	}
2116
+
2117
+
2118
+	/**
2119
+	 * set current view for List Table
2120
+	 *
2121
+	 * @return void
2122
+	 */
2123
+	protected function _set_list_table_view()
2124
+	{
2125
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2126
+		// looking at active items or dumpster diving ?
2127
+		if (! isset($this->_req_data['status']) || ! array_key_exists($this->_req_data['status'], $this->_views)) {
2128
+			$this->_view = isset($this->_views['in_use']) ? 'in_use' : 'all';
2129
+		} else {
2130
+			$this->_view = sanitize_key($this->_req_data['status']);
2131
+		}
2132
+	}
2133
+
2134
+
2135
+	/**
2136
+	 * _set_list_table_object
2137
+	 * WP_List_Table objects need to be loaded fairly early so automatic stuff WP does is taken care of.
2138
+	 *
2139
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2140
+	 * @throws \InvalidArgumentException
2141
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2142
+	 * @throws EE_Error
2143
+	 * @throws InvalidInterfaceException
2144
+	 */
2145
+	protected function _set_list_table_object()
2146
+	{
2147
+		if (isset($this->_route_config['list_table'])) {
2148
+			if (! class_exists($this->_route_config['list_table'])) {
2149
+				throw new EE_Error(
2150
+					sprintf(
2151
+						esc_html__(
2152
+							'The %s class defined for the list table does not exist.  Please check the spelling of the class ref in the $_page_config property on %s.',
2153
+							'event_espresso'
2154
+						),
2155
+						$this->_route_config['list_table'],
2156
+						get_class($this)
2157
+					)
2158
+				);
2159
+			}
2160
+			$this->_list_table_object = $this->loader->getShared(
2161
+				$this->_route_config['list_table'],
2162
+				array($this)
2163
+			);
2164
+		}
2165
+	}
2166
+
2167
+
2168
+	/**
2169
+	 * get_list_table_view_RLs - get it? View RL ?? VU-RL???  URL ??
2170
+	 *
2171
+	 * @param array $extra_query_args                     Optional. An array of extra query args to add to the generated
2172
+	 *                                                    urls.  The array should be indexed by the view it is being
2173
+	 *                                                    added to.
2174
+	 * @return array
2175
+	 */
2176
+	public function get_list_table_view_RLs($extra_query_args = array())
2177
+	{
2178
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2179
+		if (empty($this->_views)) {
2180
+			$this->_views = array();
2181
+		}
2182
+		// cycle thru views
2183
+		foreach ($this->_views as $key => $view) {
2184
+			$query_args = array();
2185
+			// check for current view
2186
+			$this->_views[ $key ]['class'] = $this->_view === $view['slug'] ? 'current' : '';
2187
+			$query_args['action'] = $this->_req_action;
2188
+			$query_args[ $this->_req_action . '_nonce' ] = wp_create_nonce($query_args['action'] . '_nonce');
2189
+			$query_args['status'] = $view['slug'];
2190
+			// merge any other arguments sent in.
2191
+			if (isset($extra_query_args[ $view['slug'] ])) {
2192
+				$query_args = array_merge($query_args, $extra_query_args[ $view['slug'] ]);
2193
+			}
2194
+			$this->_views[ $key ]['url'] = EE_Admin_Page::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2195
+		}
2196
+		return $this->_views;
2197
+	}
2198
+
2199
+
2200
+	/**
2201
+	 * _entries_per_page_dropdown
2202
+	 * generates a drop down box for selecting the number of visible rows in an admin page list table
2203
+	 *
2204
+	 * @todo   : Note: ideally this should be added to the screen options dropdown as that would be consistent with how
2205
+	 *         WP does it.
2206
+	 * @param int $max_entries total number of rows in the table
2207
+	 * @return string
2208
+	 */
2209
+	protected function _entries_per_page_dropdown($max_entries = 0)
2210
+	{
2211
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2212
+		$values = array(10, 25, 50, 100);
2213
+		$per_page = (! empty($this->_req_data['per_page'])) ? absint($this->_req_data['per_page']) : 10;
2214
+		if ($max_entries) {
2215
+			$values[] = $max_entries;
2216
+			sort($values);
2217
+		}
2218
+		$entries_per_page_dropdown = '
2219 2219
 			<div id="entries-per-page-dv" class="alignleft actions">
2220 2220
 				<label class="hide-if-no-js">
2221 2221
 					Show
2222 2222
 					<select id="entries-per-page-slct" name="entries-per-page-slct">';
2223
-        foreach ($values as $value) {
2224
-            if ($value < $max_entries) {
2225
-                $selected = $value === $per_page ? ' selected="' . $per_page . '"' : '';
2226
-                $entries_per_page_dropdown .= '
2223
+		foreach ($values as $value) {
2224
+			if ($value < $max_entries) {
2225
+				$selected = $value === $per_page ? ' selected="' . $per_page . '"' : '';
2226
+				$entries_per_page_dropdown .= '
2227 2227
 						<option value="' . $value . '"' . $selected . '>' . $value . '&nbsp;&nbsp;</option>';
2228
-            }
2229
-        }
2230
-        $selected = $max_entries === $per_page ? ' selected="' . $per_page . '"' : '';
2231
-        $entries_per_page_dropdown .= '
2228
+			}
2229
+		}
2230
+		$selected = $max_entries === $per_page ? ' selected="' . $per_page . '"' : '';
2231
+		$entries_per_page_dropdown .= '
2232 2232
 						<option value="' . $max_entries . '"' . $selected . '>All&nbsp;&nbsp;</option>';
2233
-        $entries_per_page_dropdown .= '
2233
+		$entries_per_page_dropdown .= '
2234 2234
 					</select>
2235 2235
 					entries
2236 2236
 				</label>
2237 2237
 				<input id="entries-per-page-btn" class="button-secondary" type="submit" value="Go" >
2238 2238
 			</div>
2239 2239
 		';
2240
-        return $entries_per_page_dropdown;
2241
-    }
2242
-
2243
-
2244
-    /**
2245
-     *        _set_search_attributes
2246
-     *
2247
-     * @return        void
2248
-     */
2249
-    public function _set_search_attributes()
2250
-    {
2251
-        $this->_template_args['search']['btn_label'] = sprintf(
2252
-            esc_html__('Search %s', 'event_espresso'),
2253
-            empty($this->_search_btn_label) ? $this->page_label
2254
-                : $this->_search_btn_label
2255
-        );
2256
-        $this->_template_args['search']['callback'] = 'search_' . $this->page_slug;
2257
-    }
2258
-
2259
-
2260
-
2261
-    /*** END LIST TABLE METHODS **/
2262
-
2263
-
2264
-    /**
2265
-     * _add_registered_metaboxes
2266
-     *  this loads any registered metaboxes via the 'metaboxes' index in the _page_config property array.
2267
-     *
2268
-     * @link   http://codex.wordpress.org/Function_Reference/add_meta_box
2269
-     * @return void
2270
-     * @throws EE_Error
2271
-     */
2272
-    private function _add_registered_meta_boxes()
2273
-    {
2274
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2275
-        // we only add meta boxes if the page_route calls for it
2276
-        if (is_array($this->_route_config) && isset($this->_route_config['metaboxes'])
2277
-            && is_array(
2278
-                $this->_route_config['metaboxes']
2279
-            )
2280
-        ) {
2281
-            // this simply loops through the callbacks provided
2282
-            // and checks if there is a corresponding callback registered by the child
2283
-            // if there is then we go ahead and process the metabox loader.
2284
-            foreach ($this->_route_config['metaboxes'] as $metabox_callback) {
2285
-                // first check for Closures
2286
-                if ($metabox_callback instanceof Closure) {
2287
-                    $result = $metabox_callback();
2288
-                } elseif (is_array($metabox_callback) && isset($metabox_callback[0], $metabox_callback[1])) {
2289
-                    $result = call_user_func(array($metabox_callback[0], $metabox_callback[1]));
2290
-                } else {
2291
-                    $result = call_user_func(array($this, &$metabox_callback));
2292
-                }
2293
-                if ($result === false) {
2294
-                    // user error msg
2295
-                    $error_msg = esc_html__(
2296
-                        'An error occurred. The  requested metabox could not be found.',
2297
-                        'event_espresso'
2298
-                    );
2299
-                    // developer error msg
2300
-                    $error_msg .= '||'
2301
-                                  . sprintf(
2302
-                                      esc_html__(
2303
-                                          'The metabox with the string "%s" could not be called. Check that the spelling for method names and actions in the "_page_config[\'metaboxes\']" array are all correct.',
2304
-                                          'event_espresso'
2305
-                                      ),
2306
-                                      $metabox_callback
2307
-                                  );
2308
-                    throw new EE_Error($error_msg);
2309
-                }
2310
-            }
2311
-        }
2312
-    }
2313
-
2314
-
2315
-    /**
2316
-     * _add_screen_columns
2317
-     * This will check the _page_config array and if there is "columns" key index indicated, we'll set the template as
2318
-     * the dynamic column template and we'll setup the column options for the page.
2319
-     *
2320
-     * @return void
2321
-     */
2322
-    private function _add_screen_columns()
2323
-    {
2324
-        if (is_array($this->_route_config)
2325
-            && isset($this->_route_config['columns'])
2326
-            && is_array($this->_route_config['columns'])
2327
-            && count($this->_route_config['columns']) === 2
2328
-        ) {
2329
-            add_screen_option(
2330
-                'layout_columns',
2331
-                array(
2332
-                    'max'     => (int) $this->_route_config['columns'][0],
2333
-                    'default' => (int) $this->_route_config['columns'][1],
2334
-                )
2335
-            );
2336
-            $this->_template_args['num_columns'] = $this->_route_config['columns'][0];
2337
-            $screen_id = $this->_current_screen->id;
2338
-            $screen_columns = (int) get_user_option("screen_layout_{$screen_id}");
2339
-            $total_columns = ! empty($screen_columns)
2340
-                ? $screen_columns
2341
-                : $this->_route_config['columns'][1];
2342
-            $this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns;
2343
-            $this->_template_args['current_page'] = $this->_wp_page_slug;
2344
-            $this->_template_args['screen'] = $this->_current_screen;
2345
-            $this->_column_template_path = EE_ADMIN_TEMPLATE
2346
-                                           . 'admin_details_metabox_column_wrapper.template.php';
2347
-            // finally if we don't have has_metaboxes set in the route config
2348
-            // let's make sure it IS set other wise the necessary hidden fields for this won't be loaded.
2349
-            $this->_route_config['has_metaboxes'] = true;
2350
-        }
2351
-    }
2352
-
2353
-
2354
-
2355
-    /** GLOBALLY AVAILABLE METABOXES **/
2356
-
2357
-
2358
-    /**
2359
-     * In this section we put any globally available EE metaboxes for all EE Admin pages.  They are called by simply
2360
-     * referencing the callback in the _page_config array property.  This way you can be very specific about what pages
2361
-     * these get loaded on.
2362
-     */
2363
-    private function _espresso_news_post_box()
2364
-    {
2365
-        $news_box_title = apply_filters(
2366
-            'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2367
-            esc_html__('New @ Event Espresso', 'event_espresso')
2368
-        );
2369
-        add_meta_box(
2370
-            'espresso_news_post_box',
2371
-            $news_box_title,
2372
-            array(
2373
-                $this,
2374
-                'espresso_news_post_box',
2375
-            ),
2376
-            $this->_wp_page_slug,
2377
-            'side'
2378
-        );
2379
-    }
2380
-
2381
-
2382
-    /**
2383
-     * Code for setting up espresso ratings request metabox.
2384
-     */
2385
-    protected function _espresso_ratings_request()
2386
-    {
2387
-        if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2388
-            return;
2389
-        }
2390
-        $ratings_box_title = apply_filters(
2391
-            'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2392
-            esc_html__('Keep Event Espresso Decaf Free', 'event_espresso')
2393
-        );
2394
-        add_meta_box(
2395
-            'espresso_ratings_request',
2396
-            $ratings_box_title,
2397
-            array(
2398
-                $this,
2399
-                'espresso_ratings_request',
2400
-            ),
2401
-            $this->_wp_page_slug,
2402
-            'side'
2403
-        );
2404
-    }
2405
-
2406
-
2407
-    /**
2408
-     * Code for setting up espresso ratings request metabox content.
2409
-     *
2410
-     * @throws DomainException
2411
-     */
2412
-    public function espresso_ratings_request()
2413
-    {
2414
-        EEH_Template::display_template(
2415
-            EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php',
2416
-            array()
2417
-        );
2418
-    }
2419
-
2420
-
2421
-    public static function cached_rss_display($rss_id, $url)
2422
-    {
2423
-        $loading = '<p class="widget-loading hide-if-no-js">'
2424
-                   . __('Loading&#8230;', 'event_espresso')
2425
-                   . '</p><p class="hide-if-js">'
2426
-                   . esc_html__('This widget requires JavaScript.', 'event_espresso')
2427
-                   . '</p>';
2428
-        $pre = '<div class="espresso-rss-display">' . "\n\t";
2429
-        $pre .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>';
2430
-        $post = '</div>' . "\n";
2431
-        $cache_key = 'ee_rss_' . md5($rss_id);
2432
-        $output = get_transient($cache_key);
2433
-        if ($output !== false) {
2434
-            echo $pre . $output . $post;
2435
-            return true;
2436
-        }
2437
-        if (! (defined('DOING_AJAX') && DOING_AJAX)) {
2438
-            echo $pre . $loading . $post;
2439
-            return false;
2440
-        }
2441
-        ob_start();
2442
-        wp_widget_rss_output($url, array('show_date' => 0, 'items' => 5));
2443
-        set_transient($cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS);
2444
-        return true;
2445
-    }
2446
-
2447
-
2448
-    public function espresso_news_post_box()
2449
-    {
2450
-        ?>
2240
+		return $entries_per_page_dropdown;
2241
+	}
2242
+
2243
+
2244
+	/**
2245
+	 *        _set_search_attributes
2246
+	 *
2247
+	 * @return        void
2248
+	 */
2249
+	public function _set_search_attributes()
2250
+	{
2251
+		$this->_template_args['search']['btn_label'] = sprintf(
2252
+			esc_html__('Search %s', 'event_espresso'),
2253
+			empty($this->_search_btn_label) ? $this->page_label
2254
+				: $this->_search_btn_label
2255
+		);
2256
+		$this->_template_args['search']['callback'] = 'search_' . $this->page_slug;
2257
+	}
2258
+
2259
+
2260
+
2261
+	/*** END LIST TABLE METHODS **/
2262
+
2263
+
2264
+	/**
2265
+	 * _add_registered_metaboxes
2266
+	 *  this loads any registered metaboxes via the 'metaboxes' index in the _page_config property array.
2267
+	 *
2268
+	 * @link   http://codex.wordpress.org/Function_Reference/add_meta_box
2269
+	 * @return void
2270
+	 * @throws EE_Error
2271
+	 */
2272
+	private function _add_registered_meta_boxes()
2273
+	{
2274
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2275
+		// we only add meta boxes if the page_route calls for it
2276
+		if (is_array($this->_route_config) && isset($this->_route_config['metaboxes'])
2277
+			&& is_array(
2278
+				$this->_route_config['metaboxes']
2279
+			)
2280
+		) {
2281
+			// this simply loops through the callbacks provided
2282
+			// and checks if there is a corresponding callback registered by the child
2283
+			// if there is then we go ahead and process the metabox loader.
2284
+			foreach ($this->_route_config['metaboxes'] as $metabox_callback) {
2285
+				// first check for Closures
2286
+				if ($metabox_callback instanceof Closure) {
2287
+					$result = $metabox_callback();
2288
+				} elseif (is_array($metabox_callback) && isset($metabox_callback[0], $metabox_callback[1])) {
2289
+					$result = call_user_func(array($metabox_callback[0], $metabox_callback[1]));
2290
+				} else {
2291
+					$result = call_user_func(array($this, &$metabox_callback));
2292
+				}
2293
+				if ($result === false) {
2294
+					// user error msg
2295
+					$error_msg = esc_html__(
2296
+						'An error occurred. The  requested metabox could not be found.',
2297
+						'event_espresso'
2298
+					);
2299
+					// developer error msg
2300
+					$error_msg .= '||'
2301
+								  . sprintf(
2302
+									  esc_html__(
2303
+										  'The metabox with the string "%s" could not be called. Check that the spelling for method names and actions in the "_page_config[\'metaboxes\']" array are all correct.',
2304
+										  'event_espresso'
2305
+									  ),
2306
+									  $metabox_callback
2307
+								  );
2308
+					throw new EE_Error($error_msg);
2309
+				}
2310
+			}
2311
+		}
2312
+	}
2313
+
2314
+
2315
+	/**
2316
+	 * _add_screen_columns
2317
+	 * This will check the _page_config array and if there is "columns" key index indicated, we'll set the template as
2318
+	 * the dynamic column template and we'll setup the column options for the page.
2319
+	 *
2320
+	 * @return void
2321
+	 */
2322
+	private function _add_screen_columns()
2323
+	{
2324
+		if (is_array($this->_route_config)
2325
+			&& isset($this->_route_config['columns'])
2326
+			&& is_array($this->_route_config['columns'])
2327
+			&& count($this->_route_config['columns']) === 2
2328
+		) {
2329
+			add_screen_option(
2330
+				'layout_columns',
2331
+				array(
2332
+					'max'     => (int) $this->_route_config['columns'][0],
2333
+					'default' => (int) $this->_route_config['columns'][1],
2334
+				)
2335
+			);
2336
+			$this->_template_args['num_columns'] = $this->_route_config['columns'][0];
2337
+			$screen_id = $this->_current_screen->id;
2338
+			$screen_columns = (int) get_user_option("screen_layout_{$screen_id}");
2339
+			$total_columns = ! empty($screen_columns)
2340
+				? $screen_columns
2341
+				: $this->_route_config['columns'][1];
2342
+			$this->_template_args['current_screen_widget_class'] = 'columns-' . $total_columns;
2343
+			$this->_template_args['current_page'] = $this->_wp_page_slug;
2344
+			$this->_template_args['screen'] = $this->_current_screen;
2345
+			$this->_column_template_path = EE_ADMIN_TEMPLATE
2346
+										   . 'admin_details_metabox_column_wrapper.template.php';
2347
+			// finally if we don't have has_metaboxes set in the route config
2348
+			// let's make sure it IS set other wise the necessary hidden fields for this won't be loaded.
2349
+			$this->_route_config['has_metaboxes'] = true;
2350
+		}
2351
+	}
2352
+
2353
+
2354
+
2355
+	/** GLOBALLY AVAILABLE METABOXES **/
2356
+
2357
+
2358
+	/**
2359
+	 * In this section we put any globally available EE metaboxes for all EE Admin pages.  They are called by simply
2360
+	 * referencing the callback in the _page_config array property.  This way you can be very specific about what pages
2361
+	 * these get loaded on.
2362
+	 */
2363
+	private function _espresso_news_post_box()
2364
+	{
2365
+		$news_box_title = apply_filters(
2366
+			'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2367
+			esc_html__('New @ Event Espresso', 'event_espresso')
2368
+		);
2369
+		add_meta_box(
2370
+			'espresso_news_post_box',
2371
+			$news_box_title,
2372
+			array(
2373
+				$this,
2374
+				'espresso_news_post_box',
2375
+			),
2376
+			$this->_wp_page_slug,
2377
+			'side'
2378
+		);
2379
+	}
2380
+
2381
+
2382
+	/**
2383
+	 * Code for setting up espresso ratings request metabox.
2384
+	 */
2385
+	protected function _espresso_ratings_request()
2386
+	{
2387
+		if (! apply_filters('FHEE_show_ratings_request_meta_box', true)) {
2388
+			return;
2389
+		}
2390
+		$ratings_box_title = apply_filters(
2391
+			'FHEE__EE_Admin_Page___espresso_news_post_box__news_box_title',
2392
+			esc_html__('Keep Event Espresso Decaf Free', 'event_espresso')
2393
+		);
2394
+		add_meta_box(
2395
+			'espresso_ratings_request',
2396
+			$ratings_box_title,
2397
+			array(
2398
+				$this,
2399
+				'espresso_ratings_request',
2400
+			),
2401
+			$this->_wp_page_slug,
2402
+			'side'
2403
+		);
2404
+	}
2405
+
2406
+
2407
+	/**
2408
+	 * Code for setting up espresso ratings request metabox content.
2409
+	 *
2410
+	 * @throws DomainException
2411
+	 */
2412
+	public function espresso_ratings_request()
2413
+	{
2414
+		EEH_Template::display_template(
2415
+			EE_ADMIN_TEMPLATE . 'espresso_ratings_request_content.template.php',
2416
+			array()
2417
+		);
2418
+	}
2419
+
2420
+
2421
+	public static function cached_rss_display($rss_id, $url)
2422
+	{
2423
+		$loading = '<p class="widget-loading hide-if-no-js">'
2424
+				   . __('Loading&#8230;', 'event_espresso')
2425
+				   . '</p><p class="hide-if-js">'
2426
+				   . esc_html__('This widget requires JavaScript.', 'event_espresso')
2427
+				   . '</p>';
2428
+		$pre = '<div class="espresso-rss-display">' . "\n\t";
2429
+		$pre .= '<span id="' . $rss_id . '_url" class="hidden">' . $url . '</span>';
2430
+		$post = '</div>' . "\n";
2431
+		$cache_key = 'ee_rss_' . md5($rss_id);
2432
+		$output = get_transient($cache_key);
2433
+		if ($output !== false) {
2434
+			echo $pre . $output . $post;
2435
+			return true;
2436
+		}
2437
+		if (! (defined('DOING_AJAX') && DOING_AJAX)) {
2438
+			echo $pre . $loading . $post;
2439
+			return false;
2440
+		}
2441
+		ob_start();
2442
+		wp_widget_rss_output($url, array('show_date' => 0, 'items' => 5));
2443
+		set_transient($cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS);
2444
+		return true;
2445
+	}
2446
+
2447
+
2448
+	public function espresso_news_post_box()
2449
+	{
2450
+		?>
2451 2451
         <div class="padding">
2452 2452
             <div id="espresso_news_post_box_content" class="infolinks">
2453 2453
                 <?php
2454
-                // Get RSS Feed(s)
2455
-                self::cached_rss_display(
2456
-                    'espresso_news_post_box_content',
2457
-                    urlencode(
2458
-                        apply_filters(
2459
-                            'FHEE__EE_Admin_Page__espresso_news_post_box__feed_url',
2460
-                            'http://eventespresso.com/feed/'
2461
-                        )
2462
-                    )
2463
-                );
2464
-                ?>
2454
+				// Get RSS Feed(s)
2455
+				self::cached_rss_display(
2456
+					'espresso_news_post_box_content',
2457
+					urlencode(
2458
+						apply_filters(
2459
+							'FHEE__EE_Admin_Page__espresso_news_post_box__feed_url',
2460
+							'http://eventespresso.com/feed/'
2461
+						)
2462
+					)
2463
+				);
2464
+				?>
2465 2465
             </div>
2466 2466
             <?php do_action('AHEE__EE_Admin_Page__espresso_news_post_box__after_content'); ?>
2467 2467
         </div>
2468 2468
         <?php
2469
-    }
2470
-
2471
-
2472
-    private function _espresso_links_post_box()
2473
-    {
2474
-        // Hiding until we actually have content to put in here...
2475
-        // add_meta_box('espresso_links_post_box', esc_html__('Helpful Plugin Links', 'event_espresso'), array( $this, 'espresso_links_post_box'), $this->_wp_page_slug, 'side');
2476
-    }
2477
-
2478
-
2479
-    public function espresso_links_post_box()
2480
-    {
2481
-        // Hiding until we actually have content to put in here...
2482
-        // EEH_Template::display_template(
2483
-        //     EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_links.template.php'
2484
-        // );
2485
-    }
2486
-
2487
-
2488
-    protected function _espresso_sponsors_post_box()
2489
-    {
2490
-        if (apply_filters('FHEE_show_sponsors_meta_box', true)) {
2491
-            add_meta_box(
2492
-                'espresso_sponsors_post_box',
2493
-                esc_html__('Event Espresso Highlights', 'event_espresso'),
2494
-                array($this, 'espresso_sponsors_post_box'),
2495
-                $this->_wp_page_slug,
2496
-                'side'
2497
-            );
2498
-        }
2499
-    }
2500
-
2501
-
2502
-    public function espresso_sponsors_post_box()
2503
-    {
2504
-        EEH_Template::display_template(
2505
-            EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php'
2506
-        );
2507
-    }
2508
-
2509
-
2510
-    private function _publish_post_box()
2511
-    {
2512
-        $meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview';
2513
-        // if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array
2514
-        // then we'll use that for the metabox label.
2515
-        // Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes)
2516
-        if (! empty($this->_labels['publishbox'])) {
2517
-            $box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][ $this->_req_action ]
2518
-                : $this->_labels['publishbox'];
2519
-        } else {
2520
-            $box_label = esc_html__('Publish', 'event_espresso');
2521
-        }
2522
-        $box_label = apply_filters(
2523
-            'FHEE__EE_Admin_Page___publish_post_box__box_label',
2524
-            $box_label,
2525
-            $this->_req_action,
2526
-            $this
2527
-        );
2528
-        add_meta_box(
2529
-            $meta_box_ref,
2530
-            $box_label,
2531
-            array($this, 'editor_overview'),
2532
-            $this->_current_screen->id,
2533
-            'side',
2534
-            'high'
2535
-        );
2536
-    }
2537
-
2538
-
2539
-    public function editor_overview()
2540
-    {
2541
-        // if we have extra content set let's add it in if not make sure its empty
2542
-        $this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2543
-            ? $this->_template_args['publish_box_extra_content']
2544
-            : '';
2545
-        echo EEH_Template::display_template(
2546
-            EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php',
2547
-            $this->_template_args,
2548
-            true
2549
-        );
2550
-    }
2551
-
2552
-
2553
-    /** end of globally available metaboxes section **/
2554
-
2555
-
2556
-    /**
2557
-     * Public wrapper for the protected method.  Allows plugins/addons to externally call the
2558
-     * protected method.
2559
-     *
2560
-     * @see   $this->_set_publish_post_box_vars for param details
2561
-     * @since 4.6.0
2562
-     * @param string $name
2563
-     * @param int    $id
2564
-     * @param bool   $delete
2565
-     * @param string $save_close_redirect_URL
2566
-     * @param bool   $both_btns
2567
-     * @throws EE_Error
2568
-     * @throws InvalidArgumentException
2569
-     * @throws InvalidDataTypeException
2570
-     * @throws InvalidInterfaceException
2571
-     */
2572
-    public function set_publish_post_box_vars(
2573
-        $name = '',
2574
-        $id = 0,
2575
-        $delete = false,
2576
-        $save_close_redirect_URL = '',
2577
-        $both_btns = true
2578
-    ) {
2579
-        $this->_set_publish_post_box_vars(
2580
-            $name,
2581
-            $id,
2582
-            $delete,
2583
-            $save_close_redirect_URL,
2584
-            $both_btns
2585
-        );
2586
-    }
2587
-
2588
-
2589
-    /**
2590
-     * Sets the _template_args arguments used by the _publish_post_box shortcut
2591
-     * Note: currently there is no validation for this.  However if you want the delete button, the
2592
-     * save, and save and close buttons to work properly, then you will want to include a
2593
-     * values for the name and id arguments.
2594
-     *
2595
-     * @todo  Add in validation for name/id arguments.
2596
-     * @param    string  $name                    key used for the action ID (i.e. event_id)
2597
-     * @param    int     $id                      id attached to the item published
2598
-     * @param    string  $delete                  page route callback for the delete action
2599
-     * @param    string  $save_close_redirect_URL custom URL to redirect to after Save & Close has been completed
2600
-     * @param    boolean $both_btns               whether to display BOTH the "Save & Close" and "Save" buttons or just
2601
-     *                                            the Save button
2602
-     * @throws EE_Error
2603
-     * @throws InvalidArgumentException
2604
-     * @throws InvalidDataTypeException
2605
-     * @throws InvalidInterfaceException
2606
-     */
2607
-    protected function _set_publish_post_box_vars(
2608
-        $name = '',
2609
-        $id = 0,
2610
-        $delete = '',
2611
-        $save_close_redirect_URL = '',
2612
-        $both_btns = true
2613
-    ) {
2614
-        // if Save & Close, use a custom redirect URL or default to the main page?
2615
-        $save_close_redirect_URL = ! empty($save_close_redirect_URL)
2616
-            ? $save_close_redirect_URL
2617
-            : $this->_admin_base_url;
2618
-        // create the Save & Close and Save buttons
2619
-        $this->_set_save_buttons($both_btns, array(), array(), $save_close_redirect_URL);
2620
-        // if we have extra content set let's add it in if not make sure its empty
2621
-        $this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2622
-            ? $this->_template_args['publish_box_extra_content']
2623
-            : '';
2624
-        if ($delete && ! empty($id)) {
2625
-            // make sure we have a default if just true is sent.
2626
-            $delete = ! empty($delete) ? $delete : 'delete';
2627
-            $delete_link_args = array($name => $id);
2628
-            $delete = $this->get_action_link_or_button(
2629
-                $delete,
2630
-                $delete,
2631
-                $delete_link_args,
2632
-                'submitdelete deletion',
2633
-                '',
2634
-                false
2635
-            );
2636
-        }
2637
-        $this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : '';
2638
-        if (! empty($name) && ! empty($id)) {
2639
-            $hidden_field_arr[ $name ] = array(
2640
-                'type'  => 'hidden',
2641
-                'value' => $id,
2642
-            );
2643
-            $hf = $this->_generate_admin_form_fields($hidden_field_arr, 'array');
2644
-        } else {
2645
-            $hf = '';
2646
-        }
2647
-        // add hidden field
2648
-        $this->_template_args['publish_hidden_fields'] = is_array($hf) && ! empty($name)
2649
-            ? $hf[ $name ]['field']
2650
-            : $hf;
2651
-    }
2652
-
2653
-
2654
-    /**
2655
-     * displays an error message to ppl who have javascript disabled
2656
-     *
2657
-     * @return void
2658
-     */
2659
-    private function _display_no_javascript_warning()
2660
-    {
2661
-        ?>
2469
+	}
2470
+
2471
+
2472
+	private function _espresso_links_post_box()
2473
+	{
2474
+		// Hiding until we actually have content to put in here...
2475
+		// add_meta_box('espresso_links_post_box', esc_html__('Helpful Plugin Links', 'event_espresso'), array( $this, 'espresso_links_post_box'), $this->_wp_page_slug, 'side');
2476
+	}
2477
+
2478
+
2479
+	public function espresso_links_post_box()
2480
+	{
2481
+		// Hiding until we actually have content to put in here...
2482
+		// EEH_Template::display_template(
2483
+		//     EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_links.template.php'
2484
+		// );
2485
+	}
2486
+
2487
+
2488
+	protected function _espresso_sponsors_post_box()
2489
+	{
2490
+		if (apply_filters('FHEE_show_sponsors_meta_box', true)) {
2491
+			add_meta_box(
2492
+				'espresso_sponsors_post_box',
2493
+				esc_html__('Event Espresso Highlights', 'event_espresso'),
2494
+				array($this, 'espresso_sponsors_post_box'),
2495
+				$this->_wp_page_slug,
2496
+				'side'
2497
+			);
2498
+		}
2499
+	}
2500
+
2501
+
2502
+	public function espresso_sponsors_post_box()
2503
+	{
2504
+		EEH_Template::display_template(
2505
+			EE_ADMIN_TEMPLATE . 'admin_general_metabox_contents_espresso_sponsors.template.php'
2506
+		);
2507
+	}
2508
+
2509
+
2510
+	private function _publish_post_box()
2511
+	{
2512
+		$meta_box_ref = 'espresso_' . $this->page_slug . '_editor_overview';
2513
+		// if there is a array('label' => array('publishbox' => 'some title') ) present in the _page_config array
2514
+		// then we'll use that for the metabox label.
2515
+		// Otherwise we'll just use publish (publishbox itself could be an array of labels indexed by routes)
2516
+		if (! empty($this->_labels['publishbox'])) {
2517
+			$box_label = is_array($this->_labels['publishbox']) ? $this->_labels['publishbox'][ $this->_req_action ]
2518
+				: $this->_labels['publishbox'];
2519
+		} else {
2520
+			$box_label = esc_html__('Publish', 'event_espresso');
2521
+		}
2522
+		$box_label = apply_filters(
2523
+			'FHEE__EE_Admin_Page___publish_post_box__box_label',
2524
+			$box_label,
2525
+			$this->_req_action,
2526
+			$this
2527
+		);
2528
+		add_meta_box(
2529
+			$meta_box_ref,
2530
+			$box_label,
2531
+			array($this, 'editor_overview'),
2532
+			$this->_current_screen->id,
2533
+			'side',
2534
+			'high'
2535
+		);
2536
+	}
2537
+
2538
+
2539
+	public function editor_overview()
2540
+	{
2541
+		// if we have extra content set let's add it in if not make sure its empty
2542
+		$this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2543
+			? $this->_template_args['publish_box_extra_content']
2544
+			: '';
2545
+		echo EEH_Template::display_template(
2546
+			EE_ADMIN_TEMPLATE . 'admin_details_publish_metabox.template.php',
2547
+			$this->_template_args,
2548
+			true
2549
+		);
2550
+	}
2551
+
2552
+
2553
+	/** end of globally available metaboxes section **/
2554
+
2555
+
2556
+	/**
2557
+	 * Public wrapper for the protected method.  Allows plugins/addons to externally call the
2558
+	 * protected method.
2559
+	 *
2560
+	 * @see   $this->_set_publish_post_box_vars for param details
2561
+	 * @since 4.6.0
2562
+	 * @param string $name
2563
+	 * @param int    $id
2564
+	 * @param bool   $delete
2565
+	 * @param string $save_close_redirect_URL
2566
+	 * @param bool   $both_btns
2567
+	 * @throws EE_Error
2568
+	 * @throws InvalidArgumentException
2569
+	 * @throws InvalidDataTypeException
2570
+	 * @throws InvalidInterfaceException
2571
+	 */
2572
+	public function set_publish_post_box_vars(
2573
+		$name = '',
2574
+		$id = 0,
2575
+		$delete = false,
2576
+		$save_close_redirect_URL = '',
2577
+		$both_btns = true
2578
+	) {
2579
+		$this->_set_publish_post_box_vars(
2580
+			$name,
2581
+			$id,
2582
+			$delete,
2583
+			$save_close_redirect_URL,
2584
+			$both_btns
2585
+		);
2586
+	}
2587
+
2588
+
2589
+	/**
2590
+	 * Sets the _template_args arguments used by the _publish_post_box shortcut
2591
+	 * Note: currently there is no validation for this.  However if you want the delete button, the
2592
+	 * save, and save and close buttons to work properly, then you will want to include a
2593
+	 * values for the name and id arguments.
2594
+	 *
2595
+	 * @todo  Add in validation for name/id arguments.
2596
+	 * @param    string  $name                    key used for the action ID (i.e. event_id)
2597
+	 * @param    int     $id                      id attached to the item published
2598
+	 * @param    string  $delete                  page route callback for the delete action
2599
+	 * @param    string  $save_close_redirect_URL custom URL to redirect to after Save & Close has been completed
2600
+	 * @param    boolean $both_btns               whether to display BOTH the "Save & Close" and "Save" buttons or just
2601
+	 *                                            the Save button
2602
+	 * @throws EE_Error
2603
+	 * @throws InvalidArgumentException
2604
+	 * @throws InvalidDataTypeException
2605
+	 * @throws InvalidInterfaceException
2606
+	 */
2607
+	protected function _set_publish_post_box_vars(
2608
+		$name = '',
2609
+		$id = 0,
2610
+		$delete = '',
2611
+		$save_close_redirect_URL = '',
2612
+		$both_btns = true
2613
+	) {
2614
+		// if Save & Close, use a custom redirect URL or default to the main page?
2615
+		$save_close_redirect_URL = ! empty($save_close_redirect_URL)
2616
+			? $save_close_redirect_URL
2617
+			: $this->_admin_base_url;
2618
+		// create the Save & Close and Save buttons
2619
+		$this->_set_save_buttons($both_btns, array(), array(), $save_close_redirect_URL);
2620
+		// if we have extra content set let's add it in if not make sure its empty
2621
+		$this->_template_args['publish_box_extra_content'] = isset($this->_template_args['publish_box_extra_content'])
2622
+			? $this->_template_args['publish_box_extra_content']
2623
+			: '';
2624
+		if ($delete && ! empty($id)) {
2625
+			// make sure we have a default if just true is sent.
2626
+			$delete = ! empty($delete) ? $delete : 'delete';
2627
+			$delete_link_args = array($name => $id);
2628
+			$delete = $this->get_action_link_or_button(
2629
+				$delete,
2630
+				$delete,
2631
+				$delete_link_args,
2632
+				'submitdelete deletion',
2633
+				'',
2634
+				false
2635
+			);
2636
+		}
2637
+		$this->_template_args['publish_delete_link'] = ! empty($id) ? $delete : '';
2638
+		if (! empty($name) && ! empty($id)) {
2639
+			$hidden_field_arr[ $name ] = array(
2640
+				'type'  => 'hidden',
2641
+				'value' => $id,
2642
+			);
2643
+			$hf = $this->_generate_admin_form_fields($hidden_field_arr, 'array');
2644
+		} else {
2645
+			$hf = '';
2646
+		}
2647
+		// add hidden field
2648
+		$this->_template_args['publish_hidden_fields'] = is_array($hf) && ! empty($name)
2649
+			? $hf[ $name ]['field']
2650
+			: $hf;
2651
+	}
2652
+
2653
+
2654
+	/**
2655
+	 * displays an error message to ppl who have javascript disabled
2656
+	 *
2657
+	 * @return void
2658
+	 */
2659
+	private function _display_no_javascript_warning()
2660
+	{
2661
+		?>
2662 2662
         <noscript>
2663 2663
             <div id="no-js-message" class="error">
2664 2664
                 <p style="font-size:1.3em;">
2665 2665
                     <span style="color:red;"><?php esc_html_e('Warning!', 'event_espresso'); ?></span>
2666 2666
                     <?php esc_html_e(
2667
-                        'Javascript is currently turned off for your browser. Javascript must be enabled in order for all of the features on this page to function properly. Please turn your javascript back on.',
2668
-                        'event_espresso'
2669
-                    ); ?>
2667
+						'Javascript is currently turned off for your browser. Javascript must be enabled in order for all of the features on this page to function properly. Please turn your javascript back on.',
2668
+						'event_espresso'
2669
+					); ?>
2670 2670
                 </p>
2671 2671
             </div>
2672 2672
         </noscript>
2673 2673
         <?php
2674
-    }
2675
-
2676
-
2677
-    /**
2678
-     * displays espresso success and/or error notices
2679
-     *
2680
-     * @return void
2681
-     */
2682
-    private function _display_espresso_notices()
2683
-    {
2684
-        $notices = $this->_get_transient(true);
2685
-        echo stripslashes($notices);
2686
-    }
2687
-
2688
-
2689
-    /**
2690
-     * spinny things pacify the masses
2691
-     *
2692
-     * @return void
2693
-     */
2694
-    protected function _add_admin_page_ajax_loading_img()
2695
-    {
2696
-        ?>
2674
+	}
2675
+
2676
+
2677
+	/**
2678
+	 * displays espresso success and/or error notices
2679
+	 *
2680
+	 * @return void
2681
+	 */
2682
+	private function _display_espresso_notices()
2683
+	{
2684
+		$notices = $this->_get_transient(true);
2685
+		echo stripslashes($notices);
2686
+	}
2687
+
2688
+
2689
+	/**
2690
+	 * spinny things pacify the masses
2691
+	 *
2692
+	 * @return void
2693
+	 */
2694
+	protected function _add_admin_page_ajax_loading_img()
2695
+	{
2696
+		?>
2697 2697
         <div id="espresso-ajax-loading" class="ajax-loading-grey">
2698 2698
             <span class="ee-spinner ee-spin"></span><span class="hidden"><?php
2699
-                esc_html_e('loading...', 'event_espresso'); ?></span>
2699
+				esc_html_e('loading...', 'event_espresso'); ?></span>
2700 2700
         </div>
2701 2701
         <?php
2702
-    }
2702
+	}
2703 2703
 
2704 2704
 
2705
-    /**
2706
-     * add admin page overlay for modal boxes
2707
-     *
2708
-     * @return void
2709
-     */
2710
-    protected function _add_admin_page_overlay()
2711
-    {
2712
-        ?>
2705
+	/**
2706
+	 * add admin page overlay for modal boxes
2707
+	 *
2708
+	 * @return void
2709
+	 */
2710
+	protected function _add_admin_page_overlay()
2711
+	{
2712
+		?>
2713 2713
         <div id="espresso-admin-page-overlay-dv" class=""></div>
2714 2714
         <?php
2715
-    }
2716
-
2717
-
2718
-    /**
2719
-     * facade for add_meta_box
2720
-     *
2721
-     * @param string  $action        where the metabox get's displayed
2722
-     * @param string  $title         Title of Metabox (output in metabox header)
2723
-     * @param string  $callback      If not empty and $create_fun is set to false then we'll use a custom callback
2724
-     *                               instead of the one created in here.
2725
-     * @param array   $callback_args an array of args supplied for the metabox
2726
-     * @param string  $column        what metabox column
2727
-     * @param string  $priority      give this metabox a priority (using accepted priorities for wp meta boxes)
2728
-     * @param boolean $create_func   default is true.  Basically we can say we don't WANT to have the runtime function
2729
-     *                               created but just set our own callback for wp's add_meta_box.
2730
-     * @throws \DomainException
2731
-     */
2732
-    public function _add_admin_page_meta_box(
2733
-        $action,
2734
-        $title,
2735
-        $callback,
2736
-        $callback_args,
2737
-        $column = 'normal',
2738
-        $priority = 'high',
2739
-        $create_func = true
2740
-    ) {
2741
-        do_action('AHEE_log', __FILE__, __FUNCTION__, $callback);
2742
-        // if we have empty callback args and we want to automatically create the metabox callback then we need to make sure the callback args are generated.
2743
-        if (empty($callback_args) && $create_func) {
2744
-            $callback_args = array(
2745
-                'template_path' => $this->_template_path,
2746
-                'template_args' => $this->_template_args,
2747
-            );
2748
-        }
2749
-        // if $create_func is true (default) then we automatically create the function for displaying the actual meta box.  If false then we take the $callback reference passed through and use it instead (so callers can define their own callback function/method if they wish)
2750
-        $call_back_func = $create_func
2751
-            ? function ($post, $metabox) {
2752
-                do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2753
-                echo EEH_Template::display_template(
2754
-                    $metabox['args']['template_path'],
2755
-                    $metabox['args']['template_args'],
2756
-                    true
2757
-                );
2758
-            }
2759
-            : $callback;
2760
-        add_meta_box(
2761
-            str_replace('_', '-', $action) . '-mbox',
2762
-            $title,
2763
-            $call_back_func,
2764
-            $this->_wp_page_slug,
2765
-            $column,
2766
-            $priority,
2767
-            $callback_args
2768
-        );
2769
-    }
2770
-
2771
-
2772
-    /**
2773
-     * generates HTML wrapper for and admin details page that contains metaboxes in columns
2774
-     *
2775
-     * @throws DomainException
2776
-     * @throws EE_Error
2777
-     */
2778
-    public function display_admin_page_with_metabox_columns()
2779
-    {
2780
-        $this->_template_args['post_body_content'] = $this->_template_args['admin_page_content'];
2781
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2782
-            $this->_column_template_path,
2783
-            $this->_template_args,
2784
-            true
2785
-        );
2786
-        // the final wrapper
2787
-        $this->admin_page_wrapper();
2788
-    }
2789
-
2790
-
2791
-    /**
2792
-     * generates  HTML wrapper for an admin details page
2793
-     *
2794
-     * @return void
2795
-     * @throws EE_Error
2796
-     * @throws DomainException
2797
-     */
2798
-    public function display_admin_page_with_sidebar()
2799
-    {
2800
-        $this->_display_admin_page(true);
2801
-    }
2802
-
2803
-
2804
-    /**
2805
-     * generates  HTML wrapper for an admin details page (except no sidebar)
2806
-     *
2807
-     * @return void
2808
-     * @throws EE_Error
2809
-     * @throws DomainException
2810
-     */
2811
-    public function display_admin_page_with_no_sidebar()
2812
-    {
2813
-        $this->_display_admin_page();
2814
-    }
2815
-
2816
-
2817
-    /**
2818
-     * generates HTML wrapper for an EE about admin page (no sidebar)
2819
-     *
2820
-     * @return void
2821
-     * @throws EE_Error
2822
-     * @throws DomainException
2823
-     */
2824
-    public function display_about_admin_page()
2825
-    {
2826
-        $this->_display_admin_page(false, true);
2827
-    }
2828
-
2829
-
2830
-    /**
2831
-     * display_admin_page
2832
-     * contains the code for actually displaying an admin page
2833
-     *
2834
-     * @param  boolean $sidebar true with sidebar, false without
2835
-     * @param  boolean $about   use the about admin wrapper instead of the default.
2836
-     * @return void
2837
-     * @throws DomainException
2838
-     * @throws EE_Error
2839
-     */
2840
-    private function _display_admin_page($sidebar = false, $about = false)
2841
-    {
2842
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2843
-        // custom remove metaboxes hook to add or remove any metaboxes to/from Admin pages.
2844
-        do_action('AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes');
2845
-        // set current wp page slug - looks like: event-espresso_page_event_categories
2846
-        // keep in mind "event-espresso" COULD be something else if the top level menu label has been translated.
2847
-        $this->_template_args['current_page'] = $this->_wp_page_slug;
2848
-        $this->_template_args['admin_page_wrapper_div_id'] = $this->_cpt_route
2849
-            ? 'poststuff'
2850
-            : 'espresso-default-admin';
2851
-        $template_path = $sidebar
2852
-            ? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php'
2853
-            : EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php';
2854
-        if (defined('DOING_AJAX') && DOING_AJAX) {
2855
-            $template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php';
2856
-        }
2857
-        $template_path = ! empty($this->_column_template_path)
2858
-            ? $this->_column_template_path : $template_path;
2859
-        $this->_template_args['post_body_content'] = isset($this->_template_args['admin_page_content'])
2860
-            ? $this->_template_args['admin_page_content']
2861
-            : '';
2862
-        $this->_template_args['before_admin_page_content'] = isset($this->_template_args['before_admin_page_content'])
2863
-            ? $this->_template_args['before_admin_page_content']
2864
-            : '';
2865
-        $this->_template_args['after_admin_page_content'] = isset($this->_template_args['after_admin_page_content'])
2866
-            ? $this->_template_args['after_admin_page_content']
2867
-            : '';
2868
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2869
-            $template_path,
2870
-            $this->_template_args,
2871
-            true
2872
-        );
2873
-        // the final template wrapper
2874
-        $this->admin_page_wrapper($about);
2875
-    }
2876
-
2877
-
2878
-    /**
2879
-     * This is used to display caf preview pages.
2880
-     *
2881
-     * @since 4.3.2
2882
-     * @param string $utm_campaign_source what is the key used for google analytics link
2883
-     * @param bool   $display_sidebar     whether to use the sidebar template or the full template for the page.  TRUE
2884
-     *                                    = SHOW sidebar, FALSE = no sidebar. Default no sidebar.
2885
-     * @return void
2886
-     * @throws DomainException
2887
-     * @throws EE_Error
2888
-     * @throws InvalidArgumentException
2889
-     * @throws InvalidDataTypeException
2890
-     * @throws InvalidInterfaceException
2891
-     */
2892
-    public function display_admin_caf_preview_page($utm_campaign_source = '', $display_sidebar = true)
2893
-    {
2894
-        // let's generate a default preview action button if there isn't one already present.
2895
-        $this->_labels['buttons']['buy_now'] = esc_html__(
2896
-            'Upgrade to Event Espresso 4 Right Now',
2897
-            'event_espresso'
2898
-        );
2899
-        $buy_now_url = add_query_arg(
2900
-            array(
2901
-                'ee_ver'       => 'ee4',
2902
-                'utm_source'   => 'ee4_plugin_admin',
2903
-                'utm_medium'   => 'link',
2904
-                'utm_campaign' => $utm_campaign_source,
2905
-                'utm_content'  => 'buy_now_button',
2906
-            ),
2907
-            'http://eventespresso.com/pricing/'
2908
-        );
2909
-        $this->_template_args['preview_action_button'] = ! isset($this->_template_args['preview_action_button'])
2910
-            ? $this->get_action_link_or_button(
2911
-                '',
2912
-                'buy_now',
2913
-                array(),
2914
-                'button-primary button-large',
2915
-                $buy_now_url,
2916
-                true
2917
-            )
2918
-            : $this->_template_args['preview_action_button'];
2919
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2920
-            EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php',
2921
-            $this->_template_args,
2922
-            true
2923
-        );
2924
-        $this->_display_admin_page($display_sidebar);
2925
-    }
2926
-
2927
-
2928
-    /**
2929
-     * display_admin_list_table_page_with_sidebar
2930
-     * generates HTML wrapper for an admin_page with list_table
2931
-     *
2932
-     * @return void
2933
-     * @throws EE_Error
2934
-     * @throws DomainException
2935
-     */
2936
-    public function display_admin_list_table_page_with_sidebar()
2937
-    {
2938
-        $this->_display_admin_list_table_page(true);
2939
-    }
2940
-
2941
-
2942
-    /**
2943
-     * display_admin_list_table_page_with_no_sidebar
2944
-     * generates HTML wrapper for an admin_page with list_table (but with no sidebar)
2945
-     *
2946
-     * @return void
2947
-     * @throws EE_Error
2948
-     * @throws DomainException
2949
-     */
2950
-    public function display_admin_list_table_page_with_no_sidebar()
2951
-    {
2952
-        $this->_display_admin_list_table_page();
2953
-    }
2954
-
2955
-
2956
-    /**
2957
-     * generates html wrapper for an admin_list_table page
2958
-     *
2959
-     * @param boolean $sidebar whether to display with sidebar or not.
2960
-     * @return void
2961
-     * @throws DomainException
2962
-     * @throws EE_Error
2963
-     */
2964
-    private function _display_admin_list_table_page($sidebar = false)
2965
-    {
2966
-        // setup search attributes
2967
-        $this->_set_search_attributes();
2968
-        $this->_template_args['current_page'] = $this->_wp_page_slug;
2969
-        $template_path = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php';
2970
-        $this->_template_args['table_url'] = defined('DOING_AJAX')
2971
-            ? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url)
2972
-            : add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url);
2973
-        $this->_template_args['list_table'] = $this->_list_table_object;
2974
-        $this->_template_args['current_route'] = $this->_req_action;
2975
-        $this->_template_args['list_table_class'] = get_class($this->_list_table_object);
2976
-        $ajax_sorting_callback = $this->_list_table_object->get_ajax_sorting_callback();
2977
-        if (! empty($ajax_sorting_callback)) {
2978
-            $sortable_list_table_form_fields = wp_nonce_field(
2979
-                $ajax_sorting_callback . '_nonce',
2980
-                $ajax_sorting_callback . '_nonce',
2981
-                false,
2982
-                false
2983
-            );
2984
-            $sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_page" name="ajax_table_sort_page" value="'
2985
-                                                . $this->page_slug
2986
-                                                . '" />';
2987
-            $sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_action" name="ajax_table_sort_action" value="'
2988
-                                                . $ajax_sorting_callback
2989
-                                                . '" />';
2990
-        } else {
2991
-            $sortable_list_table_form_fields = '';
2992
-        }
2993
-        $this->_template_args['sortable_list_table_form_fields'] = $sortable_list_table_form_fields;
2994
-        $hidden_form_fields = isset($this->_template_args['list_table_hidden_fields'])
2995
-            ? $this->_template_args['list_table_hidden_fields']
2996
-            : '';
2997
-        $nonce_ref = $this->_req_action . '_nonce';
2998
-        $hidden_form_fields .= '<input type="hidden" name="'
2999
-                               . $nonce_ref
3000
-                               . '" value="'
3001
-                               . wp_create_nonce($nonce_ref)
3002
-                               . '">';
3003
-        $this->_template_args['list_table_hidden_fields'] = $hidden_form_fields;
3004
-        // display message about search results?
3005
-        $this->_template_args['before_list_table'] .= ! empty($this->_req_data['s'])
3006
-            ? '<p class="ee-search-results">' . sprintf(
3007
-                esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'),
3008
-                trim($this->_req_data['s'], '%')
3009
-            ) . '</p>'
3010
-            : '';
3011
-        // filter before_list_table template arg
3012
-        $this->_template_args['before_list_table'] = apply_filters(
3013
-            'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_arg',
3014
-            $this->_template_args['before_list_table'],
3015
-            $this->page_slug,
3016
-            $this->_req_data,
3017
-            $this->_req_action
3018
-        );
3019
-        // convert to array and filter again
3020
-        // arrays are easier to inject new items in a specific location,
3021
-        // but would not be backwards compatible, so we have to add a new filter
3022
-        $this->_template_args['before_list_table'] = implode(
3023
-            " \n",
3024
-            (array) apply_filters(
3025
-                'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_args_array',
3026
-                (array) $this->_template_args['before_list_table'],
3027
-                $this->page_slug,
3028
-                $this->_req_data,
3029
-                $this->_req_action
3030
-            )
3031
-        );
3032
-        // filter after_list_table template arg
3033
-        $this->_template_args['after_list_table'] = apply_filters(
3034
-            'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_arg',
3035
-            $this->_template_args['after_list_table'],
3036
-            $this->page_slug,
3037
-            $this->_req_data,
3038
-            $this->_req_action
3039
-        );
3040
-        // convert to array and filter again
3041
-        // arrays are easier to inject new items in a specific location,
3042
-        // but would not be backwards compatible, so we have to add a new filter
3043
-        $this->_template_args['after_list_table'] = implode(
3044
-            " \n",
3045
-            (array) apply_filters(
3046
-                'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_args_array',
3047
-                (array) $this->_template_args['after_list_table'],
3048
-                $this->page_slug,
3049
-                $this->_req_data,
3050
-                $this->_req_action
3051
-            )
3052
-        );
3053
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
3054
-            $template_path,
3055
-            $this->_template_args,
3056
-            true
3057
-        );
3058
-        // the final template wrapper
3059
-        if ($sidebar) {
3060
-            $this->display_admin_page_with_sidebar();
3061
-        } else {
3062
-            $this->display_admin_page_with_no_sidebar();
3063
-        }
3064
-    }
3065
-
3066
-
3067
-    /**
3068
-     * This just prepares a legend using the given items and the admin_details_legend.template.php file and returns the
3069
-     * html string for the legend.
3070
-     * $items are expected in an array in the following format:
3071
-     * $legend_items = array(
3072
-     *        'item_id' => array(
3073
-     *            'icon' => 'http://url_to_icon_being_described.png',
3074
-     *            'desc' => esc_html__('localized description of item');
3075
-     *        )
3076
-     * );
3077
-     *
3078
-     * @param  array $items see above for format of array
3079
-     * @return string html string of legend
3080
-     * @throws DomainException
3081
-     */
3082
-    protected function _display_legend($items)
3083
-    {
3084
-        $this->_template_args['items'] = apply_filters(
3085
-            'FHEE__EE_Admin_Page___display_legend__items',
3086
-            (array) $items,
3087
-            $this
3088
-        );
3089
-        return EEH_Template::display_template(
3090
-            EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php',
3091
-            $this->_template_args,
3092
-            true
3093
-        );
3094
-    }
3095
-
3096
-
3097
-    /**
3098
-     * This is used whenever we're DOING_AJAX to return a formatted json array that our calling javascript can expect
3099
-     * The returned json object is created from an array in the following format:
3100
-     * array(
3101
-     *  'error' => FALSE, //(default FALSE), contains any errors and/or exceptions (exceptions return json early),
3102
-     *  'success' => FALSE, //(default FALSE) - contains any special success message.
3103
-     *  'notices' => '', // - contains any EE_Error formatted notices
3104
-     *  'content' => 'string can be html', //this is a string of formatted content (can be html)
3105
-     *  'data' => array() //this can be any key/value pairs that a method returns for later json parsing by the js.
3106
-     *  We're also going to include the template args with every package (so js can pick out any specific template args
3107
-     *  that might be included in here)
3108
-     * )
3109
-     * The json object is populated by whatever is set in the $_template_args property.
3110
-     *
3111
-     * @param bool  $sticky_notices    Used to indicate whether you want to ensure notices are added to a transient
3112
-     *                                 instead of displayed.
3113
-     * @param array $notices_arguments Use this to pass any additional args on to the _process_notices.
3114
-     * @return void
3115
-     * @throws EE_Error
3116
-     */
3117
-    protected function _return_json($sticky_notices = false, $notices_arguments = array())
3118
-    {
3119
-        // make sure any EE_Error notices have been handled.
3120
-        $this->_process_notices($notices_arguments, true, $sticky_notices);
3121
-        $data = isset($this->_template_args['data']) ? $this->_template_args['data'] : array();
3122
-        unset($this->_template_args['data']);
3123
-        $json = array(
3124
-            'error'     => isset($this->_template_args['error']) ? $this->_template_args['error'] : false,
3125
-            'success'   => isset($this->_template_args['success']) ? $this->_template_args['success'] : false,
3126
-            'errors'    => isset($this->_template_args['errors']) ? $this->_template_args['errors'] : false,
3127
-            'attention' => isset($this->_template_args['attention']) ? $this->_template_args['attention'] : false,
3128
-            'notices'   => EE_Error::get_notices(),
3129
-            'content'   => isset($this->_template_args['admin_page_content'])
3130
-                ? $this->_template_args['admin_page_content'] : '',
3131
-            'data'      => array_merge($data, array('template_args' => $this->_template_args)),
3132
-            'isEEajax'  => true
3133
-            // special flag so any ajax.Success methods in js can identify this return package as a EEajax package.
3134
-        );
3135
-        // make sure there are no php errors or headers_sent.  Then we can set correct json header.
3136
-        if (null === error_get_last() || ! headers_sent()) {
3137
-            header('Content-Type: application/json; charset=UTF-8');
3138
-        }
3139
-        echo wp_json_encode($json);
3140
-        exit();
3141
-    }
3142
-
3143
-
3144
-    /**
3145
-     * Simply a wrapper for the protected method so we can call this outside the class (ONLY when doing ajax)
3146
-     *
3147
-     * @return void
3148
-     * @throws EE_Error
3149
-     */
3150
-    public function return_json()
3151
-    {
3152
-        if (defined('DOING_AJAX') && DOING_AJAX) {
3153
-            $this->_return_json();
3154
-        } else {
3155
-            throw new EE_Error(
3156
-                sprintf(
3157
-                    esc_html__('The public %s method can only be called when DOING_AJAX = TRUE', 'event_espresso'),
3158
-                    __FUNCTION__
3159
-                )
3160
-            );
3161
-        }
3162
-    }
3163
-
3164
-
3165
-    /**
3166
-     * This provides a way for child hook classes to send along themselves by reference so methods/properties within
3167
-     * them can be accessed by EE_Admin_child pages. This is assigned to the $_hook_obj property.
3168
-     *
3169
-     * @param EE_Admin_Hooks $hook_obj This will be the object for the EE_Admin_Hooks child
3170
-     */
3171
-    public function set_hook_object(EE_Admin_Hooks $hook_obj)
3172
-    {
3173
-        $this->_hook_obj = $hook_obj;
3174
-    }
3175
-
3176
-
3177
-    /**
3178
-     *        generates  HTML wrapper with Tabbed nav for an admin page
3179
-     *
3180
-     * @param  boolean $about whether to use the special about page wrapper or default.
3181
-     * @return void
3182
-     * @throws DomainException
3183
-     * @throws EE_Error
3184
-     */
3185
-    public function admin_page_wrapper($about = false)
3186
-    {
3187
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3188
-        $this->_nav_tabs = $this->_get_main_nav_tabs();
3189
-        $this->_template_args['nav_tabs'] = $this->_nav_tabs;
3190
-        $this->_template_args['admin_page_title'] = $this->_admin_page_title;
3191
-        $this->_template_args['before_admin_page_content'] = apply_filters(
3192
-            "FHEE_before_admin_page_content{$this->_current_page}{$this->_current_view}",
3193
-            isset($this->_template_args['before_admin_page_content'])
3194
-                ? $this->_template_args['before_admin_page_content']
3195
-                : ''
3196
-        );
3197
-        $this->_template_args['after_admin_page_content'] = apply_filters(
3198
-            "FHEE_after_admin_page_content{$this->_current_page}{$this->_current_view}",
3199
-            isset($this->_template_args['after_admin_page_content'])
3200
-                ? $this->_template_args['after_admin_page_content']
3201
-                : ''
3202
-        );
3203
-        $this->_template_args['after_admin_page_content'] .= $this->_set_help_popup_content();
3204
-        // load settings page wrapper template
3205
-        $template_path = ! defined('DOING_AJAX')
3206
-            ? EE_ADMIN_TEMPLATE . 'admin_wrapper.template.php'
3207
-            : EE_ADMIN_TEMPLATE
3208
-              . 'admin_wrapper_ajax.template.php';
3209
-        // about page?
3210
-        $template_path = $about
3211
-            ? EE_ADMIN_TEMPLATE . 'about_admin_wrapper.template.php'
3212
-            : $template_path;
3213
-        if (defined('DOING_AJAX')) {
3214
-            $this->_template_args['admin_page_content'] = EEH_Template::display_template(
3215
-                $template_path,
3216
-                $this->_template_args,
3217
-                true
3218
-            );
3219
-            $this->_return_json();
3220
-        } else {
3221
-            EEH_Template::display_template($template_path, $this->_template_args);
3222
-        }
3223
-    }
3224
-
3225
-
3226
-    /**
3227
-     * This returns the admin_nav tabs html using the configuration in the _nav_tabs property
3228
-     *
3229
-     * @return string html
3230
-     * @throws EE_Error
3231
-     */
3232
-    protected function _get_main_nav_tabs()
3233
-    {
3234
-        // let's generate the html using the EEH_Tabbed_Content helper.
3235
-        // We do this here so that it's possible for child classes to add in nav tabs dynamically at the last minute
3236
-        // (rather than setting in the page_routes array)
3237
-        return EEH_Tabbed_Content::display_admin_nav_tabs($this->_nav_tabs);
3238
-    }
3239
-
3240
-
3241
-    /**
3242
-     *        sort nav tabs
3243
-     *
3244
-     * @param $a
3245
-     * @param $b
3246
-     * @return int
3247
-     */
3248
-    private function _sort_nav_tabs($a, $b)
3249
-    {
3250
-        if ($a['order'] === $b['order']) {
3251
-            return 0;
3252
-        }
3253
-        return ($a['order'] < $b['order']) ? -1 : 1;
3254
-    }
3255
-
3256
-
3257
-    /**
3258
-     *    generates HTML for the forms used on admin pages
3259
-     *
3260
-     * @param    array $input_vars - array of input field details
3261
-     * @param string   $generator  (options are 'string' or 'array', basically use this to indicate which generator to
3262
-     *                             use)
3263
-     * @param bool     $id
3264
-     * @return string
3265
-     * @uses   EEH_Form_Fields::get_form_fields (/helper/EEH_Form_Fields.helper.php)
3266
-     * @uses   EEH_Form_Fields::get_form_fields_array (/helper/EEH_Form_Fields.helper.php)
3267
-     */
3268
-    protected function _generate_admin_form_fields($input_vars = array(), $generator = 'string', $id = false)
3269
-    {
3270
-        $content = $generator === 'string'
3271
-            ? EEH_Form_Fields::get_form_fields($input_vars, $id)
3272
-            : EEH_Form_Fields::get_form_fields_array($input_vars);
3273
-        return $content;
3274
-    }
3275
-
3276
-
3277
-    /**
3278
-     * generates the "Save" and "Save & Close" buttons for edit forms
3279
-     *
3280
-     * @param bool             $both     if true then both buttons will be generated.  If false then just the "Save &
3281
-     *                                   Close" button.
3282
-     * @param array            $text     if included, generator will use the given text for the buttons ( array([0] =>
3283
-     *                                   'Save', [1] => 'save & close')
3284
-     * @param array            $actions  if included allows us to set the actions that each button will carry out (i.e.
3285
-     *                                   via the "name" value in the button).  We can also use this to just dump
3286
-     *                                   default actions by submitting some other value.
3287
-     * @param bool|string|null $referrer if false then we just do the default action on save and close.  Other wise it
3288
-     *                                   will use the $referrer string. IF null, then we don't do ANYTHING on save and
3289
-     *                                   close (normal form handling).
3290
-     */
3291
-    protected function _set_save_buttons($both = true, $text = array(), $actions = array(), $referrer = null)
3292
-    {
3293
-        // make sure $text and $actions are in an array
3294
-        $text = (array) $text;
3295
-        $actions = (array) $actions;
3296
-        $referrer_url = empty($referrer)
3297
-            ? '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3298
-              . $_SERVER['REQUEST_URI']
3299
-              . '" />'
3300
-            : '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3301
-              . $referrer
3302
-              . '" />';
3303
-        $button_text = ! empty($text)
3304
-            ? $text
3305
-            : array(
3306
-                esc_html__('Save', 'event_espresso'),
3307
-                esc_html__('Save and Close', 'event_espresso'),
3308
-            );
3309
-        $default_names = array('save', 'save_and_close');
3310
-        // add in a hidden index for the current page (so save and close redirects properly)
3311
-        $this->_template_args['save_buttons'] = $referrer_url;
3312
-        foreach ($button_text as $key => $button) {
3313
-            $ref = $default_names[ $key ];
3314
-            $this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary '
3315
-                                                     . $ref
3316
-                                                     . '" value="'
3317
-                                                     . $button
3318
-                                                     . '" name="'
3319
-                                                     . (! empty($actions) ? $actions[ $key ] : $ref)
3320
-                                                     . '" id="'
3321
-                                                     . $this->_current_view . '_' . $ref
3322
-                                                     . '" />';
3323
-            if (! $both) {
3324
-                break;
3325
-            }
3326
-        }
3327
-    }
3328
-
3329
-
3330
-    /**
3331
-     * Wrapper for the protected function.  Allows plugins/addons to call this to set the form tags.
3332
-     *
3333
-     * @see   $this->_set_add_edit_form_tags() for details on params
3334
-     * @since 4.6.0
3335
-     * @param string $route
3336
-     * @param array  $additional_hidden_fields
3337
-     */
3338
-    public function set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3339
-    {
3340
-        $this->_set_add_edit_form_tags($route, $additional_hidden_fields);
3341
-    }
3342
-
3343
-
3344
-    /**
3345
-     * set form open and close tags on add/edit pages.
3346
-     *
3347
-     * @param string $route                    the route you want the form to direct to
3348
-     * @param array  $additional_hidden_fields any additional hidden fields required in the form header
3349
-     * @return void
3350
-     */
3351
-    protected function _set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3352
-    {
3353
-        if (empty($route)) {
3354
-            $user_msg = esc_html__(
3355
-                'An error occurred. No action was set for this page\'s form.',
3356
-                'event_espresso'
3357
-            );
3358
-            $dev_msg = $user_msg . "\n"
3359
-                       . sprintf(
3360
-                           esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'),
3361
-                           __FUNCTION__,
3362
-                           __CLASS__
3363
-                       );
3364
-            EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
3365
-        }
3366
-        // open form
3367
-        $this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="'
3368
-                                                             . $this->_admin_base_url
3369
-                                                             . '" id="'
3370
-                                                             . $route
3371
-                                                             . '_event_form" >';
3372
-        // add nonce
3373
-        $nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false);
3374
-        $this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce;
3375
-        // add REQUIRED form action
3376
-        $hidden_fields = array(
3377
-            'action' => array('type' => 'hidden', 'value' => $route),
3378
-        );
3379
-        // merge arrays
3380
-        $hidden_fields = is_array($additional_hidden_fields)
3381
-            ? array_merge($hidden_fields, $additional_hidden_fields)
3382
-            : $hidden_fields;
3383
-        // generate form fields
3384
-        $form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array');
3385
-        // add fields to form
3386
-        foreach ((array) $form_fields as $field_name => $form_field) {
3387
-            $this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field'];
3388
-        }
3389
-        // close form
3390
-        $this->_template_args['after_admin_page_content'] = '</form>';
3391
-    }
3392
-
3393
-
3394
-    /**
3395
-     * Public Wrapper for _redirect_after_action() method since its
3396
-     * discovered it would be useful for external code to have access.
3397
-     *
3398
-     * @see   EE_Admin_Page::_redirect_after_action() for params.
3399
-     * @since 4.5.0
3400
-     * @param bool   $success
3401
-     * @param string $what
3402
-     * @param string $action_desc
3403
-     * @param array  $query_args
3404
-     * @param bool   $override_overwrite
3405
-     * @throws EE_Error
3406
-     */
3407
-    public function redirect_after_action(
3408
-        $success = false,
3409
-        $what = 'item',
3410
-        $action_desc = 'processed',
3411
-        $query_args = array(),
3412
-        $override_overwrite = false
3413
-    ) {
3414
-        $this->_redirect_after_action(
3415
-            $success,
3416
-            $what,
3417
-            $action_desc,
3418
-            $query_args,
3419
-            $override_overwrite
3420
-        );
3421
-    }
3422
-
3423
-
3424
-    /**
3425
-     * Helper method for merging existing request data with the returned redirect url.
3426
-     *
3427
-     * This is typically used for redirects after an action so that if the original view was a filtered view those
3428
-     * filters are still applied.
3429
-     *
3430
-     * @param array $new_route_data
3431
-     * @return array
3432
-     */
3433
-    protected function mergeExistingRequestParamsWithRedirectArgs(array $new_route_data)
3434
-    {
3435
-        foreach ($this->_req_data as $ref => $value) {
3436
-            // unset nonces
3437
-            if (strpos($ref, 'nonce') !== false) {
3438
-                unset($this->_req_data[ $ref ]);
3439
-                continue;
3440
-            }
3441
-            // urlencode values.
3442
-            $value = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
3443
-            $this->_req_data[ $ref ] = $value;
3444
-        }
3445
-        return array_merge($this->_req_data, $new_route_data);
3446
-    }
3447
-
3448
-
3449
-    /**
3450
-     *    _redirect_after_action
3451
-     *
3452
-     * @param int    $success            - whether success was for two or more records, or just one, or none
3453
-     * @param string $what               - what the action was performed on
3454
-     * @param string $action_desc        - what was done ie: updated, deleted, etc
3455
-     * @param array  $query_args         - an array of query_args to be added to the URL to redirect to after the admin
3456
-     *                                   action is completed
3457
-     * @param BOOL   $override_overwrite by default all EE_Error::success messages are overwritten, this allows you to
3458
-     *                                   override this so that they show.
3459
-     * @return void
3460
-     * @throws EE_Error
3461
-     */
3462
-    protected function _redirect_after_action(
3463
-        $success = 0,
3464
-        $what = 'item',
3465
-        $action_desc = 'processed',
3466
-        $query_args = array(),
3467
-        $override_overwrite = false
3468
-    ) {
3469
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3470
-        // class name for actions/filters.
3471
-        $classname = get_class($this);
3472
-        // set redirect url.
3473
-        // Note if there is a "page" index in the $query_args then we go with vanilla admin.php route,
3474
-        // otherwise we go with whatever is set as the _admin_base_url
3475
-        $redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url;
3476
-        $notices = EE_Error::get_notices(false);
3477
-        // overwrite default success messages //BUT ONLY if overwrite not overridden
3478
-        if (! $override_overwrite || ! empty($notices['errors'])) {
3479
-            EE_Error::overwrite_success();
3480
-        }
3481
-        if (! empty($what) && ! empty($action_desc) && empty($notices['errors'])) {
3482
-            // how many records affected ? more than one record ? or just one ?
3483
-            if ($success > 1) {
3484
-                // set plural msg
3485
-                EE_Error::add_success(
3486
-                    sprintf(
3487
-                        esc_html__('The "%s" have been successfully %s.', 'event_espresso'),
3488
-                        $what,
3489
-                        $action_desc
3490
-                    ),
3491
-                    __FILE__,
3492
-                    __FUNCTION__,
3493
-                    __LINE__
3494
-                );
3495
-            } elseif ($success === 1) {
3496
-                // set singular msg
3497
-                EE_Error::add_success(
3498
-                    sprintf(
3499
-                        esc_html__('The "%s" has been successfully %s.', 'event_espresso'),
3500
-                        $what,
3501
-                        $action_desc
3502
-                    ),
3503
-                    __FILE__,
3504
-                    __FUNCTION__,
3505
-                    __LINE__
3506
-                );
3507
-            }
3508
-        }
3509
-        // check that $query_args isn't something crazy
3510
-        if (! is_array($query_args)) {
3511
-            $query_args = array();
3512
-        }
3513
-        /**
3514
-         * Allow injecting actions before the query_args are modified for possible different
3515
-         * redirections on save and close actions
3516
-         *
3517
-         * @since 4.2.0
3518
-         * @param array $query_args       The original query_args array coming into the
3519
-         *                                method.
3520
-         */
3521
-        do_action(
3522
-            "AHEE__{$classname}___redirect_after_action__before_redirect_modification_{$this->_req_action}",
3523
-            $query_args
3524
-        );
3525
-        // calculate where we're going (if we have a "save and close" button pushed)
3526
-        if (isset($this->_req_data['save_and_close'], $this->_req_data['save_and_close_referrer'])) {
3527
-            // even though we have the save_and_close referrer, we need to parse the url for the action in order to generate a nonce
3528
-            $parsed_url = parse_url($this->_req_data['save_and_close_referrer']);
3529
-            // regenerate query args array from referrer URL
3530
-            parse_str($parsed_url['query'], $query_args);
3531
-            // correct page and action will be in the query args now
3532
-            $redirect_url = admin_url('admin.php');
3533
-        }
3534
-        // merge any default query_args set in _default_route_query_args property
3535
-        if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3536
-            $args_to_merge = array();
3537
-            foreach ($this->_default_route_query_args as $query_param => $query_value) {
3538
-                // is there a wp_referer array in our _default_route_query_args property?
3539
-                if ($query_param === 'wp_referer') {
3540
-                    $query_value = (array) $query_value;
3541
-                    foreach ($query_value as $reference => $value) {
3542
-                        if (strpos($reference, 'nonce') !== false) {
3543
-                            continue;
3544
-                        }
3545
-                        // finally we will override any arguments in the referer with
3546
-                        // what might be set on the _default_route_query_args array.
3547
-                        if (isset($this->_default_route_query_args[ $reference ])) {
3548
-                            $args_to_merge[ $reference ] = urlencode($this->_default_route_query_args[ $reference ]);
3549
-                        } else {
3550
-                            $args_to_merge[ $reference ] = urlencode($value);
3551
-                        }
3552
-                    }
3553
-                    continue;
3554
-                }
3555
-                $args_to_merge[ $query_param ] = $query_value;
3556
-            }
3557
-            // now let's merge these arguments but override with what was specifically sent in to the
3558
-            // redirect.
3559
-            $query_args = array_merge($args_to_merge, $query_args);
3560
-        }
3561
-        $this->_process_notices($query_args);
3562
-        // generate redirect url
3563
-        // if redirecting to anything other than the main page, add a nonce
3564
-        if (isset($query_args['action'])) {
3565
-            // manually generate wp_nonce and merge that with the query vars
3566
-            // becuz the wp_nonce_url function wrecks havoc on some vars
3567
-            $query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce');
3568
-        }
3569
-        // we're adding some hooks and filters in here for processing any things just before redirects
3570
-        // (example: an admin page has done an insert or update and we want to run something after that).
3571
-        do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args);
3572
-        $redirect_url = apply_filters(
3573
-            'FHEE_redirect_' . $classname . $this->_req_action,
3574
-            self::add_query_args_and_nonce($query_args, $redirect_url),
3575
-            $query_args
3576
-        );
3577
-        // check if we're doing ajax.  If we are then lets just return the results and js can handle how it wants.
3578
-        if (defined('DOING_AJAX')) {
3579
-            $default_data = array(
3580
-                'close'        => true,
3581
-                'redirect_url' => $redirect_url,
3582
-                'where'        => 'main',
3583
-                'what'         => 'append',
3584
-            );
3585
-            $this->_template_args['success'] = $success;
3586
-            $this->_template_args['data'] = ! empty($this->_template_args['data']) ? array_merge(
3587
-                $default_data,
3588
-                $this->_template_args['data']
3589
-            ) : $default_data;
3590
-            $this->_return_json();
3591
-        }
3592
-        wp_safe_redirect($redirect_url);
3593
-        exit();
3594
-    }
3595
-
3596
-
3597
-    /**
3598
-     * process any notices before redirecting (or returning ajax request)
3599
-     * This method sets the $this->_template_args['notices'] attribute;
3600
-     *
3601
-     * @param  array $query_args        any query args that need to be used for notice transient ('action')
3602
-     * @param bool   $skip_route_verify This is typically used when we are processing notices REALLY early and
3603
-     *                                  page_routes haven't been defined yet.
3604
-     * @param bool   $sticky_notices    This is used to flag that regardless of whether this is doing_ajax or not, we
3605
-     *                                  still save a transient for the notice.
3606
-     * @return void
3607
-     * @throws EE_Error
3608
-     */
3609
-    protected function _process_notices($query_args = array(), $skip_route_verify = false, $sticky_notices = true)
3610
-    {
3611
-        // first let's set individual error properties if doing_ajax and the properties aren't already set.
3612
-        if (defined('DOING_AJAX') && DOING_AJAX) {
3613
-            $notices = EE_Error::get_notices(false);
3614
-            if (empty($this->_template_args['success'])) {
3615
-                $this->_template_args['success'] = isset($notices['success']) ? $notices['success'] : false;
3616
-            }
3617
-            if (empty($this->_template_args['errors'])) {
3618
-                $this->_template_args['errors'] = isset($notices['errors']) ? $notices['errors'] : false;
3619
-            }
3620
-            if (empty($this->_template_args['attention'])) {
3621
-                $this->_template_args['attention'] = isset($notices['attention']) ? $notices['attention'] : false;
3622
-            }
3623
-        }
3624
-        $this->_template_args['notices'] = EE_Error::get_notices();
3625
-        // IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true)
3626
-        if (! defined('DOING_AJAX') || $sticky_notices) {
3627
-            $route = isset($query_args['action']) ? $query_args['action'] : 'default';
3628
-            $this->_add_transient(
3629
-                $route,
3630
-                $this->_template_args['notices'],
3631
-                true,
3632
-                $skip_route_verify
3633
-            );
3634
-        }
3635
-    }
3636
-
3637
-
3638
-    /**
3639
-     * get_action_link_or_button
3640
-     * returns the button html for adding, editing, or deleting an item (depending on given type)
3641
-     *
3642
-     * @param string $action        use this to indicate which action the url is generated with.
3643
-     * @param string $type          accepted strings must be defined in the $_labels['button'] array(as the key)
3644
-     *                              property.
3645
-     * @param array  $extra_request if the button requires extra params you can include them in $key=>$value pairs.
3646
-     * @param string $class         Use this to give the class for the button. Defaults to 'button-primary'
3647
-     * @param string $base_url      If this is not provided
3648
-     *                              the _admin_base_url will be used as the default for the button base_url.
3649
-     *                              Otherwise this value will be used.
3650
-     * @param bool   $exclude_nonce If true then no nonce will be in the generated button link.
3651
-     * @return string
3652
-     * @throws InvalidArgumentException
3653
-     * @throws InvalidInterfaceException
3654
-     * @throws InvalidDataTypeException
3655
-     * @throws EE_Error
3656
-     */
3657
-    public function get_action_link_or_button(
3658
-        $action,
3659
-        $type = 'add',
3660
-        $extra_request = array(),
3661
-        $class = 'button-primary',
3662
-        $base_url = '',
3663
-        $exclude_nonce = false
3664
-    ) {
3665
-        // first let's validate the action (if $base_url is FALSE otherwise validation will happen further along)
3666
-        if (empty($base_url) && ! isset($this->_page_routes[ $action ])) {
3667
-            throw new EE_Error(
3668
-                sprintf(
3669
-                    esc_html__(
3670
-                        'There is no page route for given action for the button.  This action was given: %s',
3671
-                        'event_espresso'
3672
-                    ),
3673
-                    $action
3674
-                )
3675
-            );
3676
-        }
3677
-        if (! isset($this->_labels['buttons'][ $type ])) {
3678
-            throw new EE_Error(
3679
-                sprintf(
3680
-                    __(
3681
-                        'There is no label for the given button type (%s). Labels are set in the <code>_page_config</code> property.',
3682
-                        'event_espresso'
3683
-                    ),
3684
-                    $type
3685
-                )
3686
-            );
3687
-        }
3688
-        // finally check user access for this button.
3689
-        $has_access = $this->check_user_access($action, true);
3690
-        if (! $has_access) {
3691
-            return '';
3692
-        }
3693
-        $_base_url = ! $base_url ? $this->_admin_base_url : $base_url;
3694
-        $query_args = array(
3695
-            'action' => $action,
3696
-        );
3697
-        // merge extra_request args but make sure our original action takes precedence and doesn't get overwritten.
3698
-        if (! empty($extra_request)) {
3699
-            $query_args = array_merge($extra_request, $query_args);
3700
-        }
3701
-        $url = self::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce);
3702
-        return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][ $type ], $class);
3703
-    }
3704
-
3705
-
3706
-    /**
3707
-     * _per_page_screen_option
3708
-     * Utility function for adding in a per_page_option in the screen_options_dropdown.
3709
-     *
3710
-     * @return void
3711
-     * @throws InvalidArgumentException
3712
-     * @throws InvalidInterfaceException
3713
-     * @throws InvalidDataTypeException
3714
-     */
3715
-    protected function _per_page_screen_option()
3716
-    {
3717
-        $option = 'per_page';
3718
-        $args = array(
3719
-            'label'   => apply_filters(
3720
-                'FHEE__EE_Admin_Page___per_page_screen_options___label',
3721
-                $this->_admin_page_title,
3722
-                $this
3723
-            ),
3724
-            'default' => (int) apply_filters(
3725
-                'FHEE__EE_Admin_Page___per_page_screen_options__default',
3726
-                20
3727
-            ),
3728
-            'option'  => $this->_current_page . '_' . $this->_current_view . '_per_page',
3729
-        );
3730
-        // ONLY add the screen option if the user has access to it.
3731
-        if ($this->check_user_access($this->_current_view, true)) {
3732
-            add_screen_option($option, $args);
3733
-        }
3734
-    }
3735
-
3736
-
3737
-    /**
3738
-     * set_per_page_screen_option
3739
-     * All this does is make sure that WordPress saves any per_page screen options (if set) for the current page.
3740
-     * we have to do this rather than running inside the 'set-screen-options' hook because it runs earlier than
3741
-     * admin_menu.
3742
-     *
3743
-     * @return void
3744
-     */
3745
-    private function _set_per_page_screen_options()
3746
-    {
3747
-        if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) {
3748
-            check_admin_referer('screen-options-nonce', 'screenoptionnonce');
3749
-            if (! $user = wp_get_current_user()) {
3750
-                return;
3751
-            }
3752
-            $option = $_POST['wp_screen_options']['option'];
3753
-            $value = $_POST['wp_screen_options']['value'];
3754
-            if ($option != sanitize_key($option)) {
3755
-                return;
3756
-            }
3757
-            $map_option = $option;
3758
-            $option = str_replace('-', '_', $option);
3759
-            switch ($map_option) {
3760
-                case $this->_current_page . '_' . $this->_current_view . '_per_page':
3761
-                    $value = (int) $value;
3762
-                    $max_value = apply_filters(
3763
-                        'FHEE__EE_Admin_Page___set_per_page_screen_options__max_value',
3764
-                        999,
3765
-                        $this->_current_page,
3766
-                        $this->_current_view
3767
-                    );
3768
-                    if ($value < 1) {
3769
-                        return;
3770
-                    }
3771
-                    $value = min($value, $max_value);
3772
-                    break;
3773
-                default:
3774
-                    $value = apply_filters(
3775
-                        'FHEE__EE_Admin_Page___set_per_page_screen_options__value',
3776
-                        false,
3777
-                        $option,
3778
-                        $value
3779
-                    );
3780
-                    if (false === $value) {
3781
-                        return;
3782
-                    }
3783
-                    break;
3784
-            }
3785
-            update_user_meta($user->ID, $option, $value);
3786
-            wp_safe_redirect(remove_query_arg(array('pagenum', 'apage', 'paged'), wp_get_referer()));
3787
-            exit;
3788
-        }
3789
-    }
3790
-
3791
-
3792
-    /**
3793
-     * This just allows for setting the $_template_args property if it needs to be set outside the object
3794
-     *
3795
-     * @param array $data array that will be assigned to template args.
3796
-     */
3797
-    public function set_template_args($data)
3798
-    {
3799
-        $this->_template_args = array_merge($this->_template_args, (array) $data);
3800
-    }
3801
-
3802
-
3803
-    /**
3804
-     * This makes available the WP transient system for temporarily moving data between routes
3805
-     *
3806
-     * @param string $route             the route that should receive the transient
3807
-     * @param array  $data              the data that gets sent
3808
-     * @param bool   $notices           If this is for notices then we use this to indicate so, otherwise its just a
3809
-     *                                  normal route transient.
3810
-     * @param bool   $skip_route_verify Used to indicate we want to skip route verification.  This is usually ONLY used
3811
-     *                                  when we are adding a transient before page_routes have been defined.
3812
-     * @return void
3813
-     * @throws EE_Error
3814
-     */
3815
-    protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false)
3816
-    {
3817
-        $user_id = get_current_user_id();
3818
-        if (! $skip_route_verify) {
3819
-            $this->_verify_route($route);
3820
-        }
3821
-        // now let's set the string for what kind of transient we're setting
3822
-        $transient = $notices
3823
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3824
-            : 'rte_tx_' . $route . '_' . $user_id;
3825
-        $data = $notices ? array('notices' => $data) : $data;
3826
-        // is there already a transient for this route?  If there is then let's ADD to that transient
3827
-        $existing = is_multisite() && is_network_admin()
3828
-            ? get_site_transient($transient)
3829
-            : get_transient($transient);
3830
-        if ($existing) {
3831
-            $data = array_merge((array) $data, (array) $existing);
3832
-        }
3833
-        if (is_multisite() && is_network_admin()) {
3834
-            set_site_transient($transient, $data, 8);
3835
-        } else {
3836
-            set_transient($transient, $data, 8);
3837
-        }
3838
-    }
3839
-
3840
-
3841
-    /**
3842
-     * this retrieves the temporary transient that has been set for moving data between routes.
3843
-     *
3844
-     * @param bool   $notices true we get notices transient. False we just return normal route transient
3845
-     * @param string $route
3846
-     * @return mixed data
3847
-     */
3848
-    protected function _get_transient($notices = false, $route = '')
3849
-    {
3850
-        $user_id = get_current_user_id();
3851
-        $route = ! $route ? $this->_req_action : $route;
3852
-        $transient = $notices
3853
-            ? 'ee_rte_n_tx_' . $route . '_' . $user_id
3854
-            : 'rte_tx_' . $route . '_' . $user_id;
3855
-        $data = is_multisite() && is_network_admin()
3856
-            ? get_site_transient($transient)
3857
-            : get_transient($transient);
3858
-        // delete transient after retrieval (just in case it hasn't expired);
3859
-        if (is_multisite() && is_network_admin()) {
3860
-            delete_site_transient($transient);
3861
-        } else {
3862
-            delete_transient($transient);
3863
-        }
3864
-        return $notices && isset($data['notices']) ? $data['notices'] : $data;
3865
-    }
3866
-
3867
-
3868
-    /**
3869
-     * The purpose of this method is just to run garbage collection on any EE transients that might have expired but
3870
-     * would not be called later. This will be assigned to run on a specific EE Admin page. (place the method in the
3871
-     * default route callback on the EE_Admin page you want it run.)
3872
-     *
3873
-     * @return void
3874
-     */
3875
-    protected function _transient_garbage_collection()
3876
-    {
3877
-        global $wpdb;
3878
-        // retrieve all existing transients
3879
-        $query = "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%rte_tx_%' OR option_name LIKE '%rte_n_tx_%'";
3880
-        if ($results = $wpdb->get_results($query)) {
3881
-            foreach ($results as $result) {
3882
-                $transient = str_replace('_transient_', '', $result->option_name);
3883
-                get_transient($transient);
3884
-                if (is_multisite() && is_network_admin()) {
3885
-                    get_site_transient($transient);
3886
-                }
3887
-            }
3888
-        }
3889
-    }
3890
-
3891
-
3892
-    /**
3893
-     * get_view
3894
-     *
3895
-     * @return string content of _view property
3896
-     */
3897
-    public function get_view()
3898
-    {
3899
-        return $this->_view;
3900
-    }
3901
-
3902
-
3903
-    /**
3904
-     * getter for the protected $_views property
3905
-     *
3906
-     * @return array
3907
-     */
3908
-    public function get_views()
3909
-    {
3910
-        return $this->_views;
3911
-    }
3912
-
3913
-
3914
-    /**
3915
-     * get_current_page
3916
-     *
3917
-     * @return string _current_page property value
3918
-     */
3919
-    public function get_current_page()
3920
-    {
3921
-        return $this->_current_page;
3922
-    }
3923
-
3924
-
3925
-    /**
3926
-     * get_current_view
3927
-     *
3928
-     * @return string _current_view property value
3929
-     */
3930
-    public function get_current_view()
3931
-    {
3932
-        return $this->_current_view;
3933
-    }
3934
-
3935
-
3936
-    /**
3937
-     * get_current_screen
3938
-     *
3939
-     * @return object The current WP_Screen object
3940
-     */
3941
-    public function get_current_screen()
3942
-    {
3943
-        return $this->_current_screen;
3944
-    }
3945
-
3946
-
3947
-    /**
3948
-     * get_current_page_view_url
3949
-     *
3950
-     * @return string This returns the url for the current_page_view.
3951
-     */
3952
-    public function get_current_page_view_url()
3953
-    {
3954
-        return $this->_current_page_view_url;
3955
-    }
3956
-
3957
-
3958
-    /**
3959
-     * just returns the _req_data property
3960
-     *
3961
-     * @return array
3962
-     */
3963
-    public function get_request_data()
3964
-    {
3965
-        return $this->_req_data;
3966
-    }
3967
-
3968
-
3969
-    /**
3970
-     * returns the _req_data protected property
3971
-     *
3972
-     * @return string
3973
-     */
3974
-    public function get_req_action()
3975
-    {
3976
-        return $this->_req_action;
3977
-    }
3978
-
3979
-
3980
-    /**
3981
-     * @return bool  value of $_is_caf property
3982
-     */
3983
-    public function is_caf()
3984
-    {
3985
-        return $this->_is_caf;
3986
-    }
3987
-
3988
-
3989
-    /**
3990
-     * @return mixed
3991
-     */
3992
-    public function default_espresso_metaboxes()
3993
-    {
3994
-        return $this->_default_espresso_metaboxes;
3995
-    }
3996
-
3997
-
3998
-    /**
3999
-     * @return mixed
4000
-     */
4001
-    public function admin_base_url()
4002
-    {
4003
-        return $this->_admin_base_url;
4004
-    }
4005
-
4006
-
4007
-    /**
4008
-     * @return mixed
4009
-     */
4010
-    public function wp_page_slug()
4011
-    {
4012
-        return $this->_wp_page_slug;
4013
-    }
4014
-
4015
-
4016
-    /**
4017
-     * updates  espresso configuration settings
4018
-     *
4019
-     * @param string                   $tab
4020
-     * @param EE_Config_Base|EE_Config $config
4021
-     * @param string                   $file file where error occurred
4022
-     * @param string                   $func function  where error occurred
4023
-     * @param string                   $line line no where error occurred
4024
-     * @return boolean
4025
-     */
4026
-    protected function _update_espresso_configuration($tab, $config, $file = '', $func = '', $line = '')
4027
-    {
4028
-        // remove any options that are NOT going to be saved with the config settings.
4029
-        if (isset($config->core->ee_ueip_optin)) {
4030
-            // TODO: remove the following two lines and make sure values are migrated from 3.1
4031
-            update_option('ee_ueip_optin', $config->core->ee_ueip_optin);
4032
-            update_option('ee_ueip_has_notified', true);
4033
-        }
4034
-        // and save it (note we're also doing the network save here)
4035
-        $net_saved = is_main_site() ? EE_Network_Config::instance()->update_config(false, false) : true;
4036
-        $config_saved = EE_Config::instance()->update_espresso_config(false, false);
4037
-        if ($config_saved && $net_saved) {
4038
-            EE_Error::add_success(sprintf(__('"%s" have been successfully updated.', 'event_espresso'), $tab));
4039
-            return true;
4040
-        }
4041
-        EE_Error::add_error(sprintf(__('The "%s" were not updated.', 'event_espresso'), $tab), $file, $func, $line);
4042
-        return false;
4043
-    }
4044
-
4045
-
4046
-    /**
4047
-     * Returns an array to be used for EE_FOrm_Fields.helper.php's select_input as the $values argument.
4048
-     *
4049
-     * @return array
4050
-     */
4051
-    public function get_yes_no_values()
4052
-    {
4053
-        return $this->_yes_no_values;
4054
-    }
4055
-
4056
-
4057
-    protected function _get_dir()
4058
-    {
4059
-        $reflector = new ReflectionClass(get_class($this));
4060
-        return dirname($reflector->getFileName());
4061
-    }
4062
-
4063
-
4064
-    /**
4065
-     * A helper for getting a "next link".
4066
-     *
4067
-     * @param string $url   The url to link to
4068
-     * @param string $class The class to use.
4069
-     * @return string
4070
-     */
4071
-    protected function _next_link($url, $class = 'dashicons dashicons-arrow-right')
4072
-    {
4073
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4074
-    }
4075
-
4076
-
4077
-    /**
4078
-     * A helper for getting a "previous link".
4079
-     *
4080
-     * @param string $url   The url to link to
4081
-     * @param string $class The class to use.
4082
-     * @return string
4083
-     */
4084
-    protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left')
4085
-    {
4086
-        return '<a class="' . $class . '" href="' . $url . '"></a>';
4087
-    }
4088
-
4089
-
4090
-
4091
-
4092
-
4093
-
4094
-
4095
-    // below are some messages related methods that should be available across the EE_Admin system.  Note, these methods are NOT page specific
4096
-
4097
-
4098
-    /**
4099
-     * This processes an request to resend a registration and assumes we have a _REG_ID for doing so. So if the caller
4100
-     * knows that the _REG_ID isn't in the req_data array but CAN obtain it, the caller should ADD the _REG_ID to the
4101
-     * _req_data array.
4102
-     *
4103
-     * @return bool success/fail
4104
-     * @throws EE_Error
4105
-     * @throws InvalidArgumentException
4106
-     * @throws ReflectionException
4107
-     * @throws InvalidDataTypeException
4108
-     * @throws InvalidInterfaceException
4109
-     */
4110
-    protected function _process_resend_registration()
4111
-    {
4112
-        $this->_template_args['success'] = EED_Messages::process_resend($this->_req_data);
4113
-        do_action(
4114
-            'AHEE__EE_Admin_Page___process_resend_registration',
4115
-            $this->_template_args['success'],
4116
-            $this->_req_data
4117
-        );
4118
-        return $this->_template_args['success'];
4119
-    }
4120
-
4121
-
4122
-    /**
4123
-     * This automatically processes any payment message notifications when manual payment has been applied.
4124
-     *
4125
-     * @param \EE_Payment $payment
4126
-     * @return bool success/fail
4127
-     */
4128
-    protected function _process_payment_notification(EE_Payment $payment)
4129
-    {
4130
-        add_filter('FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', '__return_true');
4131
-        do_action('AHEE__EE_Admin_Page___process_admin_payment_notification', $payment);
4132
-        $this->_template_args['success'] = apply_filters(
4133
-            'FHEE__EE_Admin_Page___process_admin_payment_notification__success',
4134
-            false,
4135
-            $payment
4136
-        );
4137
-        return $this->_template_args['success'];
4138
-    }
2715
+	}
2716
+
2717
+
2718
+	/**
2719
+	 * facade for add_meta_box
2720
+	 *
2721
+	 * @param string  $action        where the metabox get's displayed
2722
+	 * @param string  $title         Title of Metabox (output in metabox header)
2723
+	 * @param string  $callback      If not empty and $create_fun is set to false then we'll use a custom callback
2724
+	 *                               instead of the one created in here.
2725
+	 * @param array   $callback_args an array of args supplied for the metabox
2726
+	 * @param string  $column        what metabox column
2727
+	 * @param string  $priority      give this metabox a priority (using accepted priorities for wp meta boxes)
2728
+	 * @param boolean $create_func   default is true.  Basically we can say we don't WANT to have the runtime function
2729
+	 *                               created but just set our own callback for wp's add_meta_box.
2730
+	 * @throws \DomainException
2731
+	 */
2732
+	public function _add_admin_page_meta_box(
2733
+		$action,
2734
+		$title,
2735
+		$callback,
2736
+		$callback_args,
2737
+		$column = 'normal',
2738
+		$priority = 'high',
2739
+		$create_func = true
2740
+	) {
2741
+		do_action('AHEE_log', __FILE__, __FUNCTION__, $callback);
2742
+		// if we have empty callback args and we want to automatically create the metabox callback then we need to make sure the callback args are generated.
2743
+		if (empty($callback_args) && $create_func) {
2744
+			$callback_args = array(
2745
+				'template_path' => $this->_template_path,
2746
+				'template_args' => $this->_template_args,
2747
+			);
2748
+		}
2749
+		// if $create_func is true (default) then we automatically create the function for displaying the actual meta box.  If false then we take the $callback reference passed through and use it instead (so callers can define their own callback function/method if they wish)
2750
+		$call_back_func = $create_func
2751
+			? function ($post, $metabox) {
2752
+				do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2753
+				echo EEH_Template::display_template(
2754
+					$metabox['args']['template_path'],
2755
+					$metabox['args']['template_args'],
2756
+					true
2757
+				);
2758
+			}
2759
+			: $callback;
2760
+		add_meta_box(
2761
+			str_replace('_', '-', $action) . '-mbox',
2762
+			$title,
2763
+			$call_back_func,
2764
+			$this->_wp_page_slug,
2765
+			$column,
2766
+			$priority,
2767
+			$callback_args
2768
+		);
2769
+	}
2770
+
2771
+
2772
+	/**
2773
+	 * generates HTML wrapper for and admin details page that contains metaboxes in columns
2774
+	 *
2775
+	 * @throws DomainException
2776
+	 * @throws EE_Error
2777
+	 */
2778
+	public function display_admin_page_with_metabox_columns()
2779
+	{
2780
+		$this->_template_args['post_body_content'] = $this->_template_args['admin_page_content'];
2781
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2782
+			$this->_column_template_path,
2783
+			$this->_template_args,
2784
+			true
2785
+		);
2786
+		// the final wrapper
2787
+		$this->admin_page_wrapper();
2788
+	}
2789
+
2790
+
2791
+	/**
2792
+	 * generates  HTML wrapper for an admin details page
2793
+	 *
2794
+	 * @return void
2795
+	 * @throws EE_Error
2796
+	 * @throws DomainException
2797
+	 */
2798
+	public function display_admin_page_with_sidebar()
2799
+	{
2800
+		$this->_display_admin_page(true);
2801
+	}
2802
+
2803
+
2804
+	/**
2805
+	 * generates  HTML wrapper for an admin details page (except no sidebar)
2806
+	 *
2807
+	 * @return void
2808
+	 * @throws EE_Error
2809
+	 * @throws DomainException
2810
+	 */
2811
+	public function display_admin_page_with_no_sidebar()
2812
+	{
2813
+		$this->_display_admin_page();
2814
+	}
2815
+
2816
+
2817
+	/**
2818
+	 * generates HTML wrapper for an EE about admin page (no sidebar)
2819
+	 *
2820
+	 * @return void
2821
+	 * @throws EE_Error
2822
+	 * @throws DomainException
2823
+	 */
2824
+	public function display_about_admin_page()
2825
+	{
2826
+		$this->_display_admin_page(false, true);
2827
+	}
2828
+
2829
+
2830
+	/**
2831
+	 * display_admin_page
2832
+	 * contains the code for actually displaying an admin page
2833
+	 *
2834
+	 * @param  boolean $sidebar true with sidebar, false without
2835
+	 * @param  boolean $about   use the about admin wrapper instead of the default.
2836
+	 * @return void
2837
+	 * @throws DomainException
2838
+	 * @throws EE_Error
2839
+	 */
2840
+	private function _display_admin_page($sidebar = false, $about = false)
2841
+	{
2842
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2843
+		// custom remove metaboxes hook to add or remove any metaboxes to/from Admin pages.
2844
+		do_action('AHEE__EE_Admin_Page___display_admin_page__modify_metaboxes');
2845
+		// set current wp page slug - looks like: event-espresso_page_event_categories
2846
+		// keep in mind "event-espresso" COULD be something else if the top level menu label has been translated.
2847
+		$this->_template_args['current_page'] = $this->_wp_page_slug;
2848
+		$this->_template_args['admin_page_wrapper_div_id'] = $this->_cpt_route
2849
+			? 'poststuff'
2850
+			: 'espresso-default-admin';
2851
+		$template_path = $sidebar
2852
+			? EE_ADMIN_TEMPLATE . 'admin_details_wrapper.template.php'
2853
+			: EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar.template.php';
2854
+		if (defined('DOING_AJAX') && DOING_AJAX) {
2855
+			$template_path = EE_ADMIN_TEMPLATE . 'admin_details_wrapper_no_sidebar_ajax.template.php';
2856
+		}
2857
+		$template_path = ! empty($this->_column_template_path)
2858
+			? $this->_column_template_path : $template_path;
2859
+		$this->_template_args['post_body_content'] = isset($this->_template_args['admin_page_content'])
2860
+			? $this->_template_args['admin_page_content']
2861
+			: '';
2862
+		$this->_template_args['before_admin_page_content'] = isset($this->_template_args['before_admin_page_content'])
2863
+			? $this->_template_args['before_admin_page_content']
2864
+			: '';
2865
+		$this->_template_args['after_admin_page_content'] = isset($this->_template_args['after_admin_page_content'])
2866
+			? $this->_template_args['after_admin_page_content']
2867
+			: '';
2868
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2869
+			$template_path,
2870
+			$this->_template_args,
2871
+			true
2872
+		);
2873
+		// the final template wrapper
2874
+		$this->admin_page_wrapper($about);
2875
+	}
2876
+
2877
+
2878
+	/**
2879
+	 * This is used to display caf preview pages.
2880
+	 *
2881
+	 * @since 4.3.2
2882
+	 * @param string $utm_campaign_source what is the key used for google analytics link
2883
+	 * @param bool   $display_sidebar     whether to use the sidebar template or the full template for the page.  TRUE
2884
+	 *                                    = SHOW sidebar, FALSE = no sidebar. Default no sidebar.
2885
+	 * @return void
2886
+	 * @throws DomainException
2887
+	 * @throws EE_Error
2888
+	 * @throws InvalidArgumentException
2889
+	 * @throws InvalidDataTypeException
2890
+	 * @throws InvalidInterfaceException
2891
+	 */
2892
+	public function display_admin_caf_preview_page($utm_campaign_source = '', $display_sidebar = true)
2893
+	{
2894
+		// let's generate a default preview action button if there isn't one already present.
2895
+		$this->_labels['buttons']['buy_now'] = esc_html__(
2896
+			'Upgrade to Event Espresso 4 Right Now',
2897
+			'event_espresso'
2898
+		);
2899
+		$buy_now_url = add_query_arg(
2900
+			array(
2901
+				'ee_ver'       => 'ee4',
2902
+				'utm_source'   => 'ee4_plugin_admin',
2903
+				'utm_medium'   => 'link',
2904
+				'utm_campaign' => $utm_campaign_source,
2905
+				'utm_content'  => 'buy_now_button',
2906
+			),
2907
+			'http://eventespresso.com/pricing/'
2908
+		);
2909
+		$this->_template_args['preview_action_button'] = ! isset($this->_template_args['preview_action_button'])
2910
+			? $this->get_action_link_or_button(
2911
+				'',
2912
+				'buy_now',
2913
+				array(),
2914
+				'button-primary button-large',
2915
+				$buy_now_url,
2916
+				true
2917
+			)
2918
+			: $this->_template_args['preview_action_button'];
2919
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2920
+			EE_ADMIN_TEMPLATE . 'admin_caf_full_page_preview.template.php',
2921
+			$this->_template_args,
2922
+			true
2923
+		);
2924
+		$this->_display_admin_page($display_sidebar);
2925
+	}
2926
+
2927
+
2928
+	/**
2929
+	 * display_admin_list_table_page_with_sidebar
2930
+	 * generates HTML wrapper for an admin_page with list_table
2931
+	 *
2932
+	 * @return void
2933
+	 * @throws EE_Error
2934
+	 * @throws DomainException
2935
+	 */
2936
+	public function display_admin_list_table_page_with_sidebar()
2937
+	{
2938
+		$this->_display_admin_list_table_page(true);
2939
+	}
2940
+
2941
+
2942
+	/**
2943
+	 * display_admin_list_table_page_with_no_sidebar
2944
+	 * generates HTML wrapper for an admin_page with list_table (but with no sidebar)
2945
+	 *
2946
+	 * @return void
2947
+	 * @throws EE_Error
2948
+	 * @throws DomainException
2949
+	 */
2950
+	public function display_admin_list_table_page_with_no_sidebar()
2951
+	{
2952
+		$this->_display_admin_list_table_page();
2953
+	}
2954
+
2955
+
2956
+	/**
2957
+	 * generates html wrapper for an admin_list_table page
2958
+	 *
2959
+	 * @param boolean $sidebar whether to display with sidebar or not.
2960
+	 * @return void
2961
+	 * @throws DomainException
2962
+	 * @throws EE_Error
2963
+	 */
2964
+	private function _display_admin_list_table_page($sidebar = false)
2965
+	{
2966
+		// setup search attributes
2967
+		$this->_set_search_attributes();
2968
+		$this->_template_args['current_page'] = $this->_wp_page_slug;
2969
+		$template_path = EE_ADMIN_TEMPLATE . 'admin_list_wrapper.template.php';
2970
+		$this->_template_args['table_url'] = defined('DOING_AJAX')
2971
+			? add_query_arg(array('noheader' => 'true', 'route' => $this->_req_action), $this->_admin_base_url)
2972
+			: add_query_arg(array('route' => $this->_req_action), $this->_admin_base_url);
2973
+		$this->_template_args['list_table'] = $this->_list_table_object;
2974
+		$this->_template_args['current_route'] = $this->_req_action;
2975
+		$this->_template_args['list_table_class'] = get_class($this->_list_table_object);
2976
+		$ajax_sorting_callback = $this->_list_table_object->get_ajax_sorting_callback();
2977
+		if (! empty($ajax_sorting_callback)) {
2978
+			$sortable_list_table_form_fields = wp_nonce_field(
2979
+				$ajax_sorting_callback . '_nonce',
2980
+				$ajax_sorting_callback . '_nonce',
2981
+				false,
2982
+				false
2983
+			);
2984
+			$sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_page" name="ajax_table_sort_page" value="'
2985
+												. $this->page_slug
2986
+												. '" />';
2987
+			$sortable_list_table_form_fields .= '<input type="hidden" id="ajax_table_sort_action" name="ajax_table_sort_action" value="'
2988
+												. $ajax_sorting_callback
2989
+												. '" />';
2990
+		} else {
2991
+			$sortable_list_table_form_fields = '';
2992
+		}
2993
+		$this->_template_args['sortable_list_table_form_fields'] = $sortable_list_table_form_fields;
2994
+		$hidden_form_fields = isset($this->_template_args['list_table_hidden_fields'])
2995
+			? $this->_template_args['list_table_hidden_fields']
2996
+			: '';
2997
+		$nonce_ref = $this->_req_action . '_nonce';
2998
+		$hidden_form_fields .= '<input type="hidden" name="'
2999
+							   . $nonce_ref
3000
+							   . '" value="'
3001
+							   . wp_create_nonce($nonce_ref)
3002
+							   . '">';
3003
+		$this->_template_args['list_table_hidden_fields'] = $hidden_form_fields;
3004
+		// display message about search results?
3005
+		$this->_template_args['before_list_table'] .= ! empty($this->_req_data['s'])
3006
+			? '<p class="ee-search-results">' . sprintf(
3007
+				esc_html__('Displaying search results for the search string: %1$s', 'event_espresso'),
3008
+				trim($this->_req_data['s'], '%')
3009
+			) . '</p>'
3010
+			: '';
3011
+		// filter before_list_table template arg
3012
+		$this->_template_args['before_list_table'] = apply_filters(
3013
+			'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_arg',
3014
+			$this->_template_args['before_list_table'],
3015
+			$this->page_slug,
3016
+			$this->_req_data,
3017
+			$this->_req_action
3018
+		);
3019
+		// convert to array and filter again
3020
+		// arrays are easier to inject new items in a specific location,
3021
+		// but would not be backwards compatible, so we have to add a new filter
3022
+		$this->_template_args['before_list_table'] = implode(
3023
+			" \n",
3024
+			(array) apply_filters(
3025
+				'FHEE__EE_Admin_Page___display_admin_list_table_page__before_list_table__template_args_array',
3026
+				(array) $this->_template_args['before_list_table'],
3027
+				$this->page_slug,
3028
+				$this->_req_data,
3029
+				$this->_req_action
3030
+			)
3031
+		);
3032
+		// filter after_list_table template arg
3033
+		$this->_template_args['after_list_table'] = apply_filters(
3034
+			'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_arg',
3035
+			$this->_template_args['after_list_table'],
3036
+			$this->page_slug,
3037
+			$this->_req_data,
3038
+			$this->_req_action
3039
+		);
3040
+		// convert to array and filter again
3041
+		// arrays are easier to inject new items in a specific location,
3042
+		// but would not be backwards compatible, so we have to add a new filter
3043
+		$this->_template_args['after_list_table'] = implode(
3044
+			" \n",
3045
+			(array) apply_filters(
3046
+				'FHEE__EE_Admin_Page___display_admin_list_table_page__after_list_table__template_args_array',
3047
+				(array) $this->_template_args['after_list_table'],
3048
+				$this->page_slug,
3049
+				$this->_req_data,
3050
+				$this->_req_action
3051
+			)
3052
+		);
3053
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
3054
+			$template_path,
3055
+			$this->_template_args,
3056
+			true
3057
+		);
3058
+		// the final template wrapper
3059
+		if ($sidebar) {
3060
+			$this->display_admin_page_with_sidebar();
3061
+		} else {
3062
+			$this->display_admin_page_with_no_sidebar();
3063
+		}
3064
+	}
3065
+
3066
+
3067
+	/**
3068
+	 * This just prepares a legend using the given items and the admin_details_legend.template.php file and returns the
3069
+	 * html string for the legend.
3070
+	 * $items are expected in an array in the following format:
3071
+	 * $legend_items = array(
3072
+	 *        'item_id' => array(
3073
+	 *            'icon' => 'http://url_to_icon_being_described.png',
3074
+	 *            'desc' => esc_html__('localized description of item');
3075
+	 *        )
3076
+	 * );
3077
+	 *
3078
+	 * @param  array $items see above for format of array
3079
+	 * @return string html string of legend
3080
+	 * @throws DomainException
3081
+	 */
3082
+	protected function _display_legend($items)
3083
+	{
3084
+		$this->_template_args['items'] = apply_filters(
3085
+			'FHEE__EE_Admin_Page___display_legend__items',
3086
+			(array) $items,
3087
+			$this
3088
+		);
3089
+		return EEH_Template::display_template(
3090
+			EE_ADMIN_TEMPLATE . 'admin_details_legend.template.php',
3091
+			$this->_template_args,
3092
+			true
3093
+		);
3094
+	}
3095
+
3096
+
3097
+	/**
3098
+	 * This is used whenever we're DOING_AJAX to return a formatted json array that our calling javascript can expect
3099
+	 * The returned json object is created from an array in the following format:
3100
+	 * array(
3101
+	 *  'error' => FALSE, //(default FALSE), contains any errors and/or exceptions (exceptions return json early),
3102
+	 *  'success' => FALSE, //(default FALSE) - contains any special success message.
3103
+	 *  'notices' => '', // - contains any EE_Error formatted notices
3104
+	 *  'content' => 'string can be html', //this is a string of formatted content (can be html)
3105
+	 *  'data' => array() //this can be any key/value pairs that a method returns for later json parsing by the js.
3106
+	 *  We're also going to include the template args with every package (so js can pick out any specific template args
3107
+	 *  that might be included in here)
3108
+	 * )
3109
+	 * The json object is populated by whatever is set in the $_template_args property.
3110
+	 *
3111
+	 * @param bool  $sticky_notices    Used to indicate whether you want to ensure notices are added to a transient
3112
+	 *                                 instead of displayed.
3113
+	 * @param array $notices_arguments Use this to pass any additional args on to the _process_notices.
3114
+	 * @return void
3115
+	 * @throws EE_Error
3116
+	 */
3117
+	protected function _return_json($sticky_notices = false, $notices_arguments = array())
3118
+	{
3119
+		// make sure any EE_Error notices have been handled.
3120
+		$this->_process_notices($notices_arguments, true, $sticky_notices);
3121
+		$data = isset($this->_template_args['data']) ? $this->_template_args['data'] : array();
3122
+		unset($this->_template_args['data']);
3123
+		$json = array(
3124
+			'error'     => isset($this->_template_args['error']) ? $this->_template_args['error'] : false,
3125
+			'success'   => isset($this->_template_args['success']) ? $this->_template_args['success'] : false,
3126
+			'errors'    => isset($this->_template_args['errors']) ? $this->_template_args['errors'] : false,
3127
+			'attention' => isset($this->_template_args['attention']) ? $this->_template_args['attention'] : false,
3128
+			'notices'   => EE_Error::get_notices(),
3129
+			'content'   => isset($this->_template_args['admin_page_content'])
3130
+				? $this->_template_args['admin_page_content'] : '',
3131
+			'data'      => array_merge($data, array('template_args' => $this->_template_args)),
3132
+			'isEEajax'  => true
3133
+			// special flag so any ajax.Success methods in js can identify this return package as a EEajax package.
3134
+		);
3135
+		// make sure there are no php errors or headers_sent.  Then we can set correct json header.
3136
+		if (null === error_get_last() || ! headers_sent()) {
3137
+			header('Content-Type: application/json; charset=UTF-8');
3138
+		}
3139
+		echo wp_json_encode($json);
3140
+		exit();
3141
+	}
3142
+
3143
+
3144
+	/**
3145
+	 * Simply a wrapper for the protected method so we can call this outside the class (ONLY when doing ajax)
3146
+	 *
3147
+	 * @return void
3148
+	 * @throws EE_Error
3149
+	 */
3150
+	public function return_json()
3151
+	{
3152
+		if (defined('DOING_AJAX') && DOING_AJAX) {
3153
+			$this->_return_json();
3154
+		} else {
3155
+			throw new EE_Error(
3156
+				sprintf(
3157
+					esc_html__('The public %s method can only be called when DOING_AJAX = TRUE', 'event_espresso'),
3158
+					__FUNCTION__
3159
+				)
3160
+			);
3161
+		}
3162
+	}
3163
+
3164
+
3165
+	/**
3166
+	 * This provides a way for child hook classes to send along themselves by reference so methods/properties within
3167
+	 * them can be accessed by EE_Admin_child pages. This is assigned to the $_hook_obj property.
3168
+	 *
3169
+	 * @param EE_Admin_Hooks $hook_obj This will be the object for the EE_Admin_Hooks child
3170
+	 */
3171
+	public function set_hook_object(EE_Admin_Hooks $hook_obj)
3172
+	{
3173
+		$this->_hook_obj = $hook_obj;
3174
+	}
3175
+
3176
+
3177
+	/**
3178
+	 *        generates  HTML wrapper with Tabbed nav for an admin page
3179
+	 *
3180
+	 * @param  boolean $about whether to use the special about page wrapper or default.
3181
+	 * @return void
3182
+	 * @throws DomainException
3183
+	 * @throws EE_Error
3184
+	 */
3185
+	public function admin_page_wrapper($about = false)
3186
+	{
3187
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3188
+		$this->_nav_tabs = $this->_get_main_nav_tabs();
3189
+		$this->_template_args['nav_tabs'] = $this->_nav_tabs;
3190
+		$this->_template_args['admin_page_title'] = $this->_admin_page_title;
3191
+		$this->_template_args['before_admin_page_content'] = apply_filters(
3192
+			"FHEE_before_admin_page_content{$this->_current_page}{$this->_current_view}",
3193
+			isset($this->_template_args['before_admin_page_content'])
3194
+				? $this->_template_args['before_admin_page_content']
3195
+				: ''
3196
+		);
3197
+		$this->_template_args['after_admin_page_content'] = apply_filters(
3198
+			"FHEE_after_admin_page_content{$this->_current_page}{$this->_current_view}",
3199
+			isset($this->_template_args['after_admin_page_content'])
3200
+				? $this->_template_args['after_admin_page_content']
3201
+				: ''
3202
+		);
3203
+		$this->_template_args['after_admin_page_content'] .= $this->_set_help_popup_content();
3204
+		// load settings page wrapper template
3205
+		$template_path = ! defined('DOING_AJAX')
3206
+			? EE_ADMIN_TEMPLATE . 'admin_wrapper.template.php'
3207
+			: EE_ADMIN_TEMPLATE
3208
+			  . 'admin_wrapper_ajax.template.php';
3209
+		// about page?
3210
+		$template_path = $about
3211
+			? EE_ADMIN_TEMPLATE . 'about_admin_wrapper.template.php'
3212
+			: $template_path;
3213
+		if (defined('DOING_AJAX')) {
3214
+			$this->_template_args['admin_page_content'] = EEH_Template::display_template(
3215
+				$template_path,
3216
+				$this->_template_args,
3217
+				true
3218
+			);
3219
+			$this->_return_json();
3220
+		} else {
3221
+			EEH_Template::display_template($template_path, $this->_template_args);
3222
+		}
3223
+	}
3224
+
3225
+
3226
+	/**
3227
+	 * This returns the admin_nav tabs html using the configuration in the _nav_tabs property
3228
+	 *
3229
+	 * @return string html
3230
+	 * @throws EE_Error
3231
+	 */
3232
+	protected function _get_main_nav_tabs()
3233
+	{
3234
+		// let's generate the html using the EEH_Tabbed_Content helper.
3235
+		// We do this here so that it's possible for child classes to add in nav tabs dynamically at the last minute
3236
+		// (rather than setting in the page_routes array)
3237
+		return EEH_Tabbed_Content::display_admin_nav_tabs($this->_nav_tabs);
3238
+	}
3239
+
3240
+
3241
+	/**
3242
+	 *        sort nav tabs
3243
+	 *
3244
+	 * @param $a
3245
+	 * @param $b
3246
+	 * @return int
3247
+	 */
3248
+	private function _sort_nav_tabs($a, $b)
3249
+	{
3250
+		if ($a['order'] === $b['order']) {
3251
+			return 0;
3252
+		}
3253
+		return ($a['order'] < $b['order']) ? -1 : 1;
3254
+	}
3255
+
3256
+
3257
+	/**
3258
+	 *    generates HTML for the forms used on admin pages
3259
+	 *
3260
+	 * @param    array $input_vars - array of input field details
3261
+	 * @param string   $generator  (options are 'string' or 'array', basically use this to indicate which generator to
3262
+	 *                             use)
3263
+	 * @param bool     $id
3264
+	 * @return string
3265
+	 * @uses   EEH_Form_Fields::get_form_fields (/helper/EEH_Form_Fields.helper.php)
3266
+	 * @uses   EEH_Form_Fields::get_form_fields_array (/helper/EEH_Form_Fields.helper.php)
3267
+	 */
3268
+	protected function _generate_admin_form_fields($input_vars = array(), $generator = 'string', $id = false)
3269
+	{
3270
+		$content = $generator === 'string'
3271
+			? EEH_Form_Fields::get_form_fields($input_vars, $id)
3272
+			: EEH_Form_Fields::get_form_fields_array($input_vars);
3273
+		return $content;
3274
+	}
3275
+
3276
+
3277
+	/**
3278
+	 * generates the "Save" and "Save & Close" buttons for edit forms
3279
+	 *
3280
+	 * @param bool             $both     if true then both buttons will be generated.  If false then just the "Save &
3281
+	 *                                   Close" button.
3282
+	 * @param array            $text     if included, generator will use the given text for the buttons ( array([0] =>
3283
+	 *                                   'Save', [1] => 'save & close')
3284
+	 * @param array            $actions  if included allows us to set the actions that each button will carry out (i.e.
3285
+	 *                                   via the "name" value in the button).  We can also use this to just dump
3286
+	 *                                   default actions by submitting some other value.
3287
+	 * @param bool|string|null $referrer if false then we just do the default action on save and close.  Other wise it
3288
+	 *                                   will use the $referrer string. IF null, then we don't do ANYTHING on save and
3289
+	 *                                   close (normal form handling).
3290
+	 */
3291
+	protected function _set_save_buttons($both = true, $text = array(), $actions = array(), $referrer = null)
3292
+	{
3293
+		// make sure $text and $actions are in an array
3294
+		$text = (array) $text;
3295
+		$actions = (array) $actions;
3296
+		$referrer_url = empty($referrer)
3297
+			? '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3298
+			  . $_SERVER['REQUEST_URI']
3299
+			  . '" />'
3300
+			: '<input type="hidden" id="save_and_close_referrer" name="save_and_close_referrer" value="'
3301
+			  . $referrer
3302
+			  . '" />';
3303
+		$button_text = ! empty($text)
3304
+			? $text
3305
+			: array(
3306
+				esc_html__('Save', 'event_espresso'),
3307
+				esc_html__('Save and Close', 'event_espresso'),
3308
+			);
3309
+		$default_names = array('save', 'save_and_close');
3310
+		// add in a hidden index for the current page (so save and close redirects properly)
3311
+		$this->_template_args['save_buttons'] = $referrer_url;
3312
+		foreach ($button_text as $key => $button) {
3313
+			$ref = $default_names[ $key ];
3314
+			$this->_template_args['save_buttons'] .= '<input type="submit" class="button-primary '
3315
+													 . $ref
3316
+													 . '" value="'
3317
+													 . $button
3318
+													 . '" name="'
3319
+													 . (! empty($actions) ? $actions[ $key ] : $ref)
3320
+													 . '" id="'
3321
+													 . $this->_current_view . '_' . $ref
3322
+													 . '" />';
3323
+			if (! $both) {
3324
+				break;
3325
+			}
3326
+		}
3327
+	}
3328
+
3329
+
3330
+	/**
3331
+	 * Wrapper for the protected function.  Allows plugins/addons to call this to set the form tags.
3332
+	 *
3333
+	 * @see   $this->_set_add_edit_form_tags() for details on params
3334
+	 * @since 4.6.0
3335
+	 * @param string $route
3336
+	 * @param array  $additional_hidden_fields
3337
+	 */
3338
+	public function set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3339
+	{
3340
+		$this->_set_add_edit_form_tags($route, $additional_hidden_fields);
3341
+	}
3342
+
3343
+
3344
+	/**
3345
+	 * set form open and close tags on add/edit pages.
3346
+	 *
3347
+	 * @param string $route                    the route you want the form to direct to
3348
+	 * @param array  $additional_hidden_fields any additional hidden fields required in the form header
3349
+	 * @return void
3350
+	 */
3351
+	protected function _set_add_edit_form_tags($route = '', $additional_hidden_fields = array())
3352
+	{
3353
+		if (empty($route)) {
3354
+			$user_msg = esc_html__(
3355
+				'An error occurred. No action was set for this page\'s form.',
3356
+				'event_espresso'
3357
+			);
3358
+			$dev_msg = $user_msg . "\n"
3359
+					   . sprintf(
3360
+						   esc_html__('The $route argument is required for the %s->%s method.', 'event_espresso'),
3361
+						   __FUNCTION__,
3362
+						   __CLASS__
3363
+					   );
3364
+			EE_Error::add_error($user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__);
3365
+		}
3366
+		// open form
3367
+		$this->_template_args['before_admin_page_content'] = '<form name="form" method="post" action="'
3368
+															 . $this->_admin_base_url
3369
+															 . '" id="'
3370
+															 . $route
3371
+															 . '_event_form" >';
3372
+		// add nonce
3373
+		$nonce = wp_nonce_field($route . '_nonce', $route . '_nonce', false, false);
3374
+		$this->_template_args['before_admin_page_content'] .= "\n\t" . $nonce;
3375
+		// add REQUIRED form action
3376
+		$hidden_fields = array(
3377
+			'action' => array('type' => 'hidden', 'value' => $route),
3378
+		);
3379
+		// merge arrays
3380
+		$hidden_fields = is_array($additional_hidden_fields)
3381
+			? array_merge($hidden_fields, $additional_hidden_fields)
3382
+			: $hidden_fields;
3383
+		// generate form fields
3384
+		$form_fields = $this->_generate_admin_form_fields($hidden_fields, 'array');
3385
+		// add fields to form
3386
+		foreach ((array) $form_fields as $field_name => $form_field) {
3387
+			$this->_template_args['before_admin_page_content'] .= "\n\t" . $form_field['field'];
3388
+		}
3389
+		// close form
3390
+		$this->_template_args['after_admin_page_content'] = '</form>';
3391
+	}
3392
+
3393
+
3394
+	/**
3395
+	 * Public Wrapper for _redirect_after_action() method since its
3396
+	 * discovered it would be useful for external code to have access.
3397
+	 *
3398
+	 * @see   EE_Admin_Page::_redirect_after_action() for params.
3399
+	 * @since 4.5.0
3400
+	 * @param bool   $success
3401
+	 * @param string $what
3402
+	 * @param string $action_desc
3403
+	 * @param array  $query_args
3404
+	 * @param bool   $override_overwrite
3405
+	 * @throws EE_Error
3406
+	 */
3407
+	public function redirect_after_action(
3408
+		$success = false,
3409
+		$what = 'item',
3410
+		$action_desc = 'processed',
3411
+		$query_args = array(),
3412
+		$override_overwrite = false
3413
+	) {
3414
+		$this->_redirect_after_action(
3415
+			$success,
3416
+			$what,
3417
+			$action_desc,
3418
+			$query_args,
3419
+			$override_overwrite
3420
+		);
3421
+	}
3422
+
3423
+
3424
+	/**
3425
+	 * Helper method for merging existing request data with the returned redirect url.
3426
+	 *
3427
+	 * This is typically used for redirects after an action so that if the original view was a filtered view those
3428
+	 * filters are still applied.
3429
+	 *
3430
+	 * @param array $new_route_data
3431
+	 * @return array
3432
+	 */
3433
+	protected function mergeExistingRequestParamsWithRedirectArgs(array $new_route_data)
3434
+	{
3435
+		foreach ($this->_req_data as $ref => $value) {
3436
+			// unset nonces
3437
+			if (strpos($ref, 'nonce') !== false) {
3438
+				unset($this->_req_data[ $ref ]);
3439
+				continue;
3440
+			}
3441
+			// urlencode values.
3442
+			$value = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
3443
+			$this->_req_data[ $ref ] = $value;
3444
+		}
3445
+		return array_merge($this->_req_data, $new_route_data);
3446
+	}
3447
+
3448
+
3449
+	/**
3450
+	 *    _redirect_after_action
3451
+	 *
3452
+	 * @param int    $success            - whether success was for two or more records, or just one, or none
3453
+	 * @param string $what               - what the action was performed on
3454
+	 * @param string $action_desc        - what was done ie: updated, deleted, etc
3455
+	 * @param array  $query_args         - an array of query_args to be added to the URL to redirect to after the admin
3456
+	 *                                   action is completed
3457
+	 * @param BOOL   $override_overwrite by default all EE_Error::success messages are overwritten, this allows you to
3458
+	 *                                   override this so that they show.
3459
+	 * @return void
3460
+	 * @throws EE_Error
3461
+	 */
3462
+	protected function _redirect_after_action(
3463
+		$success = 0,
3464
+		$what = 'item',
3465
+		$action_desc = 'processed',
3466
+		$query_args = array(),
3467
+		$override_overwrite = false
3468
+	) {
3469
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3470
+		// class name for actions/filters.
3471
+		$classname = get_class($this);
3472
+		// set redirect url.
3473
+		// Note if there is a "page" index in the $query_args then we go with vanilla admin.php route,
3474
+		// otherwise we go with whatever is set as the _admin_base_url
3475
+		$redirect_url = isset($query_args['page']) ? admin_url('admin.php') : $this->_admin_base_url;
3476
+		$notices = EE_Error::get_notices(false);
3477
+		// overwrite default success messages //BUT ONLY if overwrite not overridden
3478
+		if (! $override_overwrite || ! empty($notices['errors'])) {
3479
+			EE_Error::overwrite_success();
3480
+		}
3481
+		if (! empty($what) && ! empty($action_desc) && empty($notices['errors'])) {
3482
+			// how many records affected ? more than one record ? or just one ?
3483
+			if ($success > 1) {
3484
+				// set plural msg
3485
+				EE_Error::add_success(
3486
+					sprintf(
3487
+						esc_html__('The "%s" have been successfully %s.', 'event_espresso'),
3488
+						$what,
3489
+						$action_desc
3490
+					),
3491
+					__FILE__,
3492
+					__FUNCTION__,
3493
+					__LINE__
3494
+				);
3495
+			} elseif ($success === 1) {
3496
+				// set singular msg
3497
+				EE_Error::add_success(
3498
+					sprintf(
3499
+						esc_html__('The "%s" has been successfully %s.', 'event_espresso'),
3500
+						$what,
3501
+						$action_desc
3502
+					),
3503
+					__FILE__,
3504
+					__FUNCTION__,
3505
+					__LINE__
3506
+				);
3507
+			}
3508
+		}
3509
+		// check that $query_args isn't something crazy
3510
+		if (! is_array($query_args)) {
3511
+			$query_args = array();
3512
+		}
3513
+		/**
3514
+		 * Allow injecting actions before the query_args are modified for possible different
3515
+		 * redirections on save and close actions
3516
+		 *
3517
+		 * @since 4.2.0
3518
+		 * @param array $query_args       The original query_args array coming into the
3519
+		 *                                method.
3520
+		 */
3521
+		do_action(
3522
+			"AHEE__{$classname}___redirect_after_action__before_redirect_modification_{$this->_req_action}",
3523
+			$query_args
3524
+		);
3525
+		// calculate where we're going (if we have a "save and close" button pushed)
3526
+		if (isset($this->_req_data['save_and_close'], $this->_req_data['save_and_close_referrer'])) {
3527
+			// even though we have the save_and_close referrer, we need to parse the url for the action in order to generate a nonce
3528
+			$parsed_url = parse_url($this->_req_data['save_and_close_referrer']);
3529
+			// regenerate query args array from referrer URL
3530
+			parse_str($parsed_url['query'], $query_args);
3531
+			// correct page and action will be in the query args now
3532
+			$redirect_url = admin_url('admin.php');
3533
+		}
3534
+		// merge any default query_args set in _default_route_query_args property
3535
+		if (! empty($this->_default_route_query_args) && ! $this->_is_UI_request) {
3536
+			$args_to_merge = array();
3537
+			foreach ($this->_default_route_query_args as $query_param => $query_value) {
3538
+				// is there a wp_referer array in our _default_route_query_args property?
3539
+				if ($query_param === 'wp_referer') {
3540
+					$query_value = (array) $query_value;
3541
+					foreach ($query_value as $reference => $value) {
3542
+						if (strpos($reference, 'nonce') !== false) {
3543
+							continue;
3544
+						}
3545
+						// finally we will override any arguments in the referer with
3546
+						// what might be set on the _default_route_query_args array.
3547
+						if (isset($this->_default_route_query_args[ $reference ])) {
3548
+							$args_to_merge[ $reference ] = urlencode($this->_default_route_query_args[ $reference ]);
3549
+						} else {
3550
+							$args_to_merge[ $reference ] = urlencode($value);
3551
+						}
3552
+					}
3553
+					continue;
3554
+				}
3555
+				$args_to_merge[ $query_param ] = $query_value;
3556
+			}
3557
+			// now let's merge these arguments but override with what was specifically sent in to the
3558
+			// redirect.
3559
+			$query_args = array_merge($args_to_merge, $query_args);
3560
+		}
3561
+		$this->_process_notices($query_args);
3562
+		// generate redirect url
3563
+		// if redirecting to anything other than the main page, add a nonce
3564
+		if (isset($query_args['action'])) {
3565
+			// manually generate wp_nonce and merge that with the query vars
3566
+			// becuz the wp_nonce_url function wrecks havoc on some vars
3567
+			$query_args['_wpnonce'] = wp_create_nonce($query_args['action'] . '_nonce');
3568
+		}
3569
+		// we're adding some hooks and filters in here for processing any things just before redirects
3570
+		// (example: an admin page has done an insert or update and we want to run something after that).
3571
+		do_action('AHEE_redirect_' . $classname . $this->_req_action, $query_args);
3572
+		$redirect_url = apply_filters(
3573
+			'FHEE_redirect_' . $classname . $this->_req_action,
3574
+			self::add_query_args_and_nonce($query_args, $redirect_url),
3575
+			$query_args
3576
+		);
3577
+		// check if we're doing ajax.  If we are then lets just return the results and js can handle how it wants.
3578
+		if (defined('DOING_AJAX')) {
3579
+			$default_data = array(
3580
+				'close'        => true,
3581
+				'redirect_url' => $redirect_url,
3582
+				'where'        => 'main',
3583
+				'what'         => 'append',
3584
+			);
3585
+			$this->_template_args['success'] = $success;
3586
+			$this->_template_args['data'] = ! empty($this->_template_args['data']) ? array_merge(
3587
+				$default_data,
3588
+				$this->_template_args['data']
3589
+			) : $default_data;
3590
+			$this->_return_json();
3591
+		}
3592
+		wp_safe_redirect($redirect_url);
3593
+		exit();
3594
+	}
3595
+
3596
+
3597
+	/**
3598
+	 * process any notices before redirecting (or returning ajax request)
3599
+	 * This method sets the $this->_template_args['notices'] attribute;
3600
+	 *
3601
+	 * @param  array $query_args        any query args that need to be used for notice transient ('action')
3602
+	 * @param bool   $skip_route_verify This is typically used when we are processing notices REALLY early and
3603
+	 *                                  page_routes haven't been defined yet.
3604
+	 * @param bool   $sticky_notices    This is used to flag that regardless of whether this is doing_ajax or not, we
3605
+	 *                                  still save a transient for the notice.
3606
+	 * @return void
3607
+	 * @throws EE_Error
3608
+	 */
3609
+	protected function _process_notices($query_args = array(), $skip_route_verify = false, $sticky_notices = true)
3610
+	{
3611
+		// first let's set individual error properties if doing_ajax and the properties aren't already set.
3612
+		if (defined('DOING_AJAX') && DOING_AJAX) {
3613
+			$notices = EE_Error::get_notices(false);
3614
+			if (empty($this->_template_args['success'])) {
3615
+				$this->_template_args['success'] = isset($notices['success']) ? $notices['success'] : false;
3616
+			}
3617
+			if (empty($this->_template_args['errors'])) {
3618
+				$this->_template_args['errors'] = isset($notices['errors']) ? $notices['errors'] : false;
3619
+			}
3620
+			if (empty($this->_template_args['attention'])) {
3621
+				$this->_template_args['attention'] = isset($notices['attention']) ? $notices['attention'] : false;
3622
+			}
3623
+		}
3624
+		$this->_template_args['notices'] = EE_Error::get_notices();
3625
+		// IF this isn't ajax we need to create a transient for the notices using the route (however, overridden if $sticky_notices == true)
3626
+		if (! defined('DOING_AJAX') || $sticky_notices) {
3627
+			$route = isset($query_args['action']) ? $query_args['action'] : 'default';
3628
+			$this->_add_transient(
3629
+				$route,
3630
+				$this->_template_args['notices'],
3631
+				true,
3632
+				$skip_route_verify
3633
+			);
3634
+		}
3635
+	}
3636
+
3637
+
3638
+	/**
3639
+	 * get_action_link_or_button
3640
+	 * returns the button html for adding, editing, or deleting an item (depending on given type)
3641
+	 *
3642
+	 * @param string $action        use this to indicate which action the url is generated with.
3643
+	 * @param string $type          accepted strings must be defined in the $_labels['button'] array(as the key)
3644
+	 *                              property.
3645
+	 * @param array  $extra_request if the button requires extra params you can include them in $key=>$value pairs.
3646
+	 * @param string $class         Use this to give the class for the button. Defaults to 'button-primary'
3647
+	 * @param string $base_url      If this is not provided
3648
+	 *                              the _admin_base_url will be used as the default for the button base_url.
3649
+	 *                              Otherwise this value will be used.
3650
+	 * @param bool   $exclude_nonce If true then no nonce will be in the generated button link.
3651
+	 * @return string
3652
+	 * @throws InvalidArgumentException
3653
+	 * @throws InvalidInterfaceException
3654
+	 * @throws InvalidDataTypeException
3655
+	 * @throws EE_Error
3656
+	 */
3657
+	public function get_action_link_or_button(
3658
+		$action,
3659
+		$type = 'add',
3660
+		$extra_request = array(),
3661
+		$class = 'button-primary',
3662
+		$base_url = '',
3663
+		$exclude_nonce = false
3664
+	) {
3665
+		// first let's validate the action (if $base_url is FALSE otherwise validation will happen further along)
3666
+		if (empty($base_url) && ! isset($this->_page_routes[ $action ])) {
3667
+			throw new EE_Error(
3668
+				sprintf(
3669
+					esc_html__(
3670
+						'There is no page route for given action for the button.  This action was given: %s',
3671
+						'event_espresso'
3672
+					),
3673
+					$action
3674
+				)
3675
+			);
3676
+		}
3677
+		if (! isset($this->_labels['buttons'][ $type ])) {
3678
+			throw new EE_Error(
3679
+				sprintf(
3680
+					__(
3681
+						'There is no label for the given button type (%s). Labels are set in the <code>_page_config</code> property.',
3682
+						'event_espresso'
3683
+					),
3684
+					$type
3685
+				)
3686
+			);
3687
+		}
3688
+		// finally check user access for this button.
3689
+		$has_access = $this->check_user_access($action, true);
3690
+		if (! $has_access) {
3691
+			return '';
3692
+		}
3693
+		$_base_url = ! $base_url ? $this->_admin_base_url : $base_url;
3694
+		$query_args = array(
3695
+			'action' => $action,
3696
+		);
3697
+		// merge extra_request args but make sure our original action takes precedence and doesn't get overwritten.
3698
+		if (! empty($extra_request)) {
3699
+			$query_args = array_merge($extra_request, $query_args);
3700
+		}
3701
+		$url = self::add_query_args_and_nonce($query_args, $_base_url, false, $exclude_nonce);
3702
+		return EEH_Template::get_button_or_link($url, $this->_labels['buttons'][ $type ], $class);
3703
+	}
3704
+
3705
+
3706
+	/**
3707
+	 * _per_page_screen_option
3708
+	 * Utility function for adding in a per_page_option in the screen_options_dropdown.
3709
+	 *
3710
+	 * @return void
3711
+	 * @throws InvalidArgumentException
3712
+	 * @throws InvalidInterfaceException
3713
+	 * @throws InvalidDataTypeException
3714
+	 */
3715
+	protected function _per_page_screen_option()
3716
+	{
3717
+		$option = 'per_page';
3718
+		$args = array(
3719
+			'label'   => apply_filters(
3720
+				'FHEE__EE_Admin_Page___per_page_screen_options___label',
3721
+				$this->_admin_page_title,
3722
+				$this
3723
+			),
3724
+			'default' => (int) apply_filters(
3725
+				'FHEE__EE_Admin_Page___per_page_screen_options__default',
3726
+				20
3727
+			),
3728
+			'option'  => $this->_current_page . '_' . $this->_current_view . '_per_page',
3729
+		);
3730
+		// ONLY add the screen option if the user has access to it.
3731
+		if ($this->check_user_access($this->_current_view, true)) {
3732
+			add_screen_option($option, $args);
3733
+		}
3734
+	}
3735
+
3736
+
3737
+	/**
3738
+	 * set_per_page_screen_option
3739
+	 * All this does is make sure that WordPress saves any per_page screen options (if set) for the current page.
3740
+	 * we have to do this rather than running inside the 'set-screen-options' hook because it runs earlier than
3741
+	 * admin_menu.
3742
+	 *
3743
+	 * @return void
3744
+	 */
3745
+	private function _set_per_page_screen_options()
3746
+	{
3747
+		if (isset($_POST['wp_screen_options']) && is_array($_POST['wp_screen_options'])) {
3748
+			check_admin_referer('screen-options-nonce', 'screenoptionnonce');
3749
+			if (! $user = wp_get_current_user()) {
3750
+				return;
3751
+			}
3752
+			$option = $_POST['wp_screen_options']['option'];
3753
+			$value = $_POST['wp_screen_options']['value'];
3754
+			if ($option != sanitize_key($option)) {
3755
+				return;
3756
+			}
3757
+			$map_option = $option;
3758
+			$option = str_replace('-', '_', $option);
3759
+			switch ($map_option) {
3760
+				case $this->_current_page . '_' . $this->_current_view . '_per_page':
3761
+					$value = (int) $value;
3762
+					$max_value = apply_filters(
3763
+						'FHEE__EE_Admin_Page___set_per_page_screen_options__max_value',
3764
+						999,
3765
+						$this->_current_page,
3766
+						$this->_current_view
3767
+					);
3768
+					if ($value < 1) {
3769
+						return;
3770
+					}
3771
+					$value = min($value, $max_value);
3772
+					break;
3773
+				default:
3774
+					$value = apply_filters(
3775
+						'FHEE__EE_Admin_Page___set_per_page_screen_options__value',
3776
+						false,
3777
+						$option,
3778
+						$value
3779
+					);
3780
+					if (false === $value) {
3781
+						return;
3782
+					}
3783
+					break;
3784
+			}
3785
+			update_user_meta($user->ID, $option, $value);
3786
+			wp_safe_redirect(remove_query_arg(array('pagenum', 'apage', 'paged'), wp_get_referer()));
3787
+			exit;
3788
+		}
3789
+	}
3790
+
3791
+
3792
+	/**
3793
+	 * This just allows for setting the $_template_args property if it needs to be set outside the object
3794
+	 *
3795
+	 * @param array $data array that will be assigned to template args.
3796
+	 */
3797
+	public function set_template_args($data)
3798
+	{
3799
+		$this->_template_args = array_merge($this->_template_args, (array) $data);
3800
+	}
3801
+
3802
+
3803
+	/**
3804
+	 * This makes available the WP transient system for temporarily moving data between routes
3805
+	 *
3806
+	 * @param string $route             the route that should receive the transient
3807
+	 * @param array  $data              the data that gets sent
3808
+	 * @param bool   $notices           If this is for notices then we use this to indicate so, otherwise its just a
3809
+	 *                                  normal route transient.
3810
+	 * @param bool   $skip_route_verify Used to indicate we want to skip route verification.  This is usually ONLY used
3811
+	 *                                  when we are adding a transient before page_routes have been defined.
3812
+	 * @return void
3813
+	 * @throws EE_Error
3814
+	 */
3815
+	protected function _add_transient($route, $data, $notices = false, $skip_route_verify = false)
3816
+	{
3817
+		$user_id = get_current_user_id();
3818
+		if (! $skip_route_verify) {
3819
+			$this->_verify_route($route);
3820
+		}
3821
+		// now let's set the string for what kind of transient we're setting
3822
+		$transient = $notices
3823
+			? 'ee_rte_n_tx_' . $route . '_' . $user_id
3824
+			: 'rte_tx_' . $route . '_' . $user_id;
3825
+		$data = $notices ? array('notices' => $data) : $data;
3826
+		// is there already a transient for this route?  If there is then let's ADD to that transient
3827
+		$existing = is_multisite() && is_network_admin()
3828
+			? get_site_transient($transient)
3829
+			: get_transient($transient);
3830
+		if ($existing) {
3831
+			$data = array_merge((array) $data, (array) $existing);
3832
+		}
3833
+		if (is_multisite() && is_network_admin()) {
3834
+			set_site_transient($transient, $data, 8);
3835
+		} else {
3836
+			set_transient($transient, $data, 8);
3837
+		}
3838
+	}
3839
+
3840
+
3841
+	/**
3842
+	 * this retrieves the temporary transient that has been set for moving data between routes.
3843
+	 *
3844
+	 * @param bool   $notices true we get notices transient. False we just return normal route transient
3845
+	 * @param string $route
3846
+	 * @return mixed data
3847
+	 */
3848
+	protected function _get_transient($notices = false, $route = '')
3849
+	{
3850
+		$user_id = get_current_user_id();
3851
+		$route = ! $route ? $this->_req_action : $route;
3852
+		$transient = $notices
3853
+			? 'ee_rte_n_tx_' . $route . '_' . $user_id
3854
+			: 'rte_tx_' . $route . '_' . $user_id;
3855
+		$data = is_multisite() && is_network_admin()
3856
+			? get_site_transient($transient)
3857
+			: get_transient($transient);
3858
+		// delete transient after retrieval (just in case it hasn't expired);
3859
+		if (is_multisite() && is_network_admin()) {
3860
+			delete_site_transient($transient);
3861
+		} else {
3862
+			delete_transient($transient);
3863
+		}
3864
+		return $notices && isset($data['notices']) ? $data['notices'] : $data;
3865
+	}
3866
+
3867
+
3868
+	/**
3869
+	 * The purpose of this method is just to run garbage collection on any EE transients that might have expired but
3870
+	 * would not be called later. This will be assigned to run on a specific EE Admin page. (place the method in the
3871
+	 * default route callback on the EE_Admin page you want it run.)
3872
+	 *
3873
+	 * @return void
3874
+	 */
3875
+	protected function _transient_garbage_collection()
3876
+	{
3877
+		global $wpdb;
3878
+		// retrieve all existing transients
3879
+		$query = "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%rte_tx_%' OR option_name LIKE '%rte_n_tx_%'";
3880
+		if ($results = $wpdb->get_results($query)) {
3881
+			foreach ($results as $result) {
3882
+				$transient = str_replace('_transient_', '', $result->option_name);
3883
+				get_transient($transient);
3884
+				if (is_multisite() && is_network_admin()) {
3885
+					get_site_transient($transient);
3886
+				}
3887
+			}
3888
+		}
3889
+	}
3890
+
3891
+
3892
+	/**
3893
+	 * get_view
3894
+	 *
3895
+	 * @return string content of _view property
3896
+	 */
3897
+	public function get_view()
3898
+	{
3899
+		return $this->_view;
3900
+	}
3901
+
3902
+
3903
+	/**
3904
+	 * getter for the protected $_views property
3905
+	 *
3906
+	 * @return array
3907
+	 */
3908
+	public function get_views()
3909
+	{
3910
+		return $this->_views;
3911
+	}
3912
+
3913
+
3914
+	/**
3915
+	 * get_current_page
3916
+	 *
3917
+	 * @return string _current_page property value
3918
+	 */
3919
+	public function get_current_page()
3920
+	{
3921
+		return $this->_current_page;
3922
+	}
3923
+
3924
+
3925
+	/**
3926
+	 * get_current_view
3927
+	 *
3928
+	 * @return string _current_view property value
3929
+	 */
3930
+	public function get_current_view()
3931
+	{
3932
+		return $this->_current_view;
3933
+	}
3934
+
3935
+
3936
+	/**
3937
+	 * get_current_screen
3938
+	 *
3939
+	 * @return object The current WP_Screen object
3940
+	 */
3941
+	public function get_current_screen()
3942
+	{
3943
+		return $this->_current_screen;
3944
+	}
3945
+
3946
+
3947
+	/**
3948
+	 * get_current_page_view_url
3949
+	 *
3950
+	 * @return string This returns the url for the current_page_view.
3951
+	 */
3952
+	public function get_current_page_view_url()
3953
+	{
3954
+		return $this->_current_page_view_url;
3955
+	}
3956
+
3957
+
3958
+	/**
3959
+	 * just returns the _req_data property
3960
+	 *
3961
+	 * @return array
3962
+	 */
3963
+	public function get_request_data()
3964
+	{
3965
+		return $this->_req_data;
3966
+	}
3967
+
3968
+
3969
+	/**
3970
+	 * returns the _req_data protected property
3971
+	 *
3972
+	 * @return string
3973
+	 */
3974
+	public function get_req_action()
3975
+	{
3976
+		return $this->_req_action;
3977
+	}
3978
+
3979
+
3980
+	/**
3981
+	 * @return bool  value of $_is_caf property
3982
+	 */
3983
+	public function is_caf()
3984
+	{
3985
+		return $this->_is_caf;
3986
+	}
3987
+
3988
+
3989
+	/**
3990
+	 * @return mixed
3991
+	 */
3992
+	public function default_espresso_metaboxes()
3993
+	{
3994
+		return $this->_default_espresso_metaboxes;
3995
+	}
3996
+
3997
+
3998
+	/**
3999
+	 * @return mixed
4000
+	 */
4001
+	public function admin_base_url()
4002
+	{
4003
+		return $this->_admin_base_url;
4004
+	}
4005
+
4006
+
4007
+	/**
4008
+	 * @return mixed
4009
+	 */
4010
+	public function wp_page_slug()
4011
+	{
4012
+		return $this->_wp_page_slug;
4013
+	}
4014
+
4015
+
4016
+	/**
4017
+	 * updates  espresso configuration settings
4018
+	 *
4019
+	 * @param string                   $tab
4020
+	 * @param EE_Config_Base|EE_Config $config
4021
+	 * @param string                   $file file where error occurred
4022
+	 * @param string                   $func function  where error occurred
4023
+	 * @param string                   $line line no where error occurred
4024
+	 * @return boolean
4025
+	 */
4026
+	protected function _update_espresso_configuration($tab, $config, $file = '', $func = '', $line = '')
4027
+	{
4028
+		// remove any options that are NOT going to be saved with the config settings.
4029
+		if (isset($config->core->ee_ueip_optin)) {
4030
+			// TODO: remove the following two lines and make sure values are migrated from 3.1
4031
+			update_option('ee_ueip_optin', $config->core->ee_ueip_optin);
4032
+			update_option('ee_ueip_has_notified', true);
4033
+		}
4034
+		// and save it (note we're also doing the network save here)
4035
+		$net_saved = is_main_site() ? EE_Network_Config::instance()->update_config(false, false) : true;
4036
+		$config_saved = EE_Config::instance()->update_espresso_config(false, false);
4037
+		if ($config_saved && $net_saved) {
4038
+			EE_Error::add_success(sprintf(__('"%s" have been successfully updated.', 'event_espresso'), $tab));
4039
+			return true;
4040
+		}
4041
+		EE_Error::add_error(sprintf(__('The "%s" were not updated.', 'event_espresso'), $tab), $file, $func, $line);
4042
+		return false;
4043
+	}
4044
+
4045
+
4046
+	/**
4047
+	 * Returns an array to be used for EE_FOrm_Fields.helper.php's select_input as the $values argument.
4048
+	 *
4049
+	 * @return array
4050
+	 */
4051
+	public function get_yes_no_values()
4052
+	{
4053
+		return $this->_yes_no_values;
4054
+	}
4055
+
4056
+
4057
+	protected function _get_dir()
4058
+	{
4059
+		$reflector = new ReflectionClass(get_class($this));
4060
+		return dirname($reflector->getFileName());
4061
+	}
4062
+
4063
+
4064
+	/**
4065
+	 * A helper for getting a "next link".
4066
+	 *
4067
+	 * @param string $url   The url to link to
4068
+	 * @param string $class The class to use.
4069
+	 * @return string
4070
+	 */
4071
+	protected function _next_link($url, $class = 'dashicons dashicons-arrow-right')
4072
+	{
4073
+		return '<a class="' . $class . '" href="' . $url . '"></a>';
4074
+	}
4075
+
4076
+
4077
+	/**
4078
+	 * A helper for getting a "previous link".
4079
+	 *
4080
+	 * @param string $url   The url to link to
4081
+	 * @param string $class The class to use.
4082
+	 * @return string
4083
+	 */
4084
+	protected function _previous_link($url, $class = 'dashicons dashicons-arrow-left')
4085
+	{
4086
+		return '<a class="' . $class . '" href="' . $url . '"></a>';
4087
+	}
4088
+
4089
+
4090
+
4091
+
4092
+
4093
+
4094
+
4095
+	// below are some messages related methods that should be available across the EE_Admin system.  Note, these methods are NOT page specific
4096
+
4097
+
4098
+	/**
4099
+	 * This processes an request to resend a registration and assumes we have a _REG_ID for doing so. So if the caller
4100
+	 * knows that the _REG_ID isn't in the req_data array but CAN obtain it, the caller should ADD the _REG_ID to the
4101
+	 * _req_data array.
4102
+	 *
4103
+	 * @return bool success/fail
4104
+	 * @throws EE_Error
4105
+	 * @throws InvalidArgumentException
4106
+	 * @throws ReflectionException
4107
+	 * @throws InvalidDataTypeException
4108
+	 * @throws InvalidInterfaceException
4109
+	 */
4110
+	protected function _process_resend_registration()
4111
+	{
4112
+		$this->_template_args['success'] = EED_Messages::process_resend($this->_req_data);
4113
+		do_action(
4114
+			'AHEE__EE_Admin_Page___process_resend_registration',
4115
+			$this->_template_args['success'],
4116
+			$this->_req_data
4117
+		);
4118
+		return $this->_template_args['success'];
4119
+	}
4120
+
4121
+
4122
+	/**
4123
+	 * This automatically processes any payment message notifications when manual payment has been applied.
4124
+	 *
4125
+	 * @param \EE_Payment $payment
4126
+	 * @return bool success/fail
4127
+	 */
4128
+	protected function _process_payment_notification(EE_Payment $payment)
4129
+	{
4130
+		add_filter('FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', '__return_true');
4131
+		do_action('AHEE__EE_Admin_Page___process_admin_payment_notification', $payment);
4132
+		$this->_template_args['success'] = apply_filters(
4133
+			'FHEE__EE_Admin_Page___process_admin_payment_notification__success',
4134
+			false,
4135
+			$payment
4136
+		);
4137
+		return $this->_template_args['success'];
4138
+	}
4139 4139
 }
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_CPT.core.php 2 patches
Indentation   +1469 added lines, -1469 removed lines patch added patch discarded remove patch
@@ -28,494 +28,494 @@  discard block
 block discarded – undo
28 28
 {
29 29
 
30 30
 
31
-    /**
32
-     * This gets set in _setup_cpt
33
-     * It will contain the object for the custom post type.
34
-     *
35
-     * @var EE_CPT_Base
36
-     */
37
-    protected $_cpt_object;
38
-
39
-
40
-    /**
41
-     * a boolean flag to set whether the current route is a cpt route or not.
42
-     *
43
-     * @var bool
44
-     */
45
-    protected $_cpt_route = false;
46
-
47
-
48
-    /**
49
-     * This property allows cpt classes to define multiple routes as cpt routes.
50
-     * //in this array we define what the custom post type for this route is.
51
-     * array(
52
-     * 'route_name' => 'custom_post_type_slug'
53
-     * )
54
-     *
55
-     * @var array
56
-     */
57
-    protected $_cpt_routes = array();
58
-
59
-
60
-    /**
61
-     * This simply defines what the corresponding routes WP will be redirected to after completing a post save/update.
62
-     * in this format:
63
-     * array(
64
-     * 'post_type_slug' => 'edit_route'
65
-     * )
66
-     *
67
-     * @var array
68
-     */
69
-    protected $_cpt_edit_routes = array();
70
-
71
-
72
-    /**
73
-     * If child classes set the name of their main model via the $_cpt_obj_models property, EE_Admin_Page_CPT will
74
-     * attempt to retrieve the related object model for the edit pages and assign it to _cpt_page_object. the
75
-     * _cpt_model_names property should be in the following format: array(
76
-     * 'route_defined_by_action_param' => 'Model_Name')
77
-     *
78
-     * @var array $_cpt_model_names
79
-     */
80
-    protected $_cpt_model_names = array();
81
-
82
-
83
-    /**
84
-     * @var EE_CPT_Base
85
-     */
86
-    protected $_cpt_model_obj = false;
87
-
88
-    /**
89
-     * @var LoaderInterface $loader ;
90
-     */
91
-    protected $loader;
92
-
93
-    /**
94
-     * This will hold an array of autosave containers that will be used to obtain input values and hook into the WP
95
-     * autosave so we can save our inputs on the save_post hook!  Children classes should add to this array by using
96
-     * the _register_autosave_containers() method so that we don't override any other containers already registered.
97
-     * Registration of containers should be done before load_page_dependencies() is run.
98
-     *
99
-     * @var array()
100
-     */
101
-    protected $_autosave_containers = array();
102
-    protected $_autosave_fields = array();
103
-
104
-    /**
105
-     * Array mapping from admin actions to their equivalent wp core pages for custom post types. So when a user visits
106
-     * a page for an action, it will appear as if they were visiting the wp core page for that custom post type
107
-     *
108
-     * @var array
109
-     */
110
-    protected $_pagenow_map;
111
-
112
-
113
-    /**
114
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
115
-     * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
116
-     * data. Keep in mind also that "save_post" runs on EVERY post update to the database. ALSO very important.  When a
117
-     * post transitions from scheduled to published, the save_post action is fired but you will NOT have any _POST data
118
-     * containing any extra info you may have from other meta saves.  So MAKE sure that you handle this accordingly.
119
-     *
120
-     * @access protected
121
-     * @abstract
122
-     * @param  string      $post_id The ID of the cpt that was saved (so you can link relationally)
123
-     * @param  EE_CPT_Base $post    The post object of the cpt that was saved.
124
-     * @return void
125
-     */
126
-    abstract protected function _insert_update_cpt_item($post_id, $post);
127
-
128
-
129
-    /**
130
-     * This is hooked into the WordPress do_action('trashed_post') hook and runs after a cpt has been trashed.
131
-     *
132
-     * @abstract
133
-     * @access public
134
-     * @param  string $post_id The ID of the cpt that was trashed
135
-     * @return void
136
-     */
137
-    abstract public function trash_cpt_item($post_id);
138
-
139
-
140
-    /**
141
-     * This is hooked into the WordPress do_action('untrashed_post') hook and runs after a cpt has been untrashed
142
-     *
143
-     * @param  string $post_id theID of the cpt that was untrashed
144
-     * @return void
145
-     */
146
-    abstract public function restore_cpt_item($post_id);
147
-
148
-
149
-    /**
150
-     * This is hooked into the WordPress do_action('delete_cpt_item') hook and runs after a cpt has been fully deleted
151
-     * from the db
152
-     *
153
-     * @param  string $post_id the ID of the cpt that was deleted
154
-     * @return void
155
-     */
156
-    abstract public function delete_cpt_item($post_id);
157
-
158
-
159
-    /**
160
-     * @return LoaderInterface
161
-     * @throws InvalidArgumentException
162
-     * @throws InvalidDataTypeException
163
-     * @throws InvalidInterfaceException
164
-     */
165
-    protected function getLoader()
166
-    {
167
-        if (! $this->loader instanceof LoaderInterface) {
168
-            $this->loader = LoaderFactory::getLoader();
169
-        }
170
-        return $this->loader;
171
-    }
172
-
173
-    /**
174
-     * Just utilizing the method EE_Admin exposes for doing things before page setup.
175
-     *
176
-     * @access protected
177
-     * @return void
178
-     */
179
-    protected function _before_page_setup()
180
-    {
181
-        $page = isset($this->_req_data['page']) ? $this->_req_data['page'] : $this->page_slug;
182
-        $this->_cpt_routes = array_merge(
183
-            array(
184
-                'create_new' => $this->page_slug,
185
-                'edit'       => $this->page_slug,
186
-                'trash'      => $this->page_slug,
187
-            ),
188
-            $this->_cpt_routes
189
-        );
190
-        // let's see if the current route has a value for cpt_object_slug if it does we use that instead of the page
191
-        $this->_cpt_object = isset($this->_req_data['action']) && isset($this->_cpt_routes[ $this->_req_data['action'] ])
192
-            ? get_post_type_object($this->_cpt_routes[ $this->_req_data['action'] ])
193
-            : get_post_type_object($page);
194
-        // tweak pagenow for page loading.
195
-        if (! $this->_pagenow_map) {
196
-            $this->_pagenow_map = array(
197
-                'create_new' => 'post-new.php',
198
-                'edit'       => 'post.php',
199
-                'trash'      => 'post.php',
200
-            );
201
-        }
202
-        add_action('current_screen', array($this, 'modify_pagenow'));
203
-        // TODO the below will need to be reworked to account for the cpt routes that are NOT based off of page but action param.
204
-        // get current page from autosave
205
-        $current_page = isset($this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page'])
206
-            ? $this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page']
207
-            : null;
208
-        $this->_current_page = isset($this->_req_data['current_page'])
209
-            ? $this->_req_data['current_page']
210
-            : $current_page;
211
-        // autosave... make sure its only for the correct page
212
-        // if ( ! empty($this->_current_page) && $this->_current_page == $this->page_slug) {
213
-        // setup autosave ajax hook
214
-        // add_action('wp_ajax_ee-autosave', array( $this, 'do_extra_autosave_stuff' ), 10 ); //TODO reactivate when 4.2 autosave is implemented
215
-        // }
216
-    }
217
-
218
-
219
-    /**
220
-     * Simply ensure that we simulate the correct post route for cpt screens
221
-     *
222
-     * @param WP_Screen $current_screen
223
-     * @return void
224
-     */
225
-    public function modify_pagenow($current_screen)
226
-    {
227
-        global $pagenow, $hook_suffix;
228
-        // possibly reset pagenow.
229
-        if (! empty($this->_req_data['page'])
230
-            && $this->_req_data['page'] == $this->page_slug
231
-            && ! empty($this->_req_data['action'])
232
-            && isset($this->_pagenow_map[ $this->_req_data['action'] ])
233
-        ) {
234
-            $pagenow = $this->_pagenow_map[ $this->_req_data['action'] ];
235
-            $hook_suffix = $pagenow;
236
-        }
237
-    }
238
-
239
-
240
-    /**
241
-     * This method is used to register additional autosave containers to the _autosave_containers property.
242
-     *
243
-     * @todo We should automate this at some point by creating a wrapper for add_post_metabox and in our wrapper we
244
-     *       automatically register the id for the post metabox as a container.
245
-     * @param  array $ids an array of ids for containers that hold form inputs we want autosave to pickup.  Typically
246
-     *                    you would send along the id of a metabox container.
247
-     * @return void
248
-     */
249
-    protected function _register_autosave_containers($ids)
250
-    {
251
-        $this->_autosave_containers = array_merge($this->_autosave_fields, (array) $ids);
252
-    }
253
-
254
-
255
-    /**
256
-     * Something nifty.  We're going to loop through all the registered metaboxes and if the CALLBACK is an instance of
257
-     * EE_Admin_Page OR EE_Admin_Hooks, then we'll add the id to our _autosave_containers array.
258
-     */
259
-    protected function _set_autosave_containers()
260
-    {
261
-        global $wp_meta_boxes;
262
-        $containers = array();
263
-        if (empty($wp_meta_boxes)) {
264
-            return;
265
-        }
266
-        $current_metaboxes = isset($wp_meta_boxes[ $this->page_slug ]) ? $wp_meta_boxes[ $this->page_slug ] : array();
267
-        foreach ($current_metaboxes as $box_context) {
268
-            foreach ($box_context as $box_details) {
269
-                foreach ($box_details as $box) {
270
-                    if (is_array($box['callback'])
271
-                        && (
272
-                            $box['callback'][0] instanceof EE_Admin_Page
273
-                            || $box['callback'][0] instanceof EE_Admin_Hooks
274
-                        )
275
-                    ) {
276
-                        $containers[] = $box['id'];
277
-                    }
278
-                }
279
-            }
280
-        }
281
-        $this->_autosave_containers = array_merge($this->_autosave_containers, $containers);
282
-        // add hidden inputs container
283
-        $this->_autosave_containers[] = 'ee-cpt-hidden-inputs';
284
-    }
285
-
286
-
287
-    protected function _load_autosave_scripts_styles()
288
-    {
289
-        /*wp_register_script('cpt-autosave', EE_ADMIN_URL . 'assets/ee-cpt-autosave.js', array('ee-serialize-full-array', 'event_editor_js'), EVENT_ESPRESSO_VERSION, TRUE );
31
+	/**
32
+	 * This gets set in _setup_cpt
33
+	 * It will contain the object for the custom post type.
34
+	 *
35
+	 * @var EE_CPT_Base
36
+	 */
37
+	protected $_cpt_object;
38
+
39
+
40
+	/**
41
+	 * a boolean flag to set whether the current route is a cpt route or not.
42
+	 *
43
+	 * @var bool
44
+	 */
45
+	protected $_cpt_route = false;
46
+
47
+
48
+	/**
49
+	 * This property allows cpt classes to define multiple routes as cpt routes.
50
+	 * //in this array we define what the custom post type for this route is.
51
+	 * array(
52
+	 * 'route_name' => 'custom_post_type_slug'
53
+	 * )
54
+	 *
55
+	 * @var array
56
+	 */
57
+	protected $_cpt_routes = array();
58
+
59
+
60
+	/**
61
+	 * This simply defines what the corresponding routes WP will be redirected to after completing a post save/update.
62
+	 * in this format:
63
+	 * array(
64
+	 * 'post_type_slug' => 'edit_route'
65
+	 * )
66
+	 *
67
+	 * @var array
68
+	 */
69
+	protected $_cpt_edit_routes = array();
70
+
71
+
72
+	/**
73
+	 * If child classes set the name of their main model via the $_cpt_obj_models property, EE_Admin_Page_CPT will
74
+	 * attempt to retrieve the related object model for the edit pages and assign it to _cpt_page_object. the
75
+	 * _cpt_model_names property should be in the following format: array(
76
+	 * 'route_defined_by_action_param' => 'Model_Name')
77
+	 *
78
+	 * @var array $_cpt_model_names
79
+	 */
80
+	protected $_cpt_model_names = array();
81
+
82
+
83
+	/**
84
+	 * @var EE_CPT_Base
85
+	 */
86
+	protected $_cpt_model_obj = false;
87
+
88
+	/**
89
+	 * @var LoaderInterface $loader ;
90
+	 */
91
+	protected $loader;
92
+
93
+	/**
94
+	 * This will hold an array of autosave containers that will be used to obtain input values and hook into the WP
95
+	 * autosave so we can save our inputs on the save_post hook!  Children classes should add to this array by using
96
+	 * the _register_autosave_containers() method so that we don't override any other containers already registered.
97
+	 * Registration of containers should be done before load_page_dependencies() is run.
98
+	 *
99
+	 * @var array()
100
+	 */
101
+	protected $_autosave_containers = array();
102
+	protected $_autosave_fields = array();
103
+
104
+	/**
105
+	 * Array mapping from admin actions to their equivalent wp core pages for custom post types. So when a user visits
106
+	 * a page for an action, it will appear as if they were visiting the wp core page for that custom post type
107
+	 *
108
+	 * @var array
109
+	 */
110
+	protected $_pagenow_map;
111
+
112
+
113
+	/**
114
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
115
+	 * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
116
+	 * data. Keep in mind also that "save_post" runs on EVERY post update to the database. ALSO very important.  When a
117
+	 * post transitions from scheduled to published, the save_post action is fired but you will NOT have any _POST data
118
+	 * containing any extra info you may have from other meta saves.  So MAKE sure that you handle this accordingly.
119
+	 *
120
+	 * @access protected
121
+	 * @abstract
122
+	 * @param  string      $post_id The ID of the cpt that was saved (so you can link relationally)
123
+	 * @param  EE_CPT_Base $post    The post object of the cpt that was saved.
124
+	 * @return void
125
+	 */
126
+	abstract protected function _insert_update_cpt_item($post_id, $post);
127
+
128
+
129
+	/**
130
+	 * This is hooked into the WordPress do_action('trashed_post') hook and runs after a cpt has been trashed.
131
+	 *
132
+	 * @abstract
133
+	 * @access public
134
+	 * @param  string $post_id The ID of the cpt that was trashed
135
+	 * @return void
136
+	 */
137
+	abstract public function trash_cpt_item($post_id);
138
+
139
+
140
+	/**
141
+	 * This is hooked into the WordPress do_action('untrashed_post') hook and runs after a cpt has been untrashed
142
+	 *
143
+	 * @param  string $post_id theID of the cpt that was untrashed
144
+	 * @return void
145
+	 */
146
+	abstract public function restore_cpt_item($post_id);
147
+
148
+
149
+	/**
150
+	 * This is hooked into the WordPress do_action('delete_cpt_item') hook and runs after a cpt has been fully deleted
151
+	 * from the db
152
+	 *
153
+	 * @param  string $post_id the ID of the cpt that was deleted
154
+	 * @return void
155
+	 */
156
+	abstract public function delete_cpt_item($post_id);
157
+
158
+
159
+	/**
160
+	 * @return LoaderInterface
161
+	 * @throws InvalidArgumentException
162
+	 * @throws InvalidDataTypeException
163
+	 * @throws InvalidInterfaceException
164
+	 */
165
+	protected function getLoader()
166
+	{
167
+		if (! $this->loader instanceof LoaderInterface) {
168
+			$this->loader = LoaderFactory::getLoader();
169
+		}
170
+		return $this->loader;
171
+	}
172
+
173
+	/**
174
+	 * Just utilizing the method EE_Admin exposes for doing things before page setup.
175
+	 *
176
+	 * @access protected
177
+	 * @return void
178
+	 */
179
+	protected function _before_page_setup()
180
+	{
181
+		$page = isset($this->_req_data['page']) ? $this->_req_data['page'] : $this->page_slug;
182
+		$this->_cpt_routes = array_merge(
183
+			array(
184
+				'create_new' => $this->page_slug,
185
+				'edit'       => $this->page_slug,
186
+				'trash'      => $this->page_slug,
187
+			),
188
+			$this->_cpt_routes
189
+		);
190
+		// let's see if the current route has a value for cpt_object_slug if it does we use that instead of the page
191
+		$this->_cpt_object = isset($this->_req_data['action']) && isset($this->_cpt_routes[ $this->_req_data['action'] ])
192
+			? get_post_type_object($this->_cpt_routes[ $this->_req_data['action'] ])
193
+			: get_post_type_object($page);
194
+		// tweak pagenow for page loading.
195
+		if (! $this->_pagenow_map) {
196
+			$this->_pagenow_map = array(
197
+				'create_new' => 'post-new.php',
198
+				'edit'       => 'post.php',
199
+				'trash'      => 'post.php',
200
+			);
201
+		}
202
+		add_action('current_screen', array($this, 'modify_pagenow'));
203
+		// TODO the below will need to be reworked to account for the cpt routes that are NOT based off of page but action param.
204
+		// get current page from autosave
205
+		$current_page = isset($this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page'])
206
+			? $this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page']
207
+			: null;
208
+		$this->_current_page = isset($this->_req_data['current_page'])
209
+			? $this->_req_data['current_page']
210
+			: $current_page;
211
+		// autosave... make sure its only for the correct page
212
+		// if ( ! empty($this->_current_page) && $this->_current_page == $this->page_slug) {
213
+		// setup autosave ajax hook
214
+		// add_action('wp_ajax_ee-autosave', array( $this, 'do_extra_autosave_stuff' ), 10 ); //TODO reactivate when 4.2 autosave is implemented
215
+		// }
216
+	}
217
+
218
+
219
+	/**
220
+	 * Simply ensure that we simulate the correct post route for cpt screens
221
+	 *
222
+	 * @param WP_Screen $current_screen
223
+	 * @return void
224
+	 */
225
+	public function modify_pagenow($current_screen)
226
+	{
227
+		global $pagenow, $hook_suffix;
228
+		// possibly reset pagenow.
229
+		if (! empty($this->_req_data['page'])
230
+			&& $this->_req_data['page'] == $this->page_slug
231
+			&& ! empty($this->_req_data['action'])
232
+			&& isset($this->_pagenow_map[ $this->_req_data['action'] ])
233
+		) {
234
+			$pagenow = $this->_pagenow_map[ $this->_req_data['action'] ];
235
+			$hook_suffix = $pagenow;
236
+		}
237
+	}
238
+
239
+
240
+	/**
241
+	 * This method is used to register additional autosave containers to the _autosave_containers property.
242
+	 *
243
+	 * @todo We should automate this at some point by creating a wrapper for add_post_metabox and in our wrapper we
244
+	 *       automatically register the id for the post metabox as a container.
245
+	 * @param  array $ids an array of ids for containers that hold form inputs we want autosave to pickup.  Typically
246
+	 *                    you would send along the id of a metabox container.
247
+	 * @return void
248
+	 */
249
+	protected function _register_autosave_containers($ids)
250
+	{
251
+		$this->_autosave_containers = array_merge($this->_autosave_fields, (array) $ids);
252
+	}
253
+
254
+
255
+	/**
256
+	 * Something nifty.  We're going to loop through all the registered metaboxes and if the CALLBACK is an instance of
257
+	 * EE_Admin_Page OR EE_Admin_Hooks, then we'll add the id to our _autosave_containers array.
258
+	 */
259
+	protected function _set_autosave_containers()
260
+	{
261
+		global $wp_meta_boxes;
262
+		$containers = array();
263
+		if (empty($wp_meta_boxes)) {
264
+			return;
265
+		}
266
+		$current_metaboxes = isset($wp_meta_boxes[ $this->page_slug ]) ? $wp_meta_boxes[ $this->page_slug ] : array();
267
+		foreach ($current_metaboxes as $box_context) {
268
+			foreach ($box_context as $box_details) {
269
+				foreach ($box_details as $box) {
270
+					if (is_array($box['callback'])
271
+						&& (
272
+							$box['callback'][0] instanceof EE_Admin_Page
273
+							|| $box['callback'][0] instanceof EE_Admin_Hooks
274
+						)
275
+					) {
276
+						$containers[] = $box['id'];
277
+					}
278
+				}
279
+			}
280
+		}
281
+		$this->_autosave_containers = array_merge($this->_autosave_containers, $containers);
282
+		// add hidden inputs container
283
+		$this->_autosave_containers[] = 'ee-cpt-hidden-inputs';
284
+	}
285
+
286
+
287
+	protected function _load_autosave_scripts_styles()
288
+	{
289
+		/*wp_register_script('cpt-autosave', EE_ADMIN_URL . 'assets/ee-cpt-autosave.js', array('ee-serialize-full-array', 'event_editor_js'), EVENT_ESPRESSO_VERSION, TRUE );
290 290
         wp_enqueue_script('cpt-autosave');/**/ // todo re-enable when we start doing autosave again in 4.2
291 291
 
292
-        // filter _autosave_containers
293
-        $containers = apply_filters(
294
-            'FHEE__EE_Admin_Page_CPT___load_autosave_scripts_styles__containers',
295
-            $this->_autosave_containers,
296
-            $this
297
-        );
298
-        $containers = apply_filters(
299
-            'FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers',
300
-            $containers,
301
-            $this
302
-        );
303
-
304
-        wp_localize_script(
305
-            'event_editor_js',
306
-            'EE_AUTOSAVE_IDS',
307
-            $containers
308
-        ); // todo once we enable autosaves, this needs to be switched to localize with "cpt-autosave"
309
-
310
-        $unsaved_data_msg = array(
311
-            'eventmsg'     => sprintf(
312
-                wp_strip_all_tags(
313
-                    __(
314
-                        "The changes you made to this %s will be lost if you navigate away from this page.",
315
-                        'event_espresso'
316
-                    )
317
-                ),
318
-                $this->_cpt_object->labels->singular_name
319
-            ),
320
-            'inputChanged' => 0,
321
-        );
322
-        wp_localize_script('event_editor_js', 'UNSAVED_DATA_MSG', $unsaved_data_msg);
323
-    }
324
-
325
-
326
-    public function load_page_dependencies()
327
-    {
328
-        try {
329
-            $this->_load_page_dependencies();
330
-        } catch (EE_Error $e) {
331
-            $e->get_error();
332
-        }
333
-    }
334
-
335
-
336
-    /**
337
-     * overloading the EE_Admin_Page parent load_page_dependencies so we can get the cpt stuff added in appropriately
338
-     *
339
-     * @access protected
340
-     * @return void
341
-     */
342
-    protected function _load_page_dependencies()
343
-    {
344
-        // we only add stuff if this is a cpt_route!
345
-        if (! $this->_cpt_route) {
346
-            parent::_load_page_dependencies();
347
-            return;
348
-        }
349
-        // now let's do some automatic filters into the wp_system
350
-        // and we'll check to make sure the CHILD class
351
-        // automatically has the required methods in place.
352
-        // the following filters are for setting all the redirects
353
-        // on DEFAULT WP custom post type actions
354
-        // let's add a hidden input to the post-edit form
355
-        // so we know when we have to trigger our custom redirects!
356
-        // Otherwise the redirects will happen on ALL post saves which wouldn't be good of course!
357
-        add_action('edit_form_after_title', array($this, 'cpt_post_form_hidden_input'));
358
-        // inject our Admin page nav tabs...
359
-        // let's make sure the nav tabs are set if they aren't already
360
-        // if ( empty( $this->_nav_tabs ) ) $this->_set_nav_tabs();
361
-        add_action('post_edit_form_tag', array($this, 'inject_nav_tabs'));
362
-        // modify the post_updated messages array
363
-        add_action('post_updated_messages', array($this, 'post_update_messages'), 10);
364
-        // add shortlink button to cpt edit screens.  We can do this as a universal thing BECAUSE,
365
-        // cpts use the same format for shortlinks as posts!
366
-        add_filter('pre_get_shortlink', array($this, 'add_shortlink_button_to_editor'), 10, 4);
367
-        // This basically allows us to change the title of the "publish" metabox area
368
-        // on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class.
369
-        if (! empty($this->_labels['publishbox'])) {
370
-            $box_label = is_array($this->_labels['publishbox'])
371
-                         && isset($this->_labels['publishbox'][ $this->_req_action ])
372
-                ? $this->_labels['publishbox'][ $this->_req_action ]
373
-                : $this->_labels['publishbox'];
374
-            add_meta_box(
375
-                'submitdiv',
376
-                $box_label,
377
-                'post_submit_meta_box',
378
-                $this->_cpt_routes[ $this->_req_action ],
379
-                'side',
380
-                'core'
381
-            );
382
-        }
383
-        // let's add page_templates metabox if this cpt added support for it.
384
-        if ($this->_supports_page_templates($this->_cpt_object->name)) {
385
-            add_meta_box(
386
-                'page_templates',
387
-                __('Page Template', 'event_espresso'),
388
-                array($this, 'page_template_meta_box'),
389
-                $this->_cpt_routes[ $this->_req_action ],
390
-                'side',
391
-                'default'
392
-            );
393
-        }
394
-        // this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form
395
-        if (method_exists($this, 'extra_permalink_field_buttons')) {
396
-            add_filter('get_sample_permalink_html', array($this, 'extra_permalink_field_buttons'), 10, 4);
397
-        }
398
-        // add preview button
399
-        add_filter('get_sample_permalink_html', array($this, 'preview_button_html'), 5, 4);
400
-        // insert our own post_stati dropdown
401
-        add_action('post_submitbox_misc_actions', array($this, 'custom_post_stati_dropdown'), 10);
402
-        // This allows adding additional information to the publish post submitbox on the wp post edit form
403
-        if (method_exists($this, 'extra_misc_actions_publish_box')) {
404
-            add_action('post_submitbox_misc_actions', array($this, 'extra_misc_actions_publish_box'), 10);
405
-        }
406
-        // This allows for adding additional stuff after the title field on the wp post edit form.
407
-        // This is also before the wp_editor for post description field.
408
-        if (method_exists($this, 'edit_form_after_title')) {
409
-            add_action('edit_form_after_title', array($this, 'edit_form_after_title'), 10);
410
-        }
411
-        /**
412
-         * Filtering WP's esc_url to capture urls pointing to core wp routes so they point to our route.
413
-         */
414
-        add_filter('clean_url', array($this, 'switch_core_wp_urls_with_ours'), 10, 3);
415
-        parent::_load_page_dependencies();
416
-        // notice we are ALSO going to load the pagenow hook set for this route
417
-        // (see _before_page_setup for the reset of the pagenow global ).
418
-        // This is for any plugins that are doing things properly
419
-        // and hooking into the load page hook for core wp cpt routes.
420
-        global $pagenow;
421
-        add_action('load-' . $pagenow, array($this, 'modify_current_screen'), 20);
422
-        do_action('load-' . $pagenow);
423
-        add_action('admin_enqueue_scripts', array($this, 'setup_autosave_hooks'), 30);
424
-        // we route REALLY early.
425
-        try {
426
-            $this->_route_admin_request();
427
-        } catch (EE_Error $e) {
428
-            $e->get_error();
429
-        }
430
-    }
431
-
432
-
433
-    /**
434
-     * Since we don't want users going to default core wp routes, this will check any wp urls run through the
435
-     * esc_url() method and if we see a url matching a pattern for our routes, we'll modify it to point to OUR
436
-     * route instead.
437
-     *
438
-     * @param string $good_protocol_url The escaped url.
439
-     * @param string $original_url      The original url.
440
-     * @param string $_context          The context sent to the esc_url method.
441
-     * @return string possibly a new url for our route.
442
-     */
443
-    public function switch_core_wp_urls_with_ours($good_protocol_url, $original_url, $_context)
444
-    {
445
-        $routes_to_match = array(
446
-            0 => array(
447
-                'edit.php?post_type=espresso_attendees',
448
-                'admin.php?page=espresso_registrations&action=contact_list',
449
-            ),
450
-            1 => array(
451
-                'edit.php?post_type=' . $this->_cpt_object->name,
452
-                'admin.php?page=' . $this->_cpt_object->name,
453
-            ),
454
-        );
455
-        foreach ($routes_to_match as $route_matches) {
456
-            if (strpos($good_protocol_url, $route_matches[0]) !== false) {
457
-                return str_replace($route_matches[0], $route_matches[1], $good_protocol_url);
458
-            }
459
-        }
460
-        return $good_protocol_url;
461
-    }
462
-
463
-
464
-    /**
465
-     * Determine whether the current cpt supports page templates or not.
466
-     *
467
-     * @since %VER%
468
-     * @param string $cpt_name The cpt slug we're checking on.
469
-     * @return bool True supported, false not.
470
-     * @throws InvalidArgumentException
471
-     * @throws InvalidDataTypeException
472
-     * @throws InvalidInterfaceException
473
-     */
474
-    private function _supports_page_templates($cpt_name)
475
-    {
476
-        /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
477
-        $custom_post_types = $this->getLoader()->getShared(
478
-            'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
479
-        );
480
-        $cpt_args = $custom_post_types->getDefinitions();
481
-        $cpt_args = isset($cpt_args[ $cpt_name ]) ? $cpt_args[ $cpt_name ]['args'] : array();
482
-        $cpt_has_support = ! empty($cpt_args['page_templates']);
483
-
484
-        // if the installed version of WP is > 4.7 we do some additional checks.
485
-        if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
486
-            $post_templates = wp_get_theme()->get_post_templates();
487
-            // if there are $post_templates for this cpt, then we return false for this method because
488
-            // that means we aren't going to load our page template manager and leave that up to the native
489
-            // cpt template manager.
490
-            $cpt_has_support = ! isset($post_templates[ $cpt_name ]) ? $cpt_has_support : false;
491
-        }
492
-
493
-        return $cpt_has_support;
494
-    }
495
-
496
-
497
-    /**
498
-     * Callback for the page_templates metabox selector.
499
-     *
500
-     * @since %VER%
501
-     * @return void
502
-     */
503
-    public function page_template_meta_box()
504
-    {
505
-        global $post;
506
-        $template = '';
507
-
508
-        if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
509
-            $page_template_count = count(get_page_templates());
510
-        } else {
511
-            $page_template_count = count(get_page_templates($post));
512
-        };
513
-
514
-        if ($page_template_count) {
515
-            $page_template = get_post_meta($post->ID, '_wp_page_template', true);
516
-            $template = ! empty($page_template) ? $page_template : '';
517
-        }
518
-        ?>
292
+		// filter _autosave_containers
293
+		$containers = apply_filters(
294
+			'FHEE__EE_Admin_Page_CPT___load_autosave_scripts_styles__containers',
295
+			$this->_autosave_containers,
296
+			$this
297
+		);
298
+		$containers = apply_filters(
299
+			'FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers',
300
+			$containers,
301
+			$this
302
+		);
303
+
304
+		wp_localize_script(
305
+			'event_editor_js',
306
+			'EE_AUTOSAVE_IDS',
307
+			$containers
308
+		); // todo once we enable autosaves, this needs to be switched to localize with "cpt-autosave"
309
+
310
+		$unsaved_data_msg = array(
311
+			'eventmsg'     => sprintf(
312
+				wp_strip_all_tags(
313
+					__(
314
+						"The changes you made to this %s will be lost if you navigate away from this page.",
315
+						'event_espresso'
316
+					)
317
+				),
318
+				$this->_cpt_object->labels->singular_name
319
+			),
320
+			'inputChanged' => 0,
321
+		);
322
+		wp_localize_script('event_editor_js', 'UNSAVED_DATA_MSG', $unsaved_data_msg);
323
+	}
324
+
325
+
326
+	public function load_page_dependencies()
327
+	{
328
+		try {
329
+			$this->_load_page_dependencies();
330
+		} catch (EE_Error $e) {
331
+			$e->get_error();
332
+		}
333
+	}
334
+
335
+
336
+	/**
337
+	 * overloading the EE_Admin_Page parent load_page_dependencies so we can get the cpt stuff added in appropriately
338
+	 *
339
+	 * @access protected
340
+	 * @return void
341
+	 */
342
+	protected function _load_page_dependencies()
343
+	{
344
+		// we only add stuff if this is a cpt_route!
345
+		if (! $this->_cpt_route) {
346
+			parent::_load_page_dependencies();
347
+			return;
348
+		}
349
+		// now let's do some automatic filters into the wp_system
350
+		// and we'll check to make sure the CHILD class
351
+		// automatically has the required methods in place.
352
+		// the following filters are for setting all the redirects
353
+		// on DEFAULT WP custom post type actions
354
+		// let's add a hidden input to the post-edit form
355
+		// so we know when we have to trigger our custom redirects!
356
+		// Otherwise the redirects will happen on ALL post saves which wouldn't be good of course!
357
+		add_action('edit_form_after_title', array($this, 'cpt_post_form_hidden_input'));
358
+		// inject our Admin page nav tabs...
359
+		// let's make sure the nav tabs are set if they aren't already
360
+		// if ( empty( $this->_nav_tabs ) ) $this->_set_nav_tabs();
361
+		add_action('post_edit_form_tag', array($this, 'inject_nav_tabs'));
362
+		// modify the post_updated messages array
363
+		add_action('post_updated_messages', array($this, 'post_update_messages'), 10);
364
+		// add shortlink button to cpt edit screens.  We can do this as a universal thing BECAUSE,
365
+		// cpts use the same format for shortlinks as posts!
366
+		add_filter('pre_get_shortlink', array($this, 'add_shortlink_button_to_editor'), 10, 4);
367
+		// This basically allows us to change the title of the "publish" metabox area
368
+		// on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class.
369
+		if (! empty($this->_labels['publishbox'])) {
370
+			$box_label = is_array($this->_labels['publishbox'])
371
+						 && isset($this->_labels['publishbox'][ $this->_req_action ])
372
+				? $this->_labels['publishbox'][ $this->_req_action ]
373
+				: $this->_labels['publishbox'];
374
+			add_meta_box(
375
+				'submitdiv',
376
+				$box_label,
377
+				'post_submit_meta_box',
378
+				$this->_cpt_routes[ $this->_req_action ],
379
+				'side',
380
+				'core'
381
+			);
382
+		}
383
+		// let's add page_templates metabox if this cpt added support for it.
384
+		if ($this->_supports_page_templates($this->_cpt_object->name)) {
385
+			add_meta_box(
386
+				'page_templates',
387
+				__('Page Template', 'event_espresso'),
388
+				array($this, 'page_template_meta_box'),
389
+				$this->_cpt_routes[ $this->_req_action ],
390
+				'side',
391
+				'default'
392
+			);
393
+		}
394
+		// this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form
395
+		if (method_exists($this, 'extra_permalink_field_buttons')) {
396
+			add_filter('get_sample_permalink_html', array($this, 'extra_permalink_field_buttons'), 10, 4);
397
+		}
398
+		// add preview button
399
+		add_filter('get_sample_permalink_html', array($this, 'preview_button_html'), 5, 4);
400
+		// insert our own post_stati dropdown
401
+		add_action('post_submitbox_misc_actions', array($this, 'custom_post_stati_dropdown'), 10);
402
+		// This allows adding additional information to the publish post submitbox on the wp post edit form
403
+		if (method_exists($this, 'extra_misc_actions_publish_box')) {
404
+			add_action('post_submitbox_misc_actions', array($this, 'extra_misc_actions_publish_box'), 10);
405
+		}
406
+		// This allows for adding additional stuff after the title field on the wp post edit form.
407
+		// This is also before the wp_editor for post description field.
408
+		if (method_exists($this, 'edit_form_after_title')) {
409
+			add_action('edit_form_after_title', array($this, 'edit_form_after_title'), 10);
410
+		}
411
+		/**
412
+		 * Filtering WP's esc_url to capture urls pointing to core wp routes so they point to our route.
413
+		 */
414
+		add_filter('clean_url', array($this, 'switch_core_wp_urls_with_ours'), 10, 3);
415
+		parent::_load_page_dependencies();
416
+		// notice we are ALSO going to load the pagenow hook set for this route
417
+		// (see _before_page_setup for the reset of the pagenow global ).
418
+		// This is for any plugins that are doing things properly
419
+		// and hooking into the load page hook for core wp cpt routes.
420
+		global $pagenow;
421
+		add_action('load-' . $pagenow, array($this, 'modify_current_screen'), 20);
422
+		do_action('load-' . $pagenow);
423
+		add_action('admin_enqueue_scripts', array($this, 'setup_autosave_hooks'), 30);
424
+		// we route REALLY early.
425
+		try {
426
+			$this->_route_admin_request();
427
+		} catch (EE_Error $e) {
428
+			$e->get_error();
429
+		}
430
+	}
431
+
432
+
433
+	/**
434
+	 * Since we don't want users going to default core wp routes, this will check any wp urls run through the
435
+	 * esc_url() method and if we see a url matching a pattern for our routes, we'll modify it to point to OUR
436
+	 * route instead.
437
+	 *
438
+	 * @param string $good_protocol_url The escaped url.
439
+	 * @param string $original_url      The original url.
440
+	 * @param string $_context          The context sent to the esc_url method.
441
+	 * @return string possibly a new url for our route.
442
+	 */
443
+	public function switch_core_wp_urls_with_ours($good_protocol_url, $original_url, $_context)
444
+	{
445
+		$routes_to_match = array(
446
+			0 => array(
447
+				'edit.php?post_type=espresso_attendees',
448
+				'admin.php?page=espresso_registrations&action=contact_list',
449
+			),
450
+			1 => array(
451
+				'edit.php?post_type=' . $this->_cpt_object->name,
452
+				'admin.php?page=' . $this->_cpt_object->name,
453
+			),
454
+		);
455
+		foreach ($routes_to_match as $route_matches) {
456
+			if (strpos($good_protocol_url, $route_matches[0]) !== false) {
457
+				return str_replace($route_matches[0], $route_matches[1], $good_protocol_url);
458
+			}
459
+		}
460
+		return $good_protocol_url;
461
+	}
462
+
463
+
464
+	/**
465
+	 * Determine whether the current cpt supports page templates or not.
466
+	 *
467
+	 * @since %VER%
468
+	 * @param string $cpt_name The cpt slug we're checking on.
469
+	 * @return bool True supported, false not.
470
+	 * @throws InvalidArgumentException
471
+	 * @throws InvalidDataTypeException
472
+	 * @throws InvalidInterfaceException
473
+	 */
474
+	private function _supports_page_templates($cpt_name)
475
+	{
476
+		/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
477
+		$custom_post_types = $this->getLoader()->getShared(
478
+			'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
479
+		);
480
+		$cpt_args = $custom_post_types->getDefinitions();
481
+		$cpt_args = isset($cpt_args[ $cpt_name ]) ? $cpt_args[ $cpt_name ]['args'] : array();
482
+		$cpt_has_support = ! empty($cpt_args['page_templates']);
483
+
484
+		// if the installed version of WP is > 4.7 we do some additional checks.
485
+		if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
486
+			$post_templates = wp_get_theme()->get_post_templates();
487
+			// if there are $post_templates for this cpt, then we return false for this method because
488
+			// that means we aren't going to load our page template manager and leave that up to the native
489
+			// cpt template manager.
490
+			$cpt_has_support = ! isset($post_templates[ $cpt_name ]) ? $cpt_has_support : false;
491
+		}
492
+
493
+		return $cpt_has_support;
494
+	}
495
+
496
+
497
+	/**
498
+	 * Callback for the page_templates metabox selector.
499
+	 *
500
+	 * @since %VER%
501
+	 * @return void
502
+	 */
503
+	public function page_template_meta_box()
504
+	{
505
+		global $post;
506
+		$template = '';
507
+
508
+		if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
509
+			$page_template_count = count(get_page_templates());
510
+		} else {
511
+			$page_template_count = count(get_page_templates($post));
512
+		};
513
+
514
+		if ($page_template_count) {
515
+			$page_template = get_post_meta($post->ID, '_wp_page_template', true);
516
+			$template = ! empty($page_template) ? $page_template : '';
517
+		}
518
+		?>
519 519
         <p><strong><?php _e('Template', 'event_espresso') ?></strong></p>
520 520
         <label class="screen-reader-text" for="page_template"><?php _e('Page Template', 'event_espresso') ?></label><select
521 521
         name="page_template" id="page_template">
@@ -523,471 +523,471 @@  discard block
 block discarded – undo
523 523
         <?php page_template_dropdown($template); ?>
524 524
     </select>
525 525
         <?php
526
-    }
527
-
528
-
529
-    /**
530
-     * if this post is a draft or scheduled post then we provide a preview button for user to click
531
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
532
-     *
533
-     * @param  string $return    the current html
534
-     * @param  int    $id        the post id for the page
535
-     * @param  string $new_title What the title is
536
-     * @param  string $new_slug  what the slug is
537
-     * @return string            The new html string for the permalink area
538
-     */
539
-    public function preview_button_html($return, $id, $new_title, $new_slug)
540
-    {
541
-        $post = get_post($id);
542
-        if ('publish' !== get_post_status($post)) {
543
-            $return .= '<span_id="view-post-btn"><a target="_blank" href="'
544
-                       . get_preview_post_link($id)
545
-                       . '" class="button button-small">'
546
-                       . __('Preview', 'event_espresso')
547
-                       . '</a></span>'
548
-                       . "\n";
549
-        }
550
-        return $return;
551
-    }
552
-
553
-
554
-    /**
555
-     * add our custom post stati dropdown on the wp post page for this cpt
556
-     *
557
-     * @return void
558
-     */
559
-    public function custom_post_stati_dropdown()
560
-    {
561
-
562
-        $statuses = $this->_cpt_model_obj->get_custom_post_statuses();
563
-        $cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses)
564
-            ? $statuses[ $this->_cpt_model_obj->status() ]
565
-            : '';
566
-        $template_args = array(
567
-            'cur_status'            => $this->_cpt_model_obj->status(),
568
-            'statuses'              => $statuses,
569
-            'cur_status_label'      => $cur_status_label,
570
-            'localized_status_save' => sprintf(__('Save %s', 'event_espresso'), $cur_status_label),
571
-        );
572
-        // we'll add a trash post status (WP doesn't add one for some reason)
573
-        if ($this->_cpt_model_obj->status() === 'trash') {
574
-            $template_args['cur_status_label'] = __('Trashed', 'event_espresso');
575
-            $statuses['trash'] = __('Trashed', 'event_espresso');
576
-            $template_args['statuses'] = $statuses;
577
-        }
578
-
579
-        $template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php';
580
-        EEH_Template::display_template($template, $template_args);
581
-    }
582
-
583
-
584
-    public function setup_autosave_hooks()
585
-    {
586
-        $this->_set_autosave_containers();
587
-        $this->_load_autosave_scripts_styles();
588
-    }
589
-
590
-
591
-    /**
592
-     * This is run on all WordPress autosaves AFTER the autosave is complete and sends along a $_POST object (available
593
-     * in $this->_req_data) containing: post_ID of the saved post autosavenonce for the saved post We'll do the check
594
-     * for the nonce in here, but then this method looks for two things:
595
-     * 1. Execute a method (if exists) matching 'ee_autosave_' and appended with the given route. OR
596
-     * 2. do_actions() for global or class specific actions that have been registered (for plugins/addons not in an
597
-     * EE_Admin_Page class. PLEASE NOTE: Data will be returned using the _return_json() object and so the
598
-     * $_template_args property should be used to hold the $data array.  We're expecting the following things set in
599
-     * template args.
600
-     *    1. $template_args['error'] = IF there is an error you can add the message in here.
601
-     *    2. $template_args['data']['items'] = an array of items that are setup in key index pairs of 'where_values_go'
602
-     *    => 'values_to_add'.  In other words, for the datetime metabox we'll have something like
603
-     *    $this->_template_args['data']['items'] = array(
604
-     *        'event-datetime-ids' => '1,2,3';
605
-     *    );
606
-     *    Keep in mind the following things:
607
-     *    - "where" index is for the input with the id as that string.
608
-     *    - "what" index is what will be used for the value of that input.
609
-     *
610
-     * @return void
611
-     */
612
-    public function do_extra_autosave_stuff()
613
-    {
614
-        // next let's check for the autosave nonce (we'll use _verify_nonce )
615
-        $nonce = isset($this->_req_data['autosavenonce'])
616
-            ? $this->_req_data['autosavenonce']
617
-            : null;
618
-        $this->_verify_nonce($nonce, 'autosave');
619
-        // make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it)
620
-        if (! defined('DOING_AUTOSAVE')) {
621
-            define('DOING_AUTOSAVE', true);
622
-        }
623
-        // if we made it here then the nonce checked out.  Let's run our methods and actions
624
-        $autosave = "_ee_autosave_{$this->_current_view}";
625
-        if (method_exists($this, $autosave)) {
626
-            $this->$autosave();
627
-        } else {
628
-            $this->_template_args['success'] = true;
629
-        }
630
-        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this);
631
-        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this);
632
-        // now let's return json
633
-        $this->_return_json();
634
-    }
635
-
636
-
637
-    /**
638
-     * This takes care of setting up default routes and pages that utilize the core WP admin pages.
639
-     * Child classes can override the defaults (in cases for adding metaboxes etc.)
640
-     * but take care that you include the defaults here otherwise your core WP admin pages for the cpt won't work!
641
-     *
642
-     * @access protected
643
-     * @throws EE_Error
644
-     * @return void
645
-     */
646
-    protected function _extend_page_config_for_cpt()
647
-    {
648
-        // before doing anything we need to make sure this runs ONLY when the loaded page matches the set page_slug
649
-        if (isset($this->_req_data['page']) && $this->_req_data['page'] !== $this->page_slug) {
650
-            return;
651
-        }
652
-        // set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes
653
-        if (! empty($this->_cpt_object)) {
654
-            $this->_page_routes = array_merge(
655
-                array(
656
-                    'create_new' => '_create_new_cpt_item',
657
-                    'edit'       => '_edit_cpt_item',
658
-                ),
659
-                $this->_page_routes
660
-            );
661
-            $this->_page_config = array_merge(
662
-                array(
663
-                    'create_new' => array(
664
-                        'nav'           => array(
665
-                            'label' => $this->_cpt_object->labels->add_new_item,
666
-                            'order' => 5,
667
-                        ),
668
-                        'require_nonce' => false,
669
-                    ),
670
-                    'edit'       => array(
671
-                        'nav'           => array(
672
-                            'label'      => $this->_cpt_object->labels->edit_item,
673
-                            'order'      => 5,
674
-                            'persistent' => false,
675
-                            'url'        => '',
676
-                        ),
677
-                        'require_nonce' => false,
678
-                    ),
679
-                ),
680
-                $this->_page_config
681
-            );
682
-        }
683
-        // load the next section only if this is a matching cpt route as set in the cpt routes array.
684
-        if (! isset($this->_cpt_routes[ $this->_req_action ])) {
685
-            return;
686
-        }
687
-        $this->_cpt_route = isset($this->_cpt_routes[ $this->_req_action ]) ? true : false;
688
-        // add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') );
689
-        if (empty($this->_cpt_object)) {
690
-            $msg = sprintf(
691
-                __(
692
-                    'This page has been set as being related to a registered custom post type, however, the custom post type object could not be retrieved. There are two possible reasons for this:  1. The "%s" does not match a registered post type. or 2. The custom post type is not registered for the "%s" action as indexed in the "$_cpt_routes" property on this class (%s).',
693
-                    'event_espresso'
694
-                ),
695
-                $this->page_slug,
696
-                $this->_req_action,
697
-                get_class($this)
698
-            );
699
-            throw new EE_Error($msg);
700
-        }
701
-        if ($this->_cpt_route) {
702
-            $id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
703
-            $this->_set_model_object($id);
704
-        }
705
-    }
706
-
707
-
708
-    /**
709
-     * Sets the _cpt_model_object property using what has been set for the _cpt_model_name and a given id.
710
-     *
711
-     * @access protected
712
-     * @param int    $id       The id to retrieve the model object for. If empty we set a default object.
713
-     * @param bool   $ignore_route_check
714
-     * @param string $req_type whether the current route is for inserting, updating, or deleting the CPT
715
-     * @throws EE_Error
716
-     * @throws InvalidArgumentException
717
-     * @throws InvalidDataTypeException
718
-     * @throws InvalidInterfaceException
719
-     * @throws ReflectionException
720
-     */
721
-    protected function _set_model_object($id = null, $ignore_route_check = false, $req_type = '')
722
-    {
723
-        $model = null;
724
-        if (empty($this->_cpt_model_names)
725
-            || (
726
-                ! $ignore_route_check
727
-                && ! isset($this->_cpt_routes[ $this->_req_action ])
728
-            ) || (
729
-                $this->_cpt_model_obj instanceof EE_CPT_Base
730
-                && $this->_cpt_model_obj->ID() === $id
731
-            )
732
-        ) {
733
-            // get out cuz we either don't have a model name OR the object has already been set and it has the same id as what has been sent.
734
-            return;
735
-        }
736
-        // if ignore_route_check is true, then get the model name via CustomPostTypeDefinitions
737
-        if ($ignore_route_check) {
738
-            $post_type = get_post_type($id);
739
-            /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
740
-            $custom_post_types = $this->getLoader()->getShared(
741
-                'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
742
-            );
743
-            $model_names = $custom_post_types->getCustomPostTypeModelNames($post_type);
744
-            if (isset($model_names[ $post_type ])) {
745
-                $model = EE_Registry::instance()->load_model($model_names[ $post_type ]);
746
-            }
747
-        } else {
748
-            $model = EE_Registry::instance()->load_model($this->_cpt_model_names[ $this->_req_action ]);
749
-        }
750
-        if ($model instanceof EEM_Base) {
751
-            $this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object();
752
-        }
753
-        do_action(
754
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
755
-            $this->_cpt_model_obj,
756
-            $req_type
757
-        );
758
-    }
759
-
760
-
761
-    /**
762
-     * admin_init_global
763
-     * This runs all the code that we want executed within the WP admin_init hook.
764
-     * This method executes for ALL EE Admin pages.
765
-     *
766
-     * @access public
767
-     * @return void
768
-     */
769
-    public function admin_init_global()
770
-    {
771
-        $post = isset($this->_req_data['post']) ? get_post($this->_req_data['post']) : null;
772
-        // its possible this is a new save so let's catch that instead
773
-        $post = isset($this->_req_data['post_ID']) ? get_post($this->_req_data['post_ID']) : $post;
774
-        $post_type = $post ? $post->post_type : false;
775
-        $current_route = isset($this->_req_data['current_route'])
776
-            ? $this->_req_data['current_route']
777
-            : 'shouldneverwork';
778
-        $route_to_check = $post_type && isset($this->_cpt_routes[ $current_route ])
779
-            ? $this->_cpt_routes[ $current_route ]
780
-            : '';
781
-        add_filter('get_delete_post_link', array($this, 'modify_delete_post_link'), 10, 3);
782
-        add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 3);
783
-        if ($post_type === $route_to_check) {
784
-            add_filter('redirect_post_location', array($this, 'cpt_post_location_redirect'), 10, 2);
785
-        }
786
-        // now let's filter redirect if we're on a revision page and the revision is for an event CPT.
787
-        $revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
788
-        if (! empty($revision)) {
789
-            $action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null;
790
-            // doing a restore?
791
-            if (! empty($action) && $action === 'restore') {
792
-                // get post for revision
793
-                $rev_post = get_post($revision);
794
-                $rev_parent = get_post($rev_post->post_parent);
795
-                // only do our redirect filter AND our restore revision action if the post_type for the parent is one of our cpts.
796
-                if ($rev_parent && $rev_parent->post_type === $this->page_slug) {
797
-                    add_filter('wp_redirect', array($this, 'revision_redirect'), 10, 2);
798
-                    // restores of revisions
799
-                    add_action('wp_restore_post_revision', array($this, 'restore_revision'), 10, 2);
800
-                }
801
-            }
802
-        }
803
-        // NOTE we ONLY want to run these hooks if we're on the right class for the given post type.  Otherwise we could see some really freaky things happen!
804
-        if ($post_type && $post_type === $route_to_check) {
805
-            // $post_id, $post
806
-            add_action('save_post', array($this, 'insert_update'), 10, 3);
807
-            // $post_id
808
-            add_action('trashed_post', array($this, 'before_trash_cpt_item'), 10);
809
-            add_action('trashed_post', array($this, 'dont_permanently_delete_ee_cpts'), 10);
810
-            add_action('untrashed_post', array($this, 'before_restore_cpt_item'), 10);
811
-            add_action('after_delete_post', array($this, 'before_delete_cpt_item'), 10);
812
-        }
813
-    }
814
-
815
-
816
-    /**
817
-     * Callback for the WordPress trashed_post hook.
818
-     * Execute some basic checks before calling the trash_cpt_item declared in the child class.
819
-     *
820
-     * @param int $post_id
821
-     * @throws \EE_Error
822
-     */
823
-    public function before_trash_cpt_item($post_id)
824
-    {
825
-        $this->_set_model_object($post_id, true, 'trash');
826
-        // if our cpt object isn't existent then get out immediately.
827
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
828
-            return;
829
-        }
830
-        $this->trash_cpt_item($post_id);
831
-    }
832
-
833
-
834
-    /**
835
-     * Callback for the WordPress untrashed_post hook.
836
-     * Execute some basic checks before calling the restore_cpt_method in the child class.
837
-     *
838
-     * @param $post_id
839
-     * @throws \EE_Error
840
-     */
841
-    public function before_restore_cpt_item($post_id)
842
-    {
843
-        $this->_set_model_object($post_id, true, 'restore');
844
-        // if our cpt object isn't existent then get out immediately.
845
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
846
-            return;
847
-        }
848
-        $this->restore_cpt_item($post_id);
849
-    }
850
-
851
-
852
-    /**
853
-     * Callback for the WordPress after_delete_post hook.
854
-     * Execute some basic checks before calling the delete_cpt_item method in the child class.
855
-     *
856
-     * @param $post_id
857
-     * @throws \EE_Error
858
-     */
859
-    public function before_delete_cpt_item($post_id)
860
-    {
861
-        $this->_set_model_object($post_id, true, 'delete');
862
-        // if our cpt object isn't existent then get out immediately.
863
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
864
-            return;
865
-        }
866
-        $this->delete_cpt_item($post_id);
867
-    }
868
-
869
-
870
-    /**
871
-     * This simply verifies if the cpt_model_object is instantiated for the given page and throws an error message
872
-     * accordingly.
873
-     *
874
-     * @access public
875
-     * @throws EE_Error
876
-     * @return void
877
-     */
878
-    public function verify_cpt_object()
879
-    {
880
-        $label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label;
881
-        // verify event object
882
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
883
-            throw new EE_Error(
884
-                sprintf(
885
-                    __(
886
-                        'Something has gone wrong with the page load because we are unable to set up the object for the %1$s.  This usually happens when the given id for the page route is NOT for the correct custom post type for this page',
887
-                        'event_espresso'
888
-                    ),
889
-                    $label
890
-                )
891
-            );
892
-        }
893
-        // if auto-draft then throw an error
894
-        if ($this->_cpt_model_obj->get('status') === 'auto-draft') {
895
-            EE_Error::overwrite_errors();
896
-            EE_Error::add_error(
897
-                sprintf(
898
-                    __(
899
-                        'This %1$s was saved without a title, description, or excerpt which means that none of the extra details you added were saved properly.  All autodrafts will show up in the "draft" view of your event list table.  You can delete them from there. Please click the "Add %1$s" button to refresh and restart.',
900
-                        'event_espresso'
901
-                    ),
902
-                    $label
903
-                ),
904
-                __FILE__,
905
-                __FUNCTION__,
906
-                __LINE__
907
-            );
908
-        }
909
-    }
910
-
911
-
912
-    /**
913
-     * admin_footer_scripts_global
914
-     * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
915
-     * will apply on ALL EE_Admin pages.
916
-     *
917
-     * @access public
918
-     * @return void
919
-     */
920
-    public function admin_footer_scripts_global()
921
-    {
922
-        $this->_add_admin_page_ajax_loading_img();
923
-        $this->_add_admin_page_overlay();
924
-    }
925
-
926
-
927
-    /**
928
-     * add in any global scripts for cpt routes
929
-     *
930
-     * @return void
931
-     */
932
-    public function load_global_scripts_styles()
933
-    {
934
-        parent::load_global_scripts_styles();
935
-        if ($this->_cpt_model_obj instanceof EE_CPT_Base) {
936
-            // setup custom post status object for localize script but only if we've got a cpt object
937
-            $statuses = $this->_cpt_model_obj->get_custom_post_statuses();
938
-            if (! empty($statuses)) {
939
-                // get ALL statuses!
940
-                $statuses = $this->_cpt_model_obj->get_all_post_statuses();
941
-                // setup object
942
-                $ee_cpt_statuses = array();
943
-                foreach ($statuses as $status => $label) {
944
-                    $ee_cpt_statuses[ $status ] = array(
945
-                        'label'      => $label,
946
-                        'save_label' => sprintf(
947
-                            wp_strip_all_tags(__('Save as %s', 'event_espresso')),
948
-                            $label
949
-                        ),
950
-                    );
951
-                }
952
-                wp_localize_script('ee_admin_js', 'eeCPTstatuses', $ee_cpt_statuses);
953
-            }
954
-        }
955
-    }
956
-
957
-
958
-    /**
959
-     * This is a wrapper for the insert/update routes for cpt items so we can add things that are common to ALL
960
-     * insert/updates
961
-     *
962
-     * @param  int     $post_id ID of post being updated
963
-     * @param  WP_Post $post    Post object from WP
964
-     * @param  bool    $update  Whether this is an update or a new save.
965
-     * @return void
966
-     * @throws \EE_Error
967
-     */
968
-    public function insert_update($post_id, $post, $update)
969
-    {
970
-        // make sure that if this is a revision OR trash action that we don't do any updates!
971
-        if (isset($this->_req_data['action'])
972
-            && (
973
-                $this->_req_data['action'] === 'restore'
974
-                || $this->_req_data['action'] === 'trash'
975
-            )
976
-        ) {
977
-            return;
978
-        }
979
-        $this->_set_model_object($post_id, true, 'insert_update');
980
-        // if our cpt object is not instantiated and its NOT the same post_id as what is triggering this callback, then exit.
981
-        if ($update
982
-            && (
983
-                ! $this->_cpt_model_obj instanceof EE_CPT_Base
984
-                || $this->_cpt_model_obj->ID() !== $post_id
985
-            )
986
-        ) {
987
-            return;
988
-        }
989
-        // check for autosave and update our req_data property accordingly.
990
-        /*if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE && isset( $this->_req_data['ee_autosave_data'] ) ) {
526
+	}
527
+
528
+
529
+	/**
530
+	 * if this post is a draft or scheduled post then we provide a preview button for user to click
531
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
532
+	 *
533
+	 * @param  string $return    the current html
534
+	 * @param  int    $id        the post id for the page
535
+	 * @param  string $new_title What the title is
536
+	 * @param  string $new_slug  what the slug is
537
+	 * @return string            The new html string for the permalink area
538
+	 */
539
+	public function preview_button_html($return, $id, $new_title, $new_slug)
540
+	{
541
+		$post = get_post($id);
542
+		if ('publish' !== get_post_status($post)) {
543
+			$return .= '<span_id="view-post-btn"><a target="_blank" href="'
544
+					   . get_preview_post_link($id)
545
+					   . '" class="button button-small">'
546
+					   . __('Preview', 'event_espresso')
547
+					   . '</a></span>'
548
+					   . "\n";
549
+		}
550
+		return $return;
551
+	}
552
+
553
+
554
+	/**
555
+	 * add our custom post stati dropdown on the wp post page for this cpt
556
+	 *
557
+	 * @return void
558
+	 */
559
+	public function custom_post_stati_dropdown()
560
+	{
561
+
562
+		$statuses = $this->_cpt_model_obj->get_custom_post_statuses();
563
+		$cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses)
564
+			? $statuses[ $this->_cpt_model_obj->status() ]
565
+			: '';
566
+		$template_args = array(
567
+			'cur_status'            => $this->_cpt_model_obj->status(),
568
+			'statuses'              => $statuses,
569
+			'cur_status_label'      => $cur_status_label,
570
+			'localized_status_save' => sprintf(__('Save %s', 'event_espresso'), $cur_status_label),
571
+		);
572
+		// we'll add a trash post status (WP doesn't add one for some reason)
573
+		if ($this->_cpt_model_obj->status() === 'trash') {
574
+			$template_args['cur_status_label'] = __('Trashed', 'event_espresso');
575
+			$statuses['trash'] = __('Trashed', 'event_espresso');
576
+			$template_args['statuses'] = $statuses;
577
+		}
578
+
579
+		$template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php';
580
+		EEH_Template::display_template($template, $template_args);
581
+	}
582
+
583
+
584
+	public function setup_autosave_hooks()
585
+	{
586
+		$this->_set_autosave_containers();
587
+		$this->_load_autosave_scripts_styles();
588
+	}
589
+
590
+
591
+	/**
592
+	 * This is run on all WordPress autosaves AFTER the autosave is complete and sends along a $_POST object (available
593
+	 * in $this->_req_data) containing: post_ID of the saved post autosavenonce for the saved post We'll do the check
594
+	 * for the nonce in here, but then this method looks for two things:
595
+	 * 1. Execute a method (if exists) matching 'ee_autosave_' and appended with the given route. OR
596
+	 * 2. do_actions() for global or class specific actions that have been registered (for plugins/addons not in an
597
+	 * EE_Admin_Page class. PLEASE NOTE: Data will be returned using the _return_json() object and so the
598
+	 * $_template_args property should be used to hold the $data array.  We're expecting the following things set in
599
+	 * template args.
600
+	 *    1. $template_args['error'] = IF there is an error you can add the message in here.
601
+	 *    2. $template_args['data']['items'] = an array of items that are setup in key index pairs of 'where_values_go'
602
+	 *    => 'values_to_add'.  In other words, for the datetime metabox we'll have something like
603
+	 *    $this->_template_args['data']['items'] = array(
604
+	 *        'event-datetime-ids' => '1,2,3';
605
+	 *    );
606
+	 *    Keep in mind the following things:
607
+	 *    - "where" index is for the input with the id as that string.
608
+	 *    - "what" index is what will be used for the value of that input.
609
+	 *
610
+	 * @return void
611
+	 */
612
+	public function do_extra_autosave_stuff()
613
+	{
614
+		// next let's check for the autosave nonce (we'll use _verify_nonce )
615
+		$nonce = isset($this->_req_data['autosavenonce'])
616
+			? $this->_req_data['autosavenonce']
617
+			: null;
618
+		$this->_verify_nonce($nonce, 'autosave');
619
+		// make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it)
620
+		if (! defined('DOING_AUTOSAVE')) {
621
+			define('DOING_AUTOSAVE', true);
622
+		}
623
+		// if we made it here then the nonce checked out.  Let's run our methods and actions
624
+		$autosave = "_ee_autosave_{$this->_current_view}";
625
+		if (method_exists($this, $autosave)) {
626
+			$this->$autosave();
627
+		} else {
628
+			$this->_template_args['success'] = true;
629
+		}
630
+		do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this);
631
+		do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this);
632
+		// now let's return json
633
+		$this->_return_json();
634
+	}
635
+
636
+
637
+	/**
638
+	 * This takes care of setting up default routes and pages that utilize the core WP admin pages.
639
+	 * Child classes can override the defaults (in cases for adding metaboxes etc.)
640
+	 * but take care that you include the defaults here otherwise your core WP admin pages for the cpt won't work!
641
+	 *
642
+	 * @access protected
643
+	 * @throws EE_Error
644
+	 * @return void
645
+	 */
646
+	protected function _extend_page_config_for_cpt()
647
+	{
648
+		// before doing anything we need to make sure this runs ONLY when the loaded page matches the set page_slug
649
+		if (isset($this->_req_data['page']) && $this->_req_data['page'] !== $this->page_slug) {
650
+			return;
651
+		}
652
+		// set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes
653
+		if (! empty($this->_cpt_object)) {
654
+			$this->_page_routes = array_merge(
655
+				array(
656
+					'create_new' => '_create_new_cpt_item',
657
+					'edit'       => '_edit_cpt_item',
658
+				),
659
+				$this->_page_routes
660
+			);
661
+			$this->_page_config = array_merge(
662
+				array(
663
+					'create_new' => array(
664
+						'nav'           => array(
665
+							'label' => $this->_cpt_object->labels->add_new_item,
666
+							'order' => 5,
667
+						),
668
+						'require_nonce' => false,
669
+					),
670
+					'edit'       => array(
671
+						'nav'           => array(
672
+							'label'      => $this->_cpt_object->labels->edit_item,
673
+							'order'      => 5,
674
+							'persistent' => false,
675
+							'url'        => '',
676
+						),
677
+						'require_nonce' => false,
678
+					),
679
+				),
680
+				$this->_page_config
681
+			);
682
+		}
683
+		// load the next section only if this is a matching cpt route as set in the cpt routes array.
684
+		if (! isset($this->_cpt_routes[ $this->_req_action ])) {
685
+			return;
686
+		}
687
+		$this->_cpt_route = isset($this->_cpt_routes[ $this->_req_action ]) ? true : false;
688
+		// add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') );
689
+		if (empty($this->_cpt_object)) {
690
+			$msg = sprintf(
691
+				__(
692
+					'This page has been set as being related to a registered custom post type, however, the custom post type object could not be retrieved. There are two possible reasons for this:  1. The "%s" does not match a registered post type. or 2. The custom post type is not registered for the "%s" action as indexed in the "$_cpt_routes" property on this class (%s).',
693
+					'event_espresso'
694
+				),
695
+				$this->page_slug,
696
+				$this->_req_action,
697
+				get_class($this)
698
+			);
699
+			throw new EE_Error($msg);
700
+		}
701
+		if ($this->_cpt_route) {
702
+			$id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
703
+			$this->_set_model_object($id);
704
+		}
705
+	}
706
+
707
+
708
+	/**
709
+	 * Sets the _cpt_model_object property using what has been set for the _cpt_model_name and a given id.
710
+	 *
711
+	 * @access protected
712
+	 * @param int    $id       The id to retrieve the model object for. If empty we set a default object.
713
+	 * @param bool   $ignore_route_check
714
+	 * @param string $req_type whether the current route is for inserting, updating, or deleting the CPT
715
+	 * @throws EE_Error
716
+	 * @throws InvalidArgumentException
717
+	 * @throws InvalidDataTypeException
718
+	 * @throws InvalidInterfaceException
719
+	 * @throws ReflectionException
720
+	 */
721
+	protected function _set_model_object($id = null, $ignore_route_check = false, $req_type = '')
722
+	{
723
+		$model = null;
724
+		if (empty($this->_cpt_model_names)
725
+			|| (
726
+				! $ignore_route_check
727
+				&& ! isset($this->_cpt_routes[ $this->_req_action ])
728
+			) || (
729
+				$this->_cpt_model_obj instanceof EE_CPT_Base
730
+				&& $this->_cpt_model_obj->ID() === $id
731
+			)
732
+		) {
733
+			// get out cuz we either don't have a model name OR the object has already been set and it has the same id as what has been sent.
734
+			return;
735
+		}
736
+		// if ignore_route_check is true, then get the model name via CustomPostTypeDefinitions
737
+		if ($ignore_route_check) {
738
+			$post_type = get_post_type($id);
739
+			/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
740
+			$custom_post_types = $this->getLoader()->getShared(
741
+				'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
742
+			);
743
+			$model_names = $custom_post_types->getCustomPostTypeModelNames($post_type);
744
+			if (isset($model_names[ $post_type ])) {
745
+				$model = EE_Registry::instance()->load_model($model_names[ $post_type ]);
746
+			}
747
+		} else {
748
+			$model = EE_Registry::instance()->load_model($this->_cpt_model_names[ $this->_req_action ]);
749
+		}
750
+		if ($model instanceof EEM_Base) {
751
+			$this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object();
752
+		}
753
+		do_action(
754
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
755
+			$this->_cpt_model_obj,
756
+			$req_type
757
+		);
758
+	}
759
+
760
+
761
+	/**
762
+	 * admin_init_global
763
+	 * This runs all the code that we want executed within the WP admin_init hook.
764
+	 * This method executes for ALL EE Admin pages.
765
+	 *
766
+	 * @access public
767
+	 * @return void
768
+	 */
769
+	public function admin_init_global()
770
+	{
771
+		$post = isset($this->_req_data['post']) ? get_post($this->_req_data['post']) : null;
772
+		// its possible this is a new save so let's catch that instead
773
+		$post = isset($this->_req_data['post_ID']) ? get_post($this->_req_data['post_ID']) : $post;
774
+		$post_type = $post ? $post->post_type : false;
775
+		$current_route = isset($this->_req_data['current_route'])
776
+			? $this->_req_data['current_route']
777
+			: 'shouldneverwork';
778
+		$route_to_check = $post_type && isset($this->_cpt_routes[ $current_route ])
779
+			? $this->_cpt_routes[ $current_route ]
780
+			: '';
781
+		add_filter('get_delete_post_link', array($this, 'modify_delete_post_link'), 10, 3);
782
+		add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 3);
783
+		if ($post_type === $route_to_check) {
784
+			add_filter('redirect_post_location', array($this, 'cpt_post_location_redirect'), 10, 2);
785
+		}
786
+		// now let's filter redirect if we're on a revision page and the revision is for an event CPT.
787
+		$revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
788
+		if (! empty($revision)) {
789
+			$action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null;
790
+			// doing a restore?
791
+			if (! empty($action) && $action === 'restore') {
792
+				// get post for revision
793
+				$rev_post = get_post($revision);
794
+				$rev_parent = get_post($rev_post->post_parent);
795
+				// only do our redirect filter AND our restore revision action if the post_type for the parent is one of our cpts.
796
+				if ($rev_parent && $rev_parent->post_type === $this->page_slug) {
797
+					add_filter('wp_redirect', array($this, 'revision_redirect'), 10, 2);
798
+					// restores of revisions
799
+					add_action('wp_restore_post_revision', array($this, 'restore_revision'), 10, 2);
800
+				}
801
+			}
802
+		}
803
+		// NOTE we ONLY want to run these hooks if we're on the right class for the given post type.  Otherwise we could see some really freaky things happen!
804
+		if ($post_type && $post_type === $route_to_check) {
805
+			// $post_id, $post
806
+			add_action('save_post', array($this, 'insert_update'), 10, 3);
807
+			// $post_id
808
+			add_action('trashed_post', array($this, 'before_trash_cpt_item'), 10);
809
+			add_action('trashed_post', array($this, 'dont_permanently_delete_ee_cpts'), 10);
810
+			add_action('untrashed_post', array($this, 'before_restore_cpt_item'), 10);
811
+			add_action('after_delete_post', array($this, 'before_delete_cpt_item'), 10);
812
+		}
813
+	}
814
+
815
+
816
+	/**
817
+	 * Callback for the WordPress trashed_post hook.
818
+	 * Execute some basic checks before calling the trash_cpt_item declared in the child class.
819
+	 *
820
+	 * @param int $post_id
821
+	 * @throws \EE_Error
822
+	 */
823
+	public function before_trash_cpt_item($post_id)
824
+	{
825
+		$this->_set_model_object($post_id, true, 'trash');
826
+		// if our cpt object isn't existent then get out immediately.
827
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
828
+			return;
829
+		}
830
+		$this->trash_cpt_item($post_id);
831
+	}
832
+
833
+
834
+	/**
835
+	 * Callback for the WordPress untrashed_post hook.
836
+	 * Execute some basic checks before calling the restore_cpt_method in the child class.
837
+	 *
838
+	 * @param $post_id
839
+	 * @throws \EE_Error
840
+	 */
841
+	public function before_restore_cpt_item($post_id)
842
+	{
843
+		$this->_set_model_object($post_id, true, 'restore');
844
+		// if our cpt object isn't existent then get out immediately.
845
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
846
+			return;
847
+		}
848
+		$this->restore_cpt_item($post_id);
849
+	}
850
+
851
+
852
+	/**
853
+	 * Callback for the WordPress after_delete_post hook.
854
+	 * Execute some basic checks before calling the delete_cpt_item method in the child class.
855
+	 *
856
+	 * @param $post_id
857
+	 * @throws \EE_Error
858
+	 */
859
+	public function before_delete_cpt_item($post_id)
860
+	{
861
+		$this->_set_model_object($post_id, true, 'delete');
862
+		// if our cpt object isn't existent then get out immediately.
863
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
864
+			return;
865
+		}
866
+		$this->delete_cpt_item($post_id);
867
+	}
868
+
869
+
870
+	/**
871
+	 * This simply verifies if the cpt_model_object is instantiated for the given page and throws an error message
872
+	 * accordingly.
873
+	 *
874
+	 * @access public
875
+	 * @throws EE_Error
876
+	 * @return void
877
+	 */
878
+	public function verify_cpt_object()
879
+	{
880
+		$label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label;
881
+		// verify event object
882
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
883
+			throw new EE_Error(
884
+				sprintf(
885
+					__(
886
+						'Something has gone wrong with the page load because we are unable to set up the object for the %1$s.  This usually happens when the given id for the page route is NOT for the correct custom post type for this page',
887
+						'event_espresso'
888
+					),
889
+					$label
890
+				)
891
+			);
892
+		}
893
+		// if auto-draft then throw an error
894
+		if ($this->_cpt_model_obj->get('status') === 'auto-draft') {
895
+			EE_Error::overwrite_errors();
896
+			EE_Error::add_error(
897
+				sprintf(
898
+					__(
899
+						'This %1$s was saved without a title, description, or excerpt which means that none of the extra details you added were saved properly.  All autodrafts will show up in the "draft" view of your event list table.  You can delete them from there. Please click the "Add %1$s" button to refresh and restart.',
900
+						'event_espresso'
901
+					),
902
+					$label
903
+				),
904
+				__FILE__,
905
+				__FUNCTION__,
906
+				__LINE__
907
+			);
908
+		}
909
+	}
910
+
911
+
912
+	/**
913
+	 * admin_footer_scripts_global
914
+	 * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
915
+	 * will apply on ALL EE_Admin pages.
916
+	 *
917
+	 * @access public
918
+	 * @return void
919
+	 */
920
+	public function admin_footer_scripts_global()
921
+	{
922
+		$this->_add_admin_page_ajax_loading_img();
923
+		$this->_add_admin_page_overlay();
924
+	}
925
+
926
+
927
+	/**
928
+	 * add in any global scripts for cpt routes
929
+	 *
930
+	 * @return void
931
+	 */
932
+	public function load_global_scripts_styles()
933
+	{
934
+		parent::load_global_scripts_styles();
935
+		if ($this->_cpt_model_obj instanceof EE_CPT_Base) {
936
+			// setup custom post status object for localize script but only if we've got a cpt object
937
+			$statuses = $this->_cpt_model_obj->get_custom_post_statuses();
938
+			if (! empty($statuses)) {
939
+				// get ALL statuses!
940
+				$statuses = $this->_cpt_model_obj->get_all_post_statuses();
941
+				// setup object
942
+				$ee_cpt_statuses = array();
943
+				foreach ($statuses as $status => $label) {
944
+					$ee_cpt_statuses[ $status ] = array(
945
+						'label'      => $label,
946
+						'save_label' => sprintf(
947
+							wp_strip_all_tags(__('Save as %s', 'event_espresso')),
948
+							$label
949
+						),
950
+					);
951
+				}
952
+				wp_localize_script('ee_admin_js', 'eeCPTstatuses', $ee_cpt_statuses);
953
+			}
954
+		}
955
+	}
956
+
957
+
958
+	/**
959
+	 * This is a wrapper for the insert/update routes for cpt items so we can add things that are common to ALL
960
+	 * insert/updates
961
+	 *
962
+	 * @param  int     $post_id ID of post being updated
963
+	 * @param  WP_Post $post    Post object from WP
964
+	 * @param  bool    $update  Whether this is an update or a new save.
965
+	 * @return void
966
+	 * @throws \EE_Error
967
+	 */
968
+	public function insert_update($post_id, $post, $update)
969
+	{
970
+		// make sure that if this is a revision OR trash action that we don't do any updates!
971
+		if (isset($this->_req_data['action'])
972
+			&& (
973
+				$this->_req_data['action'] === 'restore'
974
+				|| $this->_req_data['action'] === 'trash'
975
+			)
976
+		) {
977
+			return;
978
+		}
979
+		$this->_set_model_object($post_id, true, 'insert_update');
980
+		// if our cpt object is not instantiated and its NOT the same post_id as what is triggering this callback, then exit.
981
+		if ($update
982
+			&& (
983
+				! $this->_cpt_model_obj instanceof EE_CPT_Base
984
+				|| $this->_cpt_model_obj->ID() !== $post_id
985
+			)
986
+		) {
987
+			return;
988
+		}
989
+		// check for autosave and update our req_data property accordingly.
990
+		/*if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE && isset( $this->_req_data['ee_autosave_data'] ) ) {
991 991
             foreach( (array) $this->_req_data['ee_autosave_data'] as $id => $values ) {
992 992
 
993 993
                 foreach ( (array) $values as $key => $value ) {
@@ -997,532 +997,532 @@  discard block
 block discarded – undo
997 997
 
998 998
         }/**/ // TODO reactivate after autosave is implemented in 4.2
999 999
 
1000
-        // take care of updating any selected page_template IF this cpt supports it.
1001
-        if ($this->_supports_page_templates($post->post_type) && ! empty($this->_req_data['page_template'])) {
1002
-            // wp version aware.
1003
-            if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
1004
-                $page_templates = wp_get_theme()->get_page_templates();
1005
-            } else {
1006
-                $post->page_template = $this->_req_data['page_template'];
1007
-                $page_templates = wp_get_theme()->get_page_templates($post);
1008
-            }
1009
-            if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[ $this->_req_data['page_template'] ])) {
1010
-                EE_Error::add_error(__('Invalid Page Template.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1011
-            } else {
1012
-                update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']);
1013
-            }
1014
-        }
1015
-        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
1016
-            return;
1017
-        } //TODO we'll remove this after reimplementing autosave in 4.2
1018
-        $this->_insert_update_cpt_item($post_id, $post);
1019
-    }
1020
-
1021
-
1022
-    /**
1023
-     * This hooks into the wp_trash_post() function and removes the `_wp_trash_meta_status` and `_wp_trash_meta_time`
1024
-     * post meta IF the trashed post is one of our CPT's - note this method should only be called with our cpt routes
1025
-     * so we don't have to check for our CPT.
1026
-     *
1027
-     * @param  int $post_id ID of the post
1028
-     * @return void
1029
-     */
1030
-    public function dont_permanently_delete_ee_cpts($post_id)
1031
-    {
1032
-        // only do this if we're actually processing one of our CPTs
1033
-        // if our cpt object isn't existent then get out immediately.
1034
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1035
-            return;
1036
-        }
1037
-        delete_post_meta($post_id, '_wp_trash_meta_status');
1038
-        delete_post_meta($post_id, '_wp_trash_meta_time');
1039
-        // our cpts may have comments so let's take care of that too
1040
-        delete_post_meta($post_id, '_wp_trash_meta_comments_status');
1041
-    }
1042
-
1043
-
1044
-    /**
1045
-     * This is a wrapper for the restore_cpt_revision route for cpt items so we can make sure that when a revision is
1046
-     * triggered that we restore related items.  In order to work cpt classes MUST have a restore_cpt_revision method
1047
-     * in them. We also have our OWN action in here so addons can hook into the restore process easily.
1048
-     *
1049
-     * @param  int $post_id     ID of cpt item
1050
-     * @param  int $revision_id ID of revision being restored
1051
-     * @return void
1052
-     */
1053
-    public function restore_revision($post_id, $revision_id)
1054
-    {
1055
-        $this->_restore_cpt_item($post_id, $revision_id);
1056
-        // global action
1057
-        do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id);
1058
-        // class specific action so you can limit hooking into a specific page.
1059
-        do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id);
1060
-    }
1061
-
1062
-
1063
-    /**
1064
-     * @see restore_revision() for details
1065
-     * @param  int $post_id     ID of cpt item
1066
-     * @param  int $revision_id ID of revision for item
1067
-     * @return void
1068
-     */
1069
-    abstract protected function _restore_cpt_item($post_id, $revision_id);
1070
-
1071
-
1072
-    /**
1073
-     * Execution of this method is added to the end of the load_page_dependencies method in the parent
1074
-     * so that we can fix a bug where default core metaboxes were not being called in the sidebar.
1075
-     * To fix we have to reset the current_screen using the page_slug
1076
-     * (which is identical - or should be - to our registered_post_type id.)
1077
-     * Also, since the core WP file loads the admin_header.php for WP
1078
-     * (and there are a bunch of other things edit-form-advanced.php loads that need to happen really early)
1079
-     * we need to load it NOW, hence our _route_admin_request in here. (Otherwise screen options won't be set).
1080
-     *
1081
-     * @return void
1082
-     */
1083
-    public function modify_current_screen()
1084
-    {
1085
-        // ONLY do this if the current page_route IS a cpt route
1086
-        if (! $this->_cpt_route) {
1087
-            return;
1088
-        }
1089
-        // routing things REALLY early b/c this is a cpt admin page
1090
-        set_current_screen($this->_cpt_routes[ $this->_req_action ]);
1091
-        $this->_current_screen = get_current_screen();
1092
-        $this->_current_screen->base = 'event-espresso';
1093
-        $this->_add_help_tabs(); // we make sure we add any help tabs back in!
1094
-        /*try {
1000
+		// take care of updating any selected page_template IF this cpt supports it.
1001
+		if ($this->_supports_page_templates($post->post_type) && ! empty($this->_req_data['page_template'])) {
1002
+			// wp version aware.
1003
+			if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
1004
+				$page_templates = wp_get_theme()->get_page_templates();
1005
+			} else {
1006
+				$post->page_template = $this->_req_data['page_template'];
1007
+				$page_templates = wp_get_theme()->get_page_templates($post);
1008
+			}
1009
+			if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[ $this->_req_data['page_template'] ])) {
1010
+				EE_Error::add_error(__('Invalid Page Template.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1011
+			} else {
1012
+				update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']);
1013
+			}
1014
+		}
1015
+		if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
1016
+			return;
1017
+		} //TODO we'll remove this after reimplementing autosave in 4.2
1018
+		$this->_insert_update_cpt_item($post_id, $post);
1019
+	}
1020
+
1021
+
1022
+	/**
1023
+	 * This hooks into the wp_trash_post() function and removes the `_wp_trash_meta_status` and `_wp_trash_meta_time`
1024
+	 * post meta IF the trashed post is one of our CPT's - note this method should only be called with our cpt routes
1025
+	 * so we don't have to check for our CPT.
1026
+	 *
1027
+	 * @param  int $post_id ID of the post
1028
+	 * @return void
1029
+	 */
1030
+	public function dont_permanently_delete_ee_cpts($post_id)
1031
+	{
1032
+		// only do this if we're actually processing one of our CPTs
1033
+		// if our cpt object isn't existent then get out immediately.
1034
+		if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1035
+			return;
1036
+		}
1037
+		delete_post_meta($post_id, '_wp_trash_meta_status');
1038
+		delete_post_meta($post_id, '_wp_trash_meta_time');
1039
+		// our cpts may have comments so let's take care of that too
1040
+		delete_post_meta($post_id, '_wp_trash_meta_comments_status');
1041
+	}
1042
+
1043
+
1044
+	/**
1045
+	 * This is a wrapper for the restore_cpt_revision route for cpt items so we can make sure that when a revision is
1046
+	 * triggered that we restore related items.  In order to work cpt classes MUST have a restore_cpt_revision method
1047
+	 * in them. We also have our OWN action in here so addons can hook into the restore process easily.
1048
+	 *
1049
+	 * @param  int $post_id     ID of cpt item
1050
+	 * @param  int $revision_id ID of revision being restored
1051
+	 * @return void
1052
+	 */
1053
+	public function restore_revision($post_id, $revision_id)
1054
+	{
1055
+		$this->_restore_cpt_item($post_id, $revision_id);
1056
+		// global action
1057
+		do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id);
1058
+		// class specific action so you can limit hooking into a specific page.
1059
+		do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id);
1060
+	}
1061
+
1062
+
1063
+	/**
1064
+	 * @see restore_revision() for details
1065
+	 * @param  int $post_id     ID of cpt item
1066
+	 * @param  int $revision_id ID of revision for item
1067
+	 * @return void
1068
+	 */
1069
+	abstract protected function _restore_cpt_item($post_id, $revision_id);
1070
+
1071
+
1072
+	/**
1073
+	 * Execution of this method is added to the end of the load_page_dependencies method in the parent
1074
+	 * so that we can fix a bug where default core metaboxes were not being called in the sidebar.
1075
+	 * To fix we have to reset the current_screen using the page_slug
1076
+	 * (which is identical - or should be - to our registered_post_type id.)
1077
+	 * Also, since the core WP file loads the admin_header.php for WP
1078
+	 * (and there are a bunch of other things edit-form-advanced.php loads that need to happen really early)
1079
+	 * we need to load it NOW, hence our _route_admin_request in here. (Otherwise screen options won't be set).
1080
+	 *
1081
+	 * @return void
1082
+	 */
1083
+	public function modify_current_screen()
1084
+	{
1085
+		// ONLY do this if the current page_route IS a cpt route
1086
+		if (! $this->_cpt_route) {
1087
+			return;
1088
+		}
1089
+		// routing things REALLY early b/c this is a cpt admin page
1090
+		set_current_screen($this->_cpt_routes[ $this->_req_action ]);
1091
+		$this->_current_screen = get_current_screen();
1092
+		$this->_current_screen->base = 'event-espresso';
1093
+		$this->_add_help_tabs(); // we make sure we add any help tabs back in!
1094
+		/*try {
1095 1095
             $this->_route_admin_request();
1096 1096
         } catch ( EE_Error $e ) {
1097 1097
             $e->get_error();
1098 1098
         }/**/
1099
-    }
1100
-
1101
-
1102
-    /**
1103
-     * This allows child classes to modify the default editor title that appears when people add a new or edit an
1104
-     * existing CPT item.     * This uses the _labels property set by the child class via _define_page_props. Just make
1105
-     * sure you have a key in _labels property that equals 'editor_title' and the value can be whatever you want the
1106
-     * default to be.
1107
-     *
1108
-     * @param string $title The new title (or existing if there is no editor_title defined)
1109
-     * @return string
1110
-     */
1111
-    public function add_custom_editor_default_title($title)
1112
-    {
1113
-        return isset($this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ])
1114
-            ? $this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ]
1115
-            : $title;
1116
-    }
1117
-
1118
-
1119
-    /**
1120
-     * hooks into the wp_get_shortlink button and makes sure that the shortlink gets generated
1121
-     *
1122
-     * @param string $shortlink   The already generated shortlink
1123
-     * @param int    $id          Post ID for this item
1124
-     * @param string $context     The context for the link
1125
-     * @param bool   $allow_slugs Whether to allow post slugs in the shortlink.
1126
-     * @return string
1127
-     */
1128
-    public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs)
1129
-    {
1130
-        if (! empty($id) && get_option('permalink_structure') !== '') {
1131
-            $post = get_post($id);
1132
-            if (isset($post->post_type) && $this->page_slug === $post->post_type) {
1133
-                $shortlink = home_url('?p=' . $post->ID);
1134
-            }
1135
-        }
1136
-        return $shortlink;
1137
-    }
1138
-
1139
-
1140
-    /**
1141
-     * overriding the parent route_admin_request method so we DON'T run the route twice on cpt core page loads (it's
1142
-     * already run in modify_current_screen())
1143
-     *
1144
-     * @return void
1145
-     */
1146
-    public function route_admin_request()
1147
-    {
1148
-        if ($this->_cpt_route) {
1149
-            return;
1150
-        }
1151
-        try {
1152
-            $this->_route_admin_request();
1153
-        } catch (EE_Error $e) {
1154
-            $e->get_error();
1155
-        }
1156
-    }
1157
-
1158
-
1159
-    /**
1160
-     * Add a hidden form input to cpt core pages so that we know to do redirects to our routes on saves
1161
-     *
1162
-     * @return void
1163
-     */
1164
-    public function cpt_post_form_hidden_input()
1165
-    {
1166
-        echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="' . $this->_admin_base_url . '" />';
1167
-        // we're also going to add the route value and the current page so we can direct autosave parsing correctly
1168
-        echo '<div id="ee-cpt-hidden-inputs">';
1169
-        echo '<input type="hidden" id="current_route" name="current_route" value="' . $this->_current_view . '" />';
1170
-        echo '<input type="hidden" id="current_page" name="current_page" value="' . $this->page_slug . '" />';
1171
-        echo '</div>';
1172
-    }
1173
-
1174
-
1175
-    /**
1176
-     * This allows us to redirect the location of revision restores when they happen so it goes to our CPT routes.
1177
-     *
1178
-     * @param  string $location Original location url
1179
-     * @param  int    $status   Status for http header
1180
-     * @return string           new (or original) url to redirect to.
1181
-     */
1182
-    public function revision_redirect($location, $status)
1183
-    {
1184
-        // get revision
1185
-        $rev_id = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
1186
-        // can't do anything without revision so let's get out if not present
1187
-        if (empty($rev_id)) {
1188
-            return $location;
1189
-        }
1190
-        // get rev_post_data
1191
-        $rev = get_post($rev_id);
1192
-        $admin_url = $this->_admin_base_url;
1193
-        $query_args = array(
1194
-            'action'   => 'edit',
1195
-            'post'     => $rev->post_parent,
1196
-            'revision' => $rev_id,
1197
-            'message'  => 5,
1198
-        );
1199
-        $this->_process_notices($query_args, true);
1200
-        return self::add_query_args_and_nonce($query_args, $admin_url);
1201
-    }
1202
-
1203
-
1204
-    /**
1205
-     * Modify the edit post link generated by wp core function so that EE CPTs get setup differently.
1206
-     *
1207
-     * @param  string $link    the original generated link
1208
-     * @param  int    $id      post id
1209
-     * @param  string $context optional, defaults to display.  How to write the '&'
1210
-     * @return string          the link
1211
-     */
1212
-    public function modify_edit_post_link($link, $id, $context)
1213
-    {
1214
-        $post = get_post($id);
1215
-        if (! isset($this->_req_data['action'])
1216
-            || ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1217
-            || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1218
-        ) {
1219
-            return $link;
1220
-        }
1221
-        $query_args = array(
1222
-            'action' => isset($this->_cpt_edit_routes[ $post->post_type ])
1223
-                ? $this->_cpt_edit_routes[ $post->post_type ]
1224
-                : 'edit',
1225
-            'post'   => $id,
1226
-        );
1227
-        return self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1228
-    }
1229
-
1230
-
1231
-    /**
1232
-     * Modify the trash link on our cpt edit pages so it has the required query var for triggering redirect properly on
1233
-     * our routes.
1234
-     *
1235
-     * @param  string $delete_link  original delete link
1236
-     * @param  int    $post_id      id of cpt object
1237
-     * @param  bool   $force_delete whether this is forcing a hard delete instead of trash
1238
-     * @return string new delete link
1239
-     * @throws EE_Error
1240
-     */
1241
-    public function modify_delete_post_link($delete_link, $post_id, $force_delete)
1242
-    {
1243
-        $post = get_post($post_id);
1244
-
1245
-        if (empty($this->_req_data['action'])
1246
-            || ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1247
-            || ! $post instanceof WP_Post
1248
-            || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1249
-        ) {
1250
-            return $delete_link;
1251
-        }
1252
-        $this->_set_model_object($post->ID, true);
1253
-
1254
-        // returns something like `trash_event` or `trash_attendee` or `trash_venue`
1255
-        $action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1256
-
1257
-        return EE_Admin_Page::add_query_args_and_nonce(
1258
-            array(
1259
-                'page'   => $this->_req_data['page'],
1260
-                'action' => $action,
1261
-                $this->_cpt_model_obj->get_model()->get_primary_key_field()->get_name()
1262
-                         => $post->ID,
1263
-            ),
1264
-            admin_url()
1265
-        );
1266
-    }
1267
-
1268
-
1269
-    /**
1270
-     * This is the callback for the 'redirect_post_location' filter in wp-admin/post.php
1271
-     * so that we can hijack the default redirect locations for wp custom post types
1272
-     * that WE'RE using and send back to OUR routes.  This should only be hooked in on the right route.
1273
-     *
1274
-     * @param  string $location This is the incoming currently set redirect location
1275
-     * @param  string $post_id  This is the 'ID' value of the wp_posts table
1276
-     * @return string           the new location to redirect to
1277
-     */
1278
-    public function cpt_post_location_redirect($location, $post_id)
1279
-    {
1280
-        // we DO have a match so let's setup the url
1281
-        // we have to get the post to determine our route
1282
-        $post = get_post($post_id);
1283
-        $edit_route = $this->_cpt_edit_routes[ $post->post_type ];
1284
-        // shared query_args
1285
-        $query_args = array('action' => $edit_route, 'post' => $post_id);
1286
-        $admin_url = $this->_admin_base_url;
1287
-        if (isset($this->_req_data['save']) || isset($this->_req_data['publish'])) {
1288
-            $status = get_post_status($post_id);
1289
-            if (isset($this->_req_data['publish'])) {
1290
-                switch ($status) {
1291
-                    case 'pending':
1292
-                        $message = 8;
1293
-                        break;
1294
-                    case 'future':
1295
-                        $message = 9;
1296
-                        break;
1297
-                    default:
1298
-                        $message = 6;
1299
-                }
1300
-            } else {
1301
-                $message = 'draft' === $status ? 10 : 1;
1302
-            }
1303
-        } elseif (isset($this->_req_data['addmeta']) && $this->_req_data['addmeta']) {
1304
-            $message = 2;
1305
-        } elseif (isset($this->_req_data['deletemeta']) && $this->_req_data['deletemeta']) {
1306
-            $message = 3;
1307
-        } elseif ($this->_req_data['action'] === 'post-quickpress-save-cont') {
1308
-            $message = 7;
1309
-        } else {
1310
-            $message = 4;
1311
-        }
1312
-        // change the message if the post type is not viewable on the frontend
1313
-        $this->_cpt_object = get_post_type_object($post->post_type);
1314
-        $message = $message === 1 && ! $this->_cpt_object->publicly_queryable ? 4 : $message;
1315
-        $query_args = array_merge(array('message' => $message), $query_args);
1316
-        $this->_process_notices($query_args, true);
1317
-        return self::add_query_args_and_nonce($query_args, $admin_url);
1318
-    }
1319
-
1320
-
1321
-    /**
1322
-     * This method is called to inject nav tabs on core WP cpt pages
1323
-     *
1324
-     * @access public
1325
-     * @return void
1326
-     */
1327
-    public function inject_nav_tabs()
1328
-    {
1329
-        // can we hijack and insert the nav_tabs?
1330
-        $nav_tabs = $this->_get_main_nav_tabs();
1331
-        // first close off existing form tag
1332
-        $html = '>';
1333
-        $html .= $nav_tabs;
1334
-        // now let's handle the remaining tag ( missing ">" is CORRECT )
1335
-        $html .= '<span></span';
1336
-        echo $html;
1337
-    }
1338
-
1339
-
1340
-    /**
1341
-     * This just sets up the post update messages when an update form is loaded
1342
-     *
1343
-     * @access public
1344
-     * @param  array $messages the original messages array
1345
-     * @return array           the new messages array
1346
-     */
1347
-    public function post_update_messages($messages)
1348
-    {
1349
-        global $post;
1350
-        $id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1351
-        $id = empty($id) && is_object($post) ? $post->ID : null;
1352
-        /*$current_route = isset($this->_req_data['current_route']) ? $this->_req_data['current_route'] : 'shouldneverwork';
1099
+	}
1100
+
1101
+
1102
+	/**
1103
+	 * This allows child classes to modify the default editor title that appears when people add a new or edit an
1104
+	 * existing CPT item.     * This uses the _labels property set by the child class via _define_page_props. Just make
1105
+	 * sure you have a key in _labels property that equals 'editor_title' and the value can be whatever you want the
1106
+	 * default to be.
1107
+	 *
1108
+	 * @param string $title The new title (or existing if there is no editor_title defined)
1109
+	 * @return string
1110
+	 */
1111
+	public function add_custom_editor_default_title($title)
1112
+	{
1113
+		return isset($this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ])
1114
+			? $this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ]
1115
+			: $title;
1116
+	}
1117
+
1118
+
1119
+	/**
1120
+	 * hooks into the wp_get_shortlink button and makes sure that the shortlink gets generated
1121
+	 *
1122
+	 * @param string $shortlink   The already generated shortlink
1123
+	 * @param int    $id          Post ID for this item
1124
+	 * @param string $context     The context for the link
1125
+	 * @param bool   $allow_slugs Whether to allow post slugs in the shortlink.
1126
+	 * @return string
1127
+	 */
1128
+	public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs)
1129
+	{
1130
+		if (! empty($id) && get_option('permalink_structure') !== '') {
1131
+			$post = get_post($id);
1132
+			if (isset($post->post_type) && $this->page_slug === $post->post_type) {
1133
+				$shortlink = home_url('?p=' . $post->ID);
1134
+			}
1135
+		}
1136
+		return $shortlink;
1137
+	}
1138
+
1139
+
1140
+	/**
1141
+	 * overriding the parent route_admin_request method so we DON'T run the route twice on cpt core page loads (it's
1142
+	 * already run in modify_current_screen())
1143
+	 *
1144
+	 * @return void
1145
+	 */
1146
+	public function route_admin_request()
1147
+	{
1148
+		if ($this->_cpt_route) {
1149
+			return;
1150
+		}
1151
+		try {
1152
+			$this->_route_admin_request();
1153
+		} catch (EE_Error $e) {
1154
+			$e->get_error();
1155
+		}
1156
+	}
1157
+
1158
+
1159
+	/**
1160
+	 * Add a hidden form input to cpt core pages so that we know to do redirects to our routes on saves
1161
+	 *
1162
+	 * @return void
1163
+	 */
1164
+	public function cpt_post_form_hidden_input()
1165
+	{
1166
+		echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="' . $this->_admin_base_url . '" />';
1167
+		// we're also going to add the route value and the current page so we can direct autosave parsing correctly
1168
+		echo '<div id="ee-cpt-hidden-inputs">';
1169
+		echo '<input type="hidden" id="current_route" name="current_route" value="' . $this->_current_view . '" />';
1170
+		echo '<input type="hidden" id="current_page" name="current_page" value="' . $this->page_slug . '" />';
1171
+		echo '</div>';
1172
+	}
1173
+
1174
+
1175
+	/**
1176
+	 * This allows us to redirect the location of revision restores when they happen so it goes to our CPT routes.
1177
+	 *
1178
+	 * @param  string $location Original location url
1179
+	 * @param  int    $status   Status for http header
1180
+	 * @return string           new (or original) url to redirect to.
1181
+	 */
1182
+	public function revision_redirect($location, $status)
1183
+	{
1184
+		// get revision
1185
+		$rev_id = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
1186
+		// can't do anything without revision so let's get out if not present
1187
+		if (empty($rev_id)) {
1188
+			return $location;
1189
+		}
1190
+		// get rev_post_data
1191
+		$rev = get_post($rev_id);
1192
+		$admin_url = $this->_admin_base_url;
1193
+		$query_args = array(
1194
+			'action'   => 'edit',
1195
+			'post'     => $rev->post_parent,
1196
+			'revision' => $rev_id,
1197
+			'message'  => 5,
1198
+		);
1199
+		$this->_process_notices($query_args, true);
1200
+		return self::add_query_args_and_nonce($query_args, $admin_url);
1201
+	}
1202
+
1203
+
1204
+	/**
1205
+	 * Modify the edit post link generated by wp core function so that EE CPTs get setup differently.
1206
+	 *
1207
+	 * @param  string $link    the original generated link
1208
+	 * @param  int    $id      post id
1209
+	 * @param  string $context optional, defaults to display.  How to write the '&'
1210
+	 * @return string          the link
1211
+	 */
1212
+	public function modify_edit_post_link($link, $id, $context)
1213
+	{
1214
+		$post = get_post($id);
1215
+		if (! isset($this->_req_data['action'])
1216
+			|| ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1217
+			|| $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1218
+		) {
1219
+			return $link;
1220
+		}
1221
+		$query_args = array(
1222
+			'action' => isset($this->_cpt_edit_routes[ $post->post_type ])
1223
+				? $this->_cpt_edit_routes[ $post->post_type ]
1224
+				: 'edit',
1225
+			'post'   => $id,
1226
+		);
1227
+		return self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1228
+	}
1229
+
1230
+
1231
+	/**
1232
+	 * Modify the trash link on our cpt edit pages so it has the required query var for triggering redirect properly on
1233
+	 * our routes.
1234
+	 *
1235
+	 * @param  string $delete_link  original delete link
1236
+	 * @param  int    $post_id      id of cpt object
1237
+	 * @param  bool   $force_delete whether this is forcing a hard delete instead of trash
1238
+	 * @return string new delete link
1239
+	 * @throws EE_Error
1240
+	 */
1241
+	public function modify_delete_post_link($delete_link, $post_id, $force_delete)
1242
+	{
1243
+		$post = get_post($post_id);
1244
+
1245
+		if (empty($this->_req_data['action'])
1246
+			|| ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1247
+			|| ! $post instanceof WP_Post
1248
+			|| $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1249
+		) {
1250
+			return $delete_link;
1251
+		}
1252
+		$this->_set_model_object($post->ID, true);
1253
+
1254
+		// returns something like `trash_event` or `trash_attendee` or `trash_venue`
1255
+		$action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1256
+
1257
+		return EE_Admin_Page::add_query_args_and_nonce(
1258
+			array(
1259
+				'page'   => $this->_req_data['page'],
1260
+				'action' => $action,
1261
+				$this->_cpt_model_obj->get_model()->get_primary_key_field()->get_name()
1262
+						 => $post->ID,
1263
+			),
1264
+			admin_url()
1265
+		);
1266
+	}
1267
+
1268
+
1269
+	/**
1270
+	 * This is the callback for the 'redirect_post_location' filter in wp-admin/post.php
1271
+	 * so that we can hijack the default redirect locations for wp custom post types
1272
+	 * that WE'RE using and send back to OUR routes.  This should only be hooked in on the right route.
1273
+	 *
1274
+	 * @param  string $location This is the incoming currently set redirect location
1275
+	 * @param  string $post_id  This is the 'ID' value of the wp_posts table
1276
+	 * @return string           the new location to redirect to
1277
+	 */
1278
+	public function cpt_post_location_redirect($location, $post_id)
1279
+	{
1280
+		// we DO have a match so let's setup the url
1281
+		// we have to get the post to determine our route
1282
+		$post = get_post($post_id);
1283
+		$edit_route = $this->_cpt_edit_routes[ $post->post_type ];
1284
+		// shared query_args
1285
+		$query_args = array('action' => $edit_route, 'post' => $post_id);
1286
+		$admin_url = $this->_admin_base_url;
1287
+		if (isset($this->_req_data['save']) || isset($this->_req_data['publish'])) {
1288
+			$status = get_post_status($post_id);
1289
+			if (isset($this->_req_data['publish'])) {
1290
+				switch ($status) {
1291
+					case 'pending':
1292
+						$message = 8;
1293
+						break;
1294
+					case 'future':
1295
+						$message = 9;
1296
+						break;
1297
+					default:
1298
+						$message = 6;
1299
+				}
1300
+			} else {
1301
+				$message = 'draft' === $status ? 10 : 1;
1302
+			}
1303
+		} elseif (isset($this->_req_data['addmeta']) && $this->_req_data['addmeta']) {
1304
+			$message = 2;
1305
+		} elseif (isset($this->_req_data['deletemeta']) && $this->_req_data['deletemeta']) {
1306
+			$message = 3;
1307
+		} elseif ($this->_req_data['action'] === 'post-quickpress-save-cont') {
1308
+			$message = 7;
1309
+		} else {
1310
+			$message = 4;
1311
+		}
1312
+		// change the message if the post type is not viewable on the frontend
1313
+		$this->_cpt_object = get_post_type_object($post->post_type);
1314
+		$message = $message === 1 && ! $this->_cpt_object->publicly_queryable ? 4 : $message;
1315
+		$query_args = array_merge(array('message' => $message), $query_args);
1316
+		$this->_process_notices($query_args, true);
1317
+		return self::add_query_args_and_nonce($query_args, $admin_url);
1318
+	}
1319
+
1320
+
1321
+	/**
1322
+	 * This method is called to inject nav tabs on core WP cpt pages
1323
+	 *
1324
+	 * @access public
1325
+	 * @return void
1326
+	 */
1327
+	public function inject_nav_tabs()
1328
+	{
1329
+		// can we hijack and insert the nav_tabs?
1330
+		$nav_tabs = $this->_get_main_nav_tabs();
1331
+		// first close off existing form tag
1332
+		$html = '>';
1333
+		$html .= $nav_tabs;
1334
+		// now let's handle the remaining tag ( missing ">" is CORRECT )
1335
+		$html .= '<span></span';
1336
+		echo $html;
1337
+	}
1338
+
1339
+
1340
+	/**
1341
+	 * This just sets up the post update messages when an update form is loaded
1342
+	 *
1343
+	 * @access public
1344
+	 * @param  array $messages the original messages array
1345
+	 * @return array           the new messages array
1346
+	 */
1347
+	public function post_update_messages($messages)
1348
+	{
1349
+		global $post;
1350
+		$id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1351
+		$id = empty($id) && is_object($post) ? $post->ID : null;
1352
+		/*$current_route = isset($this->_req_data['current_route']) ? $this->_req_data['current_route'] : 'shouldneverwork';
1353 1353
 
1354 1354
         $route_to_check = $post_type && isset( $this->_cpt_routes[$current_route]) ? $this->_cpt_routes[$current_route] : '';/**/
1355
-        $messages[ $post->post_type ] = array(
1356
-            0  => '', // Unused. Messages start at index 1.
1357
-            1  => sprintf(
1358
-                __('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'),
1359
-                $this->_cpt_object->labels->singular_name,
1360
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1361
-                '</a>'
1362
-            ),
1363
-            2  => __('Custom field updated', 'event_espresso'),
1364
-            3  => __('Custom field deleted.', 'event_espresso'),
1365
-            4  => sprintf(__('%1$s updated.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1366
-            5  => isset($_GET['revision']) ? sprintf(
1367
-                __('%s restored to revision from %s', 'event_espresso'),
1368
-                $this->_cpt_object->labels->singular_name,
1369
-                wp_post_revision_title((int) $_GET['revision'], false)
1370
-            )
1371
-                : false,
1372
-            6  => sprintf(
1373
-                __('%1$s published. %2$sView %1$s%3$s', 'event_espresso'),
1374
-                $this->_cpt_object->labels->singular_name,
1375
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1376
-                '</a>'
1377
-            ),
1378
-            7  => sprintf(__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1379
-            8  => sprintf(
1380
-                __('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'),
1381
-                $this->_cpt_object->labels->singular_name,
1382
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">',
1383
-                '</a>'
1384
-            ),
1385
-            9  => sprintf(
1386
-                __('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'),
1387
-                $this->_cpt_object->labels->singular_name,
1388
-                '<strong>' . date_i18n('M j, Y @ G:i', strtotime($post->post_date)) . '</strong>',
1389
-                '<a target="_blank" href="' . esc_url(get_permalink($id)),
1390
-                '</a>'
1391
-            ),
1392
-            10 => sprintf(
1393
-                __('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'),
1394
-                $this->_cpt_object->labels->singular_name,
1395
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1396
-                '</a>'
1397
-            ),
1398
-        );
1399
-        return $messages;
1400
-    }
1401
-
1402
-
1403
-    /**
1404
-     * default method for the 'create_new' route for cpt admin pages.
1405
-     * For reference what to include in here, see wp-admin/post-new.php
1406
-     *
1407
-     * @access  protected
1408
-     * @return void
1409
-     */
1410
-    protected function _create_new_cpt_item()
1411
-    {
1412
-        // gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1413
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1414
-        $post_type = $this->_cpt_routes[ $this->_req_action ];
1415
-        $post_type_object = $this->_cpt_object;
1416
-        $title = $post_type_object->labels->add_new_item;
1417
-        $post = $post = get_default_post_to_edit($this->_cpt_routes[ $this->_req_action ], true);
1418
-        add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1419
-        // modify the default editor title field with default title.
1420
-        add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1421
-        $this->loadEditorTemplate(true);
1422
-    }
1423
-
1424
-
1425
-    /**
1426
-     * Enqueues auto-save and loads the editor template
1427
-     *
1428
-     * @param bool $creating
1429
-     */
1430
-    private function loadEditorTemplate($creating = true)
1431
-    {
1432
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1433
-        // these vars are used by the template
1434
-        $editing = true;
1435
-        $post_ID = $post->ID;
1436
-        if (apply_filters('FHEE__EE_Admin_Page_CPT___create_new_cpt_item__replace_editor', false, $post) === false) {
1437
-            // only enqueue autosave when creating event (necessary to get permalink/url generated)
1438
-            // otherwise EE doesn't support autosave fully, so to prevent user confusion we disable it in edit context.
1439
-            if ($creating) {
1440
-                wp_enqueue_script('autosave');
1441
-            } else {
1442
-                if (isset($this->_cpt_routes[ $this->_req_data['action'] ])
1443
-                    && ! isset($this->_labels['hide_add_button_on_cpt_route'][ $this->_req_data['action'] ])
1444
-                ) {
1445
-                    $create_new_action = apply_filters(
1446
-                        'FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action',
1447
-                        'create_new',
1448
-                        $this
1449
-                    );
1450
-                    $post_new_file = EE_Admin_Page::add_query_args_and_nonce(
1451
-                        array(
1452
-                            'action' => $create_new_action,
1453
-                            'page'   => $this->page_slug,
1454
-                        ),
1455
-                        'admin.php'
1456
-                    );
1457
-                }
1458
-            }
1459
-            include_once WP_ADMIN_PATH . 'edit-form-advanced.php';
1460
-        }
1461
-    }
1462
-
1463
-
1464
-    public function add_new_admin_page_global()
1465
-    {
1466
-        $admin_page = ! empty($this->_req_data['post']) ? 'post-php' : 'post-new-php';
1467
-        ?>
1355
+		$messages[ $post->post_type ] = array(
1356
+			0  => '', // Unused. Messages start at index 1.
1357
+			1  => sprintf(
1358
+				__('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'),
1359
+				$this->_cpt_object->labels->singular_name,
1360
+				'<a href="' . esc_url(get_permalink($id)) . '">',
1361
+				'</a>'
1362
+			),
1363
+			2  => __('Custom field updated', 'event_espresso'),
1364
+			3  => __('Custom field deleted.', 'event_espresso'),
1365
+			4  => sprintf(__('%1$s updated.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1366
+			5  => isset($_GET['revision']) ? sprintf(
1367
+				__('%s restored to revision from %s', 'event_espresso'),
1368
+				$this->_cpt_object->labels->singular_name,
1369
+				wp_post_revision_title((int) $_GET['revision'], false)
1370
+			)
1371
+				: false,
1372
+			6  => sprintf(
1373
+				__('%1$s published. %2$sView %1$s%3$s', 'event_espresso'),
1374
+				$this->_cpt_object->labels->singular_name,
1375
+				'<a href="' . esc_url(get_permalink($id)) . '">',
1376
+				'</a>'
1377
+			),
1378
+			7  => sprintf(__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1379
+			8  => sprintf(
1380
+				__('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'),
1381
+				$this->_cpt_object->labels->singular_name,
1382
+				'<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">',
1383
+				'</a>'
1384
+			),
1385
+			9  => sprintf(
1386
+				__('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'),
1387
+				$this->_cpt_object->labels->singular_name,
1388
+				'<strong>' . date_i18n('M j, Y @ G:i', strtotime($post->post_date)) . '</strong>',
1389
+				'<a target="_blank" href="' . esc_url(get_permalink($id)),
1390
+				'</a>'
1391
+			),
1392
+			10 => sprintf(
1393
+				__('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'),
1394
+				$this->_cpt_object->labels->singular_name,
1395
+				'<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1396
+				'</a>'
1397
+			),
1398
+		);
1399
+		return $messages;
1400
+	}
1401
+
1402
+
1403
+	/**
1404
+	 * default method for the 'create_new' route for cpt admin pages.
1405
+	 * For reference what to include in here, see wp-admin/post-new.php
1406
+	 *
1407
+	 * @access  protected
1408
+	 * @return void
1409
+	 */
1410
+	protected function _create_new_cpt_item()
1411
+	{
1412
+		// gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1413
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1414
+		$post_type = $this->_cpt_routes[ $this->_req_action ];
1415
+		$post_type_object = $this->_cpt_object;
1416
+		$title = $post_type_object->labels->add_new_item;
1417
+		$post = $post = get_default_post_to_edit($this->_cpt_routes[ $this->_req_action ], true);
1418
+		add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1419
+		// modify the default editor title field with default title.
1420
+		add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1421
+		$this->loadEditorTemplate(true);
1422
+	}
1423
+
1424
+
1425
+	/**
1426
+	 * Enqueues auto-save and loads the editor template
1427
+	 *
1428
+	 * @param bool $creating
1429
+	 */
1430
+	private function loadEditorTemplate($creating = true)
1431
+	{
1432
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1433
+		// these vars are used by the template
1434
+		$editing = true;
1435
+		$post_ID = $post->ID;
1436
+		if (apply_filters('FHEE__EE_Admin_Page_CPT___create_new_cpt_item__replace_editor', false, $post) === false) {
1437
+			// only enqueue autosave when creating event (necessary to get permalink/url generated)
1438
+			// otherwise EE doesn't support autosave fully, so to prevent user confusion we disable it in edit context.
1439
+			if ($creating) {
1440
+				wp_enqueue_script('autosave');
1441
+			} else {
1442
+				if (isset($this->_cpt_routes[ $this->_req_data['action'] ])
1443
+					&& ! isset($this->_labels['hide_add_button_on_cpt_route'][ $this->_req_data['action'] ])
1444
+				) {
1445
+					$create_new_action = apply_filters(
1446
+						'FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action',
1447
+						'create_new',
1448
+						$this
1449
+					);
1450
+					$post_new_file = EE_Admin_Page::add_query_args_and_nonce(
1451
+						array(
1452
+							'action' => $create_new_action,
1453
+							'page'   => $this->page_slug,
1454
+						),
1455
+						'admin.php'
1456
+					);
1457
+				}
1458
+			}
1459
+			include_once WP_ADMIN_PATH . 'edit-form-advanced.php';
1460
+		}
1461
+	}
1462
+
1463
+
1464
+	public function add_new_admin_page_global()
1465
+	{
1466
+		$admin_page = ! empty($this->_req_data['post']) ? 'post-php' : 'post-new-php';
1467
+		?>
1468 1468
         <script type="text/javascript">
1469 1469
             adminpage = '<?php echo $admin_page; ?>';
1470 1470
         </script>
1471 1471
         <?php
1472
-    }
1473
-
1474
-
1475
-    /**
1476
-     * default method for the 'edit' route for cpt admin pages
1477
-     * For reference on what to put in here, refer to wp-admin/post.php
1478
-     *
1479
-     * @access protected
1480
-     * @return string   template for edit cpt form
1481
-     */
1482
-    protected function _edit_cpt_item()
1483
-    {
1484
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1485
-        $post_id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1486
-        $post = ! empty($post_id) ? get_post($post_id, OBJECT, 'edit') : null;
1487
-        if (empty($post)) {
1488
-            wp_die(__('You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?', 'event_espresso'));
1489
-        }
1490
-        if (! empty($_GET['get-post-lock'])) {
1491
-            wp_set_post_lock($post_id);
1492
-            wp_redirect(get_edit_post_link($post_id, 'url'));
1493
-            exit();
1494
-        }
1495
-
1496
-        // template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1497
-        $post_type = $this->_cpt_routes[ $this->_req_action ];
1498
-        $post_type_object = $this->_cpt_object;
1499
-
1500
-        if (! wp_check_post_lock($post->ID)) {
1501
-            wp_set_post_lock($post->ID);
1502
-        }
1503
-        add_action('admin_footer', '_admin_notice_post_locked');
1504
-        if (post_type_supports($this->_cpt_routes[ $this->_req_action ], 'comments')) {
1505
-            wp_enqueue_script('admin-comments');
1506
-            enqueue_comment_hotkeys_js();
1507
-        }
1508
-        add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1509
-        // modify the default editor title field with default title.
1510
-        add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1511
-        $this->loadEditorTemplate(false);
1512
-    }
1513
-
1514
-
1515
-
1516
-    /**
1517
-     * some getters
1518
-     */
1519
-    /**
1520
-     * This returns the protected _cpt_model_obj property
1521
-     *
1522
-     * @return EE_CPT_Base
1523
-     */
1524
-    public function get_cpt_model_obj()
1525
-    {
1526
-        return $this->_cpt_model_obj;
1527
-    }
1472
+	}
1473
+
1474
+
1475
+	/**
1476
+	 * default method for the 'edit' route for cpt admin pages
1477
+	 * For reference on what to put in here, refer to wp-admin/post.php
1478
+	 *
1479
+	 * @access protected
1480
+	 * @return string   template for edit cpt form
1481
+	 */
1482
+	protected function _edit_cpt_item()
1483
+	{
1484
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1485
+		$post_id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1486
+		$post = ! empty($post_id) ? get_post($post_id, OBJECT, 'edit') : null;
1487
+		if (empty($post)) {
1488
+			wp_die(__('You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?', 'event_espresso'));
1489
+		}
1490
+		if (! empty($_GET['get-post-lock'])) {
1491
+			wp_set_post_lock($post_id);
1492
+			wp_redirect(get_edit_post_link($post_id, 'url'));
1493
+			exit();
1494
+		}
1495
+
1496
+		// template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1497
+		$post_type = $this->_cpt_routes[ $this->_req_action ];
1498
+		$post_type_object = $this->_cpt_object;
1499
+
1500
+		if (! wp_check_post_lock($post->ID)) {
1501
+			wp_set_post_lock($post->ID);
1502
+		}
1503
+		add_action('admin_footer', '_admin_notice_post_locked');
1504
+		if (post_type_supports($this->_cpt_routes[ $this->_req_action ], 'comments')) {
1505
+			wp_enqueue_script('admin-comments');
1506
+			enqueue_comment_hotkeys_js();
1507
+		}
1508
+		add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1509
+		// modify the default editor title field with default title.
1510
+		add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1511
+		$this->loadEditorTemplate(false);
1512
+	}
1513
+
1514
+
1515
+
1516
+	/**
1517
+	 * some getters
1518
+	 */
1519
+	/**
1520
+	 * This returns the protected _cpt_model_obj property
1521
+	 *
1522
+	 * @return EE_CPT_Base
1523
+	 */
1524
+	public function get_cpt_model_obj()
1525
+	{
1526
+		return $this->_cpt_model_obj;
1527
+	}
1528 1528
 }
Please login to merge, or discard this patch.
Spacing   +79 added lines, -79 removed lines patch added patch discarded remove patch
@@ -164,7 +164,7 @@  discard block
 block discarded – undo
164 164
      */
165 165
     protected function getLoader()
166 166
     {
167
-        if (! $this->loader instanceof LoaderInterface) {
167
+        if ( ! $this->loader instanceof LoaderInterface) {
168 168
             $this->loader = LoaderFactory::getLoader();
169 169
         }
170 170
         return $this->loader;
@@ -188,11 +188,11 @@  discard block
 block discarded – undo
188 188
             $this->_cpt_routes
189 189
         );
190 190
         // let's see if the current route has a value for cpt_object_slug if it does we use that instead of the page
191
-        $this->_cpt_object = isset($this->_req_data['action']) && isset($this->_cpt_routes[ $this->_req_data['action'] ])
192
-            ? get_post_type_object($this->_cpt_routes[ $this->_req_data['action'] ])
191
+        $this->_cpt_object = isset($this->_req_data['action']) && isset($this->_cpt_routes[$this->_req_data['action']])
192
+            ? get_post_type_object($this->_cpt_routes[$this->_req_data['action']])
193 193
             : get_post_type_object($page);
194 194
         // tweak pagenow for page loading.
195
-        if (! $this->_pagenow_map) {
195
+        if ( ! $this->_pagenow_map) {
196 196
             $this->_pagenow_map = array(
197 197
                 'create_new' => 'post-new.php',
198 198
                 'edit'       => 'post.php',
@@ -226,12 +226,12 @@  discard block
 block discarded – undo
226 226
     {
227 227
         global $pagenow, $hook_suffix;
228 228
         // possibly reset pagenow.
229
-        if (! empty($this->_req_data['page'])
229
+        if ( ! empty($this->_req_data['page'])
230 230
             && $this->_req_data['page'] == $this->page_slug
231 231
             && ! empty($this->_req_data['action'])
232
-            && isset($this->_pagenow_map[ $this->_req_data['action'] ])
232
+            && isset($this->_pagenow_map[$this->_req_data['action']])
233 233
         ) {
234
-            $pagenow = $this->_pagenow_map[ $this->_req_data['action'] ];
234
+            $pagenow = $this->_pagenow_map[$this->_req_data['action']];
235 235
             $hook_suffix = $pagenow;
236 236
         }
237 237
     }
@@ -263,7 +263,7 @@  discard block
 block discarded – undo
263 263
         if (empty($wp_meta_boxes)) {
264 264
             return;
265 265
         }
266
-        $current_metaboxes = isset($wp_meta_boxes[ $this->page_slug ]) ? $wp_meta_boxes[ $this->page_slug ] : array();
266
+        $current_metaboxes = isset($wp_meta_boxes[$this->page_slug]) ? $wp_meta_boxes[$this->page_slug] : array();
267 267
         foreach ($current_metaboxes as $box_context) {
268 268
             foreach ($box_context as $box_details) {
269 269
                 foreach ($box_details as $box) {
@@ -296,7 +296,7 @@  discard block
 block discarded – undo
296 296
             $this
297 297
         );
298 298
         $containers = apply_filters(
299
-            'FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers',
299
+            'FHEE__EE_Admin_Page_CPT__'.get_class($this).'___load_autosave_scripts_styles__containers',
300 300
             $containers,
301 301
             $this
302 302
         );
@@ -342,7 +342,7 @@  discard block
 block discarded – undo
342 342
     protected function _load_page_dependencies()
343 343
     {
344 344
         // we only add stuff if this is a cpt_route!
345
-        if (! $this->_cpt_route) {
345
+        if ( ! $this->_cpt_route) {
346 346
             parent::_load_page_dependencies();
347 347
             return;
348 348
         }
@@ -366,16 +366,16 @@  discard block
 block discarded – undo
366 366
         add_filter('pre_get_shortlink', array($this, 'add_shortlink_button_to_editor'), 10, 4);
367 367
         // This basically allows us to change the title of the "publish" metabox area
368 368
         // on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class.
369
-        if (! empty($this->_labels['publishbox'])) {
369
+        if ( ! empty($this->_labels['publishbox'])) {
370 370
             $box_label = is_array($this->_labels['publishbox'])
371
-                         && isset($this->_labels['publishbox'][ $this->_req_action ])
372
-                ? $this->_labels['publishbox'][ $this->_req_action ]
371
+                         && isset($this->_labels['publishbox'][$this->_req_action])
372
+                ? $this->_labels['publishbox'][$this->_req_action]
373 373
                 : $this->_labels['publishbox'];
374 374
             add_meta_box(
375 375
                 'submitdiv',
376 376
                 $box_label,
377 377
                 'post_submit_meta_box',
378
-                $this->_cpt_routes[ $this->_req_action ],
378
+                $this->_cpt_routes[$this->_req_action],
379 379
                 'side',
380 380
                 'core'
381 381
             );
@@ -386,7 +386,7 @@  discard block
 block discarded – undo
386 386
                 'page_templates',
387 387
                 __('Page Template', 'event_espresso'),
388 388
                 array($this, 'page_template_meta_box'),
389
-                $this->_cpt_routes[ $this->_req_action ],
389
+                $this->_cpt_routes[$this->_req_action],
390 390
                 'side',
391 391
                 'default'
392 392
             );
@@ -418,8 +418,8 @@  discard block
 block discarded – undo
418 418
         // This is for any plugins that are doing things properly
419 419
         // and hooking into the load page hook for core wp cpt routes.
420 420
         global $pagenow;
421
-        add_action('load-' . $pagenow, array($this, 'modify_current_screen'), 20);
422
-        do_action('load-' . $pagenow);
421
+        add_action('load-'.$pagenow, array($this, 'modify_current_screen'), 20);
422
+        do_action('load-'.$pagenow);
423 423
         add_action('admin_enqueue_scripts', array($this, 'setup_autosave_hooks'), 30);
424 424
         // we route REALLY early.
425 425
         try {
@@ -448,8 +448,8 @@  discard block
 block discarded – undo
448 448
                 'admin.php?page=espresso_registrations&action=contact_list',
449 449
             ),
450 450
             1 => array(
451
-                'edit.php?post_type=' . $this->_cpt_object->name,
452
-                'admin.php?page=' . $this->_cpt_object->name,
451
+                'edit.php?post_type='.$this->_cpt_object->name,
452
+                'admin.php?page='.$this->_cpt_object->name,
453 453
             ),
454 454
         );
455 455
         foreach ($routes_to_match as $route_matches) {
@@ -478,7 +478,7 @@  discard block
 block discarded – undo
478 478
             'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
479 479
         );
480 480
         $cpt_args = $custom_post_types->getDefinitions();
481
-        $cpt_args = isset($cpt_args[ $cpt_name ]) ? $cpt_args[ $cpt_name ]['args'] : array();
481
+        $cpt_args = isset($cpt_args[$cpt_name]) ? $cpt_args[$cpt_name]['args'] : array();
482 482
         $cpt_has_support = ! empty($cpt_args['page_templates']);
483 483
 
484 484
         // if the installed version of WP is > 4.7 we do some additional checks.
@@ -487,7 +487,7 @@  discard block
 block discarded – undo
487 487
             // if there are $post_templates for this cpt, then we return false for this method because
488 488
             // that means we aren't going to load our page template manager and leave that up to the native
489 489
             // cpt template manager.
490
-            $cpt_has_support = ! isset($post_templates[ $cpt_name ]) ? $cpt_has_support : false;
490
+            $cpt_has_support = ! isset($post_templates[$cpt_name]) ? $cpt_has_support : false;
491 491
         }
492 492
 
493 493
         return $cpt_has_support;
@@ -561,7 +561,7 @@  discard block
 block discarded – undo
561 561
 
562 562
         $statuses = $this->_cpt_model_obj->get_custom_post_statuses();
563 563
         $cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses)
564
-            ? $statuses[ $this->_cpt_model_obj->status() ]
564
+            ? $statuses[$this->_cpt_model_obj->status()]
565 565
             : '';
566 566
         $template_args = array(
567 567
             'cur_status'            => $this->_cpt_model_obj->status(),
@@ -576,7 +576,7 @@  discard block
 block discarded – undo
576 576
             $template_args['statuses'] = $statuses;
577 577
         }
578 578
 
579
-        $template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php';
579
+        $template = EE_ADMIN_TEMPLATE.'status_dropdown.template.php';
580 580
         EEH_Template::display_template($template, $template_args);
581 581
     }
582 582
 
@@ -617,7 +617,7 @@  discard block
 block discarded – undo
617 617
             : null;
618 618
         $this->_verify_nonce($nonce, 'autosave');
619 619
         // make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it)
620
-        if (! defined('DOING_AUTOSAVE')) {
620
+        if ( ! defined('DOING_AUTOSAVE')) {
621 621
             define('DOING_AUTOSAVE', true);
622 622
         }
623 623
         // if we made it here then the nonce checked out.  Let's run our methods and actions
@@ -628,7 +628,7 @@  discard block
 block discarded – undo
628 628
             $this->_template_args['success'] = true;
629 629
         }
630 630
         do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this);
631
-        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this);
631
+        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_'.get_class($this), $this);
632 632
         // now let's return json
633 633
         $this->_return_json();
634 634
     }
@@ -650,7 +650,7 @@  discard block
 block discarded – undo
650 650
             return;
651 651
         }
652 652
         // set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes
653
-        if (! empty($this->_cpt_object)) {
653
+        if ( ! empty($this->_cpt_object)) {
654 654
             $this->_page_routes = array_merge(
655 655
                 array(
656 656
                     'create_new' => '_create_new_cpt_item',
@@ -681,10 +681,10 @@  discard block
 block discarded – undo
681 681
             );
682 682
         }
683 683
         // load the next section only if this is a matching cpt route as set in the cpt routes array.
684
-        if (! isset($this->_cpt_routes[ $this->_req_action ])) {
684
+        if ( ! isset($this->_cpt_routes[$this->_req_action])) {
685 685
             return;
686 686
         }
687
-        $this->_cpt_route = isset($this->_cpt_routes[ $this->_req_action ]) ? true : false;
687
+        $this->_cpt_route = isset($this->_cpt_routes[$this->_req_action]) ? true : false;
688 688
         // add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') );
689 689
         if (empty($this->_cpt_object)) {
690 690
             $msg = sprintf(
@@ -724,7 +724,7 @@  discard block
 block discarded – undo
724 724
         if (empty($this->_cpt_model_names)
725 725
             || (
726 726
                 ! $ignore_route_check
727
-                && ! isset($this->_cpt_routes[ $this->_req_action ])
727
+                && ! isset($this->_cpt_routes[$this->_req_action])
728 728
             ) || (
729 729
                 $this->_cpt_model_obj instanceof EE_CPT_Base
730 730
                 && $this->_cpt_model_obj->ID() === $id
@@ -741,11 +741,11 @@  discard block
 block discarded – undo
741 741
                 'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
742 742
             );
743 743
             $model_names = $custom_post_types->getCustomPostTypeModelNames($post_type);
744
-            if (isset($model_names[ $post_type ])) {
745
-                $model = EE_Registry::instance()->load_model($model_names[ $post_type ]);
744
+            if (isset($model_names[$post_type])) {
745
+                $model = EE_Registry::instance()->load_model($model_names[$post_type]);
746 746
             }
747 747
         } else {
748
-            $model = EE_Registry::instance()->load_model($this->_cpt_model_names[ $this->_req_action ]);
748
+            $model = EE_Registry::instance()->load_model($this->_cpt_model_names[$this->_req_action]);
749 749
         }
750 750
         if ($model instanceof EEM_Base) {
751 751
             $this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object();
@@ -775,8 +775,8 @@  discard block
 block discarded – undo
775 775
         $current_route = isset($this->_req_data['current_route'])
776 776
             ? $this->_req_data['current_route']
777 777
             : 'shouldneverwork';
778
-        $route_to_check = $post_type && isset($this->_cpt_routes[ $current_route ])
779
-            ? $this->_cpt_routes[ $current_route ]
778
+        $route_to_check = $post_type && isset($this->_cpt_routes[$current_route])
779
+            ? $this->_cpt_routes[$current_route]
780 780
             : '';
781 781
         add_filter('get_delete_post_link', array($this, 'modify_delete_post_link'), 10, 3);
782 782
         add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 3);
@@ -785,10 +785,10 @@  discard block
 block discarded – undo
785 785
         }
786 786
         // now let's filter redirect if we're on a revision page and the revision is for an event CPT.
787 787
         $revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
788
-        if (! empty($revision)) {
788
+        if ( ! empty($revision)) {
789 789
             $action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null;
790 790
             // doing a restore?
791
-            if (! empty($action) && $action === 'restore') {
791
+            if ( ! empty($action) && $action === 'restore') {
792 792
                 // get post for revision
793 793
                 $rev_post = get_post($revision);
794 794
                 $rev_parent = get_post($rev_post->post_parent);
@@ -824,7 +824,7 @@  discard block
 block discarded – undo
824 824
     {
825 825
         $this->_set_model_object($post_id, true, 'trash');
826 826
         // if our cpt object isn't existent then get out immediately.
827
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
827
+        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
828 828
             return;
829 829
         }
830 830
         $this->trash_cpt_item($post_id);
@@ -842,7 +842,7 @@  discard block
 block discarded – undo
842 842
     {
843 843
         $this->_set_model_object($post_id, true, 'restore');
844 844
         // if our cpt object isn't existent then get out immediately.
845
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
845
+        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
846 846
             return;
847 847
         }
848 848
         $this->restore_cpt_item($post_id);
@@ -860,7 +860,7 @@  discard block
 block discarded – undo
860 860
     {
861 861
         $this->_set_model_object($post_id, true, 'delete');
862 862
         // if our cpt object isn't existent then get out immediately.
863
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
863
+        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
864 864
             return;
865 865
         }
866 866
         $this->delete_cpt_item($post_id);
@@ -879,7 +879,7 @@  discard block
 block discarded – undo
879 879
     {
880 880
         $label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label;
881 881
         // verify event object
882
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
882
+        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base) {
883 883
             throw new EE_Error(
884 884
                 sprintf(
885 885
                     __(
@@ -935,13 +935,13 @@  discard block
 block discarded – undo
935 935
         if ($this->_cpt_model_obj instanceof EE_CPT_Base) {
936 936
             // setup custom post status object for localize script but only if we've got a cpt object
937 937
             $statuses = $this->_cpt_model_obj->get_custom_post_statuses();
938
-            if (! empty($statuses)) {
938
+            if ( ! empty($statuses)) {
939 939
                 // get ALL statuses!
940 940
                 $statuses = $this->_cpt_model_obj->get_all_post_statuses();
941 941
                 // setup object
942 942
                 $ee_cpt_statuses = array();
943 943
                 foreach ($statuses as $status => $label) {
944
-                    $ee_cpt_statuses[ $status ] = array(
944
+                    $ee_cpt_statuses[$status] = array(
945 945
                         'label'      => $label,
946 946
                         'save_label' => sprintf(
947 947
                             wp_strip_all_tags(__('Save as %s', 'event_espresso')),
@@ -1006,7 +1006,7 @@  discard block
 block discarded – undo
1006 1006
                 $post->page_template = $this->_req_data['page_template'];
1007 1007
                 $page_templates = wp_get_theme()->get_page_templates($post);
1008 1008
             }
1009
-            if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[ $this->_req_data['page_template'] ])) {
1009
+            if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[$this->_req_data['page_template']])) {
1010 1010
                 EE_Error::add_error(__('Invalid Page Template.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1011 1011
             } else {
1012 1012
                 update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']);
@@ -1031,7 +1031,7 @@  discard block
 block discarded – undo
1031 1031
     {
1032 1032
         // only do this if we're actually processing one of our CPTs
1033 1033
         // if our cpt object isn't existent then get out immediately.
1034
-        if (! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1034
+        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1035 1035
             return;
1036 1036
         }
1037 1037
         delete_post_meta($post_id, '_wp_trash_meta_status');
@@ -1056,7 +1056,7 @@  discard block
 block discarded – undo
1056 1056
         // global action
1057 1057
         do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id);
1058 1058
         // class specific action so you can limit hooking into a specific page.
1059
-        do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id);
1059
+        do_action('AHEE_EE_Admin_Page_CPT_'.get_class($this).'__restore_revision', $post_id, $revision_id);
1060 1060
     }
1061 1061
 
1062 1062
 
@@ -1083,11 +1083,11 @@  discard block
 block discarded – undo
1083 1083
     public function modify_current_screen()
1084 1084
     {
1085 1085
         // ONLY do this if the current page_route IS a cpt route
1086
-        if (! $this->_cpt_route) {
1086
+        if ( ! $this->_cpt_route) {
1087 1087
             return;
1088 1088
         }
1089 1089
         // routing things REALLY early b/c this is a cpt admin page
1090
-        set_current_screen($this->_cpt_routes[ $this->_req_action ]);
1090
+        set_current_screen($this->_cpt_routes[$this->_req_action]);
1091 1091
         $this->_current_screen = get_current_screen();
1092 1092
         $this->_current_screen->base = 'event-espresso';
1093 1093
         $this->_add_help_tabs(); // we make sure we add any help tabs back in!
@@ -1110,8 +1110,8 @@  discard block
 block discarded – undo
1110 1110
      */
1111 1111
     public function add_custom_editor_default_title($title)
1112 1112
     {
1113
-        return isset($this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ])
1114
-            ? $this->_labels['editor_title'][ $this->_cpt_routes[ $this->_req_action ] ]
1113
+        return isset($this->_labels['editor_title'][$this->_cpt_routes[$this->_req_action]])
1114
+            ? $this->_labels['editor_title'][$this->_cpt_routes[$this->_req_action]]
1115 1115
             : $title;
1116 1116
     }
1117 1117
 
@@ -1127,10 +1127,10 @@  discard block
 block discarded – undo
1127 1127
      */
1128 1128
     public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs)
1129 1129
     {
1130
-        if (! empty($id) && get_option('permalink_structure') !== '') {
1130
+        if ( ! empty($id) && get_option('permalink_structure') !== '') {
1131 1131
             $post = get_post($id);
1132 1132
             if (isset($post->post_type) && $this->page_slug === $post->post_type) {
1133
-                $shortlink = home_url('?p=' . $post->ID);
1133
+                $shortlink = home_url('?p='.$post->ID);
1134 1134
             }
1135 1135
         }
1136 1136
         return $shortlink;
@@ -1163,11 +1163,11 @@  discard block
 block discarded – undo
1163 1163
      */
1164 1164
     public function cpt_post_form_hidden_input()
1165 1165
     {
1166
-        echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="' . $this->_admin_base_url . '" />';
1166
+        echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="'.$this->_admin_base_url.'" />';
1167 1167
         // we're also going to add the route value and the current page so we can direct autosave parsing correctly
1168 1168
         echo '<div id="ee-cpt-hidden-inputs">';
1169
-        echo '<input type="hidden" id="current_route" name="current_route" value="' . $this->_current_view . '" />';
1170
-        echo '<input type="hidden" id="current_page" name="current_page" value="' . $this->page_slug . '" />';
1169
+        echo '<input type="hidden" id="current_route" name="current_route" value="'.$this->_current_view.'" />';
1170
+        echo '<input type="hidden" id="current_page" name="current_page" value="'.$this->page_slug.'" />';
1171 1171
         echo '</div>';
1172 1172
     }
1173 1173
 
@@ -1212,15 +1212,15 @@  discard block
 block discarded – undo
1212 1212
     public function modify_edit_post_link($link, $id, $context)
1213 1213
     {
1214 1214
         $post = get_post($id);
1215
-        if (! isset($this->_req_data['action'])
1216
-            || ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1217
-            || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1215
+        if ( ! isset($this->_req_data['action'])
1216
+            || ! isset($this->_cpt_routes[$this->_req_data['action']])
1217
+            || $post->post_type !== $this->_cpt_routes[$this->_req_data['action']]
1218 1218
         ) {
1219 1219
             return $link;
1220 1220
         }
1221 1221
         $query_args = array(
1222
-            'action' => isset($this->_cpt_edit_routes[ $post->post_type ])
1223
-                ? $this->_cpt_edit_routes[ $post->post_type ]
1222
+            'action' => isset($this->_cpt_edit_routes[$post->post_type])
1223
+                ? $this->_cpt_edit_routes[$post->post_type]
1224 1224
                 : 'edit',
1225 1225
             'post'   => $id,
1226 1226
         );
@@ -1243,16 +1243,16 @@  discard block
 block discarded – undo
1243 1243
         $post = get_post($post_id);
1244 1244
 
1245 1245
         if (empty($this->_req_data['action'])
1246
-            || ! isset($this->_cpt_routes[ $this->_req_data['action'] ])
1246
+            || ! isset($this->_cpt_routes[$this->_req_data['action']])
1247 1247
             || ! $post instanceof WP_Post
1248
-            || $post->post_type !== $this->_cpt_routes[ $this->_req_data['action'] ]
1248
+            || $post->post_type !== $this->_cpt_routes[$this->_req_data['action']]
1249 1249
         ) {
1250 1250
             return $delete_link;
1251 1251
         }
1252 1252
         $this->_set_model_object($post->ID, true);
1253 1253
 
1254 1254
         // returns something like `trash_event` or `trash_attendee` or `trash_venue`
1255
-        $action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1255
+        $action = 'trash_'.str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1256 1256
 
1257 1257
         return EE_Admin_Page::add_query_args_and_nonce(
1258 1258
             array(
@@ -1280,7 +1280,7 @@  discard block
 block discarded – undo
1280 1280
         // we DO have a match so let's setup the url
1281 1281
         // we have to get the post to determine our route
1282 1282
         $post = get_post($post_id);
1283
-        $edit_route = $this->_cpt_edit_routes[ $post->post_type ];
1283
+        $edit_route = $this->_cpt_edit_routes[$post->post_type];
1284 1284
         // shared query_args
1285 1285
         $query_args = array('action' => $edit_route, 'post' => $post_id);
1286 1286
         $admin_url = $this->_admin_base_url;
@@ -1352,12 +1352,12 @@  discard block
 block discarded – undo
1352 1352
         /*$current_route = isset($this->_req_data['current_route']) ? $this->_req_data['current_route'] : 'shouldneverwork';
1353 1353
 
1354 1354
         $route_to_check = $post_type && isset( $this->_cpt_routes[$current_route]) ? $this->_cpt_routes[$current_route] : '';/**/
1355
-        $messages[ $post->post_type ] = array(
1355
+        $messages[$post->post_type] = array(
1356 1356
             0  => '', // Unused. Messages start at index 1.
1357 1357
             1  => sprintf(
1358 1358
                 __('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'),
1359 1359
                 $this->_cpt_object->labels->singular_name,
1360
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1360
+                '<a href="'.esc_url(get_permalink($id)).'">',
1361 1361
                 '</a>'
1362 1362
             ),
1363 1363
             2  => __('Custom field updated', 'event_espresso'),
@@ -1372,27 +1372,27 @@  discard block
 block discarded – undo
1372 1372
             6  => sprintf(
1373 1373
                 __('%1$s published. %2$sView %1$s%3$s', 'event_espresso'),
1374 1374
                 $this->_cpt_object->labels->singular_name,
1375
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1375
+                '<a href="'.esc_url(get_permalink($id)).'">',
1376 1376
                 '</a>'
1377 1377
             ),
1378 1378
             7  => sprintf(__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1379 1379
             8  => sprintf(
1380 1380
                 __('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'),
1381 1381
                 $this->_cpt_object->labels->singular_name,
1382
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">',
1382
+                '<a target="_blank" href="'.esc_url(add_query_arg('preview', 'true', get_permalink($id))).'">',
1383 1383
                 '</a>'
1384 1384
             ),
1385 1385
             9  => sprintf(
1386 1386
                 __('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'),
1387 1387
                 $this->_cpt_object->labels->singular_name,
1388
-                '<strong>' . date_i18n('M j, Y @ G:i', strtotime($post->post_date)) . '</strong>',
1389
-                '<a target="_blank" href="' . esc_url(get_permalink($id)),
1388
+                '<strong>'.date_i18n('M j, Y @ G:i', strtotime($post->post_date)).'</strong>',
1389
+                '<a target="_blank" href="'.esc_url(get_permalink($id)),
1390 1390
                 '</a>'
1391 1391
             ),
1392 1392
             10 => sprintf(
1393 1393
                 __('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'),
1394 1394
                 $this->_cpt_object->labels->singular_name,
1395
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1395
+                '<a target="_blank" href="'.esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1396 1396
                 '</a>'
1397 1397
             ),
1398 1398
         );
@@ -1411,10 +1411,10 @@  discard block
 block discarded – undo
1411 1411
     {
1412 1412
         // gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1413 1413
         global $post, $title, $is_IE, $post_type, $post_type_object;
1414
-        $post_type = $this->_cpt_routes[ $this->_req_action ];
1414
+        $post_type = $this->_cpt_routes[$this->_req_action];
1415 1415
         $post_type_object = $this->_cpt_object;
1416 1416
         $title = $post_type_object->labels->add_new_item;
1417
-        $post = $post = get_default_post_to_edit($this->_cpt_routes[ $this->_req_action ], true);
1417
+        $post = $post = get_default_post_to_edit($this->_cpt_routes[$this->_req_action], true);
1418 1418
         add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1419 1419
         // modify the default editor title field with default title.
1420 1420
         add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
@@ -1439,8 +1439,8 @@  discard block
 block discarded – undo
1439 1439
             if ($creating) {
1440 1440
                 wp_enqueue_script('autosave');
1441 1441
             } else {
1442
-                if (isset($this->_cpt_routes[ $this->_req_data['action'] ])
1443
-                    && ! isset($this->_labels['hide_add_button_on_cpt_route'][ $this->_req_data['action'] ])
1442
+                if (isset($this->_cpt_routes[$this->_req_data['action']])
1443
+                    && ! isset($this->_labels['hide_add_button_on_cpt_route'][$this->_req_data['action']])
1444 1444
                 ) {
1445 1445
                     $create_new_action = apply_filters(
1446 1446
                         'FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action',
@@ -1456,7 +1456,7 @@  discard block
 block discarded – undo
1456 1456
                     );
1457 1457
                 }
1458 1458
             }
1459
-            include_once WP_ADMIN_PATH . 'edit-form-advanced.php';
1459
+            include_once WP_ADMIN_PATH.'edit-form-advanced.php';
1460 1460
         }
1461 1461
     }
1462 1462
 
@@ -1487,21 +1487,21 @@  discard block
 block discarded – undo
1487 1487
         if (empty($post)) {
1488 1488
             wp_die(__('You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?', 'event_espresso'));
1489 1489
         }
1490
-        if (! empty($_GET['get-post-lock'])) {
1490
+        if ( ! empty($_GET['get-post-lock'])) {
1491 1491
             wp_set_post_lock($post_id);
1492 1492
             wp_redirect(get_edit_post_link($post_id, 'url'));
1493 1493
             exit();
1494 1494
         }
1495 1495
 
1496 1496
         // template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1497
-        $post_type = $this->_cpt_routes[ $this->_req_action ];
1497
+        $post_type = $this->_cpt_routes[$this->_req_action];
1498 1498
         $post_type_object = $this->_cpt_object;
1499 1499
 
1500
-        if (! wp_check_post_lock($post->ID)) {
1500
+        if ( ! wp_check_post_lock($post->ID)) {
1501 1501
             wp_set_post_lock($post->ID);
1502 1502
         }
1503 1503
         add_action('admin_footer', '_admin_notice_post_locked');
1504
-        if (post_type_supports($this->_cpt_routes[ $this->_req_action ], 'comments')) {
1504
+        if (post_type_supports($this->_cpt_routes[$this->_req_action], 'comments')) {
1505 1505
             wp_enqueue_script('admin-comments');
1506 1506
             enqueue_comment_hotkeys_js();
1507 1507
         }
Please login to merge, or discard this patch.