settings = $settings; add_action( 'login_enqueue_scripts', array( $this, 'enqueue' ) ); add_filter( 'login_message', array( $this, 'render_above' ), 20 ); add_action( 'login_footer', array( $this, 'render_below' ) ); add_shortcode( 'm365_login_button', array( $this, 'shortcode' ) ); } /** * Whether the button should be shown for the current login screen. * * @return bool */ private function should_render() { if ( ! $this->settings->is_configured() ) { return false; } // phpcs:disable WordPress.Security.NonceVerification.Recommended -- read-only routing check. $action = isset( $_REQUEST['action'] ) ? sanitize_key( wp_unslash( $_REQUEST['action'] ) ) : 'login'; $interim = ! empty( $_REQUEST['interim-login'] ); // phpcs:enable WordPress.Security.NonceVerification.Recommended if ( $interim || ! in_array( $action, array( '', 'login' ), true ) ) { return false; } /** * Filters whether the Microsoft button is displayed on the login screen. * * @param bool $show Show the button. */ return (bool) apply_filters( 'm365_login_show_button', true ); } /** * Enqueues login styles and the small positioning script. */ public function enqueue() { if ( ! $this->should_render() ) { return; } wp_enqueue_style( 'm365-login', M365_LOGIN_URL . 'assets/css/login.css', array(), M365_LOGIN_VERSION ); wp_add_inline_style( 'm365-login', $this->css_variables() ); if ( 'below' === $this->settings->get( 'button_position' ) ) { wp_enqueue_script( 'm365-login', M365_LOGIN_URL . 'assets/js/login.js', array(), M365_LOGIN_VERSION, true ); } } /** * CSS custom properties derived from the settings. * * @return string */ public function css_variables() { $s = $this->settings->all(); return sprintf( '.m365-login{--m365-bg:%1$s;--m365-bg-hover:%2$s;--m365-color:%3$s;--m365-border:%4$s;--m365-radius:%5$dpx;}', sanitize_hex_color( $s['button_bg'] ), sanitize_hex_color( $s['button_bg_hover'] ), sanitize_hex_color( $s['button_color'] ), sanitize_hex_color( $s['button_border'] ), absint( $s['button_radius'] ) ); } /** * Output above the form (via login_message). * * @param string $message Existing message HTML. * @return string */ public function render_above( $message ) { if ( 'above' !== $this->settings->get( 'button_position' ) || ! $this->should_render() ) { return $message; } return $message . $this->markup( 'above' ); } /** * Output below the form (moved into place by login.js). */ public function render_below() { if ( 'below' !== $this->settings->get( 'button_position' ) || ! $this->should_render() ) { return; } echo $this->markup( 'below' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- markup() escapes everything. } /** * Shortcode for placing the button on custom login pages. * * @param array $atts Attributes. * @return string */ public function shortcode( $atts ) { if ( ! $this->settings->is_configured() || is_user_logged_in() ) { return ''; } $atts = shortcode_atts( array( 'redirect' => '' ), $atts, 'm365_login_button' ); wp_enqueue_style( 'm365-login', M365_LOGIN_URL . 'assets/css/login.css', array(), M365_LOGIN_VERSION ); wp_add_inline_style( 'm365-login', $this->css_variables() ); return '
' . $this->button( esc_url_raw( $atts['redirect'] ) ) . '
'; } /** * Full block: divider + button. * * @param string $position 'above' or 'below'. * @return string */ public function markup( $position ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- passed through to the flow, validated there. $redirect_to = isset( $_REQUEST['redirect_to'] ) ? esc_url_raw( wp_unslash( $_REQUEST['redirect_to'] ) ) : ''; $divider = (string) $this->settings->get( 'divider_text' ); $divider = '' === trim( $divider ) ? '' : ''; $html = '
'; $html .= 'above' === $position ? $this->button( $redirect_to ) . $divider : $divider . $this->button( $redirect_to ); $html .= '
'; return $html; } /** * Button markup. * * @param string $redirect_to Post-login destination. * @return string */ public function button( $redirect_to = '' ) { $auth = M365_Login::instance()->auth; $url = $auth->start_url( $redirect_to ); $icon = ''; if ( $this->settings->get( 'button_show_icon' ) ) { $custom = (string) $this->settings->get( 'button_icon' ); if ( '' !== $custom && M365_Login_Settings::is_safe_image_url( $custom ) ) { $icon = ''; } else { $icon = self::microsoft_logo(); } } return '' . $icon . '' . esc_html( $this->settings->get( 'button_text' ) ) . '' . ''; } /** * Bundled Microsoft logo (inline SVG, four coloured squares). * * @return string */ public static function microsoft_logo() { return ''; } }