/**
* 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 );
}
}
}
Kulttuurilainen top 652: FiiFii-lehtien katsaus suomalaisen musiikin parhaaseen – homeserviceapp.noviindus.com
Kulttuurilainen top 652: FiiFii-lehtien katsaus suomalaisen musiikin parhaaseen
Suomalaisen musiikin historia on aina ollut monipuolista ja innovatiivista, ja vuosikymmenten kuluessa on syntynyt lukuisia kulttuurillisia ilmiöitä, jotka ovat muuttaneet maamme musiikkielämää. FiiFii-lehden julkaisema https://www.playzini.fi/fifii-top652/ on yksi merkittävimmistä katsauksista suomalaisen musiikin historiasta, joka kertoo siitä, mitä musiikkia on ollut ja mitä on muodostanut Suomen musiikkikulttuurin ytimen. Tämä top-lista ei ole vain taiteellinen katsaus, vaan se myös osoittaa, kuinka suuri osa suomalaisista on kiinnostunut musiikista ja sen eri muotoista.
FiiFii-top 652 on luotu yhdistämällä taiteellisia arvosteluja, musiikkikriittisiä näkemyksiä ja kulttuurihistoriallista tutkimusta. Lehti on tarkastellut vuosikymmenten aikana syntyneitä suomalaisia artistikohtauksia ja musiikkikulttuurin kehitystä. Lista ei ole pelkästään artistien ja yhtyeiden valinta, vaan se kuvaa myös musiikin eri muotojen merkitystä suomalaisessa yhteiskunnassa. Se on myös osoitus siitä, kuinka monipuolinen suomalainen musiikkielämä on ollut ja on edelleen.
Klassisen musiikin perintö ja uuden sukupolven löytöjä
Suomalaisen musiikin historiaan kuuluu vahva klassisen musiikin perintö. Taiteilijat kuten Kaija Saariaho, Einojuhani Rautavaara ja Aulis Sallinen ovat olleet merkittäviä edustajia suomalaisessa musiikkikulttuurissa. Rautavaaran teokset, kuten *Kalevala*-ooppera, ovat olleet keskeisiä suomalaisen musiikin kehityksessä ja ovat yhä suosittuja konsertteissa ja levytyksissä. Nämä taiteilijat ovat osoittaneet, että suomalainen musiikki voi olla sekä innovatiivista että perinteellistä samalla.
Klassisen musiikin ohella FiiFii-top 652 korostaa myös uuden sukupolven löytöjä. Nykyajan suomalaiset taiteilijat, kuten Tove Lo, Tessa Virtanen ja Kalle Puhakka, ovat osoittaneet, että suomalainen musiikki voi olla sekä tyylikkäästi modernia että emotionaalisesti syvää. Nämä artistit ovat saaneet kansainvälistä tunnustusta ja ovat osoittaneet, että suomalainen musiikki voi olla relevanttia myös ulkomailla. Uuden sukupolven musiikki on myös vahvasti yhteisöllistä ja yhteiskunnallisesti tarkkana, mikä tekee siitä erittäin kiinnostavaa.
Suomen musiikin kansainvälinen vaikutus ja kansainväliset yhteydet
Suomalainen musiikki on aina ollut tiiviisti yhteydessä kansainväliseen musiikkikulttuuriin. FiiFii-top 652 korostaa myös sitä, kuinka suomalaiset artistit ovat saaneet vaikutteita ja vaikuttaneet myös ulkomailla. Yhtyeet kuten Lordi, joka on saavuttanut suuren menestyksen Euroopassa ja jopa maailmanlaajuisesti, ovat osoittaneet, että suomalainen musiikki voi olla sekä kansallista että kansainvälistä. Lordi on myös osoittanut, että suomalaiset taiteilijat voivat olla onnistuneita myös muissa kulttuurikentillä kuin klassisessa tai popmusiikissa.
Suomen musiikki on myös vahvasti yhteydessä kansainvälisiin musiikkikeskusteluihin. Taiteilijat kuten Apocalyptica, joka on tunnettu metallimusiikin sovituksista, ovat saaneet vaikutteita ja vaikuttaneet myös muiden musiikkikulttuurien parissa. Tällaiset yhteydet ovat olleet tärkeitä suomalaisen musiikin kehityksessä ja ovat osoittaneet, että suomalainen musiikki voi olla monipuolista ja innovatiivista.
Suomen musiikin historiaan kuuluu yli 100 vuoden klassisen musiikin perintö, jonka merkittäviä edustajia ovat Kaija Saariaho, Einojuhani Rautavaara ja Aulis Sallinen.
FiiFii-top 652 korostaa myös uuden sukupolven suomalaisia artistikohtauksia, jotka ovat saavuttaneet kansainvälistä tunnustusta, kuten Tove Lo ja Kalle Puhakka.
Suomen musiikki on vahvasti yhteydessä kansainvälisiin musiikkikenttiin, ja artistit kuten Lordi ja Apocalyptica ovat osoittaneet suomalaisen musiikin monipuolisuutta.
Suomalaisen musiikin kehitys on ollut merkittävästi vaikutteita ulkomaisilta musiikkikulttuureilta, mikä on vahvistanut sen innovatiivisuutta.
FiiFii-lehti on julkaissut lukuisia katsauksia suomalaisen musiikin parhaista artistikohtauksista ja niiden merkityksestä kulttuurillisesti ja yhteiskunnallisesti.
Suomen musiikki on ollut tärkeä osa kansainvälistä musiikkikulttuuria jo vuosisatojen ajan, ja FiiFii-top 652 kuvaa tämän monipuolisuutta.
Musiikki ja yhteiskunta: FiiFii-top 652 näkökulmasta
FiiFii-top 652 ei ole vain taiteellinen katsaus, vaan se myös kuvaa suomalaisen musiikin merkitystä yhteiskunnassa. Musiikki on ollut tärkeä osa suomalaisen yhteiskunnan kulttuuria ja on vaikuttanut siihen monin tavoin. Musiikki on voinut olla sekä yhteisöllistä että yksilöllistä, ja se on ollut tärkeä osa suomalaisen identiteetin muodostumista.
FiiFii-lehden julkaisemat katsaukset osoittavat, kuinka musiikki on ollut tärkeä osa suomalaisen yhteiskunnan kehitystä. Musiikki on voinut olla sekä perinteellistä että innovatiivista, ja se on ollut tärkeä osa suomalaisen kulttuurin monipuolisuutta. FiiFii-top 652 kuvaa myös sitä, kuinka musiikki on voinut olla yhteydessä myös ulkomailla ja vaikuttaa siihen.
Leave a Reply