<?php
/**
* Internal module: Demo Seeder.
* Loaded by onOffice Elementor Bridge.
*/
defined('ABSPATH') || exit;
final class FRESH_OnOffice_Demo_Seeder {
const CPT = 'fresh_immobilie';
const DEMO_META = '_fresh_oo_demo';
public function __construct() {
add_action('admin_menu', [$this, 'admin_menu']);
add_action('admin_post_fresh_oo_demo_create', [$this, 'handle_create']);
add_action('admin_post_fresh_oo_demo_delete', [$this, 'handle_delete']);
}
public function admin_menu(): void {
add_submenu_page(
'edit.php?post_type=' . self::CPT,
'Demo-Immobilien',
'Demo-Immobilien',
'manage_options',
'fresh-oo-demo',
[$this, 'render_admin']
);
}
private function demo_count(): int {
$q = new WP_Query([
'post_type' => self::CPT,
'post_status' => ['publish','draft','private','pending'],
'posts_per_page' => 1,
'fields' => 'ids',
'meta_key' => self::DEMO_META,
'meta_value' => '1',
]);
return (int)$q->found_posts;
}
public function render_admin(): void {
if (!current_user_can('manage_options')) return;
$count = $this->demo_count();
?>
<div class="wrap">
<h1>onOffice Demo-Immobilien</h1>
<p>Hier kannst Du lokale Demo-Objekte anlegen, bevor der echte onOffice-Account des Kunden verfügbar ist. Die Datensätze verwenden dieselben <code>oo_*</code>-Felder und Taxonomien wie der spätere Live-Import.</p>
<div class="notice notice-info inline"><p><strong>Aktuell vorhanden:</strong> <?php echo esc_html((string)$count); ?> Demo-Immobilien.</p></div>
<h2>Demo-Daten anlegen</h2>
<p>Es werden 10 Berliner Beispielobjekte mit Kauf-/Mietobjekten, Preisen, Flächen, Zimmern, Texten, Energieangaben und Taxonomien erzeugt.</p>
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
<input type="hidden" name="action" value="fresh_oo_demo_create">
<?php wp_nonce_field('fresh_oo_demo_create'); ?>
<?php submit_button('Demo-Immobilien anlegen', 'primary', 'submit', false); ?>
</form>
<hr>
<h2>Demo-Daten entfernen</h2>
<p>Entfernt ausschließlich Immobilien, die von diesem Seeder erzeugt wurden. Echte oder manuell angelegte Immobilien bleiben unberührt.</p>
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" onsubmit="return confirm('Demo-Immobilien wirklich löschen?');">
<input type="hidden" name="action" value="fresh_oo_demo_delete">
<?php wp_nonce_field('fresh_oo_demo_delete'); ?>
<?php submit_button('Demo-Immobilien löschen', 'delete', 'submit', false); ?>
</form>
</div>
<?php
}
public function handle_create(): void {
if (!current_user_can('manage_options')) wp_die('Keine Berechtigung.');
check_admin_referer('fresh_oo_demo_create');
$created = 0;
foreach ($this->demo_properties() as $index => $property) {
if ($this->create_property($property, $index + 1)) $created++;
}
wp_safe_redirect(admin_url('edit.php?post_type=' . self::CPT . '&page=fresh-oo-demo&created=' . $created));
exit;
}
public function handle_delete(): void {
if (!current_user_can('manage_options')) wp_die('Keine Berechtigung.');
check_admin_referer('fresh_oo_demo_delete');
$ids = get_posts([
'post_type' => self::CPT,
'post_status' => ['publish','draft','private','pending'],
'numberposts' => -1,
'fields' => 'ids',
'meta_key' => self::DEMO_META,
'meta_value' => '1',
]);
foreach ($ids as $id) wp_delete_post((int)$id, true);
$media_ids = get_posts([
'post_type' => 'attachment',
'post_status' => 'inherit',
'numberposts' => -1,
'fields' => 'ids',
'meta_key' => '_fresh_oo_demo_media',
'meta_value' => '1',
]);
foreach ($media_ids as $media_id) wp_delete_attachment((int)$media_id, true);
wp_safe_redirect(admin_url('edit.php?post_type=' . self::CPT . '&page=fresh-oo-demo&deleted=' . count($ids)));
exit;
}
private function create_property(array $p, int $number): int {
$existing = get_posts([
'post_type' => self::CPT,
'post_status' => ['publish','draft'],
'numberposts' => 1,
'fields' => 'ids',
'meta_query' => [
['key' => self::DEMO_META, 'value' => '1'],
['key' => '_fresh_oo_demo_key', 'value' => $p['key']],
],
]);
if ($existing) {
$post_id = (int)$existing[0];
wp_update_post([
'ID' => $post_id,
'post_status' => 'publish',
'post_title' => $p['title'],
'post_content' => $p['beschreibung'],
'post_excerpt' => $p['lage'],
]);
} else {
$post_id = wp_insert_post([
'post_type' => self::CPT,
'post_status' => 'publish',
'post_title' => $p['title'],
'post_content' => $p['beschreibung'],
'post_excerpt' => $p['lage'],
], true);
if (is_wp_error($post_id)) return 0;
}
update_post_meta($post_id, self::DEMO_META, 1);
update_post_meta($post_id, '_fresh_oo_demo_key', $p['key']);
update_post_meta($post_id, '_fresh_oo_id', 900000 + $number);
update_post_meta($post_id, '_fresh_oo_last_seen', time());
$meta = [
'oo_objekttitel' => $p['title'],
'oo_objektbeschreibung' => $p['beschreibung'],
'oo_lage' => $p['lage'],
'oo_ausstatt_beschr' => $p['ausstattung'],
'oo_sonstige_angaben' => $p['sonstiges'],
'oo_objektart' => $p['objektart'],
'oo_objekttyp' => $p['objekttyp'],
'oo_nutzungsart' => $p['nutzungsart'],
'oo_vermarktungsart' => $p['vermarktungsart'],
'oo_ort' => $p['ort'],
'oo_plz' => $p['plz'],
'oo_strasse' => $p['strasse'],
'oo_hausnummer' => $p['hausnummer'],
'oo_land' => 'DEU',
'oo_wohnflaeche' => $p['wohnflaeche'],
'oo_nutzflaeche' => $p['nutzflaeche'],
'oo_grundstuecksflaeche' => $p['grundstuecksflaeche'],
'oo_anzahl_zimmer' => $p['zimmer'],
'oo_anzahl_schlafzimmer' => $p['schlafzimmer'],
'oo_anzahl_badezimmer' => $p['badezimmer'],
'oo_anzahl_balkone' => $p['balkone'],
'oo_anzahl_terrassen' => $p['terrassen'],
'oo_etagenzahl' => $p['etagen'],
'oo_baujahr' => $p['baujahr'],
'oo_zustand' => $p['zustand'],
'oo_waehrung' => 'EUR',
'oo_kaufpreis' => $p['kaufpreis'],
'oo_kaltmiete' => $p['kaltmiete'],
'oo_warmmiete' => $p['warmmiete'],
'oo_hausgeld' => $p['hausgeld'],
'oo_aussen_courtage' => $p['courtage'],
'oo_provisionsfrei' => $p['provisionsfrei'],
'oo_energieausweistyp' => $p['energieausweistyp'],
'oo_endenergiebedarf' => $p['endenergiebedarf'],
'oo_endenergieverbrauch' => $p['endenergieverbrauch'],
'oo_energyclass' => $p['energieklasse'],
'oo_baujahr_laut_energieausweis' => $p['baujahr'],
'oo_heizungsart' => $p['heizung'],
'oo_befeuerung' => $p['befeuerung'],
'oo_fahrstuhl' => $p['fahrstuhl'],
'oo_balkon' => $p['balkone'] > 0 ? 1 : 0,
'oo_terrasse' => $p['terrassen'] > 0 ? 1 : 0,
'oo_keller' => $p['keller'],
'oo_gartennutzung' => $p['garten'],
'oo_stellplatzart' => $p['stellplatz'],
'oo_veroeffentlichen' => 1,
'oo_referenz' => 0,
];
foreach ($meta as $key => $value) update_post_meta($post_id, $key, $value);
wp_set_object_terms($post_id, $p['ort'], 'immo_ort', false);
wp_set_object_terms($post_id, $p['objektart'], 'immo_objektart', false);
wp_set_object_terms($post_id, $p['vermarktungsart'], 'immo_vermarktungsart', false);
wp_set_object_terms($post_id, 'Aktiv', 'immo_status', false);
$this->ensure_demo_gallery((int)$post_id, $p, $number);
return (int)$post_id;
}
private function ensure_demo_gallery(int $post_id, array $p, int $number): void {
$existing = get_post_meta($post_id, 'oo_gallery_ids', true);
if (is_array($existing) && count($existing) >= 4 && has_post_thumbnail($post_id)) return;
if (!function_exists('imagecreatetruecolor') || !function_exists('imagejpeg')) return;
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/image.php';
$uploads = wp_upload_dir();
if (!empty($uploads['error'])) return;
$ids = [];
$themes = [
[236,230,217,58,61,60], [216,224,220,50,64,67], [229,218,205,78,64,54], [219,222,228,52,57,68]
];
foreach ($themes as $i => $c) {
$w=1600; $h=1000;
$im=imagecreatetruecolor($w,$h);
$bg=imagecolorallocate($im,$c[0],$c[1],$c[2]);
$dark=imagecolorallocate($im,$c[3],$c[4],$c[5]);
$light=imagecolorallocate($im,min(255,$c[0]+14),min(255,$c[1]+14),min(255,$c[2]+14));
imagefilledrectangle($im,0,0,$w,$h,$bg);
imagefilledrectangle($im,0,690,$w,$h,$dark);
// Abstract architectural composition for layout testing.
imagefilledrectangle($im,180 + $i*40,250,720 + $i*25,690,$light);
imagefilledrectangle($im,760,155 + $i*20,1390,690,$light);
imagefilledrectangle($im,250,330,420,600,$dark);
imagefilledrectangle($im,485,330,655,600,$dark);
imagefilledrectangle($im,850,250,1010,420,$dark);
imagefilledrectangle($im,1080,250,1240,420,$dark);
imagefilledrectangle($im,850,480,1240,690,$dark);
imagestring($im,5,65,80,'IB IMMOBILIEN - DEMO', $dark);
imagestring($im,4,65,115,substr($p['title'],0,48), $dark);
imagestring($im,3,65,150,$p['ort'].' | Ansicht '.($i+1), $dark);
$filename = 'ib-demo-' . sanitize_file_name($p['key']) . '-' . ($i+1) . '.jpg';
$filepath = trailingslashit($uploads['path']) . $filename;
imagejpeg($im,$filepath,88);
imagedestroy($im);
$filetype = wp_check_filetype($filename, null);
$attachment_id = wp_insert_attachment([
'post_mime_type' => $filetype['type'] ?: 'image/jpeg',
'post_title' => $p['title'] . ' – Ansicht ' . ($i+1),
'post_content' => '',
'post_status' => 'inherit',
], $filepath, $post_id);
if (is_wp_error($attachment_id)) continue;
$meta = wp_generate_attachment_metadata($attachment_id, $filepath);
wp_update_attachment_metadata($attachment_id, $meta);
update_post_meta($attachment_id, '_wp_attachment_image_alt', $p['title'] . ' – Demoansicht ' . ($i+1));
update_post_meta($attachment_id, '_fresh_oo_demo_media', 1);
$ids[] = (int)$attachment_id;
}
if ($ids) {
update_post_meta($post_id, 'oo_gallery_ids', $ids);
update_post_meta($post_id, 'oo_gallery_csv', implode(',', $ids));
set_post_thumbnail($post_id, $ids[0]);
}
}
private function demo_properties(): array {
$common = [
'nutzflaeche'=>0,'grundstuecksflaeche'=>0,'schlafzimmer'=>2,'badezimmer'=>1,'balkone'=>1,'terrassen'=>0,'etagen'=>4,
'zustand'=>'Gepflegt','hausgeld'=>0,'courtage'=>'3,57 % inkl. MwSt.','provisionsfrei'=>0,'energieausweistyp'=>'Verbrauchsausweis',
'endenergiebedarf'=>0,'endenergieverbrauch'=>85.0,'energieklasse'=>'C','heizung'=>'Zentralheizung','befeuerung'=>'Gas','fahrstuhl'=>1,
'keller'=>1,'garten'=>0,'stellplatz'=>'','sonstiges'=>'Alle Angaben dienen der unverbindlichen Vorschau und können später durch Live-Daten aus onOffice ersetzt werden.'
];
$items = [
['key'=>'charlottenburg-altbau','title'=>'Stilvolle Altbauwohnung in Charlottenburg','objektart'=>'Wohnung','objekttyp'=>'Etagenwohnung','nutzungsart'=>'Wohnen','vermarktungsart'=>'Kauf','ort'=>'Berlin-Charlottenburg','plz'=>'10623','strasse'=>'Knesebeckstraße','hausnummer'=>'48','wohnflaeche'=>128,'zimmer'=>4,'baujahr'=>1908,'kaufpreis'=>895000,'kaltmiete'=>0,'warmmiete'=>0,'hausgeld'=>495,'endenergieverbrauch'=>92.4,'beschreibung'=>'Großzügige Altbauwohnung mit hohen Decken, Stuckdetails und modernem Wohnkomfort.','lage'=>'Ruhige Seitenstraße nahe Savignyplatz und Kurfürstendamm.','ausstattung'=>'Echtholzparkett, Stuck, Balkon, Einbauküche, Aufzug, zwei Bäder.'],
['key'=>'kudamm-penthouse','title'=>'Penthouse mit Dachterrasse nahe Kurfürstendamm','objektart'=>'Wohnung','objekttyp'=>'Penthouse','nutzungsart'=>'Wohnen','vermarktungsart'=>'Kauf','ort'=>'Berlin-Wilmersdorf','plz'=>'10719','strasse'=>'Fasanenstraße','hausnummer'=>'71','wohnflaeche'=>162,'zimmer'=>5,'baujahr'=>2018,'kaufpreis'=>1490000,'kaltmiete'=>0,'warmmiete'=>0,'hausgeld'=>690,'terrassen'=>1,'badezimmer'=>2,'energieausweistyp'=>'Bedarfsausweis','endenergiebedarf'=>54.7,'endenergieverbrauch'=>0,'energieklasse'=>'B','heizung'=>'Fußbodenheizung','befeuerung'=>'Fernwärme','stellplatz'=>'Tiefgarage','beschreibung'=>'Lichtdurchflutetes Penthouse mit großzügigen Fensterflächen und weitläufiger Dachterrasse.','lage'=>'Zwischen Kurfürstendamm und Lietzenburger Straße in einer gefragten City-West-Lage.','ausstattung'=>'Dachterrasse, Fußbodenheizung, Natursteinbäder, Designküche, Lift, Tiefgarage.'],
['key'=>'zehlendorf-villa','title'=>'Architektenvilla im grünen Zehlendorf','objektart'=>'Haus','objekttyp'=>'Villa','nutzungsart'=>'Wohnen','vermarktungsart'=>'Kauf','ort'=>'Berlin-Zehlendorf','plz'=>'14169','strasse'=>'Argentinische Allee','hausnummer'=>'132','wohnflaeche'=>238,'nutzflaeche'=>74,'grundstuecksflaeche'=>946,'zimmer'=>7,'schlafzimmer'=>4,'badezimmer'=>3,'terrassen'=>2,'etagen'=>2,'baujahr'=>2006,'kaufpreis'=>1850000,'kaltmiete'=>0,'warmmiete'=>0,'fahrstuhl'=>0,'garten'=>1,'stellplatz'=>'Garage','beschreibung'=>'Freistehende Architektenvilla auf großzügigem Grundstück mit viel Privatsphäre.','lage'=>'Bevorzugte Wohnlage in Zehlendorf mit kurzen Wegen zum Schlachtensee.','ausstattung'=>'Kamin, zwei Terrassen, Garten, Garage, Fußbodenheizung, Keller.'],
['key'=>'prenzlauerberg-miete','title'=>'Moderne Mietwohnung im Prenzlauer Berg','objektart'=>'Wohnung','objekttyp'=>'Etagenwohnung','nutzungsart'=>'Wohnen','vermarktungsart'=>'Miete','ort'=>'Berlin-Prenzlauer Berg','plz'=>'10405','strasse'=>'Hufelandstraße','hausnummer'=>'22','wohnflaeche'=>96,'zimmer'=>3,'baujahr'=>2014,'kaufpreis'=>0,'kaltmiete'=>2150,'warmmiete'=>2480,'provisionsfrei'=>1,'courtage'=>'provisionsfrei','energieausweistyp'=>'Bedarfsausweis','endenergiebedarf'=>61.3,'endenergieverbrauch'=>0,'energieklasse'=>'B','befeuerung'=>'Fernwärme','beschreibung'=>'Helle Drei-Zimmer-Wohnung mit offenem Wohnbereich und sonnigem Balkon.','lage'=>'Nahe Kollwitzplatz mit Cafés, Wochenmarkt und sehr guter ÖPNV-Anbindung.','ausstattung'=>'Balkon, Einbauküche, Parkett, Aufzug, Keller, modernes Bad.'],
['key'=>'mitte-loft','title'=>'Urbanes Loft in Berlin-Mitte','objektart'=>'Wohnung','objekttyp'=>'Loft/Studio/Atelier','nutzungsart'=>'Wohnen','vermarktungsart'=>'Kauf','ort'=>'Berlin-Mitte','plz'=>'10115','strasse'=>'Chausseestraße','hausnummer'=>'95','wohnflaeche'=>118,'nutzflaeche'=>14,'zimmer'=>3,'schlafzimmer'=>1,'badezimmer'=>2,'baujahr'=>1910,'kaufpreis'=>1125000,'kaltmiete'=>0,'warmmiete'=>0,'hausgeld'=>525,'beschreibung'=>'Außergewöhnliches Loft mit offenem Grundriss, Industriecharakter und hochwertigen Einbauten.','lage'=>'Zentrale Lage zwischen Hauptbahnhof, Naturkundemuseum und Invalidenstraße.','ausstattung'=>'Loftfenster, Sichtmauerwerk, maßgefertigte Küche, zwei Bäder, Balkon, Aufzug.'],
['key'=>'kreuzberg-maisonette','title'=>'Maisonette mit Terrasse in Kreuzberg','objektart'=>'Wohnung','objekttyp'=>'Maisonette','nutzungsart'=>'Wohnen','vermarktungsart'=>'Kauf','ort'=>'Berlin-Kreuzberg','plz'=>'10961','strasse'=>'Bergmannstraße','hausnummer'=>'74','wohnflaeche'=>134,'nutzflaeche'=>9,'zimmer'=>4,'badezimmer'=>2,'terrassen'=>1,'etagen'=>2,'baujahr'=>2012,'kaufpreis'=>1095000,'kaltmiete'=>0,'warmmiete'=>0,'hausgeld'=>540,'heizung'=>'Fußbodenheizung','befeuerung'=>'Fernwärme','stellplatz'=>'Tiefgarage','beschreibung'=>'Moderne Maisonettewohnung über zwei Ebenen mit großzügiger Terrasse.','lage'=>'Im beliebten Bergmannkiez mit kurzen Wegen zu Viktoriapark und Mehringdamm.','ausstattung'=>'Terrasse, Fußbodenheizung, bodentiefe Fenster, Einbauküche, Tiefgarage.'],
['key'=>'grunewald-grundstueck','title'=>'Großzügiges Baugrundstück in Grunewald','objektart'=>'Grundstück','objekttyp'=>'Wohnen','nutzungsart'=>'Wohnen','vermarktungsart'=>'Kauf','ort'=>'Berlin-Grunewald','plz'=>'14193','strasse'=>'Koenigsallee','hausnummer'=>'38','wohnflaeche'=>0,'grundstuecksflaeche'=>1280,'zimmer'=>0,'schlafzimmer'=>0,'badezimmer'=>0,'balkone'=>0,'etagen'=>0,'baujahr'=>0,'kaufpreis'=>2450000,'kaltmiete'=>0,'warmmiete'=>0,'fahrstuhl'=>0,'keller'=>0,'garten'=>1,'energieausweistyp'=>'','endenergieverbrauch'=>0,'energieklasse'=>'','beschreibung'=>'Seltenes Baugrundstück in einer der exklusivsten Wohnlagen Berlins.','lage'=>'Ruhige und grüne Lage unweit des Grunewaldsees und der Königsallee.','ausstattung'=>'Erschlossenes Grundstück mit gewachsenem Baumbestand.'],
['key'=>'friedrichshain-office','title'=>'Repräsentative Bürofläche in Friedrichshain','objektart'=>'Büro/Praxen','objekttyp'=>'Bürofläche','nutzungsart'=>'Gewerbe','vermarktungsart'=>'Miete','ort'=>'Berlin-Friedrichshain','plz'=>'10243','strasse'=>'Warschauer Straße','hausnummer'=>'55','wohnflaeche'=>0,'nutzflaeche'=>286,'zimmer'=>8,'schlafzimmer'=>0,'badezimmer'=>2,'terrassen'=>1,'etagen'=>5,'baujahr'=>2019,'kaufpreis'=>0,'kaltmiete'=>7150,'warmmiete'=>8460,'courtage'=>'2,38 Monatsmieten inkl. MwSt.','befeuerung'=>'Fernwärme','stellplatz'=>'Tiefgarage','beschreibung'=>'Flexible Bürofläche mit moderner technischer Ausstattung und repräsentativem Empfangsbereich.','lage'=>'Direkt an der Mediaspree mit hervorragender Anbindung an S- und U-Bahn.','ausstattung'=>'Kühlung, Doppelboden, Glasfaser, Besprechungsräume, Teeküche, Terrasse.'],
['key'=>'koepenick-house','title'=>'Familienhaus nahe Müggelsee','objektart'=>'Haus','objekttyp'=>'Einfamilienhaus','nutzungsart'=>'Wohnen','vermarktungsart'=>'Kauf','ort'=>'Berlin-Köpenick','plz'=>'12587','strasse'=>'Müggelseedamm','hausnummer'=>'164','wohnflaeche'=>176,'nutzflaeche'=>52,'grundstuecksflaeche'=>720,'zimmer'=>6,'schlafzimmer'=>4,'badezimmer'=>2,'terrassen'=>1,'etagen'=>2,'baujahr'=>1998,'kaufpreis'=>985000,'kaltmiete'=>0,'warmmiete'=>0,'fahrstuhl'=>0,'garten'=>1,'stellplatz'=>'Garage','beschreibung'=>'Gepflegtes Einfamilienhaus mit familienfreundlichem Grundriss und Garten.','lage'=>'Grüne Wohnlage in Köpenick mit guter Infrastruktur und hohem Freizeitwert.','ausstattung'=>'Garten, Terrasse, Balkon, Garage, Keller, Kamin, Einbauküche.'],
['key'=>'schoeneberg-miete','title'=>'Elegante 4-Zimmer-Wohnung in Schöneberg','objektart'=>'Wohnung','objekttyp'=>'Etagenwohnung','nutzungsart'=>'Wohnen','vermarktungsart'=>'Miete','ort'=>'Berlin-Schöneberg','plz'=>'10781','strasse'=>'Motzstraße','hausnummer'=>'41','wohnflaeche'=>121,'zimmer'=>4,'schlafzimmer'=>3,'badezimmer'=>2,'baujahr'=>1912,'kaufpreis'=>0,'kaltmiete'=>2690,'warmmiete'=>3060,'provisionsfrei'=>1,'courtage'=>'provisionsfrei','beschreibung'=>'Großzügige Altbauwohnung mit vier gut geschnittenen Zimmern, Balkon und zwei modernen Bädern.','lage'=>'Zentral in Schöneberg zwischen Viktoria-Luise-Platz und Nollendorfplatz.','ausstattung'=>'Parkett, Balkon, Aufzug, Einbauküche, zwei Bäder, Keller.'],
];
return array_map(static fn($item) => array_replace($common, $item), $items);
}
}
new FRESH_OnOffice_Demo_Seeder();