<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[13298] sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events: Translate Events: add languages and contributors</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://meta.trac.wordpress.org/changeset/13298">13298</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://meta.trac.wordpress.org/changeset/13298","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>akirk</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2024-03-07 06:39:00 +0000 (Thu, 07 Mar 2024)</dd>
</dl>
<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Translate Events: add languages and contributors</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsassetscsstranslationeventscss">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/assets/css/translation-events.css</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesstatscalculatorphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/stats-calculator.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesstatslistenerphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/stats-listener.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventstemplateseventphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/event.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventswporggptranslationeventsphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/wporg-gp-translation-events.php</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li>sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/</li>
<li>sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesrouteseventcreatephp">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/create.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesrouteseventdetailsphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/details.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesrouteseventeditphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/edit.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesrouteseventlistphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/list.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesroutesroutephp">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/route.php</a></li>
<li>sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/user/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesroutesuserattendeventphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/user/attend-event.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesroutesusermyeventsphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/user/my-events.php</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesroutephp">sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/route.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsassetscsstranslationeventscss"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/assets/css/translation-events.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/assets/css/translation-events.css 2024-03-07 04:39:31 UTC (rev 13297)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/assets/css/translation-events.css 2024-03-07 06:39:00 UTC (rev 13298)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -49,10 +49,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> width: 100%;
</span><span class="cx" style="display: block; padding: 0 10px"> table-layout: fixed;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.event-details-stats table th, .event-details-stats table td{
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.event-details-stats table th, .event-details-stats table td {
</ins><span class="cx" style="display: block; padding: 0 10px"> padding: 1em;
</span><span class="cx" style="display: block; padding: 0 10px"> text-align: center;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.event-details-stats table td:first-child {
+ text-align: left;
+}
</ins><span class="cx" style="display: block; padding: 0 10px"> .event-details-stats table tr {
</span><span class="cx" style="display: block; padding: 0 10px"> border-bottom: thin solid #f0f0f0;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -59,9 +62,20 @@
</span><span class="cx" style="display: block; padding: 0 10px"> .event-details-stats table th {
</span><span class="cx" style="display: block; padding: 0 10px"> background-color: #e9e9e9;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.event-details-stats-totals {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.event-details-stats-totals td {
</ins><span class="cx" style="display: block; padding: 0 10px"> font-weight: bold;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.event-contributors li {
+ display: inline-block;
+ list-style-type: none;
+ margin-right: 1em;
+ margin-bottom: .5em;
+ width: 15em;
+}
+.event-contributors li .avatar {
+ border-radius: 50%;
+ vertical-align: middle;
+}
</ins><span class="cx" style="display: block; padding: 0 10px"> .hide-event-url {
</span><span class="cx" style="display: block; padding: 0 10px"> display: none;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -217,7 +231,6 @@
</span><span class="cx" style="display: block; padding: 0 10px"> padding: 0.8em;
</span><span class="cx" style="display: block; padding: 0 10px"> font-size: .9em;
</span><span class="cx" style="display: block; padding: 0 10px"> border-top: thin solid #e0e0e0;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- font-family: monospace;
</del><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> time.event-utc-time {
</span><span class="cx" style="display: block; padding: 0 10px"> display: block;
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesroutephp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/route.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/route.php 2024-03-07 04:39:31 UTC (rev 13297)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/route.php 2024-03-07 06:39:00 UTC (rev 13298)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,404 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-
-namespace Wporg\TranslationEvents;
-
-use DateTime;
-use DateTimeZone;
-use Exception;
-use GP_Route;
-use WP_Query;
-use GP;
-
-class Route extends GP_Route {
- public const USER_META_KEY_ATTENDING = 'translation-events-attending';
-
- public function __construct() {
- parent::__construct();
- $this->template_path = __DIR__ . '/../templates/';
- }
-
- /**
- * Loads the 'events_list' template.
- *
- * @return void
- */
- public function events_list() {
- $current_datetime_utc = null;
- try {
- $current_datetime_utc = ( new DateTime( 'now', new DateTimeZone( 'UTC' ) ) )->format( 'Y-m-d H:i:s' );
- } catch ( Exception $e ) {
- // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
- error_log( $e );
- $this->die_with_error( esc_html__( 'Something is wrong.', 'gp-translation-events' ) );
- }
-
- $_current_events_paged = 1;
- $_upcoming_events_paged = 1;
- $_past_events_paged = 1;
- $_user_attending_events_paged = 1;
-
- // phpcs:disable WordPress.Security.NonceVerification.Recommended
- if ( isset( $_GET['current_events_paged'] ) ) {
- $value = sanitize_text_field( wp_unslash( $_GET['current_events_paged'] ) );
- if ( is_numeric( $value ) ) {
- $_current_events_paged = (int) $value;
- }
- }
- if ( isset( $_GET['upcoming_events_paged'] ) ) {
- $value = sanitize_text_field( wp_unslash( $_GET['upcoming_events_paged'] ) );
- if ( is_numeric( $value ) ) {
- $_upcoming_events_paged = (int) $value;
- }
- }
- if ( isset( $_GET['past_events_paged'] ) ) {
- $value = sanitize_text_field( wp_unslash( $_GET['past_events_paged'] ) );
- if ( is_numeric( $value ) ) {
- $_past_events_paged = (int) $value;
- }
- }
- if ( isset( $_GET['user_attending_events_paged'] ) ) {
- $value = sanitize_text_field( wp_unslash( $_GET['user_attending_events_paged'] ) );
- if ( is_numeric( $value ) ) {
- $_user_attending_events_paged = (int) $value;
- }
- }
- // phpcs:enable
-
- $current_events_args = array(
- 'post_type' => Translation_Events::CPT,
- 'posts_per_page' => 10,
- 'paged' => $_current_events_paged,
- 'post_status' => 'publish',
- // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
- 'meta_query' => array(
- array(
- 'key' => '_event_start',
- 'value' => $current_datetime_utc,
- 'compare' => '<=',
- 'type' => 'DATETIME',
- ),
- array(
- 'key' => '_event_end',
- 'value' => $current_datetime_utc,
- 'compare' => '>=',
- 'type' => 'DATETIME',
- ),
- ),
- 'orderby' => 'meta_value',
- 'order' => 'ASC',
- );
- $current_events_query = new WP_Query( $current_events_args );
-
- $upcoming_events_args = array(
- 'post_type' => Translation_Events::CPT,
- 'posts_per_page' => 10,
- 'paged' => $_upcoming_events_paged,
- 'post_status' => 'publish',
- // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
- 'meta_query' => array(
- array(
- 'key' => '_event_start',
- 'value' => $current_datetime_utc,
- 'compare' => '>=',
- 'type' => 'DATETIME',
- ),
- ),
- 'orderby' => 'meta_value',
- 'order' => 'ASC',
- );
- $upcoming_events_query = new WP_Query( $upcoming_events_args );
-
- $past_events_args = array(
- 'post_type' => Translation_Events::CPT,
- 'posts_per_page' => 10,
- 'paged' => $_past_events_paged,
- 'post_status' => 'publish',
- // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
- 'meta_query' => array(
- array(
- 'key' => '_event_end',
- 'value' => $current_datetime_utc,
- 'compare' => '<',
- 'type' => 'DATETIME',
- ),
- ),
- 'orderby' => 'meta_value',
- 'order' => 'ASC',
- );
- $past_events_query = new WP_Query( $past_events_args );
-
- $user_attending_events = get_user_meta( get_current_user_id(), self::USER_META_KEY_ATTENDING, true ) ?: array( 0 );
- $user_attending_events_args = array(
- 'post_type' => Translation_Events::CPT,
- 'post__in' => array_keys( $user_attending_events ),
- 'posts_per_page' => 10,
- 'paged' => $_user_attending_events_paged,
- 'post_status' => 'publish',
- // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
- 'meta_query' => array(
- array(
- 'key' => '_event_end',
- 'value' => $current_datetime_utc,
- 'compare' => '>',
- 'type' => 'DATETIME',
- ),
- ),
- // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
- 'meta_key' => '_event_start',
- 'orderby' => 'meta_value',
- 'order' => 'ASC',
- );
- $user_attending_events_query = new WP_Query( $user_attending_events_args );
-
- $this->tmpl( 'events-list', get_defined_vars() );
- }
-
- /**
- * Loads the 'events_create' template.
- *
- * @return void
- */
- public function events_create() {
- global $wp;
- if ( ! is_user_logged_in() ) {
- wp_safe_redirect( wp_login_url( home_url( $wp->request ) ) );
- exit;
- }
- $event_form_title = 'Create Event';
- $event_form_name = 'create_event';
- $css_show_url = 'hide-event-url';
- $event_id = null;
- $event_title = '';
- $event_description = '';
- $event_timezone = '';
- $event_start = '';
- $event_end = '';
- $event_url = '';
- $create_delete_button = true;
- $visibility_delete_button = 'none';
-
- $this->tmpl( 'events-form', get_defined_vars() );
- }
-
- /**
- * Loads the 'events_edit' template.
- *
- * @param int $event_id The event ID.
- *
- * @return void
- */
- public function events_edit( int $event_id ) {
- global $wp;
- if ( ! is_user_logged_in() ) {
- wp_safe_redirect( wp_login_url( home_url( $wp->request ) ) );
- exit;
- }
- $event = get_post( $event_id );
- if ( ! $event || Translation_Events::CPT !== $event->post_type || ! ( current_user_can( 'edit_post', $event->ID ) || intval( $event->post_author ) === get_current_user_id() ) ) {
- $this->die_with_error( esc_html__( 'Event does not exist, or you do not have permission to edit it.', 'gp-translation-events' ), 403 );
- }
- if ( 'trash' === $event->post_status ) {
- $this->die_with_error( esc_html__( 'You cannot edit a trashed event', 'gp-translation-events' ), 403 );
- }
-
- include ABSPATH . 'wp-admin/includes/post.php';
- $event_form_title = 'Edit Event';
- $event_form_name = 'edit_event';
- $css_show_url = '';
- $event_title = $event->post_title;
- $event_description = $event->post_content;
- $event_status = $event->post_status;
- list( $permalink, $post_name ) = get_sample_permalink( $event_id );
- $permalink = str_replace( '%pagename%', $post_name, $permalink );
- $event_url = get_site_url() . gp_url( wp_make_link_relative( $permalink ) );
- $event_timezone = get_post_meta( $event_id, '_event_timezone', true ) ?: '';
- $create_delete_button = false;
- $visibility_delete_button = 'inline-flex';
-
- $stats_calculator = new Stats_Calculator();
- if ( ! $stats_calculator->event_has_stats( $event ) ) {
- $current_user = wp_get_current_user();
- if ( $current_user->ID === $event->post_author || current_user_can( 'manage_options' ) ) {
- $create_delete_button = true;
- }
- }
-
- try {
- $event_start = self::convertToTimezone( get_post_meta( $event_id, '_event_start', true ), $event_timezone );
- $event_end = self::convertToTimezone( get_post_meta( $event_id, '_event_end', true ), $event_timezone );
- } catch ( Exception $e ) {
- // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
- error_log( $e );
- $this->die_with_error( esc_html__( 'Something is wrong.', 'gp-translation-events' ) );
- }
-
- $this->tmpl( 'events-form', get_defined_vars() );
- }
-
- /**
- * Loads the 'event' template.
- *
- * @param string $event_slug The event slug.
- *
- * @return void
- */
- public function events_details( string $event_slug ) {
- $user = wp_get_current_user();
- $event = get_page_by_path( $event_slug, OBJECT, Translation_Events::CPT );
- if ( ! $event ) {
- $this->die_with_404();
- }
- /**
- * Filter the ability to create, edit, or delete an event.
- *
- * @param bool $can_crud_event Whether the user can create, edit, or delete an event.
- */
- $can_crud_event = apply_filters( 'gp_translation_events_can_crud_event', GP::$permission->current_user_can( 'admin' ) );
- if ( 'publish' !== $event->post_status && ! $can_crud_event ) {
- $this->die_with_error( esc_html__( 'You are not authorized to view this page.', 'gp-translation-events' ), 403 );
- }
-
- $event_id = $event->ID;
- $event_title = $event->post_title;
- $event_description = $event->post_content;
- $event_start = get_post_meta( $event->ID, '_event_start', true ) ?: '';
- $event_end = get_post_meta( $event->ID, '_event_end', true ) ?: '';
- $attending_event_ids = get_user_meta( $user->ID, self::USER_META_KEY_ATTENDING, true ) ?: array();
- $user_is_attending = isset( $attending_event_ids[ $event_id ] );
-
- $stats_calculator = new Stats_Calculator();
- try {
- $event_stats = $stats_calculator->for_event( $event );
- } catch ( Exception $e ) {
- // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
- error_log( $e );
- $this->die_with_error( esc_html__( 'Failed to calculate event stats', 'gp-translation-events' ) );
- }
-
- $this->tmpl( 'event', get_defined_vars() );
- }
-
- /**
- * Toggle whether the current user is attending an event.
- * If the user is not currently marked as attending, they will be marked as attending.
- * If the user is currently marked as attending, they will be marked as not attending.
- */
- public function events_attend( int $event_id ) {
- $user = wp_get_current_user();
- if ( ! $user ) {
- $this->die_with_error( esc_html__( 'Only logged-in users can attend events', 'gp-translation-events' ), 403 );
- }
-
- $event = get_post( $event_id );
-
- if ( ! $event ) {
- $this->die_with_404();
- }
-
- $event_ids = get_user_meta( $user->ID, self::USER_META_KEY_ATTENDING, true ) ?? array();
- if ( ! $event_ids ) {
- $event_ids = array();
- }
-
- if ( ! isset( $event_ids[ $event_id ] ) ) {
- // Not yet attending, mark as attending.
- $event_ids[ $event_id ] = true;
- } else {
- // Currently attending, mark as not attending.
- unset( $event_ids[ $event_id ] );
- }
-
- update_user_meta( $user->ID, self::USER_META_KEY_ATTENDING, $event_ids );
-
- wp_safe_redirect( gp_url( "/events/$event->post_name" ) );
- exit;
- }
-
- /**
- * Loads the 'events_user_created' template.
- *
- * @return void
- */
- public function my_events() {
- global $wp;
- if ( ! is_user_logged_in() ) {
- wp_safe_redirect( wp_login_url( home_url( $wp->request ) ) );
- exit;
- }
- include ABSPATH . 'wp-admin/includes/post.php';
-
- $_events_i_created_paged = 1;
- $_events_i_attended_paged = 1;
-
- // phpcs:disable WordPress.Security.NonceVerification.Recommended
- if ( isset( $_GET['events_i_created_paged'] ) ) {
- $value = sanitize_text_field( wp_unslash( $_GET['events_i_created_paged'] ) );
- if ( is_numeric( $value ) ) {
- $_events_i_created_paged = (int) $value;
- }
- }
- if ( isset( $_GET['events_i_attended_paged'] ) ) {
- $value = sanitize_text_field( wp_unslash( $_GET['events_i_attended_paged'] ) );
- if ( is_numeric( $value ) ) {
- $_events_i_attended_paged = (int) $value;
- }
- }
- // phpcs:enable
-
- $user_id = get_current_user_id();
- $events = get_user_meta( $user_id, self::USER_META_KEY_ATTENDING, true ) ?: array();
- $events = array_keys( $events );
- $current_datetime_utc = ( new DateTime( 'now', new DateTimeZone( 'UTC' ) ) )->format( 'Y-m-d H:i:s' );
- $args = array(
- 'post_type' => Translation_Events::CPT,
- 'posts_per_page' => 10,
- 'events_i_created_paged' => $_events_i_created_paged,
- 'paged' => $_events_i_created_paged,
- 'post_status' => array( 'publish', 'draft' ),
- 'author' => $user_id,
- // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
- 'meta_key' => '_event_start',
- 'orderby' => 'meta_value',
- 'order' => 'DESC',
- );
- $events_i_created_query = new WP_Query( $args );
-
- $args = array(
- 'post_type' => Translation_Events::CPT,
- 'posts_per_page' => 10,
- 'events_i_attended_paged' => $_events_i_attended_paged,
- 'paged' => $_events_i_attended_paged,
- 'post_status' => 'publish',
- 'post__in' => $events,
- // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
- 'meta_query' => array(
- array(
- 'key' => '_event_end',
- 'value' => $current_datetime_utc,
- 'compare' => '<',
- 'type' => 'DATETIME',
- ),
- ),
- // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
- 'meta_key' => '_event_end',
- 'orderby' => 'meta_value',
- 'order' => 'DESC',
- );
- $events_i_attended_query = new WP_Query( $args );
-
- $this->tmpl( 'events-my-events', get_defined_vars() );
- }
-
- /**
- * Convert date time stored in UTC to a date time in a time zone.
- *
- * @param string $date_time The date time in UTC.
- * @param string $time_zone The time zone.
- *
- * @return string The date time in the time zone.
- * @throws Exception When date is invalid.
- */
- public static function convertToTimezone( string $date_time, string $time_zone ): string {
- return ( new DateTime( $date_time, new DateTimeZone( 'UTC' ) ) )->setTimezone( new DateTimeZone( $time_zone ) )->format( 'Y-m-d H:i:s' );
- }
-}
</del></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesrouteseventcreatephp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/create.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/create.php (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/create.php 2024-03-07 06:39:00 UTC (rev 13298)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,32 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+namespace Wporg\TranslationEvents\Routes\Event;
+
+use Wporg\TranslationEvents\Routes\Route;
+
+/**
+ * Displays the event create page.
+ */
+class Create_Route extends Route {
+ public function handle(): void {
+ global $wp;
+ if ( ! is_user_logged_in() ) {
+ wp_safe_redirect( wp_login_url( home_url( $wp->request ) ) );
+ exit;
+ }
+ $event_form_title = 'Create Event';
+ $event_form_name = 'create_event';
+ $css_show_url = 'hide-event-url';
+ $event_id = null;
+ $event_title = '';
+ $event_description = '';
+ $event_timezone = '';
+ $event_start = '';
+ $event_end = '';
+ $event_url = '';
+ $create_delete_button = true;
+ $visibility_delete_button = 'none';
+
+ $this->tmpl( 'events-form', get_defined_vars() );
+ }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/create.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesrouteseventdetailsphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/details.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/details.php (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/details.php 2024-03-07 06:39:00 UTC (rev 13298)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,52 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+namespace Wporg\TranslationEvents\Routes\Event;
+
+use Exception;
+use GP;
+use Wporg\TranslationEvents\Routes\Route;
+use Wporg\TranslationEvents\Stats_Calculator;
+use Wporg\TranslationEvents\Translation_Events;
+
+/**
+ * Displays the event details page.
+ */
+class Details_Route extends Route {
+ public function handle( string $event_slug ): void {
+ $user = wp_get_current_user();
+ $event = get_page_by_path( $event_slug, OBJECT, Translation_Events::CPT );
+ if ( ! $event ) {
+ $this->die_with_404();
+ }
+
+ /**
+ * Filter the ability to create, edit, or delete an event.
+ *
+ * @param bool $can_crud_event Whether the user can create, edit, or delete an event.
+ */
+ $can_crud_event = apply_filters( 'gp_translation_events_can_crud_event', GP::$permission->current_user_can( 'admin' ) );
+ if ( 'publish' !== $event->post_status && ! $can_crud_event ) {
+ $this->die_with_error( esc_html__( 'You are not authorized to view this page.', 'gp-translation-events' ), 403 );
+ }
+
+ $event_id = $event->ID;
+ $event_title = $event->post_title;
+ $event_description = $event->post_content;
+ $event_start = get_post_meta( $event->ID, '_event_start', true ) ?: '';
+ $event_end = get_post_meta( $event->ID, '_event_end', true ) ?: '';
+ $attending_event_ids = get_user_meta( $user->ID, Translation_Events::USER_META_KEY_ATTENDING, true ) ?: array();
+ $user_is_attending = isset( $attending_event_ids[ $event_id ] );
+
+ $stats_calculator = new Stats_Calculator();
+ try {
+ $event_stats = $stats_calculator->for_event( $event );
+ $contributors = $stats_calculator->get_contributors( $event );
+ } catch ( Exception $e ) {
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
+ error_log( $e );
+ $this->die_with_error( esc_html__( 'Failed to calculate event stats', 'gp-translation-events' ) );
+ }
+
+ $this->tmpl( 'event', get_defined_vars() );
+ }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/details.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesrouteseventeditphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/edit.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/edit.php (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/edit.php 2024-03-07 06:39:00 UTC (rev 13298)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,76 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+namespace Wporg\TranslationEvents\Routes\Event;
+
+use DateTime;
+use DateTimeZone;
+use Exception;
+use Wporg\TranslationEvents\Routes\Route;
+use Wporg\TranslationEvents\Stats_Calculator;
+use Wporg\TranslationEvents\Translation_Events;
+
+/**
+ * Displays the event edit page.
+ */
+class Edit_Route extends Route {
+ public function handle( int $event_id ): void {
+ global $wp;
+ if ( ! is_user_logged_in() ) {
+ wp_safe_redirect( wp_login_url( home_url( $wp->request ) ) );
+ exit;
+ }
+ $event = get_post( $event_id );
+ if ( ! $event || Translation_Events::CPT !== $event->post_type || ! ( current_user_can( 'edit_post', $event->ID ) || intval( $event->post_author ) === get_current_user_id() ) ) {
+ $this->die_with_error( esc_html__( 'Event does not exist, or you do not have permission to edit it.', 'gp-translation-events' ), 403 );
+ }
+ if ( 'trash' === $event->post_status ) {
+ $this->die_with_error( esc_html__( 'You cannot edit a trashed event', 'gp-translation-events' ), 403 );
+ }
+
+ include ABSPATH . 'wp-admin/includes/post.php';
+ $event_form_title = 'Edit Event';
+ $event_form_name = 'edit_event';
+ $css_show_url = '';
+ $event_title = $event->post_title;
+ $event_description = $event->post_content;
+ $event_status = $event->post_status;
+ list( $permalink, $post_name ) = get_sample_permalink( $event_id );
+ $permalink = str_replace( '%pagename%', $post_name, $permalink );
+ $event_url = get_site_url() . gp_url( wp_make_link_relative( $permalink ) );
+ $event_timezone = get_post_meta( $event_id, '_event_timezone', true ) ?: '';
+ $create_delete_button = false;
+ $visibility_delete_button = 'inline-flex';
+
+ $stats_calculator = new Stats_Calculator();
+ if ( ! $stats_calculator->event_has_stats( $event ) ) {
+ $current_user = wp_get_current_user();
+ if ( $current_user->ID === $event->post_author || current_user_can( 'manage_options' ) ) {
+ $create_delete_button = true;
+ }
+ }
+
+ try {
+ $event_start = self::convertToTimezone( get_post_meta( $event_id, '_event_start', true ), $event_timezone );
+ $event_end = self::convertToTimezone( get_post_meta( $event_id, '_event_end', true ), $event_timezone );
+ } catch ( Exception $e ) {
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
+ error_log( $e );
+ $this->die_with_error( esc_html__( 'Something is wrong.', 'gp-translation-events' ) );
+ }
+
+ $this->tmpl( 'events-form', get_defined_vars() );
+ }
+
+ /**
+ * Convert date time stored in UTC to a date time in a time zone.
+ *
+ * @param string $date_time The date time in UTC.
+ * @param string $time_zone The time zone.
+ *
+ * @return string The date time in the time zone.
+ * @throws Exception When date is invalid.
+ */
+ private static function convertToTimezone( string $date_time, string $time_zone ): string {
+ return ( new DateTime( $date_time, new DateTimeZone( 'UTC' ) ) )->setTimezone( new DateTimeZone( $time_zone ) )->format( 'Y-m-d H:i:s' );
+ }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/edit.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesrouteseventlistphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/list.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/list.php (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/list.php 2024-03-07 06:39:00 UTC (rev 13298)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,146 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+namespace Wporg\TranslationEvents\Routes\Event;
+
+use DateTime;
+use DateTimeZone;
+use Exception;
+use WP_Query;
+use Wporg\TranslationEvents\Routes\Route;
+use Wporg\TranslationEvents\Translation_Events;
+
+/**
+ * Displays the event list page.
+ */
+class List_Route extends Route {
+ public function handle(): void {
+ $current_datetime_utc = null;
+ try {
+ $current_datetime_utc = ( new DateTime( 'now', new DateTimeZone( 'UTC' ) ) )->format( 'Y-m-d H:i:s' );
+ } catch ( Exception $e ) {
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
+ error_log( $e );
+ $this->die_with_error( esc_html__( 'Something is wrong.', 'gp-translation-events' ) );
+ }
+
+ $_current_events_paged = 1;
+ $_upcoming_events_paged = 1;
+ $_past_events_paged = 1;
+ $_user_attending_events_paged = 1;
+
+ // phpcs:disable WordPress.Security.NonceVerification.Recommended
+ if ( isset( $_GET['current_events_paged'] ) ) {
+ $value = sanitize_text_field( wp_unslash( $_GET['current_events_paged'] ) );
+ if ( is_numeric( $value ) ) {
+ $_current_events_paged = (int) $value;
+ }
+ }
+ if ( isset( $_GET['upcoming_events_paged'] ) ) {
+ $value = sanitize_text_field( wp_unslash( $_GET['upcoming_events_paged'] ) );
+ if ( is_numeric( $value ) ) {
+ $_upcoming_events_paged = (int) $value;
+ }
+ }
+ if ( isset( $_GET['past_events_paged'] ) ) {
+ $value = sanitize_text_field( wp_unslash( $_GET['past_events_paged'] ) );
+ if ( is_numeric( $value ) ) {
+ $_past_events_paged = (int) $value;
+ }
+ }
+ if ( isset( $_GET['user_attending_events_paged'] ) ) {
+ $value = sanitize_text_field( wp_unslash( $_GET['user_attending_events_paged'] ) );
+ if ( is_numeric( $value ) ) {
+ $_user_attending_events_paged = (int) $value;
+ }
+ }
+ // phpcs:enable
+
+ $current_events_args = array(
+ 'post_type' => Translation_Events::CPT,
+ 'posts_per_page' => 10,
+ 'paged' => $_current_events_paged,
+ 'post_status' => 'publish',
+ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
+ 'meta_query' => array(
+ array(
+ 'key' => '_event_start',
+ 'value' => $current_datetime_utc,
+ 'compare' => '<=',
+ 'type' => 'DATETIME',
+ ),
+ array(
+ 'key' => '_event_end',
+ 'value' => $current_datetime_utc,
+ 'compare' => '>=',
+ 'type' => 'DATETIME',
+ ),
+ ),
+ 'orderby' => 'meta_value',
+ 'order' => 'ASC',
+ );
+ $current_events_query = new WP_Query( $current_events_args );
+
+ $upcoming_events_args = array(
+ 'post_type' => Translation_Events::CPT,
+ 'posts_per_page' => 10,
+ 'paged' => $_upcoming_events_paged,
+ 'post_status' => 'publish',
+ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
+ 'meta_query' => array(
+ array(
+ 'key' => '_event_start',
+ 'value' => $current_datetime_utc,
+ 'compare' => '>=',
+ 'type' => 'DATETIME',
+ ),
+ ),
+ 'orderby' => 'meta_value',
+ 'order' => 'ASC',
+ );
+ $upcoming_events_query = new WP_Query( $upcoming_events_args );
+
+ $past_events_args = array(
+ 'post_type' => Translation_Events::CPT,
+ 'posts_per_page' => 10,
+ 'paged' => $_past_events_paged,
+ 'post_status' => 'publish',
+ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
+ 'meta_query' => array(
+ array(
+ 'key' => '_event_end',
+ 'value' => $current_datetime_utc,
+ 'compare' => '<',
+ 'type' => 'DATETIME',
+ ),
+ ),
+ 'orderby' => 'meta_value',
+ 'order' => 'ASC',
+ );
+ $past_events_query = new WP_Query( $past_events_args );
+
+ $user_attending_events = get_user_meta( get_current_user_id(), Translation_Events::USER_META_KEY_ATTENDING, true ) ?: array( 0 );
+ $user_attending_events_args = array(
+ 'post_type' => Translation_Events::CPT,
+ 'post__in' => array_keys( $user_attending_events ),
+ 'posts_per_page' => 10,
+ 'paged' => $_user_attending_events_paged,
+ 'post_status' => 'publish',
+ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
+ 'meta_query' => array(
+ array(
+ 'key' => '_event_end',
+ 'value' => $current_datetime_utc,
+ 'compare' => '>',
+ 'type' => 'DATETIME',
+ ),
+ ),
+ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
+ 'meta_key' => '_event_start',
+ 'orderby' => 'meta_value',
+ 'order' => 'ASC',
+ );
+ $user_attending_events_query = new WP_Query( $user_attending_events_args );
+
+ $this->tmpl( 'events-list', get_defined_vars() );
+ }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/event/list.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesroutesroutephp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/route.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/route.php (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/route.php 2024-03-07 06:39:00 UTC (rev 13298)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,12 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+namespace Wporg\TranslationEvents\Routes;
+
+use GP_Route;
+
+abstract class Route extends GP_Route {
+ public function __construct() {
+ parent::__construct();
+ $this->template_path = __DIR__ . '/../../templates/';
+ }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/route.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesroutesuserattendeventphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/user/attend-event.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/user/attend-event.php (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/user/attend-event.php 2024-03-07 06:39:00 UTC (rev 13298)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,44 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+namespace Wporg\TranslationEvents\Routes\User;
+
+use Wporg\TranslationEvents\Routes\Route;
+use Wporg\TranslationEvents\Translation_Events;
+
+/**
+ * Toggle whether the current user is attending an event.
+ * If the user is not currently marked as attending, they will be marked as attending.
+ * If the user is currently marked as attending, they will be marked as not attending.
+ */
+class Attend_Event_Route extends Route {
+ public function handle( int $event_id ): void {
+ $user = wp_get_current_user();
+ if ( ! $user ) {
+ $this->die_with_error( esc_html__( 'Only logged-in users can attend events', 'gp-translation-events' ), 403 );
+ }
+
+ $event = get_post( $event_id );
+
+ if ( ! $event ) {
+ $this->die_with_404();
+ }
+
+ $event_ids = get_user_meta( $user->ID, Translation_Events::USER_META_KEY_ATTENDING, true ) ?? array();
+ if ( ! $event_ids ) {
+ $event_ids = array();
+ }
+
+ if ( ! isset( $event_ids[ $event_id ] ) ) {
+ // Not yet attending, mark as attending.
+ $event_ids[ $event_id ] = true;
+ } else {
+ // Currently attending, mark as not attending.
+ unset( $event_ids[ $event_id ] );
+ }
+
+ update_user_meta( $user->ID, Translation_Events::USER_META_KEY_ATTENDING, $event_ids );
+
+ wp_safe_redirect( gp_url( "/events/$event->post_name" ) );
+ exit;
+ }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/user/attend-event.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesroutesusermyeventsphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/user/my-events.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/user/my-events.php (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/user/my-events.php 2024-03-07 06:39:00 UTC (rev 13298)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,84 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+namespace Wporg\TranslationEvents\Routes\User;
+
+use DateTime;
+use DateTimeZone;
+use WP_Query;
+use Wporg\TranslationEvents\Routes\Route;
+use Wporg\TranslationEvents\Translation_Events;
+
+/**
+ * Displays the My Events page for a user.
+ */
+class My_Events_Route extends Route {
+ public function handle(): void {
+ global $wp;
+ if ( ! is_user_logged_in() ) {
+ wp_safe_redirect( wp_login_url( home_url( $wp->request ) ) );
+ exit;
+ }
+ include ABSPATH . 'wp-admin/includes/post.php';
+
+ $_events_i_created_paged = 1;
+ $_events_i_attended_paged = 1;
+
+ // phpcs:disable WordPress.Security.NonceVerification.Recommended
+ if ( isset( $_GET['events_i_created_paged'] ) ) {
+ $value = sanitize_text_field( wp_unslash( $_GET['events_i_created_paged'] ) );
+ if ( is_numeric( $value ) ) {
+ $_events_i_created_paged = (int) $value;
+ }
+ }
+ if ( isset( $_GET['events_i_attended_paged'] ) ) {
+ $value = sanitize_text_field( wp_unslash( $_GET['events_i_attended_paged'] ) );
+ if ( is_numeric( $value ) ) {
+ $_events_i_attended_paged = (int) $value;
+ }
+ }
+ // phpcs:enable
+
+ $user_id = get_current_user_id();
+ $events = get_user_meta( $user_id, Translation_Events::USER_META_KEY_ATTENDING, true ) ?: array();
+ $events = array_keys( $events );
+ $current_datetime_utc = ( new DateTime( 'now', new DateTimeZone( 'UTC' ) ) )->format( 'Y-m-d H:i:s' );
+ $args = array(
+ 'post_type' => Translation_Events::CPT,
+ 'posts_per_page' => 10,
+ 'events_i_created_paged' => $_events_i_created_paged,
+ 'paged' => $_events_i_created_paged,
+ 'post_status' => array( 'publish', 'draft' ),
+ 'author' => $user_id,
+ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
+ 'meta_key' => '_event_start',
+ 'orderby' => 'meta_value',
+ 'order' => 'DESC',
+ );
+ $events_i_created_query = new WP_Query( $args );
+
+ $args = array(
+ 'post_type' => Translation_Events::CPT,
+ 'posts_per_page' => 10,
+ 'events_i_attended_paged' => $_events_i_attended_paged,
+ 'paged' => $_events_i_attended_paged,
+ 'post_status' => 'publish',
+ 'post__in' => $events,
+ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
+ 'meta_query' => array(
+ array(
+ 'key' => '_event_end',
+ 'value' => $current_datetime_utc,
+ 'compare' => '<',
+ 'type' => 'DATETIME',
+ ),
+ ),
+ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
+ 'meta_key' => '_event_end',
+ 'orderby' => 'meta_value',
+ 'order' => 'DESC',
+ );
+ $events_i_attended_query = new WP_Query( $args );
+
+ $this->tmpl( 'events-my-events', get_defined_vars() );
+ }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/routes/user/my-events.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesstatscalculatorphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/stats-calculator.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/stats-calculator.php 2024-03-07 04:39:31 UTC (rev 13297)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/stats-calculator.php 2024-03-07 06:39:00 UTC (rev 13298)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4,16 +4,21 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> use Exception;
</span><span class="cx" style="display: block; padding: 0 10px"> use WP_Post;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+use WP_User;
+use GP_Locale;
+use GP_Locales;
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> class Stats_Row {
</span><span class="cx" style="display: block; padding: 0 10px"> public int $created;
</span><span class="cx" style="display: block; padding: 0 10px"> public int $reviewed;
</span><span class="cx" style="display: block; padding: 0 10px"> public int $users;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public ?GP_Locale $language = null;
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function __construct( $created, $reviewed, $users ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function __construct( $created, $reviewed, $users, ?GP_Locale $language = null ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->created = $created;
</span><span class="cx" style="display: block; padding: 0 10px"> $this->reviewed = $reviewed;
</span><span class="cx" style="display: block; padding: 0 10px"> $this->users = $users;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->language = $language;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -49,6 +54,23 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @return Stats_Row[]
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function rows(): array {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ uasort(
+ $this->rows,
+ function ( $a, $b ) {
+ if ( ! $a->language && ! $b->language ) {
+ return 0;
+ }
+ if ( ! $a->language ) {
+ return -1;
+ }
+ if ( ! $b->language ) {
+ return 1;
+ }
+
+ return strcasecmp( $a->language->english_name, $b->language->english_name );
+ }
+ );
+
</ins><span class="cx" style="display: block; padding: 0 10px"> return $this->rows;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -100,10 +122,16 @@
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $lang = GP_Locales::by_slug( $row->locale );
+ if ( ! $lang ) {
+ $lang = null;
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> $stats_row = new Stats_Row(
</span><span class="cx" style="display: block; padding: 0 10px"> $row->created,
</span><span class="cx" style="display: block; padding: 0 10px"> $row->total - $row->created,
</span><span class="cx" style="display: block; padding: 0 10px"> $row->users,
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $lang
</ins><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ( ! $is_totals ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -117,6 +145,49 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Get contributors for an event.
+ */
+ public function get_contributors( WP_Post $event ): array {
+ global $wpdb, $gp_table_prefix;
+
+ // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
+ // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
+ // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching
+ // phpcs thinks we're doing a schema change but we aren't.
+ // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange
+ $rows = $wpdb->get_results(
+ $wpdb->prepare(
+ "
+ select user_id, group_concat( distinct locale ) as locales
+ from {$gp_table_prefix}event_actions
+ where event_id = %d
+ group by user_id
+ ",
+ array(
+ $event->ID,
+ )
+ )
+ );
+ // phpcs:enable
+
+ $users = array();
+ foreach ( $rows as $row ) {
+ $user = new WP_User( $row->user_id );
+ $user->locales = explode( ',', $row->locales );
+ $users[] = $user;
+ }
+
+ uasort(
+ $users,
+ function ( $a, $b ) {
+ return strcasecmp( $a->display_name, $b->display_name );
+ }
+ );
+
+ return $users;
+ }
+
+ /**
</ins><span class="cx" style="display: block; padding: 0 10px"> * Check if an event has stats.
</span><span class="cx" style="display: block; padding: 0 10px"> *
</span><span class="cx" style="display: block; padding: 0 10px"> * @param WP_Post $event The event to check.
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventsincludesstatslistenerphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/stats-listener.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/stats-listener.php 2024-03-07 04:39:31 UTC (rev 13297)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/includes/stats-listener.php 2024-03-07 06:39:00 UTC (rev 13298)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -25,6 +25,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 'gp_translation_created',
</span><span class="cx" style="display: block; padding: 0 10px"> function ( $translation ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $happened_at = DateTimeImmutable::createFromFormat( 'Y-m-d H:i:s', $translation->date_added, new DateTimeZone( 'UTC' ) );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! $translation->user_id ) {
+ return;
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->handle_action( $translation, $translation->user_id, self::ACTION_CREATE, $happened_at );
</span><span class="cx" style="display: block; padding: 0 10px"> },
</span><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -54,7 +57,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ( $action ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( $action && $user_id ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->handle_action( $translation, $user_id, $action, $happened_at );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> },
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -65,9 +68,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> private function handle_action( GP_Translation $translation, int $user_id, string $action, DateTimeImmutable $happened_at ): void {
</span><span class="cx" style="display: block; padding: 0 10px"> try {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ( ! $user_id ) {
- return;
- }
</del><span class="cx" style="display: block; padding: 0 10px"> // Get events that are active when the action happened, for which the user is registered for.
</span><span class="cx" style="display: block; padding: 0 10px"> $active_events = $this->get_active_events( $happened_at );
</span><span class="cx" style="display: block; padding: 0 10px"> $events = $this->select_events_user_is_registered_for( $active_events, $user_id );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -171,7 +171,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
</span><span class="cx" style="display: block; padding: 0 10px"> // phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.Found
</span><span class="cx" style="display: block; padding: 0 10px"> private function select_events_user_is_registered_for( array $events, int $user_id ): array {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $attending_event_ids = get_user_meta( $user_id, Route::USER_META_KEY_ATTENDING, true );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $attending_event_ids = get_user_meta( $user_id, Translation_Events::USER_META_KEY_ATTENDING, true );
</ins><span class="cx" style="display: block; padding: 0 10px"> return array_filter(
</span><span class="cx" style="display: block; padding: 0 10px"> $events,
</span><span class="cx" style="display: block; padding: 0 10px"> function ( Event $event ) use ( $attending_event_ids ) {
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventstemplateseventphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/event.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/event.php 2024-03-07 04:39:31 UTC (rev 13297)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/templates/event.php 2024-03-07 06:39:00 UTC (rev 13298)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -46,7 +46,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> </div>
</span><span class="cx" style="display: block; padding: 0 10px"> <?php if ( ! empty( $event_stats->rows() ) ) : ?>
</span><span class="cx" style="display: block; padding: 0 10px"> <div class="event-details-stats">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- <h2>Stats</h2>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ <h2><?php esc_html_e( 'Stats', 'gp-translation-events' ); ?></h2>
</ins><span class="cx" style="display: block; padding: 0 10px"> <table>
</span><span class="cx" style="display: block; padding: 0 10px"> <thead>
</span><span class="cx" style="display: block; padding: 0 10px"> <tr>
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -58,9 +58,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> </thead>
</span><span class="cx" style="display: block; padding: 0 10px"> <tbody>
</span><span class="cx" style="display: block; padding: 0 10px"> <?php /** @var $row Stats_Row */ ?>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- <?php foreach ( $event_stats->rows() as $locale_ => $row ) : ?>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ <?php foreach ( $event_stats->rows() as $_locale => $row ) : ?>
</ins><span class="cx" style="display: block; padding: 0 10px"> <tr>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- <td><?php echo esc_html( $locale_ ); ?></td>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ <td title="<?php echo esc_html( $_locale ); ?> "><a href="<?php echo esc_url( gp_url_join( gp_url( '/languages' ), $row->language->slug ) ); ?>"><?php echo esc_html( $row->language->english_name ); ?></a></td>
</ins><span class="cx" style="display: block; padding: 0 10px"> <td><?php echo esc_html( $row->created ); ?></td>
</span><span class="cx" style="display: block; padding: 0 10px"> <td><?php echo esc_html( $row->reviewed ); ?></td>
</span><span class="cx" style="display: block; padding: 0 10px"> <td><?php echo esc_html( $row->users ); ?></td>
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -75,11 +75,70 @@
</span><span class="cx" style="display: block; padding: 0 10px"> </tbody>
</span><span class="cx" style="display: block; padding: 0 10px"> </table>
</span><span class="cx" style="display: block; padding: 0 10px"> </div>
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ <div class="event-contributors">
+ <h2><?php esc_html_e( 'Contributors', 'gp-translation-events' ); ?></h2>
+ <ul>
+ <?php foreach ( $contributors as $contributor ) : ?>
+ <li class="event-contributor" title="<?php echo esc_html( implode( ', ', $contributor->locales ) ); ?>"
+ <a href="<?php echo esc_url( get_author_posts_url( $contributor->ID ) ); ?>"><?php echo get_avatar( $contributor->ID, 48 ); ?></a>
+ <a href="<?php echo esc_url( get_author_posts_url( $contributor->ID ) ); ?>"><?php echo esc_html( get_the_author_meta( 'display_name', $contributor->ID ) ); ?></a>
+ </li>
+ <?php endforeach; ?>
+ </ul>
+ </div>
</ins><span class="cx" style="display: block; padding: 0 10px"> <details class="event-stats-summary">
</span><span class="cx" style="display: block; padding: 0 10px"> <summary>View stats summary in text </summary>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- <p class="event-stats-text"><?php echo esc_html( sprintf( 'At the %s event, %d people contributed in %d languages (%s), translated %d strings and reviewed %d strings.', esc_html( $event_title ), esc_html( $event_stats->totals()->users ), count( $event_stats->rows() ), esc_html( implode( ',', array_keys( $event_stats->rows() ) ) ), esc_html( $event_stats->totals()->created ), esc_html( $event_stats->totals()->reviewed ) ) ); ?></p>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ <p class="event-stats-text">
+ <?php
+ echo wp_kses(
+ sprintf(
+ // translators: %1$s: Event title, %2$d: Number of contributors, %3$d: Number of languages, %4$s: List of languages, %5$d: Number of strings translated, %6$d: Number of strings reviewed.
+ __( 'At the <strong>%1$s</strong> event, %2$d people contributed in %3$d languages (%4$s), translated %5$d strings and reviewed %6$d strings.', 'gp-translation-events' ),
+ esc_html( $event_title ),
+ esc_html( $event_stats->totals()->users ),
+ count( $event_stats->rows() ),
+ esc_html(
+ implode(
+ ', ',
+ array_map(
+ function ( $row ) {
+ return $row->language->english_name;
+ },
+ $event_stats->rows()
+ )
+ )
+ ),
+ esc_html( $event_stats->totals()->created ),
+ esc_html( $event_stats->totals()->reviewed )
+ ),
+ array(
+ 'strong' => array(),
+ )
+ );
+ ?>
+ <?php
+ echo esc_html(
+ sprintf(
+ // translators: %s the contributors.
+ __( 'Contributors were %s.', 'gp-translation-events' ),
+ esc_html(
+ implode(
+ ', ',
+ array_map(
+ function ( $contributor ) {
+ return '@' . $contributor->user_login;
+ },
+ $contributors
+ )
+ )
+ )
+ )
+ );
+ ?>
+ </p>
</ins><span class="cx" style="display: block; padding: 0 10px"> </details>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- <?php endif ?>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+ <?php endif; ?>
</ins><span class="cx" style="display: block; padding: 0 10px"> </div>
</span><span class="cx" style="display: block; padding: 0 10px"> <div class="event-details-right">
</span><span class="cx" style="display: block; padding: 0 10px"> <div class="event-details-date">
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginswporggptranslationeventswporggptranslationeventsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/wporg-gp-translation-events.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/wporg-gp-translation-events.php 2024-03-07 04:39:31 UTC (rev 13297)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-events/wporg-gp-translation-events.php 2024-03-07 06:39:00 UTC (rev 13298)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -26,7 +26,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> use WP_Query;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> class Translation_Events {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- const CPT = 'translation_event';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public const CPT = 'translation_event';
+ public const USER_META_KEY_ATTENDING = 'translation-events-attending';
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> public static function get_instance() {
</span><span class="cx" style="display: block; padding: 0 10px"> static $instance = null;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -55,16 +56,22 @@
</span><span class="cx" style="display: block; padding: 0 10px"> require_once __DIR__ . '/templates/helper-functions.php';
</span><span class="cx" style="display: block; padding: 0 10px"> require_once __DIR__ . '/includes/active-events-cache.php';
</span><span class="cx" style="display: block; padding: 0 10px"> require_once __DIR__ . '/includes/event.php';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- require_once __DIR__ . '/includes/route.php';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ require_once __DIR__ . '/includes/routes/route.php';
+ require_once __DIR__ . '/includes/routes/event/create.php';
+ require_once __DIR__ . '/includes/routes/event/details.php';
+ require_once __DIR__ . '/includes/routes/event/edit.php';
+ require_once __DIR__ . '/includes/routes/event/list.php';
+ require_once __DIR__ . '/includes/routes/user/attend-event.php';
+ require_once __DIR__ . '/includes/routes/user/my-events.php';
</ins><span class="cx" style="display: block; padding: 0 10px"> require_once __DIR__ . '/includes/stats-calculator.php';
</span><span class="cx" style="display: block; padding: 0 10px"> require_once __DIR__ . '/includes/stats-listener.php';
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- GP::$router->add( '/events?', array( 'Wporg\TranslationEvents\Route', 'events_list' ) );
- GP::$router->add( '/events/new', array( 'Wporg\TranslationEvents\Route', 'events_create' ) );
- GP::$router->add( '/events/edit/(\d+)', array( 'Wporg\TranslationEvents\Route', 'events_edit' ) );
- GP::$router->add( '/events/attend/(\d+)', array( 'Wporg\TranslationEvents\Route', 'events_attend' ), 'post' );
- GP::$router->add( '/events/my-events', array( 'Wporg\TranslationEvents\Route', 'my_events' ) );
- GP::$router->add( '/events/([a-z0-9_-]+)', array( 'Wporg\TranslationEvents\Route', 'events_details' ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ GP::$router->add( '/events?', array( 'Wporg\TranslationEvents\Routes\Event\List_Route', 'handle' ) );
+ GP::$router->add( '/events/new', array( 'Wporg\TranslationEvents\Routes\Event\Create_Route', 'handle' ) );
+ GP::$router->add( '/events/edit/(\d+)', array( 'Wporg\TranslationEvents\Routes\Event\Edit_Route', 'handle' ) );
+ GP::$router->add( '/events/attend/(\d+)', array( 'Wporg\TranslationEvents\Routes\User\Attend_Event_Route', 'handle' ), 'post' );
+ GP::$router->add( '/events/my-events', array( 'Wporg\TranslationEvents\Routes\User\My_Events_Route', 'handle' ) );
+ GP::$router->add( '/events/([a-z0-9_-]+)', array( 'Wporg\TranslationEvents\Routes\Event\Details_Route', 'handle' ) );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $active_events_cache = new Active_Events_Cache();
</span><span class="cx" style="display: block; padding: 0 10px"> $stats_listener = new Stats_Listener( $active_events_cache );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -399,12 +406,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if ( 'publish' === $new_status && ( 'new' === $old_status || 'draft' === $old_status ) ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $current_user_id = get_current_user_id();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $user_attending_events = get_user_meta( $current_user_id, Route::USER_META_KEY_ATTENDING, true ) ?: array();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $user_attending_events = get_user_meta( $current_user_id, self::USER_META_KEY_ATTENDING, true ) ?: array();
</ins><span class="cx" style="display: block; padding: 0 10px"> $is_user_attending_event = in_array( $post->ID, $user_attending_events, true );
</span><span class="cx" style="display: block; padding: 0 10px"> if ( ! $is_user_attending_event ) {
</span><span class="cx" style="display: block; padding: 0 10px"> $new_user_attending_events = $user_attending_events;
</span><span class="cx" style="display: block; padding: 0 10px"> $new_user_attending_events[ $post->ID ] = true;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- update_user_meta( $current_user_id, Route::USER_META_KEY_ATTENDING, $new_user_attending_events, $user_attending_events );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ update_user_meta( $current_user_id, self::USER_META_KEY_ATTENDING, $new_user_attending_events, $user_attending_events );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -461,7 +468,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * @return void
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> public function add_active_events_current_user(): void {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $user_attending_events = get_user_meta( get_current_user_id(), Route::USER_META_KEY_ATTENDING, true ) ?: array();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $user_attending_events = get_user_meta( get_current_user_id(), self::USER_META_KEY_ATTENDING, true ) ?: array();
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( empty( $user_attending_events ) ) {
</span><span class="cx" style="display: block; padding: 0 10px"> return;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre>
</div>
</div>
</body>
</html>