<?php

/**
 * File robots.txt helper.
 *
 * @author     Time.ly Network Inc.
 * @since      2.0
 *
 * @package    AI1EC
 * @subpackage AI1EC.query
 */
class Ai1ec_Robots_Helper extends Ai1ec_Base {

    /**
     * Install robotx.txt into current Wordpress instance
     *
     * @return void
     */
    public function install() {
        $option   = $this->_registry->get( 'model.option' );
        $settings = $this->_registry->get( 'model.settings' );
        $robots   = $option->get( 'ai1ec_robots_txt' );
        if ( isset( $robots['page_id'] ) &&
                    $robots['page_id'] == $settings->get( 'calendar_page_id' ) ) {
            return;
        }

        $ftp_base_dir  = defined( 'FTP_BASE' ) ? ( FTP_BASE . DIRECTORY_SEPARATOR ) : '';
        // we can't use ABSPATH for ftp, if ftp user is not chrooted they need
        // to define FTP_BASE in wp-config.php
        $robots_file   = $ftp_base_dir . 'robots.txt';
        $robots_txt    = array();
        $is_installed  = false;
        $current_rules = null;
        $custom_rules  = $this->rules( '', false );

        $url = wp_nonce_url(
            'edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-settings',
            'ai1ec-nonce'
        );

        $redirect_url = ai1ec_admin_url(
            'edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-settings&noredirect=1'
        );

        if ( ! function_exists( 'request_filesystem_credentials' )  ) {
            return;
        }
        $type = get_filesystem_method();
        if ( 'direct' === $type ) {
            // we have to use ABSPATH for direct
            $robots_file = ABSPATH . 'robots.txt';
        }

        $creds = request_filesystem_credentials( $url, $type, false, false, null );

        if ( ! WP_Filesystem( $creds ) ) {
            $error_v = (
                isset( $_POST['hostname'] ) ||
                isset( $_POST['username'] ) ||
                isset( $_POST['password'] ) ||
                isset( $_POST['connection_type'] )
            );
            if ( $error_v ) {
                // if credentials are given and we don't have access to
                // wp filesystem show notice to user
                // we could use request_filesystem_credentials with true error
                // parameter but in this case second ftp credentials screen
                // would appear
                $notification = $this->_registry->get( 'notification.admin' );
                $err_msg = Ai1ec_I18n::__(
                    '<strong>ERROR:</strong> There was an error connecting to the server, Please verify the settings are correct.'
                );
                $notification->store( $err_msg, 'error', 1 );
                // we need to avoid infinity loop if FS_METHOD direct
                // and robots.txt is not writable
                if ( ! isset( $_REQUEST['noredirect'] ) ) {
                    Ai1ec_Http_Response_Helper::redirect( $redirect_url );
                }
            }
            return;
        }

        global $wp_filesystem;
        // sometimes $wp_filesystem could be null
        if ( null === $wp_filesystem ) {
            return;
        }
        $redirect = false;
        if ( $wp_filesystem->exists( $robots_file )
                && $wp_filesystem->is_readable( $robots_file )
                    && $wp_filesystem->is_writable( $robots_file ) ) {
            // Get current robots txt content
            $current_rules = $wp_filesystem->get_contents( $robots_file );

            // Update robots.txt
            $custom_rules = $this->rules( $current_rules, false );
        }
        $robots_txt['is_installed'] = $wp_filesystem->put_contents(
            $robots_file,
            $custom_rules,
            FS_CHMOD_FILE
        );
        if ( false === $robots_txt['is_installed'] ) {
            $err_msg = Ai1ec_I18n::__(
                '<strong>ERROR:</strong> There was an error storing <strong>robots.txt</strong> to the server, the file could not be written.'
            );
            $this->_registry->get( 'notification.admin' )
                ->store( $err_msg, 'error' );
            $redirect = true;
        }
        // Set Page ID
        $robots_txt['page_id'] = $settings->get( 'calendar_page_id' );

        // Update Robots Txt
        $option->set( 'ai1ec_robots_txt', $robots_txt );

        // Update settings textarea
        $settings->set( 'edit_robots_txt', $custom_rules );

        // we need to avoid infinity loop if FS_METHOD direct
        // and robots.txt is not writable
        if ( $redirect && ! isset( $_REQUEST['noredirect'] ) ) {
            Ai1ec_Http_Response_Helper::redirect( $redirect_url );
        }
    }

    /**
     * Get default robots rules for the calendar
     *
     * @param  string $output Current robots rules
     * @param  string $public Public flag
     * @return array
     */
    public function rules( $output = '', $public ) {
        // Current rules
        $current_rules = array_map(
            'trim',
            explode( PHP_EOL, $output )
        );

        // Get calendar page URI
        $calendar_page_id = $this->_registry->get( 'model.settings' )
                                            ->get( 'calendar_page_id' );
        $page_base = get_page_uri( $calendar_page_id );

        // Custom rules
        $custom_rules = array();
        if ( $page_base ) {
            $custom_rules += array(
                "User-agent: *",
                "Disallow: /$page_base/action~posterboard/",
                "Disallow: /$page_base/action~agenda/",
                "Disallow: /$page_base/action~oneday/",
                "Disallow: /$page_base/action~month/",
                "Disallow: /$page_base/action~week/",
                "Disallow: /$page_base/action~stream/",
                "Disallow: /$page_base/action~undefined/",
                "Disallow: /$page_base/action~http:/",
                "Disallow: /$page_base/action~default/",
                "Disallow: /$page_base/action~poster/",
                "Disallow: /$page_base/action~*/",
                "Disallow: /*controller=ai1ec_exporter_controller*",
                "Disallow: /*/action~*/",
            );
        }

        $robots = array_merge( $current_rules, $custom_rules );
        $robots = implode(
            PHP_EOL,
            array_filter( array_unique( $robots ) )
        );
        return $robots;
    }
}
