From 697a4b2329d39268befedc81d67a228e0fd5cd12 Mon Sep 17 00:00:00 2001 From: Corey McKrill <916023+coreymckrill@users.noreply.github.com> Date: Fri, 27 Sep 2019 17:41:19 -0700 Subject: [PATCH] Add 5ftf plugin from https://github.com/coreymckrill/5ftf --- plugins/wporg-5ftf/assets/css/admin.css | 1 + plugins/wporg-5ftf/assets/css/front-end.css | 21 ++ plugins/wporg-5ftf/assets/js/blocks.js | 1 + plugins/wporg-5ftf/assets/js/front-end.js | 65 ++++++ plugins/wporg-5ftf/includes/company-meta.php | 218 ++++++++++++++++++ plugins/wporg-5ftf/includes/company.php | 136 +++++++++++ plugins/wporg-5ftf/includes/pledge-form.php | 89 +++++++ plugins/wporg-5ftf/includes/shortcodes.php | 92 ++++++++ plugins/wporg-5ftf/index.php | 27 +++ plugins/wporg-5ftf/views/front-end.php | 99 ++++++++ .../views/metabox-company-information.php | 39 ++++ plugins/wporg-5ftf/views/pledge-form.php | 155 +++++++++++++ 12 files changed, 943 insertions(+) create mode 100755 plugins/wporg-5ftf/assets/css/admin.css create mode 100755 plugins/wporg-5ftf/assets/css/front-end.css create mode 100755 plugins/wporg-5ftf/assets/js/blocks.js create mode 100755 plugins/wporg-5ftf/assets/js/front-end.js create mode 100755 plugins/wporg-5ftf/includes/company-meta.php create mode 100755 plugins/wporg-5ftf/includes/company.php create mode 100755 plugins/wporg-5ftf/includes/pledge-form.php create mode 100755 plugins/wporg-5ftf/includes/shortcodes.php create mode 100755 plugins/wporg-5ftf/index.php create mode 100755 plugins/wporg-5ftf/views/front-end.php create mode 100755 plugins/wporg-5ftf/views/metabox-company-information.php create mode 100755 plugins/wporg-5ftf/views/pledge-form.php diff --git a/plugins/wporg-5ftf/assets/css/admin.css b/plugins/wporg-5ftf/assets/css/admin.css new file mode 100755 index 0000000..64f72ac --- /dev/null +++ b/plugins/wporg-5ftf/assets/css/admin.css @@ -0,0 +1 @@ +/* rounded corners on contributor avatar */ \ No newline at end of file diff --git a/plugins/wporg-5ftf/assets/css/front-end.css b/plugins/wporg-5ftf/assets/css/front-end.css new file mode 100755 index 0000000..9e8cc01 --- /dev/null +++ b/plugins/wporg-5ftf/assets/css/front-end.css @@ -0,0 +1,21 @@ +/* copy homepage styles except those trendy fixed bg images */ + +.fftf-sorting-indicator { + visibility: hidden; +} + +.fftf-sorted-ascending .fftf-sorting-indicator, +.fftf-sorted-descending .fftf-sorting-indicator, +.fftf-companies th:hover .fftf-sorting-indicator { + visibility: visible; + font: normal 20px/1 dashicons; +} + +.fftf-sorting-indicator::before, +.fftf-sorted-ascending .fftf-sorting-indicator::before { + content: "\f142"; +} + +.fftf-sorted-descending .fftf-sorting-indicator::before { + content: "\f140"; +} diff --git a/plugins/wporg-5ftf/assets/js/blocks.js b/plugins/wporg-5ftf/assets/js/blocks.js new file mode 100755 index 0000000..70b786d --- /dev/null +++ b/plugins/wporg-5ftf/assets/js/blocks.js @@ -0,0 +1 @@ +// TODO diff --git a/plugins/wporg-5ftf/assets/js/front-end.js b/plugins/wporg-5ftf/assets/js/front-end.js new file mode 100755 index 0000000..dbe58c1 --- /dev/null +++ b/plugins/wporg-5ftf/assets/js/front-end.js @@ -0,0 +1,65 @@ +window.wp = window.wp || {}; + +jQuery( function( $ ) { + 'use strict'; + + var allCompanies = window.fiveFutureCompanies || {}, + sortOrder = 'ascending'; + + var app = window.wp.FiveForTheFuture = { + // jsdoc + init: function() { + app.renderTemplate( allCompanies ); + + $( '#5ftf-search' ).keyup( app.searchCompanies ); + // works on keyup but not change. isn't change better? + $( '.fftf-sorting-indicator' ).click( app.orderCompanies ); + }, + + // + renderTemplate: function( companies ) { + var $container = $( '#5ftf-companies-body' ), + template = wp.template( '5ftf-companies' ); + + $container.html( template( companies ) ); + }, + + // + searchCompanies: function( event ) { + var matches = $.extend( true, [], allCompanies ), + query = $( event.target ).val().toLowerCase(); + + matches = _.filter( matches, function( company ) { + return -1 !== company.name.toLowerCase().indexOf( query ); + } ); + + app.renderTemplate( matches ); + }, + + // + orderCompanies: function( event ) { + var $activeSortButton = $( event.target ), + $activeSortColumn = $activeSortButton.parent( 'th' ), + $sortColumns = $( '.fftf-sorting-indicator' ); + + allCompanies = _.sortBy( allCompanies, $activeSortButton.data( 'field' ) ); + + $sortColumns.removeClass( 'fftf-sorted-ascending' ); + $sortColumns.removeClass( 'fftf-sorted-descending' ); + + if ( 'ascending' === sortOrder ) { + sortOrder = 'descending'; + allCompanies = allCompanies.reverse(); + + $activeSortColumn.addClass( 'fftf-sorted-descending' ); + } else { + sortOrder = 'ascending'; + $activeSortColumn.addClass( 'fftf-sorted-ascending' ); + } + + app.renderTemplate( allCompanies ); + } + }; + + app.init(); +} ); diff --git a/plugins/wporg-5ftf/includes/company-meta.php b/plugins/wporg-5ftf/includes/company-meta.php new file mode 100755 index 0000000..6543c85 --- /dev/null +++ b/plugins/wporg-5ftf/includes/company-meta.php @@ -0,0 +1,218 @@ + [ + 'show_in_rest' => true, + 'sanitize_callback' => 'sanitize_text_field', + 'required' => true, + ], + 'company-url' => [ + 'show_in_rest' => true, + 'sanitize_callback' => 'esc_url_raw', + 'required' => true, + ], + 'company-email' => [ + 'show_in_rest' => false, + 'sanitize_callback' => 'sanitize_email', + 'required' => true, + ], + 'company-phone' => [ + 'show_in_rest' => false, + 'sanitize_callback' => 'sanitize_text_field', + 'required' => false, + ], + 'company-total-employees' => [ + 'show_in_rest' => true, + 'sanitize_callback' => 'absint', + 'required' => true, + ], + // todo add # sponsored employees here and also to form, etc + 'contact-name' => [ + 'show_in_rest' => false, + 'sanitize_callback' => 'sanitize_text_field', + 'required' => true, + ], + 'contact-wporg-username' => [ + 'show_in_rest' => false, + 'sanitize_callback' => 'sanitize_user', + 'required' => true, + ], + 'pledge-hours' => [ + 'show_in_rest' => true, + 'sanitize_callback' => 'absint', + 'required' => true, + ], + 'pledge-agreement' => [ + 'show_in_rest' => false, + 'sanitize_callback' => 'wp_validate_boolean', + 'required' => true, + ], + ]; +} + +/** + * Register post meta keys for the Company post type. + */ +function register_company_meta() { + $meta = get_company_meta_config(); + + foreach ( $meta as $key => $args ) { + $meta_key = META_PREFIX . $key; + + register_post_meta( Company\CPT_SLUG, $meta_key, $args ); + } +} + +/** + * Adds meta boxes for the custom post type + */ +function add_meta_boxes() { + add_meta_box( + 'company-information', + __( 'Company Information', 'wordpressorg' ), + __NAMESPACE__ . '\markup_meta_boxes', + Company\CPT_SLUG, + 'normal', + 'default' + ); +} + +add_action( 'admin_init', __NAMESPACE__ . '\add_meta_boxes' ); + +/** + * Builds the markup for all meta boxes + * + * @param WP_Post $company + * @param array $box + */ +function markup_meta_boxes( $company, $box ) { + /** @var $view string */ + + switch ( $box['id'] ) { + case 'company-information': + $wporg_user = get_user_by( 'login', $company->_5ftf_wporg_username ); + $avatar_url = $wporg_user ? get_avatar_url( $wporg_user->ID ) : false; + break; + } + + require_once( dirname( __DIR__ ) . '/views/metabox-' . sanitize_file_name( $box['id'] ) . '.php' ); +} + +/** + * Check that an array contains values for all required keys. + * + * @return bool|WP_Error True if all required values are present. + */ +function has_required_company_meta( array $values ) { + $config = get_company_meta_config(); + $plucked = wp_list_pluck( get_company_meta_config(), 'required' ); + $required = array_combine( array_keys( $config ), $plucked ); + + $required_keys = array_keys( $required, true ); + $error = new WP_Error(); + + foreach ( $required_keys as $key ) { + if ( ! isset( $values[ $key ] ) || empty( $values[ $key ] ) ) { + $error->add( + 'required_field', + __( 'Please fill all required fields.', 'wporg' ) + ); + + break; + } + } + + if ( ! empty( $error->get_error_messages() ) ) { + return $error; + } + + return true; +} + +/** + * Save the company data + * + * @param int $company_id + * @param WP_Post $company + */ +function save_company( $company_id, $company ) { + $ignored_actions = array( 'trash', 'untrash', 'restore' ); + + if ( isset( $_GET['action'] ) && in_array( $_GET['action'], $ignored_actions ) ) { + return; + } + + if ( ! $company || $company->post_type != Company\CPT_SLUG || ! current_user_can( 'edit_company', $company_id ) ) { + return; + } + + if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $company->post_status == 'auto-draft' ) { + return; + } + + if ( is_wp_error( has_required_company_meta( $_POST ) ) ) { + return; + } + + save_company_meta( $company_id, $_POST ); +} + + +add_action( 'save_post', __NAMESPACE__ . '\save_company', 10, 2 ); + +/** + * Save the company's meta fields + * + * @param int $company_id + * @param array $new_values + */ +function save_company_meta( $company_id, $new_values ) { + $keys = array_keys( get_company_meta_config() ); + + foreach ( $keys as $key ) { + $meta_key = META_PREFIX . $key; + + if ( isset( $new_values[ $key ] ) ) { + // Since the sanitize callback is called during this function, it could still end up + // saving an empty value to the database. + update_post_meta( $company_id, $meta_key, $new_values[ $key ] ); + } else { + delete_post_meta( $company_id, $meta_key ); + } + } + + // maybe set the wporg username as the company author, so they can edit it themselves to keep it updated, + // then make the user a contributor if they don't already have a role on the site + // setup cron to automatically email once per quarter + // "here's all the info we have: x, y, z" + // is that still accurate? if not, click here to update it + // if want to be removed from public listing, emailing support@wordcamp.org + // don't let them edit the "featured" taxonomy, only admins +} diff --git a/plugins/wporg-5ftf/includes/company.php b/plugins/wporg-5ftf/includes/company.php new file mode 100755 index 0000000..923c162 --- /dev/null +++ b/plugins/wporg-5ftf/includes/company.php @@ -0,0 +1,136 @@ + _x( 'Companies', 'Companies General Name', 'wporg' ), + 'singular_name' => _x( 'Company', 'Company Type Singular Name', 'wporg' ), + 'menu_name' => __( 'Five for the Future', 'wporg' ), + 'name_admin_bar' => __( 'Company', 'wporg' ), + 'archives' => __( 'Item Archives', 'wporg' ), + 'attributes' => __( 'Item Attributes', 'wporg' ), + 'parent_item_colon' => __( 'Parent Item:', 'wporg' ), + 'all_items' => __( 'All Items', 'wporg' ), + 'add_new_item' => __( 'Add New Company', 'wporg' ), + 'add_new' => __( 'Add New', 'wporg' ), + 'new_item' => __( 'New Item', 'wporg' ), + 'edit_item' => __( 'Edit Item', 'wporg' ), + 'update_item' => __( 'Update Item', 'wporg' ), + 'view_item' => __( 'View Item', 'wporg' ), + 'view_items' => __( 'View Items', 'wporg' ), + 'search_items' => __( 'Search Item', 'wporg' ), + 'not_found' => __( 'Not found', 'wporg' ), + 'not_found_in_trash' => __( 'Not found in Trash', 'wporg' ), + 'featured_image' => __( 'Featured Image', 'wporg' ), + 'set_featured_image' => __( 'Set featured image', 'wporg' ), + 'remove_featured_image' => __( 'Remove featured image', 'wporg' ), + 'use_featured_image' => __( 'Use as featured image', 'wporg' ), + 'insert_into_item' => __( 'Insert into item', 'wporg' ), + 'uploaded_to_this_item' => __( 'Uploaded to this item', 'wporg' ), + 'items_list' => __( 'Items list', 'wporg' ), + 'items_list_navigation' => __( 'Items list navigation', 'wporg' ), + 'filter_items_list' => __( 'Filter items list', 'wporg' ), + ); + + $args = array( + 'label' => __( 'Company Type', 'wporg' ), + 'description' => __( 'Company Type Description', 'wporg' ), + 'labels' => $labels, + 'supports' => array( 'title', 'editor', 'revisions', 'author' ), + //'taxonomies' => array( '5ftf_tax' ), + 'hierarchical' => false, + 'public' => true, + 'show_ui' => true, + 'show_in_menu' => true, + 'menu_position' => 25, + 'show_in_admin_bar' => false, + 'show_in_nav_menus' => false, + 'can_export' => false, + 'has_archive' => false, + 'exclude_from_search' => true, + 'publicly_queryable' => true, //false? + 'capability_type' => 'page', + 'show_in_rest' => true, + // rewerite url to be pretty + ); + + register_post_type( CPT_SLUG, $args ); +} + +/** + * + */ +function register_custom_taxonomy() { + // TODO update the labels + + // add taxonomy for teams + + /* + $labels = array( + 'name' => _x( 'Companies', 'Company General Name', 'wporg' ), + 'singular_name' => _x( 'Company', 'Company Singular Name', 'wporg' ), + 'menu_name' => __( 'Companies', 'wporg' ), + 'all_items' => __( 'All Companies', 'wporg' ), + 'parent_item' => __( 'Parent Item', 'wporg' ), + 'parent_item_colon' => __( 'Parent Item:', 'wporg' ), + 'new_item_name' => __( 'New Item Name', 'wporg' ), + 'add_new_item' => __( 'Add New Item', 'wporg' ), + 'edit_item' => __( 'Edit Item', 'wporg' ), + 'update_item' => __( 'Update Item', 'wporg' ), + 'view_item' => __( 'View Item', 'wporg' ), + 'separate_items_with_commas' => __( 'Separate items with commas', 'wporg' ), + 'add_or_remove_items' => __( 'Add or remove items', 'wporg' ), + 'choose_from_most_used' => __( 'Choose from the most used', 'wporg' ), + 'popular_items' => __( 'Popular Items', 'wporg' ), + 'search_items' => __( 'Search Items', 'wporg' ), + 'not_found' => __( 'Not Found', 'wporg' ), + 'no_terms' => __( 'No items', 'wporg' ), + 'items_list' => __( 'Items list', 'wporg' ), + 'items_list_navigation' => __( 'Items list navigation', 'wporg' ), + ); + + $args = array( + 'labels' => $labels, + 'hierarchical' => false, + 'public' => true, + 'show_ui' => true, + 'show_admin_column' => true, + 'show_in_nav_menus' => false, + 'show_tagcloud' => false, + 'show_in_rest' => true, + ); + + register_taxonomy( CPT_SLUG, array( CPT_SLUG ), $args ); + */ + + + // also add one for skills - design,dev, project management, etc + + // and another for using as a case study / featuring on the front end + // - this way we can use this as a database of contributors but not all of them have to be on the front end +} diff --git a/plugins/wporg-5ftf/includes/pledge-form.php b/plugins/wporg-5ftf/includes/pledge-form.php new file mode 100755 index 0000000..3584c1d --- /dev/null +++ b/plugins/wporg-5ftf/includes/pledge-form.php @@ -0,0 +1,89 @@ +get_error_messages() ); + } elseif ( 'success' === $processed ) { + $complete = true; + } + } + + if ( $complete ) { + $html = wpautop( __( 'Thank you for your submission.', 'wporg' ) ); + } else { + ob_start(); + require FiveForTheFuture\PATH . 'views/pledge-form.php'; + $html = ob_get_clean(); + } + + return $html; +} + +add_shortcode( 'five_for_the_future_pledge_form', __NAMESPACE__ . '\render_shortcode' ); + +/** + * + * + * @param array $form_values + * + * @return string|WP_Error String "success" if the form processed correctly. Otherwise WP_Error. + */ +function process_form( array $form_values ) { + $required_fields = CompanyMeta\has_required_company_meta( $form_values ); + + if ( is_wp_error( $required_fields ) ) { + return $required_fields; + } + + $name = sanitize_meta( + CompanyMeta\META_PREFIX . 'company-name', + $form_values['company-name'], + 'post', + Company\CPT_SLUG + ); + + $created = create_new_company( $name ); + + if ( is_wp_error( $created ) ) { + return $created; + } + + CompanyMeta\save_company_meta( $created, $form_values ); + // save teams contirbuted to as terms + + return 'success'; +} + +/** + * + * + * @param string $name The name of the company to use as the post title. + * + * @return int|WP_Error Post ID on success. Otherwise WP_Error. + */ +function create_new_company( $name ) { + $args = [ + 'post_type' => Company\CPT_SLUG, + 'post_title' => $name, + 'post_status' => 'pending', + 'post_author' => get_current_user_id(), // TODO is this how we want to do this? + ]; + + return wp_insert_post( $args, true ); +} \ No newline at end of file diff --git a/plugins/wporg-5ftf/includes/shortcodes.php b/plugins/wporg-5ftf/includes/shortcodes.php new file mode 100755 index 0000000..eb6680d --- /dev/null +++ b/plugins/wporg-5ftf/includes/shortcodes.php @@ -0,0 +1,92 @@ +post_content, 'five_for_the_future_companies' ) ) { + return; + } + + $params = array( + // explain 100 is just sanity limit to keep page size performant. might need to lazy-load more in the future + // maybe order by donated_employees, or rand, to ensure the top companies are always displayed first, or to make sure treta everyone equal + 'post_type' => Company\CPT_SLUG, + 'post_status' => 'publish', + 'posts_per_page' => 100, + 'orderby' => 'title', + 'order' => 'ASC', + ); + + $companies = get_posts( $params ); + + foreach ( $companies as $key => $company ) { + $teams = get_post_meta( $company->ID, '_5ftf_teams', false ); + + $companies[ $key ] = array( + 'name' => $company->post_title, + 'url' => $company->_5ftf_url, + 'total_employees' => $company->_5ftf_total_employees, + 'sponsored_employees' => $company->_5ftf_sponsored_employees, + 'hours_per_week' => $company->_5ftf_hours_per_week, + 'teams_contributing_to' => implode( ', ', $teams ), + ); + } + + $inline_script = sprintf( "var fiveFutureCompanies = %s;", wp_json_encode( $companies ) ); + + wp_enqueue_style( '5ftf-front-end' ); + wp_enqueue_script( '5ftf-list' ); + wp_add_inline_script( '5ftf-list', $inline_script ); +} +add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\enqueue_scripts' ); + +/** + * todo + * + * @return string + */ +function render_shortcode() { + // The limit is just a sanity check, but ideally all should be displayed. + // If this is reached, then refactor the page to lazy-load, etc. + + ob_start(); + require_once( dirname( __DIR__ ) . '/views/front-end.php' ); + return ob_get_clean(); +} + +add_shortcode( 'five_for_the_future_companies', __NAMESPACE__ . '\render_shortcode' ); + +// shortcode for pledge form +// form handler for pledge form + +function register() { + //register_block_type(); +} + +add_action( 'init', __NAMESPACE__ . '\register' ); diff --git a/plugins/wporg-5ftf/index.php b/plugins/wporg-5ftf/index.php new file mode 100755 index 0000000..6ef2b64 --- /dev/null +++ b/plugins/wporg-5ftf/index.php @@ -0,0 +1,27 @@ + + +
+
+

+ +

+ +

+ tragedy of the commons.', 'wordpressdotorg' ); ?> + +

+
+ +
+

+ +

+ + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + +
+ Company + + + Total # Employees + + + # Sponsored Employees + + + Hours Pledged per Week + + + Teams Contributing To + +
+ +
+
+ +
+

Take the Next Step

+ +

Have a question? Ready to get started? Get in touch and we'll help you find where you're needed the most.

+ + +
+
\ No newline at end of file diff --git a/plugins/wporg-5ftf/views/metabox-company-information.php b/plugins/wporg-5ftf/views/metabox-company-information.php new file mode 100755 index 0000000..57dba8e --- /dev/null +++ b/plugins/wporg-5ftf/views/metabox-company-information.php @@ -0,0 +1,39 @@ + + + url + total # employees + # employees pledged at least part time + total # hours pleged + what else was there? + + + + + + + + + + + + + */ ?> + +
+ + + + + + + +
+ + + +
diff --git a/plugins/wporg-5ftf/views/pledge-form.php b/plugins/wporg-5ftf/views/pledge-form.php new file mode 100755 index 0000000..17686cc --- /dev/null +++ b/plugins/wporg-5ftf/views/pledge-form.php @@ -0,0 +1,155 @@ + + + + +
+ +
+ + + +
+
+ + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ +
+ + +
+ +
+ +
+ +
+
+ +
+ + +
+ +
+ +
+ expectations of the Five For The Future program and that it will dedicate this amount of employee time per week to the WordPress project', 'wporg' ), + esc_url( '#' ) + ); + ?> + +
+
+ +
+ +
+