'; } public static function tag() { return 'div'; } public static function tagOptions() { return []; } public static function tagControlPath() { return false; } public static function name() { return 'Product Collection'; } public static function className() { return 'fcbd-product-collection-element'; } public static function category() { return 'fluentcart'; } public static function badge() { return ['label' => 'FC', 'backgroundColor' => '#3157d5', 'textColor' => '#fff']; } public static function slug() { return __CLASS__; } public static function template() { return file_get_contents(__DIR__ . '/html.twig'); } public static function defaultCss() { return file_get_contents(__DIR__ . '/default.css'); } public static function cssTemplate() { return file_get_contents(__DIR__ . '/css.twig'); } public static function defaultChildren() { return false; } public static function dependencies() { return false; } public static function settingsControls() { return []; } public static function settings() { return ['proOnly' => false]; } public static function availableIn() { return ['oxygen', 'breakdance']; } public static function propertyPathsToSsrElementWhenValueChanges() { return ['content.collection']; } public static function defaultProperties() { return ['content' => ['collection' => [ 'per_page' => 12, 'columns' => 3, 'view_mode' => 'grid', 'sort_by' => 'date-newest', 'paginator' => 'scroll', 'category_id' => '', 'fulfillment_type' => '', 'on_sale' => false, 'with_cart' => false, 'show_category_filter' => false, ]]]; } /** * Category dropdown items are built from the live FluentCart taxonomy * (get_terms) so editors pick a category by name instead of typing a raw * term ID. Guarded by taxonomy_exists('product-categories'): if FluentCart * is inactive or the taxonomy is not yet registered when this runs, the * control falls back to the previous plain text field so the panel never * breaks. The stored value stays a term-id string either way, so * FluentCartAdapter::renderCollection()'s shortcode-building is unchanged. */ private static function categoryControl() { $canQueryTerms = function_exists('taxonomy_exists') && function_exists('get_terms') && taxonomy_exists('product-categories'); if (!$canQueryTerms) { return c('category_id', __('Category term ID', 'sparkcore-commerce'), [], ['type' => 'text', 'layout' => 'inline'], false, false, []); } $items = [['value' => '', 'text' => __('All categories', 'sparkcore-commerce')]]; $terms = get_terms(['taxonomy' => 'product-categories', 'hide_empty' => false]); if (is_array($terms)) { foreach ($terms as $term) { if (isset($term->term_id) && isset($term->name)) { $items[] = ['value' => (string) $term->term_id, 'text' => (string) $term->name]; } } } return c('category_id', __('Category', 'sparkcore-commerce'), [], ['type' => 'dropdown', 'layout' => 'inline', 'items' => $items], false, false, []); } public static function contentControls() { return [c('collection', __('Products', 'sparkcore-commerce'), [ c('per_page', __('Products per page', 'sparkcore-commerce'), [], ['type' => 'number', 'layout' => 'inline'], false, false, []), c('columns', __('Columns', 'sparkcore-commerce'), [], ['type' => 'dropdown', 'layout' => 'inline', 'items' => [ ['value' => 1, 'text' => '1'], ['value' => 2, 'text' => '2'], ['value' => 3, 'text' => '3'], ['value' => 4, 'text' => '4'], ['value' => 5, 'text' => '5'], ['value' => 6, 'text' => '6'], ]], false, false, []), c('view_mode', __('View', 'sparkcore-commerce'), [], ['type' => 'dropdown', 'layout' => 'inline', 'items' => [ ['value' => 'grid', 'text' => __('Grid', 'sparkcore-commerce')], ['value' => 'list', 'text' => __('List', 'sparkcore-commerce')], ]], false, false, []), c('sort_by', __('Sort', 'sparkcore-commerce'), [], ['type' => 'dropdown', 'layout' => 'inline', 'items' => [ ['value' => 'date-newest', 'text' => __('Newest', 'sparkcore-commerce')], ['value' => 'date-oldest', 'text' => __('Oldest', 'sparkcore-commerce')], ['value' => 'name-asc', 'text' => __('Name A to Z', 'sparkcore-commerce')], ['value' => 'name-desc', 'text' => __('Name Z to A', 'sparkcore-commerce')], ['value' => 'price-low', 'text' => __('Price low to high', 'sparkcore-commerce')], ['value' => 'price-high', 'text' => __('Price high to low', 'sparkcore-commerce')], ]], false, false, []), c('paginator', __('Pagination', 'sparkcore-commerce'), [], ['type' => 'dropdown', 'layout' => 'inline', 'items' => [ ['value' => 'scroll', 'text' => __('Load more / scroll', 'sparkcore-commerce')], ['value' => 'numbers', 'text' => __('Numbers', 'sparkcore-commerce')], ]], false, false, []), self::categoryControl(), c('fulfillment_type', __('Fulfillment', 'sparkcore-commerce'), [], ['type' => 'dropdown', 'layout' => 'inline', 'items' => [ ['value' => '', 'text' => __('All', 'sparkcore-commerce')], ['value' => 'physical', 'text' => __('Physical', 'sparkcore-commerce')], ['value' => 'digital', 'text' => __('Digital', 'sparkcore-commerce')], ]], false, false, []), c('on_sale', __('Only on sale', 'sparkcore-commerce'), [], ['type' => 'toggle', 'layout' => 'inline'], false, false, []), c('with_cart', __('Show cart control', 'sparkcore-commerce'), [], ['type' => 'toggle', 'layout' => 'inline'], false, false, []), c('show_category_filter', __('Show category filter', 'sparkcore-commerce'), [], ['type' => 'toggle', 'layout' => 'inline'], false, false, []), ], ['type' => 'section', 'layout' => 'vertical'], false, false, [])]; } public static function designControls() { return [controlSection('layout', __('Layout', 'sparkcore-commerce'), [ control('max_width', __('Maximum width', 'sparkcore-commerce'), ['type' => 'unit', 'layout' => 'inline'], true), ])]; } }