diff --git a/.changelogs/feature_any-engagement-trigger.yml b/.changelogs/feature_any-engagement-trigger.yml
new file mode 100644
index 0000000000..f9a0be6587
--- /dev/null
+++ b/.changelogs/feature_any-engagement-trigger.yml
@@ -0,0 +1,7 @@
+significance: minor
+type: added
+links:
+ - "#3109"
+entry: Added an explicit 'Any' trigger option for engagements so one engagement
+ can apply to all matching courses, memberships, lessons, quizzes, sections,
+ access plans, or tracks.
diff --git a/includes/admin/post-types/meta-boxes/class.llms.meta.box.engagement.php b/includes/admin/post-types/meta-boxes/class.llms.meta.box.engagement.php
index a182935e73..795da3fd31 100644
--- a/includes/admin/post-types/meta-boxes/class.llms.meta.box.engagement.php
+++ b/includes/admin/post-types/meta-boxes/class.llms.meta.box.engagement.php
@@ -71,12 +71,14 @@ public function get_fields() {
),
'id' => '_faux_engagement_trigger_post_course',
'label' => __( 'Select a Course', 'lifterlms' ),
+ 'placeholder' => __( 'Any Course', 'lifterlms' ),
),
'lesson' => array(
'controller_value' => array( 'lesson_completed' ),
'id' => '_faux_engagement_trigger_post_lesson',
'label' => __( 'Select a Lesson', 'lifterlms' ),
+ 'placeholder' => __( 'Any Lesson', 'lifterlms' ),
),
'llms_access_plan' => array(
@@ -85,6 +87,7 @@ public function get_fields() {
),
'id' => '_faux_engagement_trigger_post_access_plan',
'label' => __( 'Select an Access Plan', 'lifterlms' ),
+ 'placeholder' => __( 'Any Access Plan', 'lifterlms' ),
),
'llms_membership' => array(
@@ -94,6 +97,7 @@ public function get_fields() {
),
'id' => '_faux_engagement_trigger_post_membership',
'label' => __( 'Select a Membership', 'lifterlms' ),
+ 'placeholder' => __( 'Any Membership', 'lifterlms' ),
),
'llms_quiz' => array(
@@ -104,12 +108,14 @@ public function get_fields() {
),
'id' => '_faux_engagement_trigger_post_quiz',
'label' => __( 'Select a Quiz', 'lifterlms' ),
+ 'placeholder' => __( 'Any Quiz', 'lifterlms' ),
),
'section' => array(
'controller_value' => array( 'section_completed' ),
'id' => '_faux_engagement_trigger_post_section',
'label' => __( 'Select a Section', 'lifterlms' ),
+ 'placeholder' => __( 'Any Section', 'lifterlms' ),
),
);
@@ -118,12 +124,17 @@ public function get_fields() {
$data['controller_value'] = apply_filters( 'llms_engagement_controller_values_' . $post_type, $data['controller_value'] );
- if ( in_array( get_post_meta( $this->post->ID, $this->prefix . 'trigger_type', true ), $data['controller_value'] ) ) {
- $val = llms_make_select2_post_array( array( get_post_meta( $this->post->ID, $this->prefix . 'engagement_trigger_post', true ) ) );
+ $trigger_post_val = get_post_meta( $this->post->ID, $this->prefix . 'engagement_trigger_post', true );
+ if ( 'any' === $trigger_post_val || empty( $trigger_post_val ) ) {
+ $val = array();
+ } elseif ( in_array( get_post_meta( $this->post->ID, $this->prefix . 'trigger_type', true ), $data['controller_value'] ) ) {
+ $val = llms_make_select2_post_array( array( $trigger_post_val ) );
} else {
$val = array();
}
+ $placeholder = isset( $data['placeholder'] ) ? $data['placeholder'] : $data['label'];
+
$fields[] = array(
'allow_null' => false,
'class' => 'llms-select2-post',
@@ -131,9 +142,10 @@ public function get_fields() {
'controller_value' => implode( ',', $data['controller_value'] ),
'data_attributes' => array(
'allow_clear' => true,
- 'placeholder' => $data['label'],
+ 'placeholder' => $placeholder,
'post-type' => $post_type,
),
+ 'desc' => __( 'Leave blank to apply to all.', 'lifterlms' ),
'id' => $data['id'],
'label' => $data['label'],
'type' => 'select',
@@ -156,19 +168,24 @@ public function get_fields() {
);
}
+ $track_selected = get_post_meta( $this->post->ID, $this->prefix . 'engagement_trigger_post', true );
+ if ( 'any' === $track_selected ) {
+ $track_selected = '';
+ }
+
$fields[] = array(
- 'allow_null' => false,
+ 'allow_null' => true,
'class' => 'llms-select2',
'controller' => '#' . $this->prefix . 'trigger_type',
'controller_value' => implode( ',', apply_filters( 'llms_engagement_controller_values_track', array( 'course_track_completed' ) ) ),
'data_attributes' => array(
'allow_clear' => true,
- 'placeholder' => __( 'Select a Course Track', 'lifterlms' ),
+ 'placeholder' => __( 'Any Course Track', 'lifterlms' ),
),
'id' => '_faux_engagement_trigger_post_track',
'label' => __( 'Select a Course Track', 'lifterlms' ),
'type' => 'select',
- 'selected' => get_post_meta( $this->post->ID, $this->prefix . 'engagement_trigger_post', true ),
+ 'selected' => $track_selected,
'value' => $track_options,
);
@@ -333,6 +350,11 @@ public function save( $post_id ) {
$val = llms_filter_input_sanitize_string( INPUT_POST, '_faux_engagement_trigger_post_' . $var );
+ // An empty trigger post means "any" — store explicitly so the intent is clear.
+ if ( empty( $val ) ) {
+ $val = 'any';
+ }
+
} else {
$val = '';
diff --git a/includes/admin/post-types/post-tables/class.llms.admin.post.table.engagements.php b/includes/admin/post-types/post-tables/class.llms.admin.post.table.engagements.php
index 9a6d9d1324..f48deba282 100644
--- a/includes/admin/post-types/post-tables/class.llms.admin.post.table.engagements.php
+++ b/includes/admin/post-types/post-tables/class.llms.admin.post.table.engagements.php
@@ -75,7 +75,7 @@ public function manage_columns( $column, $post_id ) {
echo isset( $triggers[ $trigger ] ) ? esc_html( $triggers[ $trigger ] ) : esc_html( $trigger );
$tid = get_post_meta( $post_id, '_llms_engagement_trigger_post', true );
- if ( $tid ) {
+ if ( $tid && 'any' !== $tid ) {
echo '
';
@@ -90,6 +90,10 @@ public function manage_columns( $column, $post_id ) {
printf( '%s (ID# %d)', esc_url( $link ), esc_html( $title ), esc_html( $tid ) );
+ } elseif ( 'any' === $tid ) {
+
+ echo '
' . esc_html__( 'Any', 'lifterlms' ) . '';
+
}
break;
diff --git a/includes/class.llms.engagements.php b/includes/class.llms.engagements.php
index 9c44b485e2..9e56ac6895 100644
--- a/includes/class.llms.engagements.php
+++ b/includes/class.llms.engagements.php
@@ -151,7 +151,10 @@ private function get_engagements( $trigger_type, $related_post_id = '' ) {
$related_select = ', relation_meta.meta_value AS related_post_id';
$related_join = "LEFT JOIN $wpdb->postmeta AS relation_meta ON triggers.ID = relation_meta.post_id";
- $related_where = $wpdb->prepare( "AND relation_meta.meta_key = '_llms_engagement_trigger_post' AND relation_meta.meta_value = %d", $related_post_id );
+ $related_where = $wpdb->prepare(
+ "AND relation_meta.meta_key = '_llms_engagement_trigger_post' AND ( relation_meta.meta_value = %d OR relation_meta.meta_value = 'any' )",
+ $related_post_id
+ );
}