HEX
Server: LiteSpeed
System: Linux server315.web-hosting.com 4.18.0-553.54.1.lve.el8.x86_64 #1 SMP Wed Jun 4 13:01:13 UTC 2025 x86_64
User: globfdxw (6114)
PHP: 8.1.34
Disabled: NONE
Upload Files
File: /home/globfdxw/diasporameetsafrica.com/wp-content/plugins/extendify/app/Toolbar/Frontend.php
<?php

/**
 * Front-end loader for the simple Extendify toolbar.
 *
 * Renders a minimal toolbar at the top of the page (AI Agent /
 * Quick Edit / Edit page / WP Admin) to replace the WordPress core
 * admin bar for editors who prefer it. The core admin bar stays in
 * the DOM so the Agent's mounted button still exists for the toolbar's
 * "AI Agent" link to drive — we just hide it via CSS.
 *
 * Render decision: front end + logged in + Extendify's required
 * capability (default manage_options) + the user's core "Show Toolbar
 * when viewing site" preference is on + the user's Toolbar Style
 * setting resolves to "simple". The default style is Launch-aware:
 * 'simple' when the site has finished Launch, 'full' before it.
 */

namespace Extendify\Toolbar;

defined('ABSPATH') || die('No direct access.');

use Extendify\Config;
use Extendify\PartnerData;

class Frontend
{
    // phpcs:ignore PSR12.Properties.ConstantVisibility.NotFound -- 7.0 floor: no const visibility
    const STYLE_META = 'extendify_toolbar_style';

    public function __construct()
    {
        \add_action('wp_enqueue_scripts', [$this, 'loadScriptsAndStyles']);
        \add_action('wp_body_open', [$this, 'render'], 1);
        \add_action('wp_head', [$this, 'hideCoreAdminBar'], 1);
    }

    /**
     * Resolved style for the current user — 'simple' or 'full'.
     *
     * Honors the per-user setting; falls back to a Launch-aware
     * default when the user hasn't picked one.
     *
     * @param int|null $userId
     * @return string
     */
    public static function style($userId = null)
    {
        $userId = $userId ? (int) $userId : \get_current_user_id();
        if (!$userId) {
            return self::defaultStyle();
        }
        $val = \get_user_meta($userId, self::STYLE_META, true);
        if ($val === 'simple' || $val === 'full') {
            return $val;
        }
        return self::defaultStyle();
    }

    /**
     * The toolbar style the user lands on when they haven't picked
     * one explicitly. Simple after Launch, full before.
     *
     * @return string
     */
    public static function defaultStyle()
    {
        return Config::$launchCompleted ? 'simple' : 'full';
    }

    /**
     * True iff the user has the core "Show Toolbar when viewing
     * site" pref on. We respect it — turning the toolbar off in the
     * core profile setting hides ours too.
     *
     * @param int|null $userId
     * @return bool
     */
    protected static function corePrefOn($userId = null)
    {
        $userId = $userId ? (int) $userId : \get_current_user_id();
        if (!$userId) {
            return false;
        }
        return 'true' === \get_user_option('show_admin_bar_front', $userId);
    }

    /**
     * Whether to render the simple toolbar on this request.
     *
     * @return bool
     */
    public static function shouldRender()
    {
        if (\is_admin() || !\is_user_logged_in() || !\current_user_can(Config::$requiredCapability)) {
            return false;
        }
        // The Customizer preview iframe is a front-end render — the toolbar
        // belongs only on the live, top-level page.
        if (\is_customize_preview()) {
            return false;
        }
        if (!self::corePrefOn()) {
            return false;
        }
        return self::style() === 'simple';
    }

    /**
     * @return void
     */
    public function loadScriptsAndStyles()
    {
        if (!self::shouldRender()) {
            return;
        }

        $version = constant('EXTENDIFY_DEVMODE') ? uniqid() : Config::$version;
        $manifest = Config::$assetManifest;
        $assetKey = 'extendify-toolbar.php';
        $jsKey = 'extendify-toolbar.js';
        $cssKey = 'extendify-toolbar.css';

        if (empty($manifest[$assetKey]) || empty($manifest[$jsKey])) {
            return;
        }

        $scriptAssetPath = EXTENDIFY_PATH . 'public/build/' . $manifest[$assetKey];
        $fallback = ['dependencies' => [], 'version' => $version];
        $scriptAsset = file_exists($scriptAssetPath) ? require $scriptAssetPath : $fallback;

        \wp_enqueue_script(
            Config::$slug . '-toolbar-scripts',
            EXTENDIFY_BASE_URL . 'public/build/' . $manifest[$jsKey],
            $scriptAsset['dependencies'],
            $scriptAsset['version'],
            true
        );

        \wp_set_script_translations(
            Config::$slug . '-toolbar-scripts',
            'extendify-local',
            EXTENDIFY_PATH . 'languages/js'
        );

        if (!empty($manifest[$cssKey])) {
            \wp_enqueue_style(
                Config::$slug . '-toolbar-styles',
                EXTENDIFY_BASE_URL . 'public/build/' . $manifest[$cssKey],
                [],
                $version,
                'all'
            );
        }
    }

    /**
     * Render the toolbar at the top of <body>.
     *
     * @return void
     */
    public function render()
    {
        if (!self::shouldRender()) {
            return;
        }

        $editLink = '';
        $queried = \get_queried_object();
        if ($queried instanceof \WP_Post) {
            $maybe = \get_edit_post_link($queried->ID);
            if ($maybe) {
                $editLink = $maybe;
            }
        }

        // phpcs:disable Generic.Files.LineLength.TooLong -- inline SVG + HTML template markup
        ?>
        <div id="extendify-toolbar" role="navigation" aria-label="<?php \esc_attr_e('Site toolbar', 'extendify-local'); ?>">
            <div class="ext-tb-section ext-tb-left">
                <button type="button" class="ext-tb-btn ext-tb-ai-agent" id="ext-tb-ai-agent" aria-label="<?php \esc_attr_e('Open the AI Agent', 'extendify-local'); ?>">
                    <svg class="ext-tb-magic" width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
                        <path d="M17.0909 9.81818L18 7.81818L20 6.90909L18 6L17.0909 4L16.1818 6L14.1818 6.90909L16.1818 7.81818L17.0909 9.81818Z" fill="currentColor"/>
                        <path d="M17.0909 14.1818L16.1818 16.1818L14.1818 17.0909L16.1818 18L17.0909 20L18 18L20 17.0909L18 16.1818L17.0909 14.1818Z" fill="currentColor"/>
                        <path d="M11.6364 10.1818L9.81818 6.18182L8 10.1818L4 12L8 13.8182L9.81818 17.8182L11.6364 13.8182L15.6364 12L11.6364 10.1818ZM10.5382 12.72L9.81818 14.3055L9.09818 12.72L7.51273 12L9.09818 11.28L9.81818 9.69455L10.5382 11.28L12.1236 12L10.5382 12.72Z" fill="currentColor"/>
                    </svg>
                    <span class="ext-tb-ai-label"><?php \esc_html_e('AI Agent', 'extendify-local'); ?></span>
                </button>
                <?php if (PartnerData::setting('showQuickEdit') || Config::preview('quick-edit')) : ?>
                    <button type="button" class="ext-tb-btn ext-tb-quick-edit" id="ext-tb-quick-edit" role="switch" aria-checked="false">
                        <span class="ext-tb-toggle" aria-hidden="true"><span class="ext-tb-toggle-thumb"></span></span>
                        <span><?php \esc_html_e('Quick Edit', 'extendify-local'); ?></span>
                    </button>
                <?php endif; ?>
            </div>
            <div class="ext-tb-section ext-tb-right">
                <?php if ($editLink) : ?>
                    <a class="ext-tb-btn ext-tb-edit" href="<?php echo \esc_url($editLink); ?>" target="_blank" rel="noopener noreferrer">
                        <svg class="ext-tb-pencil" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
                            <path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 0 0 0-1.41l-2.34-2.34a1 1 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z" fill="currentColor"/>
                        </svg>
                        <span><?php /* translators: button label linking to the WordPress block editor. */ \esc_html_e('Block Editor', 'extendify-local'); ?></span>
                        <svg class="ext-tb-external" width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
                            <path d="M7 1.5h3.5V5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
                            <path d="M10.5 1.5L5.5 6.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
                            <path d="M9.5 7v3a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1H5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
                        </svg>
                        <span class="screen-reader-text"><?php \esc_html_e('(opens in a new tab)', 'extendify-local'); ?></span>
                    </a>
                <?php endif; ?>
                <a class="ext-tb-btn ext-tb-admin-link" href="<?php echo \esc_url(\admin_url()); ?>" target="_blank" rel="noopener noreferrer">
                    <span><?php \esc_html_e('WP Admin', 'extendify-local'); ?></span>
                    <svg class="ext-tb-external" width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false">
                        <path d="M7 1.5h3.5V5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
                        <path d="M10.5 1.5L5.5 6.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
                        <path d="M9.5 7v3a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1H5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
                    </svg>
                    <span class="screen-reader-text"><?php \esc_html_e('(opens in a new tab)', 'extendify-local'); ?></span>
                </a>
            </div>
        </div>
        <?php
        // phpcs:enable Generic.Files.LineLength.TooLong
    }

    /**
     * Hide the core admin bar visually and keep the top-margin reservation
     * so theme layouts that account for it still flow correctly. We can't
     * unconditionally drop the bar from the DOM — the Agent script mounts
     * its own button into `#wp-admin-bar-extendify-agent-btn`, and the
     * toolbar's "AI Agent" link drives that mounted button at click time.
     *
     * @return void
     */
    public function hideCoreAdminBar()
    {
        if (!self::shouldRender()) {
            return;
        }

        ?>
        <style id="extendify-toolbar-reset">
            #wpadminbar { display: none !important; }
            html { margin-top: 32px !important; }
            * html body { margin-top: 32px !important; }
            @media screen and (max-width: 782px) {
                html { margin-top: 46px !important; }
                * html body { margin-top: 46px !important; }
            }
        </style>
        <?php
    }
}