diff --git a/compile-sass.sh b/compile-sass.sh index 88be95d24..24fd5c724 100644 --- a/compile-sass.sh +++ b/compile-sass.sh @@ -40,7 +40,9 @@ sass -E 'UTF-8' --cache-location .tmp/sass-cache-15 src/views/gutenberg-blocks/t sass -E 'UTF-8' --cache-location .tmp/sass-cache-16 src/views/gutenberg-blocks/tainacan-items/item-submission-form/item-submission-form.scss:src/assets/css/tainacan-gutenberg-block-item-submission-form.css -sass -E 'UTF-8' --cache-location .tmp/sass-cache-17 src/views/gutenberg-blocks/gutenberg-blocks-style.scss:src/assets/css/tainacan-gutenberg-block-common-styles.css +sass -E 'UTF-8' --cache-location .tmp/sass-cache-17 src/views/gutenberg-blocks/tainacan-items/carousel-related-items/carousel-related-items.scss:src/assets/css/tainacan-gutenberg-block-carousel-related-items.css + +sass -E 'UTF-8' --cache-location .tmp/sass-cache-18 src/views/gutenberg-blocks/gutenberg-blocks-style.scss:src/assets/css/tainacan-gutenberg-block-common-styles.css echo "Compilação do Sass Concluído!" exit 0 diff --git a/src/assets/css/tainacan-gutenberg-block-carousel-collections-list.css b/src/assets/css/tainacan-gutenberg-block-carousel-collections-list.css index 2e79500dc..0f7a64ac2 100644 --- a/src/assets/css/tainacan-gutenberg-block-carousel-collections-list.css +++ b/src/assets/css/tainacan-gutenberg-block-carousel-collections-list.css @@ -122,7 +122,7 @@ color: var(--tainacan-block-gray5, #454647); font-weight: bold; text-decoration: none; - padding: 8px 16px; + padding: 8px 12px; display: block; line-height: 1.2em; word-break: break-word; } diff --git a/src/assets/css/tainacan-gutenberg-block-carousel-items-list.css b/src/assets/css/tainacan-gutenberg-block-carousel-items-list.css index de71369db..9f374daac 100644 --- a/src/assets/css/tainacan-gutenberg-block-carousel-items-list.css +++ b/src/assets/css/tainacan-gutenberg-block-carousel-items-list.css @@ -129,7 +129,7 @@ color: var(--tainacan-block-gray5, #454647); font-weight: bold; text-decoration: none; - padding: 8px 16px; + padding: 8px 12px; display: block; line-height: 1.2em; word-break: break-word; } diff --git a/src/assets/css/tainacan-gutenberg-block-carousel-related-items.css b/src/assets/css/tainacan-gutenberg-block-carousel-related-items.css new file mode 100644 index 000000000..ea7dfd802 --- /dev/null +++ b/src/assets/css/tainacan-gutenberg-block-carousel-related-items.css @@ -0,0 +1,51 @@ +.wp-block-tainacan-carousel-related-items { + margin: 0.5em auto; + width: 100%; } + .wp-block-tainacan-carousel-related-items .spinner-container { + min-height: 56px; + padding: 1em; + display: flex; + justify-content: center; + align-items: center; + color: var(--tainacan-block-gray4, #555758); } +@-webkit-keyframes skeleton-animation { + 0% { + opacity: 1.0; } + 50% { + opacity: 0.2; } + 100% { + opacity: 1.0; } } +@-moz-keyframes skeleton-animation { + 0% { + opacity: 1.0; } + 50% { + opacity: 0.2; } + 100% { + opacity: 1.0; } } +@-o-keyframes skeleton-animation { + 0% { + opacity: 1.0; } + 50% { + opacity: 0.2; } + 100% { + opacity: 1.0; } } +@keyframes skeleton-animation { + 0% { + opacity: 1.0; } + 50% { + opacity: 0.2; } + 100% { + opacity: 1.0; } } + .wp-block-tainacan-carousel-related-items .skeleton { + border-radius: 2px; + background: var(--tainacan-block-gray1, #f2f2f2); + -webkit-animation: skeleton-animation 1.8s ease infinite; + -moz-animation: skeleton-animation 1.8s ease infinite; + -o-animation: skeleton-animation 1.8s ease infinite; + animation: skeleton-animation 1.8s ease infinite; } + .wp-block-tainacan-carousel-related-items .carousel-related-items-edit-container { + position: relative; } + .wp-block-tainacan-carousel-related-items .carousel-related-items-edit-container .skeleton { + min-height: 150px; } + +/*# sourceMappingURL=tainacan-gutenberg-block-carousel-related-items.css.map */ diff --git a/src/assets/css/tainacan-gutenberg-block-carousel-related-items.css.map b/src/assets/css/tainacan-gutenberg-block-carousel-related-items.css.map new file mode 100644 index 000000000..a62d01597 --- /dev/null +++ b/src/assets/css/tainacan-gutenberg-block-carousel-related-items.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AAEA,yCAA0C;EACtC,MAAM,EAAE,UAAU;EAClB,KAAK,EAAE,IAAI;EAGX,4DAAmB;IACf,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,MAAM;IACvB,WAAW,EAAE,MAAM;IACnB,KAAK,EAAE,oCAAmC;AAI9C,qCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,kCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,gCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,6BAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;EAErB,mDAAU;IACN,aAAa,EAAE,GAAG;IAClB,UAAU,EAAE,oCAAmC;IAE/C,iBAAiB,EAAE,qCAAqC;IACxD,cAAc,EAAE,qCAAqC;IACrD,YAAY,EAAE,qCAAqC;IACnD,SAAS,EAAE,qCAAqC;EAIpD,gFAAuC;IACnC,QAAQ,EAAE,QAAQ;IAElB,0FAAY;MACR,UAAU,EAAE,KAAK", +"sources": ["../../views/gutenberg-blocks/tainacan-items/carousel-related-items/carousel-related-items.scss"], +"names": [], +"file": "tainacan-gutenberg-block-carousel-related-items.css" +} diff --git a/src/assets/css/tainacan-gutenberg-block-carousel-terms-list.css b/src/assets/css/tainacan-gutenberg-block-carousel-terms-list.css index 3d3b861ce..507137817 100644 --- a/src/assets/css/tainacan-gutenberg-block-carousel-terms-list.css +++ b/src/assets/css/tainacan-gutenberg-block-carousel-terms-list.css @@ -122,7 +122,7 @@ color: var(--tainacan-block-gray5, #454647); font-weight: bold; text-decoration: none; - padding: 8px 16px; + padding: 8px 12px; display: block; line-height: 1.2em; word-break: break-word; } diff --git a/src/classes/api/endpoints/class-tainacan-rest-items-controller.php b/src/classes/api/endpoints/class-tainacan-rest-items-controller.php index 5b7c7ba9c..e54f976f5 100644 --- a/src/classes/api/endpoints/class-tainacan-rest-items-controller.php +++ b/src/classes/api/endpoints/class-tainacan-rest-items-controller.php @@ -189,6 +189,24 @@ class REST_Items_Controller extends REST_Controller { return $item_array; } + /** + * @param \Tainacan\Entities\Item $item|int + * + * @return array + */ + public function get_context_edit($item) { + if(is_numeric($item)) + $item = new Entities\Item($item); + + return array( + 'current_user_can_edit' => $item->can_edit(), + 'current_user_can_delete' => $item->can_delete(), + 'nonces' => array( + 'update-post_' . $item->get_id() => wp_create_nonce('update-post_' . $item->get_id()) + ) + ); + } + /** * @param mixed $item * @param \WP_REST_Request $request @@ -256,6 +274,12 @@ class REST_Items_Controller extends REST_Controller { $attributes_to_filter .= ',id,collection_id'; } + if ( $request['context'] === 'edit' ) { + add_filter( 'taiancan_add_related_item', function( $related_item ) { + return array_merge($related_item, $this->get_context_edit($related_item['id'])); + }, 10, 2 ); + } + $item_arr = $this->filter_object_by_attributes($item, $attributes_to_filter); $item_arr = array_merge($extra_metadata_values, $item_arr); @@ -274,11 +298,7 @@ class REST_Items_Controller extends REST_Controller { } if ( $request['context'] === 'edit' ) { - $item_arr['current_user_can_edit'] = $item->can_edit(); - $item_arr['current_user_can_delete'] = $item->can_delete(); - $item_arr['nonces'] = array( - 'update-post_' . $item->get_id() => wp_create_nonce('update-post_' . $item->get_id()) - ); + $item_arr = array_merge($item_arr, $this->get_context_edit($item)); } if( isset($item_arr['thumbnail']) ) { $item_arr['thumbnail_alt'] = get_post_meta( $item->get__thumbnail_id(), '_wp_attachment_image_alt', true ); diff --git a/src/classes/entities/class-tainacan-item.php b/src/classes/entities/class-tainacan-item.php index a79253022..66f9743e7 100644 --- a/src/classes/entities/class-tainacan-item.php +++ b/src/classes/entities/class-tainacan-item.php @@ -816,4 +816,15 @@ class Item extends Entity { return $link; } + + /** + * Return related items withs the item + * + * @return array + */ + public function get_related_items($args = []) { + $Tainacan_Items = \Tainacan\Repositories\Items::get_instance(); + $related_items = $Tainacan_Items->fetch_related_items($this, $args); + return $related_items; + } } diff --git a/src/classes/importer/class-tainacan-test-importer.php b/src/classes/importer/class-tainacan-test-importer.php index effcbff1c..8494244c1 100644 --- a/src/classes/importer/class-tainacan-test-importer.php +++ b/src/classes/importer/class-tainacan-test-importer.php @@ -523,7 +523,6 @@ class Test_Importer extends Importer { 'type' => 'Tainacan\Metadata_Types\Relationship', 'options' => [ 'collection_id' => $col2->get_id(), - 'repeated' => 'yes', 'search' => $col2_core_title->get_id() ] ], $col1 ); diff --git a/src/classes/repositories/class-tainacan-items.php b/src/classes/repositories/class-tainacan-items.php index 776c627ce..cbee28804 100644 --- a/src/classes/repositories/class-tainacan-items.php +++ b/src/classes/repositories/class-tainacan-items.php @@ -116,7 +116,7 @@ class Items extends Repository { 'description' => __( 'Item comment status: "open" means comments are allowed, "closed" means comments are not allowed.', 'tainacan' ), 'default' => get_default_comment_status(Entities\Collection::get_post_type()), 'validation' => v::optional(v::stringType()->in( [ 'open', 'closed' ] )), - ] + ], ] ); } @@ -573,5 +573,95 @@ class Items extends Repository { return $caps; } + private function get_related_items_by_collection($item, $collection, $metadata, $args=[]) { + $Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance(); + if (!$collection instanceof \Tainacan\Entities\Collection || !$metadata instanceof \Tainacan\Entities\Metadatum || !$Tainacan_Metadata->metadata_is_enabled($collection, $metadata)) + return false; + + $prepared_items = array(); + $items = $this->fetch(array_merge([ + 'meta_query' => [ + [ + 'key' => $metadata->get_id(), + 'value' => $item->get_id() + ] + ] + ], $args), $collection->get_id(), 'WP_Query'); + + if ($items->have_posts()) { + while ( $items->have_posts() ) { + $items->the_post(); + $item_related = new \Tainacan\Entities\Item($items->post); + $item_arr = $item_related->_toArray(); + $item_arr['thumbnail'] = $item_related->get_thumbnail(); + array_push($prepared_items, apply_filters( 'taiancan_add_related_item', $item_arr ) ); + } + wp_reset_postdata(); + } + + return array( + "found_posts" => $items->found_posts, + 'items' => $prepared_items + ); + } + + public function fetch_related_items($item, $args=[]) { + $Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance(); + $Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance(); + $current_collection = $item->get_collection(); + $metadatas = $Tainacan_Metadata->fetch([ + 'meta_query' => [ + [ + 'key' => 'metadata_type', + 'value' => 'Tainacan\Metadata_Types\Relationship' + ], + [ + 'key' => '_option_collection_id', + 'value' => $current_collection->get_id() + ], + [ + 'key' => '_option_display_in_related_items', + 'value' => 'yes' + ] + ] + ], 'OBJECT'); + + $response = array(); + foreach($metadatas as $metadata) { + if($metadata->get_collection_id() == $Tainacan_Metadata->get_default_metadata_attribute()) { + $collections = $Tainacan_Collections->fetch([], 'OBJECT'); + foreach($collections as $collection) { + $related_items = $this->get_related_items_by_collection($item, $collection, $metadata, $args); + if($related_items == false) continue; + $response[$metadata->get_id() . '_' . $collection->get_id()] = array( + 'collection_id' => $collection->get_id(), + 'collection_name' => $collection->get_name(), + 'collection_url' => $collection->get_url(), + 'collection_slug' => $collection->get_slug(), + 'metadata_id' => $metadata->get_id(), + 'metadata_name' => $metadata->get_name(), + 'total_items' => $related_items['found_posts'], + 'items' => $related_items['items'] + ); + } + } else { + $collection = $metadata->get_collection(); + $related_items = $this->get_related_items_by_collection($item, $collection, $metadata, $args); + if($related_items == false) continue; + $response[$metadata->get_id()] = array( + 'collection_id' => $collection->get_id(), + 'collection_name' => $collection->get_name(), + 'collection_url' => $collection->get_url(), + 'collection_slug' => $collection->get_slug(), + 'metadata_id' => $metadata->get_id(), + 'metadata_name' => $metadata->get_name(), + 'total_items' => $related_items['found_posts'], + 'items' => $related_items['items'] + ); + } + } + + return $response; + } } diff --git a/src/classes/repositories/class-tainacan-metadata.php b/src/classes/repositories/class-tainacan-metadata.php index 26f78d289..52902fd92 100644 --- a/src/classes/repositories/class-tainacan-metadata.php +++ b/src/classes/repositories/class-tainacan-metadata.php @@ -87,7 +87,7 @@ class Metadata extends Repository { 'map' => 'post_content', 'title' => __( 'Description', 'tainacan' ), 'type' => 'string', - 'description' => __( 'The metadata description', 'tainacan' ), + 'description' => __( 'The metadatum description. This may provide information on how to fill this metadatum, which will appear inside a tooltip alongside the input label.', 'tainacan' ), 'default' => '', //'on_error' => __('The description should be a text value', 'tainacan'), //'validation' => v::stringType()->notEmpty(), @@ -134,7 +134,7 @@ class Metadata extends Repository { 'type' => ['string', 'number'], 'description' => __( 'Number of multiples possible metadata', 'tainacan' ), 'on_error' => __( 'This number of multiples metadata is not allowed', 'tainacan' ), - 'validation' => v::numeric()->positive(), + //'validation' => v::numeric()->positive(), 'default' => 1 ], 'mask' => [ @@ -1681,4 +1681,28 @@ class Metadata extends Repository { } + /** + * Test if a metadata is enabled on collection. + * + * @param \Tainacan\Entities\Collection $collection + * @param \Tainacan\Entities\Metadatum $metadata + * + * @return boolean + */ + public function metadata_is_enabled($collection, $metadata) { + $order = $collection->get_metadata_order(); + if($order == false) return true; + $order = ( is_array( $order ) ) ? $order : unserialize( $order ); + if( is_array($order) ) { + foreach ($order as $metadata_order) { + if( $metadata_order['id'] == $metadata->get_id() || $metadata_order['id'] == $metadata->get_parent() ) { + if($metadata_order['enabled'] == false) + return false; + return true; + } + } + } + return false; + } + } diff --git a/src/classes/theme-helper/class-tainacan-theme-helper.php b/src/classes/theme-helper/class-tainacan-theme-helper.php index e0e93efb5..b41c969e9 100644 --- a/src/classes/theme-helper/class-tainacan-theme-helper.php +++ b/src/classes/theme-helper/class-tainacan-theme-helper.php @@ -50,6 +50,8 @@ class Theme_Helper { add_shortcode( 'tainacan-search', array($this, 'search_shortcode')); add_shortcode( 'tainacan-item-submission', array($this, 'item_submission_shortcode')); + add_shortcode( 'tainacan-items-carousel', array($this, 'get_tainacan_items_carousel')); + add_shortcode( 'tainacan-related-items-carousel', array($this, 'get_tainacan_related_items_carousel')); add_action( 'generate_rewrite_rules', array( &$this, 'rewrite_rules' ), 10, 1 ); add_filter( 'query_vars', array( &$this, 'rewrite_rules_query_vars' ) ); @@ -122,6 +124,49 @@ class Theme_Helper { wp_localize_script('tainacan-search', 'tainacan_plugin', \Tainacan\Admin::get_instance()->get_admin_js_localization_params()); } } + + public function enqueue_items_carousel_scripts() { + global $post; + global $TAINACAN_BASE_URL; + global $TAINACAN_VERSION; + global $wp_version; + + $settings = [ + 'wp_version' => $wp_version, + 'root' => esc_url_raw( rest_url() ) . 'tainacan/v2', + 'nonce' => is_user_logged_in() ? wp_create_nonce( 'wp_rest' ) : false, + 'base_url' => $TAINACAN_BASE_URL, + 'admin_url' => admin_url(), + 'site_url' => site_url(), + 'theme_items_list_url' => esc_url_raw( get_site_url() ) . '/' . \Tainacan\Theme_Helper::get_instance()->get_items_list_slug() + ]; + + wp_enqueue_script( + 'carousel-items-list-theme', + $TAINACAN_BASE_URL . '/assets/js/block_carousel_items_list_theme.js', + array('wp-components') + ); + wp_enqueue_style( + 'carousel-items-list', + $TAINACAN_BASE_URL . '/assets/css/tainacan-gutenberg-block-' . 'carousel-items-list' . '.css', + array('tainacan-blocks-common-styles'), + $TAINACAN_VERSION + ); + wp_set_script_translations('carousel-items-list-theme', 'tainacan'); + wp_localize_script('carousel-items-list-theme', 'tainacan_blocks', $settings); + } + + public function enqueue_related_items_carousel_scripts() { + global $TAINACAN_BASE_URL; + global $TAINACAN_VERSION; + + wp_enqueue_style( + 'carousel-related-items', + $TAINACAN_BASE_URL . '/assets/css/tainacan-gutenberg-block-' . 'carousel-related-items' . '.css', + array('tainacan-blocks-common-styles'), + $TAINACAN_VERSION + ); + } public function is_post_an_item(\WP_Post $post) { $post_type = $post->post_type; @@ -428,7 +473,6 @@ class Theme_Helper { public function search_shortcode($args) { return $this->get_tainacan_items_list($args, true); } - public function get_tainacan_items_list($args, $force_enqueue = false) { $props = ' '; @@ -828,5 +872,175 @@ class Theme_Helper { return $adjacent_items; } + /** + * Returns the div used by Vue to render the Carousel of Related Items + * + * @param array $args { + * Optional. Array of arguments. + * @type string $collection_id The Collection ID + * @type string $search_URL A query string to fetch items from, if load strategy is 'search' + * @type array $selected_items An array of item IDs to fetch items from, if load strategy is 'selection' and an array of items, if the load strategy is 'parent' + * @type string $load_strategy Either 'search' or 'selection', to determine how items will be fetch + * @type integer $max_items_number Maximum number of items to be fetch + * @type integer $max_tems_per_screen Maximum columns of items to be displayed on a row of the carousel + * @type string $arrows_position How the arrows will be positioned regarding the carousel ('around', 'left', 'right') + * @type bool $large_arrows Should large arrows be displayed? + * @type bool $auto_play Should the Caroulsel start automatically to slide? + * @type integer $auto_play_speed The time in s to translate to the next slide automatically + * @type bool $loop_slides Should slides loop when reached the end of the Carousel? + * @type bool $hide_title Should the title of the items be displayed? + * @type bool $crop_images_to_square Should it use the `tainacan-medium-size` instead of the `tainacan-medium-large-size`? + * @type bool $show_collection_header Should it display a small version of the collection header? + * @type bool $show_collection_label Should it displar a 'Collection' label before the collection name on the collection header? + * @type string $collection_background_color Color of the collection header background + * @type string $collection_text_color Color of the collection header text + * @type string $tainacan_api_root Path of the Tainacan api root (to make the items request) + * @type string $tainacan_base_url Path of the Tainacan base URL (to make the links to the items) + * @type string $class_name Extra class to add to the wrapper, besides the default wp-block-tainacan-carousel-items-list + * @return string The HTML div to be used for rendering the items carousel vue component + */ + public function get_tainacan_items_carousel($args = []) { + if (!is_array($args)) + return __('There are missing parameters for Tainacan Items Carousel shortcode', 'tainacan'); + + $defaults = array( + 'max_items_number' => 12, + 'max_items_per_screen' => 7, + 'arrows_position' => 'around', + 'large_arrows' => false, + 'auto_play' => false, + 'auto_play_speed' => 3, + 'loop_slides' => false, + 'hide_title' => false, + 'crop_images_to_square' => true, + 'show_collection_header' => false, + 'show_collection_label' => false, + 'collection_background_color' => '#454647', + 'collection_text_color' => '#ffffff', + 'tainacan_api_root' => '', + 'tainacan_base_url' => '', + 'class_name' => '', + ); + $args = wp_parse_args($args, $defaults); + + $props = ' '; + + // Always pass the class needed by Vue to mount the component; + $args['class'] = $args['class_name'] . ' wp-block-tainacan-carousel-items-list'; + unset($args['class_name']); + + // Builds parameters to the html div rendered by Vue + foreach ($args as $key => $value) { + if (is_bool($value)) + $value = $value ? 'true' : 'false'; + // Changes from PHP '_' notation to HTML '-' notation + $props .= (str_replace('_', '-', $key) . "='" . $value . "' "); + } + + $this->enqueue_items_carousel_scripts(); + + return ""; + } + + /** + * Returns a group of related items carousels + * For each metatada, the collection name, the metadata name and a button linking + * the items list filtered is presented + * + * @param array $args { + * Optional. Array of arguments. + * @type string $item_id The Item ID + * @type string $class_name Extra class to add to the wrapper, besides the default wp-block-tainacan-carousel-related-items + * @type string $collection_heading_class_name Extra class to add to the collection name wrapper. Defaults to '' + * @type string $collection_heading_tag Tag to be used as wrapper of the collection name. Defaults to h2 + * @type string $metadata_label_class_name Extra class to add to the metadata label wrapper. Defaults to '' + * @type string $metadata_label_tag Tag to be used as wrapper of the metadata label. Defaults to p + * @type array $carousel_args Array of arguments to be passed to the get_tainacan_items_carousel function + * @return string The HTML div to be used for rendering the related items vue component + */ + public function get_tainacan_related_items_carousel($args = []) { + + $defaults = array( + 'class_name' => '', + 'collection_heading_class_name' => '', + 'collection_heading_tag' => 'h2', + 'metadata_label_class_name' => '', + 'metadata_label_tag' => 'p', + 'carousel_args' => [] + ); + $args = wp_parse_args($args, $defaults); + + // Gets the current Item + $item = isset($args['item_id']) ? $this->tainacan_get_item($args['item_id']) : $this->tainacan_get_item(); + if (!$item) + return; + + // Then fetches related ones + $related_items = $item->get_related_items(); + if (!count($related_items)) + return; + + // Enqueues necessary CSS + $this->enqueue_related_items_carousel_scripts(); + + // Always pass the default class; + $output = ''; + + return $output; + } } diff --git a/src/classes/theme-helper/template-tags.php b/src/classes/theme-helper/template-tags.php index f3a4bc4aa..42fdc285d 100644 --- a/src/classes/theme-helper/template-tags.php +++ b/src/classes/theme-helper/template-tags.php @@ -998,3 +998,70 @@ function tainacan_get_the_mime_type_icon($mime_type, $image_size = 'medium') { return $images_path . $icon_file . $image_size . '.png'; } + +/** + * Displays a carousel of items, the same of the gutenberg block + * + * @param array $args { + * Optional. Array of arguments. + * @type string $collection_id The Collection ID + * @type string $search_URL A query string to fetch items from, if load strategy is 'search' + * @type array $selected_items An array of item IDs to fetch items from, if load strategy is 'selection' and an array of items, if the load strategy is 'parent' + * @type string $load_strategy Either 'search' or 'selection', to determine how items will be fetch + * @type integer $max_items_number Maximum number of items to be fetch + * @type integer $max_tems_per_screen Maximum columns of items to be displayed on a row of the carousel + * @type string $arrows_position How the arrows will be positioned regarding the carousel ('around', 'left', 'right') + * @type bool $large_arrows Should large arrows be displayed? + * @type bool $auto_play Should the Caroulsel start automatically to slide? + * @type integer $auto_play_speed The time in s to translate to the next slide automatically + * @type bool $loop_slides Should slides loop when reached the end of the Carousel? + * @type bool $hide_title Should the title of the items be displayed? + * @type bool $crop_images_to_square Should it use the `tainacan-medium-size` instead of the `tainacan-medium-large-size`? + * @type bool $show_collection_header Should it display a small version of the collection header? + * @type bool $show_collection_label Should it displar a 'Collection' label before the collection name on the collection header? + * @type string $collection_background_color Color of the collection header background + * @type string $collection_text_color Color of the collection header text + * @type string $tainacan_api_root Path of the Tainacan api root (to make the items request) + * @type string $tainacan_base_url Path of the Tainacan base URL (to make the links to the items) + * @type string $class_name Extra class to add to the wrapper, besides the default wp-block-tainacan-carousel-items-list + * @return void The HTML div to be used for rendering the items carousel vue component +*/ +function tainacan_the_items_carousel($args = []) { + echo \Tainacan\Theme_Helper::get_instance()->get_tainacan_items_carousel($args); +} + +/** + * Displays a group of related items carousels + * For each metatada, the collection name, the metadata name and a button linking + * the items list filtered is presented + * + * @param array $args { + * Optional. Array of arguments. + * @type string $item_id The Item ID + * @return void + */ +function tainacan_the_related_items_carousel($args = []) { + echo \Tainacan\Theme_Helper::get_instance()->get_tainacan_related_items_carousel($args); +} + +/** + * Checks if the current item has or not related items + */ +function tainacan_has_related_items($item_id = false) { + // Gets the current Item + $item = $item_id ? \Tainacan\Theme_Helper::get_instance()->tainacan_get_item($item_id) : \Tainacan\Theme_Helper::get_instance()->tainacan_get_item(); + if (!$item) + return; + + // Then fetches related ones + $related_items = $item->get_related_items();// TODO: handle this inside the item so we don't have to load things here. + if ( !$related_items || !is_array($related_items) || !count($related_items) ) + return false; + + // If we have at least one total_items, there are related items + foreach($related_items as $related_group) { + if ( isset($related_group['total_items']) && (int)$related_group['total_items'] > 0 ) + return true; + } + return false; +} \ No newline at end of file diff --git a/src/views/admin/admin.vue b/src/views/admin/admin.vue index 0a504c205..1e82706af 100644 --- a/src/views/admin/admin.vue +++ b/src/views/admin/admin.vue @@ -3,39 +3,40 @@ id="tainacan-admin-app" class="columns is-fullheight" :class="{ - 'tainacan-admin-iframe-mode': $route.query.iframemode, - 'tainacan-admin-read-mode': $route.query.readmode + 'tainacan-admin-iframe-mode': isIframeMode, + 'tainacan-admin-read-mode': isReadMode }"> - - {{ collapseAll ? $i18n.get('label_collapse_all') : $i18n.get('label_expand_all') }} - - - - +
+ + {{ collapseAll ? $i18n.get('label_collapse_all') : $i18n.get('label_expand_all') }} + + + + + + + + +
+ @@ -520,6 +192,37 @@ + + + + + +
+

+ {{ $i18n.get("info_related_items") }} +

+
+ + + +
+ +