<!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>[3274] sites/trunk/wordcamp.org/public_html/wp-content/plugins: WordCamp Docs: Move plugin to Meta from private repository.</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/3274">3274</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/3274","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>2016-05-31 16:39:47 +0000 (Tue, 31 May 2016)</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 Docs: Move plugin to Meta from private repository.</pre>
<h3>Added Paths</h3>
<ul>
<li>sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/</li>
<li>sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/classes/</li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampdocsclassesclasswordcampdocspdfgeneratorphp">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/classes/class-wordcamp-docs-pdf-generator.php</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampdocsclassesclasswordcampdocstemplatephp">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/classes/class-wordcamp-docs-template.php</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampdocsclassesclasswordcampdocsphp">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/classes/class-wordcamp-docs.php</a></li>
<li>sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/templates/</li>
<li>sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/templates/assets/</li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampdocstemplatesassetslogopng">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/templates/assets/logo.png</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampdocstemplatesspeakerinvitationphp">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/templates/speaker-invitation.php</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampdocswordcampdocsphp">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/wordcamp-docs.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampdocsclassesclasswordcampdocspdfgeneratorphp"></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-docs/classes/class-wordcamp-docs-pdf-generator.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-docs/classes/class-wordcamp-docs-pdf-generator.php (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/classes/class-wordcamp-docs-pdf-generator.php 2016-05-31 16:39:47 UTC (rev 3274)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,168 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Helper class to generate PDFs from HTML strings or files using wkhtmltopdf.
+ *
+ * Thanks to Viper007Bond ( http://www.viper007bond.com )
+ */
+class WordCamp_Docs_PDF_Generator {
+
+ /**
+ * Full path to your tmp folder where files should be created. Include a trailing slash.
+ * You should probably just leave this as "/tmp/" as you should move your PDF on your own.
+ *
+ * @var string
+ */
+ public $tmp_folder_base = '/tmp/';
+
+ /**
+ * Stores a unique folder name that the class instance will work out of.
+ * Generated dynamically using uniqid().
+ *
+ * @var string
+ */
+ public $working_folder_name;
+
+ /**
+ * Constructor. No parameters.
+ */
+ function __construct() {
+ $this->working_folder_name = uniqid( 'wcdocs_' );
+ }
+
+ /**
+ * Generates a PDF from a string of HTML.
+ *
+ * @param string $string A string of HTML.
+ * @param string $filename Filename of the PDF, including the extension.
+ * @param array $args Optional. An associative array of additional parameters.
+ * assets: optional array of full paths to local assets (images for example).
+ * dpi: optional integer to be passed directly to wkhtmltopdf.
+ * margins: optional array of 4 integers specifying PDF margins. Top, right, bottom, left.
+ *
+ * @return string The path to the generated PDF.
+ */
+ public function generate_pdf_from_string( $string, $filename, $args = array() ) {
+ $file = $this->write_file( $filename . '.html', $string );
+ return $this->generate_pdf_from_file( $file, $filename, $args );
+ }
+
+ /**
+ * Generates a PDF from an HTML file.
+ *
+ * @param string $source_file Full path to the HTML file.
+ * @param string $filename Filename of the PDF, including the extension.
+ * @param array $args Optional. An associative array of additional parameters.
+ * assets: optional array of full paths to local assets (images for example).
+ * dpi: optional integer to be passed directly to wkhtmltopdf.
+ * margins: optional array of 4 integers specifying PDF margins. Top, right, bottom, left.
+ *
+ * @return string The path to the generated PDF.
+ */
+ public function generate_pdf_from_file( $source_file, $filename, $args = array() ) {
+ if ( ! empty( $args['assets'] ) && is_array( $args['assets'] ) ) {
+ foreach ( $args['assets'] as $asset ) {
+ copy( $asset, $this->get_tmp_folder( basename( $asset ) ) );
+ }
+ }
+
+ $dpi = ( ! empty( $args['dpi'] ) ) ? absint( $args['dpi'] ) : 300;
+
+ $margins = ( ! empty( $args['margins'] ) && is_array( $args['margins'] ) && 4 == count( $args['margins'] ) ) ? $args['margins'] : array( 0, 0, 0, 0 );
+
+ $file = $this->get_tmp_folder( $filename );
+
+ $command = sprintf(
+ 'wkhtmltopdf -d %d -T %s -R %s -B %s -L %s %s %s',
+ $dpi,
+ escapeshellarg( $margins[0] ),
+ escapeshellarg( $margins[1] ),
+ escapeshellarg( $margins[2] ),
+ escapeshellarg( $margins[3] ),
+ escapeshellarg( $source_file ),
+ escapeshellarg( $file )
+ );
+
+ exec( $command );
+
+ return $file;
+ }
+
+ /**
+ * Serves a file from the tmp folder up to the browser.
+ * Does NOT exit when finished so that you can still call
+ * A8C_PDF_Generator::delete_tmp_folder() when you're all done.
+ *
+ * @param string $filename The filename within this instance's temporary folder to serve up.
+ * @param bool $download Whether to prompt downloading or serve it natively within the browser.
+ */
+ public function serve_pdf_to_browser( $filename, $download = false ) {
+ $filename = basename( $filename );
+
+ $file = $this->get_tmp_folder( $filename );
+
+ nocache_headers();
+
+ if ( ! file_exists( $file ) ) {
+ status_header( 404 );
+ echo 'File not found.';
+ }
+
+ header( 'Content-Type: application/pdf' );
+
+ if ( $download ) {
+ header( 'Content-Disposition: attachment; filename="' . esc_attr( $filename ) . '"' );
+ }
+
+ echo file_get_contents( $file );
+ }
+
+ /**
+ * Writes out a file to this instance's temporary file.
+ *
+ * @param string $filename The filename (not the path) that should be written to.
+ * @param string $data The contents of the file, such as HTML.
+ *
+ * @return string The full path to the newly created file.
+ */
+ public function write_file( $filename, $data ) {
+ if ( ! is_dir( $this->get_tmp_folder() ) ) {
+ mkdir( $this->get_tmp_folder() );
+ }
+
+ $path = $this->get_tmp_folder( $filename );
+
+ file_put_contents( $path, $data );
+
+ return $path;
+ }
+
+ /**
+ * Returns the path to this instance's temporary folder.
+ * Optionally you can include a filename that will be relative to that path.
+ *
+ * @param string $filename Optional. Filename to be appended onto the end of the path.
+ *
+ * @return string Full path to the temporary folder or file.
+ */
+ public function get_tmp_folder( $filename = '' ) {
+ return trailingslashit( $this->tmp_folder_base ) . $this->working_folder_name . '/' . $filename;
+ }
+
+ /**
+ * Run this when you're all done. Deletes the instance's temporary folder and all files within it.
+ * You should make sure to move the generated PDF out of the folder first.
+ *
+ * @return bool True on success or false on failure.
+ */
+ public function delete_tmp_folder() {
+ $tmp_folder = $this->get_tmp_folder();
+
+ $files = array_diff( scandir( $tmp_folder ), array( '.', '..' ) );
+
+ foreach ( $files as $file ) {
+ unlink( $tmp_folder . $file );
+ }
+
+ return rmdir( $tmp_folder );
+ }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampdocsclassesclasswordcampdocstemplatephp"></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-docs/classes/class-wordcamp-docs-template.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-docs/classes/class-wordcamp-docs-template.php (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/classes/class-wordcamp-docs-template.php 2016-05-31 16:39:47 UTC (rev 3274)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,46 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Make sure your custom template implements this interface.
+ */
+interface WordCamp_Docs_Template {
+
+ /**
+ * This is the name that will be displayed in the WordCamp Docs UI.
+ */
+ public function get_name();
+
+ /**
+ * This is the PDF filename which will be used when serving the
+ * generated PDF file to the browser.
+ */
+ public function get_filename();
+
+ /**
+ * This function will be called with POST data. It should render a
+ * form for the WordCamp Docs UI.
+ *
+ * @param array $data POST-ed data (if any)
+ */
+ public function form( $data );
+
+ /**
+ * This function is called with the POST-ed data, should return
+ * clean input.
+ *
+ * @param array $input POST-ed data.
+ */
+ public function sanitize( $input );
+
+ /**
+ * This function is called when generating a PDF, should return
+ * HTML and CSS. You can use ob_* functions for convenience.
+ *
+ * @param array $input POST-ed and self::sanitized() data.
+ */
+ public function render( $data );
+
+ /**
+ * This function should return an array of absolute paths to assets.
+ */
+ public function get_assets();
+}
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampdocsclassesclasswordcampdocsphp"></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-docs/classes/class-wordcamp-docs.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-docs/classes/class-wordcamp-docs.php (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/classes/class-wordcamp-docs.php 2016-05-31 16:39:47 UTC (rev 3274)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,186 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+class WordCamp_Docs {
+ private static $templates = null;
+ private static $errors = array();
+ private static $step = 0;
+
+ /**
+ * Runs at plugins_loaded
+ */
+ public static function load() {
+ add_action( 'admin_menu', array( __CLASS__, 'admin_menu' ) );
+ add_action( 'admin_init', array( __CLASS__, 'form_handler' ) );
+
+ add_filter( 'wcdocs_templates', array( __CLASS__, 'default_templates' ) );
+ }
+
+ /**
+ * To load additional templates just hook into wcdocs_template
+ * some time around plugins_loaded and add your own objects that
+ * implement the WordCamp_Docs_Template class.
+ *
+ * @return array An array of template objects.
+ */
+ private static function get_templates() {
+ if ( self::$templates === null )
+ self::$templates = apply_filters( 'wcdocs_templates', array() );
+
+ return self::$templates;
+ }
+
+ /**
+ *
+ * Get template by key.
+ *
+ * @param string $key Template key.
+ * @return object|null The template object or null if not found.
+ */
+ private static function get_template( $key ) {
+ $templates = self::get_templates();
+ if ( empty( $templates[ $key ] ) )
+ return null;
+
+ return $templates[ $key ];
+ }
+
+ /**
+ * Load default templates.
+ *
+ * @param array $templates An array of available templates.
+ * @return array Same array of templates with new ones added.
+ */
+ public static function default_templates( $templates ) {
+ require_once( WORDCAMP_DOCS__PLUGIN_DIR . 'templates/speaker-invitation.php' );
+ $templates['speaker-invitation'] = new WordCamp_Docs_Template_Speaker_Invitation;
+
+ return $templates;
+ }
+
+ /**
+ * Add a menu item.
+ */
+ public static function admin_menu() {
+ add_menu_page( __( 'WordCamp Docs', 'wordcamporg' ), __( 'Docs', 'wordcamporg' ), 'manage_options', 'wordcamporg', array( __CLASS__, 'render_menu_page' ), 'dashicons-portfolio', 58 );
+ }
+
+ /**
+ * Our main form handler, runs at admin_init.
+ */
+ public static function form_handler() {
+ if ( empty( $_POST['wcdocs_submit'] ) )
+ return;
+
+ if ( empty( $_POST['_wpnonce'] ) )
+ return self::error( __( 'Empty nonce', 'wordcamporg' ) );
+
+ $nonce = $_POST['_wpnonce'];
+ $step = absint( $_POST['wcdocs_submit'] );
+
+ if ( ! wp_verify_nonce( $nonce, 'wcdocs_step_' . $step ) )
+ return self::error( __( 'Invalid nonce', 'wordcamporg' ) );
+
+ // Check selected template on any step.
+ $templates = self::get_templates();
+ $template = sanitize_text_field( $_POST['wcdocs_template'] );
+ if ( ! array_key_exists( $template, $templates ) )
+ return self::error( __( 'Selected template does not exist', 'wordcamporg' ) );
+
+ $template = $templates[ $template ];
+
+ switch ( $step ) {
+ case 1: // submitted step 1
+
+ // Nothing else to check on this step.
+ self::$step = 2;
+ break;
+
+ case 2: // submitted step 2
+
+ require_once( WORDCAMP_DOCS__PLUGIN_DIR . 'classes/class-wordcamp-docs-pdf-generator.php' );
+ $generator = new WordCamp_Docs_PDF_Generator;
+
+ // Sanitize input
+ $data = $template->sanitize( $_POST );
+ $generator->generate_pdf_from_string(
+ $template->render( $data ),
+ sanitize_file_name( $template->get_filename() ),
+ array( 'assets' => $template->get_assets() ) );
+
+ $generator->serve_pdf_to_browser( $template->get_filename(), true );
+ $generator->delete_tmp_folder();
+ die();
+ break;
+
+ }
+ }
+
+ /**
+ * Append an error message to self::$errors
+ *
+ * @param string $message Error message contents.
+ */
+ private static function error( $message ) {
+ self::$errors[] = $message;
+ }
+
+ /**
+ * Render the contents of our admin section.
+ */
+ public static function render_menu_page() {
+ ?>
+ <div class="wrap">
+ <h1><?php _e( 'WordCamp Docs', 'wordcamporg' ); ?></h1>
+
+ <?php if ( ! empty( self::$errors ) ) : ?>
+ <?php foreach ( self::$errors as $error ) : ?>
+ <div class="error">
+ <p><?php echo esc_html( $error ); ?></p>
+ </div>
+ <?php endforeach; ?>
+ <?php endif; ?>
+
+ <?php if ( self::$step <= 1 ) : ?>
+
+ <p><?php _e( 'This tool will help you generate various documents and forms for your WordCamp.', 'wordcamporg' ); ?></p>
+
+ <form method="POST">
+ <input type="hidden" name="wcdocs_submit" value="1" />
+ <?php wp_nonce_field( 'wcdocs_step_1' ); ?>
+
+ <p><?php _e( 'Pick a template to get started:', 'wordcamporg' ); ?></p>
+ <select name="wcdocs_template">
+ <?php foreach ( self::get_templates() as $key => $template ) : ?>
+ <option value="<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $template->get_name() ); ?></option>
+ <?php endforeach; ?>
+ </select>
+ <p class="submit">
+ <input type="submit" class="button-primary" value="Next →">
+ </p>
+ </form>
+
+ <?php elseif ( self::$step == 2 ) : ?>
+
+ <form method="POST">
+ <input type="hidden" name="wcdocs_submit" value="2" />
+ <input type="hidden" name="wcdocs_template" value="<?php echo esc_attr( $_POST['wcdocs_template'] ); ?>">
+ <?php wp_nonce_field( 'wcdocs_step_2' ); ?>
+
+ <?php
+ $template = self::get_template( $_POST['wcdocs_template'] );
+ $template->form( $_POST );
+ ?>
+
+ <p class="submit">
+ <input type="submit" class="button-primary" value="<?php esc_attr_e( 'Download PDF', 'wordcamporg' ); ?>">
+ </p>
+ </form>
+
+ <?php endif; ?>
+ </div>
+ <?php
+ }
+
+ private function __construct() {} // Not this time.
+}
+
+add_action( 'plugins_loaded', array( 'WordCamp_Docs', 'load' ) );
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampdocstemplatesassetslogopng"></a>
<div class="binary"><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-docs/templates/assets/logo.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx" style="display: block; padding: 0 10px">Index: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/templates/assets/logo.png
</span><span class="cx" style="display: block; padding: 0 10px">===================================================================
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">--- sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/templates/assets/logo.png 2016-05-30 18:15:50 UTC (rev 3273)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/templates/assets/logo.png 2016-05-31 16:39:47 UTC (rev 3274)
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/templates/assets/logo.png
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:mime-type</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+image/png
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampdocstemplatesspeakerinvitationphp"></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-docs/templates/speaker-invitation.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-docs/templates/speaker-invitation.php (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/templates/speaker-invitation.php 2016-05-31 16:39:47 UTC (rev 3274)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,200 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Speakers Invitation Template
+ *
+ * @see classes/class-wordcamp-docs.php for implementation details.
+ */
+class WordCamp_Docs_Template_Speaker_Invitation implements WordCamp_Docs_Template {
+ public function form( $data ) {
+
+ /**
+ * @todo Grab defaults from central and/or options, cpt, etc.
+ */
+ $data = wp_parse_args( $data, array(
+ 'name' => '',
+ 'gender' => '',
+ 'dates' => '',
+ 'city' => '',
+ 'country' => '',
+ 'venue_name' => '',
+ 'venue_address' => '',
+ 'signature' => '',
+ ) );
+ ?>
+ <style>
+ .wcorg-speaker-invitation-form label {
+ display: block;
+ clear: both;
+ margin-top: 12px;
+ }
+
+ .wcorg-speaker-invitation-form input,
+ .wcorg-speaker-invitation-form textarea,
+ .wcorg-speaker-invitation-form select {
+ width: 240px;
+ }
+
+ .wcorg-speaker-invitation-form textarea {
+ height: 120px;
+ }
+
+ .wcorg-speaker-invitation-form .description {
+ display: block;
+ clear: both;
+ }
+ </style>
+
+ <div class="wcorg-speaker-invitation-form">
+ <label><?php _e( 'Speaker Name:', 'wordcamporg' ); ?></label>
+ <input name="name" value="<?php echo esc_attr( $data['name'] ); ?>" />
+
+ <label><?php _e( 'Gender:', 'wordcamporg' ); ?></label>
+ <select name="gender">
+ <option value="male" <?php selected( $data['gender'], 'male' ); ?>><?php _e( 'Male', 'wordcamporg' ); ?></option>
+ <option value="female" <?php selected( $data['gender'], 'female' ); ?>><?php _e( 'Female', 'wordcamporg' ); ?></option>
+ </select>
+
+ <label><?php _e( 'Travel Dates:', 'wordcamporg' ); ?></label>
+ <input name="dates" value="<?php echo esc_attr( $data['dates'] ); ?>" />
+ <span class="description"><?php _e( 'Ex: January 15-16, 2019', 'wordcamporg' ); ?></span>
+
+ <label><?php _e( 'City:', 'wordcamporg' ); ?></label>
+ <input name="city" value="<?php echo esc_attr( $data['city'] ); ?>" />
+
+ <label><?php _e( 'Country:', 'wordcamporg' ); ?></label>
+ <input name="country" value="<?php echo esc_attr( $data['country'] ); ?>" />
+
+ <label><?php _e( 'Venue Name:', 'wordcamporg' ); ?></label>
+ <input name="venue_name" value="<?php echo esc_attr( $data['venue_name'] ); ?>" />
+
+ <label><?php _e( 'Venue Address:', 'wordcamporg' ); ?></label>
+ <input name="venue_address" value="<?php echo esc_attr( $data['venue_address'] ); ?>" />
+
+ <label><?php _e( 'Signature:', 'wordcamporg' ); ?></label>
+ <textarea name="signature"><?php echo esc_textarea( $data['signature'] ); ?></textarea>
+ <span class="description"><?php _e( 'Name, title, phone, e-mail address', 'wordcamporg' ); ?></span>
+ </div>
+
+ <?php
+ }
+
+ public function render( $data ) {
+ ob_start();
+ ?>
+<html>
+<head>
+<meta charset="UTF-8">
+<link href="http://fonts.googleapis.com/css?family=Open+Sans:300,400,700" rel="stylesheet" type="text/css" />
+<style type="text/css">
+body {
+ margin: 0;
+ padding: 0;
+ font-family: 'Open Sans', sans-serif;
+ font-size: 16px;
+ line-height: 1.5;
+ font-weight: 300;
+ color: #444;
+}
+
+p {
+ margin: 0 0 1.5em;
+}
+
+h1, h2, h3, h4, div, p, span {
+ font-family: 'Open Sans', sans-serif;
+}
+
+.wrap {
+ clear: both;
+ margin: 40px 40px;
+}
+
+.main {
+ float: left;
+ width: 100%;
+ margin-top: 40px;
+}
+
+.logo {
+ width: 300px;
+ height: 150px;
+ margin-bottom: 40px;
+}
+
+#footer {
+ position: absolute;
+ bottom: 0px;
+ left: 40px;
+ right: 40px;
+}
+</style>
+</head>
+
+<body>
+
+<div class="wrap">
+ <div class="main">
+ <img class="logo" src="logo.png" alt="WordPress Foundation">
+
+ <p><?php echo date( 'F j, Y' ); ?></p>
+ <p>To whom it may concern:</p>
+
+ <p>This letter is to confirm that <?php echo esc_html( $data['name'] ); ?> has been invited to speak at an international WordCamp conference in <?php echo esc_html( $data['city'] ) ; ?>, <?php echo esc_html( $data['country'] ) ; ?>. <?php echo $data['gender'] == 'male' ? 'His' : 'Her'; ?> participation in this conference will require <?php echo $data['gender'] == 'male' ? 'him' : 'her'; ?> to be in <?php echo esc_html( $data['city'] ); ?> from <?php echo esc_html( $data['dates'] ); ?>.<p>
+
+ <p>The conference will be held at <?php echo esc_html( $data['venue_name'] ); ?>, <?php echo esc_html( $data['venue_address'] ); ?>.</p>
+
+ <p>Please don't hesitate to contact me for any additional information regarding this invitation.</p>
+
+ <p>Sincerely,</p>
+ <p><?php echo nl2br( esc_html( $data['signature'] ) ); ?></p>
+
+ </div>
+
+ <div id="footer">
+ <p>WordPress Foundation, 200 Brannan Street Apt 239, San Francisco, CA 94107-6008, USA</p>
+ </div>
+</div>
+</body>
+</html>
+ <?php
+ return ob_get_clean();
+ }
+
+ public function sanitize( $input ) {
+ $output = array();
+ $input = wp_parse_args( $input, array(
+ 'name' => '',
+ 'gender' => '',
+ 'dates' => '',
+ 'city' => '',
+ 'country' => '',
+ 'venue_name' => '',
+ 'venue_address' => '',
+ 'signature' => '',
+ ) );
+
+ foreach ( array( 'name', 'dates', 'city', 'country', 'venue_name', 'venue_address' ) as $field )
+ $output[ $field ] = sanitize_text_field( wp_strip_all_tags( $input[ $field ] ) );
+
+ $output['gender'] = 'male';
+ if ( in_array( $input['gender'], array( 'male', 'female' ) ) )
+ $output['gender'] = $input['gender'];
+
+ $output['signature'] = wp_strip_all_tags( $input['signature'] );
+ return $output;
+ }
+
+ public function get_name() {
+ return __( 'Speaker Invitation', 'wordcamporg' );
+ }
+
+ public function get_filename() {
+ return 'speaker-invitation.pdf';
+ }
+
+ public function get_assets() {
+ return array(
+ dirname( __FILE__ ) . '/assets/logo.png',
+ );
+ }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcampdocswordcampdocsphp"></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-docs/wordcamp-docs.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-docs/wordcamp-docs.php (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-docs/wordcamp-docs.php 2016-05-31 16:39:47 UTC (rev 3274)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,14 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/*
+ * Plugin Name: WordCamp Docs
+ * Plugin URI: http://central.wordcamp.org/
+ * Description: Generate various WordCamp-related documents.
+ * Author: Konstantin Kovshenin
+ * Version: 1.0-dev
+ * License: GPL2+
+ */
+
+define( 'WORDCAMP_DOCS__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
+
+require_once( WORDCAMP_DOCS__PLUGIN_DIR . 'classes/class-wordcamp-docs.php' );
+require_once( WORDCAMP_DOCS__PLUGIN_DIR . 'classes/class-wordcamp-docs-template.php' );
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span></span></pre>
</div>
</div>
</body>
</html>