/home/edulekha/sriramaaresorts.com/wp-content/plugins/adminify/Inc/Modules/Folders/Folders.php
<?php
namespace WPAdminify\Inc\Modules\Folders;
use WPAdminify\Inc\Utils;
use WPAdminify\Inc\Admin\AdminSettings;
if ( !defined( 'ABSPATH' ) ) {
exit;
}
class Folders {
private static $postIds;
public $options;
public function __construct() {
$this->options = (array) AdminSettings::get_instance()->get( 'folders' );
$needed_keys = ['user_roles', 'enable_for', 'media'];
add_action( 'init', [$this, 'register_folders_terms'], 999 );
add_action( 'admin_footer', [$this, 'add_footer_markup'] );
add_action( 'admin_enqueue_scripts', [$this, 'enqueue_scripts'], PHP_INT_MAX );
add_action( 'wp_ajax_adminify_folder', [$this, 'handle_adminify_folder'] );
add_action( 'ajax_query_attachments_args', [$this, 'filter_grid'] );
add_filter( 'pre_get_posts', [$this, 'filter_list'] );
add_action( 'admin_init', [$this, 'modify_columns_actions'] );
add_action( 'print_media_templates', [$this, 'modify_media_templates'] );
add_filter( 'wp_prepare_attachment_for_js', [$this, 'modify_attachment_for_js'] );
add_action( 'pre-upload-ui', [$this, 'wp_adminify_select_folder_when_upload'] );
add_filter(
'attachment_fields_to_edit',
[$this, 'wp_adminify_edit_attachment_fields'],
25,
2
);
add_action( 'wp_ajax_wp_adminify_assign_media_folder', array($this, 'wp_adminify_handle_folder_assignment') );
add_action( 'restrict_manage_posts', [$this, 'wp_adminify_show_folders_in_list_filter'] );
add_action( 'add_attachment', [$this, 'wp_adminify_assign_media_folder_to_new_attachment'] );
add_action( 'enqueue_block_editor_assets', [$this, 'enqueue_scripts_for_media_uploads'], PHP_INT_MAX );
}
public function modify_attachment_for_js( $response ) {
if ( !(bool) $this->options['media'] ) {
return $response;
}
$folders = wp_get_post_terms( $response['id'], 'media_folder' );
$folder_ids = wp_list_pluck( $folders, 'term_id' );
$response['media_folder'] = implode( ',', $folder_ids );
return $response;
}
public function get_post_types() {
$post_types = get_post_types( [
'public' => true,
] );
// @todo add more configurations here
return $post_types;
}
public function filter_list( $query ) {
global $typenow;
global $pagenow;
$post_type = $typenow;
if ( empty( $post_type ) ) {
if ( $pagenow == 'edit.php' ) {
$post_type = 'post';
} elseif ( $pagenow == 'upload.php' ) {
$post_type = 'attachment';
}
}
if ( !isset( $query->query['post_type'] ) ) {
return $query;
}
$taxonomy = self::get_post_type_taxonomy( $post_type );
if ( !isset( $_REQUEST[$taxonomy] ) ) {
return $query;
}
$term = sanitize_text_field( wp_unslash( $_REQUEST[$taxonomy] ) );
if ( $term != '-1' ) {
return $query;
}
unset($query->query_vars[$taxonomy]);
$tax_query = [
'taxonomy' => $taxonomy,
'operator' => __( 'NOT EXISTS', 'adminify' ),
];
$query->set( 'tax_query', [$tax_query] );
$query->tax_query = new \WP_Tax_Query([$tax_query]);
return $query;
}
public function filter_grid( $args ) {
$taxonomy = self::get_post_type_taxonomy( 'attachment' );
if ( !isset( $args[$taxonomy] ) ) {
return $args;
}
$term = sanitize_text_field( $args[$taxonomy] );
if ( $term != '-1' ) {
return $args;
}
unset($args[$taxonomy]);
$args['tax_query'] = [[
'taxonomy' => $taxonomy,
'operator' => __( 'NOT EXISTS', 'adminify' ),
]];
return $args;
}
public function is_module_active( $post_type = null ) {
$current_screen = get_current_screen();
if ( empty( $current_screen->base ) || !in_array( $current_screen->base, ['upload', 'edit', 'media'] ) ) {
return false;
}
if ( $current_screen->base === 'media' && $current_screen->action === 'add' ) {
$post_type = 'attachment';
}
if ( empty( $post_type ) ) {
if ( empty( $post_type = $current_screen->post_type ) ) {
return false;
}
}
if ( $post_type == 'attachment' ) {
return (bool) $this->options['media'];
}
$default_post_types = ['post', 'page'];
$folders_enable_for = (array) $this->options['enable_for'];
$folders_enable_for = array_intersect( $folders_enable_for, $default_post_types );
if ( in_array( $post_type, $folders_enable_for ) ) {
return true;
}
return false;
}
// Add folder app markup in footer but move it to wpbody
public function add_footer_markup() {
if ( $this->is_module_active() ) {
?>
<div id="wp-adminify--folder-app"></div>
<script>
(function() {
var folderApp = document.getElementById('wp-adminify--folder-app');
var wpbody = document.getElementById('wpbody');
var wpbodyContent = document.getElementById('wpbody-content');
if (folderApp && wpbody && wpbodyContent) {
wpbody.insertBefore(folderApp, wpbodyContent);
}
})();
</script>
<?php
}
}
public function get_uncategorized_posts( $post_type ) {
global $wpdb;
$post_table = $wpdb->prefix . 'posts';
$term_table = $wpdb->prefix . 'term_relationships';
$term_taxonomy_table = $wpdb->prefix . 'term_taxonomy';
$post_type_tax = self::get_post_type_taxonomy( $post_type );
if ( $post_type != 'attachment' ) {
$query = "SELECT COUNT(DISTINCT({$post_table}.ID)) AS total_records FROM {$post_table} WHERE 1=1 AND (\n NOT EXISTS (\n SELECT 1\n FROM {$term_table}\n INNER JOIN {$term_taxonomy_table}\n ON {$term_taxonomy_table}.term_taxonomy_id = {$term_table}.term_taxonomy_id\n WHERE {$term_taxonomy_table}.taxonomy = '%s'\n AND {$term_table}.object_id = {$post_table}.ID\n )\n ) AND {$post_table}.post_type = '%s' AND (({$post_table}.post_status = 'publish' OR {$post_table}.post_status = 'future' OR {$post_table}.post_status = 'draft' OR {$post_table}.post_status = 'private'))";
} else {
$query = "SELECT COUNT(DISTINCT({$post_table}.ID)) AS total_records FROM {$post_table} WHERE 1=1 AND (\n NOT EXISTS (\n SELECT 1\n FROM {$term_table}\n INNER JOIN {$term_taxonomy_table}\n ON {$term_taxonomy_table}.term_taxonomy_id = {$term_table}.term_taxonomy_id\n WHERE {$term_taxonomy_table}.taxonomy = '%s'\n AND {$term_table}.object_id = {$post_table}.ID\n )\n ) AND {$post_table}.post_type = '%s' AND {$post_table}.post_status = 'inherit'";
}
$query = $wpdb->prepare( $query, $post_type_tax, $post_type );
$total = $wpdb->get_var( $query );
return ( empty( $total ) ? 0 : $total );
}
public function get_folders( $post_type, $post_type_tax ) {
$folders = get_terms( $post_type_tax, [
'hide_empty' => false,
'pad_counts' => true,
] );
if ( is_wp_error( $folders ) ) {
return [];
}
foreach ( $folders as $folder ) {
$posts = $this->get_posts_by_folder( $folder->term_id, $post_type, $post_type_tax );
$color = get_term_meta( $folder->term_id, '_wp_adminify_fodler_color', true );
if ( empty( $color ) ) {
$color = '';
}
$folder->color = $color;
$folder->count = count( $posts );
$folder->posts = $posts;
}
return $folders;
}
public function enqueue_scripts() {
if ( !$this->is_module_active() ) {
return;
}
$current_screen = get_current_screen();
wp_enqueue_style(
'wp-adminify--folder',
WP_ADMINIFY_URL . 'assets/admin/css/wp-adminify--folder' . Utils::assets_ext( '.css' ),
[],
WP_ADMINIFY_VER
);
wp_enqueue_style(
'wp-adminify-simple-line-icons',
WP_ADMINIFY_ASSETS . '/vendors/font-icons/simple-line-icons/css/simple-line-icons' . Utils::assets_ext( '.css' ),
false,
WP_ADMINIFY_VER
);
$post_type = $current_screen->post_type;
$post_type_tax = self::get_post_type_taxonomy( $post_type );
if ( $current_screen->base === 'media' && $current_screen->action === 'add' ) {
$post_type = 'attachment';
$post_type_tax = 'media_folder';
}
$media_folders = get_terms( [
'taxonomy' => 'media_folder',
'hide_empty' => false,
] );
$media_folders_data = [];
foreach ( $media_folders as $media_folder ) {
$media_folders_data[$media_folder->term_id] = [
'name' => $media_folder->name,
'slug' => $media_folder->slug,
'term_id' => $media_folder->term_id,
];
}
$data = [
'adminurl' => admin_url(),
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'post_type' => $post_type,
'nonce' => wp_create_nonce( '__adminify-folder-secirity__' ),
'post_type_tax' => $post_type_tax,
'media_folders_data' => $media_folders_data,
'is_pro' => wp_validate_boolean( jltwp_adminify()->can_use_premium_code__premium_only() ),
'pro_notice' => Utils::adminify_upgrade_pro(),
];
$data = array_merge( $data, $this->refreshed_folder_data( $post_type, $post_type_tax ) );
// Adminify Folder
// wp_enqueue_script('wp-adminify-vue-vendors', WP_ADMINIFY_ASSETS . 'admin/js/vendor' . Utils::assets_ext('.js'), [], WP_ADMINIFY_VER, true);
wp_enqueue_script(
'wp-adminify--folder',
WP_ADMINIFY_ASSETS . 'admin/js/wp-adminify--folder' . Utils::assets_ext( '.js' ),
array('jquery', 'jquery-ui-droppable', 'jquery-ui-draggable'),
WP_ADMINIFY_VER,
true
);
wp_localize_script( 'wp-adminify--folder', 'wp_adminify__folder_data', $data );
$inline_script_content = '
(function($) {
$(document).ready(function() {
let selectedFolder = null;
if (typeof wp.media !== "undefined") {
const urlParams = new URLSearchParams(window.location.search);
const currentFolder = urlParams.get("media_folder");
selectedFolder = currentFolder;
const MediaLibraryTaxonomyFilter = wp.media.view.AttachmentFilters.extend({
id: "wp-adminify-media-folder-filter",
createFilters: function() {
const filters = {};
filters.all = {
text: "All folders",
props: { folders: "" },
priority: 10
};
_.each(window.wp_adminify__folder_data?.media_folders_data || {}, function(value) {
filters[value.slug] = {
text: value.name,
props: { folders: value.slug },
priority: 20
};
});
this.filters = filters;
},
initialize: function() {
wp.media.view.AttachmentFilters.prototype.initialize.apply(this, arguments);
if (currentFolder) {
this.model.set("folders", currentFolder);
setTimeout(() => {
this.$el.find("select").val(currentFolder);
}, 100);
}
}
});
const AttachmentsBrowser = wp.media.view.AttachmentsBrowser;
wp.media.view.AttachmentsBrowser = AttachmentsBrowser.extend({
createToolbar: function() {
AttachmentsBrowser.prototype.createToolbar.call(this);
this.toolbar.set("MediaLibraryTaxonomyFilter", new MediaLibraryTaxonomyFilter({
controller: this.controller,
model: this.collection.props,
priority: -75
}).render());
}
});
}
if (typeof wp.Uploader === "function") {
$.extend(wp.Uploader.prototype, {
init: function() {
selectedFolder = $("#folders").val() || currentFolder;
$("body").on("change", "#folders", function() {
selectedFolder = $(this).val();
});
if (this.uploader) {
this.uploader.bind("BeforeUpload", function(up, file) {
up.settings.multipart_params = up.settings.multipart_params || {};
up.settings.multipart_params.folder_id = selectedFolder;
});
this.uploader.bind("UploadComplete", function() {
if (typeof wp !== "undefined" && wp.media && wp.media.frame) {
const frame = wp.media.frame;
const state = frame.state();
const library = state.get("library");
if (library) {
library.props.set("ignore", Date.now());
state.trigger("reset");
}
}
});
}
}
});
}
});
})(jQuery);
';
wp_add_inline_script( 'media-views', $inline_script_content, 'after' );
}
function enqueue_scripts_for_media_uploads() {
wp_enqueue_media();
wp_enqueue_script( 'media-views' );
wp_enqueue_script( 'wp-dom-ready' );
// Enqueue folder styles for modal
wp_enqueue_style(
'wp-adminify--folder',
WP_ADMINIFY_URL . 'assets/admin/css/wp-adminify--folder' . Utils::assets_ext( '.css' ),
[],
WP_ADMINIFY_VER
);
wp_enqueue_style(
'wp-adminify-simple-line-icons',
WP_ADMINIFY_ASSETS . '/vendors/font-icons/simple-line-icons/css/simple-line-icons' . Utils::assets_ext( '.css' ),
false,
WP_ADMINIFY_VER
);
// Enqueue folder script for modal sidebar
wp_enqueue_script(
'wp-adminify--popup-folder',
WP_ADMINIFY_ASSETS . 'admin/js/wp-adminify--popup-folder' . Utils::assets_ext( '.js' ),
array(
'jquery',
'jquery-ui-droppable',
'jquery-ui-draggable',
'wp-element',
'wp-dom-ready'
),
WP_ADMINIFY_VER,
true
);
wp_enqueue_script(
'wp-adminify--folder',
WP_ADMINIFY_ASSETS . 'admin/js/wp-adminify--folder' . Utils::assets_ext( '.js' ),
array(
'jquery',
'jquery-ui-droppable',
'jquery-ui-draggable',
'wp-element',
'wp-dom-ready'
),
WP_ADMINIFY_VER,
true
);
$post_type = 'attachment';
$post_type_tax = 'media_folder';
// Get simplified folder data for dropdown filter
$media_folders = get_terms( [
'taxonomy' => 'media_folder',
'hide_empty' => false,
] );
$media_folders_data = [];
foreach ( $media_folders as $folder ) {
$media_folders_data[$folder->term_id] = [
'name' => $folder->name,
'slug' => $folder->slug,
'term_id' => $folder->term_id,
];
}
// Build full folder data for React sidebar
$data = apply_filters( 'wp_adminify_folder_data', [
'adminurl' => admin_url(),
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'post_type' => $post_type,
'nonce' => wp_create_nonce( '__adminify-folder-secirity__' ),
'post_type_tax' => $post_type_tax,
'media_folders_data' => $media_folders_data,
'is_pro' => wp_validate_boolean( jltwp_adminify()->can_use_premium_code__premium_only() ),
'pro_notice' => Utils::adminify_upgrade_pro(),
'is_rtl' => is_rtl(),
] );
// Add full folder data (folders, hierarchy, counts)
$data = array_merge( $data, $this->refreshed_folder_data( $post_type, $post_type_tax ) );
// Localize the data to multiple script handles (like FileBird approach)
// This ensures data is available in different contexts
wp_localize_script( 'wp-adminify--folder', 'wp_adminify__folder_data', $data );
wp_localize_script( 'wp-dom-ready', 'wp_adminify__folder_data', $data );
wp_localize_script( 'media-views', 'wp_adminify__folder_data', $data );
$inline_script_content = '
(function($) {
$(document).ready(function() {
let selectedFolder = null;
if (typeof wp.media !== "undefined") {
const urlParams = new URLSearchParams(window.location.search);
const currentFolder = urlParams.get("media_folder");
selectedFolder = currentFolder;
const MediaLibraryTaxonomyFilter = wp.media.view.AttachmentFilters.extend({
id: "wp-adminify-media-folder-filter",
createFilters: function() {
const filters = {};
filters.all = {
text: "All folders",
props: { folders: "" },
priority: 10
};
_.each(window.wp_adminify__folder_data?.media_folders_data || {}, function(value) {
filters[value.slug] = {
text: value.name,
props: { folders: value.slug },
priority: 20
};
});
this.filters = filters;
},
initialize: function() {
wp.media.view.AttachmentFilters.prototype.initialize.apply(this, arguments);
if (currentFolder) {
this.model.set("folders", currentFolder);
setTimeout(() => {
this.$el.find("select").val(currentFolder);
}, 100);
}
}
});
// Note: AttachmentsBrowser extension for folder sidebar is handled in wp-adminify--folder.js
}
if (typeof wp.Uploader === "function") {
$.extend(wp.Uploader.prototype, {
init: function() {
selectedFolder = $("#folders").val() || currentFolder;
$("body").on("change", "#folders", function() {
selectedFolder = $(this).val();
});
if (this.uploader) {
this.uploader.bind("BeforeUpload", function(up, file) {
up.settings.multipart_params = up.settings.multipart_params || {};
up.settings.multipart_params.folder_id = selectedFolder;
});
this.uploader.bind("UploadComplete", function() {
if (typeof wp !== "undefined" && wp.media && wp.media.frame) {
const frame = wp.media.frame;
const state = frame.state();
const library = state.get("library");
if (library) {
library.props.set("ignore", Date.now());
state.trigger("reset");
}
}
});
}
}
});
}
});
})(jQuery);
';
wp_add_inline_script( 'media-views', $inline_script_content, 'after' );
}
public function modify_media_templates() {
?>
<script>
var attachment_template = jQuery('#tmpl-attachment');
if ( attachment_template.length ) {
var template = attachment_template.html().replace( 'data.orientation }}">', 'data.orientation }}" data-folders="{{ data.media_folder }}">' );
attachment_template.html( template );
}
</script>
<?php
}
public function handle_adminify_folder() {
check_ajax_referer( '__adminify-folder-secirity__' );
if ( !current_user_can( 'edit_posts' ) ) {
wp_send_json_error( array(
'message' => __( 'You do not have permission to perform this action.', 'adminify' ),
) );
}
if ( !empty( $_POST['route'] ) ) {
$route_handler = 'handle_' . sanitize_text_field( wp_unslash( $_POST['route'] ) );
if ( is_callable( get_class( $this ), $route_handler ) ) {
$this->{$route_handler}( $_POST );
}
}
wp_send_json_error( [
'message' => __( 'Something is wrong, no route found' ),
], 400 );
}
public function handle_delete_folders( $data ) {
if ( empty( $data['term_ids'] ) || empty( $data['post_type'] ) || empty( $data['post_type_tax'] ) ) {
wp_send_json_error( [
'message' => __( 'Something is wrong, few args are missing' ),
], 400 );
}
$term_ids = $data['term_ids'];
$post_type = $data['post_type'];
$post_type_tax = $data['post_type_tax'];
foreach ( $term_ids as $term_id ) {
wp_delete_term( $term_id, $post_type_tax );
}
$data = $this->refreshed_folder_data( $post_type, $post_type_tax );
wp_send_json_success( $data );
}
public function handle_rename_folder( $data ) {
if ( empty( $data['term_id'] ) || empty( $data['post_type'] ) || empty( $data['post_type_tax'] ) || empty( $data['folder_name'] ) || empty( $data['folder_color_tag'] ) ) {
wp_send_json_error( [
'message' => __( 'Something is wrong, few args are missing' ),
], 400 );
}
$term_id = $data['term_id'];
$folder_name = $data['folder_name'];
$post_type = $data['post_type'];
$post_type_tax = $data['post_type_tax'];
$folder_color_tag = $data['folder_color_tag'];
$update = wp_update_term( $term_id, $post_type_tax, [
'name' => $folder_name,
] );
if ( is_wp_error( $update ) ) {
wp_send_json_success( [
'message' => $update->get_error_message(),
], 202 );
}
update_term_meta( $term_id, '_wp_adminify_fodler_color', $folder_color_tag );
$data = $this->refreshed_folder_data( $post_type, $post_type_tax );
wp_send_json_success( $data );
}
public function handle_move_to_folder( $data ) {
if ( empty( $data['post_ids'] ) || empty( $data['folder_id'] ) || empty( $data['post_type'] ) || empty( $data['post_type_tax'] ) ) {
wp_send_json_error( [
'message' => __( 'Something is wrong, few args are missing' ),
], 400 );
}
$post_ids = (array) $data['post_ids'];
$folder_id = sanitize_text_field( $data['folder_id'] );
$post_type = sanitize_text_field( $data['post_type'] );
$post_type_tax = sanitize_text_field( $data['post_type_tax'] );
global $mode;
$mode = ( empty( $data['mode'] ) ? 'list' : sanitize_text_field( $data['mode'] ) );
$move_to_folder = wp_validate_boolean( $data['move_to_folder'] );
foreach ( $post_ids as $post_id ) {
if ( $folder_id == 'uncategorized' ) {
wp_set_object_terms(
$post_id,
'',
$post_type_tax,
false
);
continue;
}
$term = get_term( $folder_id );
if ( !empty( $term ) && isset( $term->slug ) ) {
wp_set_object_terms(
$post_id,
$term->slug,
$post_type_tax,
!$move_to_folder
);
}
}
$updated_rows = '';
if ( $post_type == 'attachment' ) {
global $wp_query;
$args = [
'posts_per_page' => count( $post_ids ),
'orderby' => 'title',
'order' => 'ASC',
'post_type' => $post_type,
'post_status' => 'any',
'post__in' => $post_ids,
];
$wp_query = new \WP_Query($args);
$wp_list_table = \_get_list_table( 'WP_Media_List_Table', [
'screen' => sanitize_text_field( wp_unslash( $_POST['screen'] ) ),
] );
foreach ( $post_ids as $post_id ) {
ob_start();
$wp_list_table->display_rows();
$updated_rows = ob_get_clean();
}
} else {
$wp_list_table = \_get_list_table( 'WP_Posts_List_Table', [
'screen' => sanitize_text_field( wp_unslash( $_POST['screen'] ) ),
] );
foreach ( $post_ids as $post_id ) {
$level = 0;
if ( is_post_type_hierarchical( $wp_list_table->screen->post_type ) ) {
$request_post = [get_post( $post_id )];
$parent = $request_post[0]->post_parent;
while ( $parent > 0 ) {
$parent_post = get_post( $parent );
$parent = $parent_post->post_parent;
$level++;
}
}
ob_start();
$wp_list_table->display_rows( [get_post( $post_id )], $level );
$updated_rows .= ob_get_clean();
}
}
$data = [
'updated_rows' => $updated_rows,
];
$data = array_merge( $data, $this->refreshed_folder_data( $post_type, $post_type_tax ) );
wp_send_json_success( $data );
}
public function handle_refresh_folders( $data ) {
if ( empty( $data['post_type'] ) || empty( $data['post_type_tax'] ) ) {
wp_send_json_error( [
'message' => __( 'Something is wrong, few args are missing' ),
], 400 );
}
$post_type = $data['post_type'];
$post_type_tax = $data['post_type_tax'];
wp_send_json_success( $this->refreshed_folder_data( $post_type, $post_type_tax ) );
}
public function handle_create_new_folder( $data ) {
if ( empty( $data['post_type'] ) || empty( $data['post_type_tax'] ) ) {
wp_send_json_error( [
'message' => __( 'Something is wrong, few args are missing' ),
], 400 );
}
if ( empty( $data['new_folder_name'] ) || empty( $data['folder_color_tag'] ) ) {
wp_send_json_error( [
'message' => __( 'Something is wrong, few args are missing' ),
], 400 );
}
$post_type = $data['post_type'];
$post_type_tax = $data['post_type_tax'];
$new_folder_name = $data['new_folder_name'];
$folder_color_tag = $data['folder_color_tag'];
$parent_term_id = 0;
if ( jltwp_adminify()->can_use_premium_code__premium_only() && !empty( $data['parent_folder'] ) ) {
$parent_term_id = $data['parent_folder'];
}
$insert_data = wp_insert_term( $new_folder_name, $post_type_tax, [
'parent' => $parent_term_id,
] );
if ( !is_wp_error( $insert_data ) ) {
update_term_meta( $insert_data['term_id'], '_wp_adminify_fodler_color', $folder_color_tag );
wp_send_json_success( $this->refreshed_folder_data( $post_type, $post_type_tax ) );
} else {
wp_send_json_success( [
'message' => $insert_data->get_error_message(),
], 202 );
}
}
function refreshed_folder_data( $post_type, $post_type_tax ) {
remove_filter( 'pre_get_posts', [$this, 'filter_list'] );
return [
'folders' => $this->get_folders( $post_type, $post_type_tax ),
'folder_hierarchy' => _get_term_hierarchy( $post_type_tax ),
'total_posts' => wp_count_posts( $post_type ),
'total_uncat_posts' => $this->get_uncategorized_posts( $post_type ),
];
}
function wp_set_post_categories( $post_ID = 0, $post_categories = [], $append = false ) {
$post_ID = (int) $post_ID;
$post_type = get_post_type( $post_ID );
$post_status = get_post_status( $post_ID );
// If $post_categories isn't already an array, make it one.
$post_categories = (array) $post_categories;
if ( empty( $post_categories ) ) {
/**
* Filters post types (in addition to 'post') that require a default category.
*
* @since 5.5.0
*
* @param string[] $post_types An array of post type names. Default empty array.
*/
$default_category_post_types = apply_filters( 'default_category_post_types', [] );
// Regular posts always require a default category.
$default_category_post_types = array_merge( $default_category_post_types, ['post'] );
if ( in_array( $post_type, $default_category_post_types, true ) && is_object_in_taxonomy( $post_type, 'category' ) && 'auto-draft' !== $post_status ) {
$post_categories = [get_option( 'default_category' )];
$append = false;
} else {
$post_categories = [];
}
} elseif ( 1 === count( $post_categories ) && '' === reset( $post_categories ) ) {
return true;
}
return wp_set_post_terms(
$post_ID,
$post_categories,
'category',
$append
);
}
public function get_posts_by_folder( $term_id, $post_type, $taxonomy ) {
$posts = get_posts( [
'numberposts' => -1,
'post_status' => 'any',
'post_type' => $post_type,
'fields' => 'ids',
'tax_query' => [[
'operator' => 'IN',
'taxonomy' => $taxonomy,
'field' => 'term_id',
'terms' => $term_id,
]],
] );
return $posts;
}
public static function get_post_type_taxonomy( $post_type ) {
if ( $post_type == 'page' ) {
return 'folder';
}
if ( $post_type == 'attachment' ) {
$post_type = 'media';
}
return $post_type . '_folder';
}
public function register_folders_terms() {
$post_types = $this->get_post_types();
foreach ( $post_types as $post_type ) {
$labels = [
'name' => esc_html__( 'Folders', 'adminify' ),
'singular_name' => esc_html__( 'Folder', 'adminify' ),
'all_items' => esc_html__( 'All Folders', 'adminify' ),
'edit_item' => esc_html__( 'Edit Folder', 'adminify' ),
'update_item' => esc_html__( 'Update Folder', 'adminify' ),
'add_new_item' => esc_html__( 'Add New Folder', 'adminify' ),
'new_item_name' => esc_html__( 'Add folder name', 'adminify' ),
'menu_name' => esc_html__( 'Folders', 'adminify' ),
'search_items' => esc_html__( 'Search Folders', 'adminify' ),
'parent_item' => esc_html__( 'Parent Folder', 'adminify' ),
];
$args = [
'label' => esc_html__( 'Folder', 'adminify' ),
'labels' => $labels,
'show_tagcloud' => false,
'hierarchical' => true,
'public' => false,
'show_ui' => false,
'show_in_menu' => false,
'show_in_rest' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => false,
'capabilities' => [
'manage_terms' => 'manage_categories',
'edit_terms' => 'manage_categories',
'delete_terms' => 'manage_categories',
'assign_terms' => 'manage_categories',
],
];
$taxonomy = self::get_post_type_taxonomy( $post_type );
register_taxonomy( $taxonomy, $post_type, $args );
}
}
public function modify_columns_actions() {
$post_types = $this->get_post_types();
foreach ( $post_types as $post_type ) {
if ( $post_type == 'post' ) {
add_filter( 'manage_edit-post_columns', [$this, 'manage_columns_head'] );
add_filter( 'manage_posts_columns', [$this, 'manage_columns_head'] );
add_action(
'manage_posts_custom_column',
[$this, 'manage_columns_content'],
10,
2
);
add_filter( 'bulk_actions-edit-post', [$this, 'custom_bulk_action'] );
} elseif ( $post_type == 'page' ) {
add_filter( 'manage_edit-page_columns', [$this, 'manage_columns_head'] );
add_filter( 'manage_page_posts_columns', [$this, 'manage_columns_head'] );
add_action(
'manage_page_posts_custom_column',
[$this, 'manage_columns_content'],
10,
2
);
add_filter( 'bulk_actions-edit-page', [$this, 'custom_bulk_action'] );
} elseif ( $post_type == 'attachment' ) {
add_filter( 'manage_media_columns', [$this, 'manage_columns_head'] );
add_action(
'manage_media_custom_column',
[$this, 'manage_columns_content'],
10,
2
);
} else {
add_filter( 'manage_edit-' . $post_type . '_columns', [$this, 'manage_columns_head'], 99999 );
add_action(
'manage_' . $post_type . '_posts_custom_column',
[$this, 'manage_columns_content'],
2,
2
);
add_filter( 'bulk_actions-edit-' . $post_type, [$this, 'custom_bulk_action'] );
}
}
}
function manage_columns_head( $posts_columns ) {
$post_type = null;
if ( isset( $_REQUEST['post_type'] ) ) {
$post_type = sanitize_text_field( wp_unslash( $_REQUEST['post_type'] ) );
}
if ( $this->is_module_active( $post_type ) ) {
$title = sprintf( __( 'Moving selected items', 'adminify' ), '<span class="adminify-folder-items--count"></span>' );
return [
'adminify_move' => '<div class="adminify-move-multiple adminify-col" title="' . esc_attr__( 'Move selected items', 'adminify' ) . '"><span class="dashicons dashicons-move"></span><span class="adminify-move-file--title">' . wp_kses_post( $title ) . '</span><div class="adminify-items"></div></div>',
] + $posts_columns;
}
return $posts_columns;
}
function manage_columns_content( $column_name, $post_ID ) {
$post_type = null;
if ( isset( $_REQUEST['post_type'] ) ) {
$post_type = sanitize_text_field( wp_unslash( $_REQUEST['post_type'] ) );
}
$postIDs = self::$postIds;
$folder_ids = $this->get_folders_by_post( $post_ID );
$folder_ids = implode( ',', $folder_ids );
if ( !is_array( $postIDs ) ) {
$postIDs = [];
}
if ( !in_array( $post_ID, $postIDs ) ) {
$postIDs[] = $post_ID;
self::$postIds = $postIDs;
if ( $this->is_module_active( $post_type ) ) {
if ( $column_name == 'adminify_move' ) {
$title = get_the_title();
if ( strlen( $title ) > 20 ) {
$title = substr( $title, 0, 20 ) . '...';
}
echo Utils::wp_kses_custom( '<div class="adminify-move-file" data-id="' . esc_attr( $post_ID ) . '" data-folders="' . esc_attr( $folder_ids ) . '"><span class="adminify-move dashicons dashicons-move"></span><span class="adminify-move-file--title">' . esc_html( $title ) . '</span></div>' );
}
}
}
}
public function get_folders_by_post( $post_ID, $return_type = 'ids' ) {
$folder_tax = self::get_post_type_taxonomy( get_post_type( $post_ID ) );
$folders = wp_get_post_terms( $post_ID, $folder_tax );
if ( $return_type == 'ids' ) {
return wp_list_pluck( $folders, 'term_id' );
}
return $folders;
}
public function custom_bulk_action( $bulk_actions ) {
$bulk_actions['move_to_folder'] = __( 'Move to Folder', 'adminify' );
return $bulk_actions;
}
public function wp_adminify_select_folder_when_upload() {
if ( !$this->options['media'] ) {
return;
}
$selected = ( isset( $_GET['media_folder'] ) ? $_GET['media_folder'] : '' );
wp_dropdown_categories( array(
'show_option_none' => 'Choose folder',
'taxonomy' => 'media_folder',
'name' => 'folder_id',
'id' => 'folders',
'orderby' => 'name',
'selected' => $selected,
'hierarchical' => true,
'value_field' => 'slug',
'hide_empty' => 0,
) );
}
public function wp_adminify_assign_media_folder_to_new_attachment( $post_ID ) {
if ( isset( $_POST['folder_id'] ) && !empty( $_POST['folder_id'] ) && $_POST['folder_id'] !== '-1' ) {
$term = get_term_by( 'slug', $_POST['folder_id'], 'media_folder' );
if ( !$term && is_numeric( $_POST['folder_id'] ) ) {
$term = get_term_by( 'id', (int) $_POST['folder_id'], 'media_folder' );
}
if ( $term && !is_wp_error( $term ) ) {
wp_set_object_terms( $post_ID, (int) $term->term_id, 'media_folder' );
$post_type = 'attachment';
$post_type_tax = $_POST['folder_id'];
} else {
error_log( 'Media Folder: Could not find term for value "' . $_POST['folder_id'] . '" for attachment ID ' . $post_ID );
}
$this->refreshed_folder_data( $post_type, $post_type_tax );
}
}
public function wp_adminify_edit_attachment_fields( $form_fields, $post ) {
if ( !$this->options['media'] ) {
return;
}
$folder_fields = array(
'label' => 'Folders',
'show_in_edit' => false,
'input' => 'html',
'value' => '',
);
$taxonomy_name = 'media_folder';
// get the assigned media library folders from the cache
$terms = get_the_terms( $post->ID, $taxonomy_name );
if ( $terms ) {
$folder_fields['value'] = join( ', ', wp_list_pluck( $terms, 'slug' ) );
}
ob_start();
$this->wp_adminify_render_terms_dropdown( $post->ID, $taxonomy_name );
$html = ob_get_contents();
ob_end_clean();
$folder_fields['html'] = $html;
$form_fields[$taxonomy_name] = $folder_fields;
return $form_fields;
}
public function wp_adminify_render_terms_dropdown( $post_id, $taxonomy ) {
$selected_terms = wp_get_object_terms( $post_id, $taxonomy, array(
'fields' => 'ids',
) );
$selected_term = ( !empty( $selected_terms ) ? $selected_terms[0] : 0 );
$terms = get_terms( array(
'taxonomy' => $taxonomy,
'hide_empty' => false,
'parent' => 0,
) );
echo '<select name="media_folder_select" class="media-folder-select" data-attachment-id="' . $post_id . '">';
echo '<option value="">— Select Folder —</option>';
if ( !empty( $terms ) && !is_wp_error( $terms ) ) {
foreach ( $terms as $term ) {
$this->wp_adminify_render_term_option( $term, $selected_term, $taxonomy );
}
}
echo '</select>';
$this->wp_adminify_add_folder_script();
}
public function wp_adminify_render_term_option(
$term,
$selected_term,
$taxonomy,
$depth = 0
) {
$indent = str_repeat( ' ', $depth );
$selected = selected( $term->term_id, $selected_term, false );
echo sprintf(
'<option value="%s" %s>%s%s</option>',
$term->term_id,
$selected,
$indent,
esc_html( $term->name )
);
// Get children
$children = get_terms( array(
'taxonomy' => $taxonomy,
'hide_empty' => false,
'parent' => $term->term_id,
) );
if ( !empty( $children ) && !is_wp_error( $children ) ) {
foreach ( $children as $child ) {
$this->wp_adminify_render_term_option(
$child,
$selected_term,
$taxonomy,
$depth + 1
);
}
}
}
public function wp_adminify_add_folder_script() {
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('.media-folder-select').on('change', function() {
var $select = $(this);
var attachment_id = $select.data('attachment-id');
var term_id = $select.val();
if (!term_id) return;
// Store original value in case we need to revert
$select.data('prev-value', $select.val());
// Show loading indicator
var $spinner = $('<span class="spinner is-active"></span>');
$select
.prop('disabled', true)
.after($spinner);
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'wp_adminify_assign_media_folder',
attachment_id: attachment_id,
term_id: term_id,
security: '<?php
echo wp_create_nonce( "wp_adminify_media_folder" );
?>'
},
success: function(response) {
if (response.success) {
} else {
$select.val($select.data('prev-value'));
console.log('Error: ' + (response.data || 'Failed to update folder'));
}
},
error: function(xhr, status, error) {
$select.val($select.data('prev-value'));
console.log('Error: ' + error);
},
complete: function() {
// Always clean up
$spinner.remove();
$select.prop('disabled', false);
}
});
});
});
</script>
<?php
}
public function wp_adminify_handle_folder_assignment() {
check_ajax_referer( 'wp_adminify_media_folder', 'security' );
if ( !current_user_can( 'upload_files' ) ) {
wp_send_json_error( __( 'You do not have permission to perform this action.', 'adminify' ) );
}
$attachment_id = ( isset( $_POST['attachment_id'] ) ? intval( $_POST['attachment_id'] ) : 0 );
$term_id = ( isset( $_POST['term_id'] ) ? intval( $_POST['term_id'] ) : 0 );
$taxonomy = 'media_folder';
if ( !$attachment_id || !$term_id ) {
wp_send_json_error( 'Invalid data' );
}
// First remove all terms from this taxonomy
wp_delete_object_term_relationships( $attachment_id, $taxonomy );
// Add the new term
$result = wp_set_object_terms( $attachment_id, $term_id, $taxonomy );
if ( is_wp_error( $result ) ) {
wp_send_json_error( $result->get_error_message() );
}
wp_send_json_success();
}
public function wp_adminify_show_folders_in_list_filter() {
global $typenow;
if ( !$this->is_module_active() ) {
return;
}
if ( 'attachment' !== $typenow ) {
return;
}
$selected = ( isset( $_GET['media_folder'] ) ? $_GET['media_folder'] : '' );
wp_dropdown_categories( array(
'show_option_all' => 'All folders',
'taxonomy' => 'media_folder',
'name' => 'folder_id',
'id' => 'wp-adminify-media-folder-filter',
'orderby' => 'name',
'selected' => $selected,
'hierarchical' => true,
'value_field' => 'slug',
'depth' => 3,
'hide_empty' => false,
) );
}
}