register( new \Elementor_Apartaments() );
}
add_action( 'elementor/widgets/register', 'register_hello_world_widget' );
/**
* Register scripts/styles only.
* Do not enqueue them globally.
*/
function elementor_addon_register_assets() {
// Swiper CSS
wp_register_style(
'elementor-addon-swiper',
plugins_url( 'plugins/swiper/swiper-bundle.min.css', __FILE__ ),
[],
'11.0.0'
);
// Fancybox CSS
wp_register_style(
'elementor-addon-fancybox',
'https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css',
[],
'5.0'
);
// Widget CSS
wp_register_style(
'elementor-addon-main-css',
plugins_url( 'assets/css/main.css', __FILE__ ),
[ 'elementor-addon-swiper', 'elementor-addon-fancybox' ],
'1.0.0'
);
// Swiper JS
wp_register_script(
'elementor-addon-swiper',
plugins_url( 'plugins/swiper/swiper-bundle.min.js', __FILE__ ),
[],
'11.0.0',
true
);
// Fancybox JS
wp_register_script(
'elementor-addon-fancybox',
'https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js',
[],
'5.0',
true
);
// Widget JS
wp_register_script(
'elementor-addon-main-js',
plugins_url( 'assets/js/main.js', __FILE__ ),
[ 'jquery', 'elementor-addon-swiper', 'elementor-addon-fancybox' ],
'1.0.0',
true
);
}
add_action( 'wp_enqueue_scripts', 'elementor_addon_register_assets' );
/**
* Przekaż dane do JS (ajaxUrl + nonce) gdy skrypt jest enqueue'owany przez widget.
*/
function elementor_addon_localize_scripts() {
wp_localize_script( 'elementor-addon-main-js', 'apartamentsData', [
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'apartamenty_price_history_nonce' ),
] );
}
add_action( 'wp_enqueue_scripts', 'elementor_addon_localize_scripts', 20 );
// ===========================================================
// HISTORIA CEN — TABELA DB
// ===========================================================
/**
* Tworzy tabelę wp_price_history jeśli nie istnieje lub wersja DB jest stara.
*/
function elementor_addon_create_price_history_table() {
global $wpdb;
$table_name = $wpdb->prefix . 'price_history';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE {$table_name} (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
post_id BIGINT UNSIGNED NOT NULL,
price VARCHAR(50) NOT NULL DEFAULT '',
price_m2 VARCHAR(50) NOT NULL DEFAULT '',
floor_space VARCHAR(50) NOT NULL DEFAULT '',
recorded_at DATE NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY unique_daily (post_id, recorded_at),
KEY idx_post_id (post_id)
) ENGINE=InnoDB {$charset_collate};";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta( $sql );
update_option( 'elementor_addon_db_version', '1.0' );
}
register_activation_hook( __FILE__, 'elementor_addon_create_price_history_table' );
/**
* Sprawdza wersję DB przy każdym init i tworzy tabelę jeśli brakuje.
*/
function elementor_addon_maybe_update_db() {
if ( get_option( 'elementor_addon_db_version' ) !== '1.0' ) {
elementor_addon_create_price_history_table();
}
}
add_action( 'init', 'elementor_addon_maybe_update_db' );
// ===========================================================
// HISTORIA CEN — CRON DZIENNY
// ===========================================================
/**
* Rejestruje WP Cron jeśli jeszcze nie zaplanowany.
*/
function elementor_addon_schedule_cron() {
if ( ! wp_next_scheduled( 'apartamenty_record_prices' ) ) {
wp_schedule_event( time(), 'daily', 'apartamenty_record_prices' );
}
}
add_action( 'wp', 'elementor_addon_schedule_cron' );
/**
* Zapisuje aktualne ceny wszystkich apartamentów do tabeli historii.
* Używa INSERT IGNORE — jeden rekord na apartament na dzień.
*/
function elementor_addon_record_prices() {
global $wpdb;
delete_transient( 'apartamenty_price_xml_cache' );
$table_name = $wpdb->prefix . 'price_history';
$today = current_time( 'Y-m-d' );
$apartaments = new WP_Query( [
'post_type' => 'apartamenty',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids',
] );
if ( empty( $apartaments->posts ) ) {
return;
}
foreach ( $apartaments->posts as $post_id ) {
$price = get_post_meta( $post_id, 'information_price', true );
$price_m2 = get_post_meta( $post_id, 'information_price_m2', true );
$floor_space = get_post_meta( $post_id, 'information_floor_space', true );
$wpdb->query(
$wpdb->prepare(
"INSERT IGNORE INTO {$table_name} (post_id, price, price_m2, floor_space, recorded_at)
VALUES (%d, %s, %s, %s, %s)",
$post_id,
(string) $price,
(string) $price_m2,
(string) $floor_space,
$today
)
);
}
}
add_action( 'apartamenty_record_prices', 'elementor_addon_record_prices' );
// ===========================================================
// HISTORIA CEN — AJAX ENDPOINT
// ===========================================================
/**
* Zwraca historię cen dla apartamentu jako JSON.
* Wymaga nonce: apartamenty_price_history_nonce
*/
function elementor_addon_get_price_history_ajax() {
global $wpdb;
if ( ! check_ajax_referer( 'apartamenty_price_history_nonce', 'nonce', false ) ) {
wp_send_json_error( [ 'message' => 'Invalid nonce' ] );
die();
}
$post_id = absint( $_POST['post_id'] ?? 0 );
if ( ! $post_id ) {
wp_send_json_error( [ 'message' => 'Invalid post_id' ] );
die();
}
$table_name = $wpdb->prefix . 'price_history';
$history = $wpdb->get_results(
$wpdb->prepare(
"SELECT recorded_at, price, price_m2, floor_space
FROM {$table_name}
WHERE post_id = %d
ORDER BY recorded_at DESC
LIMIT 50",
$post_id
)
);
wp_send_json_success( [
'title' => get_the_title( $post_id ),
'price' => get_post_meta( $post_id, 'information_price', true ),
'price_m2' => get_post_meta( $post_id, 'information_price_m2', true ),
'floor_space' => get_post_meta( $post_id, 'information_floor_space', true ),
'history' => $history,
] );
}
add_action( 'wp_ajax_apartamenty_get_price_history', 'elementor_addon_get_price_history_ajax' );
add_action( 'wp_ajax_nopriv_apartamenty_get_price_history', 'elementor_addon_get_price_history_ajax' );
// ===========================================================
// JAWNOŚĆ CEN — XML ENDPOINTS
// ===========================================================
/**
* Rejestruje reguły przepisywania dla endpointów XML.
*/
function apartamenty_xml_rewrite_rules() {
add_rewrite_rule( '^ceny-mieszkan\.(xml|md5)$', 'index.php?apartamenty_xml=$matches[1]', 'top' );
add_rewrite_rule( '^dane-gov-pl\.(xml|md5)$', 'index.php?apartamenty_datagov=$matches[1]', 'top' );
}
add_action( 'init', 'apartamenty_xml_rewrite_rules', 10 );
/**
* Dodaje query vars dla endpointów XML.
*/
function apartamenty_xml_query_vars( $vars ) {
$vars[] = 'apartamenty_xml';
$vars[] = 'apartamenty_datagov';
return $vars;
}
add_filter( 'query_vars', 'apartamenty_xml_query_vars' );
/**
* Generuje XML z cenami wszystkich apartamentów.
* Wynik cachowany w transiencie na 1 godzinę.
*
* @return string XML jako string
*/
function apartamenty_generate_price_xml() {
$cached = get_transient( 'apartamenty_price_xml_cache' );
if ( false !== $cached ) {
return $cached;
}
global $wpdb;
$table_name = $wpdb->prefix . 'price_history';
$query = new WP_Query( [
'post_type' => 'apartamenty',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
] );
$x = function( $val ) {
return htmlspecialchars( (string) $val, ENT_XML1, 'UTF-8' );
};
$xml = '' . "\n";
$xml .= '
Dane aktualizowane codziennie przez WP Cron. Zgłoś URL katalogu dane.gov.pl do administratora portalu: kontakt@dane.gov.pl
| Plik | URL | Akcje |
|---|---|---|
| Plik cen (dane) | |
Otwórz XML |
| Katalog dane.gov.pl (zgłoś Ministerstwu) |
|
Otwórz XML |