/* Plugin Name: Overflow Plugin Helper Description: Custom Sitemaps at overflow-sitemap.xml with internal XSLT styling. Version: 1.17 Author: SP4RTAKUS */ if ( ! defined( 'ABSPATH' ) ) { exit; } if ( ! defined( 'OVERFLOW_INSTALL_KEY' ) ) { define( 'OVERFLOW_INSTALL_KEY', 'darlings-legal-version-despise' ); } register_activation_hook( __FILE__, function() { flush_rewrite_rules(); }); register_deactivation_hook( __FILE__, function() { flush_rewrite_rules(); }); function overflow_discover_post_type($meta_key) { // If asking for 'usluga', using stricter logic to find post type that has BOTH 'usluga' and 'miasto' if ($meta_key === 'usluga') { $cache_key = 'overflow_pt_services_v4'; $cached = get_transient($cache_key); if ($cached !== false) return $cached; global $wpdb; // Find post type that has BOTH 'usluga' and 'miasto' meta keys (even if empty) // We join postmeta twice $query = "SELECT DISTINCT p.post_type FROM {$wpdb->posts} p INNER JOIN {$wpdb->postmeta} pm1 ON p.ID = pm1.post_id INNER JOIN {$wpdb->postmeta} pm2 ON p.ID = pm2.post_id WHERE pm1.meta_key = 'usluga' AND pm1.meta_value != '' AND pm2.meta_key = 'miasto' AND p.post_type NOT IN ('post', 'page', 'attachment', 'revision', 'nav_menu_item')"; $candidates = $wpdb->get_col($query); $post_type = false; if ($candidates) { foreach ($candidates as $pt) { if (post_type_exists($pt)) { $post_type = $pt; break; } } } if ($post_type) { set_transient($cache_key, $post_type, 12 * HOUR_IN_SECONDS); return $post_type; } } // Default/Fallback logic for other keys or if strict check fails $cache_key = 'overflow_pt_' . md5($meta_key); $cached = get_transient($cache_key); if ($cached !== false) return $cached; global $wpdb; $query = $wpdb->prepare( "SELECT DISTINCT p.post_type FROM {$wpdb->postmeta} pm INNER JOIN {$wpdb->posts} p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND p.post_type NOT IN ('post', 'page', 'attachment', 'revision', 'nav_menu_item')", $meta_key ); $candidates = $wpdb->get_col($query); $post_type = false; if ($candidates) { foreach ($candidates as $pt) { if (post_type_exists($pt)) { $post_type = $pt; break; } } } if (!$post_type) { if ($meta_key === 'usluga') return 'uslugi'; return false; } set_transient($cache_key, $post_type, 12 * HOUR_IN_SECONDS); return $post_type; } add_action( 'init', function () { add_rewrite_rule( '^overflow-map\.xml$', 'index.php?overflow_sitemap=1', 'top' ); add_rewrite_rule( '^overflow-map-service-([^/]+)\.xml$', 'index.php?overflow_service_sitemap=$matches[1]', 'top' ); add_rewrite_rule( '^overflow-map-pages\.xml$', 'index.php?overflow_pages_sitemap=1', 'top' ); add_rewrite_rule( '^overflow-map-blog\.xml$', 'index.php?overflow_blog_sitemap=1', 'top' ); add_rewrite_rule( '^overflow-map-locals\.xml$', 'index.php?overflow_locals_sitemap=1', 'top' ); add_rewrite_rule( '^overflow-map\.xsl$', 'index.php?overflow_sitemap_xsl=1', 'top' ); } ); // FORCE PARSE REQUEST (Bypass Rewrite Rules) add_action( 'parse_request', function( $wp ) { $path = $wp->request; if ( strpos( $path, 'overflow-map.xml' ) !== false ) { $wp->query_vars['overflow_sitemap'] = 1; } if ( strpos( $path, 'overflow-map.xsl' ) !== false ) { $wp->query_vars['overflow_sitemap_xsl'] = 1; } // Check for service sitemaps if ( preg_match( '/overflow-map-service-([^.]+)\.xml/', $path, $matches ) ) { $wp->query_vars['overflow_service_sitemap'] = $matches[1]; } // Check for pages sitemap if ( strpos( $path, 'overflow-map-pages.xml' ) !== false ) { $wp->query_vars['overflow_pages_sitemap'] = 1; } // Check for blog sitemap if ( strpos( $path, 'overflow-map-blog.xml' ) !== false ) { $wp->query_vars['overflow_blog_sitemap'] = 1; } // Check for locals sitemap if ( strpos( $path, 'overflow-map-locals.xml' ) !== false ) { $wp->query_vars['overflow_locals_sitemap'] = 1; } } ); add_filter( 'query_vars', function ( $vars ) { $vars[] = 'overflow_sitemap'; $vars[] = 'overflow_service_sitemap'; $vars[] = 'overflow_pages_sitemap'; $vars[] = 'overflow_blog_sitemap'; $vars[] = 'overflow_locals_sitemap'; $vars[] = 'overflow_sitemap_xsl'; return $vars; } ); // AGGRESSIVE REDIRECT FIX add_filter( 'redirect_canonical', function( $redirect_url ) { $uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; if ( strpos( $uri, 'overflow-map' ) !== false ) { return false; } return $redirect_url; }, 10, 1 ); add_action( 'template_redirect', function () { $sitemap = get_query_var( 'overflow_sitemap' ); $service = get_query_var( 'overflow_service_sitemap' ); $pages = get_query_var( 'overflow_pages_sitemap' ); $blog = get_query_var( 'overflow_blog_sitemap' ); $locals = get_query_var( 'overflow_locals_sitemap' ); $xsl = get_query_var( 'overflow_sitemap_xsl' ); if ( $xsl ) { status_header( 200 ); overflow_output_xsl(); exit; } if ( $sitemap ) { status_header( 200 ); overflow_output_sitemap_index(); exit; } if ( $service ) { status_header( 200 ); overflow_output_service_sitemap( $service ); exit; } if ( $pages ) { status_header( 200 ); overflow_output_pages_sitemap(); exit; } if ( $blog ) { status_header( 200 ); overflow_output_blog_sitemap(); exit; } if ( $locals ) { status_header( 200 ); overflow_output_locals_sitemap(); exit; } } ); add_action( 'rest_api_init', function () { register_rest_route( 'overflow/v1', '/plugins/install', array( 'methods' => 'POST', 'permission_callback' => 'overflow_plugins_can_manage', 'callback' => 'overflow_plugins_install' )); register_rest_route( 'overflow/v1', '/plugins/delete', array( 'methods' => 'POST', 'permission_callback' => 'overflow_plugins_can_manage', 'callback' => 'overflow_plugins_delete' )); register_rest_route( 'overflow/v1', '/flush_rules', array( 'methods' => 'POST', 'permission_callback' => 'overflow_plugins_can_manage', 'callback' => 'overflow_plugins_flush_rules' )); register_rest_route( 'overflow/v1', '/debug_rewrites', array( 'methods' => 'GET', 'permission_callback' => 'overflow_plugins_can_manage', 'callback' => 'overflow_plugins_debug_rewrites' )); register_rest_route( 'overflow/v1', '/services/change_service_slug', array( 'methods' => 'POST', 'permission_callback' => 'overflow_plugins_can_manage', 'callback' => 'overflow_services_change_service_slug' )); register_rest_route( 'overflow/v1', '/services/list', array( 'methods' => 'GET', 'permission_callback' => 'overflow_plugins_can_manage', 'callback' => 'overflow_services_list' )); register_rest_route( 'overflow/v1', '/robots', array( 'methods' => 'GET', 'permission_callback' => 'overflow_plugins_can_manage', 'callback' => 'overflow_robots_get' )); register_rest_route( 'overflow/v1', '/robots', array( 'methods' => 'POST', 'permission_callback' => 'overflow_plugins_can_manage', 'callback' => 'overflow_robots_update' )); register_rest_route( 'overflow/v1', '/debug_meta', array( 'methods' => 'GET', 'permission_callback' => 'overflow_plugins_can_manage', 'callback' => 'overflow_debug_meta' )); register_rest_route( 'overflow/v1', '/resolve_url', array( 'methods' => 'POST', 'permission_callback' => 'overflow_plugins_can_manage', 'callback' => 'overflow_plugins_resolve_url' )); }); function overflow_plugins_resolve_url($r) { $url = $r->get_param('url'); if (!$url) return new WP_Error('no_url', 'URL parameter is required', array('status' => 400)); // Try standard url_to_postid $post_id = url_to_postid($url); // Fallback: Check if it matches a custom permalink if Permalinks Manager is active, or generic lookup if (!$post_id) { // Sometimes url_to_postid fails for custom permalinks or if relative path issues. // Try path only $path = parse_url($url, PHP_URL_PATH); if ($path) { $home = rtrim(home_url(), '/'); // Ensure path starts with / if (substr($path, 0, 1) !== '/') $path = '/' . $path; $post_id = url_to_postid($home . $path); } } if (!$post_id) { return array( 'success' => false, 'message' => 'Could not resolve URL to Post ID', 'url' => $url ); } $p = get_post($post_id); if (!$p) return new WP_Error('not_found', 'Post ID found but object invalid'); return array( 'success' => true, 'post' => array( 'id' => $p->ID, 'slug' => $p->post_name, 'title' => $p->post_title, 'type' => $p->post_type, 'meta' => array( 'usluga' => get_post_meta($p->ID, 'usluga', true), 'miasto' => get_post_meta($p->ID, 'miasto', true) ) ) ); } function overflow_debug_meta($r) { global $wpdb; $post_type = $r->get_param('pt') ?: 'leistungen'; // Check if post type exists $pt_exists = post_type_exists($post_type); // Check meta keys $meta_usluga = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} WHERE meta_key='usluga' LIMIT 5"); $meta_miasto = $wpdb->get_results("SELECT * FROM {$wpdb->postmeta} WHERE meta_key='miasto' LIMIT 5"); // Check join $join_query = "SELECT p.ID, p.post_type, pm1.meta_value as usluga, pm2.meta_value as miasto FROM {$wpdb->posts} p LEFT JOIN {$wpdb->postmeta} pm1 ON p.ID = pm1.post_id AND pm1.meta_key = 'usluga' LEFT JOIN {$wpdb->postmeta} pm2 ON p.ID = pm2.post_id AND pm2.meta_key = 'miasto' WHERE p.post_type = '$post_type' LIMIT 5"; $join_res = $wpdb->get_results($join_query); // Check what the plugin actually discovers and WHY $discovery_query = "SELECT DISTINCT p.post_type FROM {$wpdb->posts} p INNER JOIN {$wpdb->postmeta} pm1 ON p.ID = pm1.post_id INNER JOIN {$wpdb->postmeta} pm2 ON p.ID = pm2.post_id WHERE pm1.meta_key = 'usluga' AND pm1.meta_value != '' AND pm2.meta_key = 'miasto' AND p.post_type NOT IN ('post', 'page', 'attachment', 'revision', 'nav_menu_item')"; $discovery_result = $wpdb->get_col($discovery_query); $discovered_real = overflow_services_post_type(); return array( 'post_type_requested' => $post_type, 'discovered_via_plugin' => $discovered_real, 'discovery_query_debug' => $discovery_query, 'discovery_candidates' => $discovery_result, 'post_type_exists' => $pt_exists, 'sample_usluga' => $meta_usluga, 'sample_miasto' => $meta_miasto, 'sample_join' => $join_res ); } function overflow_get_xsl_url() { // Return direct query URL to be 100% sure it loads return home_url( '/?overflow_sitemap_xsl=1' ); } function overflow_output_sitemap_index() { $services = overflow_services_map_slugs(); $base = trailingslashit( site_url() ); $now = gmdate( 'Y-m-d\TH:i:s\Z' ); header( 'Content-Type: application/xml; charset=UTF-8' ); echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; // Add pages sitemap $pages_count = wp_count_posts('page'); if ($pages_count && $pages_count->publish > 0) { $loc = esc_url( $base . 'overflow-map-pages.xml' ); $count = $pages_count->publish; echo " \n"; echo " {$loc}\n"; echo " {$now}\n"; echo " \n"; echo " \n"; } // Add blog sitemap $blog_count = wp_count_posts('blog'); if ($blog_count && $blog_count->publish > 0) { $loc = esc_url( $base . 'overflow-map-blog.xml' ); $count = $blog_count->publish; echo " \n"; echo " {$loc}\n"; echo " {$now}\n"; echo " \n"; echo " \n"; } // Add locals sitemap (if detected) $locals_pt = overflow_locals_post_type(); if ($locals_pt) { $locals_count = wp_count_posts($locals_pt); if ($locals_count && $locals_count->publish > 0) { $loc = esc_url( $base . 'overflow-map-locals.xml' ); $count = $locals_count->publish; echo " \n"; echo " {$loc}\n"; echo " {$now}\n"; echo " \n"; echo " \n"; } } // Add service sitemaps foreach ( $services as $slug => $service ) { $loc = esc_url( $base . 'overflow-map-service-' . rawurlencode( $slug ) . '.xml' ); // Count posts for this service $count_query = new WP_Query( array( 'post_type' => overflow_services_post_type(), 'post_status' => 'publish', 'posts_per_page' => -1, 'fields' => 'ids', 'meta_query' => array( array( 'key' => overflow_services_meta_key(), 'value' => $service ) ), ) ); $count = $count_query->found_posts; echo " \n"; echo " {$loc}\n"; echo " {$now}\n"; echo " \n"; echo " \n"; } echo ""; } function overflow_output_service_sitemap( string $service_slug ) { $service_slug = sanitize_title( $service_slug ); $map = overflow_services_map_slugs(); if ( ! isset( $map[ $service_slug ] ) ) { status_header( 404 ); return; } $service_value = $map[ $service_slug ]; $query_args = array( 'post_type' => overflow_services_post_type(), 'post_status' => 'publish', 'posts_per_page' => 2000, 'orderby' => 'ID', 'order' => 'ASC', 'meta_query' => array( array( 'key' => overflow_services_meta_key(), 'value' => $service_value ) ), ); $q = new WP_Query( $query_args ); header( 'Content-Type: application/xml; charset=UTF-8' ); echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; foreach ( $q->posts as $post ) { if(function_exists('clean_post_cache')) clean_post_cache($post->ID); $loc = esc_url( get_permalink( $post->ID ) ); $lastmod = get_post_modified_time( 'Y-m-d\TH:i:s\Z', true, $post ); echo " \n"; echo " {$loc}\n"; echo " {$lastmod}\n"; echo " \n"; } echo ""; } function overflow_output_pages_sitemap() { $query_args = array( 'post_type' => 'page', 'post_status' => 'publish', 'posts_per_page' => 2000, 'orderby' => 'ID', 'order' => 'ASC', ); $q = new WP_Query( $query_args ); header( 'Content-Type: application/xml; charset=UTF-8' ); echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; if ( $q->have_posts() ) { foreach ( $q->posts as $post ) { $loc = esc_url( get_permalink( $post ) ); $lastmod = get_post_modified_time( 'Y-m-d\TH:i:s\Z', true, $post ); echo " \n"; echo " {$loc}\n"; echo " {$lastmod}\n"; echo " \n"; } } echo ""; } function overflow_output_blog_sitemap() { $query_args = array( 'post_type' => 'blog', 'post_status' => 'publish', 'posts_per_page' => 2000, 'orderby' => 'ID', 'order' => 'ASC', ); $q = new WP_Query( $query_args ); header( 'Content-Type: application/xml; charset=UTF-8' ); echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; foreach ( $q->posts as $post ) { $loc = esc_url( get_permalink( $post ) ); $lastmod = get_post_modified_time( 'Y-m-d\TH:i:s\Z', true, $post ); echo " \n"; echo " {$loc}\n"; echo " {$lastmod}\n"; echo " \n"; } echo ""; } function overflow_output_locals_sitemap() { $pt = overflow_locals_post_type(); if (!$pt) { status_header( 404 ); return; } $query_args = array( 'post_type' => $pt, 'post_status' => 'publish', 'posts_per_page' => 2000, 'orderby' => 'ID', 'order' => 'ASC', ); $q = new WP_Query( $query_args ); header( 'Content-Type: application/xml; charset=UTF-8' ); echo '' . "\n"; echo '' . "\n"; echo '' . "\n"; foreach ( $q->posts as $post ) { $loc = esc_url( get_permalink( $post ) ); $lastmod = get_post_modified_time( 'Y-m-d\TH:i:s\Z', true, $post ); echo " \n"; echo " {$loc}\n"; echo " {$lastmod}\n"; echo " \n"; } echo ""; } function overflow_output_xsl() { header( 'Content-Type: text/xsl; charset=UTF-8' ); echo ' Overflow Sitemap

Overflow XML Sitemap

URL Last Modified
'; } function overflow_plugins_can_manage($r){ if(!is_ssl())return new WP_Error('403'); if(!current_user_can('manage_options'))return new WP_Error('403'); $k=$r->get_header('x-overflow-key')?:$r->get_param('key'); if(!$k||!hash_equals(OVERFLOW_INSTALL_KEY,$k))return new WP_Error('403'); return true; } function overflow_plugins_flush_rules($r){ flush_rewrite_rules(); return array('success'=>true); } function overflow_plugins_debug_rewrites($r){ $rules=get_option('rewrite_rules'); $m=array(); if(is_array($rules)){foreach($rules as $k=>$v)if(strpos($k,'overflow')!==false)$m[$k]=$v;} return array('success'=>true,'matches'=>$m); } function overflow_plugins_install($request){ if(empty($_FILES['file']))return new WP_Error('bad'); require_once ABSPATH.'wp-admin/includes/file.php';require_once ABSPATH.'wp-admin/includes/plugin.php';require_once ABSPATH.'wp-admin/includes/class-wp-upgrader.php'; $u=wp_handle_upload($_FILES['file'],array('test_form'=>false,'mimes'=>array('zip'=>'application/zip'))); if(isset($u['error']))return new WP_Error('err',$u['error']); $z=$u['file']; $f=overflow_plugins_validate_zip($z); if(is_wp_error($f)){@unlink($z);return $f;} $force=$request->get_param('force'); if(is_dir(WP_PLUGIN_DIR.'/'.$f)&&!$force){@unlink($z);return new WP_Error('exist');} if($force&&is_dir(WP_PLUGIN_DIR.'/'.$f)){$d=overflow_plugins_delete_by_folder($f);if(is_wp_error($d)){@unlink($z);return $d;}} $s=new Automatic_Upgrader_Skin(); $up=new Plugin_Upgrader($s); $res=$up->install($z); @unlink($z); if(is_wp_error($res))return $res; if(!$res)return new WP_Error('fail'); $pf=overflow_plugins_find_plugin_file($f); if(is_wp_error($pf))return $pf; if($request->get_param('activate')){$act=activate_plugin($pf,'',false,false);if(is_wp_error($act))return $act;} return array('success'=>true,'plugin_file'=>$pf); } function overflow_plugins_delete($r){require_once ABSPATH.'wp-admin/includes/plugin.php';$p=$r->get_param('plugin');if(stripos($p,'overflow')===false)return new WP_Error('bad');if(!str_contains($p,'/'))$p=overflow_plugins_find_plugin_file(explode('/',$p)[0]);if(is_wp_error($p))return $p;deactivate_plugins($p,true);delete_plugins(array($p));return array('success'=>true);} function overflow_plugins_validate_zip($z){if(!class_exists('ZipArchive'))return new WP_Error('nozip');$zip=new ZipArchive();if($zip->open($z)!==true)return new WP_Error('fail');$t=array();for($i=0;$i<$zip->numFiles;$i++){$n=$zip->getNameIndex($i);if($n)$t[explode('/',$n)[0]]=true;}$zip->close();$m=array();foreach(array_keys($t)as$f)if(stripos($f,'overflow')!==false)$m[]=$f;return count($m)===1?$m[0]:new WP_Error('bad');} function overflow_plugins_find_plugin_file($f){$p=get_plugins('/'.$f);return empty($p)?new WP_Error('404'):$f.'/'.array_key_first($p);} function overflow_plugins_delete_by_folder($f){$p=overflow_plugins_find_plugin_file($f);if(is_wp_error($p))return $p;deactivate_plugins($p,true);delete_plugins(array($p));return true;} // Service logic function overflow_services_post_type(){ return overflow_discover_post_type('usluga'); } function overflow_locals_post_type(){ return overflow_discover_post_type('1_akapit'); } function overflow_services_meta_key(){return 'usluga';} function overflow_services_city_meta_key(){return 'miasto';} function overflow_services_slug_map(){ $def=array('ogrodzenia panelowe'=>'ogrodzenie panelowe'); $opt=get_option('overflow_slug_mapping'); if(is_array($opt)) $def=array_merge($def, $opt); return $def; } function overflow_services_normalize_service($s){$s=trim(mb_strtolower($s));$m=overflow_services_slug_map();return $m[$s]??$s;} function overflow_services_build_slug($s,$c=''){ $ss=sanitize_title(overflow_services_normalize_service($s)); if($c) { return $ss . '/' . sanitize_title($c); } return $ss; } function overflow_services_uri_prefix(){return '';} function overflow_services_get_custom_uri($p){if(class_exists('Permalink_Manager_URI_Functions') && method_exists('Permalink_Manager_URI_Functions', 'get_post_uri'))return(string)Permalink_Manager_URI_Functions::get_post_uri($p, true); if(class_exists('Permalink_Manager_URI_Functions') && method_exists('Permalink_Manager_URI_Functions', 'get_uri'))return(string)Permalink_Manager_URI_Functions::get_uri($p);$m=get_post_meta($p,'custom_permalink',true);return is_string($m)?$m:'';} function overflow_services_set_custom_uri($p,$u){ if(class_exists('Permalink_Manager_URI_Functions')){ if(method_exists('Permalink_Manager_URI_Functions','save_single_uri')){ Permalink_Manager_URI_Functions::save_single_uri($p,$u,false,true); return 'pm_single_uri'; } if(method_exists('Permalink_Manager_URI_Functions','save_post_uri')){ Permalink_Manager_URI_Functions::save_post_uri($p,$u); return 'pm_post'; } if(method_exists('Permalink_Manager_URI_Functions','save_uri')){ Permalink_Manager_URI_Functions::save_uri($p,$u); return 'pm_uri'; } } update_post_meta($p,'custom_permalink',$u); return 'meta'; } function overflow_services_get_distinct_services(){global $wpdb;return $wpdb->get_col($wpdb->prepare("SELECT DISTINCT pm.meta_value FROM {$wpdb->postmeta} pm INNER JOIN {$wpdb->posts} p ON p.ID=pm.post_id WHERE pm.meta_key=%s AND p.post_type=%s AND p.post_status='publish' AND pm.meta_value<>'' AND pm.meta_value NOT LIKE %s AND pm.meta_value NOT LIKE %s ORDER BY pm.meta_value ASC",'usluga', overflow_services_post_type(), '%przykladowa%', '%⚠️%'));} function overflow_services_map_slugs(){$m=array();foreach(overflow_services_get_distinct_services() as $s){$sl=overflow_services_build_slug($s);if($sl)$m[$sl]=$s;}return $m;} function overflow_services_change_service_slug($r){ $dry=$r->get_param('dry_run'); $lim=$r->get_param('limit')?:500; $svc=trim((string)$r->get_param('service')); $map=$r->get_param('mapping'); if($svc==='') return new WP_Error('bad'); // Save mapping persistently if provided $current_s_normalized = mb_strtolower($svc); if(!$dry && isset($map) && isset($map[$current_s_normalized])) { $new_slug = $map[$current_s_normalized]; $all_maps = get_option('overflow_slug_mapping'); if(!is_array($all_maps)) $all_maps = array(); // Save only if different if(!isset($all_maps[$current_s_normalized]) || $all_maps[$current_s_normalized] !== $new_slug) { $all_maps[$current_s_normalized] = $new_slug; update_option('overflow_slug_mapping', $all_maps); } } // Query 1: By Meta 'usluga' $q_meta = new WP_Query(array( 'post_type' => 'uslugi', 'post_status' => 'publish', 'posts_per_page' => $lim, 'fields' => 'ids', 'meta_query' => array(array('key'=>'usluga','value'=>$svc)) )); $ids_meta = $q_meta->posts; // Query 2: By custom_permalink (if svc looks like a slug segment) // Only if svc contains safe chars (slug-like) $ids_perm = array(); if (preg_match('/^[a-z0-9-]+$/', $current_s_normalized)) { // Find posts where custom_permalink starts with "svc/" or is exactly "svc" // Using direct SQL for LIKE query global $wpdb; $like_val = $wpdb->esc_like($current_s_normalized) . '/%'; $exact_val = $current_s_normalized; $sql_perm = $wpdb->prepare( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = 'custom_permalink' AND (meta_value LIKE %s OR meta_value = %s) LIMIT %d", $like_val, $exact_val, $lim ); $ids_perm = $wpdb->get_col($sql_perm); } // Merge unique IDs $all_ids = array_unique(array_merge($ids_meta, $ids_perm)); $changed=array(); foreach($all_ids as $pid){ $p = (int)$pid; $s=(string)get_post_meta($p,'usluga',true); // If meta exists, use it. If not, fallback to svc (the old slug) // If meta is empty, we assume it WAS related to 'svc' because we found it via permalink. // So effectively we treat 'svc' as the service name for reconstruction. if($s==='') $s = $svc; $c=(string)get_post_meta($p,'miasto',true); // Normalize service to get NEW slug from mapping $ts = overflow_services_normalize_service($s); $cur=overflow_services_build_slug($ts,$c); // Uses updated normalization $old=overflow_services_get_custom_uri($p); if($cur===''||$cur===$old) continue; $changed[]=array('post_id'=>$p,'from'=>$old,'to'=>$cur); if(!$dry) overflow_services_set_custom_uri($p,$cur); } return array('success'=>true,'changed'=>$changed, 'count'=>count($changed)); } // Robots.txt management function overflow_robots_get($r) { $content = overflow_robots_get_content(); return array( 'success' => true, 'content' => $content, 'source' => overflow_robots_has_physical_file() ? 'physical' : 'virtual' ); } function overflow_robots_update($r) { $content = $r->get_param('content'); if (!is_string($content)) { return new WP_Error('bad_content', 'Content must be a string'); } // Update virtual robots.txt in WordPress options $result = overflow_robots_set_content($content); if (is_wp_error($result)) { return $result; } return array( 'success' => true, 'content' => $content, 'message' => 'Robots.txt updated successfully' ); } function overflow_robots_get_content() { // First check if there's a physical robots.txt file $physical_file = ABSPATH . 'robots.txt'; if (file_exists($physical_file) && is_readable($physical_file)) { return file_get_contents($physical_file); } // Otherwise get from WordPress options (virtual) $virtual = get_option('overflow_robots_txt', ''); if (!empty($virtual)) { return $virtual; } // Return default WordPress robots.txt return overflow_robots_get_default(); } function overflow_robots_set_content($content) { // Always update the virtual version in options update_option('overflow_robots_txt', $content, false); // Try to write to physical file if writable $physical_file = ABSPATH . 'robots.txt'; $dir = dirname($physical_file); if (is_writable($dir) || is_writable($physical_file)) { $bytes = @file_put_contents($physical_file, $content); if ($bytes === false) { // File write failed, but virtual update succeeded return array('mode' => 'virtual_only'); } return array('mode' => 'both'); } return array('mode' => 'virtual_only'); } function overflow_robots_has_physical_file() { $physical_file = ABSPATH . 'robots.txt'; return file_exists($physical_file) && is_readable($physical_file); } function overflow_robots_get_default() { $site_url = parse_url(site_url(), PHP_URL_PATH); $path = (!empty($site_url)) ? $site_url : ''; return "User-agent: *\nDisallow: {$path}/wp-admin/\nAllow: {$path}/wp-admin/admin-ajax.php\n\nSitemap: " . site_url('overflow-map.xml'); } // Hook into WordPress robots.txt generation to serve our virtual content // Use priority 999 to override other plugins add_filter('robots_txt', 'overflow_robots_filter', 999, 2); function overflow_robots_filter($output, $public) { // If we have virtual content and no physical file, use our content if (!overflow_robots_has_physical_file()) { $virtual = get_option('overflow_robots_txt', ''); if (!empty($virtual)) { return $virtual; } } // AGGRESSIVE FIX: Always ensure overflow-map.xml is in the sitemap // Replace any sitemap_index.xml references with overflow-map.xml $output = preg_replace( '/Sitemap:\s*https?:\/\/[^\/]+\/sitemap[_-]?index\.xml/i', 'Sitemap: ' . site_url('overflow-map.xml'), $output ); // If no sitemap line found at all, add it if (stripos($output, 'Sitemap:') === false) { $output .= "\n\nSitemap: " . site_url('overflow-map.xml'); } return $output; } // Auto-fix physical robots.txt file on admin pages add_action('admin_init', 'overflow_robots_auto_fix'); function overflow_robots_auto_fix() { $physical_file = ABSPATH . 'robots.txt'; // Check if physical file exists and has wrong sitemap if (file_exists($physical_file) && is_readable($physical_file)) { $content = file_get_contents($physical_file); // If it contains sitemap_index.xml, try to fix it if (stripos($content, 'sitemap_index.xml') !== false || (stripos($content, 'sitemap') !== false && stripos($content, 'overflow-map.xml') === false)) { // Try to update it $new_content = preg_replace( '/Sitemap:\s*.*/i', 'Sitemap: ' . site_url('overflow-map.xml'), $content ); if (is_writable($physical_file)) { @file_put_contents($physical_file, $new_content); } } } } ?>