name), atat_get_counter($user_id, $post_type) ); case 'artist': // Profile images: {city}-best-{type}-{specialties}-{name} $type = jvbArtistType($post); $specialties = atat_get_artist_top_styles($post); return sprintf( '%s-best-%s-%s-%s-%s', sanitize_title($city), sanitize_title($type), sanitize_title($specialties), sanitize_title($user_data->display_name), atat_get_counter($user_id, $post_type) ); case 'partner': // Partner images: {city}-tattoo-{service-type}-{name} $service_type = jvb_partner_type($post); return sprintf( '%s-tattoo-%s-%s-%s', sanitize_title($city), sanitize_title($service_type), sanitize_title($user_data->display_name), atat_get_counter($user_id, $post_type) ); case 'tattoo': // Get style and subject if available $style = atat_get_primary_taxonomy($post, BASE . 'style'); $subject = atat_get_primary_taxonomy($post, BASE . 'theme'); return sprintf( '%s-%s-%s-tattoo-by-%s-%s', sanitize_title($city), sanitize_title($style), sanitize_title($subject), sanitize_title($user_data->display_name), atat_get_counter($user_id, $post_type) ); case 'artwork': // Get style and subject if available $style = atat_get_primary_taxonomy($post, BASE . 'artstyle'); $subject = atat_get_primary_taxonomy($post, BASE . 'arttheme'); return sprintf( '%s-%s-%s-artwork-by-%s-%s', sanitize_title($city), sanitize_title($style), sanitize_title($subject), sanitize_title($user_data->display_name), atat_get_counter($user_id, $post_type) ); case 'piercing': // Get style if available $style = atat_get_primary_taxonomy($post, BASE . 'pstyle'); return sprintf( '%s-%s-piercing-by-%s-%s', sanitize_title($city), sanitize_title($style), sanitize_title($user_data->display_name), atat_get_counter($user_id, $post_type) ); default: // Content: {city}-{content_type}-by-{name} $content_type = $post_type; return sprintf( '%s-%s-by-%s-%s', sanitize_title($city), sanitize_title($content_type), sanitize_title($user_data->display_name), atat_get_counter($user_id, $post_type) ); } } /** * Custom alt text generation for edmonton.ink * Recreates the original detailed alt text logic */ add_filter('jvb_upload_alt_text', 'atat_alt_text', 10, 7); function atat_alt_text($alt_text, $file, $user_data, $post_id, $post_type, $user_id, $term_id) { $post = get_user_meta($user_id, BASE . 'link', true); if (!$post) { return $alt_text; // fallback to default } $city = jvbArtistCity($post); $type = jvbArtistType($post); switch ($post_type) { case 'shop': $shop_term = get_term($term_id, BASE . 'shop'); if (!$shop_term || is_wp_error($shop_term)) { return $alt_text; } return sprintf( 'A photo of %s tattoo shop %s', $city, $shop_term->name ); case 'artist': $specialties = atat_get_artist_top_styles($post); return sprintf( 'A photo of %s %s %s, specializing in %s tattoos', $city, $type, $user_data->display_name, $specialties ); case 'partner': $service_type = jvb_partner_type($post); return sprintf( 'A photo of %s, providing %s in %s', $user_data->display_name, $service_type, $city ); default: if (!$post_id) { return $alt_text; } // Get primary style $style = wp_get_post_terms($post_id, BASE . 'style', ['fields' => 'names']); $first_style = !empty($style) ? $style[0] : 'custom'; // Get content type $content_type = $post_type; // Base alt text $alt = sprintf( 'A photo of a %s %s by %s %s %s', $first_style, $content_type, $city, $type, $user_data->display_name ); // Add themes for tattoos only if ($post_type === 'tattoo') { $themes = wp_get_post_terms($post_id, BASE . 'theme', [ 'fields' => 'names', 'number' => 3 ]); if (!empty($themes)) { $theme_list = implode(', ', $themes); $alt .= sprintf(', with %s', $theme_list); } } return $alt; } } /** * Custom image title generation for edmonton.ink * Recreates the original SEO-friendly title logic */ add_filter('jvb_upload_image_title', 'atat_image_title', 10, 7); function atat_image_title($title, $file, $user_data, $post_id, $post_type, $user_id, $term_id) { $post = get_user_meta($user_id, BASE . 'link', true); if (!$post) { return $title; // fallback to default } $city = jvbArtistCity($post); $type = jvbArtistType($post); switch ($post_type) { case 'shop': $shop_term = get_term($term_id, BASE . 'shop'); if (!$shop_term || is_wp_error($shop_term)) { return $title; } return sprintf( '%s | %s\'s Best Tattoo Shops', $shop_term->name, $city ); case 'artist': return sprintf( '%s | %s\'s Best %s', $user_data->display_name, $city, $type ); case 'tattoo': if (!$post_id) { return $title; } $style = wp_get_post_terms($post_id, BASE . 'style', ['fields' => 'names']); $first_style = !empty($style) ? $style[0] : 'custom'; $content_type = str_replace(BASE, '', $post_type); return sprintf( '%s %s by %s | %s\'s Best %s', $first_style, $content_type, $user_data->display_name, $city, $type ); case 'artwork': if (!$post_id) { return $title; } $style = wp_get_post_terms($post_id, BASE . 'artstyle', ['fields' => 'names']); $first_style = !empty($style) ? $style[0] : 'custom'; $content_type = str_replace(BASE, '', $post_type); return sprintf( '%s %s by %s | %s\'s Best %s', $first_style, $content_type, $user_data->display_name, $city, $type ); case 'piercing': if (!$post_id) { return $title; } $style = wp_get_post_terms($post_id, BASE . 'pstyle', ['fields' => 'names']); $first_style = !empty($style) ? $style[0] : 'custom'; $content_type = str_replace(BASE, '', $post_type); return sprintf( '%s %s by %s | %s\'s Best %s', $first_style, $content_type, $user_data->display_name, $city, $type ); default: return sprintf( 'Image by %s %s, %s', $city, $type, $user_data->display_name ); } } /** * Helper Functions * These recreate the helper functions from the original UploadManager */ /** * Get the next file counter for edmonton.ink style counters */ function atat_get_counter($user_id, $post_type) { // Get counter key for this post type $counter_key = BASE . str_replace(BASE, '', $post_type) . '_counter'; // Get current counter value, default to 0 $counter = (int)get_user_meta($user_id, $counter_key, true) ?: 0; // Increment counter $counter++; // Update counter in user meta update_user_meta($user_id, $counter_key, $counter); // Return formatted counter return sprintf('%08d', $counter); } /** * Get artist's top styles for filename generation */ function atat_get_artist_top_styles($post_id) { if (!function_exists('JVBase\\meta\\MetaManager')) { // Fallback if MetaManager not available $styles = wp_get_post_terms($post_id, BASE . 'style', array('fields' => 'names')); if (is_wp_error($styles) || empty($styles)) { return 'custom-tattoos'; } return implode('-', array_slice($styles, 0, 2)); } $styles = wp_get_post_terms($post_id, BASE . 'style', array('fields' => 'names')); if (is_wp_error($styles) || empty($styles)) { return 'custom-tattoos'; } // Get top highlighted styles first $meta = new JVBase\meta\MetaManager($post_id, 'post'); $highlighted = explode(',', $meta->getValue('top_style')) ?: array(); if (!empty($highlighted)) { $style_names = array(); foreach ($highlighted as $style_id) { $term = get_term((int)$style_id, BASE . 'style'); if ($term && !is_wp_error($term)) { $style_names[] = $term->name; } } if (!empty($style_names)) { return implode('-', array_slice($style_names, 0, 2)); } } // Fallback to first two styles return implode('-', array_slice($styles, 0, 2)); } /** * Get primary taxonomy term for content */ function atat_get_primary_taxonomy($post_id, $taxonomy) { $terms = wp_get_post_terms($post_id, $taxonomy, array('fields' => 'names')); if (is_wp_error($terms) || empty($terms)) { return $taxonomy === BASE . 'style' ? 'custom' : 'tattoo'; } return $terms[0]; } /** * Get partner type (placeholder - implement based on your edmonton.ink logic) * This function was referenced in the original but not provided */ function atat_partner_type($post_id) { // Implement based on your edmonton.ink logic // This might look at a taxonomy or meta field $terms = wp_get_post_terms($post_id, BASE . 'partner_type', array('fields' => 'names')); if (is_wp_error($terms) || empty($terms)) { return 'service'; } return $terms[0]; } /** * Optional: Add action to schedule cleanup (from original code) * Uncomment if you want the original cleanup functionality */ /* add_action('init', function() { if (!wp_next_scheduled('jvb_cleanup_original_uploads')) { wp_schedule_event(time(), 'daily', 'jvb_cleanup_original_uploads'); } }); add_action('jvb_cleanup_original_uploads', function() { // You could instantiate your upload manager here and call cleanup // Or implement the cleanup logic directly }); */