Server : LiteSpeed
System : Linux server104.web-hosting.com 4.18.0-513.24.1.lve.1.el8.x86_64 #1 SMP Thu May 9 15:10:09 UTC 2024 x86_64
User : saleoqej ( 6848)
PHP Version : 8.0.30
Disable Function : NONE
Directory :  /home/saleoqej/chijamzacademy.com/wp-content/plugins/sfwd-lms/includes/
Upload File :
Current Directory [ Writeable ] Root Directory [ Writeable ]


Current File : /home/saleoqej/chijamzacademy.com/wp-content/plugins/sfwd-lms/includes/class-ld-permalinks.php
<?php
/**
 * LearnDash Permalink functions
 *
 * @since 2.5.0
 *
 * @package LearnDash
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

if ( ! class_exists( 'LearnDash_Permalinks' ) ) {
	/**
	 * Class for LearnDash Permalinks
	 */
	class LearnDash_Permalinks {

		/**
		 * Public constructor for class
		 */
		public function __construct() {
			add_action( 'generate_rewrite_rules', array( $this, 'generate_rewrite_rules' ) );
			add_filter( 'post_type_link', array( $this, 'post_type_link' ), 10, 4 );
			add_filter( 'get_edit_post_link', array( $this, 'get_edit_post_link' ), 10, 3 );
			add_filter( 'get_sample_permalink', array( $this, 'get_sample_permalink' ), 99, 5 );

			add_filter( 'attachment_link', array( $this, 'attachment_link' ), 10, 2 );
			add_action( 'comment_form_top', array( $this, 'comment_form_top' ) );
			add_action( 'comment_post', array( $this, 'comment_post' ), 30, 3 );
		}

		/**
		 * Setup custom rewrite URLs.
		 *
		 * Important note: This is very much dependant on the order of the registered post types. This is import when WP goes to parse the request. See
		 * the logic in wp-includes/class-wp.php starting in the loop at line 289 where it loops the registered CPTs. Within this loop at line 311 it
		 * set the queried post_type with the last matched post_type per the parse/marched request. So if the Quiz CPT is registered before Topic then
		 * when we try to match the /courses/course-slug/lessons/lesson-slug/topics/topic-slug/quizzes/quiz-slug/ the queried 'post_type' will be set to
		 * topic not quiz. As a result in LD v2.5 in includes/class-ld-lms.php where we build the $post_args array we ensure the order of the to-be
		 * CPTs.
		 *
		 * @param array $wp_rewrite Global WP rewrite array.
		 */
		public function generate_rewrite_rules( $wp_rewrite ) {
			if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Section_Permalinks', 'nested_urls' ) == 'yes' ) {
				$courses_cpt = get_post_type_object( learndash_get_post_type_slug( 'course' ) );
				$lessons_cpt = get_post_type_object( learndash_get_post_type_slug( 'lesson' ) );
				$topics_cpt  = get_post_type_object( learndash_get_post_type_slug( 'topic' ) );
				$quizzes_cpt = get_post_type_object( learndash_get_post_type_slug( 'quiz' ) );

				$ld_rewrite_values = array(
					learndash_get_post_type_slug( 'course' ) => array(
						'name' => array(
							'placeholder' => '{{courses_cpt_name}}',
							'value'       => $courses_cpt->name,
						),
						'slug' => array(
							'placeholder' => '{{courses_cpt_slug}}',
							'value'       => $courses_cpt->rewrite['slug'],
						),
					),
					learndash_get_post_type_slug( 'lesson' ) => array(
						'name' => array(
							'placeholder' => '{{lessons_cpt_name}}',
							'value'       => $lessons_cpt->name,
						),
						'slug' => array(
							'placeholder' => '{{lessons_cpt_slug}}',
							'value'       => $lessons_cpt->rewrite['slug'],
						),
					),
					learndash_get_post_type_slug( 'topic' ) => array(
						'name' => array(
							'placeholder' => '{{topics_cpt_name}}',
							'value'       => $topics_cpt->name,
						),
						'slug' => array(
							'placeholder' => '{{topics_cpt_slug}}',
							'value'       => $topics_cpt->rewrite['slug'],
						),
					),
					learndash_get_post_type_slug( 'quiz' ) => array(
						'name' => array(
							'placeholder' => '{{quizzes_cpt_name}}',
							'value'       => $quizzes_cpt->name,
						),
						'slug' => array(
							'placeholder' => '{{quizzes_cpt_slug}}',
							'value'       => $quizzes_cpt->rewrite['slug'],
						),
					),
				);

				$ld_rewrite_patterns = array(
					// Course > Quiz.
					'{{courses_cpt_slug}}/([^/]+)/{{quizzes_cpt_slug}}/([^/]+)/comment-page-([0-9]{1,})/?$' => 'index.php?{{courses_cpt_name}}=$matches[1]&{{quizzes_cpt_name}}=$matches[2]&cpage=$matches[3]',
					'{{courses_cpt_slug}}/([^/]+)/{{quizzes_cpt_slug}}/([^/]+)(?:/([0-9]+))?/?$' => 'index.php?{{courses_cpt_name}}=$matches[1]&{{quizzes_cpt_name}}=$matches[2]&page=$matches[3]',

					// Course > Lesson.
					'{{courses_cpt_slug}}/([^/]+)/{{lessons_cpt_slug}}/([^/]+)/comment-page-([0-9]{1,})/?$' => 'index.php?{{courses_cpt_name}}=$matches[1]&{{lessons_cpt_name}}=$matches[2]&cpage=$matches[3]',
					'{{courses_cpt_slug}}/([^/]+)/{{lessons_cpt_slug}}/([^/]+)(?:/([0-9]+))?/?$' => 'index.php?{{courses_cpt_name}}=$matches[1]&{{lessons_cpt_name}}=$matches[2]&page=$matches[3]',

					// Course > Lesson > Quiz.
					'{{courses_cpt_slug}}/([^/]+)/{{lessons_cpt_slug}}/([^/]+)/{{quizzes_cpt_slug}}/([^/]+)/comment-page-([0-9]{1,})/?$' => 'index.php?{{courses_cpt_name}}=$matches[1]&{{lessons_cpt_name}}=$matches[2]&{{quizzes_cpt_name}}=$matches[3]&cpage=$matches[4]',
					'{{courses_cpt_slug}}/([^/]+)/{{lessons_cpt_slug}}/([^/]+)/{{quizzes_cpt_slug}}/([^/]+)(?:/([0-9]+))?/?$' => 'index.php?{{courses_cpt_name}}=$matches[1]&{{lessons_cpt_name}}=$matches[2]&{{quizzes_cpt_name}}=$matches[3]&page=$matches[4]',

					// Course > Lesson > Topic.
					'{{courses_cpt_slug}}/([^/]+)/{{lessons_cpt_slug}}/([^/]+)/{{topics_cpt_slug}}/([^/]+)/comment-page-([0-9]{1,})/?$' => 'index.php?{{courses_cpt_name}}=$matches[1]&{{lessons_cpt_name}}=$matches[2]&{{topics_cpt_name}}=$matches[3]&cpage=$matches[4]',
					'{{courses_cpt_slug}}/([^/]+)/{{lessons_cpt_slug}}/([^/]+)/{{topics_cpt_slug}}/([^/]+)(?:/([0-9]+))?/?$' => 'index.php?{{courses_cpt_name}}=$matches[1]&{{lessons_cpt_name}}=$matches[2]&{{topics_cpt_name}}=$matches[3]&page=$matches[4]',

					// Course > Lesson > Topic > Quiz.
					'{{courses_cpt_slug}}/([^/]+)/{{lessons_cpt_slug}}/([^/]+)/{{topics_cpt_slug}}/([^/]+)/{{quizzes_cpt_slug}}/([^/]+)/comment-page-([0-9]{1,})/?$' => 'index.php?{{courses_cpt_name}}=$matches[1]&{{lessons_cpt_name}}=$matches[2]&{{topics_cpt_name}}=$matches[3]&{{quizzes_cpt_name}}=$matches[4]&cpage=$matches[5]',
					'{{courses_cpt_slug}}/([^/]+)/{{lessons_cpt_slug}}/([^/]+)/{{topics_cpt_slug}}/([^/]+)/{{quizzes_cpt_slug}}/([^/]+)(?:/([0-9]+))?/?$' => 'index.php?{{courses_cpt_name}}=$matches[1]&{{lessons_cpt_name}}=$matches[2]&{{topics_cpt_name}}=$matches[3]&{{quizzes_cpt_name}}=$matches[4]&page=$matches[5]',
				);

				$ld_rewrite_rules = array();
				if ( ( ! empty( $ld_rewrite_patterns ) ) && ( ! empty( $ld_rewrite_values ) ) ) {
					foreach ( $ld_rewrite_patterns as $rewrite_pattern_key => $rewrite_pattern_rule ) {
						foreach ( $ld_rewrite_values as $post_type_name => $ld_rewrite_values_sets ) {
							if ( ! empty( $ld_rewrite_values_sets ) ) {
								foreach ( $ld_rewrite_values_sets as $ld_rewrite_values_set_key => $ld_rewrite_values_set ) {
									if ( ! empty( $ld_rewrite_values_set ) ) {
										if ( ( ! isset( $ld_rewrite_values_set['placeholder'] ) ) || ( empty( $ld_rewrite_values_set['placeholder'] ) ) ) {
											continue;
										}
										if ( ( ! isset( $ld_rewrite_values_set['value'] ) ) || ( empty( $ld_rewrite_values_set['value'] ) ) ) {
											continue;
										}

										$rewrite_pattern_key  = str_replace( $ld_rewrite_values_set['placeholder'], $ld_rewrite_values_set['value'], $rewrite_pattern_key );
										$rewrite_pattern_rule = str_replace( $ld_rewrite_values_set['placeholder'], $ld_rewrite_values_set['value'], $rewrite_pattern_rule );
									}
								}
							}
						}
						$ld_rewrite_rules[ $rewrite_pattern_key ] = $rewrite_pattern_rule;
					}
				}

				/**
				 * Filters list of permalinks structure rules.
				 *
				 * @param array $permalink_structure An array of permalink structure rules. @since 2.5.0
				 * @param array $ld_rewrite_patterns An array of rewrite patterns. @since 3.1.4
				 * @param array $ld_rewrite_values   An array of rewrite placeholder/value pairs. @since 3.1.4
				 */
				$ld_rewrite_rules = apply_filters( 'learndash_permalinks_nested_urls', $ld_rewrite_rules, $ld_rewrite_patterns, $ld_rewrite_values );

				if ( ! empty( $ld_rewrite_rules ) ) {
					$wp_rewrite->rules = array_merge( $ld_rewrite_rules, $wp_rewrite->rules );
				}
			}
		}

		/**
		 * This second filter will correct calls to the WordPress get_permalink() function to use the new structure
		 *
		 * @param string $post_link  The post's permalink.
		 * @param Object $post       The WP_Post post in question.
		 * @param bool   $leave_name Whether to keep the post name.
		 * @param bool   $sample     Is it a sample permalink.
		 */
		public function post_type_link( $post_link = '', $post = null, $leave_name = false, $sample = false ) {
			global $pagenow, $wp_rewrite;

			$url_part_old = '';
			$url_part_new = '';

			if ( ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Section_Permalinks', 'nested_urls' ) == 'yes' ) && ( in_array( $post->post_type, learndash_get_post_types( 'course_steps' ), true ) ) ) {

				// If we are viewing one of the list tables we only effect the link if the course_id URL param is set.
				if ( ( is_admin() ) && ( 'edit.php' == $pagenow ) ) {
					if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) {
						$course_id = 0;

						// phpcs:ignore WordPress.Security.NonceVerification.Recommended
						if ( ( isset( $_GET['course_id'] ) ) && ( ! empty( $_GET['course_id'] ) ) ) {
							// phpcs:ignore WordPress.Security.NonceVerification.Recommended
							$course_id = absint( $_GET['course_id'] );
						}
						$course_id = apply_filters( 'learndash_post_link_course_id', $course_id, $post_link, $post );
						if ( empty( $course_id ) ) {
							return $post_link;
						}
					}
				}

				$courses_cpt = get_post_type_object( learndash_get_post_type_slug( 'course' ) );
				$lessons_cpt = get_post_type_object( learndash_get_post_type_slug( 'lesson' ) );
				$topics_cpt  = get_post_type_object( learndash_get_post_type_slug( 'topic' ) );
				$quizzes_cpt = get_post_type_object( learndash_get_post_type_slug( 'quiz' ) );

				/**
				 * Filters the rewrite slug for a post type.
				 *
				 * @param string $rewrite_slug   Rewrite slug.
				 * @param string $post_type_slug Post type slug.
				 */
				$courses_cpt->rewrite['slug_alt'] = apply_filters( 'learndash_post_type_rewrite_slug', $courses_cpt->rewrite['slug'], learndash_get_post_type_slug( 'course' ) );
				/** This filter is documented in includes/class-ld-permalinks.php */
				$lessons_cpt->rewrite['slug_alt'] = apply_filters( 'learndash_post_type_rewrite_slug', $lessons_cpt->rewrite['slug'], learndash_get_post_type_slug( 'lesson' ) );
				/** This filter is documented in includes/class-ld-permalinks.php */
				$topics_cpt->rewrite['slug_alt'] = apply_filters( 'learndash_post_type_rewrite_slug', $topics_cpt->rewrite['slug'], learndash_get_post_type_slug( 'topic' ) );
				/** This filter is documented in includes/class-ld-permalinks.php */
				$quizzes_cpt->rewrite['slug_alt'] = apply_filters( 'learndash_post_type_rewrite_slug', $quizzes_cpt->rewrite['slug'], learndash_get_post_type_slug( 'quiz' ) );

				$draft_or_pending = in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft', 'future' ), true );

				if ( $lessons_cpt->name == $post->post_type ) {

					$lesson = $post;

					/**
					 * Filters course link post ID.
					 *
					 * @param int     $course_id Course ID.
					 * @param string  $post_link Post Link.
					 * @param WP_Post $post      Post Object.
					 */
					$course_id = apply_filters(
						'learndash_post_link_course_id',
						learndash_get_course_id( $lesson->ID ),
						$post_link,
						$post
					);

					if ( ! empty( $course_id ) ) {
						$course = get_post( $course_id );
						if ( $course instanceof WP_Post ) {
							$url_part_old = '';
							$url_part_new = '';

							$course_post_name = $course->post_name;
							if ( false === $sample ) {
								$lesson_post_name = $lesson->post_name;
							} else {
								$lesson_post_name = '%' . $lessons_cpt->name . '%';
							}

							if ( ( $wp_rewrite->using_permalinks() ) && ( ! $draft_or_pending ) ) {
								// Old URL part.
								if ( strstr( $post_link, $lessons_cpt->rewrite['slug'] . '/' . $lesson_post_name ) ) {
									$url_part_old = '/' . $lessons_cpt->rewrite['slug'] . '/' . $lesson_post_name;
								} elseif ( strstr( $post_link, $lessons_cpt->rewrite['slug_alt'] . '/' . $lesson_post_name ) ) {
									$url_part_old = '/' . $lessons_cpt->rewrite['slug_alt'] . '/' . $lesson_post_name;
								}

								// New URL part.
								if ( ! strstr( $post_link, $courses_cpt->rewrite['slug_alt'] . '/' . $course_post_name ) ) {
									$url_part_new .= '/' . $courses_cpt->rewrite['slug_alt'] . '/' . $course_post_name;
								}
								$url_part_new .= '/' . $lessons_cpt->rewrite['slug_alt'] . '/' . $lesson_post_name;
							} else {
								// Old URL part.
								$url_part_old = add_query_arg( $lessons_cpt->name, $lesson->post_name, $url_part_old );

								// New URL part.
								$url_part_new = add_query_arg( $courses_cpt->name, $course->post_name, $url_part_new );
								$url_part_new = add_query_arg( $lessons_cpt->name, $lesson->post_name, $url_part_new );
							}
						}
					}
				} elseif ( $topics_cpt->name == $post->post_type ) {

					$topic = $post;

					/** This filter is documented in includes/class-ld-permalinks.php */
					$course_id = apply_filters( 'learndash_post_link_course_id', learndash_get_course_id( $topic->ID ), $post_link, $post );
					if ( ! empty( $course_id ) ) {
						if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) {
							$lesson_id = learndash_course_get_single_parent_step( $course_id, $topic->ID );
						} else {
							$lesson_id = learndash_get_lesson_id( $topic->ID );
						}

						if ( ! empty( $lesson_id ) ) {
							$course = get_post( $course_id );
							$lesson = get_post( $lesson_id );

							if ( ( $course instanceof WP_Post ) && ( $lesson instanceof WP_Post ) ) {

								$course_post_name = $course->post_name;
								$lesson_post_name = $lesson->post_name;
								if ( false === $sample ) {
									$topic_post_name = $topic->post_name;
								} else {
									$topic_post_name = '%' . $topics_cpt->name . '%';
								}

								if ( ( $wp_rewrite->using_permalinks() ) && ( ! $draft_or_pending ) ) {
									if ( strstr( $post_link, $topics_cpt->rewrite['slug'] . '/' . $topic_post_name ) ) {
										$url_part_old = '/' . $topics_cpt->rewrite['slug'] . '/' . $topic_post_name;
									} elseif ( strstr( $post_link, $topics_cpt->rewrite['slug_alt'] . '/' . $topic_post_name ) ) {
										$url_part_old = '/' . $topics_cpt->rewrite['slug_alt'] . '/' . $topic_post_name;
									}

									if ( ! strstr( $post_link, $courses_cpt->rewrite['slug_alt'] . '/' . $course_post_name ) ) {
										$url_part_new .= '/' . $courses_cpt->rewrite['slug_alt'] . '/' . $course_post_name;
									}
									if ( ! strstr( $post_link, $lessons_cpt->rewrite['slug_alt'] . '/' . $lesson_post_name ) ) {
										$url_part_new .= '/' . $lessons_cpt->rewrite['slug_alt'] . '/' . $lesson_post_name;
									}
									$url_part_new .= '/' . $topics_cpt->rewrite['slug_alt'] . '/' . $topic_post_name;

								} else {
									$url_part_old = add_query_arg( $topics_cpt->name, $topic->post_name, $url_part_old );

									$url_part_new = add_query_arg( $courses_cpt->name, $course->post_name, $url_part_new );
									$url_part_new = add_query_arg( $lessons_cpt->name, $lesson->post_name, $url_part_new );
									$url_part_new = add_query_arg( $topics_cpt->name, $topic->post_name, $url_part_new );
								}
							}
						}
					}
				} elseif ( $quizzes_cpt->name == $post->post_type ) {
					$quiz = $post;

					/** This filter is documented in includes/class-ld-permalinks.php */
					$course_id = apply_filters( 'learndash_post_link_course_id', learndash_get_course_id( $quiz->ID ), $post_link, $post );

					if ( ! empty( $course_id ) ) {
						$course = get_post( $course_id );
						if ( $course instanceof WP_Post ) {

							$course_post_name = $course->post_name;
							if ( false === $sample ) {
								$quiz_post_name = $quiz->post_name;
							} else {
								$quiz_post_name = '%' . $quizzes_cpt->name . '%';
							}

							if ( ( $wp_rewrite->using_permalinks() ) && ( ! $draft_or_pending ) ) {
								if ( strstr( $post_link, $quizzes_cpt->rewrite['slug'] . '/' . $quiz_post_name ) ) {
									$url_part_old = '/' . $quizzes_cpt->rewrite['slug'] . '/' . $quiz_post_name;
								} elseif ( strstr( $post_link, $quizzes_cpt->rewrite['slug_alt'] . '/' . $quiz_post_name ) ) {
									$url_part_old = '/' . $quizzes_cpt->rewrite['slug_alt'] . '/' . $quiz_post_name;
								}
							} else {
								$url_part_old = add_query_arg( $quizzes_cpt->name, $quiz->post_name, $url_part_old );
							}

							$quiz_parents = array();

							if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) {
								$quiz_parents = learndash_course_get_all_parent_step_ids( $course_id, $quiz->ID );
							} else {
								$lesson_id = learndash_get_lesson_id( $quiz->ID );
								if ( ! empty( $lesson_id ) ) {
									if ( get_post_type( $lesson_id ) == $topics_cpt->name ) {
										$topic_id  = $lesson_id;
										$lesson_id = learndash_get_lesson_id( $topic_id );
										if ( ! empty( $lesson_id ) ) {
											if ( get_post_type( $lesson_id ) == $lessons_cpt->name ) {
												$quiz_parents[] = $lesson_id;
												$quiz_parents[] = $topic_id;
											}
										}
									} else {
										$quiz_parents[] = $lesson_id;
									}
								}
							}

							if ( ( $wp_rewrite->using_permalinks() ) && ( ! $draft_or_pending ) ) {
								if ( ! strstr( $post_link, $courses_cpt->rewrite['slug_alt'] . '/' . $course_post_name ) ) {
									$url_part_new .= '/' . $courses_cpt->rewrite['slug_alt'] . '/' . $course_post_name;
								}
							} else {
								$url_part_new = add_query_arg( $courses_cpt->name, $course->post_name, $url_part_new );
							}

							if ( ! empty( $quiz_parents ) ) {
								foreach ( $quiz_parents as $quiz_parent_id ) {
									$quiz_parent_post = get_post( $quiz_parent_id );
									if ( $quiz_parent_post->post_type == $lessons_cpt->name ) {
										if ( ( $wp_rewrite->using_permalinks() ) && ( ! $draft_or_pending ) ) {
											$parent_slug = $lessons_cpt->rewrite['slug_alt'];
										} else {
											$parent_slug = $lessons_cpt->name;
										}
									} elseif ( $quiz_parent_post->post_type == $topics_cpt->name ) {
										if ( ( $wp_rewrite->using_permalinks() ) && ( ! $draft_or_pending ) ) {
											$parent_slug = $topics_cpt->rewrite['slug_alt'];
										} else {
											$parent_slug = $topics_cpt->name;
										}
									}

									if ( ( $wp_rewrite->using_permalinks() ) && ( ! $draft_or_pending ) ) {
										if ( ! strstr( $post_link, $parent_slug . '/' . $quiz_parent_post->post_name ) ) {
											$url_part_new .= '/' . $parent_slug . '/' . $quiz_parent_post->post_name;
										}
									} else {
										$url_part_new = add_query_arg( $parent_slug, $quiz_parent_post->post_name, $url_part_new );
									}
								}
							}

							if ( ( $wp_rewrite->using_permalinks() ) && ( ! $draft_or_pending ) ) {
								$url_part_new .= '/' . $quizzes_cpt->rewrite['slug_alt'] . '/' . $quiz_post_name;
							} else {
								$url_part_new = add_query_arg( $quizzes_cpt->name, $quiz->post_name, $url_part_new );
							}
						}
					}
				}
			}

			if ( ( ! empty( $url_part_new ) ) && ( ! empty( $url_part_old ) ) && ( $url_part_old !== $url_part_new ) ) {
				if ( ( ! $wp_rewrite->using_permalinks() ) || ( $draft_or_pending ) ) {
					$url_part_old = str_replace( '?', '', $url_part_old );
					$url_part_new = str_replace( '?', '', $url_part_new );

					/**
					 * We could normally just append the new args to the end of the URL. But
					 * we want to control the ordering for readability.
					 */
					$args = wp_parse_args( $url_part_new, array() );
					if ( ! empty( $args ) ) {
						foreach ( $args as $arg_key => $arg_val ) {
							$post_link = remove_query_arg( $arg_key, $post_link );
						}

						$post_link_parts_old = wp_parse_url( $post_link );
						if ( ( isset( $post_link_parts_old['query'] ) ) && ( ! empty( $post_link_parts_old['query'] ) ) ) {
							$post_link = str_replace( $post_link_parts_old['query'], '', $post_link );
						}

						$post_link           = add_query_arg( $args, $post_link );
						$post_link_parts_new = wp_parse_url( $post_link );

						/**
						 * Here we have removed the original LD post type elements and any non-LD elements from the
						 * original URL. Now we want to add the non-LD elements back.
						 */
						if ( ( isset( $post_link_parts_old['query'] ) ) && ( ! empty( $post_link_parts_old['query'] ) ) ) {
							if ( ( isset( $post_link_parts_old['query'] ) ) && ( ! empty( $post_link_parts_old['query'] ) ) ) {
								$post_link .= '&' . $post_link_parts_old['query'];
							} else {
								$post_link .= '?' . $post_link_parts_old['query'];
							}
						}
					}
				} else {
					$post_link = str_replace( $url_part_old, $url_part_new, $post_link );
				}
			}

			return $post_link;
		}


		/**
		 * Called via the WordPress List Table instance. This function will adjust the course
		 * step permalinks to be nested if enabled.
		 *
		 * @since 2.5.0
		 * @param array  $actions Array of row actions to be shown.
		 * @param object $post    WP_Post object being displayed for the row.
		 */
		public function row_actions( $actions = array(), $post = '' ) {
			global $pagenow, $typenow;

			if ( ( is_admin() ) && ( 'edit.php' == $pagenow ) ) {
				if ( ( 'yes' === LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) ) && ( in_array( $typenow, learndash_get_post_types( 'course_steps' ), true ) ) ) {
					$course_id = 0;

					// phpcs:ignore WordPress.Security.NonceVerification.Recommended
					if ( isset( $_GET['course_id'] ) ) {
						// phpcs:ignore WordPress.Security.NonceVerification.Recommended
						$course_id = absint( $_GET['course_id'] );
					}

					if ( ( empty( $course_id ) ) && ( isset( $actions['view'] ) ) ) {
						unset( $actions['view'] );
					}
				}
			}

			return $actions;
		}

		/**
		 * Override WordPress Get Edit Post Link to include nested URL.
		 *
		 * @since 2.5.0
		 * @param string  $link    The edit link.
		 * @param integer $post_id Post ID to edit.
		 * @param string  $context The link context. If set to 'display' then ampersands are encoded.
		 */
		public function get_edit_post_link( $link = '', $post_id = 0, $context = '' ) {
			global $pagenow;

			if ( ( ! empty( $post_id ) ) && ( ! is_admin() ) || ( ( is_admin() && ( in_array( $pagenow, array( 'post.php', 'edit.php' ), true ) ) ) ) ) {
				$post_type_name = get_post_type( $post_id );
				if ( ( ! empty( $post_type_name ) ) && ( in_array( $post_type_name, learndash_get_post_types( 'course_steps' ), true ) ) ) {
					if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) {

						$course_id = 0;
						$course_id = learndash_get_course_id( $post_id );
						if ( ! empty( $course_id ) ) {
							$link = add_query_arg( 'course_id', $course_id, $link );
						}
					}
				}

				if ( ( ! empty( $post_type_name ) ) && ( in_array( $post_type_name, LDLMS_Post_Types::get_post_types( 'quiz_questions' ), true ) ) ) {
					$quiz_id = 0;
					$quiz_id = learndash_get_quiz_id( $post_id );
					if ( ! empty( $quiz_id ) ) {
						$link = add_query_arg( 'quiz_id', $quiz_id, $link );
					}
				}
			}

			return $link;
		}

		/**
		 * Hook into the admin post editor Permalink display. We override the LD post
		 * items so they include the full nested URL
		 *
		 * @since 2.5.0
		 * @param array  $permalink Array containing the sample permalink with placeholder for the post name, and the post name.
		 * @param int    $post_id   Post ID.
		 * @param string $title    Post title.
		 * @param string $name     Post name (slug).
		 * @param object $post     (WP_Post) Post object.
		 */
		public function get_sample_permalink( $permalink = '', $post_id = 0, $title = '', $name = '', $post = '' ) {
			global $pagenow;

			if ( ( is_admin() ) && ( 'post.php' === $pagenow ) && ( is_a( $post, 'WP_Post' ) ) && ( in_array( $post->post_type, learndash_get_post_types( 'course_steps' ), true ) ) ) {
				$permalink_new = $this->post_type_link( $permalink[0], $post, false, true );
				if ( ( ! empty( $permalink_new ) ) && ( $permalink_new !== $permalink[0] ) ) {
					$permalink[0] = $permalink_new;
				}
			}

			return $permalink;
		}

		/**
		 * Filter the attachment link when using nested URLs.
		 *
		 * @since 3.4.1
		 *
		 * @param string  $attachment_link Attachment link.
		 * @param integer $attachment_id   Attachment post ID.
		 *
		 * @return string $attachment_link
		 */
		public function attachment_link( $attachment_link = '', $attachment_id = 0 ) {
			global $wp_rewrite;

			if ( ( ! empty( $attachment_link ) ) && ( ! empty( $attachment_id ) ) ) {
				if ( ( $wp_rewrite->using_permalinks() ) && ( 'yes' === LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Section_Permalinks', 'nested_urls' ) ) ) {
					$attachment_post = get_post( $attachment_id );
					if ( ( $attachment_post ) && ( is_a( $attachment_post, 'WP_Post' ) ) ) {
						if ( ( property_exists( $attachment_post, 'post_parent' ) ) && ( ! empty( $attachment_post->post_parent ) ) ) {
							if ( in_array( get_post_type( $attachment_post->post_parent ), learndash_get_post_types( 'course' ), true ) ) {
								$attachment_link = str_replace( '/' . $attachment_post->post_name . '/', '/attachment/' . $attachment_post->post_name . '/', $attachment_link );
							}
						}
					}
				}
			}

			return $attachment_link;
		}


		/**
		 * Action for comment form when nested URLs are enabled. This way the user is returned to this course step URL
		 *
		 * @since 2.5.5
		 */
		public function comment_form_top() {
			$queried_object = get_queried_object();

			if ( ( is_a( $queried_object, 'WP_Post' ) ) && ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Section_Permalinks', 'nested_urls' ) == 'yes' ) ) {
				if ( in_array( $queried_object->post_type, learndash_get_post_types( 'course_steps' ), true ) ) {
					echo '<input type="hidden" name="step_id" value="' . absint( $queried_object->ID ) . '" />';

					$course_id = learndash_get_course_id( $queried_object->ID );
					if ( ! empty( $course_id ) ) {
						echo '<input type="hidden" name="course_id" value="' . absint( $course_id ) . '" />';

						$redirect_to = learndash_get_step_permalink( $queried_object->ID, $course_id );
						if ( ! empty( $redirect_to ) ) {
							// This 'redirect_to' is used by WP in wp-comments-post.php to redirect back to a specific URL.
							// This is the important part.
							echo '<input type="hidden" name="redirect_to" value="' . esc_url( $redirect_to ) . '" />';
						}
					}
				}
			}
		}

		/**
		 * Add the course_id to comment meta
		 *
		 * @since 2.5.5
		 *
		 * @param int        $comment_id       The comment ID.
		 * @param int|string $comment_approved Comment Approve Status, 1 if the comment is approved, 0 if not, 'spam' if spam.
		 * @param array      $comment_data     Comment data.
		 */
		public function comment_post( $comment_id, $comment_approved, $comment_data ) {
			// phpcs:ignore WordPress.Security.NonceVerification.Missing
			if ( ( isset( $_POST['course_id'] ) ) && ( ! empty( $_POST['course_id'] ) ) ) {
				// phpcs:ignore WordPress.Security.NonceVerification.Missing
				update_comment_meta( $comment_id, 'course_id', absint( $_POST['course_id'] ) );
			}
		}

		// End of function.
	}
}

add_action(
	'plugins_loaded',
	function() {
		new LearnDash_Permalinks();
	}
);


/**
 * Utility function to get the nested permalink of the course step within in the course.
 *
 * @since 2.5.0
 * @param int $step_id        Course Step Post ID.
 * @param int $step_course_id Course ID.
 */
function learndash_get_step_permalink( $step_id = 0, $step_course_id = null ) {

	if ( ! empty( $step_id ) ) {
		if ( ! is_null( $step_course_id ) ) {
			$GLOBALS['step_course_id'] = $step_course_id; //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound
			add_filter(
				'learndash_post_link_course_id',
				function( $course_id ) {
					if ( ( isset( $GLOBALS['step_course_id'] ) ) && ( ! is_null( $GLOBALS['step_course_id'] ) ) ) { // @phpstan-ignore-line -- filter is processed later.
						$course_id = $GLOBALS['step_course_id'];
					}
					return $course_id;
				}
			);
		}
		$step_permalink = get_permalink( $step_id );

		if ( isset( $GLOBALS['step_course_id'] ) ) {
			unset( $GLOBALS['step_course_id'] );
		}

		return $step_permalink;
	}
}


/**
 * Used when editing Lesson, Topic, Quiz or Question post items. This filter is needed to add
 * the 'course_id' parameter back to the edit URL after the post is submitted (saved).
 *
 * @since 2.5.0
 * @param string $location The destination URL.
 * @param int    $post_id  The post ID.
 */
function learndash_redirect_post_location( $location = '', $post_id = 0 ) {
	if ( ( is_admin() ) && ( ! empty( $location ) ) ) {

		global $typenow;

		check_admin_referer( 'update-post_' . $post_id );

		if ( in_array( $typenow, learndash_get_post_types( 'course_steps' ), true ) ) {
			if ( ( isset( $_POST['ld-course-switcher'] ) ) && ( ! empty( $_POST['ld-course-switcher'] ) ) ) {
				$post_args = wp_parse_args( $_POST['ld-course-switcher'], array() );
				if ( ( isset( $post_args['course_id'] ) ) && ( ! empty( $post_args['course_id'] ) ) ) {
					$location = add_query_arg( 'course_id', intval( $post_args['course_id'] ), $location );
				}
			}
		} elseif ( learndash_get_post_type_slug( 'question' ) === $typenow ) {
			if ( ( isset( $_POST['ld-quiz-switcher'] ) ) && ( ! empty( $_POST['ld-quiz-switcher'] ) ) ) {
				$post_args = wp_parse_args( $_POST['ld-quiz-switcher'], array() );
				if ( ( isset( $post_args['quiz_id'] ) ) && ( ! empty( $post_args['quiz_id'] ) ) ) {
					$location = add_query_arg( 'quiz_id', absint( $post_args['quiz_id'] ), $location );
				}
			}
		}
	}

	return $location;
}
add_filter( 'redirect_post_location', 'learndash_redirect_post_location', 10, 2 );


/**
 * Utility function to set the option to trigger flush of rewrite rules.
 * This is checked during the 'shutdown' action where the rewrites will
 * then be flushed.
 */
function learndash_setup_rewrite_flush() {
	update_option( 'sfwd_lms_rewrite_flush', true, false );
}