<?php

    if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
    
    class WPH_module_rewrite_author extends WPH_module_component
        {
            
            function get_component_title()
                {
                    return "Users";
                }
                                                
            function get_module_component_settings()
                {
                    $this->component_settings[]                 = array(
                                                                        'id'                        => 'author',
                                                                        'input_type'                => 'text',
                                                                        'value_description'         => __('e.g. profile', 'wp-hide-security-enhancer'),
                                                                        'sanitize_type'             => array(array($this->wph->functions, 'sanitize_file_path_name')),
                                                                        'processing_order'          => 60
                                                                    );
                    
                    $this->component_settings[]                  =   array(
                                                                        'id'            =>  'author_disable_archive',
                                                  
                                                                        'input_type'    =>  'radio',
                                                             
                                                                        'default_value' =>  'no',
                                                                        
                                                                        'sanitize_type' =>  array('sanitize_title', 'strtolower'),
                                                                        'processing_order'  =>  62
                                                                        
                                                                        );
                                                                        
                    $this->component_settings[]                  =   array(
                                                                        'id'            =>  'author_disable_enumeration',
                                                  
                                                                        'input_type'    =>  'radio',
                                                             
                                                                        'default_value' =>  'no',
                                                                        
                                                                        'sanitize_type' =>  array('sanitize_title', 'strtolower'),
                                                                        'processing_order'  =>  62
                                                                        
                                                                        );

                    $this->component_settings[]                  = array(
                                                                        'id'                        => 'author_block_default',
                                                                        'input_type'                => 'radio',
                                                                        'default_value'             => 'no',
                                                                        'sanitize_type'             => array('sanitize_title', 'strtolower'),
                                                                        'processing_order'          => 61
                                                                    );

                    return $this->component_settings;
                }

            function set_module_components_description( $component_settings )
                {
                    foreach ( $component_settings as $component_key => $component_setting )
                        {
                            if ( ! isset ( $component_setting['id'] ) )
                                continue;

                            switch ( $component_setting['id'] )
                                {
                                    case 'author' :
                                                        $component_setting = array_merge( $component_setting, array(
                                                                                                                    'label'         => __('New User Path', 'wp-hide-security-enhancer'),
                                                                                                                    'description'   => __('The default path is set to /author/', 'wp-hide-security-enhancer'),
                                                                                                                    'help'          => array(
                                                                                                                        'title'                     => __('Help', 'wp-hide-security-enhancer') . ' - ' . __('New Author Path', 'wp-hide-security-enhancer'),
                                                                                                                        'description'               => __("An user URL display all posts associated to a particular user. The default URL format is:", 'wp-hide-security-enhancer') . "<br />  <br />
                                                                                                                                                       <code>https://-domain-name-/author/author-name/</code>
                                                                                                                                                       <br /><br /> " . __("By using a value of 'contributor' this become:", 'wp-hide-security-enhancer') . "<br />
                                                                                                                                                       <code>https://-domain-name-/contributor/author-name/</code>",
                                                                                                                        'option_documentation_url'  => 'https://www.wp-hide.com/documentation/rewrite-author/',
                                                                                                                        'ai_question'               =>  'Help me understand the "New Author Path" option with WP Hide plugin'
                                                                                                                    ),
                                                                                                                ) );
                                    break;
                                        
                                        
                                    case 'author_disable_archive' :
                                                                $component_setting =   array_merge ( $component_setting , array(
                                                                                                                                    'label'         =>  __('Prevent Access to User Archives',    'wp-hide-security-enhancer'),
                                                                                                                                    'description'   =>  __('Prevent Access to User Archives via User IDs',    'wp-hide-security-enhancer'),
                                                                                                                                    
                                                                                                                                    'help'          =>  array(
                                                                                                                                                                    'title'                     =>  __('Help',    'wp-hide-security-enhancer') . ' - ' . __('Prevent Access to User Archives',    'wp-hide-security-enhancer'),
                                                                                                                                                                    'description'               =>  __("By default, WordPress generates user archive pages using URLs like ",    'wp-hide-security-enhancer') .
                                                                                                                                                                                                        "<code>yoursite.com/?author=ID</code>" .
                                                                                                                                                                                                        __(". This behavior can be exploited by attackers who repeatedly request URLs such as ",    'wp-hide-security-enhancer') .
                                                                                                                                                                                                        "<code>?author=1, ?author=2</code>" .
                                                                                                                                                                                                        __(". and so on, until they find valid user IDs—revealing active usernames on your site.",    'wp-hide-security-enhancer') . "<br />  <br />" .
                                                                                                                                                                                                        __("To enhance security, it's best to completely disable access to these types of URLs, especially since user archive pages often serve little or no purpose on many sites.",    'wp-hide-security-enhancer')  . "<br />  <br />" .
                                                                                                                                                                                                        __("Even if your permalink settings are not set to the default (i.e., 'Plain'), WordPress will still redirect ?author=ID URLs to the corresponding user archive page, if it exists. Therefore, additional measures are necessary to block these redirects and prevent username enumeration.",    'wp-hide-security-enhancer') ,
                                                                                                                                                                    'option_documentation_url'  =>  'https://wp-hide.com/documentation/rewrite-author/',
                                                                                                                                                                    'ai_question'               =>  'Help me understand the "Prevent Access to Author Archives" option with WP Hide plugin'
                                                                                                                                                                    ),
                                                                                                                                                                    
                                                                                                                                    'options'       =>  array(
                                                                                                                                                                'no'        =>  __('No',     'wp-hide-security-enhancer'),
                                                                                                                                                                'yes'       =>  __('Yes',    'wp-hide-security-enhancer'),
                                                                                                                                                                ),
                                                                                                                                ) );
                                    break;
                                    
                                    case 'author_disable_enumeration' :
                                                                $component_setting =   array_merge ( $component_setting , array(
                                                                                                                                    'label'         =>  __('Disable User Enumeration',    'wp-hide-security-enhancer'),
                                                                                                                                    'description'   =>  __('Prevents bots and automated attackers from discovering author usernames or IDs by restricting exposure through REST API endpoints, sitemaps and other publicly accessible sources.',    'wp-hide-security-enhancer'),
                                                                                                                                    
                                                                                                                                    'help'          =>  array(
                                                                                                                                                                    'title'                     =>  __('Help',    'wp-hide-security-enhancer') . ' - ' . __('Disable User Enumeration',    'wp-hide-security-enhancer'),
                                                                                                                                                                    'description'               =>  __("User enumeration refers to the process where automated tools attempt to identify valid WordPress usernames or author IDs exposed by a site. Once these identifiers are known, attackers can use them as entry points for brute-force login attempts, credential stuffing, or targeted social engineering attacks.",    'wp-hide-security-enhancer') .
                                                                                                                                                                                                            "<br />" .  __("By default, WordPress may unintentionally reveal user-related data through several publicly accessible routes, such as:",    'wp-hide-security-enhancer') .
                                                                                                                                                                                                            "<ul><li>" .  __('REST API endpoints ( e.g. ',    'wp-hide-security-enhancer') . "<code>/wp-json/wp/v2/users</code> )</li>" .
                                                                                                                                                                                                            "<li> " . __('Author archives and sitemap entries',    'wp-hide-security-enhancer')  ."</li>" .
                                                                                                                                                                                                            "<li> " . __('Predictable URL patterns ( e.g.',    'wp-hide-security-enhancer')  . "<code>/?author=1</code> )</li></ul>" .
                                                                                                                                                                                                        __("Enabling the Disable User Enumeration option strengthens your site’s security by limiting or blocking access to these exposure points. It ensures that user-related data is no longer easily accessible to bots, reduces information leakage, and makes it significantly harder for attackers to identify valid accounts to target.",    'wp-hide-security-enhancer'),
                                                                                                                                                                    'option_documentation_url'  =>  'https://wp-hide.com/documentation/rewrite-author/',
                                                                                                                                                                    'ai_question'               =>  'Help me understand the "Disable User Enumeration" option with WP Hide plugin'
                                                                                                                                                                    ),
                                                                                                                                                                    
                                                                                                                                    'options'       =>  array(
                                                                                                                                                                'no'        =>  __('No',     'wp-hide-security-enhancer'),
                                                                                                                                                                'yes'       =>  __('Yes',    'wp-hide-security-enhancer'),
                                                                                                                                                                ),
                                                                                                                                ) );
                                    break;

                                    case 'author_block_default' :
                                                        $component_setting = array_merge( $component_setting, array(
                                                                                                                    'label'         => __('Block default', 'wp-hide-security-enhancer'),
                                                                                                                    'description'   => __('Block default /author/ when using custom one.', 'wp-hide-security-enhancer') . '<br />' . __('Apply only if ', 'wp-hide-security-enhancer') . '<b>New Author Path</b> ' . __('is not empty.', 'wp-hide-security-enhancer'),
                                                                                                                    'help'          => array(
                                                                                                                        'title'                     => __('Help', 'wp-hide-security-enhancer') . ' - ' . __('Block default', 'wp-hide-security-enhancer'),
                                                                                                                        'description'               => __("After changing the default author, the old url is still accessible, this provide a way to block it.<br />The functionality apply only if <b>New Author Path</b> option is filled in.", 'wp-hide-security-enhancer'),
                                                                                                                        'option_documentation_url'  => 'https://www.wp-hide.com/documentation/rewrite-author/',
                                                                                                                        'ai_question'               =>  'Help me understand the "Block default /author/ when using custom one" option with WP Hide plugin'
                                                                                                                    ),
                                                                                                                    'options'       => array(
                                                                                                                        'no'        => __('No', 'wp-hide-security-enhancer'),
                                                                                                                        'yes'       => __('Yes', 'wp-hide-security-enhancer')
                                                                                                                    )
                                                                                                                ) );
                                    break;
                                }

                            $component_settings[ $component_key ] = $component_setting;
                        }

                    return $component_settings;
                }


                
            
            
            function _init_author( $saved_field_data )
                {
                    if ( ! $this->ReInit )
                        {
                            if  ( ! is_multisite() )
                                add_filter('author_rewrite_rules',      array( $this, 'author_rewrite_rules'), 999);
                                else
                                add_filter ('request', array( $this, 'request'), 999);
                        }
                                        
                    if(empty($saved_field_data))
                        return FALSE;
                    
                    //add default plugin path replacement
                    $url            =   trailingslashit(    site_url()  ) .  'author';
                    $replacement    =   trailingslashit(    home_url()  ) .  $saved_field_data;
                    $this->wph->functions->add_replacement( $url , $replacement );
                    
                    if  ( is_multisite() )
                        {
                            global $blog_id;
                            
                            $url            =   trailingslashit(    site_url()  ) .  'blog/author';
                            $replacement    =   trailingslashit(    home_url()  ) .  $saved_field_data;
                            $this->wph->functions->add_replacement( $url , $replacement );   
                        }
                    
                    return TRUE;
                }
                
            
            function request( $query_vars )
                {
                    //return $author_rewrite;
                    $new_author_path        =   $this->wph->functions->get_site_module_saved_value( 'author',  $this->wph->functions->get_blog_id_setting_to_use() );
                    
                    if( empty( $new_author_path ) )
                        return $query_vars;
                    
                    if ( isset( $_GET['author_name'] ) &&   strpos( $_SERVER['REDIRECT_URL'], '/' . $new_author_path . '/' . $_GET['author_name']) !==  FALSE )
                        {
                            foreach  ( $query_vars  as  $key    =>  $value )   
                                {
                                    if ( ! in_array(  $key,  array( 'author_name' , 'paged' ) ) )
                                        unset ( $query_vars[$key] ) ;
                                }
                        }
                    
                    return $query_vars;
                    
                }
                
                 
            function _callback_saved_author( $saved_field_data )
                {
                    
                    if(empty($saved_field_data) ||  ! is_multisite() )
                        return FALSE;
                    
                    $processing_response    =   array();
                    
                    global $blog_id;
                    if(is_multisite())
                        {
                            $blog_details   =   get_blog_details( $blog_id );
                            $ms_settings    =   $this->wph->functions->get_site_settings('network');
                        }
                        
                    $rewrite                            =  '';
                    
                    
                    $rewrite_blocks     =   array();
                    
                    $rewrite_base       =   $this->wph->functions->get_rewrite_base( $saved_field_data . '/([_0-9a-zA-Z-]+)/page/?([0-9]{1,})/?$', FALSE, FALSE );
                    $rewrite_to         =   $this->wph->functions->get_rewrite_to_base( '/index.php?author_name=$2&paged=$3' , TRUE, FALSE, 'full_path' );
                    $rewrite_blocks[$rewrite_base]  =   $rewrite_to;
                    
                    $rewrite_base       =   $this->wph->functions->get_rewrite_base( $saved_field_data . '/([_0-9a-zA-Z-]+)/?$', FALSE, FALSE );
                    $rewrite_to         =   $this->wph->functions->get_rewrite_to_base( '/index.php?author_name=$2' , TRUE, FALSE, 'full_path' );
                    $rewrite_blocks[$rewrite_base]  =   $rewrite_to;
                    
                    foreach ($rewrite_blocks    as  $rewrite_base   =>  $rewrite_to )
                        {
                               
                            if($this->wph->server_htaccess_config   === TRUE)
                                {
                                    
                                    if(!is_multisite() )
                                        {
                                            $rewrite  .= "\nRewriteRule ^"    .   $rewrite_base   .   ' '. $rewrite_to .' [END,QSA]' . "";
                                        }
                                        else
                                        {
                                            $rewrite  .= "\nRewriteRule ^([_0-9a-zA-Z-]+/)?"    .   $rewrite_base   .   ' '. $rewrite_to .' [END,QSA]' . "";   
                                        }
                                }
                            
                            if($this->wph->server_web_config   === TRUE)
                                {
                                    $rewrite    =   "\n" . '<rule name="wph-new_wp_comments_post" stopProcessing="true">';
                                    
                                    if(!is_multisite() )
                                        {
                                            $rewrite .=  "\n"  .    '    <match url="^'.  $rewrite_base   .'"  />';
                                            $rewrite .=   "\n" .    '    <action type="Rewrite" url="'.  $rewrite_to .'"  appendQueryString="true" />';
                                        }
                                        else
                                        {
                                            $rewrite .=  "\n"  .    '    <match url="^([_0-9a-zA-Z-]+/)?'.  $rewrite_base   .'"  />';
                                            $rewrite .=   "\n" .    '    <action type="Rewrite" url="'.  $rewrite_to .'"  appendQueryString="true" />';
                                        }
                                    
                                    $rewrite .=  "\n" . '</rule>';
                                }
                                
                            if($this->wph->server_nginx_config   === TRUE)           
                                {
                                    $rewrite        =   array();
                                    $rewrite_list   =   array();
                                    $rewrite_rules  =   array();
                                    
                                    $global_settings    =   $this->wph->functions->get_global_settings ( );
                                    
                                    $home_root_path =   $this->wph->functions->get_home_root();
                                       
                                    if(!is_multisite() )
                                        {
                                            $rewrite_list['blog_id'] =   $blog_id;
                                            if( is_multisite() )
                                                {
                                                    $rewrite_base   =   ltrim($this->wph->functions->string_left_replacement($rewrite_base, ltrim($blog_details->path, '/')));
                                                }
                                        }
                                        else
                                            $rewrite_list['blog_id'] =   'network';
                                        
                                    $rewrite_list['type']        =   'location';
                                    $rewrite_list['description'] =   '~ ^__WPH_SITES_SLUG__/' . untrailingslashit($rewrite_base) ;
                                    
                                    
                                    if( $global_settings['nginx_generate_simple_rewrite']   !=  'yes' )
                                        {
                                            $rewrite_rules[]  =   '         set $wph_remap  "${wph_remap}wp-comments__";';
                                        }
                                    
                                    $rewrite_data   =   '';
                                    
                                    $rewrite_data .= "\n         rewrite \"^". untrailingslashit($home_root_path) ."__WPH_SITES_SLUG__/". $rewrite_base ."\" ". $rewrite_to .' '.  $this->wph->functions->get_nginx_flag_type() .';';
                                                                            
                                    $rewrite_rules[]            =   $rewrite_data;
                                    $rewrite_list['data']       =   $rewrite_rules;
                                    
                                    $rewrite[]  =   $rewrite_list;   
                                }
                        }
                    
                    $processing_response['rewrite'] =   $rewrite;   
                                
                    return  $processing_response;     
                    
                    
                }
                
                
            function _callback_saved_author_disable_archive($saved_field_data)
                {
                    $processing_response    =   array();
                    
                    if(empty($saved_field_data) ||  $saved_field_data   ==  'no')
                        return FALSE;
                                           
                    $rewrite_to     =   $this->wph->functions->get_rewrite_to_base( 'index.php', TRUE, FALSE, 'site_path' );
                    
                    $text   =   '';
                                        
                    if($this->wph->server_htaccess_config   === TRUE)
                        {                                        
                            $text    =  'RewriteCond %{QUERY_STRING} author=\d+' . "\n";
                            $text   .=  'RewriteRule ^ '.  $rewrite_to .'?wph-throw-404 [L]';
                        }
                    
                               
                    $processing_response['rewrite'] = $text;            
                                
                    return  $processing_response;     
                    
                    
                }
                
                
            function _init_author_disable_enumeration( $saved_field_data )
                {
                    if( empty ( $saved_field_data ) ||  $saved_field_data   !== 'yes' )
                        return FALSE;
                                        
                    add_filter('rest_endpoints', function ($endpoints) 
                        {
                            foreach ($endpoints as $route => $details) 
                                {
                                    if ( strpos($route, '/wp/v2/users' ) === 0 )
                                        unset($endpoints[$route]);
                                }
                            return $endpoints;
                            
                        }, 999 );
                        
                    add_filter('oembed_response_data', function ( $data ) 
                        {
                            if (!empty($data['author_name']))
                                unset($data['author_name']);

                            if (!empty($data['author_url']))
                                unset($data['author_url']);

                            return $data;
                            
                        }, 999 );
                        
                    add_filter( 'wp_sitemaps_users_pre_url_list', '__return_false' );
                    
                }
                
            
            
            function _callback_saved_author_block_default( $saved_field_data )
                {

                    if(empty($saved_field_data) ||  $saved_field_data   ==  'no'     ||  ! is_multisite())
                        return FALSE;
                    
                    $processing_response    =   array();
                    
                    global $blog_id;
                    if ( is_multisite() )
                        {
                            $blog_details   =   get_blog_details( $blog_id );
                            $ms_settings    =   $this->wph->functions->get_site_settings('network');
                        }
                    
                    //prevent from blocking if the wp_comments_post is not modified
                    $new_path     =   $this->wph->functions->get_site_module_saved_value('new_wp_comments_post',  $this->wph->functions->get_blog_id_setting_to_use(), 'display');
                    if (empty(  $new_path ))
                        return FALSE;

                        
                    $rewrite                            =  '';

                    $rewrite_base       =   $this->wph->functions->get_rewrite_base( 'author/(.+)', FALSE, FALSE, 'wp_path' );
                    $rewrite_to         =   $this->wph->functions->get_rewrite_to_base( 'index.php?wph-throw-404' , TRUE, FALSE, 'site_path' );
                    
                    if($this->wph->server_htaccess_config   === TRUE)
                        {                                        
 
                            if(!is_multisite() )
                                {
                                    $rewrite   .=   "\nRewriteRule ^" . $rewrite_base ." ".  $rewrite_to ." [END]";
                                }
                                else
                                {
                                    $rewrite   .=   "\nRewriteRule ^([_0-9a-zA-Z-]+/)?" . $rewrite_base ." ".  $rewrite_to ." [END]";
                                }
                            
                        }
                        
                    if($this->wph->server_web_config   === TRUE)
                        {
                            $rewrite    =   "\n" . '<rule name="wph-block_wp_comments_post_url" stopProcessing="true">';
                            
                            if(!is_multisite() )
                                {
                                    $rewrite .=  "\n"  .    '    <match url="^'.  $rewrite_base   .'"  />';
                                    $rewrite .=   "\n" .    '    <action type="Rewrite" url="'.  $rewrite_to .'"  appendQueryString="false" />';
                                }
                                else
                                {
                                    $rewrite .=  "\n"  .    '    <match url="^([_0-9a-zA-Z-]+/)?'.  $rewrite_base   .'"  />';
                                    $rewrite .=   "\n" .    '    <action type="Rewrite" url="'.  $rewrite_to .'"  appendQueryString="false" />';
                                }
                            
                            $rewrite .=  "\n" . '</rule>';

                        }
                    
                    if($this->wph->server_nginx_config   === TRUE)           
                        {
                            $global_settings    =   $this->wph->functions->get_global_settings ( );
                            
                            $home_root_path =   $this->wph->functions->get_home_root();
                            
                            if ( $global_settings['nginx_generate_simple_rewrite']   ==  'yes' )
                                {
                                    if ( ! is_multisite() )
                                        {
                                            $rewrite        =   array();    
                                            $rewrite_list   =   array();
                                            $rewrite_rules  =   array();
                                            
                                            $rewrite_list['blog_id']        =   'network';
                                            $rewrite_list['type']           =   'location';
                                            $rewrite_list['description']    =   '~ ^__WPH_SITES_SLUG__/' . untrailingslashit($rewrite_base);
                                            
                                            $rewrite_data               =   "rewrite \"^". untrailingslashit($home_root_path) ."__WPH_SITES_SLUG__/". $rewrite_base ."\" ". $rewrite_to .' '.  $this->wph->functions->get_nginx_flag_type() .';';    
                                            
                                            $rewrite_rules[]            =   $rewrite_data;
                                            $rewrite_list['data']       =   $rewrite_rules; 
                                            
                                            $rewrite[]                  =   $rewrite_list; 
                                        }
                                    
                                    $processing_response['rewrite'] = $rewrite;            
                                    return  $processing_response;    
                                }
                                                            
                            $rewrite        =   array();    
                            $rewrite_list   =   array();
                            $rewrite_rules  =   array();
                            
                            if(!is_multisite() )
                                {
                                    $rewrite_list['blog_id'] =   $blog_id;
                                    if( is_multisite() )
                                        {
                                            $rewrite_base   =   ltrim($this->wph->functions->string_left_replacement($rewrite_base, ltrim($blog_details->path, '/')));
                                        }
                                }
                                else
                                    $rewrite_list['blog_id'] =   'network';
                            
                            $rewrite_list   =   array();
                            $rewrite_rules  =   array();
                            
                            if(!is_multisite() )
                                {
                                    $rewrite_list['blog_id'] =   $blog_id;
                                }
                                else
                                    $rewrite_list['blog_id'] =   'network';
                                    
                            $rewrite_list['type']        =   'location';
                            $rewrite_list['description'] =   '~ ^__WPH_SITES_SLUG__/' . untrailingslashit($rewrite_base) . '';
                                                        
                            $rewrite_data   =   '';

                            $rewrite_data  .=   "\n".'         if ( $wph_remap = "" ) {';
                            $rewrite_data  .=   "\n             rewrite ^__WPH_SITES_SLUG__/". $rewrite_base ." ". $rewrite_to .' last;';
                            $rewrite_data  .=   "\n         }";
                            $rewrite_data  .=   "\n\n         #" . __('REPLACE THE FOLLOWING LINE WITH YOUR OWN INCLUDE! This can be found within block', 'wp-hide-security-enhancer') ."  location ~ \.php$";
                            $rewrite_data  .=   "\n" .'         include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.0-fpm.sock;';
                            
                            $rewrite_rules[]            =   $rewrite_data;
                            $rewrite_list['data']       =   $rewrite_rules;
                            
                            $rewrite[]  =   $rewrite_list;    
                        }
                               
                    $processing_response['rewrite'] = $rewrite;            
                                
                    return  $processing_response;     
                    
                    
                }
                
            
            /**
            * Rewrite the default Author url
            * 
            * @param mixed $author_rewrite
            */
            function author_rewrite_rules( $author_rewrite )
                {
                    $new_author_path        =   $this->wph->functions->get_site_module_saved_value( 'author',  $this->wph->functions->get_blog_id_setting_to_use() );
                    
                    if( empty( $new_author_path ) )
                        return $author_rewrite;
                        
                    $author_block_default   =   $this->wph->functions->get_site_module_saved_value('author_block_default', $this->wph->functions->get_blog_id_setting_to_use() );                    
                    
                    $new_rules              =   array();
                    foreach ( $author_rewrite   as  $key    =>  $value )
                        {
                            $new_rules[ str_replace( 'author/', $new_author_path .'/' , $key ) ]    =   $value;    
                        }
                        
                    if  ( $author_block_default ==  'yes')
                        $author_rewrite =   $new_rules;
                        else
                        $author_rewrite =   array_merge ( $author_rewrite, $new_rules );
                    
                    return $author_rewrite;
                      
                }

            
        }
?>