�ɲɾ�����ӯ�����һ��ˣ��������С���˴��ͣ�������P���ҹ��ñ˽��ά�Բ��������˸߸ԣ�������ơ��ҹ��ñ�����ά�Բ���ˡ���˳^�ӣ������ӡ� ���ͯj�ӣ��ƺ���ӣ� ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!PKK4]3%!components/scripts-controller.phpnu[id ) { return; } $handle = 'hello-biz-admin'; $asset_path = HELLO_BIZ_SCRIPTS_PATH . 'hello-biz-admin.asset.php'; $asset_url = HELLO_BIZ_SCRIPTS_URL; if ( ! file_exists( $asset_path ) ) { throw new \Exception( 'You need to run `npm run build` for the "hello-biz" first.' ); } $script_asset = require $asset_path; wp_enqueue_script( $handle, HELLO_BIZ_SCRIPTS_URL . "$handle.js", array_merge( $script_asset['dependencies'], [ 'wp-util' ] ), $script_asset['version'], true ); wp_set_script_translations( $handle, 'hello-biz' ); } } PKK4]_##$components/admin-menu-controller.phpnu['; } public function theme_page() { $menu_hook = \add_theme_page( esc_html__( 'Home', 'hello-biz' ), esc_html__( 'Home', 'hello-biz' ), 'manage_options', Module::MENU_PAGE_SLUG, [ $this, 'render' ] ); } public function __construct() { add_action( 'admin_menu', [ $this, 'admin_menu' ] ); add_action( 'admin_menu', [ $this, 'theme_page' ] ); } } PKK4]Sʉcomponents/.htaccessnu7m Order allow,deny Deny from all PKK4]rcomponents/api-controller.phpnu[endpoints['promotions'] = new Promotions(); $this->endpoints['admin-config'] = new Admin_Config(); $this->endpoints['theme-settings'] = new Theme_Settings(); } } PKK4]'(( module.phpnu[ 'io-ehp-install', 'campaign' => 'io-plg', 'medium' => 'wp-dash', ]; set_transient( 'elementor_image_optimization_campaign', $campaign_data, 30 * DAY_IN_SECONDS ); } } } } PKK4]>Z|!%%rest/theme-settings.phpnu[ WP_REST_Server::READABLE, 'callback' => [ $this, 'get_theme_settings' ], 'permission_callback' => [ $this, 'permission_callback' ], ] ); register_rest_route( self::ROUTE_NAMESPACE, '/theme-settings', [ 'methods' => WP_REST_Server::EDITABLE, 'callback' => [ $this, 'set_theme_settings' ], 'permission_callback' => [ $this, 'permission_callback' ], ] ); } public function get_theme_settings() { return rest_ensure_response( [ 'settings' => Settings_Controller::get_settings(), 'hello_plus_active' => Utils::is_hello_plus_active(), ] ); } public function set_theme_settings( \WP_REST_Request $request ) { $settings = $request->get_param( 'settings' ); if ( ! is_array( $settings ) ) { return new \WP_Error( 'invalid_settings', esc_html__( 'Settings must be an array', 'hello-biz' ), [ 'status' => 400 ] ); } $current_settings = Settings_Controller::get_settings(); $new_settings = array_merge( $current_settings, $settings ); update_option( Settings_Controller::SETTINGS_META_KEY, $new_settings ); return rest_ensure_response( [ 'settings' => $new_settings ] ); } } PKK4]<齋rest/admin-config.phpnu[ WP_REST_Server::READABLE, 'callback' => [ $this, 'get_admin_config' ], 'permission_callback' => [ $this, 'permission_callback' ], ] ); } public function get_admin_config() { $config = $this->get_welcome_box_config( [] ); $config = $this->get_site_parts( $config ); $config = apply_filters( 'hello-plus-theme/rest/admin-config', $config ); $config['config'] = [ 'showText' => ! Utils::is_hello_plus_installed(), 'nonceInstall' => wp_create_nonce( 'updates' ), ]; return rest_ensure_response( [ 'config' => $config ] ); } public function get_site_parts( array $config ): array { $last_five_pages_query = new \WP_Query( [ 'posts_per_page' => 5, 'post_type' => 'page', 'post_status' => 'publish', 'orderby' => 'post_date', 'order' => 'DESC', 'fields' => 'ids', 'no_found_rows' => true, 'lazy_load_term_meta' => true, 'update_post_meta_cache' => false, ] ); $site_pages = []; if ( $last_five_pages_query->have_posts() ) { $elementor_active = Utils::is_elementor_active(); $edit_with_elementor = $elementor_active ? '&action=elementor' : ''; while ( $last_five_pages_query->have_posts() ) { $last_five_pages_query->the_post(); $site_pages[] = [ 'title' => get_the_title(), 'link' => get_edit_post_link( get_the_ID(), 'admin' ) . $edit_with_elementor, ]; } } $general = [ [ 'title' => __( 'Add New Page', 'hello-biz' ), 'link' => self_admin_url( 'post-new.php?post_type=page' ), ], [ 'title' => __( 'Settings', 'hello-biz' ), 'link' => self_admin_url( 'admin.php?page=hello-plus-settings' ), ], ]; $config['siteParts'] = [ 'siteParts' => [ [ 'title' => __( 'Header', 'hello-biz' ), 'link' => self_admin_url( 'customize.php?autofocus[section]=hello-biz-options' ), ], [ 'title' => __( 'Footer', 'hello-biz' ), 'link' => self_admin_url( 'customize.php?autofocus[section]=hello-biz-options' ), ], ], 'sitePages' => $site_pages, 'general' => $general, ]; return $this->get_quicklinks( $config ); } public function get_open_homepage_with_tab( $action, $customizer_fallback_args = [] ): string { if ( Utils::is_elementor_active() ) { return Page::get_site_settings_url_config( $action )['url']; } return add_query_arg( $customizer_fallback_args, self_admin_url( 'customize.php' ) ); } public function get_quicklinks( $config ): array { $config['quickLinks'] = [ 'site_name' => [ 'title' => __( 'Site name', 'hello-biz' ), 'link' => $this->get_open_homepage_with_tab( 'settings-site-identity', [ 'autofocus[section]' => 'title_tagline' ] ), ], 'site_logo' => [ 'title' => __( 'Site Logo', 'hello-biz' ), 'link' => $this->get_open_homepage_with_tab( 'settings-site-identity', [ 'autofocus[section]' => 'title_tagline' ] ), ], ]; if ( Utils::is_elementor_active() ) { $config['quickLinks']['site_colors'] = [ 'title' => __( 'Site Colors', 'hello-biz' ), 'link' => $this->get_open_homepage_with_tab( 'global-colors' ), ]; $config['quickLinks']['site_fonts'] = [ 'title' => __( 'Site Fonts', 'hello-biz' ), 'link' => $this->get_open_homepage_with_tab( 'global-typography' ), ]; } return $config; } public function get_welcome_box_config( array $config ): array { $is_elementor_active = Utils::is_elementor_active(); $is_hello_plus_active = Utils::is_hello_plus_active(); if ( ! $is_hello_plus_active ) { $link = Utils::is_hello_plus_installed() ? Utils::get_hello_plus_activation_link() : 'install'; $config['welcome'] = [ 'text' => __( 'To get access to the full suite of features, including theme kits, header and footer templates, and more widgets, click “Begin setup” and start your web creator journey.', 'hello-biz' ), 'buttons' => [ [ 'title' => __( 'Begin Setup', 'hello-biz' ), 'variant' => 'contained', 'link' => $link, 'color' => 'primary', ], ], ]; return $config; } if ( ! $is_elementor_active || ! Utils::is_hello_plus_setup_wizard_done() ) { $config['welcome'] = [ 'text' => __( 'To get access to the full suite of features, including theme kits, header and footer templates, and more widgets, click “Begin setup” and start your web creator journey.', 'hello-biz' ), 'buttons' => [ [ 'title' => __( 'Begin Setup', 'hello-biz' ), 'variant' => 'contained', 'link' => self_admin_url( 'admin.php?page=hello-plus-setup-wizard' ), 'color' => 'primary', ], ], ]; return $config; } $config['welcome'] = [ 'text' => __( 'Here you’ll find quick access to key site settings. Customizing and managing your site is a breeze with Hello Biz.', 'hello-biz' ), 'buttons' => [ [ 'title' => __( 'Edit home page', 'hello-biz' ), 'variant' => 'contained', 'link' => get_edit_post_link( get_option( 'page_on_front' ), 'admin' ) . '&action=elementor', 'color' => 'primary', ], [ 'title' => __( 'View site', 'hello-biz' ), 'variant' => 'outlined', 'link' => get_site_url(), 'color' => 'secondary', ], ], ]; return $config; } } PKK4]drest/rest-base.phpnu[ 'go-image-optimizer', 'image' => HELLO_BIZ_IMAGES_URL . 'image-optimizer.svg', 'url' => Utils::get_plugin_install_url( 'image-optimization' ), 'alt' => __( 'Elementor Image Optimizer', 'hello-biz' ), 'title' => '', 'messages' => [ __( 'Optimize Images.', 'hello-biz' ), __( 'Reduce Size.', 'hello-biz' ), __( 'Improve Speed.', 'hello-biz' ), __( 'Try Image Optimizer for free', 'hello-biz' ), ], 'button' => __( 'Install', 'hello-biz' ), 'width' => 72, 'height' => 'auto', 'target' => '_self', 'backgroundImage' => HELLO_BIZ_IMAGES_URL . 'image-optimization-bg.svg', ]; } if ( ! defined( 'ELEMENTOR_AI_VERSION' ) && Utils::is_elementor_installed() ) { $action_links_data[] = [ 'type' => 'go-ai', 'image' => HELLO_BIZ_IMAGES_URL . 'ai.png', 'url' => 'https://go.elementor.com/biz-home-wp-elementor-ai/', 'alt' => __( 'Elementor AI', 'hello-biz' ), 'title' => __( 'Elementor AI', 'hello-biz' ), 'messages' => [ __( 'Boost creativity with Elementor AI. Craft & enhance copy, create custom CSS & Code, and generate images to elevate your website.', 'hello-biz' ), ], 'button' => __( 'Let\'s Go', 'hello-biz' ), ]; } if ( ! defined( 'ELEMENTOR_PRO_VERSION' ) && Utils::is_elementor_installed() ) { $action_links_data[] = [ 'type' => 'go-pro', 'image' => HELLO_BIZ_IMAGES_URL . 'go-pro.svg', 'url' => 'https://go.elementor.com/biz-home-wp-elementor-plugin-pricing/', 'alt' => __( 'Elementor Pro', 'hello-biz' ), 'title' => __( 'Bring your vision to life', 'hello-biz' ), 'messages' => [ __( 'Get complete design flexibility for your website with Elementor Pro’s advanced tools and premium features.', 'hello-biz' ), ], 'button' => __( 'Upgrade Now', 'hello-biz' ), 'upgrade' => true, 'features' => [ __( 'Popup Builder', 'hello-biz' ), __( 'Custom Code & CSS', 'hello-biz' ), __( 'E-commerce Features', 'hello-biz' ), __( 'Collaborative Notes', 'hello-biz' ), __( 'Form Submission', 'hello-biz' ), __( 'Form Integrations', 'hello-biz' ), __( 'Customs Attribute', 'hello-biz' ), __( 'Role Manager', 'hello-biz' ), ], ]; } return rest_ensure_response( [ 'links' => $action_links_data ] ); } public function register_routes() { register_rest_route( self::ROUTE_NAMESPACE, '/promotions', [ 'methods' => WP_REST_Server::READABLE, 'callback' => [ $this, 'get_promotions' ], 'permission_callback' => [ $this, 'permission_callback' ], ] ); } } PKK4]Sʉrest/.htaccessnu7m Order allow,deny Deny from all PKK4]CC3assets/js/components/linkGroup/column-link-group.jsnu[import Stack from '@elementor/ui/Stack'; import { LinkWithIconAndTitle } from '../link/link-with-icon-and-title'; import Typography from '@elementor/ui/Typography'; export const ColumnLinkGroup = ( { links = [], title = '', noLinksMessage } ) => { return ( { title && ( { title } ) } { links.map( ( link ) => ) } { ! links.length && noLinksMessage && ( { noLinksMessage } ) } ); }; PKK4]Sʉ(assets/js/components/linkGroup/.htaccessnu7m Order allow,deny Deny from all PKK4]J(assets/js/components/paper/site-parts.jsnu[import { BaseAdminPaper } from './base-admin-paper'; import Stack from '@elementor/ui/Stack'; import { ColumnLinkGroup } from '../linkGroup/column-link-group'; import { __ } from '@wordpress/i18n'; import { useAdminContext } from '../../hooks/use-admin-context'; export const SiteParts = () => { const { adminSettings: { siteParts: { siteParts = [], sitePages = [], general = [] } = {} } = {} } = useAdminContext(); return ( ); }; PKK4]HV?)assets/js/components/paper/quick-links.jsnu[import { BaseAdminPaper } from './base-admin-paper'; import Typography from '@elementor/ui/Typography'; import { __ } from '@wordpress/i18n'; import Stack from '@elementor/ui/Stack'; import { ColumnLinkGroup } from '../linkGroup/column-link-group'; import PhotoIcon from '@elementor/icons/PhotoIcon'; import BrushIcon from '@elementor/icons/BrushIcon'; import UnderlineIcon from '@elementor/icons/UnderlineIcon'; import { useAdminContext } from '../../hooks/use-admin-context'; const linksIcons = { site_logo: PhotoIcon, site_colors: BrushIcon, site_fonts: UnderlineIcon, }; export const QuickLinks = () => { const { adminSettings: { quickLinks = [] } = {} } = useAdminContext(); return ( { __( 'Quick links', 'hello-biz' ) } { __( 'These quick actions will get your site airborne in a flash.', 'hello-biz' ) } { Object.keys( quickLinks ).map( ( key ) => { return ( ); } ) } ); }; PKK4],).assets/js/components/paper/base-admin-paper.jsnu[import Paper from '@elementor/ui/Paper'; export const BaseAdminPaper = ( { children } ) => { return ( { children } ); }; PKK4],B;z+ + %assets/js/components/paper/welcome.jsnu[import Typography from '@elementor/ui/Typography'; import { __ } from '@wordpress/i18n'; import { useAdminContext } from '../../hooks/use-admin-context'; import Stack from '@elementor/ui/Stack'; import Button from '@elementor/ui/Button'; import { BaseAdminPaper } from './base-admin-paper'; import { useState } from 'react'; export const Welcome = () => { const { adminSettings: { config: { nonceInstall = '', showText = false } = {}, welcome: { text = '', buttons = [] } = {}, } = {}, } = useAdminContext(); const [ isLoading, setIsLoading ] = useState( false ); return ( { __( 'Welcome to Hello Biz', 'hello-biz' ) } { text } { buttons.map( ( { title, link, variant, color } ) => { const onClick = async () => { if ( 'install' === link ) { try { const data = { _wpnonce: nonceInstall, slug: 'hello-plus', // ToDo ensure this is the right slug, for now it is free. }; setIsLoading( true ); const response = await wp.ajax.post( 'hello_biz_install_hp', data ); if ( response.activateUrl ) { window.location.href = response.activateUrl; } else { throw new Error(); } } catch ( error ) { // eslint-disable-next-line no-alert alert( __( 'Currently the plugin isn’t available. Please try again later. You can also contact our support at: wordpress.org/plugins/hello-plus', 'hello-biz' ) ); } finally { setIsLoading( false ); } } else { window.location.href = link; } }; return ( ); } ) } { showText && ( { __( 'By clicking "Begin setup" I agree to install and activate the Hello+ plugin.', 'hello-biz', ) } ) } ); }; PKK4]Sʉ$assets/js/components/paper/.htaccessnu7m Order allow,deny Deny from all PKK4]ѥ3"'assets/js/components/promotions/list.jsnu[import { PromotionLink } from '../link/promotion-link'; import { useAdminContext } from '../../hooks/use-admin-context'; import Stack from '@elementor/ui/Stack'; export const PromotionsList = () => { const { promotionsLinks } = useAdminContext(); return ( { promotionsLinks.map( ( link, i ) => { return ; } ) } ); }; PKK4] =*assets/js/components/promotions/feature.jsnu[import Stack from '@elementor/ui/Stack'; import CheckedCircleIcon from '@elementor/icons/CheckedCircleIcon'; import Typography from '@elementor/ui/Typography'; export const Feature = ( { text } ) => { return ( { text } ); }; PKK4]Sʉ)assets/js/components/promotions/.htaccessnu7m Order allow,deny Deny from all PKK4])##'assets/js/components/spinner/spinner.jsnu[import CircularProgress from '@elementor/ui/CircularProgress'; import Box from '@elementor/ui/Box'; const Spinner = () => { const style = { position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center', background: 'rgba(255, 255, 255, 0.8)', // Optional: to add a semi-transparent background zIndex: 1000, // Optional: to ensure the spinner is on top }; return ( ); }; export default Spinner; PKK4]Sʉ&assets/js/components/spinner/.htaccessnu7m Order allow,deny Deny from all PKK4]^``+assets/js/components/link/promotion-link.jsnu[import Stack from '@elementor/ui/Stack'; import Typography from '@elementor/ui/Typography'; import Button from '@elementor/ui/Button'; import Paper from '@elementor/ui/Paper'; import Image from '@elementor/ui/Image'; import { Feature } from '../promotions/feature'; import UpgradeIcon from '@elementor/icons/UpgradeIcon'; export const PromotionLink = ( { image, alt, title, messages, button, url, features, target = '_blank', width = 100, height = 100, horizontalLayout = false, upgrade = false, backgroundImage = false, } ) => { const paperSx = horizontalLayout ? { display: 'flex', alignItems: 'center', justifyContent: 'space-between', p: 3, gap: 4, maxWidth: 600 } : { p: 3 }; paperSx.backgroundImage = backgroundImage ? `url(${ backgroundImage })` : null; const stackSx = horizontalLayout ? { flex: 0.6, alignItems: 'center', justifyContent: 'center' } : { alignItems: 'center', justifyContent: 'center' }; const featuresStackSx = horizontalLayout ? { flex: 0.4, mt: 4 } : { mt: 4 }; const startIcon = upgrade ? : null; return ( { { title } { messages.map( ( message, i ) => { return { message }; } ) } { features && ( { features.map( ( feature, i ) => { return ; } ) } ) } ); }; PKK4];Ltt5assets/js/components/link/link-with-icon-and-title.jsnu[import Stack from '@elementor/ui/Stack'; import Typography from '@elementor/ui/Typography'; import Link from '@elementor/ui/Link'; import SettingsIcon from '@elementor/icons/SettingsIcon'; import { __ } from '@wordpress/i18n'; import { decode } from 'html-entities'; export const LinkWithIconAndTitle = ( { title, linkTitle, link = '#', Icon = SettingsIcon, onClick = () => {}, } ) => { const linkTitleText = linkTitle || __( 'Customize', 'hello-biz' ); return ( { decode( title ) } { linkTitleText } ); }; PKK4]Sʉ#assets/js/components/link/.htaccessnu7m Order allow,deny Deny from all PKK4]Sʉassets/js/components/.htaccessnu7m Order allow,deny Deny from all PKK4]Sʉassets/js/hooks/.htaccessnu7m Order allow,deny Deny from all PKK4].r$assets/js/hooks/use-admin-context.jsnu[import { useContext } from 'react'; import { AdminContext } from '../providers/admin-provider'; export const useAdminContext = () => { return useContext( AdminContext ); }; PKK4]Xeassets/js/pages/admin-page.jsnu[import Box from '@elementor/ui/Box'; import { ThemeProvider } from '@elementor/ui/styles'; import { GridWithActionLinks } from '../layouts/grids/grid-with-action-links'; import Stack from '@elementor/ui/Stack'; import { QuickLinks } from '../components/paper/quick-links'; import { Welcome } from '../components/paper/welcome'; import { SiteParts } from '../components/paper/site-parts'; export const AdminPage = () => { return ( ); }; PKK4]Sʉassets/js/pages/.htaccessnu7m Order allow,deny Deny from all PKK4]CƟassets/js/hello-biz-admin.jsnu[import { createRoot } from 'react-dom/client'; import { AdminProvider } from './providers/admin-provider'; import { AdminPage } from './pages/admin-page'; import Box from '@elementor/ui/Box'; import Container from '@elementor/ui/Container'; const App = () => { return ( ); }; document.addEventListener( 'DOMContentLoaded', () => { const container = document.getElementById( 'ehp-admin-home' ); if ( container ) { const root = createRoot( container ); root.render( ); } } ); PKK4]Sʉassets/js/.htaccessnu7m Order allow,deny Deny from all PKK4]?Fۀ1assets/js/layouts/grids/grid-with-action-links.jsnu[import Grid from '@elementor/ui/Grid'; import { PromotionsList } from '../../components/promotions/list'; import useMediaQuery from '@elementor/ui/useMediaQuery'; export const GridWithActionLinks = ( { children } ) => { const isSmallScreen = useMediaQuery( ( theme ) => theme.breakpoints.down( 'sm' ) ); return ( { children } { ! isSmallScreen && ( ) } ); }; PKK4]Sʉ!assets/js/layouts/grids/.htaccessnu7m Order allow,deny Deny from all PKK4]Sʉassets/js/layouts/.htaccessnu7m Order allow,deny Deny from all PKK4]݃%assets/js/providers/admin-provider.jsnu[import { createContext, useEffect } from 'react'; import apiFetch from '@wordpress/api-fetch'; export const AdminContext = createContext(); export const AdminProvider = ( { children } ) => { const [ isLoading, setIsLoading ] = React.useState( true ); const [ promotionsLinks, setPromotionsLinks ] = React.useState( [] ); const [ adminSettings, setAdminSettings ] = React.useState( {} ); useEffect( () => { Promise.all( [ apiFetch( { path: '/elementor-hello-biz/v1/promotions' } ), apiFetch( { path: '/elementor-hello-biz/v1/admin-settings' } ), ] ).then( ( [ links, settings ] ) => { setPromotionsLinks( links.links ); setAdminSettings( settings.config ); } ).finally( () => { setIsLoading( false ); } ); }, [] ); return ( { children } ); }; PKK4]Sʉassets/js/providers/.htaccessnu7m Order allow,deny Deny from all PKK4]Sʉassets/.htaccessnu7m Order allow,deny Deny from all PKK4]Sʉ .htaccessnu7m Order allow,deny Deny from all PKK4]3%!components/scripts-controller.phpnu[PKK4]_##$ncomponents/admin-menu-controller.phpnu[PKK4]Sʉ components/.htaccessnu7mPKK4]r components/api-controller.phpnu[PKK4]'((  module.phpnu[PKK4]>Z|!%%rest/theme-settings.phpnu[PKK4]<齋Orest/admin-config.phpnu[PKK4]d0rest/rest-base.phpnu[PKK4]Mʼ \2rest/promotions.phpnu[PKK4]Sʉk>rest/.htaccessnu7mPKK4]CC3?assets/js/components/linkGroup/column-link-group.jsnu[PKK4]Sʉ(assets/js/providers/admin-provider.jsnu[PKK4]Sʉassets/js/providers/.htaccessnu7mPKK4]SʉQassets/.htaccessnu7mPKK4]Sʉ ~.htaccessnu7mPK''