Compare commits
31 Commits
v1.4.2
...
45a7067878
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45a7067878 | ||
|
|
4787d7b770 | ||
|
|
a0aa8b12ca | ||
|
|
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;
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -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>
|
||||||
|
|||||||
@@ -2,43 +2,43 @@
|
|||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
<url>
|
<url>
|
||||||
<loc>https://hexahost.de/</loc>
|
<loc>https://hexahost.de/</loc>
|
||||||
<lastmod>2024-01-01</lastmod>
|
<lastmod>2026-05-28</lastmod>
|
||||||
<changefreq>weekly</changefreq>
|
<changefreq>weekly</changefreq>
|
||||||
<priority>1.0</priority>
|
<priority>1.0</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://hexahost.de/vpc.html</loc>
|
<loc>https://hexahost.de/vpc.html</loc>
|
||||||
<lastmod>2024-01-01</lastmod>
|
<lastmod>2026-05-28</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.9</priority>
|
<priority>0.9</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://hexahost.de/vps.html</loc>
|
<loc>https://hexahost.de/vps.html</loc>
|
||||||
<lastmod>2024-01-01</lastmod>
|
<lastmod>2026-05-28</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.9</priority>
|
<priority>0.9</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://hexahost.de/mail-gateway.html</loc>
|
<loc>https://hexahost.de/mail-gateway.html</loc>
|
||||||
<lastmod>2024-01-01</lastmod>
|
<lastmod>2026-05-28</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.9</priority>
|
<priority>0.9</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://hexahost.de/webhosting.html</loc>
|
<loc>https://hexahost.de/webhosting.html</loc>
|
||||||
<lastmod>2024-01-01</lastmod>
|
<lastmod>2026-05-28</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.9</priority>
|
<priority>0.9</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://hexahost.de/about.html</loc>
|
<loc>https://hexahost.de/about.html</loc>
|
||||||
<lastmod>2024-01-01</lastmod>
|
<lastmod>2026-05-28</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.7</priority>
|
<priority>0.7</priority>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://hexahost.de/contact.html</loc>
|
<loc>https://hexahost.de/contact.html</loc>
|
||||||
<lastmod>2024-01-01</lastmod>
|
<lastmod>2026-05-28</lastmod>
|
||||||
<changefreq>monthly</changefreq>
|
<changefreq>monthly</changefreq>
|
||||||
<priority>0.8</priority>
|
<priority>0.8</priority>
|
||||||
</url>
|
</url>
|
||||||
|
|||||||
@@ -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