Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add translations for lessons and quizzes that were created while saving the course structure #7383

Merged
merged 10 commits into from
Jan 16, 2024
4 changes: 4 additions & 0 deletions changelog/fix-wpml-save-course-structure
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Add translations for lessons and quizzes that were created while saving the course structure
merkushin marked this conversation as resolved.
Show resolved Hide resolved
35 changes: 31 additions & 4 deletions includes/class-sensei-course-structure.php
Original file line number Diff line number Diff line change
Expand Up @@ -519,14 +519,26 @@
],
];

$post_id = wp_insert_post( $post_args );
if ( ! $post_id ) {
$lesson_id = wp_insert_post( $post_args );
if ( ! $lesson_id ) {
return false;
}

$this->create_quiz( $post_id );
/**
* Fires after a lesson is created while saving the course structure.
*
* @since $$next-version$$
*
* @hook sensei_course_structure_lesson_created
*
* @param int $lesson_id Lesson post ID.
merkushin marked this conversation as resolved.
Show resolved Hide resolved
* @param int $course_id Course post ID.
*/
do_action( 'sensei_course_structure_lesson_created', $lesson_id, $this->course_id );

return $post_id;
$this->create_quiz( $lesson_id );

return $lesson_id;
}

/**
Expand All @@ -549,8 +561,23 @@
];

$quiz_id = wp_insert_post( $post_args );
if ( ! $quiz_id ) {
return;

Check warning on line 565 in includes/class-sensei-course-structure.php

View check run for this annotation

Codecov / codecov/patch

includes/class-sensei-course-structure.php#L565

Added line #L565 was not covered by tests
}

update_post_meta( $lesson_id, '_lesson_quiz', $quiz_id );

/**
* Fires after a quiz is created while saving the course structure.
*
* @since $$next-version$$
*
* @hook sensei_course_structure_quiz_created
*
* @param int $quiz_id Quiz post ID.
merkushin marked this conversation as resolved.
Show resolved Hide resolved
* @param int $lesson_id Course post ID.
*/
do_action( 'sensei_course_structure_quiz_created', $quiz_id, $lesson_id );
}

/**
Expand Down
102 changes: 100 additions & 2 deletions includes/wpml/class-sensei-wpml.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
<?php
/**
* File containing the Sensei_WPML class.
*
* @package sensei
*/

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

/**
* Class Sensei_WPML
*/
class Sensei_WPML {
public function __construct() {
add_action( 'sensei_before_mail', array( $this, 'sensei_before_mail' ) );
add_action( 'sensei_after_sending_email', array( $this, 'sensei_after_sending_email' ) );
add_action( 'sensei_course_structure_lesson_created', array( $this, 'set_language_details_when_lesson_created' ), 10, 2 );
add_action( 'sensei_course_structure_quiz_created', array( $this, 'set_language_details_when_quiz_created' ), 10, 2 );
}

/**
* Switch language for email.
*
* @param string $email_address Recipient's email address.
*/
public function sensei_before_mail( $email_address ) {
/**
* Switch language for email
Expand All @@ -18,9 +38,12 @@
*
* @param string $email_address Recipient's email address
*/
do_action( 'wpml_switch_language_for_email', $email_address );
do_action( 'wpml_switch_language_for_email', $email_address ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound

Check warning on line 41 in includes/wpml/class-sensei-wpml.php

View check run for this annotation

Codecov / codecov/patch

includes/wpml/class-sensei-wpml.php#L41

Added line #L41 was not covered by tests
}

/**
* Restore language after sending email.
*/
public function sensei_after_sending_email() {
/**
* Restore language after sending email
Expand All @@ -32,6 +55,81 @@
*
* @since 1.9.7
*/
do_action( 'wpml_restore_language_from_email' );
do_action( 'wpml_restore_language_from_email' ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound

Check warning on line 58 in includes/wpml/class-sensei-wpml.php

View check run for this annotation

Codecov / codecov/patch

includes/wpml/class-sensei-wpml.php#L58

Added line #L58 was not covered by tests
}

/**
* Set language details for the lesson when it is created.
*
merkushin marked this conversation as resolved.
Show resolved Hide resolved
* @since $$next-version$$
* @param int $lesson_id Lesson ID.
* @param int $course_id Course ID.
*/
public function set_language_details_when_lesson_created( $lesson_id, $course_id ) {

// Get course language_code.
$language_code = apply_filters(
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
'wpml_element_language_code',
null,
array(
'element_id' => $course_id,
'element_type' => 'post_course',
merkushin marked this conversation as resolved.
Show resolved Hide resolved
)
);
if ( ! $language_code ) {
// Use current language if course language is not set.
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
$language_code = apply_filters( 'wpml_current_language', null );
}

$args = array(
'element_id' => $lesson_id,
'element_type' => 'post_lesson',
'trid' => false,
'language_code' => $language_code,
);

// Set language details for the lesson.
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
do_action( 'wpml_set_element_language_details', $args );
}

/**
* Set language details for the lesson when it is created.
merkushin marked this conversation as resolved.
Show resolved Hide resolved
*
* @since $$next-version$$
*
* @param int $quiz_id Quiz ID.
* @param int $lesson_id Lesson ID.
*/
public function set_language_details_when_quiz_created( $quiz_id, $lesson_id ) {

// Get lesson language_code.
$language_code = apply_filters(
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
'wpml_element_language_code',
null,
array(
'element_id' => $lesson_id,
'element_type' => 'post_lesson',
)
);
if ( ! $language_code ) {
// Use current language if lesson language is not set.
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
$language_code = apply_filters( 'wpml_current_language', null );
}

$args = array(
'element_id' => $quiz_id,
'element_type' => 'post_quiz',
'trid' => false,
'language_code' => $language_code,
);

// Set language details for the lesson.
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
do_action( 'wpml_set_element_language_details', $args );
}
}
66 changes: 61 additions & 5 deletions tests/unit-tests/test-class-sensei-course-structure.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function setUp(): void {
/**
* Test getting course structure when just lessons when one lesson is unpublished in view context.
*/
public function testGetJustLessonsView() {
public function testGet_WithViewContextWhenStructureSavedWithLessonsOnly_ReturnSameStructureWithIdsAndTypes() {
$course_id = $this->factory->course->create();
$course_lesson_args = [
'meta_input' => [
Expand Down Expand Up @@ -66,7 +66,7 @@ public function testGetJustLessonsView() {
/**
* Test getting course structure when just lessons when one lesson is unpublished in edit context.
*/
public function testGetJustLessonsEdit() {
public function testGet_WithEditContextWhenStructureSavedWithLessonsOnly_ReturnsSameStuctureWithIdsAndTypes() {
$course_id = $this->factory->course->create();
$course_lesson_args = [
'meta_input' => [
Expand Down Expand Up @@ -107,7 +107,7 @@ public function testGetJustLessonsEdit() {
/**
* Test getting course structure when just modules on the first level.
*/
public function testGetJustModules() {
public function testGet_WithViewContextWhenStructureSavedWithModulesOnly_ReturnsSameStructure() {
$course_id = $this->factory->course->create();

$lessons = $this->factory->lesson->create_many( 4 );
Expand Down Expand Up @@ -156,7 +156,7 @@ public function testGetJustModules() {
/**
* Test getting course structure when just modules with no lessons and one rogue lesson while in edit context.
*/
public function testGetModulesWithEmptyLessonsEdit() {
public function testGet_WithEditContextWhenStructureSavedWithModulesWithEmptyLessons_ReturnsSameStructure() {
$this->login_as_admin();

$course_id = $this->factory->course->create();
Expand Down Expand Up @@ -1654,7 +1654,7 @@ private function saveStructure( int $course_id, array $structure, $module_parent
}
}

public function testGetForEditMode_WhenCalled_ReturnsTeacherNameWithModulesProperly() {
public function testGet_CalledAsAdminWithEditContextAndTeacherAssignedToModule_ReturnsTeacherNameWithModulesProperly() {
/* Arrange */
global $current_screen;
$initial_current_screen = $current_screen;
Expand Down Expand Up @@ -1715,4 +1715,60 @@ public function testGetForEditMode_WhenCalled_ReturnsTeacherNameWithModulesPrope
// @see https://core.trac.wordpress.org/ticket/53431
$current_screen = $initial_current_screen;
}

public function testSave_WithNewLesson_FiresLessonCreatedAction() {
/* Arrange. */
$this->login_as_teacher();

$course_id = $this->factory->course->create();

$new_structure = array(
array(
'type' => 'lesson',
'title' => 'New lesson',
),
);

$course_structure = Sensei_Course_Structure::instance( $course_id );

$lesson_created_action_fired = false;
$action = function( $lesson_id, $course_id ) use ( &$lesson_created_action_fired ) {
$lesson_created_action_fired = true;
};
add_action( 'sensei_course_structure_lesson_created', $action, 10, 2 );

/* Act. */
$course_structure->save( $new_structure );

/* Assert. */
$this->assertTrue( $lesson_created_action_fired );
}

public function testSave_WithNewLesson_FiresQuizCreatedAction() {
/* Arrange. */
$this->login_as_teacher();

$course_id = $this->factory->course->create();

$new_structure = array(
array(
'type' => 'lesson',
'title' => 'New lesson',
),
);

$course_structure = Sensei_Course_Structure::instance( $course_id );

$quiz_created_action_fired = false;
$action = function( $quiz, $lesson ) use ( &$quiz_created_action_fired ) {
$quiz_created_action_fired = true;
};
add_action( 'sensei_course_structure_quiz_created', $action, 10, 2 );

/* Act. */
$course_structure->save( $new_structure );

/* Assert. */
$this->assertTrue( $quiz_created_action_fired );
}
}