<!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>[8980] sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins: WordCamp Helpers: Rename to load earlier.</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/8980">8980</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/8980","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>iandunn</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2019-06-20 20:24:08 +0000 (Thu, 20 Jun 2019)</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'>WordCamp Helpers: Rename to load earlier.

Other mu-plugins depend on these, so they should load early to ensure they're always available, rather than relying on alphabetical happenstance.</pre>

<h3>Added Paths</h3>
<ul>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentmuplugins3helpersmiscphp">sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/3-helpers-misc.php</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentmuplugins4helperswcptphp">sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/4-helpers-wcpt.php</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentmupluginshelpersmiscphp">sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/helpers-misc.php</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentmupluginshelperswcptphp">sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/helpers-wcpt.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentmuplugins3helpersmiscphpfromrev8979sitestrunkwordcamporgpublic_htmlwpcontentmupluginshelpersmiscphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/3-helpers-misc.php (from rev 8979, sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/helpers-misc.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/3-helpers-misc.php                             (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/3-helpers-misc.php       2019-06-20 20:24:08 UTC (rev 8980)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,131 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+defined( 'WPINC' ) or die();
+use function WordCamp\Logger\log;
+
+/*
+ * Miscellaneous helper functions.
+ */
+
+
+/**
+ * Determine if a specific feature should be skipped on the current site
+ *
+ * Warning: Pay careful attention to how things are named, since setting a flag here is typically done when you
+ * want a feature to be _enabled_ by default on new sites. In the cases where you want it _disabled_ by default
+ * on new sites, you can reverse the name (e.g., `local_terms` instead of `global_terms` for the
+ * `global_terms_enabled` callback).
+ *
+ * Often times we want to add new functionality to plugins and themes, but can't let it run on older sites
+ * because that would break backwards compatibility. To get around that, we set a flag on older sites to
+ * indicate that they should not have the new feature, and then setup the feature to run on sites that
+ * don't have the flag, i.e., to run by default.
+ *
+ * Doing it this way means that local development environments like the Meta Environment don't to have add any
+ * new filters in order to start using the new functionality.
+ *
+ * See WordCamp_CLI_Miscellaneous::set_skip_feature_flag() for how to set the flags.
+ *
+ * @param string $flag
+ *
+ * @return bool
+ */
+function wcorg_skip_feature( $flag ) {
+       $flags = get_option( 'wordcamp_skip_features', array() );
+
+       return isset( $flags[ $flag ] );
+}
+
+/**
+ * Get a user by the username or nicename
+ *
+ * Note: This intentionally doesn't lookup users by the display name or nickname, because those can be set by the
+ * user, which could result in false-positive matches.
+ *
+ * @param string $name
+ *
+ * @return false|WP_User
+ */
+function wcorg_get_user_by_canonical_names( $name ) {
+       if ( ! $user = get_user_by( 'login', $name ) ) {    // user_login
+               $user = get_user_by( 'slug', $name );           // user_nicename
+       }
+
+       return $user;
+}
+
+/**
+ * Get ISO-3166 country names and codes
+ *
+ * @todo move the real functionality from get_valid_countries_iso3166() to here, then have the Budgets plugin,
+ * QBO, etc call this.
+ *
+ * @return array
+ */
+function wcorg_get_countries() {
+       require_once( WP_PLUGIN_DIR . '/wordcamp-payments/includes/wordcamp-budgets.php' );
+
+       return WordCamp_Budgets::get_valid_countries_iso3166();
+}
+
+/**
+ * Make a remote HTTP request, and retry if it fails
+ *
+ * Sometimes the HTTP request times out, or there's a temporary server-side error, etc. Some use cases require a
+ * successful request, like stats scripts, where the resulting data would be distorted by a failed response.
+ *
+ * @todo Add support for wp_remote_post() too
+ * @todo Remove this if https://github.com/rmccue/Requests/issues/222 is implemented
+ * @todo maybe `set_time_limit( absint( ini_get( 'max_execution_time' ) ) + $retry_after );` before sleep()'ing to
+ *       avoid php timeout
+ *
+ * @param string $request_url
+ * @param array  $request_args
+ *
+ * @return array|WP_Error
+ */
+function wcorg_redundant_remote_get( $request_url, $request_args = array() ) {
+       $attempt_count = 1;
+
+       while ( true ) {
+               $response    = wp_remote_get( $request_url, $request_args );
+               $status_code = wp_remote_retrieve_response_code( $response );
+               $body        = wp_remote_retrieve_body( $response );
+               $retry_after = wp_remote_retrieve_header( $response, 'retry-after' ) ?: 5;
+               $retry_after = min( $retry_after * $attempt_count, 30 );
+
+               if ( ! is_wp_error( $response ) && 200 === $status_code && $body ) {
+                       break;
+               }
+
+               if ( $attempt_count < 3 ) {
+                       log( 'request_failed_temporarily', compact( 'request_url', 'request_args', 'response', 'attempt_count', 'retry_after' ) );
+                       sleep( $retry_after );
+               } else {
+                       log( 'request_failed_permenantly', compact( 'request_url', 'request_args', 'response' ) );
+                       break;
+               }
+
+               $attempt_count++;
+       }
+
+       return $response;
+}
+
+/**
+ * Display the indicator that marks a form field as required
+ */
+function wcorg_required_indicator() {
+       ?>
+
+       <span class="wcorg-required" aria-hidden="true">
+               <?php // translators: The symbol to indicate the form field is required ?>
+               <?php _e( '*', 'wordcamporg' ); ?>
+       </span>
+
+       <span class="screen-reader-text">
+               <?php _e( 'required field', 'wordcamporg' ); ?>
+       </span>
+
+       <?php
+}
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentmuplugins4helperswcptphpfromrev8979sitestrunkwordcamporgpublic_htmlwpcontentmupluginshelperswcptphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/4-helpers-wcpt.php (from rev 8979, sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/helpers-wcpt.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/4-helpers-wcpt.php                             (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/4-helpers-wcpt.php       2019-06-20 20:24:08 UTC (rev 8980)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,254 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+defined( 'WPINC' ) or die();
+
+/*
+ * Helper functions related to the `wordcamp` post type.
+ */
+
+
+/**
+ * Retrieve `wordcamp` posts and their metadata.
+ *
+ * @param array $args Optional. Extra arguments to pass to `get_posts()`.
+ *
+ * @return array
+ */
+function get_wordcamps( $args = array() ) {
+       $args = wp_parse_args( $args, array(
+               'post_type'   => WCPT_POST_TYPE_ID,
+               'post_status' => 'any',
+               'orderby'     => 'ID',
+               'numberposts' => -1,
+               'perm'        => 'readable',
+       ) );
+
+       $wordcamps = get_posts( $args );
+
+       foreach ( $wordcamps as &$wordcamp ) {
+               $wordcamp->meta = get_post_custom( $wordcamp->ID );
+       }
+
+       return $wordcamps;
+}
+
+/**
+ * Retrieves the `wordcamp` post and postmeta associated with the current site.
+ *
+ * `Site ID` is the most reliable way to associate a site with it's corresponding `wordcamp` post,
+ * but wasn't historically assigned when new sites are created. For older sites, we fallback to
+ * using the `URL` to associate them. That will only work if the site's site_url() exactly
+ * matches the `wordcamp` post's `URL` meta field, though. It could also fail if we ever migrate
+ * to a different URL structure.
+ *
+ * @return false|WP_Post
+ */
+function get_wordcamp_post() {
+       $current_site_id  = get_current_blog_id();
+       $current_site_url = site_url();
+
+       switch_to_blog( BLOG_ID_CURRENT_SITE ); // central.wordcamp.org
+
+       $wordcamp = get_posts( array(
+               'post_type'   => 'wordcamp',
+               'post_status' => 'any',
+
+               'meta_query' => array(
+                       'relation' => 'OR',
+
+                       array(
+                               'key'   => '_site_id',
+                               'value' => $current_site_id,
+                       ),
+
+                       array(
+                               'key'   => 'URL',
+                               'value' => $current_site_url,
+                       ),
+               ),
+       ) );
+
+       if ( isset( $wordcamp[0]->ID ) ) {
+               $wordcamp       = $wordcamp[0];
+               $wordcamp->meta = get_post_custom( $wordcamp->ID );
+       } else {
+               $wordcamp = false;
+       }
+
+       restore_current_blog();
+
+       return $wordcamp;
+}
+
+/**
+ * Find the site that corresponds to the given `wordcamp` post
+ *
+ * @param WP_Post $wordcamp_post
+ *
+ * @return mixed An integer if successful, or boolean false if failed
+ */
+function get_wordcamp_site_id( $wordcamp_post ) {
+       switch_to_blog( BLOG_ID_CURRENT_SITE ); // central.wordcamp.org
+
+       if ( ! $site_id = get_post_meta( $wordcamp_post->ID, '_site_id', true ) ) {
+               $url = parse_url( get_post_meta( $wordcamp_post->ID, 'URL', true ) );
+
+               if ( isset( $url['host'] ) && isset( $url['path'] ) ) {
+                       if ( $site = get_site_by_path( $url['host'], $url['path'] ) ) {
+                               $site_id = $site->blog_id;
+                       }
+               }
+       }
+
+       restore_current_blog();
+
+       return $site_id;
+}
+
+/**
+ * Get a consistent WordCamp name in the 'WordCamp [Location] [Year]' format.
+ *
+ * The results of bloginfo( 'name' ) don't always contain the year, but the title of the site's corresponding
+ * `wordcamp` post is usually named 'WordCamp [Location]', so we can get a consistent name most of the time
+ * by using that and adding the year (if available).
+ *
+ * @param int $site_id Optionally, get the name for a site other than the current one.
+ *
+ * @return string
+ */
+function get_wordcamp_name( $site_id = 0 ) {
+       $name = false;
+
+       switch_to_blog( $site_id );
+
+       if ( $wordcamp = get_wordcamp_post() ) {
+               if ( ! empty( $wordcamp->meta['Start Date (YYYY-mm-dd)'][0] ) ) {
+                       $name = $wordcamp->post_title . ' ' . date( 'Y', $wordcamp->meta['Start Date (YYYY-mm-dd)'][0] );
+               }
+       }
+
+       if ( ! $name ) {
+               $name = get_bloginfo( 'name' );
+       }
+
+       restore_current_blog();
+
+       return $name;
+}
+
+
+/**
+ * Extract pieces from a WordCamp.org URL
+ *
+ * @todo find other code that's doing this same task in an ad-hoc manner, and convert it to use this instead
+ *
+ * @param string $url
+ * @param string $part 'city', 'city-domain' (without the year, e.g. seattle.wordcamp.org), 'year'
+ *
+ * @return false|string|int False on errors; an integer for years; a string for city and city-domain
+ */
+function wcorg_get_url_part( $url, $part ) {
+       $url_parts = explode( '.', parse_url( $url, PHP_URL_HOST ) );
+       $result    = false;
+
+       // Make sure it matches the typical year.city.wordcamp.org structure
+       if ( 4 !== count( $url_parts ) ) {
+               return $result;
+       }
+
+       switch ( $part ) {
+               case 'city':
+                       $result = $url_parts[1];
+                       break;
+
+               case 'city-domain':
+                       $result = ltrim( strstr( $url, '.' ), '.' );
+                       break;
+
+               case 'year':
+                       $result = absint( $url_parts[0] );
+                       break;
+       }
+
+       return $result;
+}
+
+
+/**
+ * Take the start and end dates for a WordCamp and calculate how many days it lasts.
+ *
+ * @param WP_Post $wordcamp
+ *
+ * @return int
+ */
+function wcorg_get_wordcamp_duration( WP_Post $wordcamp ) {
+       // @todo Make sure $wordcamp is the correct post type
+
+       $start = get_post_meta( $wordcamp->ID, 'Start Date (YYYY-mm-dd)', true );
+       $end   = get_post_meta( $wordcamp->ID, 'End Date (YYYY-mm-dd)', true );
+
+       // Assume 1 day duration if there is no end date
+       if ( ! $end ) {
+               return 1;
+       }
+
+       $duration_raw = $end - $start;
+
+       // Add one second and round up to ensure the end date counts as a day as well
+       $duration_days = ceil( ( $duration_raw + 1 ) / DAY_IN_SECONDS );
+
+       return absint( $duration_days );
+}
+
+/**
+ * Get a <select> dropdown of `wordcamp` posts with a select2 UI.
+ *
+ * The calling plugin is responsible for validating and processing the form, this just outputs a single field.
+ *
+ * @param string $name          Optional. The `name` attribute for the `select` element. Defaults to `wordcamp_id`.
+ * @param array  $query_options Optional. Extra arguments to pass to `get_posts()`. Defaults to the values in `get_wordcamps()`.
+ * @param int    $selected      Optional. The list option to select. Defaults to not selecting any.
+ *
+ * @return string The HTML for the <select> list.
+ */
+function get_wordcamp_dropdown( $name = 'wordcamp_id', $query_options = array(), $selected = 0 ) {
+       $wordcamps = get_wordcamps( $query_options );
+
+       wp_enqueue_script( 'select2' );
+       wp_enqueue_style(  'select2' );
+
+       ob_start();
+
+       ?>
+
+       <select name="<?php echo esc_attr( $name ); ?>" class="select2">
+               <option value=""><?php _e( 'Select a WordCamp', 'wordcamporg' ); ?></option>
+               <option value=""></option>
+
+               <?php foreach ( $wordcamps as $wordcamp ) : ?>
+                       <option
+                               value="<?php echo esc_attr( $wordcamp->ID ); ?>"
+                               <?php selected( $selected, $wordcamp->ID ); ?>
+                       >
+                               <?php
+
+                               echo esc_html( $wordcamp->post_title );
+                               if ( ! empty( $wordcamp->meta['Start Date (YYYY-mm-dd)'][0] ) ) {
+                                       echo ' ' . esc_html( date( 'Y', $wordcamp->meta['Start Date (YYYY-mm-dd)'][0] ) );
+                               }
+
+                               ?>
+                       </option>
+               <?php endforeach; ?>
+       </select>
+
+       <script>
+               jQuery( document ).ready( function() {
+                       jQuery( '.select2' ).select2();
+               } );
+       </script>
+
+       <?php
+
+       return ob_get_clean();
+}
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentmupluginshelpersmiscphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/helpers-misc.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/helpers-misc.php       2019-06-20 19:11:55 UTC (rev 8979)
+++ sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/helpers-misc.php 2019-06-20 20:24:08 UTC (rev 8980)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,131 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-
-defined( 'WPINC' ) or die();
-use function WordCamp\Logger\log;
-
-/*
- * Miscellaneous helper functions.
- */
-
-
-/**
- * Determine if a specific feature should be skipped on the current site
- *
- * Warning: Pay careful attention to how things are named, since setting a flag here is typically done when you
- * want a feature to be _enabled_ by default on new sites. In the cases where you want it _disabled_ by default
- * on new sites, you can reverse the name (e.g., `local_terms` instead of `global_terms` for the
- * `global_terms_enabled` callback).
- *
- * Often times we want to add new functionality to plugins and themes, but can't let it run on older sites
- * because that would break backwards compatibility. To get around that, we set a flag on older sites to
- * indicate that they should not have the new feature, and then setup the feature to run on sites that
- * don't have the flag, i.e., to run by default.
- *
- * Doing it this way means that local development environments like the Meta Environment don't to have add any
- * new filters in order to start using the new functionality.
- *
- * See WordCamp_CLI_Miscellaneous::set_skip_feature_flag() for how to set the flags.
- *
- * @param string $flag
- *
- * @return bool
- */
-function wcorg_skip_feature( $flag ) {
-       $flags = get_option( 'wordcamp_skip_features', array() );
-
-       return isset( $flags[ $flag ] );
-}
-
-/**
- * Get a user by the username or nicename
- *
- * Note: This intentionally doesn't lookup users by the display name or nickname, because those can be set by the
- * user, which could result in false-positive matches.
- *
- * @param string $name
- *
- * @return false|WP_User
- */
-function wcorg_get_user_by_canonical_names( $name ) {
-       if ( ! $user = get_user_by( 'login', $name ) ) {    // user_login
-               $user = get_user_by( 'slug', $name );           // user_nicename
-       }
-
-       return $user;
-}
-
-/**
- * Get ISO-3166 country names and codes
- *
- * @todo move the real functionality from get_valid_countries_iso3166() to here, then have the Budgets plugin,
- * QBO, etc call this.
- *
- * @return array
- */
-function wcorg_get_countries() {
-       require_once( WP_PLUGIN_DIR . '/wordcamp-payments/includes/wordcamp-budgets.php' );
-
-       return WordCamp_Budgets::get_valid_countries_iso3166();
-}
-
-/**
- * Make a remote HTTP request, and retry if it fails
- *
- * Sometimes the HTTP request times out, or there's a temporary server-side error, etc. Some use cases require a
- * successful request, like stats scripts, where the resulting data would be distorted by a failed response.
- *
- * @todo Add support for wp_remote_post() too
- * @todo Remove this if https://github.com/rmccue/Requests/issues/222 is implemented
- * @todo maybe `set_time_limit( absint( ini_get( 'max_execution_time' ) ) + $retry_after );` before sleep()'ing to
- *       avoid php timeout
- *
- * @param string $request_url
- * @param array  $request_args
- *
- * @return array|WP_Error
- */
-function wcorg_redundant_remote_get( $request_url, $request_args = array() ) {
-       $attempt_count = 1;
-
-       while ( true ) {
-               $response    = wp_remote_get( $request_url, $request_args );
-               $status_code = wp_remote_retrieve_response_code( $response );
-               $body        = wp_remote_retrieve_body( $response );
-               $retry_after = wp_remote_retrieve_header( $response, 'retry-after' ) ?: 5;
-               $retry_after = min( $retry_after * $attempt_count, 30 );
-
-               if ( ! is_wp_error( $response ) && 200 === $status_code && $body ) {
-                       break;
-               }
-
-               if ( $attempt_count < 3 ) {
-                       log( 'request_failed_temporarily', compact( 'request_url', 'request_args', 'response', 'attempt_count', 'retry_after' ) );
-                       sleep( $retry_after );
-               } else {
-                       log( 'request_failed_permenantly', compact( 'request_url', 'request_args', 'response' ) );
-                       break;
-               }
-
-               $attempt_count++;
-       }
-
-       return $response;
-}
-
-/**
- * Display the indicator that marks a form field as required
- */
-function wcorg_required_indicator() {
-       ?>
-
-       <span class="wcorg-required" aria-hidden="true">
-               <?php // translators: The symbol to indicate the form field is required ?>
-               <?php _e( '*', 'wordcamporg' ); ?>
-       </span>
-
-       <span class="screen-reader-text">
-               <?php _e( 'required field', 'wordcamporg' ); ?>
-       </span>
-
-       <?php
-}
</del></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentmupluginshelperswcptphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/helpers-wcpt.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/helpers-wcpt.php       2019-06-20 19:11:55 UTC (rev 8979)
+++ sites/trunk/wordcamp.org/public_html/wp-content/mu-plugins/helpers-wcpt.php 2019-06-20 20:24:08 UTC (rev 8980)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,254 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-
-defined( 'WPINC' ) or die();
-
-/*
- * Helper functions related to the `wordcamp` post type.
- */
-
-
-/**
- * Retrieve `wordcamp` posts and their metadata.
- *
- * @param array $args Optional. Extra arguments to pass to `get_posts()`.
- *
- * @return array
- */
-function get_wordcamps( $args = array() ) {
-       $args = wp_parse_args( $args, array(
-               'post_type'   => WCPT_POST_TYPE_ID,
-               'post_status' => 'any',
-               'orderby'     => 'ID',
-               'numberposts' => -1,
-               'perm'        => 'readable',
-       ) );
-
-       $wordcamps = get_posts( $args );
-
-       foreach ( $wordcamps as &$wordcamp ) {
-               $wordcamp->meta = get_post_custom( $wordcamp->ID );
-       }
-
-       return $wordcamps;
-}
-
-/**
- * Retrieves the `wordcamp` post and postmeta associated with the current site.
- *
- * `Site ID` is the most reliable way to associate a site with it's corresponding `wordcamp` post,
- * but wasn't historically assigned when new sites are created. For older sites, we fallback to
- * using the `URL` to associate them. That will only work if the site's site_url() exactly
- * matches the `wordcamp` post's `URL` meta field, though. It could also fail if we ever migrate
- * to a different URL structure.
- *
- * @return false|WP_Post
- */
-function get_wordcamp_post() {
-       $current_site_id  = get_current_blog_id();
-       $current_site_url = site_url();
-
-       switch_to_blog( BLOG_ID_CURRENT_SITE ); // central.wordcamp.org
-
-       $wordcamp = get_posts( array(
-               'post_type'   => 'wordcamp',
-               'post_status' => 'any',
-
-               'meta_query' => array(
-                       'relation' => 'OR',
-
-                       array(
-                               'key'   => '_site_id',
-                               'value' => $current_site_id,
-                       ),
-
-                       array(
-                               'key'   => 'URL',
-                               'value' => $current_site_url,
-                       ),
-               ),
-       ) );
-
-       if ( isset( $wordcamp[0]->ID ) ) {
-               $wordcamp       = $wordcamp[0];
-               $wordcamp->meta = get_post_custom( $wordcamp->ID );
-       } else {
-               $wordcamp = false;
-       }
-
-       restore_current_blog();
-
-       return $wordcamp;
-}
-
-/**
- * Find the site that corresponds to the given `wordcamp` post
- *
- * @param WP_Post $wordcamp_post
- *
- * @return mixed An integer if successful, or boolean false if failed
- */
-function get_wordcamp_site_id( $wordcamp_post ) {
-       switch_to_blog( BLOG_ID_CURRENT_SITE ); // central.wordcamp.org
-
-       if ( ! $site_id = get_post_meta( $wordcamp_post->ID, '_site_id', true ) ) {
-               $url = parse_url( get_post_meta( $wordcamp_post->ID, 'URL', true ) );
-
-               if ( isset( $url['host'] ) && isset( $url['path'] ) ) {
-                       if ( $site = get_site_by_path( $url['host'], $url['path'] ) ) {
-                               $site_id = $site->blog_id;
-                       }
-               }
-       }
-
-       restore_current_blog();
-
-       return $site_id;
-}
-
-/**
- * Get a consistent WordCamp name in the 'WordCamp [Location] [Year]' format.
- *
- * The results of bloginfo( 'name' ) don't always contain the year, but the title of the site's corresponding
- * `wordcamp` post is usually named 'WordCamp [Location]', so we can get a consistent name most of the time
- * by using that and adding the year (if available).
- *
- * @param int $site_id Optionally, get the name for a site other than the current one.
- *
- * @return string
- */
-function get_wordcamp_name( $site_id = 0 ) {
-       $name = false;
-
-       switch_to_blog( $site_id );
-
-       if ( $wordcamp = get_wordcamp_post() ) {
-               if ( ! empty( $wordcamp->meta['Start Date (YYYY-mm-dd)'][0] ) ) {
-                       $name = $wordcamp->post_title . ' ' . date( 'Y', $wordcamp->meta['Start Date (YYYY-mm-dd)'][0] );
-               }
-       }
-
-       if ( ! $name ) {
-               $name = get_bloginfo( 'name' );
-       }
-
-       restore_current_blog();
-
-       return $name;
-}
-
-
-/**
- * Extract pieces from a WordCamp.org URL
- *
- * @todo find other code that's doing this same task in an ad-hoc manner, and convert it to use this instead
- *
- * @param string $url
- * @param string $part 'city', 'city-domain' (without the year, e.g. seattle.wordcamp.org), 'year'
- *
- * @return false|string|int False on errors; an integer for years; a string for city and city-domain
- */
-function wcorg_get_url_part( $url, $part ) {
-       $url_parts = explode( '.', parse_url( $url, PHP_URL_HOST ) );
-       $result    = false;
-
-       // Make sure it matches the typical year.city.wordcamp.org structure
-       if ( 4 !== count( $url_parts ) ) {
-               return $result;
-       }
-
-       switch ( $part ) {
-               case 'city':
-                       $result = $url_parts[1];
-                       break;
-
-               case 'city-domain':
-                       $result = ltrim( strstr( $url, '.' ), '.' );
-                       break;
-
-               case 'year':
-                       $result = absint( $url_parts[0] );
-                       break;
-       }
-
-       return $result;
-}
-
-
-/**
- * Take the start and end dates for a WordCamp and calculate how many days it lasts.
- *
- * @param WP_Post $wordcamp
- *
- * @return int
- */
-function wcorg_get_wordcamp_duration( WP_Post $wordcamp ) {
-       // @todo Make sure $wordcamp is the correct post type
-
-       $start = get_post_meta( $wordcamp->ID, 'Start Date (YYYY-mm-dd)', true );
-       $end   = get_post_meta( $wordcamp->ID, 'End Date (YYYY-mm-dd)', true );
-
-       // Assume 1 day duration if there is no end date
-       if ( ! $end ) {
-               return 1;
-       }
-
-       $duration_raw = $end - $start;
-
-       // Add one second and round up to ensure the end date counts as a day as well
-       $duration_days = ceil( ( $duration_raw + 1 ) / DAY_IN_SECONDS );
-
-       return absint( $duration_days );
-}
-
-/**
- * Get a <select> dropdown of `wordcamp` posts with a select2 UI.
- *
- * The calling plugin is responsible for validating and processing the form, this just outputs a single field.
- *
- * @param string $name          Optional. The `name` attribute for the `select` element. Defaults to `wordcamp_id`.
- * @param array  $query_options Optional. Extra arguments to pass to `get_posts()`. Defaults to the values in `get_wordcamps()`.
- * @param int    $selected      Optional. The list option to select. Defaults to not selecting any.
- *
- * @return string The HTML for the <select> list.
- */
-function get_wordcamp_dropdown( $name = 'wordcamp_id', $query_options = array(), $selected = 0 ) {
-       $wordcamps = get_wordcamps( $query_options );
-
-       wp_enqueue_script( 'select2' );
-       wp_enqueue_style(  'select2' );
-
-       ob_start();
-
-       ?>
-
-       <select name="<?php echo esc_attr( $name ); ?>" class="select2">
-               <option value=""><?php _e( 'Select a WordCamp', 'wordcamporg' ); ?></option>
-               <option value=""></option>
-
-               <?php foreach ( $wordcamps as $wordcamp ) : ?>
-                       <option
-                               value="<?php echo esc_attr( $wordcamp->ID ); ?>"
-                               <?php selected( $selected, $wordcamp->ID ); ?>
-                       >
-                               <?php
-
-                               echo esc_html( $wordcamp->post_title );
-                               if ( ! empty( $wordcamp->meta['Start Date (YYYY-mm-dd)'][0] ) ) {
-                                       echo ' ' . esc_html( date( 'Y', $wordcamp->meta['Start Date (YYYY-mm-dd)'][0] ) );
-                               }
-
-                               ?>
-                       </option>
-               <?php endforeach; ?>
-       </select>
-
-       <script>
-               jQuery( document ).ready( function() {
-                       jQuery( '.select2' ).select2();
-               } );
-       </script>
-
-       <?php
-
-       return ob_get_clean();
-}
</del></span></pre>
</div>
</div>

</body>
</html>