HEX
Server: Apache
System: Linux scp1.abinfocom.com 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
User: confeduphaar (1010)
PHP: 8.1.33
Disabled: exec,passthru,shell_exec,system
Upload Files
File: /home/confeduphaar/public_html/wp-content/plugins/essential-blocks/src/blocks/post-meta/src/edit.js
/**
 * WordPress dependencies
 */
import { __ } from "@wordpress/i18n";
import { useEffect, memo } from "@wordpress/element";
import { select, withSelect } from "@wordpress/data";
import { compose } from "@wordpress/compose";
import { useEntityProp } from "@wordpress/core-data";
import { dateI18n } from "@wordpress/date";

/**
 * Internal depencencies
 */
import Inspector from "./inspector";
import Style from "./style";
import defaultAttributes from './attributes'
import {
    BlockProps,
    withBlockContext,
    EBDisplayIcon
} from "@essential-blocks/controls";

function Edit(props) {
    const { attributes, setAttributes, isSelected, selectPostType, context } = props;
    const {
        blockId,
        type,
        enableContents,
        authorLabel,
        dateLabel,
        productSkuLabel,
        metaDisplay,
        classHook,
        authorIcon,
        dateIcon,
        skuIcon,
        showMetaIcon,
        showAuthor,
        showAuthorPicture,
        authorPictureLink
    } = attributes;

    // Get post data from Loop Builder context
    const loopPostId = context?.["essential-blocks/postId"];
    const loopPostType = context?.["essential-blocks/postType"];

    // Check if block is inside Loop Builder context
    const isInLoopBuilder = Boolean(
        context &&
            // Primary check: explicit isLoopBuilder flag
            (context["essential-blocks/isLoopBuilder"] === true ||
                // Secondary check: presence of loop context values (even if null initially)
                (context.hasOwnProperty("essential-blocks/postId") &&
                    context.hasOwnProperty("essential-blocks/postType"))),
    );

    const postType = select("core/editor").getCurrentPostType();
    const isContentEnabled = (contentName) => enableContents.includes(contentName);

    // Effect to handle Loop Builder specific default settings (only on first entry)
    useEffect(() => {
        if (isInLoopBuilder && !attributes.hasLoopBuilderDefaults) {
            // Set default values for loop builder context only once
            setAttributes({
                showAuthor: false,
                showMetaIcon: false,
                dateLabel: "",
                hasLoopBuilderDefaults: true
            });
        }
    }, [isInLoopBuilder]);

    // Use loop context values when in Loop Builder, otherwise use current post
    const currentPostId = select("core/editor")?.getCurrentPostId();
    const effectivePostType = isInLoopBuilder ? (loopPostType || 'post') : postType;
    const effectivePostId = isInLoopBuilder ? (loopPostId || 0) : currentPostId;



    // Fetch author data
    const [authorId] = useEntityProp(
        "postType",
        effectivePostType,
        "author",
        effectivePostId,
    );

    const [authorData] = useEntityProp(
        "root",
        "user",
        "name",
        authorId,
    );

    // Fetch author avatar URL
    const [authorAvatarUrls] = useEntityProp(
        "root",
        "user",
        "avatar_urls",
        authorId,
    );

    // Fetch post date
    const [postDate] = useEntityProp(
        "postType",
        effectivePostType,
        "date",
        effectivePostId,
    );



    useEffect(() => {

        if (postType === "templately_library") {
            let type = 'post';
            const templateType = select('core/editor').getEditedPostAttribute('templately_type');
            if (templateType) {
                if (['product_archive', 'product_single'].includes(templateType)) {
                    type = 'product'
                }
                if (['course_archive', 'course_single'].includes(templateType)) {
                    type = 'sfwd-courses'
                }
            }
            setAttributes({ type: type })
        } else if (postType === 'wp_template') {
            const slugArray = select('core/editor').getEditedPostAttribute('slug').split('-');
            let type = 'post';
            if (slugArray.length > 1) {
                type = slugArray[1];
            }
            if (slugArray.length === 1 && slugArray[0] === 'page') {
                type = 'page';
            }
            setAttributes({ type: type })
        } else {
            setAttributes({ type: selectPostType })
        }

        if (type !== null && type !== 'product') {
            let list = [...enableContents];
            const index = list.indexOf('product_sku');
            if (index !== -1) {
                list.splice(index, 1);
            }
            setAttributes({ enableContents: list })
        }

    }, [])

    // Effect to handle Loop Builder context initialization
    useEffect(() => {
        if (isInLoopBuilder && !attributes.hasLoopBuilderDefaults) {
            // Set Loop Builder defaults when first entering loop context
            setAttributes({
                showAuthor: false,
                showMetaIcon: false,
                authorLabel: "",
                dateLabel: "",
                showAuthorPicture: true, // Enable author picture by default in Loop Builder
                hasLoopBuilderDefaults: true,
            });
        }
    }, [isInLoopBuilder, attributes.hasLoopBuilderDefaults]);

    // you must declare this variable
    const enhancedProps = {
        ...props,
        blockPrefix: 'eb-post-meta',
        style: <Style {...props} isContentEnabled={isContentEnabled} />
    };



    // Format post date for display using WordPress date format
    const getFormattedPostDate = () => {
        if (postDate) {
            // Use WordPress date format settings
            const dateFormat = select("core").getEntityRecord("root", "site")?.date_format || "F j, Y";
            return dateI18n(dateFormat, postDate);
        }
        // Fallback to current date with WordPress format
        const dateFormat = select("core").getEntityRecord("root", "site")?.date_format || "F j, Y";
        return dateI18n(dateFormat, new Date());
    }

    // Get author name for display
    const getAuthorName = () => {
        if (authorData) {
            return authorData;
        }
        return __("Author", "essential-blocks");
    }

    // Get author avatar URL for display
    const getAuthorAvatarUrl = () => {
        if (authorAvatarUrls && authorAvatarUrls['96']) {
            return authorAvatarUrls['96'];
        }

        // Fallback to default avatar (same as PHP backend)
        return `https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp&f=y&s=96`;
    }

    // Get author URL for linking
    const getAuthorUrl = () => {
        if (authorId) {
            // In the editor, we'll use a placeholder URL
            return `#author-${authorId}`;
        }
        return '#';
    }

    // Check if author should be shown (handles loop builder initial state)
    const shouldShowAuthor = () => {
        if (isInLoopBuilder && !attributes.hasLoopBuilderDefaults) {
            // In loop builder but defaults not set yet - don't show author
            return false;
        }
        return showAuthor;
    }

    // Check if meta icons should be shown (handles loop builder initial state)
    const shouldShowMetaIcon = () => {
        if (isInLoopBuilder && !attributes.hasLoopBuilderDefaults) {
            // In loop builder but defaults not set yet - don't show icons
            return false;
        }
        return showMetaIcon;
    }

    // Get effective date label (handles loop builder initial state)
    const getEffectiveDateLabel = () => {
        if (isInLoopBuilder && !attributes.hasLoopBuilderDefaults) {
            // In loop builder but defaults not set yet - no label
            return "";
        }
        return dateLabel;
    }


    // Function to render individual meta items based on type
    const renderMetaItem = (contentType) => {
        switch (contentType) {
            case 'author':
                if (!isContentEnabled("author") || !shouldShowAuthor()) return null;

                if (metaDisplay === "stacked") {
                    // For stacked layout, return the author content part only
                    return (
                        <div key="author" className="eb-author-info">
                            {shouldShowMetaIcon() && authorIcon && (
                                <EBDisplayIcon icon={authorIcon} className={`eb-post-metadata-icon`} />
                            )}
                            <span className="eb-post-metadata-label">{authorLabel} </span>
                            <span className="eb-post-metadata-value">{getAuthorName()}</span>
                        </div>
                    );
                } else {
                    // For inline layout, return complete author item with picture
                    return (
                        <div key="author" className="eb-post-metadata-item eb-post-metadata-author eb-author-inline-layout">
                            {shouldShowMetaIcon() && authorIcon && (
                                <EBDisplayIcon icon={authorIcon} className={`eb-post-metadata-icon`} />
                            )}
                            {showAuthorPicture && (
                                <div className="eb-author-picture">
                                    {authorPictureLink ? (
                                        <a href={getAuthorUrl()}>
                                            <img
                                                src={getAuthorAvatarUrl()}
                                                alt={getAuthorName()}
                                                className="eb-author-avatar"
                                            />
                                        </a>
                                    ) : (
                                        <img
                                            src={getAuthorAvatarUrl()}
                                            alt={getAuthorName()}
                                            className="eb-author-avatar"
                                        />
                                    )}
                                </div>
                            )}
                            <span className="eb-post-metadata-label">{authorLabel} </span>
                            <span className="eb-post-metadata-value">{getAuthorName()}</span>
                        </div>
                    );
                }

            case 'date':
                if (!isContentEnabled("date")) return null;

                if (metaDisplay === "stacked") {
                    // For stacked layout, return the date content part only
                    return (
                        <div key="date" className="eb-date-info">
                            {shouldShowMetaIcon() && dateIcon && (
                                <EBDisplayIcon icon={dateIcon} className={`eb-post-metadata-icon`} />
                            )}
                            <span className="eb-post-metadata-label">{getEffectiveDateLabel()} </span>
                            <span className="eb-post-metadata-value">{getFormattedPostDate()}</span>
                        </div>
                    );
                } else {
                    // For inline layout, return complete date item
                    return (
                        <div key="date" className="eb-post-metadata-item eb-post-metadata-date">
                            {shouldShowMetaIcon() && dateIcon && (
                                <EBDisplayIcon icon={dateIcon} className={`eb-post-metadata-icon`} />
                            )}
                            <span className="eb-post-metadata-label">{getEffectiveDateLabel()} </span>
                            <span className="eb-post-metadata-value">{getFormattedPostDate()}</span>
                        </div>
                    );
                }

            case 'product_sku':
                if (!isContentEnabled("product_sku") || type !== 'product') return null;

                return (
                    <div key="product_sku" className="eb-post-metadata-item eb-post-metadata-product_sku">
                        {showMetaIcon == true && skuIcon && (
                            <EBDisplayIcon icon={skuIcon} className={`eb-post-metadata-icon`} />
                        )}
                        <span className="eb-post-metadata-label">{productSkuLabel} </span>
                        <span className="eb-post-metadata-value">{__("Product SKU", "essential-blocks")}</span>
                    </div>
                );

            default:
                return null;
        }
    };

    // Check if we have author and date for stacked layout
    const hasAuthorForStacked = isContentEnabled("author") && shouldShowAuthor();
    const hasDateForStacked = isContentEnabled("date");
    const shouldShowStackedLayout = metaDisplay === "stacked" && (hasAuthorForStacked || hasDateForStacked);

    return (
        <>
            {isSelected && <Inspector {...props} />}
            <BlockProps.Edit {...enhancedProps}>
                <div className={`eb-parent-wrapper eb-parent-${blockId} ${classHook}`}>
                    <div className={`eb-post-meta-wrapper ${blockId}`} data-id={blockId}>
                        <div className={`eb-post-metadata eb-post-meta-${metaDisplay}`}>
                            {shouldShowStackedLayout ? (
                                // Stacked layout: Picture on left, author name and date stacked on right
                                <div className="eb-post-metadata-item eb-post-metadata-author eb-author-stacked-layout">
                                    {hasAuthorForStacked && showAuthorPicture && (
                                        <div className="eb-author-picture">
                                            {authorPictureLink ? (
                                                <a href={getAuthorUrl()}>
                                                    <img
                                                        src={getAuthorAvatarUrl()}
                                                        alt={getAuthorName()}
                                                        className="eb-author-avatar"
                                                    />
                                                </a>
                                            ) : (
                                                <img
                                                    src={getAuthorAvatarUrl()}
                                                    alt={getAuthorName()}
                                                    className="eb-author-avatar"
                                                />
                                            )}
                                        </div>
                                    )}
                                    <div className="eb-author-meta-content">
                                        {enableContents.map(contentType => renderMetaItem(contentType)).filter(Boolean)}
                                    </div>
                                </div>
                            ) : (
                                // Inline layout: Render items in sorted order
                                enableContents.map(contentType => renderMetaItem(contentType)).filter(Boolean)
                            )}
                        </div>
                    </div>
                </div>
            </BlockProps.Edit>
        </>
    );
}

export default memo(
    compose([
        withSelect((select) => {
            const selectPostType = select("core/editor") ? select("core/editor").getCurrentPostType() : "";
            return {
                selectPostType: selectPostType,
            };
        }),
        withBlockContext(defaultAttributes)
    ])(Edit)
)