/** * Dynamic functions class */ // If this file is called directly, abort.x if ( ! defined( 'WPINC' ) ) { die; } if ( ! class_exists( 'Jet_Engine_Dynamic_Functions' ) ) { class Jet_Engine_Dynamic_Functions { private $functions_list = array(); private $cache_group = 'jet_engine_dynamic_functions'; public function __construct() { $number_format_settings = array( 'decimal_point' => array( 'label' => __( 'Decimals Point', 'jet-engine' ), 'type' => 'text', 'default' => '.', ), 'thousands_separator' => array( 'label' => __( 'Thousands separator', 'jet-engine' ), 'type' => 'text', 'default' => ',', ), 'decimal_count' => array( 'label' => __( 'Decimals Count', 'jet-engine' ), 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 5, ), ); $this->functions_list = apply_filters( 'jet-engine/dynamic-functions/functions-list', array( 'sum' => array( 'label' => __( 'Summed value', 'jet-engine' ), 'type' => 'sql', // sql or raw 'query' => 'SUM( CAST( meta_value AS DECIMAL( 10, %decimal_count% ) ) )', 'cb' => array( $this, 'number_format' ), 'custom_settings' => $number_format_settings, ), 'avg' => array( 'label' => __( 'Average value', 'jet-engine' ), 'type' => 'sql', 'query' => 'ROUND( AVG( CAST( meta_value AS DECIMAL( 10, %decimal_count% ) ) ), %decimal_count% )', 'cb' => array( $this, 'number_format' ), 'custom_settings' => $number_format_settings, ), 'count' => array( 'label' => __( 'Count', 'jet-engine' ), 'type' => 'sql', 'query' => 'COUNT(meta_value)', 'cb' => false, ), 'max' => array( 'label' => __( 'Maximum value', 'jet-engine' ), 'type' => 'sql', 'query' => 'MAX( CAST( meta_value AS DECIMAL( 10, %decimal_count% ) ) )', 'cb' => array( $this, 'number_format' ), 'custom_settings' => $number_format_settings, ), 'min' => array( 'label' => __( 'Minimum value', 'jet-engine' ), 'type' => 'sql', 'query' => 'MIN( CAST( meta_value AS DECIMAL( 10, %decimal_count% ) ) )', 'cb' => array( $this, 'number_format' ), 'custom_settings' => $number_format_settings, ), 'query_var' => array( 'label' => __( 'SQL query results', 'jet-engine' ), 'type' => 'query_var', 'query' => false, 'cb' => array( $this, 'number_format' ), 'custom_settings' => $number_format_settings, 'custom_settings_cb' => array( $this, 'get_query_settings' ), ), ) ); add_filter( 'jet-engine/blocks-views/dynamic-content/data-sources', array( $this, 'register_blocks_dynamic_source' ) ); add_filter( 'jet-engine/blocks-views/editor-data', array( $this, 'register_blocks_controls' ) ); add_filter( 'jet-engine/blocks-views/dynamic-content/get-dynamic-value/dynamic_function', array( $this, 'get_block_dynamic_value' ), 10, 2 ); } /** * Register Dynamic function source for blocks dynamic data. * * @param [type] $sources [description] * @return [type] [description] */ public function register_blocks_dynamic_source( $sources ) { $sources[] = array( 'value' => 'dynamic_function', 'label' => __( 'Dynamic function', 'jet-engine' ), ); return $sources; } /** * Get block dyanmic value * * @param [type] $result [description] * @param [type] $data [description] * @return [type] [description] */ public function get_block_dynamic_value( $result, $data ) { $prepared_data = array(); $prefix = 'dynamic_functions_'; foreach ( $data as $key => $value ) { if ( false !== strpos( $key, $prefix ) ) { $prepared_data[ str_replace( $prefix, '', $key ) ] = $value; } } $function_name = \Jet_Engine_Tools::safe_get( 'function_name', $prepared_data ); $source = \Jet_Engine_Tools::safe_get( 'data_source', $prepared_data ); $field_name = \Jet_Engine_Tools::safe_get( 'field_name', $prepared_data ); if ( ! $source ) { $source = 'post_meta'; } $data_source = array( 'source' => $source ); if ( empty( $function_name ) ) { return; } if ( 'post_meta' === $source ) { $data_source['context'] = \Jet_Engine_Tools::safe_get( 'data_context', $prepared_data , 'all_posts' ); $data_source['context_tax'] = \Jet_Engine_Tools::safe_get( 'data_context_tax', $prepared_data ); $data_source['context_tax_term'] = \Jet_Engine_Tools::safe_get( 'data_context_tax_term', $prepared_data ); $data_source['context_user_id'] = \Jet_Engine_Tools::safe_get( 'data_context_user_id', $prepared_data ); $data_source['context_relation'] = \Jet_Engine_Tools::safe_get( 'data_context_relation', $prepared_data ); $data_source['post_status'] = \Jet_Engine_Tools::safe_get( 'data_post_status', $prepared_data ); $data_source['post_types'] = \Jet_Engine_Tools::safe_get( 'data_post_types', $prepared_data ); } $custom_settings = $this->get_custom_settings( $function_name, null, $prepared_data ); $result = $this->call_function( $function_name, $data_source, $field_name, $custom_settings ); return $result; } /** * Register denamic functions related controls for the blocks editor * * @param [type] $editor_config [description] * @return [type] [description] */ public function register_blocks_controls( $editor_config ) { $editor_config['dynamicFunctionsControls'] = $this->get_editor_controls( 'blocks' ); return $editor_config; } /** * Returns functions list for options */ public function functions_list() { $result = array(); foreach ( $this->functions_list as $func_key => $func_data ) { $result[ $func_key ] = ! empty( $func_data['label'] ) ? $func_data['label'] : $func_key; } return $result; } public function get_query_settings() { $queries = \Jet_Engine\Query_Builder\Manager::instance()->get_queries(); $options = array(); $sql_queries = array(); if ( ! empty( $queries ) ) { foreach( $queries as $query ) { if ( ! $query || ! is_object( $query ) ) { continue; } if ( 'sql' === $query->query_type ) { $sql_queries[] = $query; } } } if ( empty( $sql_queries ) ) { $options['no_query_notice'] = array( 'type' => 'raw_html', 'raw' => sprintf( esc_html__( 'With this function you can output any data from custom SQL query. To start, please %s', 'jet-elements' ), '' . esc_html__( 'create your query', 'jet-elements' ) . '' ) ); } $columns = array(); foreach ( $sql_queries as $query ) { $fields = $query->get_instance_fields(); $prepared_fields = array(); foreach ( $fields as $field ) { $prepared_fields[ $query->get_instance_id() . '::' . $field ] = $field; } $columns[] = array( 'label' => $query->get_instance_name(), 'options' => $prepared_fields, ); } $options['_query_field'] = array( 'label' => __( 'Query Column', 'jet-engine' ), 'description' => __( 'Select column from the query to show', 'jet-engine' ), 'type' => 'select', 'groups' => $columns, ); $options['_additional_function'] = array( 'label' => __( 'Additional Function', 'jet-engine' ), 'description' => __( 'Apply additional function to SQL query', 'jet-engine' ), 'type' => 'select', 'options' => array( '' => __( 'Select...', 'jet-engine' ), 'SUM' => __( 'Sum', 'jet-engine' ), 'AVG' => __( 'Average', 'jet-engine' ), 'COUNT' => __( 'Count', 'jet-engine' ), 'MIN' => __( 'Minimum', 'jet-engine' ), 'MAX' => __( 'Maximum', 'jet-engine' ), ), ); return $options; } public function get_relations_for_options() { $result = array( '' => __( 'Select...', 'jet-engine' ), ); $relations = jet_engine()->relations->get_relations_for_js(); if ( ! empty( $relations ) ) { foreach ( $relations as $relations ) { $result[ $relations['value'] ] = $relations['label']; } } return $result; } /** * Returns all taxonomies list for options * * @return [type] [description] */ public function get_taxonomies_for_options() { $result = array(); $taxonomies = get_taxonomies( array( 'public' => true ), 'objects' ); foreach ( $taxonomies as $taxonomy ) { if ( empty( $taxonomy->object_type ) || ! is_array( $taxonomy->object_type ) ) { continue; } foreach ( $taxonomy->object_type as $object ) { if ( empty( $result[ $object ] ) ) { $post_type = get_post_type_object( $object ); if ( ! $post_type ) { continue; } $result[ $object ] = array( 'label' => $post_type->labels->name, 'options' => array(), ); } $result[ $object ]['options'][ $taxonomy->name ] = $taxonomy->labels->name; }; } return $result; } /** * Returns editor controls for Elementor or Blocks editor * * @param string $for [description] * @return [type] [description] */ public function get_editor_controls( $for = 'elementor' ) { $controls = array(); $functions_list = array_reverse( $this->functions_list ); $controls['function_name'] = array( 'label' => __( 'Function', 'jet-engine' ), 'type' => 'select', 'add_placeholder' => __( 'Select...', 'jet-engine' ), 'options' => $this->functions_list(), ); $controls['data_source'] = array( 'label' => __( 'Data Source', 'jet-engine' ), 'type' => 'select', 'add_placeholder' => __( 'Select...', 'jet-engine' ), 'options' => array( 'post_meta' => __( 'Post Meta', 'jet-engine' ), 'term_meta' => __( 'Term Meta', 'jet-engine' ), 'user_meta' => __( 'User Meta', 'jet-engine' ), ), 'description' => __( 'Please note: if you used Custom Meta Storage feature for meta data you want to get with Dynamic Functions, you need to use SQL Query Results function type', 'jet-engine' ), 'condition' => array( 'function_name!' => 'query_var', ), ); $controls['field_name'] = array( 'label' => __( 'Field Name', 'jet-engine' ), 'type' => 'text', 'label_block' => true, 'condition' => array( 'function_name!' => 'query_var', ), ); $controls['data_context'] = array( 'label' => __( 'Data Context', 'jet-engine' ), 'type' => 'select', 'default' => 'all_posts', 'add_placeholder' => __( 'Select...', 'jet-engine' ), 'options' => array( 'all_posts' => __( 'All posts', 'jet-engine' ), 'current_term' => __( 'Posts from current term', 'jet-engine' ), 'current_user' => __( 'Posts by current user', 'jet-engine' ), 'queried_user' => __( 'Posts by queried user', 'jet-engine' ), 'related_posts' => __( 'Related posts for current post', 'jet-engine' ), ), 'condition' => array( 'data_source' => 'post_meta', 'function_name!' => 'query_var', ), ); $controls['data_context_relation'] = array( 'label' => __( 'Relation', 'jet-engine' ), 'type' => 'select', 'options' => $this->get_relations_for_options(), 'condition' => array( 'data_source' => 'post_meta', 'data_context' => 'related_posts', 'function_name!' => 'query_var', ), ); $controls['data_context_relation_object'] = array( 'label' => __( 'From Object (what to show)', 'jet-engine' ), 'type' => 'select', 'options' => array( 'parent_object' => __( 'Parent Object', 'jet-engine' ), 'child_object' => __( 'Child Object', 'jet-engine' ), ), 'default' => 'child_object', 'condition' => array( 'data_source' => 'post_meta', 'data_context' => 'related_posts', 'function_name!' => 'query_var', ), ); $controls['data_context_tax'] = array( 'label' => __( 'Taxonomy', 'jet-engine' ), 'type' => 'select', 'groups' => $this->get_taxonomies_for_options(), 'add_placeholder' => __( 'Select...', 'jet-engine' ), 'condition' => array( 'data_source' => 'post_meta', 'data_context' => 'current_term', 'function_name!' => 'query_var', ), ); $controls['data_context_tax_term'] = array( 'label' => __( 'Set term ID/slug', 'jet-engine' ), 'type' => 'text', 'label_block' => true, 'description' => __( 'Leave empty to get term dynamically. Use prefix slug:: to set term by slug instead of ID, for example - slug::term-slug', 'jet-engine' ), 'has_html' => true, 'condition' => array( 'data_source' => 'post_meta', 'data_context' => 'current_term', 'function_name!' => 'query_var', ), ); $controls['data_context_user_id'] = array( 'label' => __( 'Set user ID/login/email', 'jet-engine' ), 'type' => 'text', 'label_block' => true, 'description' => __( 'Leave empty to get user ID dynamically. Use prefixes login:: or email:: to set user by login or email instead of ID, for example - email::admin@demolink.org', 'jet-engine' ), 'has_html' => true, 'condition' => array( 'data_source' => 'post_meta', 'data_context' => 'queried_user', 'function_name!' => 'query_var', ), ); $controls['data_post_status'] = array( 'label' => __( 'Query by posts with status', 'jet-engine' ), 'description' => __( 'Leave empy to search anywhere', 'jet-engine' ), 'type' => 'select2', 'default' => '', 'label_block' => true, 'multiple' => true, 'add_placeholder' => __( 'Select...', 'jet-engine' ), 'options' => array( 'publish' => __( 'Publish', 'jet-engine' ), 'pending' => __( 'Pending', 'jet-engine' ), 'draft' => __( 'Draft', 'jet-engine' ), 'auto-draft' => __( 'Auto draft', 'jet-engine' ), 'future' => __( 'Future', 'jet-engine' ), 'private' => __( 'Private', 'jet-engine' ), 'trash' => __( 'Trash', 'jet-engine' ), 'any' => __( 'Any', 'jet-engine' ), ), 'condition' => array( 'data_source' => 'post_meta', 'function_name!' => 'query_var', ), ); $controls['data_post_types'] = array( 'label' => esc_html__( 'Query by posts with types', 'jet-engine' ), 'description' => __( 'Leave empy to search anywhere', 'jet-engine' ), 'type' => 'select2', 'label_block' => true, 'add_placeholder' => __( 'Select...', 'jet-engine' ), 'multiple' => true, 'options' => jet_engine()->listings->get_post_types_for_options(), 'condition' => array( 'data_source' => 'post_meta', 'function_name!' => 'query_var', ), ); foreach ( $functions_list as $func_name => $data ) { $custom_settings = array(); if ( ! empty( $data['custom_settings_cb'] ) && is_callable( $data['custom_settings_cb'] ) ) { $custom_settings = array_merge( $custom_settings, call_user_func( $data['custom_settings_cb'] ) ); } if ( ! empty( $data['custom_settings'] ) ) { $custom_settings = array_merge( $custom_settings, $data['custom_settings'] ); } if ( ! empty( $custom_settings ) ) { foreach ( $custom_settings as $setting_key => $setting_data ) { if ( empty( $controls[ $setting_key ] ) ) { $setting_data['condition'] = array( 'function_name' => array( $func_name ), ); $controls[ $setting_key ] = $setting_data; } else { $controls[ $setting_key ]['condition']['function_name'][] = $func_name; } } } } if ( 'blocks' === $for ) { $controls = \Jet_Engine_Tools::prepare_controls_for_js( $controls ); } return $controls; } /** * Allow to register custom settings to each function */ public function register_custom_settings( $tag ) { $controls = $this->get_editor_controls(); if ( ! empty( $controls ) ) { foreach ( $controls as $control_key => $control_data ) { $tag->add_control( $control_key, $control_data ); } } } /** * Allow to get custom settings to each function */ public function get_custom_settings( $function, $tag, $all_settings = array() ) { $settings = array(); $custom_settings = array(); $data = ! empty( $this->functions_list[ $function ] ) ? $this->functions_list[ $function ] : array(); if ( ! empty( $data['custom_settings_cb'] ) && is_callable( $data['custom_settings_cb'] ) ) { $custom_settings = array_merge( $custom_settings, call_user_func( $data['custom_settings_cb'] ) ); } if ( ! empty( $data['custom_settings'] ) ) { $custom_settings = array_merge( $custom_settings, $data['custom_settings'] ); } if ( empty( $this->functions_list[ $function ] ) || empty( $custom_settings ) ) { return $settings; } $required_sql_settings = array( 'decimal_count' ); foreach ( $custom_settings as $setting_key => $setting_data ) { if ( $tag ) { $settings[ $setting_key ] = $tag->get_settings( $setting_key ); } else { $settings[ $setting_key ] = isset( $all_settings[ $setting_key ] ) ? $all_settings[ $setting_key ] : false; } // Added to prevent SQL error if required sql setting is empty. if ( in_array( $setting_key, $required_sql_settings ) && Jet_Engine_Tools::is_empty( $settings[ $setting_key ] ) && isset( $setting_data['default'] ) ) { $settings[ $setting_key ] = $setting_data['default']; } } return $settings; } /** * Call function by function name and arguments */ public function call_function( $function_name = null, $data_source = array(), $field_name = null, $custom_settings = array() ) { if ( empty( $this->functions_list[ $function_name ] ) ) { return null; } $func_data = $this->functions_list[ $function_name ]; $func_data['function'] = $function_name; $func_data['data_source'] = $data_source; $func_data['field_name'] = $field_name; $func_data['custom_settings'] = $custom_settings; if ( ! empty( $func_data['type'] ) ) { switch ( $func_data['type'] ) { case 'sql': return $this->call_sql_function( $func_data ); case 'query_var': return $this->get_query_var( $func_data ); default: return $this->call_raw_function( $func_data ); } } } public function get_query_var( $func_data ) { if ( empty( $func_data['custom_settings'] ) || empty( $func_data['custom_settings']['_query_field'] ) ) { return; } $query_data = explode( '::', $func_data['custom_settings']['_query_field'] ); $query_id = str_replace( '_query_', '', $query_data[0] ); $column = $query_data[1]; $query = \Jet_Engine\Query_Builder\Manager::instance()->get_query_by_id( $query_id ); if ( ! $query || 'sql' !== $query->query_type ) { return; } $func = ! empty( $func_data['custom_settings']['_additional_function'] ) ? $func_data['custom_settings']['_additional_function'] : false; $decimal_count = isset( $func_data['custom_settings']['decimal_count'] ) ? $func_data['custom_settings']['decimal_count'] : 0; $callback = ! empty( $func_data['cb'] ) ? $func_data['cb'] : false; $result = $query->get_var( $column, $func, $decimal_count ); if ( $callback && is_callable( $callback ) ) { return call_user_func( $callback, array( 'result' => $result, 'custom_settings' => $func_data['custom_settings'] ) ); } else { return $result; } } /** * Call plain PHP function */ public function call_raw_function( $func_data ) { $function = ! empty( $func_data['cb'] ) ? $func_data['cb'] : false; if ( ! $function || ! is_callable( $function ) ) { return null; } unset( $func_data['cb'] ); return call_user_func( $function, $func_data ); } /** * Call sql-query function */ public function call_sql_function( $data ) { $query = ! empty( $data['query'] ) ? $data['query'] : false; $where = ! empty( $data['where'] ) ? $data['where'] : false; $data_source = ! empty( $data['data_source'] ) ? $data['data_source'] : false; $field_name = ! empty( $data['field_name'] ) ? $data['field_name'] : false; if ( ! $field_name || ! $query ) { return null; } $table = false; global $wpdb; $source = ! empty( $data_source['source'] ) ? $data_source['source'] : 'post_meta'; switch ( $source ) { case 'post_meta': $table = $wpdb->postmeta; break; case 'term_meta': $table = $wpdb->termmeta; break; case 'user_meta': $table = $wpdb->usermeta; break; default: $table = apply_filters( 'jet-engine/dynamic-functions/custom-sql-table', $table, $data ); break; } if ( ! $table ) { return null; } if ( ! $where ) { $where = $wpdb->prepare( "WHERE $table.meta_key ='%s'", $field_name ); } if ( ! empty( $data['custom_settings'] ) ) { foreach ( $data['custom_settings'] as $key => $value ) { $query = str_replace( '%' . $key . '%', $value, $query ); $where = str_replace( '%' . $key . '%', $value, $where ); } } $posts_table = $wpdb->posts; $posts_query_join = " INNER JOIN $posts_table ON $table.post_id = $posts_table.ID "; $posts_join = ""; $posts_where = ""; if ( ! empty( $data_source['post_status'] ) ) { $posts_join = $posts_query_join; $posts_where .= " AND $posts_table.post_status"; $post_status = is_array( $data_source['post_status'] ) ? $data_source['post_status'] : array( $data_source['post_status'] ); if ( 1 === count( $post_status ) ) { $status = $post_status[0]; $posts_where .= " = '$status'"; } else { $statuses = array(); foreach ( $post_status as $status ) { $statuses[] = sprintf( "'%s'", $status ); } $statuses = implode( ', ', $statuses ); $posts_where .= " IN ($statuses)"; } } if ( ! empty( $data_source['post_types'] ) ) { if ( ! $posts_join ) { $posts_join = $posts_query_join; } $posts_where .= " AND $posts_table.post_type"; $post_types = is_array( $data_source['post_types'] ) ? $data_source['post_types'] : array( $data_source['post_types'] ); if ( 1 === count( $post_types ) ) { $type = $post_types[0]; $posts_where .= " = '$type'"; } else { $types = array(); foreach ( $post_types as $type ) { $types[] = sprintf( "'%s'", $type ); } $types = implode( ', ', $types ); $posts_where .= " IN ($types)"; } } $final_query = "SELECT $query FROM $table $posts_join $where $posts_where;"; if ( 'post_meta' === $source ) { switch ( $data_source['context'] ) { case 'current_term': $term_id = $this->get_current_term_id( $data_source ); if ( $term_id ) { $term_relationships = $wpdb->term_relationships; $final_query = "SELECT $query FROM $table $posts_join INNER JOIN $term_relationships ON $table.post_id = $term_relationships.object_id $where AND $term_relationships.term_taxonomy_id = $term_id $posts_where"; } break; case 'related_posts': $relation = ! empty( $data_source['context_relation'] ) ? $data_source['context_relation'] : false; $post = get_post(); $posts = false; if ( $relation && $post ) { $post_type = $post->post_type; $relation_data = jet_engine()->relations->legacy->get_relation_info( $relation ); if ( $relation_data ) { $from = ( $post_type === $relation_data['post_type_1'] ) ? $relation_data['post_type_2'] : $relation_data['post_type_1']; $posts = jet_engine()->relations->legacy->get_related_posts( array( 'post_type_1' => $relation_data['post_type_1'], 'post_type_2' => $relation_data['post_type_2'], 'hash' => $relation, 'from' => $from, ) ); } else { $from = ! empty( $data_source['data_context_relation_object'] ) ? $data_source['data_context_relation_object'] : 'child_object'; $object_id = jet_engine()->listings->data->get_current_object_id(); $relation_instance = jet_engine()->relations->get_active_relations( $relation ); if ( ! $relation_instance ) { return null; } switch ( $from ) { case 'parent_object': $posts = $relation_instance->get_parents( $object_id, 'ids' ); break; default: $posts = $relation_instance->get_children( $object_id, 'ids' ); break; } } if ( ! empty( $posts ) ) { $posts = implode( ', ', $posts ); } else { // If related posts not found - return null to avoid incorrect calculations return null; } $final_query = str_replace( ";", " AND $table.post_id IN ( $posts );", $final_query ); } break; case 'current_user': $user_id = get_current_user_id(); if ( $user_id ) { $posts = $wpdb->posts; $final_query = "SELECT $query FROM $table INNER JOIN $posts ON $table.post_id = $posts.ID $where AND $posts.post_author = $user_id $posts_where"; } break; case 'queried_user': $user_id = false; if ( ! empty( $data_source['context_user_id'] ) ) { $user = $data_source['context_user_id']; if ( false === strpos( $user, '::' ) ) { $user_id = absint( $user ); } else { $user_data = explode( '::', $user ); if ( ! empty( $user_data[0] ) && ! empty( $user_data[1] ) ) { $user_obj = get_user_by( $user_data[0], $user_data[1] ); } if ( $user_obj ) { $user_id = $user_obj->ID; } } } else { if ( is_author() ) { $user_id = get_queried_object_id(); } elseif ( jet_engine()->modules->is_module_active( 'profile-builder' ) ) { $user_id = \Jet_Engine\Modules\Profile_Builder\Module::instance()->query->get_queried_user_id(); } } if ( ! $user_id ) { $user_id = get_current_user_id(); } if ( $user_id ) { $posts = $wpdb->posts; $final_query = "SELECT $query FROM $table INNER JOIN $posts ON $table.post_id = $posts.ID $where AND $posts.post_author = $user_id $posts_where"; } break; } } $final_query = apply_filters( 'jet-engine/dynamic-functions/final-query', $final_query, $data, $this ); $hash = md5( $final_query ); $result = wp_cache_get( $hash, $this->cache_group ); if ( ! $result ) { $result = $wpdb->get_var( $final_query ); if ( ! empty( $data['cb'] ) ) { $data['result'] = $result; $cb_result = $this->call_raw_function( $data ); $result = ( null !== $cb_result ) ? $cb_result : $result; } wp_cache_set( $hash, $result, $this->cache_group ); } return $result; } /** * Get term ID for current context and settings */ public function get_current_term_id( $data_source ) { if ( ! empty( $data_source['context_tax_term'] ) ) { $term = $data_source['context_tax_term']; $term_id = false; if ( false === strpos( $term, 'slug::' ) ) { $term_id = absint( $term ); } elseif ( ! empty( $data_source['context_tax'] ) ) { $term = str_replace( 'slug::', '', $term ); $term_obj = get_term_by( 'slug', $term, $data_source['context_tax'] ); if ( $term_obj ) { $term_id = $term_obj->term_id; } } if ( $term_id ) { return $term_id; } } $listing_object = jet_engine()->listings->data->get_current_object(); $term_id = false; if ( $listing_object && 'WP_Term' === get_class( $listing_object ) ) { $term_id = $listing_object->term_id; } else { $queried_object = get_queried_object(); if ( $queried_object && isset( $queried_object->term_id ) ) { $term_id = $queried_object->term_id; } elseif ( $listing_object && 'WP_Post' === get_class( $listing_object ) && ! empty( $data_source['context_tax'] ) ) { $post_id = $listing_object->ID; $terms = wp_get_post_terms( $post_id, $data_source['context_tax'], array( 'fields' => 'ids' ) ); if ( ! is_wp_error( $terms ) && ! empty( $terms ) ) { $term_id = $terms[0]; } } } return $term_id; } /** * Number format. * * @param array $data * @return string|null */ public function number_format( $data = array() ) { if ( ! isset( $data['result'] ) ) { return null; } $decimal_point = isset( $data['custom_settings']['decimal_point'] ) ? $data['custom_settings']['decimal_point'] : '.'; $thousands_sep = isset( $data['custom_settings']['thousands_separator'] ) ? $data['custom_settings']['thousands_separator'] : ','; $decimal_count = isset( $data['custom_settings']['decimal_count'] ) ? $data['custom_settings']['decimal_count'] : 0; return number_format( $data['result'], $decimal_count, $decimal_point, $thousands_sep ); } } } Η Τροπική Κουλτούρα: Από τα Παράδοξα των Κλιματικών Ζωνών έως την Αειφόρο Ανάπτυξη – homeserviceapp.noviindus.com

Η Τροπική Κουλτούρα: Από τα Παράδοξα των Κλιματικών Ζωνών έως την Αειφόρο Ανάπτυξη

Η Ελλάδα, παρά το γεγονός ότι βρίσκεται σε γεωγραφική θέση που την συνδέει άμεσα με την τροπική ζώνη, διαθέτει μια μοναδική κουλτούρα που διαφέρει από τα παραδοσιακά μοντέλα της τροπικής ζωής. Οι ελληνικές περιοχές με κλίμα που πλησιάζει ή ενδέχεται να εισέλθει σε τροπικά όρια—όπως η Κρήτη, η Χίο ή η Κεφαλονιά—είναι παράδειγμα μιας αλληλεπίδρασης μεταξύ τοπικών παραδόσεων και κλιματικών συνθηκών που δημιουργούν μια ξεχωριστή ταυτότητα.

Η τροπική κουλτούρα στην Ελλάδα δεν περιορίζεται σε γεωγραφικά όρια αλλά επηρεάζεται από ιστορικές, οικονομικές και κοινωνικές διαδικασίες που έχουν διαμορφωθεί μέσα σε αιώνες. Από την παραδοσιακή γεωργία μέχρι την παραδοσιακή κουζίνα, οι τοπικές κοινότητες έχουν προσαρμοστεί σε ένα κλίμα που, αν και δεν είναι εντελώς τροπικό, προσφέρει μοναδικές ευκαιρίες για την ανάπτυξη ξεχωριστών προϊόντων. Για παράδειγμα, οι ελαιόδεντρες της Κρήτης και οι καρποί της Χίου δεν ακολουθούν τα same μοντέλα παραγωγής που συναντάμε σε τροπικές περιοχές του κόσμου.

Ένα από τα πιο ενδιαφέροντα πτυχή της ελληνικής τροπικής κουλτούρας είναι η έμφαση στην αειφόρο ανάπτυξη. Σε αντίθεση με τις βιομηχανικές μεθόδους παραγωγής που συχνά καταστρέφουν τα οικοσυστήματα, οι τοπικές κοινότητες της Ελλάδας έχουν αναπτύξει μεθόδους που συνδυάζουν την παραδοσιακή γνώση με σύγχρονες τεχνολογίες. Η χρήση του φυτικού λίπους για την παρασκευή σαπουνιών, η καλλιέργεια εσπεριδοειδών με βιολογικούς τρόπους και η προστασία των δασών από την υπερεκμετάλλευση είναι μόνο μερικά παραδείγματα μιας προσέγγισης που προωθεί την ισορροπία μεταξύ ανάπτυξης και προστασίας του περιβάλλοντος.

Οι Τροπικές Περιοχές της Ελλάδας: Γεωγραφική και Κλιματική Ανασκόπηση

Η Ελλάδα διαθέτει περιοχές που, αν και δεν βρίσκονται εντελώς στην τροπική ζώνη, παρουσιάζουν χαρακτηριστικά που τις συνδέουν με αυτήν. Σύμφωνα με το Παγκόσμιο Μετεωρολογικό Οργανισμό, οι περιοχές με μέση ετήσια θερμοκρασία μεγαλύτερη από 18°C και σημαντική βροχόπτωση κατά τη διάρκεια του καλοκαιριού—όπως η Κρήτη, η Χίο και η Κεφαλονιά—μπορούν να θεωρηθούν ως προαστιακές ζώνες της τροπικής κουλτούρας. Ωστόσο, η γεωγραφική τους θέση, η ποικιλία των εδαφών και οι τοπικές συνθήκες δημιουργούν ένα κλίμα που είναι τόσο μοναδικό όσο και προσαρμοστικό.

Στην Κρήτη, για παράδειγμα, η θερμοκρασία μπορεί να φτάσει έως και 40°C κατά τους καλοκαιρινούς μήνες, ενώ η υγρασία είναι χαμηλή, δημιουργώντας ένα κλίμα που είναι πιο ξηρό και θερμό από αυτό των παραδοσιακών τροπικών περιοχών. Αυτό έχει οδηγήσει στην ανάπτυξη ειδικών γεωργικών τεχνικών, όπως η καλλιέργεια ελαιοδεντρών και εσπεριδοειδών με συστηματικά ριζικά συστήματα για να αποφευχθεί η απώλεια νερού. Η Χίο, με τις θερμές ακτές της και την παρουσία δασών με τοπικά είδη, παρουσιάζει επίσης μια μοναδική προσαρμογή στη θερμότητα και την υγρασία.

Η Τροπική Κουλτούρα και η Τροπική Γεύση: Από τα Προϊόντα έως την Κουζίνα

Η τροπική γεύση στην ελληνική κουζίνα δεν περιορίζεται σε καρπούς ή φρούτα αλλά επεκτείνεται και σε προϊόντα που παράγονται με τοπικές μεθόδους. Τα παραδοσιακά προϊόντα όπως οι εσπεριδοειδές, οι ελαιόλαδοι και τα φρούτα της Κρήτης και της Χίου έχουν γίνει γνωστά για τις μοναδικές γεύσεις τους. Για παράδειγμα, ο εσπεριδοειδής της Χίου, γνωστός ως «Χιώτικο», έχει μια γεύση που συνδυάζει τη σαρκαστικότητα του λεμονιού με το γλυκό της πορτοκαλιού, ενώ οι εσπεριδοειδές της Κρήτης είναι πιο ζεστοί και αρωματικοί.

Η κουζίνα της Ελλάδας έχει ενσωματώσει επίσης τα τοπικά προϊόντα σε παραδοσιακές συνταγές, δημιουργώντας ένα είδος «τροπικής» κουζίνας που είναι τόσο ελληνική όσο και ξεχωριστή. Για παράδειγμα, οι σαλάτες με εσπεριδοειδές, οι ζυμαρικά με ελαιόλαδο και τα αποξηραμένα φρούτα χρησιμοποιούνται συχνά σε παραδοσιακές συνταγές, ενώ τα τοπικά προϊόντα όπως οι γλυκοί καρποί και τα φρούτα της Κρήτης προσφέρονται σε εστιατόρια και καφενεία ως επιλογές για τους επισκέπτες.

Είναι σημαντικό να σημειωθεί ότι η τροπική κουλτούρα στην Ελλάδα δεν είναι μόνο μια εμπορική προσέγγιση αλλά μια βαθιά ρίζα της τοπικής κοινωνίας. Οι επιχειρήσεις που παράγουν και πωλούν τοπικά προϊόντα, όπως οι εσπεριδοειδές και οι ελαιόλαδοι, συνδέονται άμεσα με την τοπική κοινότητα και την προστασία του περιβάλλοντος. Η διατήρηση αυτών των παραδόσεων αποτελεί μέρος μιας ευρύτερης προσπάθειας για την ανάπτυξη μιας αειφόρου και βιώσιμης οικονομίας.

Η Προοπτική της Αειφόρου Ανάπτυξης στην Τροπική Κουλτούρα

Η Ελλάδα έχει αναλάβει μια σειρά από πρωτοβουλίες για την προώθηση της αειφόρου ανάπτυξης στις τροπικές περιοχές της. Ένα από τα κύρια μέτρα είναι η προστασία των τοπικών δασών και η ανάπτυξη βιώσιμων γεωργικών μεθόδων. Για παράδειγμα, το πρόγραμμα «Πράσινη Κρήτη» έχει στόχο την ανάπτυξη βιώσιμων γεωργικών τεχνικών, όπως η χρήση βιολογικών φυτικών προϊόντων και η προστασία των τοπικών είδων.

Επιπλέον, η Ελλάδα έχει ενσωματώσει τις αρχές της αειφόρου ανάπτυξης στην εκπαίδευση και την έρευνα, προωθώντας την ανάπτυξη νέων τεχνολογιών που μπορούν να βοηθήσουν στην προστασία των τροπικών περιοχών. Η συνεργασία μεταξύ τοπικών κοινωνιών, κυβερνητικών οργανισμών και ερευνητών έχει οδηγήσει στην ανάπτυξη νέων προγραμμάτων που στόχο έχουν την προστασία του περιβάλλοντος και την προώθηση της βιώσιμης ανάπτυξης.

Η διατήρηση της τροπικής κουλτούρας στην Ελλάδα αποτελεί επίσης μια σημαντική προσπάθεια για την προστασία της πολιτιστικής κληρονομιάς. Οι τοπικές κοινότητες, οι οποίες έχουν διατηρήσει τις παραδόσεις τους για αιώνες, είναι οι κύριες φορείς για την προστασία και την ανάπτυξη αυτών των πολιτιστικών στοιχείων. Η ενσωμάτωση αυτών των παραδόσεων στην σύγχρονη κοινωνία αποτελεί μέρος μιας ευρύτερης προσπάθειας για την ανάπτυξη μιας βιώσιμης και ισορροπημένης κοινωνίας.

  • Η Κρήτη και η Χίο είναι οι σημαντικότερες ελληνικές περιοχές που παρουσιάζουν τροπικά χαρακτηριστικά, με θερμοκρασίες που φτάνουν έως και 40°C κατά τους καλοκαιρινούς μήνες.
  • Τα τοπικά προϊόντα όπως οι εσπεριδοειδές της Χίου και της Κρήτης έχουν μοναδικές γεύσεις που συνδυάζουν ξηρότητα και θερμότητα.
  • Η Ελλάδα έχει αναλάβει πρωτοβουλίες για την προστασία των τοπικών δασών και την ανάπτυξη βιώσιμων γεωργικών μεθόδων.
  • Το πρόγραμμα «Πράσινη Κρήτη» προωθεί την χρήση βιολογικών φυτικών προϊόντων και την προστασία των τοπικών ειδών.
  • Η ενσωμάτωση των παραδόσεων της τροπικής κουλτούρας στην εκπαίδευση και την έρευνα συμβάλλει στην ανάπτυξη νέων τεχνολογιών για την προστασία του περιβάλλοντος.

Η τροπική κουλτούρα στην Ελλάδα δεν είναι απλά μια γεωγραφική ή κλιματική έννοια αλλά μια βαθιά ρίζα της τοπικής κοινωνίας και της πολιτιστικής μας ταυτότητας. Από την παραδοσιακή γεωργία έως την κουζίνα, οι τοπικές κοινότητες έχουν αναπτύξει μεθόδους προσαρμογής που συνδυάζουν την παραδοσιακή γνώση με σύγχρονες τεχνολογίες. Η διατήρηση αυτών των παραδόσεων αποτελεί μέρος μιας ευρύτερης προσπάθειας για την ανάπτυξη μιας βιώσιμης και ισορροπημένης κοινωνίας, όπου η κουλτούρα, το περιβάλλον και η οικονομία βρίσκονται σε αρμονία. διαβάστε περισσότερα


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *