mirror of
https://git.hexahost.dev/smueller/HexaHost-Frontend.git
synced 2026-06-02 13:28:43 +00:00
Compare commits
28 Commits
ci
...
b113bdeaa2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b113bdeaa2 | ||
|
|
5d2be60dfa | ||
|
|
62d0076799 | ||
|
|
e920fdfc8e | ||
|
|
5d953fda7b | ||
|
|
6ca4786955 | ||
|
|
b9bd339607 | ||
|
|
b893272d64 | ||
|
|
3dd707ab93 | ||
|
|
cc1a48943a | ||
|
|
dfc781f3ed | ||
|
|
d0e5baa443 | ||
|
|
8afba16905 | ||
|
|
96a5977283 | ||
|
|
ec8686761c | ||
|
|
d3da589a1d | ||
|
|
b6e268855e | ||
|
|
d02377c735 | ||
|
|
d62d6b576d | ||
|
|
2c0138f55d | ||
|
|
2074707c9d | ||
|
|
55f9fdd957 | ||
|
|
ab81d1c49f | ||
|
|
b40ad53d9c | ||
|
|
e5402189ea | ||
|
|
e544720900 | ||
| a5bba86db0 | |||
| d34dbbb079 |
@@ -2,7 +2,8 @@
|
|||||||
/**
|
/**
|
||||||
* HexaHost.de Produkt-Konfiguration
|
* HexaHost.de Produkt-Konfiguration
|
||||||
*
|
*
|
||||||
* Hier können Sie alle Preise und Produktinformationen zentral verwalten.
|
* Hier können Sie alle Preise, Shop-Links und Produktinformationen zentral verwalten.
|
||||||
|
* Pro Paket: shop_url (WHMCS/Warenkorb-Link, z. B. https://shop.hexahost.de/cart.php?a=add&pid=123)
|
||||||
* Nach Änderungen: npm run build && npm run deploy
|
* Nach Änderungen: npm run build && npm run deploy
|
||||||
*
|
*
|
||||||
* Verwendung in PHP-Seiten:
|
* Verwendung in PHP-Seiten:
|
||||||
@@ -30,6 +31,7 @@ $PRODUCTS['vpc'] = [
|
|||||||
'starter' => [
|
'starter' => [
|
||||||
'name' => 'VPC Starter',
|
'name' => 'VPC Starter',
|
||||||
'price' => '4,99',
|
'price' => '4,99',
|
||||||
|
'shop_url' => '',
|
||||||
'featured' => false,
|
'featured' => false,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'CPU Kerne', 'value' => '1 vCore'],
|
['label' => 'CPU Kerne', 'value' => '1 vCore'],
|
||||||
@@ -49,6 +51,7 @@ $PRODUCTS['vpc'] = [
|
|||||||
'business' => [
|
'business' => [
|
||||||
'name' => 'VPC Business',
|
'name' => 'VPC Business',
|
||||||
'price' => '9,99',
|
'price' => '9,99',
|
||||||
|
'shop_url' => '',
|
||||||
'featured' => true,
|
'featured' => true,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'CPU Kerne', 'value' => '2 vCores'],
|
['label' => 'CPU Kerne', 'value' => '2 vCores'],
|
||||||
@@ -69,6 +72,7 @@ $PRODUCTS['vpc'] = [
|
|||||||
'professional' => [
|
'professional' => [
|
||||||
'name' => 'VPC Professional',
|
'name' => 'VPC Professional',
|
||||||
'price' => '19,99',
|
'price' => '19,99',
|
||||||
|
'shop_url' => '',
|
||||||
'featured' => false,
|
'featured' => false,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'CPU Kerne', 'value' => '4 vCores'],
|
['label' => 'CPU Kerne', 'value' => '4 vCores'],
|
||||||
@@ -90,6 +94,7 @@ $PRODUCTS['vpc'] = [
|
|||||||
'enterprise' => [
|
'enterprise' => [
|
||||||
'name' => 'VPC Enterprise',
|
'name' => 'VPC Enterprise',
|
||||||
'price' => '39,99',
|
'price' => '39,99',
|
||||||
|
'shop_url' => '',
|
||||||
'featured' => false,
|
'featured' => false,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'CPU Kerne', 'value' => '8 vCores'],
|
['label' => 'CPU Kerne', 'value' => '8 vCores'],
|
||||||
@@ -132,6 +137,7 @@ $PRODUCTS['vps'] = [
|
|||||||
'starter' => [
|
'starter' => [
|
||||||
'name' => 'VPS Starter',
|
'name' => 'VPS Starter',
|
||||||
'price' => '9,99',
|
'price' => '9,99',
|
||||||
|
'shop_url' => '',
|
||||||
'featured' => false,
|
'featured' => false,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'CPU Kerne', 'value' => '1 vCore'],
|
['label' => 'CPU Kerne', 'value' => '1 vCore'],
|
||||||
@@ -151,6 +157,7 @@ $PRODUCTS['vps'] = [
|
|||||||
'business' => [
|
'business' => [
|
||||||
'name' => 'VPS Business',
|
'name' => 'VPS Business',
|
||||||
'price' => '19,99',
|
'price' => '19,99',
|
||||||
|
'shop_url' => '',
|
||||||
'featured' => true,
|
'featured' => true,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'CPU Kerne', 'value' => '2 vCores'],
|
['label' => 'CPU Kerne', 'value' => '2 vCores'],
|
||||||
@@ -171,6 +178,7 @@ $PRODUCTS['vps'] = [
|
|||||||
'professional' => [
|
'professional' => [
|
||||||
'name' => 'VPS Professional',
|
'name' => 'VPS Professional',
|
||||||
'price' => '39,99',
|
'price' => '39,99',
|
||||||
|
'shop_url' => '',
|
||||||
'featured' => false,
|
'featured' => false,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'CPU Kerne', 'value' => '4 vCores'],
|
['label' => 'CPU Kerne', 'value' => '4 vCores'],
|
||||||
@@ -192,6 +200,7 @@ $PRODUCTS['vps'] = [
|
|||||||
'enterprise' => [
|
'enterprise' => [
|
||||||
'name' => 'VPS Enterprise',
|
'name' => 'VPS Enterprise',
|
||||||
'price' => '79,99',
|
'price' => '79,99',
|
||||||
|
'shop_url' => '',
|
||||||
'featured' => false,
|
'featured' => false,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'CPU Kerne', 'value' => '8 vCores'],
|
['label' => 'CPU Kerne', 'value' => '8 vCores'],
|
||||||
@@ -234,6 +243,7 @@ $PRODUCTS['mail-gateway'] = [
|
|||||||
'starter' => [
|
'starter' => [
|
||||||
'name' => 'Mail Starter',
|
'name' => 'Mail Starter',
|
||||||
'price' => '4,99',
|
'price' => '4,99',
|
||||||
|
'shop_url' => '',
|
||||||
'featured' => false,
|
'featured' => false,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'Postfächer', 'value' => '5'],
|
['label' => 'Postfächer', 'value' => '5'],
|
||||||
@@ -252,6 +262,7 @@ $PRODUCTS['mail-gateway'] = [
|
|||||||
'business' => [
|
'business' => [
|
||||||
'name' => 'Mail Business',
|
'name' => 'Mail Business',
|
||||||
'price' => '14,99',
|
'price' => '14,99',
|
||||||
|
'shop_url' => '',
|
||||||
'featured' => true,
|
'featured' => true,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'Postfächer', 'value' => '25'],
|
['label' => 'Postfächer', 'value' => '25'],
|
||||||
@@ -272,6 +283,7 @@ $PRODUCTS['mail-gateway'] = [
|
|||||||
'professional' => [
|
'professional' => [
|
||||||
'name' => 'Mail Professional',
|
'name' => 'Mail Professional',
|
||||||
'price' => '29,99',
|
'price' => '29,99',
|
||||||
|
'shop_url' => '',
|
||||||
'featured' => false,
|
'featured' => false,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'Postfächer', 'value' => '100'],
|
['label' => 'Postfächer', 'value' => '100'],
|
||||||
@@ -293,6 +305,7 @@ $PRODUCTS['mail-gateway'] = [
|
|||||||
'enterprise' => [
|
'enterprise' => [
|
||||||
'name' => 'Mail Enterprise',
|
'name' => 'Mail Enterprise',
|
||||||
'price' => '59,99',
|
'price' => '59,99',
|
||||||
|
'shop_url' => '',
|
||||||
'featured' => false,
|
'featured' => false,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'Postfächer', 'value' => 'Unbegrenzt'],
|
['label' => 'Postfächer', 'value' => 'Unbegrenzt'],
|
||||||
@@ -336,6 +349,7 @@ $PRODUCTS['webhosting'] = [
|
|||||||
'starter' => [
|
'starter' => [
|
||||||
'name' => 'Webhosting Starter',
|
'name' => 'Webhosting Starter',
|
||||||
'price' => '4,99',
|
'price' => '4,99',
|
||||||
|
'shop_url' => 'https://shop.hexahost.de/store/webserver/webhosting-starter',
|
||||||
'featured' => false,
|
'featured' => false,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'Webspace', 'value' => '10 GB'],
|
['label' => 'Webspace', 'value' => '10 GB'],
|
||||||
@@ -358,6 +372,7 @@ $PRODUCTS['webhosting'] = [
|
|||||||
'business' => [
|
'business' => [
|
||||||
'name' => 'Webhosting Business',
|
'name' => 'Webhosting Business',
|
||||||
'price' => '7,99',
|
'price' => '7,99',
|
||||||
|
'shop_url' => 'https://shop.hexahost.de/store/webserver/webhosting-business',
|
||||||
'featured' => true,
|
'featured' => true,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'Webspace', 'value' => '30 GB'],
|
['label' => 'Webspace', 'value' => '30 GB'],
|
||||||
@@ -380,6 +395,7 @@ $PRODUCTS['webhosting'] = [
|
|||||||
'professional' => [
|
'professional' => [
|
||||||
'name' => 'Webhosting Professional',
|
'name' => 'Webhosting Professional',
|
||||||
'price' => '9,99',
|
'price' => '9,99',
|
||||||
|
'shop_url' => 'https://shop.hexahost.de/store/webserver/webhosting-professional',
|
||||||
'featured' => false,
|
'featured' => false,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'Webspace', 'value' => '50 GB'],
|
['label' => 'Webspace', 'value' => '50 GB'],
|
||||||
@@ -402,6 +418,7 @@ $PRODUCTS['webhosting'] = [
|
|||||||
'enterprise' => [
|
'enterprise' => [
|
||||||
'name' => 'Webhosting Enterprise',
|
'name' => 'Webhosting Enterprise',
|
||||||
'price' => '29,99',
|
'price' => '29,99',
|
||||||
|
'shop_url' => '',
|
||||||
'featured' => false,
|
'featured' => false,
|
||||||
'specs' => [
|
'specs' => [
|
||||||
['label' => 'Webspace', 'value' => '200 GB'],
|
['label' => 'Webspace', 'value' => '200 GB'],
|
||||||
@@ -485,6 +502,38 @@ function formatPrice($price, $withCurrency = true) {
|
|||||||
return $withCurrency ? $price . '€' : $price;
|
return $withCurrency ? $price . '€' : $price;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bestell-Link für ein Paket (Online-Shop oder Kontaktformular)
|
||||||
|
*/
|
||||||
|
function getOrderUrl($productId, $packageId) {
|
||||||
|
$package = getPackage($productId, $packageId);
|
||||||
|
if ($package && !empty($package['shop_url'])) {
|
||||||
|
return $package['shop_url'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf('contact.php?package=%s-%s', $productId, $packageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bestell-Link für CTA (beliebtes Paket oder erstes Paket)
|
||||||
|
*/
|
||||||
|
function getProductOrderUrl($productId) {
|
||||||
|
$packages = getProductPackages($productId);
|
||||||
|
|
||||||
|
foreach ($packages as $packageId => $package) {
|
||||||
|
if (!empty($package['featured'])) {
|
||||||
|
return getOrderUrl($productId, $packageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$firstPackageId = array_key_first($packages);
|
||||||
|
if ($firstPackageId !== null) {
|
||||||
|
return getOrderUrl($productId, $firstPackageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf('contact.php?product=%s', $productId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generiert HTML für eine Paket-Karte
|
* Generiert HTML für eine Paket-Karte
|
||||||
*/
|
*/
|
||||||
@@ -522,7 +571,7 @@ function renderPackageCard($productId, $packageId, $package) {
|
|||||||
<div class="package-features">
|
<div class="package-features">
|
||||||
%s
|
%s
|
||||||
</div>
|
</div>
|
||||||
<a href="contact.php?package=%s-%s" class="btn btn-primary">Jetzt bestellen</a>
|
<a href="%s" class="btn btn-primary">Jetzt bestellen</a>
|
||||||
</div>',
|
</div>',
|
||||||
$featuredClass,
|
$featuredClass,
|
||||||
$featuredBadge,
|
$featuredBadge,
|
||||||
@@ -530,8 +579,7 @@ function renderPackageCard($productId, $packageId, $package) {
|
|||||||
$package['price'],
|
$package['price'],
|
||||||
$specsHtml,
|
$specsHtml,
|
||||||
$featuresHtml,
|
$featuresHtml,
|
||||||
$productId,
|
htmlspecialchars(getOrderUrl($productId, $packageId), ENT_QUOTES, 'UTF-8')
|
||||||
$packageId
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,3 +15,94 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Legal pages: plain white content with black text */
|
||||||
|
.legal-hero,
|
||||||
|
.legal-content {
|
||||||
|
background: #ffffff;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-hero {
|
||||||
|
margin-top: 70px;
|
||||||
|
padding: 2rem 0 1.5rem;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-content {
|
||||||
|
padding-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-hero-title {
|
||||||
|
background: none;
|
||||||
|
-webkit-text-fill-color: #000000;
|
||||||
|
color: #000000;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-hero-description,
|
||||||
|
.legal-section h2,
|
||||||
|
.legal-section h3,
|
||||||
|
.legal-block p,
|
||||||
|
.legal-block li,
|
||||||
|
.breadcrumb,
|
||||||
|
.breadcrumb span {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-section,
|
||||||
|
.legal-section.glass-card {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
backdrop-filter: none;
|
||||||
|
-webkit-backdrop-filter: none;
|
||||||
|
border-radius: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-section:hover,
|
||||||
|
.legal-section.glass-card:hover {
|
||||||
|
transform: none;
|
||||||
|
box-shadow: none;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-content .glass-card:hover {
|
||||||
|
transform: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-section h2 {
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-block a,
|
||||||
|
.breadcrumb a {
|
||||||
|
color: #0b57d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legal-block a:hover,
|
||||||
|
.breadcrumb a:hover {
|
||||||
|
color: #0b57d0;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure absolutely no hover effects on legal text/content */
|
||||||
|
.legal-hero *,
|
||||||
|
.legal-content *,
|
||||||
|
.legal-hero *:hover,
|
||||||
|
.legal-content *:hover,
|
||||||
|
.legal-hero *:focus,
|
||||||
|
.legal-content *:focus,
|
||||||
|
.legal-hero *:active,
|
||||||
|
.legal-content *:active {
|
||||||
|
transform: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
text-shadow: none !important;
|
||||||
|
transition: none !important;
|
||||||
|
animation: none !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -166,8 +166,8 @@ includeHeader($page_title, $page_description, $current_page);
|
|||||||
<h2><?php echo htmlspecialchars($product['cta_title'] ?? ('Bereit für ' . $product['name'] . '?')); ?></h2>
|
<h2><?php echo htmlspecialchars($product['cta_title'] ?? ('Bereit für ' . $product['name'] . '?')); ?></h2>
|
||||||
<p><?php echo htmlspecialchars($product['cta_description'] ?? ('Starten Sie noch heute mit ' . $product['name'])); ?></p>
|
<p><?php echo htmlspecialchars($product['cta_description'] ?? ('Starten Sie noch heute mit ' . $product['name'])); ?></p>
|
||||||
<div class="cta-actions">
|
<div class="cta-actions">
|
||||||
<a href="contact.php?product=mail-gateway" class="btn btn-primary">Jetzt bestellen</a>
|
<a href="<?php echo htmlspecialchars(getProductOrderUrl('mail-gateway'), ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-primary">Jetzt bestellen</a>
|
||||||
<a href="/contact" class="btn btn-secondary">Beratung anfordern</a>
|
<a href="contact.php" class="btn btn-secondary">Beratung anfordern</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -166,8 +166,8 @@ includeHeader($page_title, $page_description, $current_page);
|
|||||||
<h2><?php echo htmlspecialchars($product['cta_title'] ?? ('Bereit für ' . $product['name'] . '?')); ?></h2>
|
<h2><?php echo htmlspecialchars($product['cta_title'] ?? ('Bereit für ' . $product['name'] . '?')); ?></h2>
|
||||||
<p><?php echo htmlspecialchars($product['cta_description'] ?? ('Starten Sie noch heute mit ' . $product['name'])); ?></p>
|
<p><?php echo htmlspecialchars($product['cta_description'] ?? ('Starten Sie noch heute mit ' . $product['name'])); ?></p>
|
||||||
<div class="cta-actions">
|
<div class="cta-actions">
|
||||||
<a href="contact.php?product=vpc" class="btn btn-primary">Jetzt bestellen</a>
|
<a href="<?php echo htmlspecialchars(getProductOrderUrl('vpc'), ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-primary">Jetzt bestellen</a>
|
||||||
<a href="/contact" class="btn btn-secondary">Beratung anfordern</a>
|
<a href="contact.php" class="btn btn-secondary">Beratung anfordern</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -171,8 +171,8 @@ includeHeader($page_title, $page_description, $current_page);
|
|||||||
<h2><?php echo htmlspecialchars($product['cta_title'] ?? ('Bereit für ' . $product['name'] . '?')); ?></h2>
|
<h2><?php echo htmlspecialchars($product['cta_title'] ?? ('Bereit für ' . $product['name'] . '?')); ?></h2>
|
||||||
<p><?php echo htmlspecialchars($product['cta_description'] ?? ('Starten Sie noch heute mit ' . $product['name'])); ?></p>
|
<p><?php echo htmlspecialchars($product['cta_description'] ?? ('Starten Sie noch heute mit ' . $product['name'])); ?></p>
|
||||||
<div class="cta-actions">
|
<div class="cta-actions">
|
||||||
<a href="contact.php?product=vps" class="btn btn-primary">Jetzt bestellen</a>
|
<a href="<?php echo htmlspecialchars(getProductOrderUrl('vps'), ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-primary">Jetzt bestellen</a>
|
||||||
<a href="/contact" class="btn btn-secondary">Beratung anfordern</a>
|
<a href="contact.php" class="btn btn-secondary">Beratung anfordern</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ includeHeader($page_title, $page_description, $current_page);
|
|||||||
<polyline points="10,9 9,9 8,9"/>
|
<polyline points="10,9 9,9 8,9"/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3>cPanel/Webmin</h3>
|
<h3>Plesk</h3>
|
||||||
<p>Benutzerfreundliche Verwaltungsoberfläche für einfache Website-Verwaltung und E-Mail-Konfiguration.</p>
|
<p>Benutzerfreundliche Verwaltungsoberfläche für einfache Website-Verwaltung und E-Mail-Konfiguration.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-card glass-card">
|
<div class="detail-card glass-card">
|
||||||
@@ -170,8 +170,8 @@ includeHeader($page_title, $page_description, $current_page);
|
|||||||
<h2><?php echo htmlspecialchars($product['cta_title'] ?? ('Bereit für ' . $product['name'] . '?')); ?></h2>
|
<h2><?php echo htmlspecialchars($product['cta_title'] ?? ('Bereit für ' . $product['name'] . '?')); ?></h2>
|
||||||
<p><?php echo htmlspecialchars($product['cta_description'] ?? ('Starten Sie noch heute mit ' . $product['name'])); ?></p>
|
<p><?php echo htmlspecialchars($product['cta_description'] ?? ('Starten Sie noch heute mit ' . $product['name'])); ?></p>
|
||||||
<div class="cta-actions">
|
<div class="cta-actions">
|
||||||
<a href="contact.php?product=webhosting" class="btn btn-primary">Jetzt bestellen</a>
|
<a href="<?php echo htmlspecialchars(getProductOrderUrl('webhosting'), ENT_QUOTES, 'UTF-8'); ?>" class="btn btn-primary">Jetzt bestellen</a>
|
||||||
<a href="/contact" class="btn btn-secondary">Beratung anfordern</a>
|
<a href="contact.php" class="btn btn-secondary">Beratung anfordern</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,185 +0,0 @@
|
|||||||
#Requires -Version 5.1
|
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Erstellt einen Production-Build und veroeffentlicht ihn auf den Branch main.
|
|
||||||
|
|
||||||
.DESCRIPTION
|
|
||||||
1. Wechselt auf main und setzt ihn auf den Stand von dev
|
|
||||||
2. Entfernt Kommentare, minifiziert CSS, obfuskiert JavaScript
|
|
||||||
3. Committet und pusht main (optional)
|
|
||||||
4. Wechselt zurueck auf dev (Quellcode bleibt unveraendert)
|
|
||||||
|
|
||||||
.PARAMETER Push
|
|
||||||
Pusht main nach origin (Standard: nur lokaler Commit)
|
|
||||||
|
|
||||||
.PARAMETER DryRun
|
|
||||||
Fuehrt Git-Schritte nur simuliert aus (Build wird trotzdem erstellt)
|
|
||||||
|
|
||||||
.PARAMETER AllowDirty
|
|
||||||
Erlaubt uncommittete Aenderungen
|
|
||||||
|
|
||||||
.PARAMETER Message
|
|
||||||
Commit-Nachricht fuer den Production-Build
|
|
||||||
|
|
||||||
.EXAMPLE
|
|
||||||
.\scripts\publish-to-main.ps1
|
|
||||||
|
|
||||||
.EXAMPLE
|
|
||||||
.\scripts\publish-to-main.ps1 -Push
|
|
||||||
#>
|
|
||||||
[CmdletBinding()]
|
|
||||||
param(
|
|
||||||
[switch]$Push,
|
|
||||||
[switch]$DryRun,
|
|
||||||
[switch]$AllowDirty,
|
|
||||||
[string]$Message = ""
|
|
||||||
)
|
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
|
||||||
$Root = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
|
|
||||||
$BuildDir = Join-Path $Root "scripts\build"
|
|
||||||
$OriginalBranch = ""
|
|
||||||
|
|
||||||
function Write-Step([string]$Text) {
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "==> $Text" -ForegroundColor Cyan
|
|
||||||
}
|
|
||||||
|
|
||||||
function Ensure-GitClean {
|
|
||||||
$status = git -C $Root status --porcelain
|
|
||||||
if ($status) {
|
|
||||||
throw "Uncommittete Aenderungen im Repository. Bitte zuerst committen oder stashen."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Resolve-NodeTool([string]$ToolName) {
|
|
||||||
$command = Get-Command $ToolName -ErrorAction SilentlyContinue
|
|
||||||
if ($command) {
|
|
||||||
return $command.Source
|
|
||||||
}
|
|
||||||
|
|
||||||
$candidates = @(
|
|
||||||
(Join-Path $env:ProgramFiles "nodejs\$ToolName.cmd"),
|
|
||||||
(Join-Path ${env:ProgramFiles(x86)} "nodejs\$ToolName.cmd"),
|
|
||||||
(Join-Path $env:LOCALAPPDATA "Programs\nodejs\$ToolName.cmd"),
|
|
||||||
"c:\Program Files\cursor\resources\app\resources\helpers\node.exe"
|
|
||||||
)
|
|
||||||
|
|
||||||
foreach ($candidate in $candidates) {
|
|
||||||
if ($ToolName -eq "node" -and (Test-Path $candidate)) {
|
|
||||||
return $candidate
|
|
||||||
}
|
|
||||||
if ($ToolName -ne "node" -and (Test-Path $candidate)) {
|
|
||||||
return $candidate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $null
|
|
||||||
}
|
|
||||||
|
|
||||||
function Ensure-Node {
|
|
||||||
$script:NodeExe = Resolve-NodeTool "node"
|
|
||||||
$script:NpmExe = Resolve-NodeTool "npm"
|
|
||||||
|
|
||||||
if (-not $script:NodeExe) {
|
|
||||||
throw "Node.js ist nicht installiert. Bitte Node.js 18+ installieren: https://nodejs.org/"
|
|
||||||
}
|
|
||||||
if (-not $script:NpmExe) {
|
|
||||||
throw "npm wurde nicht gefunden. Bitte Node.js inkl. npm installieren und PATH setzen."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Set-Location $Root
|
|
||||||
Ensure-Node
|
|
||||||
if (-not $AllowDirty) {
|
|
||||||
Ensure-GitClean
|
|
||||||
} else {
|
|
||||||
Write-Warning "AllowDirty aktiv - uncommittete Aenderungen werden mit veroeffentlicht."
|
|
||||||
}
|
|
||||||
|
|
||||||
$OriginalBranch = (git branch --show-current).Trim()
|
|
||||||
if ($OriginalBranch -ne "dev") {
|
|
||||||
Write-Warning "Empfohlen: Auf Branch 'dev' starten (aktuell: $OriginalBranch)"
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([string]::IsNullOrWhiteSpace($Message)) {
|
|
||||||
$Message = "chore(release): production build $(Get-Date -Format 'yyyy-MM-dd HH:mm')"
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Step "Installiere Build-Abhaengigkeiten"
|
|
||||||
Set-Location $BuildDir
|
|
||||||
if (-not $DryRun) {
|
|
||||||
& $NpmExe ci --no-fund --no-audit
|
|
||||||
if ($LASTEXITCODE -ne 0) { throw "npm ci fehlgeschlagen" }
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Step "Wechsle auf main und synchronisiere mit dev"
|
|
||||||
Set-Location $Root
|
|
||||||
if ($DryRun) {
|
|
||||||
Write-Host '[DryRun] git checkout main'
|
|
||||||
Write-Host '[DryRun] git reset --hard dev'
|
|
||||||
} else {
|
|
||||||
git checkout main
|
|
||||||
git reset --hard dev
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Step "Production-Build (Kommentare entfernen, JS obfuscaten)"
|
|
||||||
Set-Location $BuildDir
|
|
||||||
if ($DryRun) {
|
|
||||||
Write-Host '[DryRun] npm run build:in-place'
|
|
||||||
} else {
|
|
||||||
& $NpmExe run build:in-place
|
|
||||||
if ($LASTEXITCODE -ne 0) { throw "Production-Build fehlgeschlagen" }
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Step "Production-Build committen"
|
|
||||||
Set-Location $Root
|
|
||||||
if ($DryRun) {
|
|
||||||
Write-Host '[DryRun] git add -A'
|
|
||||||
Write-Host ('[DryRun] git commit -m "' + $Message + '"')
|
|
||||||
} else {
|
|
||||||
git add -A
|
|
||||||
$null = git diff --cached --quiet
|
|
||||||
if ($LASTEXITCODE -eq 0) {
|
|
||||||
Write-Warning "Keine Build-Aenderungen - nichts zu committen."
|
|
||||||
} else {
|
|
||||||
git commit -m $Message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($Push) {
|
|
||||||
Write-Step "Push nach origin/main"
|
|
||||||
if ($DryRun) {
|
|
||||||
Write-Host '[DryRun] git push origin main'
|
|
||||||
} else {
|
|
||||||
git push origin main
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Write-Host "Hinweis: Ohne -Push wurde nur lokal auf main gebaut." -ForegroundColor Yellow
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Step "Zurueck auf $OriginalBranch"
|
|
||||||
if (-not $DryRun) {
|
|
||||||
if ([string]::IsNullOrWhiteSpace($OriginalBranch)) {
|
|
||||||
git checkout dev
|
|
||||||
} else {
|
|
||||||
git checkout $OriginalBranch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host "Production-Release abgeschlossen." -ForegroundColor Green
|
|
||||||
if (-not $Push -and -not $DryRun) {
|
|
||||||
Write-Host "Zum Veroeffentlichen: git push origin main" -ForegroundColor Yellow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
Write-Host ""
|
|
||||||
Write-Host ('FEHLER: ' + $_.Exception.Message) -ForegroundColor Red
|
|
||||||
Set-Location $Root
|
|
||||||
if ($OriginalBranch -and -not $DryRun) {
|
|
||||||
git checkout $OriginalBranch 2>$null
|
|
||||||
}
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
#
|
|
||||||
# Erstellt einen Production-Build und veröffentlicht ihn auf den Branch main.
|
|
||||||
#
|
|
||||||
# 1. Wechselt auf main und setzt ihn auf den Stand von dev
|
|
||||||
# 2. Entfernt Kommentare, minifiziert CSS, obfuskiert JavaScript
|
|
||||||
# 3. Committet und pusht main (optional)
|
|
||||||
# 4. Wechselt zurück auf den ursprünglichen Branch (dev bleibt unverändert)
|
|
||||||
#
|
|
||||||
# Nutzung:
|
|
||||||
# ./scripts/publish-to-main.sh
|
|
||||||
# ./scripts/publish-to-main.sh --push
|
|
||||||
# ./scripts/publish-to-main.sh --dry-run
|
|
||||||
# ./scripts/publish-to-main.sh --allow-dirty --message "chore(release): v1.2"
|
|
||||||
#
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
PUSH=false
|
|
||||||
DRY_RUN=false
|
|
||||||
ALLOW_DIRTY=false
|
|
||||||
MESSAGE=""
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat <<'EOF'
|
|
||||||
Usage: publish-to-main.sh [OPTIONS]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--push Push nach origin/main
|
|
||||||
--dry-run Git-Schritte nur anzeigen (Build wird ausgeführt)
|
|
||||||
--allow-dirty Uncommittete Änderungen erlauben
|
|
||||||
--message TEXT Commit-Nachricht
|
|
||||||
-h, --help Hilfe anzeigen
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
--push)
|
|
||||||
PUSH=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--dry-run)
|
|
||||||
DRY_RUN=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--allow-dirty)
|
|
||||||
ALLOW_DIRTY=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--message)
|
|
||||||
MESSAGE="${2:-}"
|
|
||||||
shift 2
|
|
||||||
;;
|
|
||||||
-h|--help)
|
|
||||||
usage
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Unbekannte Option: $1" >&2
|
|
||||||
usage >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
||||||
BUILD_DIR="$ROOT/scripts/build"
|
|
||||||
ORIGINAL_BRANCH=""
|
|
||||||
|
|
||||||
step() {
|
|
||||||
echo ""
|
|
||||||
echo "==> $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
require_command() {
|
|
||||||
if ! command -v "$1" >/dev/null 2>&1; then
|
|
||||||
echo "FEHLER: '$1' nicht gefunden. Bitte installieren und PATH setzen." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure_git_clean() {
|
|
||||||
if [[ -n "$(git -C "$ROOT" status --porcelain)" ]]; then
|
|
||||||
echo "FEHLER: Uncommittete Änderungen. Bitte zuerst committen oder stashen." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup_on_error() {
|
|
||||||
echo ""
|
|
||||||
echo "FEHLER: Abgebrochen." >&2
|
|
||||||
cd "$ROOT" || true
|
|
||||||
if [[ -n "$ORIGINAL_BRANCH" && "$DRY_RUN" == false ]]; then
|
|
||||||
git checkout "$ORIGINAL_BRANCH" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
trap cleanup_on_error ERR
|
|
||||||
|
|
||||||
require_command node
|
|
||||||
require_command npm
|
|
||||||
require_command git
|
|
||||||
|
|
||||||
cd "$ROOT"
|
|
||||||
|
|
||||||
if [[ "$ALLOW_DIRTY" == false ]]; then
|
|
||||||
ensure_git_clean
|
|
||||||
else
|
|
||||||
echo "WARNUNG: --allow-dirty aktiv – uncommittete Änderungen werden mit veröffentlicht." >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
ORIGINAL_BRANCH="$(git branch --show-current | tr -d '[:space:]')"
|
|
||||||
if [[ "$ORIGINAL_BRANCH" != "dev" ]]; then
|
|
||||||
echo "WARNUNG: Empfohlen auf Branch 'dev' zu starten (aktuell: ${ORIGINAL_BRANCH:-detached})" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "$MESSAGE" ]]; then
|
|
||||||
MESSAGE="chore(release): production build $(date '+%Y-%m-%d %H:%M')"
|
|
||||||
fi
|
|
||||||
|
|
||||||
step "Installiere Build-Abhängigkeiten"
|
|
||||||
cd "$BUILD_DIR"
|
|
||||||
if [[ "$DRY_RUN" == false ]]; then
|
|
||||||
npm ci --no-fund --no-audit
|
|
||||||
fi
|
|
||||||
|
|
||||||
step "Wechsle auf main und synchronisiere mit dev"
|
|
||||||
cd "$ROOT"
|
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
|
||||||
echo "[DryRun] git checkout main"
|
|
||||||
echo "[DryRun] git reset --hard dev"
|
|
||||||
else
|
|
||||||
git checkout main
|
|
||||||
git reset --hard dev
|
|
||||||
fi
|
|
||||||
|
|
||||||
step "Production-Build (Kommentare entfernen, JS obfuscaten)"
|
|
||||||
cd "$BUILD_DIR"
|
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
|
||||||
echo "[DryRun] npm run build:in-place"
|
|
||||||
else
|
|
||||||
npm run build:in-place
|
|
||||||
fi
|
|
||||||
|
|
||||||
step "Production-Build committen"
|
|
||||||
cd "$ROOT"
|
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
|
||||||
echo "[DryRun] git add -A"
|
|
||||||
echo "[DryRun] git commit -m \"$MESSAGE\""
|
|
||||||
else
|
|
||||||
git add -A
|
|
||||||
if git diff --cached --quiet; then
|
|
||||||
echo "WARNUNG: Keine Build-Änderungen – nichts zu committen." >&2
|
|
||||||
else
|
|
||||||
git commit -m "$MESSAGE"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$PUSH" == true ]]; then
|
|
||||||
step "Push nach origin/main"
|
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
|
||||||
echo "[DryRun] git push origin main"
|
|
||||||
else
|
|
||||||
git push origin main
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "Hinweis: Ohne --push wurde nur lokal auf main gebaut."
|
|
||||||
fi
|
|
||||||
|
|
||||||
step "Zurück auf ${ORIGINAL_BRANCH:-dev}"
|
|
||||||
if [[ "$DRY_RUN" == false ]]; then
|
|
||||||
if [[ -n "$ORIGINAL_BRANCH" ]]; then
|
|
||||||
git checkout "$ORIGINAL_BRANCH"
|
|
||||||
else
|
|
||||||
git checkout dev
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
trap - ERR
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Production-Release abgeschlossen."
|
|
||||||
if [[ "$PUSH" == false && "$DRY_RUN" == false ]]; then
|
|
||||||
echo "Zum Veröffentlichen: git push origin main"
|
|
||||||
fi
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
#Requires -Version 5.1
|
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Erstellt ein Production-Bundle unter dist/ (ohne Branch-Wechsel).
|
|
||||||
#>
|
|
||||||
[CmdletBinding()]
|
|
||||||
param(
|
|
||||||
[switch]$InPlace
|
|
||||||
)
|
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
|
||||||
$Root = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
|
|
||||||
$BuildDir = Join-Path $Root "scripts\build"
|
|
||||||
|
|
||||||
function Resolve-NodeTool([string]$ToolName) {
|
|
||||||
$command = Get-Command $ToolName -ErrorAction SilentlyContinue
|
|
||||||
if ($command) { return $command.Source }
|
|
||||||
|
|
||||||
$candidates = @(
|
|
||||||
(Join-Path $env:ProgramFiles "nodejs\$ToolName.cmd"),
|
|
||||||
(Join-Path ${env:ProgramFiles(x86)} "nodejs\$ToolName.cmd")
|
|
||||||
)
|
|
||||||
|
|
||||||
foreach ($candidate in $candidates) {
|
|
||||||
if (Test-Path $candidate) { return $candidate }
|
|
||||||
}
|
|
||||||
|
|
||||||
return $null
|
|
||||||
}
|
|
||||||
|
|
||||||
$npm = Resolve-NodeTool "npm"
|
|
||||||
if (-not $npm) {
|
|
||||||
throw "npm nicht gefunden. Bitte Node.js installieren."
|
|
||||||
}
|
|
||||||
|
|
||||||
Set-Location $BuildDir
|
|
||||||
& $npm ci --no-fund --no-audit
|
|
||||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
|
||||||
|
|
||||||
if ($InPlace) {
|
|
||||||
& $npm run build:in-place
|
|
||||||
} else {
|
|
||||||
& $npm run build
|
|
||||||
}
|
|
||||||
|
|
||||||
exit $LASTEXITCODE
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
#
|
|
||||||
# Erstellt ein Production-Bundle unter dist/ (ohne Branch-Wechsel).
|
|
||||||
#
|
|
||||||
# Nutzung:
|
|
||||||
# ./scripts/run-build.sh
|
|
||||||
# ./scripts/run-build.sh --in-place
|
|
||||||
#
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
IN_PLACE=false
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat <<'EOF'
|
|
||||||
Usage: run-build.sh [OPTIONS]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--in-place Build direkt im Repository (statt dist/)
|
|
||||||
-h, --help Hilfe anzeigen
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
--in-place)
|
|
||||||
IN_PLACE=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-h|--help)
|
|
||||||
usage
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Unbekannte Option: $1" >&2
|
|
||||||
usage >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
||||||
BUILD_DIR="$ROOT/scripts/build"
|
|
||||||
|
|
||||||
if ! command -v npm >/dev/null 2>&1; then
|
|
||||||
echo "FEHLER: npm nicht gefunden. Bitte Node.js installieren." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd "$BUILD_DIR"
|
|
||||||
npm ci --no-fund --no-audit
|
|
||||||
|
|
||||||
if [[ "$IN_PLACE" == true ]]; then
|
|
||||||
npm run build:in-place
|
|
||||||
else
|
|
||||||
npm run build
|
|
||||||
fi
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* HexaHost.de E-Mail Test (nur CLI oder lokale Entwicklung)
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (PHP_SAPI !== 'cli') {
|
|
||||||
$remoteAddr = $_SERVER['REMOTE_ADDR'] ?? '';
|
|
||||||
$isLocal = in_array($remoteAddr, ['127.0.0.1', '::1'], true)
|
|
||||||
|| filter_var($remoteAddr, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false;
|
|
||||||
|
|
||||||
if (!$isLocal) {
|
|
||||||
http_response_code(403);
|
|
||||||
exit('Forbidden');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once __DIR__ . '/../backend/config/mail-config.php';
|
|
||||||
|
|
||||||
function testEmail() {
|
|
||||||
$config = getHexaHostConfig();
|
|
||||||
|
|
||||||
$subject = '[HexaHost.de] Test-E-Mail';
|
|
||||||
$message = "Test-E-Mail von HexaHost.de\n\n";
|
|
||||||
$message .= "Zeitstempel: " . date('d.m.Y H:i:s') . "\n";
|
|
||||||
|
|
||||||
$headers = [
|
|
||||||
'From: ' . $config['from_name'] . ' <' . $config['from_email'] . '>',
|
|
||||||
'MIME-Version: 1.0',
|
|
||||||
'Content-Type: text/plain; charset=UTF-8',
|
|
||||||
'X-Mailer: HexaHost Test Email',
|
|
||||||
];
|
|
||||||
|
|
||||||
return mail($config['to_email'], $subject, $message, implode("\r\n", $headers));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PHP_SAPI === 'cli') {
|
|
||||||
echo testEmail() ? "Test-E-Mail gesendet.\n" : "Fehler beim Senden.\n";
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_GET['test'])) {
|
|
||||||
echo testEmail()
|
|
||||||
? 'Test-E-Mail wurde gesendet.'
|
|
||||||
: 'Fehler beim Senden der Test-E-Mail.';
|
|
||||||
} else {
|
|
||||||
echo '<h1>HexaHost.de E-Mail Test</h1>';
|
|
||||||
echo '<p><a href="?test=1">Test-E-Mail senden</a></p>';
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user