settings = array( 'version' => '1.2.3', 'acf_version' => acf_mc_set_version(), 'url' => plugin_dir_url( __FILE__ ), 'path' => plugin_dir_path( __FILE__ ) ); // include field add_action('acf/include_field_types', array($this, 'include_field')); // v5/6 add_action('acf/register_fields', array($this, 'include_field')); // v4 } /* * scripts * * Enqueue necessary scripts and styles */ function scripts() { $settings = $this->settings; $version = $settings['version']; wp_register_style('css-acf-media-cluster', plugins_url('/assets/css/acf-media-cluster.css', __FILE__), null, $version, null); wp_enqueue_style('css-acf-media-cluster'); wp_register_script( 'js-acf-media-cluster', plugins_url('/assets/js/acf-media-cluster.js', __FILE__ ), 'jquery', $version, true); wp_enqueue_script('js-acf-media-cluster'); } /* * include_field * * This function will include the field type class * * @type function * @date 4/21/2023 * @since 1.0.0 * * @return void */ function include_field() { $acf_version = $this->settings['acf_version']; // include if($acf_version == "6") { include_once('fields/class-acf-media-cluster-v6.php'); } elseif($acf_version == "5") { include_once('fields/class-acf-media-cluster-v5.php'); } else { //default to version 5 include_once('fields/class-acf-media-cluster-v5.php'); } } /* * edit_fields * * Edit field arguments * * @param int $post * @param array $args * * @return array $args */ function edit_fields( $post, $args ){ return $args; } } // initialize new acf_media_cluster(); } //class_exists check /* * Save a new or existing media cluster field and settings * * @param $post_id (int) the post the field is attached to * @return n/a */ function acf_mc_save_fields( $post_id ) { // verify this came from our site and with proper authorization if ( !isset( $_POST['acf-mc-nonce'] ) || !wp_verify_nonce( sanitize_key($_POST['acf-mc-nonce']), 'editpost_'.$post_id ) ) { return; } $fields = array(); if(!empty($_POST['acf-mc-fields'])) { //content is an array, so send it to the helper function to sanitize everything, including array keys. //I'm genuinely at a loss as to another way to do this sanitization that would be acceptable and not destroy the array... $fields = acf_mc_sanitize_array_helper($_POST['acf-mc-fields']); } if( !empty($fields) and count($fields) ){ update_post_meta( $post_id, '_' . esc_attr(sanitize_text_field($_POST['acf-mc-field-name'])), esc_attr(sanitize_text_field($_POST['acf-mc-field-key']))); foreach($fields as $field_name => $ids){ //both the keys and values of the $fields array are sanitized by the acf_mc_sanitize_array_helper() function immediately preceeding this loop if( count($ids) === 1 and $ids[0] < 1){ delete_post_meta( $post_id, esc_attr(sanitize_text_field($field_name)) ); } else if( count($ids) > 1 ){ $idx = array(); foreach($ids as $id){ if( $id > 0 ){ $idx[] = esc_attr(sanitize_text_field(preg_replace('/\D/', '', $id))); } } update_post_meta( $post_id, $field_name, implode(',', $idx)); } } } add_action( 'save_post', 'acf_mc_save_fields' ); } add_action( 'save_post', 'acf_mc_save_fields' ); /* * Include the code for the media cluster field group */ function acf_mc_cluster_field_group($noajax = false, $attachment_id = 0, $fname = "", $pkey = "", $url = "", $title = "", $type = "", $size = "", $downloads = "", $showEditDel = false, $showAdd = true, $groupIndex = 0){ include( dirname(__FILE__) . '/includes/acf_mc_cluster_field_group.php' ); } add_action('wp_ajax_acf_mc_cluster_field_group', 'acf_mc_cluster_field_group'); /* * Include code for the model edit window for individual files attached to the media cluster field * * @return n/a */ function acf_mc_cluster_edit_fields(){ include( dirname(__FILE__) . '/includes/acf_mc_cluster_edit_fields.php' ); die(); } add_action('wp_ajax_acf_mc_cluster_edit_fields', 'acf_mc_cluster_edit_fields'); /* * Save edits made in the modal edit window for individual files * * @return n/a */ function acf_mc_cluster_edit_save_field(){ if( $_POST['action'] == 'acf_mc_cluster_edit_save_field' ){ global $wpdb; $t = array(); //sanitize/decode/escape the $tables JSON $get_tables = sanitize_text_field($_POST['tables']); $tables = json_decode(stripslashes($get_tables), true); foreach($tables as $i => $tableitem) { $tables[$i] = esc_attr($tableitem); } $post_id = (int) sanitize_key($_POST['post_id']); $acf_mc_key = sanitize_key($_POST['acf-mc-field-key']); foreach($tables as $a => $b){ if( !empty($t[$b]) ){ array_push($t[sanitize_text_field($b)], sanitize_text_field($a)); } else { $t[sanitize_text_field($b)] = array($a); } } if( !empty($t) ){ foreach($t as $a => $b){ if( $a == "postmeta" ){ foreach($b as $c){ update_post_meta( $post_id, $c, sanitize_text_field($_POST[$c])); } } if( $a == "posts" ){ $u = array(); $u['ID'] = $post_id; foreach( $b as $c){ if( in_array($c, array('post_content', 'post_title', 'post_excerpt')) ){ if( in_array($c, array('post_content')) ){ $u[$c] = sanitize_textarea_field($_POST[$c]); } else { $u[$c] = sanitize_text_field($_POST[$c]); } } } if( !empty($u) ){ wp_update_post( $u ); } } } update_option('acf_mc_key_' . $acf_mc_key, wp_json_encode($t) ); } } die(); } add_action('wp_ajax_acf_mc_cluster_edit_save_field', 'acf_mc_cluster_edit_save_field'); /* * Retrieves the contents of a media cluster field * * @param string $field_name - the name of the ACF field to locate * @param int $post_id - the post ID of the post to which the field is attached * @param array $args - arguements for the get_posts query. Valid arguements are orderby and order * * return array $data */ function acf_media_cluster($field_name, $post_id = null, $args = array()){ global $wpdb; $post_id = $post_id>0?$post_id:get_the_ID(); $field_name = sanitize_text_field($field_name); $orderby = !empty($args['orderby'])?sanitize_text_field($args['orderby']):'post__in'; $order = !empty($args['order'])?sanitize_text_field($args['order']):'ASC'; $field_key = get_field('_' . sanitize_text_field($field_name)); $option = json_decode(get_option('acf_mc_key_' . $field_key)); $meta_attachment_ids = array_filter(explode(',', get_field($field_name, preg_replace('/\D/', '', $post_id)))); $posts = array(); if($meta_attachment_ids) { //running get_posts() on an empty array returns unrelated data, to check that the array has values $posts = get_posts(array( 'post__in' => $meta_attachment_ids, 'post_type' => 'attachment', 'orderby' => $orderby, 'order' => $order, 'numberposts' => -1 )); } $data = array(); foreach( $posts as $a ){ //get the extension so we can set the filetype icon correctly $filename = get_attached_file( $a->ID ); $filetype = wp_check_filetype( $filename ); switch ( $filetype['ext'] ) { case 'jpeg' : $extension = 'jpg'; break; case 'docx' : $extension = 'doc'; break; case 'xlsx' : $extension = 'xls'; break; default : $extension = $filetype['ext']; break; } $data[$a->ID] = (object) array( 'ID' => $a->ID, 'post_media_url' => wp_get_attachment_url($a->ID), 'post_content' => $a->post_content, 'post_title' => $a->post_title, 'post_excerpt' => $a->post_excerpt, 'post_mime_type' => $a->post_mime_type, 'post_date' => $a->post_date, 'post_downloads' => (int) get_post_meta( $a->ID, '_acf_mc_downloads', true ), 'post_filesize' => size_format( filesize( get_attached_file( $a->ID ) ), 0 ), 'post_icon_url' => ( file_exists( plugin_dir_path( __FILE__ ) . '/assets/images/ext/' . $extension . '.gif' ) ? plugins_url( '', __FILE__ ) . '/assets/images/ext/' . $extension . '.gif' : plugins_url( '', __FILE__ ) . '/assets/images/ext/unknown.gif' ) ); } return $data; } /* * Create the shortcode to output a table of file attachments * @param array $args - the arguments for the shortcode. This variable accespts the following * string|required $field_name - Which ACF field name should be used * string $container_id - Wrap the output with your custom CSS ID * string $container_class - Wrap the output with your custom CSS class * string $skin - Do you want default CSS styling to apply. yes|no * string $format - html format for the output. table|list * string $title - a title in an container heading (H3 by default). Leave blank for no heading tag. * string $title_container - the html container to wrap the title in (H3 by default). * string $show_meta - Do you want to display file metadata (size, downloads, date)? yes|no * @param int $post_id - the id of the post the field is attached to - if not specified, uses post id for current page * * return string $html */ function acf_mc_do_shortcodes($args, $post_id = null){ global $wp; $post_id = $post_id > 0 ? $post_id : get_the_ID(); extract( shortcode_atts( array( 'field_name' => null, 'container_id' => null, 'container_class' => 'null', 'skin' => null, 'format' => 'table', 'title' => null, 'title_container' => 'h3', 'show_meta' => 'yes' ), $args ) ); if(!$field_name) { return false; } if($skin == 'yes') { $container_class .= ' acf-mc-sc-output'; } $plugin_dir = plugins_url( '', __FILE__ ); //get the data $response = acf_media_cluster($field_name, $post_id); $html = ''; if( !empty($response) and count($response) > 0 ){ if($title) { $html .= '<'.$title_container.' class="download-title">'.$title.''.$title_container.'>'; } if($format == 'table') { //format as table $html .= '
| File | '; if($show_meta == 'yes') { $html .= 'Upload Date | '; $html .= 'Filesize | '; $html .= 'Downloads | '; } $html .= ''; foreach($response as $item){ $html .= '
|---|---|---|---|
| ';
$html .= ' | ';
if($show_meta == 'yes') {
$html .= '' . date('Y-m-d', strtotime($item->post_date)) . ' | '; $html .= '' . $item->post_filesize . ' | '; $html .= '' . $item->post_downloads . ' | '; } $html .= '