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 filtering of lesson plans by language #1500

Merged
merged 10 commits into from May 3, 2023

Conversation

adamwoodnz
Copy link
Contributor

@adamwoodnz adamwoodnz commented Apr 18, 2023

Closes #874

This PR adds admin and frontend filtering of Lesson Plans, expanding on the functionality previously added for Tutorials.

Screenshots

Admin Frontend Cards
Screen Shot 2023-04-20 at 1 41 41 PM Screen Shot 2023-04-20 at 1 43 22 PM Screen Shot 2023-04-20 at 1 44 31 PM

How to test

IMPORTANT before you start

In the Lesson Plan list if the Language field displays English [en_US] it is most likely that the Lesson Plan actually has no meta language set and the column is displaying the default value. The easiest way to fix this is to bulk edit all these entries and set them to English. This has already been done in prod, so if you're testing in sandbox things should just work.

Admin
  1. Ensure you have Lesson Plans with multiple languages in your environment
  2. In the admin, navigate to the Lesson Plan list. Check that the filter language dropdown has options covering all the items listed. If you find there is no English option, ensure you have read the note above.
  3. Filter the admin list. Changing post status should update the languages in the filter dropdown.
  4. Add a new Lesson Plan and leave the language as the default
  5. Navigate to the Tutorial list page. Smoke test that the filtering still works there, matching the behaviour for Lesson Plans.
Frontend
  1. Open the frontend Lesson Plan archive at http://localhost:8888/lesson-plans/?_view=all
  2. Note the new language filter at the top of the sidebar
  3. Test filtering and check the results against the admin
  4. Check that the cards in the left have the correct language displayed
  5. Filter by English [en_US] and check that the Lesson Plan you created in step 4 above is displayed
  6. Test the 'Clear all filters' action. You should stay on the archive page and not be redirected to the Lesson Plan landing page.
  7. Navigate to the Tutorials archive and smoke test filtering using the language and subtitle dropdowns

@adamwoodnz adamwoodnz self-assigned this Apr 18, 2023
@adamwoodnz adamwoodnz force-pushed the add/874-lesson-plans-filter-by-language branch from 948c26f to 226c779 Compare April 19, 2023 02:30
Comment on lines +357 to +361
// This language meta field is rendered in the editor sidebar using a PluginDocumentSettingPanel block,
// which won't save the field on publish if it has the default value.
// Our filtering by locale depends on it being set, so we force it to be updated after saving:
$language = get_post_meta( $post_id, 'language', true );
$language_default = 'en_US';
if ( ! isset( $language ) || $language_default === $language ) {
update_post_meta( $post_id, 'language', $language_default );
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This follows the same approach that we had to take with Tutorials: https://github.com/WordPress/Learn/blob/trunk/wp-content/plugins/wporg-learn/inc/post-meta.php#L525

$language can be read as the default value of en_US even if it's not set, hence forcing save in this case as well, on line 362.

@adamwoodnz adamwoodnz force-pushed the add/874-lesson-plans-filter-by-language branch from 019928f to d181ba8 Compare April 20, 2023 02:06
@adamwoodnz adamwoodnz marked this pull request as ready for review April 20, 2023 02:08
@adamwoodnz adamwoodnz force-pushed the add/874-lesson-plans-filter-by-language branch from d181ba8 to ca29dbd Compare April 20, 2023 03:03
@adamwoodnz adamwoodnz force-pushed the add/874-lesson-plans-filter-by-language branch from ca29dbd to 4c1afee Compare April 20, 2023 03:10
@jonathanbossenger
Copy link
Collaborator

Nice work @adamwoodnz I've made a note to review this ASAP.

@adamwoodnz adamwoodnz added [Type] Enhancement New feature request for the Learn website. [Component] Learn Theme Website development issues related to the Learn theme. [Component] Learn Plugin Website development issues related to the Learn plugin. labels Apr 21, 2023
Copy link
Member

@iandunn iandunn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! I left a minor suggestion, but I don't feel strongly about it.

Comment on lines 272 to 293
$results = isset( $post_status )
? $wpdb->get_col( $wpdb->prepare(
"
SELECT DISTINCT postmeta.meta_value
FROM {$wpdb->postmeta} postmeta
JOIN {$wpdb->posts} posts ON posts.ID = postmeta.post_id AND posts.post_type = %s AND posts.post_status = %s
WHERE postmeta.meta_key = %s
",
$post_type,
$post_status,
$meta_key
) )
: $wpdb->get_col( $wpdb->prepare(
"
SELECT DISTINCT postmeta.meta_value
FROM {$wpdb->postmeta} postmeta
JOIN {$wpdb->posts} posts ON posts.ID = postmeta.post_id AND posts.post_type = %s
WHERE postmeta.meta_key = %s
",
$post_type,
$meta_key
) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's a fair point. I was trying to remove the need for phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, but it seems to be common practice. Changed to something closer resembling the previous code, and updated the comment.

Copy link
Collaborator

@jonathanbossenger jonathanbossenger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The functionality works great, nice one @adamwoodnz

@adamwoodnz adamwoodnz force-pushed the add/874-lesson-plans-filter-by-language branch from 32b84ce to b36d679 Compare April 26, 2023 02:27
@adamwoodnz adamwoodnz force-pushed the add/874-lesson-plans-filter-by-language branch from b36d679 to 6f881b8 Compare April 26, 2023 02:31
@adamwoodnz adamwoodnz marked this pull request as draft April 26, 2023 02:37
global $wpdb;

$and_post_status = '';
if ( $published_only ) {
$and_post_status = "AND posts.post_status = 'publish'";
if ( in_array( $post_status, get_post_stati(), true ) ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iandunn are you satisfied with the security of this approach? $post_status is passed in from INPUT_GET here.

This line attempts to ensure that only safe strings matching post_status values in the system are included in the query.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

post_status is also only sourced from INPUT_GET in the admin. On the frontend post_status is always hard coded to publish.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that looks like a great way to guarantee it's a valid value 👍🏻

@adamwoodnz adamwoodnz marked this pull request as ready for review April 26, 2023 23:29
@adamwoodnz adamwoodnz requested a review from iandunn April 26, 2023 23:29
Copy link
Member

@iandunn iandunn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

*
* @return array
*/
function get_available_workshop_locales( $meta_key, $label_language = 'english', $published_only = true ) {
function get_available_post_type_locales( $meta_key, $post_type, $label_language = 'english', $post_status ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get this notice on PHP 8.0.28. We don't run that on prod yet, but will in the near future, so it'd be good to be prepared now IMO.

PHP Deprecated: Required parameter $post_status follows optional parameter $label_language in wp-content/plugins/wporg-learn/inc/post-meta.php on line 269

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 4cb6519

global $wpdb;

$and_post_status = '';
if ( $published_only ) {
$and_post_status = "AND posts.post_status = 'publish'";
if ( in_array( $post_status, get_post_stati(), true ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that looks like a great way to guarantee it's a valid value 👍🏻

Optional parameter should be last in PHP 8
@adamwoodnz adamwoodnz merged commit 83713e4 into trunk May 3, 2023
1 check passed
@adamwoodnz adamwoodnz deleted the add/874-lesson-plans-filter-by-language branch May 3, 2023 23:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Component] Learn Plugin Website development issues related to the Learn plugin. [Component] Learn Theme Website development issues related to the Learn theme. [Type] Enhancement New feature request for the Learn website.
Projects
Status: Done
Status: Done
Development

Successfully merging this pull request may close these issues.

Add language filtering option for lesson plans
3 participants