Issues (2873)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

components/Templates/Templates.php (28 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 35 and the first side effect is on line 20.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Name: Templates
4
 *
5
 * Description: An easy to use templating engine for Pods. Use {@field_name} magic tags to output values, within your
6
 * HTML markup.
7
 *
8
 * Version: 2.3
9
 *
10
 * Category: Advanced
11
 *
12
 * Menu Page: edit.php?post_type=_pods_template
13
 * Menu Add Page: post-new.php?post_type=_pods_template
14
 *
15
 * @package    Pods\Components
16
 * @subpackage Templates
17
 */
18
19
// Pull in the functions
20
require_once plugin_dir_path( __FILE__ ) . '/includes/functions-view_template.php';
21
require_once plugin_dir_path( __FILE__ ) . '/includes/functions-pod_reference.php';
22
23
// Pull in the Frontier Template System
24
require_once plugin_dir_path( __FILE__ ) . 'class-pods_templates.php';
25
26
// Pull in Auto Template
27
require_once dirname( __FILE__ ) . '/includes/auto-template/Pods_Templates_Auto_Template_Settings.php';
28
new Pods_Templates_Auto_Template_Settings();
29
30
Pods_Templates_Frontier::get_instance();
31
32
/**
33
 * Class Pods_Templates
34
 */
35
class Pods_Templates extends PodsComponent {
36
37
	/**
38
	 * Pods object
39
	 *
40
	 * @var object
41
	 *
42
	 * @since 2.0
43
	 */
44
	public static $obj = null;
45
46
	/**
47
	 * Whether to enable deprecated functionality based on old function usage
48
	 *
49
	 * @var bool
50
	 *
51
	 * @since 2.0
52
	 */
53
	public static $deprecated = false;
54
55
	/**
56
	 * Object type
57
	 *
58
	 * @var string
59
	 *
60
	 * @since 2.0
61
	 */
62
	private $object_type = '_pods_template';
63
64
	/**
65
	 * The capability type.
66
	 *
67
	 * @link https://codex.wordpress.org/Function_Reference/register_post_type
68
	 * @var string
69
	 */
70
	private $capability_type = 'pods_template';
71
72
	/**
73
	 * {@inheritdoc}
74
	 */
75
	public function init() {
76
77
		$args = array(
78
			'label'        => 'Pod Templates',
79
			'labels'       => array( 'singular_name' => 'Pod Template' ),
80
			'public'       => false,
81
			'can_export'   => false,
82
			'show_ui'      => true,
83
			'show_in_menu' => false,
84
			'query_var'    => false,
85
			'rewrite'      => false,
86
			'has_archive'  => false,
87
			'hierarchical' => false,
88
			'supports'     => array( 'title', 'author', 'revisions' ),
89
			'menu_icon'    => 'dashicons-pods',
90
		);
91
92
		if ( ! pods_is_admin() ) {
93
			$args['capability_type'] = $this->capability_type;
94
		}
95
96
		$args = PodsInit::object_label_fix( $args, 'post_type' );
97
98
		register_post_type( $this->object_type, apply_filters( 'pods_internal_register_post_type_object_template', $args ) );
99
100
		if ( is_admin() ) {
101
			add_filter( 'post_updated_messages', array( $this, 'setup_updated_messages' ), 10, 1 );
102
103
			add_action( 'dbx_post_advanced', array( $this, 'edit_page_form' ) );
104
105
			add_action( 'pods_meta_groups', array( $this, 'add_meta_boxes' ) );
106
107
			add_filter( 'get_post_metadata', array( $this, 'get_meta' ), 10, 4 );
108
			add_filter( 'update_post_metadata', array( $this, 'save_meta' ), 10, 4 );
109
110
			add_action( 'pods_meta_save_pre_post__pods_template', array( $this, 'fix_filters' ), 10, 5 );
111
			add_action( 'post_updated', array( $this, 'clear_cache' ), 10, 3 );
112
			add_action( 'delete_post', array( $this, 'clear_cache' ), 10, 1 );
113
			add_filter( 'post_row_actions', array( $this, 'remove_row_actions' ), 10, 2 );
114
			add_filter( 'bulk_actions-edit-' . $this->object_type, array( $this, 'remove_bulk_actions' ) );
115
116
			add_filter( 'builder_layout_filter_non_layout_post_types', array( $this, 'disable_builder_layout' ) );
117
118
		}
119
120
		add_filter( 'members_get_capabilities', array( $this, 'get_capabilities' ) );
121
	}
122
123
	/**
124
	 * @param $caps
125
	 *
126
	 * @return array
0 ignored issues
show
Consider making the return type a bit more specific; maybe use string[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
127
	 */
128
	public function get_capabilities( $caps ) {
129
130
		$caps = array_merge(
131
			$caps, array(
132
				'edit_' . $this->capability_type,
133
				'read_' . $this->capability_type,
134
				'delete_' . $this->capability_type,
135
				'edit_' . $this->capability_type . 's',
136
				'edit_others_' . $this->capability_type . 's',
137
				'publish_' . $this->capability_type . 's',
138
				'read_private_' . $this->capability_type . 's',
139
				'edit_' . $this->capability_type . 's',
140
			)
141
		);
142
143
		return $caps;
144
	}
145
146
	/**
147
	 * @param $post_types
148
	 *
149
	 * @return array
0 ignored issues
show
Consider making the return type a bit more specific; maybe use string[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
150
	 */
151
	public function disable_builder_layout( $post_types ) {
152
153
		$post_types[] = $this->object_type;
154
155
		return $post_types;
156
	}
157
158
	/**
159
	 * Update Post Type messages
160
	 *
161
	 * @param array $messages
162
	 *
163
	 * @return array
0 ignored issues
show
Consider making the return type a bit more specific; maybe use array<*,array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
164
	 * @since 2.0.2
165
	 */
166
	public function setup_updated_messages( $messages ) {
167
168
		global $post, $post_ID;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
169
170
		$post_type = get_post_type_object( $this->object_type );
0 ignored issues
show
Overridding WordPress globals is prohibited
Loading history...
171
172
		$labels = $post_type->labels;
173
174
		$messages[ $post_type->name ] = array(
175
			1  => sprintf( __( '%1$s updated. <a href="%2$s">%3$s</a>', 'pods' ), $labels->singular_name, esc_url( get_permalink( $post_ID ) ), $labels->view_item ),
176
			2  => __( 'Custom field updated.', 'pods' ),
177
			3  => __( 'Custom field deleted.', 'pods' ),
178
			4  => sprintf( __( '%s updated.', 'pods' ), $labels->singular_name ),
179
			/* translators: %s: date and time of the revision */
180
			5  => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s', 'pods' ), $labels->singular_name, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
181
			6  => sprintf( __( '%1$s published. <a href="%2$s">%3$s</a>', 'pods' ), $labels->singular_name, esc_url( get_permalink( $post_ID ) ), $labels->view_item ),
182
			7  => sprintf( __( '%s saved.', 'pods' ), $labels->singular_name ),
183
			8  => sprintf( __( '%1$s submitted. <a target="_blank" href="%2$s">Preview %3$s</a>', 'pods' ), $labels->singular_name, esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ), $labels->singular_name ),
184
			9  => sprintf(
185
				__( '%s scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview %s</a>', 'pods' ), $labels->singular_name,
186
				// translators: Publish box date format, see http://php.net/date
187
				date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink( $post_ID ) ), $labels->singular_name
188
			),
189
			10 => sprintf( __( '%1$s draft updated. <a target="_blank" href="%2$s">Preview %3$s</a>', 'pods' ), $labels->singular_name, esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ), $labels->singular_name ),
190
		);
191
192
		if ( false === (boolean) $post_type->public ) {
193
			$messages[ $post_type->name ][1] = sprintf( __( '%s updated.', 'pods' ), $labels->singular_name );
194
			$messages[ $post_type->name ][6] = sprintf( __( '%s published.', 'pods' ), $labels->singular_name );
195
			$messages[ $post_type->name ][8] = sprintf( __( '%s submitted.', 'pods' ), $labels->singular_name );
196
			$messages[ $post_type->name ][9] = sprintf(
197
				__( '%s scheduled for: <strong>%1$s</strong>.', 'pods' ), $labels->singular_name,
198
				// translators: Publish box date format, see http://php.net/date
199
				date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) )
200
			);
201
			$messages[ $post_type->name ][10] = sprintf( __( '%s draft updated.', 'pods' ), $labels->singular_name );
202
		}
203
204
		return $messages;
205
	}
206
207
	/**
208
	 * Enqueue styles
209
	 *
210
	 * @since 2.0
211
	 */
212
	public function admin_assets() {
213
214
		wp_enqueue_style( 'pods-styles' );
215
	}
216
217
	/**
218
	 * Fix filters, specifically removing balanceTags
219
	 *
220
	 * @since 2.0.1
221
	 *
222
	 * @param      $data
223
	 * @param null $pod
224
	 * @param null $id
225
	 * @param null $groups
226
	 * @param null $post
227
	 */
228
	public function fix_filters( $data, $pod = null, $id = null, $groups = null, $post = null ) {
0 ignored issues
show
Overridding WordPress globals is prohibited
Loading history...
229
230
		remove_filter( 'content_save_pre', 'balanceTags', 50 );
231
	}
232
233
	/**
234
	 * Remove unused row actions
235
	 *
236
	 * @since 2.0.5
237
	 *
238
	 * @param $actions
239
	 * @param $post
240
	 *
241
	 * @return
242
	 */
243
	public function remove_row_actions( $actions, $post ) {
0 ignored issues
show
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
244
245
		global $current_screen;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
246
247
		if ( ! is_object( $current_screen ) || $this->object_type != $current_screen->post_type ) {
248
			return $actions;
249
		}
250
251
		if ( isset( $actions['view'] ) ) {
252
			unset( $actions['view'] );
253
		}
254
255
		if ( isset( $actions['inline hide-if-no-js'] ) ) {
256
			unset( $actions['inline hide-if-no-js'] );
257
		}
258
259
		// W3 Total Cache
260
		if ( isset( $actions['pgcache_purge'] ) ) {
261
			unset( $actions['pgcache_purge'] );
262
		}
263
264
		return $actions;
265
	}
266
267
	/**
268
	 * Remove unused bulk actions
269
	 *
270
	 * @since 2.0.5
271
	 *
272
	 * @param $actions
273
	 *
274
	 * @return
275
	 */
276
	public function remove_bulk_actions( $actions ) {
0 ignored issues
show
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
277
278
		if ( isset( $actions['edit'] ) ) {
279
			unset( $actions['edit'] );
280
		}
281
282
		return $actions;
283
	}
284
285
	/**
286
	 * Clear cache on save
287
	 *
288
	 * @since 2.0
289
	 *
290
	 * @param      $data
291
	 * @param null $pod
292
	 * @param null $id
293
	 * @param null $groups
294
	 * @param null $post
295
	 */
296
	public function clear_cache( $data, $pod = null, $id = null, $groups = null, $post = null ) {
0 ignored issues
show
Overridding WordPress globals is prohibited
Loading history...
297
298
		$old_post = $id;
299
300
		if ( ! is_object( $id ) ) {
301
			$old_post = null;
302
		}
303
304
		if ( is_object( $post ) && $this->object_type != $post->post_type ) {
305
			return;
306
		}
307
308
		if ( ! is_array( $data ) && 0 < $data ) {
309
			$post = $data;
0 ignored issues
show
Overridding WordPress globals is prohibited
Loading history...
310
			$post = get_post( $post );
0 ignored issues
show
Overridding WordPress globals is prohibited
Loading history...
311
		}
312
313
		if ( $this->object_type == $post->object_type ) {
314
			pods_transient_clear( 'pods_object_templates' );
315
		}
316
	}
317
318
	/**
319
	 * Change post title placeholder text
320
	 *
321
	 * @since 2.0
322
	 *
323
	 * @param $text
324
	 * @param $post
325
	 *
326
	 * @return string|void
327
	 */
328
	public function set_title_text( $text, $post ) {
329
330
		return __( 'Enter template name here', 'pods' );
331
	}
332
333
	/**
334
	 * Edit page form
335
	 *
336
	 * @since 2.0
337
	 */
338
	public function edit_page_form() {
339
340
		global $post_type;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
341
342
		if ( $this->object_type != $post_type ) {
343
			return;
344
		}
345
346
		add_filter( 'enter_title_here', array( $this, 'set_title_text' ), 10, 2 );
347
	}
348
349
	/**
350
	 * Add meta boxes to the page
351
	 *
352
	 * @since 2.0
353
	 */
354
	public function add_meta_boxes() {
355
356
		$pod = array(
357
			'name' => $this->object_type,
358
			'type' => 'post_type',
359
		);
360
361
		if ( isset( PodsMeta::$post_types[ $pod['name'] ] ) ) {
362
			return;
363
		}
364
365
		$fields = array(
366
			array(
367
				'name'       => 'admin_only',
368
				'label'      => __( 'Show to Admins Only?', 'pods' ),
369
				'default'    => 0,
370
				'type'       => 'boolean',
371
				'dependency' => true,
372
			),
373
			array(
374
				'name'       => 'restrict_capability',
375
				'label'      => __( 'Restrict access by Capability?', 'pods' ),
376
				'help'       => array(
377
					__( '<h6>Capabilities</h6> Capabilities denote access to specific functionality in WordPress, and are assigned to specific User Roles. Please see the Roles and Capabilities component in Pods for an easy tool to add your own capabilities and roles.', 'pods' ),
378
					'http://codex.wordpress.org/Roles_and_Capabilities',
379
				),
380
				'default'    => 0,
381
				'type'       => 'boolean',
382
				'dependency' => true,
383
			),
384
			array(
385
				'name'              => 'capability_allowed',
386
				'label'             => __( 'Capability Allowed', 'pods' ),
387
				'type'              => 'pick',
388
				'pick_object'       => 'capability',
389
				'pick_format_type'  => 'multi',
390
				'pick_format_multi' => 'autocomplete',
391
				'pick_ajax'         => false,
392
				'default'           => '',
393
				'depends-on'        => array(
394
					'restrict_capability' => true,
395
				),
396
			),
397
		);
398
399
		pods_group_add( $pod, __( 'Restrict Access', 'pods' ), $fields, 'normal', 'high' );
400
	}
401
402
	/**
403
	 * Get the fields
404
	 *
405
	 * @param null   $_null
406
	 * @param int    $post_ID
0 ignored issues
show
Should the type for parameter $post_ID not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
407
	 * @param string $meta_key
0 ignored issues
show
Should the type for parameter $meta_key not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
408
	 * @param bool   $single
409
	 *
410
	 * @return array|bool|int|mixed|null|string|void
411
	 */
412
	public function get_meta( $_null, $post_ID = null, $meta_key = null, $single = false ) {
0 ignored issues
show
Overridding WordPress globals is prohibited
Loading history...
413
414
		if ( 'code' === $meta_key ) {
415
			$post = get_post( $post_ID );
0 ignored issues
show
Overridding WordPress globals is prohibited
Loading history...
416
417
			if ( is_object( $post ) && $this->object_type == $post->post_type ) {
418
				return $post->post_content;
419
			}
420
		}
421
422
		return $_null;
423
	}
424
425
	/**
426
	 * Save the fields
427
	 *
428
	 * @param        $_null
429
	 * @param int    $post_ID
0 ignored issues
show
Should the type for parameter $post_ID not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
430
	 * @param string $meta_key
0 ignored issues
show
Should the type for parameter $meta_key not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
431
	 * @param string $meta_value
0 ignored issues
show
Should the type for parameter $meta_value not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
432
	 *
433
	 * @return bool|int|null
434
	 */
435
	public function save_meta( $_null, $post_ID = null, $meta_key = null, $meta_value = null ) {
0 ignored issues
show
Overridding WordPress globals is prohibited
Loading history...
436
437
		if ( 'code' === $meta_key ) {
438
			$post = get_post( $post_ID );
0 ignored issues
show
Overridding WordPress globals is prohibited
Loading history...
439
440
			if ( is_object( $post ) && $this->object_type == $post->post_type ) {
441
				$postdata = array(
442
					'ID'           => $post_ID,
443
					'post_content' => $meta_value,
444
				);
445
446
				remove_filter( current_filter(), array( $this, __FUNCTION__ ) );
447
448
				$revisions = false;
449
450
				if ( has_action( 'pre_post_update', 'wp_save_post_revision' ) ) {
451
					remove_action( 'pre_post_update', 'wp_save_post_revision' );
452
453
					$revisions = true;
454
				}
455
456
				wp_update_post( (object) $postdata );
457
				// objects will be automatically sanitized
458
				if ( $revisions ) {
459
					add_action( 'pre_post_update', 'wp_save_post_revision' );
460
				}
461
462
				return true;
463
			}//end if
464
		}//end if
465
466
		return $_null;
467
	}
468
469
	/**
470
	 * Display the page template
471
	 *
472
	 * @param string $template_name The template name
473
	 * @param string $code          Custom template code to use instead
0 ignored issues
show
Should the type for parameter $code not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
474
	 * @param object $obj           The Pods object
0 ignored issues
show
Should the type for parameter $obj not be object|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
475
	 * @param bool   $deprecated    Whether to use deprecated functionality based on old function usage
476
	 *
477
	 * @return mixed|string|void
478
	 * @since 2.0
479
	 */
480
	public static function template( $template_name, $code = null, $obj = null, $deprecated = false ) {
481
482
		if ( ! empty( $obj ) ) {
483
			self::$obj =& $obj;
484
		} else {
485
			$obj =& self::$obj;
486
		}
487
488
		self::$deprecated = $deprecated;
489
490
		if ( empty( $obj ) || ! is_object( $obj ) ) {
491
			return '';
492
		}
493
494
		$template = array(
495
			'id'      => 0,
496
			'slug'    => $template_name,
497
			'code'    => $code,
498
			'options' => array(),
499
		);
500
501
		if ( empty( $code ) && ! empty( $template_name ) ) {
502
			$template_obj = $obj->api->load_template( array( 'name' => $template_name ) );
503
504
			if ( ! empty( $template_obj ) ) {
505
				$template = $template_obj;
506
507
				if ( ! empty( $template['code'] ) ) {
508
					$code = $template['code'];
509
				}
510
511
				$permission = pods_permission( $template['options'] );
512
513
				$permission = (boolean) apply_filters( 'pods_templates_permission', $permission, $code, $template, $obj );
514
515
				if ( ! $permission ) {
516
					return apply_filters( 'pods_templates_permission_denied', __( 'You do not have access to view this content.', 'pods' ), $code, $template, $obj );
517
				}
518
			}
519
		}
520
521
		$code = apply_filters( 'pods_templates_pre_template', $code, $template, $obj );
522
		$code = apply_filters( 'pods_templates_pre_template_' . $template['slug'], $code, $template, $obj );
523
524
		ob_start();
525
526
		if ( ! empty( $code ) ) {
527
			// Only detail templates need $this->id
528
			if ( empty( $obj->id ) ) {
529
				while ( $obj->fetch() ) {
530
					echo self::do_template( $code, $obj );
531
				}
532
			} else {
533
				echo self::do_template( $code, $obj );
534
			}
535
		} elseif ( $template_name == trim( preg_replace( '/[^a-zA-Z0-9_\-\/]/', '', $template_name ), ' /-' ) ) {
536
			$default_templates = array(
537
				'pods/' . $template_name,
538
				'pods-' . $template_name,
539
				$template_name,
540
			);
541
542
			$default_templates = apply_filters( 'pods_template_default_templates', $default_templates );
543
544
			if ( empty( $obj->id ) ) {
545
				while ( $obj->fetch() ) {
546
					pods_template_part( $default_templates, compact( array_keys( get_defined_vars() ) ) );
547
				}
548
			} else {
549
				pods_template_part( $default_templates, compact( array_keys( get_defined_vars() ) ) );
550
			}
551
		}//end if
552
553
		$out = ob_get_clean();
554
555
		$out = apply_filters( 'pods_templates_post_template', $out, $code, $template, $obj );
556
		$out = apply_filters( 'pods_templates_post_template_' . $template['slug'], $out, $code, $template, $obj );
557
558
		return $out;
559
	}
560
561
	/**
562
	 * Parse a template string
563
	 *
564
	 * @param string $code The template string to parse
565
	 * @param object $obj  The Pods object
0 ignored issues
show
Should the type for parameter $obj not be object|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
566
	 *
567
	 * @since 1.8.5
568
	 * @return mixed|string|void
569
	 */
570
	public static function do_template( $code, $obj = null ) {
571
572
		if ( ! empty( $obj ) ) {
573
			self::$obj =& $obj;
574
		} else {
575
			$obj =& self::$obj;
576
		}
577
578
		if ( empty( $obj ) || ! is_object( $obj ) ) {
579
			return '';
580
		}
581
582
		$code = trim( $code );
583
584
		if ( false !== strpos( $code, '<?' ) && ( ! defined( 'PODS_DISABLE_EVAL' ) || ! PODS_DISABLE_EVAL ) ) {
585
			pods_deprecated( 'Pod Template PHP code has been deprecated, please use WP Templates instead of embedding PHP.', '2.3' );
586
587
			$code = str_replace( '$this->', '$obj->', $code );
588
589
			ob_start();
590
591
			eval( "?>$code" );
0 ignored issues
show
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
eval is prohibited, please use Anonymous functions instead.
Loading history...
592
593
			$out = ob_get_clean();
594
		} else {
595
			$out = $code;
596
		}
597
598
		$out = $obj->do_magic_tags( $out );
599
600
		return apply_filters( 'pods_templates_do_template', $out, $code, $obj );
601
	}
602
603
}
604