<!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>[1715] sites/trunk/wordcamp.org/public_html/wp-content/plugins: WordCamp Site Cloner: Initial commit.</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 { 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/1715">1715</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/1715","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>2015-07-08 22:57:41 +0000 (Wed, 08 Jul 2015)</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 Site Cloner: Initial commit.

Imported from https://github.com/ryelle/WordCamp-Style-Import/                             

Props ryelle, iandunn</pre>

<h3>Added Paths</h3>
<ul>
<li>sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/</li>
<li>sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/includes/</li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonerincludessitecontrolphp">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/includes/site-control.php</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonerincludessitessectionphp">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/includes/sites-section.php</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonerincludessourcesiteidsettingphp">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/includes/source-site-id-setting.php</a></li>
<li>sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/templates/</li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonertemplatessitecontrolphp">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/templates/site-control.php</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonertemplatessitessectionphp">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/templates/sites-section.php</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonerwordcampsiteclonercss">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/wordcamp-site-cloner.css</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonerwordcampsiteclonerjs">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/wordcamp-site-cloner.js</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonerwordcampsiteclonerphp">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/wordcamp-site-cloner.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonerincludessitecontrolphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/includes/site-control.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/plugins/wordcamp-site-cloner/includes/site-control.php                            (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/includes/site-control.php      2015-07-08 22:57:41 UTC (rev 1715)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,37 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+namespace WordCamp\Site_Cloner;
+
+defined( 'WPINC' ) or die();
+
+/**
+ * Custom Customizer Control for a WordCamp site
+ */
+class Site_Control extends \WP_Customize_Control {
+       public $site_id, $site_name, $screenshot_url, $theme_slug;
+       public $settings = 'wcsc_source_site_id';
+       public $section  = 'wcsc_sites';
+
+       /**
+        * Enqueue scripts and styles
+        */
+       public function enqueue() {
+               wp_enqueue_style(  'wordcamp-site-cloner' );
+               wp_enqueue_script( 'wordcamp-site-cloner' );
+       }
+
+       /**
+        * Render the control's content
+        */
+       public function render_content() {
+               $preview_url = add_query_arg(
+                       array(
+                               'theme'               => rawurlencode( $this->theme_slug ),
+                               'wcsc_source_site_id' => rawurlencode( $this->site_id ),
+                       ),
+                       admin_url( 'customize.php' )
+               );
+
+               require( dirname( __DIR__ ) . '/templates/site-control.php' );
+       }
+}
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonerincludessitessectionphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/includes/sites-section.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/plugins/wordcamp-site-cloner/includes/sites-section.php                           (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/includes/sites-section.php     2015-07-08 22:57:41 UTC (rev 1715)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,19 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+namespace WordCamp\Site_Cloner;
+
+defined( 'WPINC' ) or die();
+
+/**
+ * Custom Customizer Section for WordCamp sites
+ */
+class Sites_Section extends \WP_Customize_Section {
+       public $type = 'wcsc-sites';
+
+       /**
+        * Render the section's content
+        */
+       protected function render() {
+               require_once( dirname( __DIR__ ) . '/templates/sites-section.php' );
+       }
+}
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonerincludessourcesiteidsettingphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/includes/source-site-id-setting.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/plugins/wordcamp-site-cloner/includes/source-site-id-setting.php                          (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/includes/source-site-id-setting.php    2015-07-08 22:57:41 UTC (rev 1715)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,136 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+namespace WordCamp\Site_Cloner;
+
+defined( 'WPINC' ) or die();
+
+/**
+ * Customizer Setting for source site ID
+ *
+ * This isn't an actual setting that gets stored in the database, it's just a temporary value to track the ID of
+ * the site that that will be cloned. There are actually many data points that we'll import, but they don't fit
+ * into the default model that the Customizer expects.
+ */
+class Source_Site_ID_Setting extends \WP_Customize_Setting {
+       public $type              = 'wcsc-source-site-id';
+       public $default           = 0;
+       public $sanitize_callback = 'absint';
+       protected $preview_source_site_id;
+
+       /**
+        * Preview another site before it's imported
+        */
+       public function preview() {
+               if ( ! $this->preview_source_site_id = $this->manager->post_value( $this ) ) {
+                       return;
+               }
+
+               add_action( 'wp_head',                 array( $this, 'preview_source_site_css'  ), 99 );   // wp_print_styles is too early; the theme's stylesheet would get enqueued later and take precedence
+               add_filter( 'get_post_metadata',       array( $this, 'preview_jetpack_postmeta' ), 10, 4 );
+               add_filter( 'safecss_skip_stylesheet', array( $this, 'preview_skip_stylesheet'  ) );
+       }
+
+       /**
+        * Print the source site's custom CSS in an inline style block
+        *
+        * It can't be easily enqueued as an external stylesheet because Jetpack_Custom_CSS::link_tag() returns early
+        * in the Customizer if the theme being previewed is different from the live theme.
+        */
+       public function preview_source_site_css() {
+               if ( method_exists( '\Jetpack', 'get_module_path' ) ) {
+                       require_once( \Jetpack::get_module_path( 'custom-css' ) );
+               } else {
+                       return;
+               }
+
+               switch_to_blog( $this->preview_source_site_id );
+               printf( '<style id="wcsc-source-site-custom-css">%s</style>', \Jetpack_Custom_CSS::get_css( true ) );
+               restore_current_blog();
+       }
+
+       /**
+        * Overwrite the previewing site's Custom CSS settings with values from the source site
+        *
+        * @param mixed  $pre_filter_value
+        * @param int    $post_id
+        * @param string $meta_key
+        * @param bool   $return_single_value
+        *
+        * @return mixed
+        */
+       public function preview_jetpack_postmeta( $pre_filter_value, $post_id, $meta_key, $return_single_value ) {
+               if ( ! in_array( $meta_key, array( 'content_width' ) ) ) {
+                       return $pre_filter_value;
+               }
+
+               remove_filter( 'get_post_metadata', array( $this, 'preview_jetpack_postmeta' ), 10, 4 );    // avoid infinite recursion
+               switch_to_blog( $this->preview_source_site_id );
+
+               if ( $source_cite_css_post = \Jetpack_Custom_CSS::get_current_revision() ) {
+                       $pre_filter_value = get_post_meta( $source_cite_css_post['ID'], $meta_key, $return_single_value );
+               }
+
+               restore_current_blog();
+               add_filter( 'get_post_metadata', array( $this, 'preview_jetpack_postmeta' ), 10, 4 );
+
+               return $pre_filter_value;
+       }
+
+       /**
+        * Determine whether or not to skip the primary stylesheet
+        *
+        * When the Custom CSS value for `Mode` is `Replacement`, Jetpack will prevent the primary stylesheet from
+        * being enqueued. We need to trigger that behavior based on the value on the source site, rather than the
+        * current site.
+        *
+        * This could be actually handled along with other Jetpack options in preview_jetpack_postmeta(), if it
+        * weren't for the fact that Jetpack_Custom_CSS::skip_stylesheet always returns false in the Previewer.
+        *
+        * @param bool $skip
+        *
+        * @return bool
+        */
+       public function preview_skip_stylesheet( $skip ) {
+               switch_to_blog( $this->preview_source_site_id );
+
+               if ( $source_cite_css_post = \Jetpack_Custom_CSS::get_current_revision() ) {
+                       $skip = 'no' === get_post_meta( $source_cite_css_post['ID'], 'custom_css_add', true );
+               }
+
+               restore_current_blog();
+
+               return $skip;
+       }
+
+       /**
+        * Clone the source site into the current site
+        *
+        * If the theme needs to be switched, Core will do that for us because we added the `?theme=` parameter
+        * to the URL.
+        *
+        * @param int $source_site_id
+        */
+       protected function update( $source_site_id ) {
+               switch_to_blog( $source_site_id );
+
+               if ( ! $source_cite_css_post = \Jetpack_Custom_CSS::get_current_revision() ) {
+                       restore_current_blog();
+                       return;
+               }
+
+               $source_site_css           = \Jetpack_Custom_CSS::get_css( false );
+               $source_site_preprocessor  = get_post_meta( $source_cite_css_post['ID'], 'custom_css_preprocessor', true );
+               $source_site_mode          = get_post_meta( $source_cite_css_post['ID'], 'custom_css_add', true );
+               $source_site_content_width = get_post_meta( $source_cite_css_post['ID'], 'content_width', true );
+
+               restore_current_blog();
+
+               \Jetpack_Custom_CSS::save( array(
+                       'css'             => $source_site_css,
+                       'is_preview'      => false,
+                       'preprocessor'    => $source_site_preprocessor,
+                       'add_to_existing' => 'yes' === $source_site_mode ? true : false,
+                       'content_width'   => $source_site_content_width,
+               ) );
+       }
+}
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonertemplatessitecontrolphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/templates/site-control.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/plugins/wordcamp-site-cloner/templates/site-control.php                           (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/templates/site-control.php     2015-07-08 22:57:41 UTC (rev 1715)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,15 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php defined( 'WPINC' ) or die(); ?>
+
+<div id="wcsc-site-<?php echo esc_attr( $this->site_id ); ?>" class="wcscSite" data-preview-url="<?php echo esc_url( $preview_url ); ?>">
+       <div class="wcsc-site-screenshot">
+               <img src="<?php echo esc_url( $this->screenshot_url ); ?>" alt="<?php echo esc_attr( $this->site_name ); ?>" />
+       </div>
+
+       <h3 class="wcsc-site-name">
+               <?php echo esc_html( $this->site_name ); ?>
+       </h3>
+
+       <span id="live-preview-label-<?php echo esc_attr( $this->site_id ); ?>" class="wcsc-live-preview-label">
+               <?php _e( 'Live Preview', 'wordcamporg' ); ?>
+       </span>
+</div>
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonertemplatessitessectionphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/templates/sites-section.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/plugins/wordcamp-site-cloner/templates/sites-section.php                          (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/templates/sites-section.php    2015-07-08 22:57:41 UTC (rev 1715)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,15 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php defined( 'WPINC' ) or die(); ?>
+
+<li id="section-<?php echo esc_attr( $this->id ); ?>" class="accordion-section control-section control-section-<?php echo esc_attr( $this->type ); ?>">
+       <h3>
+               <?php esc_html_e( 'WordCamp Sites' ); ?>
+
+               <span class="title-count wcsc-sites-count">
+                       <?php echo count( $this->controls ); ?>
+               </span>
+       </h3>
+
+       <div class="wcsc-sites-section-content">
+               <ul id="wcsc-sites"></ul>
+       </div>
+</li>
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonerwordcampsiteclonercss"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/wordcamp-site-cloner.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/wordcamp-site-cloner.css                             (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/wordcamp-site-cloner.css       2015-07-08 22:57:41 UTC (rev 1715)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,43 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.control-section-wcsc-sites {
+       padding: 0 8px;
+}
+
+       #wcsc-sites {
+               overflow: auto;
+       }
+
+               .wcscSite {
+                       position: relative;
+                       cursor: pointer;
+                       border: 1px solid #DEDEDE;
+                       box-shadow: 0 1px 1px -1px rgba( 0, 0, 0, 0.1 );
+               }
+
+                       .wcsc-site-screenshot {
+                               transition: opacity 0.2s ease-in-out 0s;
+                       }
+
+                               .wcscSite:hover .wcsc-site-screenshot {
+                                       opacity: 0.4;
+                               }
+
+                       .wcsc-live-preview-label {
+                               opacity: 0;
+                               position: absolute;
+                               top: 35%;
+                               right: 25%;
+                               left: 25%;
+                               background: rgba( 0, 0, 0, 0.7 ) none repeat scroll 0 0;
+                               color: #FFF;
+                               font-size: 15px;
+                               text-shadow: 0 1px 0 rgba( 0, 0, 0, 0.6 );
+                               font-weight: 600;
+                               padding: 15px 12px;
+                               text-align: center;
+                               border-radius: 3px;
+                               transition: opacity 0.1s ease-in-out 0s;
+                       }
+
+                               .wcscSite:hover .wcsc-live-preview-label {
+                                       opacity: 1;
+                               }
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonerwordcampsiteclonerjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/wordcamp-site-cloner.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/wordcamp-site-cloner.js                              (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/wordcamp-site-cloner.js        2015-07-08 22:57:41 UTC (rev 1715)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,99 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+( function( wp, $ ) {
+       'use strict';
+
+       if ( ! wp || ! wp.customize ) {
+               return;
+       }
+
+       var api = wp.customize;
+
+       /**
+        * The Clone Another WordCamp panel
+        */
+       api.panelConstructor.wcscPanel = api.Panel.extend( {
+               /**
+                * Initialize the panel after it's loaded
+                *
+                * Ideally, the Previewer would be set to the requested site ID during the initial PHP request, rather than
+                * loading the host site in the Previewer, and then refreshing it to use the requested site. That became a
+                * rabbit hole, though, so it's done this way instead.
+                */
+               ready : function() {
+                       var urlParams = getUrlParams( window.location.href );
+
+                       if ( urlParams.hasOwnProperty( 'wcsc_source_site_id' ) ) {
+                               this.expand();
+                               api( 'wcsc_source_site_id' ).set( urlParams.wcsc_source_site_id );
+                       }
+               }
+       } );
+
+       /**
+        * Custom control representing a site that can be previewed/imported
+        */
+       api.controlConstructor.wcscSite = api.Control.extend( {
+               /**
+                * Initialize the control after it's loaded
+                */
+               ready : function() {
+                       this.container.on( 'click', '.wcscSite', this.previewSite );
+               },
+
+               /**
+                * Preview the selected site
+                *
+                * If the site is using a different theme, then reload the entire Customizer with the theme URL parameter
+                * set, so that the Theme Switcher will handle previewing the new theme for us. Otherwise just set the ID
+                * to refresh the Previewer with the current theme and the new site's CSS, etc.
+                *
+                * @param {object} event
+                */
+               previewSite : function( event ) {
+                       var previewUrl       = $( this ).data( 'preview-url' ),
+                               previewUrlParams = getUrlParams( previewUrl );
+
+                       if ( api( 'wcsc_source_site_id' ).get() == previewUrlParams.wcsc_source_site_id ) {
+                               return;
+                       }
+
+                       if ( api.settings.theme.stylesheet === previewUrlParams.theme ) {
+                               api( 'wcsc_source_site_id' ).set( previewUrlParams.wcsc_source_site_id );
+                       } else {
+                               window.parent.location = previewUrl;
+                       }
+               }
+       } );
+
+       /**
+        * Parse the URL parameters
+        *
+        * Based on https://stackoverflow.com/a/2880929/450127
+        *
+        * @param {string} url
+        *
+        * @returns {object}
+        */
+       function getUrlParams( url ) {
+               var match, questionMarkIndex, query,
+                       urlParams = {},
+                       pl        = /\+/g,  // Regex for replacing addition symbol with a space
+                       search    = /([^&=]+)=?([^&]*)/g,
+                       decode    = function ( s ) {
+                               return decodeURIComponent( s.replace( pl, " " ) );
+                       };
+
+               questionMarkIndex = url.indexOf( '?' );
+
+               if ( -1 === questionMarkIndex ) {
+                       return urlParams;
+               } else {
+                       query = url.substring( questionMarkIndex + 1 );
+               }
+
+               while ( match = search.exec( query ) ) {
+                       urlParams[ decode( match[ 1 ] ) ] = decode( match[ 2 ] );
+               }
+
+               return urlParams;
+       }
+} )( window.wp, jQuery );
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampsiteclonerwordcampsiteclonerphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/wordcamp-site-cloner.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/plugins/wordcamp-site-cloner/wordcamp-site-cloner.php                             (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/wordcamp-site-cloner.php       2015-07-08 22:57:41 UTC (rev 1715)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,176 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+
+namespace WordCamp\Site_Cloner;
+
+defined( 'WPINC' ) or die();
+
+/*
+Plugin Name: WordCamp Site Cloner
+Description: Allows organizers to clone another WordCamp's theme and custom CSS as a starting point for their site.
+Version:     0.1
+Author:      WordCamp.org
+Author URI:  http://wordcamp.org
+License:     GPLv2 or later
+*/
+
+add_action( 'plugins_loaded',        __NAMESPACE__ . '\get_wordcamp_sites' );
+add_action( 'admin_enqueue_scripts', __NAMESPACE__ . '\register_scripts' );
+add_action( 'customize_register',    __NAMESPACE__ . '\register_customizer_components' );
+
+/**
+ * Register scripts and styles
+ */
+function register_scripts() {
+       wp_register_style(
+               'wordcamp-site-cloner',
+               plugin_dir_url( __FILE__ ) . 'wordcamp-site-cloner.css',
+               array(),
+               1
+       );
+
+       wp_register_script(
+               'wordcamp-site-cloner',
+               plugin_dir_url( __FILE__ ) . 'wordcamp-site-cloner.js',
+               array( 'jquery', 'customize-controls' ),
+               1,
+               true
+       );
+}
+
+/**
+ * Register our Customizer settings, panels, sections, and controls
+ *
+ * @param \WP_Customize_Manager $wp_customize
+ */
+function register_customizer_components( $wp_customize ) {
+       require_once( __DIR__ . '/includes/source-site-id-setting.php' );
+       require_once( __DIR__ . '/includes/sites-section.php' );
+       require_once( __DIR__ . '/includes/site-control.php' );
+
+       $wp_customize->register_control_type( __NAMESPACE__ . '\Site_Control' );
+
+       $wp_customize->add_setting( new Source_Site_ID_Setting(
+               $wp_customize,
+               'wcsc_source_site_id',
+               array()
+       ) );
+
+       $wp_customize->add_panel(
+               'wordcamp_site_cloner',
+               array(
+                       'type'        => 'wcscPanel',
+                       'title'       => __( 'Clone Another WordCamp', 'wordcamporg' ),
+                       'description' => __( "Clone another WordCamp's theme and custom CSS as a starting point for your site.", 'wordcamporg' ),
+               )
+       );
+
+       $wp_customize->add_section( new Sites_Section(
+               $wp_customize,
+               'wcsc_sites',
+               array(
+                       'panel' => 'wordcamp_site_cloner',
+                       'title' => __( 'WordCamp Sites', 'wordcamporg' ),
+               )
+       ) );
+
+       foreach( get_wordcamp_sites() as $wordcamp ) {
+               if ( get_current_blog_id() == $wordcamp['site_id'] ) {
+                       continue;
+               }
+
+               $wp_customize->add_control( new Site_Control(
+                       $wp_customize,
+                       'wcsc_site_id_' . $wordcamp['site_id'],
+                       array(
+                               'type'           => 'wcscSite',                      // todo should be able to set this in control instead of here, but if do that then control contents aren't rendered
+                               'site_id'        => $wordcamp['site_id'],
+                               'site_name'      => $wordcamp['name'],
+                               'theme_slug'     => $wordcamp['theme_slug'],
+                               'screenshot_url' => $wordcamp['screenshot_url'],
+                       )
+               ) );
+       }
+}
+
+/**
+ * Get required data for relevant WordCamp sites
+ *
+ * This isn't actually used until register_customizer_components(), but it's called during `plugins_loaded` in
+ * order to prime the cache. That has to be done before `setup_theme`, because the Theme Switcher will override
+ * the current theme when `?theme=` is present in the URL parameters, and it's safer to just avoid that than to
+ * muck with the internals and try to reverse it on the fly.
+ *
+ * @return array
+ */
+function get_wordcamp_sites() {
+       // plugins_loaded is runs on every screen, but we only need this when loading the Customizer and Previewer
+       if ( 'customize.php' != basename( $_SERVER['SCRIPT_NAME'] ) && empty( $_REQUEST['wp_customize'] ) ) {
+               return array();
+       }
+
+       $transient_key = 'wcsc_sites';
+
+       if ( $sites = get_site_transient( $transient_key ) ) {
+               return $sites;
+       }
+
+       switch_to_blog( BLOG_ID_CURRENT_SITE ); // central.wordcamp.org
+
+       $sites = array();
+       $wordcamps = get_posts( array(
+               'post_type'      => 'wordcamp',
+               'post_status'    => 'publish',
+               'posts_per_page' => 50, // todo temporary workaround until able to add filters to make hundreds of sites manageable
+               'meta_key'       => 'Start Date (YYYY-mm-dd)',
+               'orderby'        => 'meta_value_num',
+
+               'meta_query' => array(
+                       array(
+                               'key'     => 'Start Date (YYYY-mm-dd)',
+                               'value'   => strtotime( 'now - 1 month' ),
+                               'compare' => '<'
+                       ),
+               ),
+       ) );
+
+       foreach( $wordcamps as $wordcamp ) {
+               $site_id  = get_wordcamp_site_id( $wordcamp );
+               $site_url = get_post_meta( $wordcamp->ID, 'URL', true );
+
+               if ( ! $site_id || ! $site_url ) {
+                       continue;
+               }
+
+               switch_to_blog( $site_id );
+
+               $sites[] = array(
+                       'site_id'        => $site_id,
+                       'name'           => get_wordcamp_name(),
+                       'theme_slug'     => get_stylesheet(),
+                       'screenshot_url' => get_screenshot_url( $site_url ),
+               );
+
+               restore_current_blog();
+       }
+
+       restore_current_blog();
+
+       set_site_transient( $transient_key, $sites, DAY_IN_SECONDS );
+
+       return $sites;
+}
+
+/**
+ * Get the mShot URL for the given site URL
+ *
+ * Allow it to be filtered so that production URLs can be changed to match development URLs in local environments.
+ *
+ * @param string $site_url
+ *
+ * @return string
+ */
+function get_screenshot_url( $site_url ) {
+       $screenshot_url = add_query_arg( 'w', 275, 'https://www.wordpress.com/mshots/v1/' . rawurlencode( $site_url ) );
+
+       return apply_filters( 'wcsc_site_screenshot_url', $screenshot_url );
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-site-cloner/wordcamp-site-cloner.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svnexecutable"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:executable</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+*
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span></div>

</body>
</html>