mirror of
https://github.com/WordPress/five-for-the-future.git
synced 2025-07-13 22:05:44 +03:00
Add 5ftf plugin from https://github.com/coreymckrill/5ftf
This commit is contained in:
parent
1db9ec9203
commit
697a4b2329
12 changed files with 943 additions and 0 deletions
218
plugins/wporg-5ftf/includes/company-meta.php
Executable file
218
plugins/wporg-5ftf/includes/company-meta.php
Executable file
|
@ -0,0 +1,218 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file handles the operations related to registering and handling company meta values for the CPT.
|
||||
*/
|
||||
|
||||
namespace WordPressDotOrg\FiveForTheFuture\CompanyMeta;
|
||||
use WordPressDotOrg\FiveForTheFuture\Company;
|
||||
use WP_Post, WP_Error;
|
||||
|
||||
defined( 'WPINC' ) || die();
|
||||
|
||||
const META_PREFIX = '5ftf-';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function register() {
|
||||
register_company_meta();
|
||||
}
|
||||
|
||||
add_action( 'init', __NAMESPACE__ . '\register' );
|
||||
|
||||
/**
|
||||
* Define company meta fields and their properties.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_company_meta_config() {
|
||||
return [
|
||||
'company-name' => [
|
||||
'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
|
||||
}
|
136
plugins/wporg-5ftf/includes/company.php
Executable file
136
plugins/wporg-5ftf/includes/company.php
Executable file
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file handles the operations related to setting up a custom post type. We change change the filename, namespace,
|
||||
* etc. once we have a better idea of what the CPT will be called.
|
||||
*/
|
||||
|
||||
// todo normalize text domain across all files
|
||||
|
||||
namespace WordPressDotOrg\FiveForTheFuture\Company;
|
||||
defined( 'WPINC' ) || die();
|
||||
|
||||
const CPT_SLUG = '5ftf_company';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function register() {
|
||||
register_custom_post_type();
|
||||
register_custom_taxonomy();
|
||||
}
|
||||
|
||||
add_action( 'init', __NAMESPACE__ . '\register', 0 );
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function register_custom_post_type() {
|
||||
// TODO update the labels
|
||||
$labels = array(
|
||||
'name' => _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
|
||||
}
|
89
plugins/wporg-5ftf/includes/pledge-form.php
Executable file
89
plugins/wporg-5ftf/includes/pledge-form.php
Executable file
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace WordPressDotOrg\FiveForTheFuture\PledgeForm;
|
||||
use WordPressDotOrg\FiveForTheFuture;
|
||||
use WordPressDotOrg\FiveForTheFuture\Company;
|
||||
use WordPressDotOrg\FiveForTheFuture\CompanyMeta;
|
||||
use WP_Error;
|
||||
|
||||
defined( 'WPINC' ) || die();
|
||||
|
||||
function render_shortcode( $attributes, $content ) {
|
||||
$action = filter_input( INPUT_POST, 'action' );
|
||||
$messages = [];
|
||||
$complete = false;
|
||||
$html = '';
|
||||
|
||||
if ( 'Submit' === $action ) {
|
||||
$processed = process_form( $_POST );
|
||||
|
||||
if ( is_wp_error( $processed ) ) {
|
||||
$messages = array_merge( $messages, $processed->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 );
|
||||
}
|
92
plugins/wporg-5ftf/includes/shortcodes.php
Executable file
92
plugins/wporg-5ftf/includes/shortcodes.php
Executable file
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file handles operations related to registering blocks and their assets. If there end up being more than one
|
||||
* or two, we may want to create a subfolder and have a separate file for each block.
|
||||
*/
|
||||
|
||||
namespace WordPressDotOrg\FiveForTheFuture\Blocks;
|
||||
use WordPressDotOrg\FiveForTheFuture;
|
||||
use WordPressDotOrg\FiveForTheFuture\Company;
|
||||
|
||||
defined( 'WPINC' ) || die();
|
||||
|
||||
function enqueue_scripts() {
|
||||
global $post;
|
||||
|
||||
wp_register_script(
|
||||
'5ftf-list',
|
||||
plugins_url( 'assets/js/front-end.js', __DIR__ ),
|
||||
array( 'jquery', 'underscore', 'wp-util' ),
|
||||
filemtime( FiveForTheFuture\PATH . '/assets/js/front-end.js' ),
|
||||
true
|
||||
);
|
||||
|
||||
wp_register_style(
|
||||
'5ftf-front-end',
|
||||
plugins_url( 'assets/css/front-end.css', __DIR__ ),
|
||||
array( 'dashicons' ),
|
||||
filemtime( FiveForTheFuture\PATH . '/assets/css/front-end.css' )
|
||||
);
|
||||
|
||||
if ( ! is_a( $post, 'WP_Post' ) || ! has_shortcode( $post->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' );
|
Loading…
Add table
Add a link
Reference in a new issue