block // in the middle of the form and registered the header filter too late // to have any effect. $this->action( 'login_enqueue_scripts', [$this, 'print_login_styles'] ); if ( !$this->is_enabled() ) { return; } $this->filter( 'login_headerurl', [$this, 'login_header_url'] ); $this->filter( 'login_headertext', [$this, 'login_header_text'] ); $settings = $this->get_settings(); if ( !empty( $settings['remember-me'] ) ) { $this->action( 'login_footer', [$this, 'precheck_remember_me'] ); } } /** * Build and print the login stylesheet. * * @return void */ public function print_login_styles() { if ( !$this->is_enabled() ) { return; } $css = $this->build_css(); if ( '' === trim( $css ) ) { return; } // wp_add_inline_style needs a registered handle; login-styles is the // stylesheet WordPress itself enqueues on wp-login.php. wp_add_inline_style( 'login', $css ); } /** * Compose the stylesheet from the saved options. * * @return string */ private function build_css() { $s = $this->get_settings(); $out = []; // --- Logo ----------------------------------------------------------- $logo = isset( $s['logo'] ) ? esc_url_raw( (string) $s['logo'] ) : ''; if ( '' !== $logo ) { $width = $this->px( $s['logo-width'] ?? 84, 84 ); $height = $this->px( $s['logo-height'] ?? 84, 84 ); $out[] = sprintf( '#login h1 a, .login h1 a { background-image: url(%1$s); background-size: contain; background-repeat: no-repeat; background-position: center center; width: %2$dpx; height: %3$dpx; margin-bottom: 20px; }', esc_url( $logo ), $width, $height ); } // --- Page background ------------------------------------------------- $body = []; $bg_color = $this->color( $s['bg-color'] ?? '' ); if ( '' !== $bg_color ) { $body[] = sprintf( 'background-color: %s;', $bg_color ); } $bg_image = isset( $s['bg-image'] ) ? esc_url_raw( (string) $s['bg-image'] ) : ''; if ( '' !== $bg_image ) { $body[] = sprintf( 'background-image: url(%s);', esc_url( $bg_image ) ); $body[] = 'background-size: cover;'; $body[] = 'background-position: center center;'; $body[] = 'background-repeat: no-repeat;'; $body[] = 'background-attachment: fixed;'; } if ( $body ) { $out[] = "body.login {\n " . implode( "\n ", $body ) . "\n}"; } // --- Form card ------------------------------------------------------- $form = []; $form_bg = $this->color( $s['form-bg-color'] ?? '' ); if ( '' !== $form_bg ) { $form[] = sprintf( 'background: %s;', $form_bg ); } if ( !empty( $s['form-rounded'] ) ) { $form[] = 'border-radius: 10px;'; } if ( $form ) { $out[] = ".login form {\n " . implode( "\n ", $form ) . "\n}"; } // --- Text and links --------------------------------------------------- $text_color = $this->color( $s['text-color'] ?? '' ); if ( '' !== $text_color ) { $out[] = sprintf( '.login form label, .login form, .login #backtoblog a, .login #nav a { color: %s; }', $text_color ); } $link_color = $this->color( $s['link-color'] ?? '' ); if ( '' !== $link_color ) { $out[] = sprintf( '.login #nav a, .login #backtoblog a, .login a { color: %1$s; } .login #nav a:hover, .login #backtoblog a:hover, .login a:hover { color: %1$s; opacity: .8; }', $link_color ); } // --- Primary button --------------------------------------------------- $button_color = $this->color( $s['button-color'] ?? '' ); if ( '' !== $button_color ) { $out[] = sprintf( '.login .button-primary { background: %1$s; border-color: %1$s; color: #fff; text-shadow: none; box-shadow: none; } .login .button-primary:hover, .login .button-primary:focus { background: %1$s; border-color: %1$s; color: #fff; opacity: .9; } .login input[type="text"]:focus, .login input[type="password"]:focus, .login input[type="email"]:focus { border-color: %1$s; box-shadow: 0 0 0 1px %1$s; outline: 2px solid transparent; }', $button_color ); } // --- Hide default links ------------------------------------------------ $hide = []; if ( !empty( $s['hide-lost-password'] ) ) { $hide[] = '.login #nav a[href*="lostpassword"]'; } if ( !empty( $s['hide-register'] ) ) { $hide[] = '.login #nav a[href*="action=register"]'; $hide[] = '.login #nav a[href*="wp-signup"]'; } if ( !empty( $s['hide-back-to-site'] ) ) { $hide[] = '.login #backtoblog'; } if ( !empty( $s['hide-language-switcher'] ) ) { $hide[] = '.login .language-switcher'; } if ( !empty( $s['hide-logo'] ) ) { $hide[] = '#login h1'; } if ( $hide ) { $out[] = implode( ",\n", $hide ) . " {\n display: none !important;\n}"; } // --- Free-form CSS ------------------------------------------------------ if ( !empty( $s['custom-css'] ) ) { $out[] = $this->sanitize_css( (string) $s['custom-css'] ); } return implode( "\n\n", array_filter( $out ) ); } /* --------------------------------------------------------------------- * Header link and text * ------------------------------------------------------------------- */ /** * Where the logo links to. Defaults to the site home rather than wordpress.org. * * @param string $url Current URL. * @return string */ public function login_header_url( $url ) { $s = $this->get_settings(); $target = isset( $s['logo-url'] ) ? trim( (string) $s['logo-url'] ) : ''; if ( '' === $target ) { return home_url( '/' ); } $target = esc_url_raw( $target ); return $target ? $target : home_url( '/' ); } /** * Accessible text behind the logo. * * @param string $text Current text. * @return string */ public function login_header_text( $text ) { $s = $this->get_settings(); $custom = isset( $s['logo-text'] ) ? trim( (string) $s['logo-text'] ) : ''; return '' !== $custom ? esc_html( $custom ) : $text; } /** * Tick "Remember Me" by default. * * @return void */ public function precheck_remember_me() { ?> 0 && $value <= 600 ) ? $value : $default; } /** * Strip anything from the custom CSS box that is not CSS. * * The value is administrator-authored, but it is printed into a or a * javascript: URL must not survive. * * @param string $css Raw CSS. * @return string */ private function sanitize_css( $css ) { $css = wp_strip_all_tags( $css ); $css = preg_replace( '#javascript\s*:#i', '', $css ); $css = preg_replace( '#expression\s*\(#i', '', $css ); $css = str_replace( ['<', '>'], '', $css ); return trim( $css ); } private function get_settings() { if ( null === $this->settings ) { $settings = get_option( get_tpsa_settings_option_name( $this->features_id ), [] ); $this->settings = is_array( $settings ) ? $settings : []; } return $this->settings; } private function is_enabled() { $s = $this->get_settings(); return isset( $s['enable'] ) && (int) $s['enable'] === 1; } }