Skip to content

Commit ed640aa

Browse files
committed
First version upload
1 parent 8a1ceb6 commit ed640aa

File tree

7 files changed

+369
-1
lines changed

7 files changed

+369
-1
lines changed

Contact/Api/Guest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/**
4+
* FOSSBilling.
5+
*
6+
* @copyright FOSSBilling (https://www.fossbilling.org)
7+
* @license Apache-2.0
8+
*
9+
* Copyright FOSSBilling 2022
10+
* This software may contain code previously used in the BoxBilling project.
11+
* Copyright BoxBilling, Inc 2011-2021
12+
*
13+
* This source file is subject to the Apache-2.0 License that is bundled
14+
* with this source code in the file LICENSE
15+
*/
16+
17+
/**
18+
* All public methods in this class are exposed to public. Always think
19+
* what kind of information you are exposing. Emails, passwords and other
20+
* information should NOT be returned by functions in this class.
21+
*
22+
* This module can be called from API or in template
23+
*/
24+
25+
// Change "Example" with your module's name
26+
27+
namespace Box\Mod\CONTACT\Api;
28+
29+
class Guest extends \Api_Abstract
30+
{
31+
}

Contact/Controller/Client.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
/**
4+
* FOSSBilling.
5+
*
6+
* @copyright FOSSBilling (https://www.fossbilling.org)
7+
* @license Apache-2.0
8+
*
9+
* Copyright FOSSBilling 2022
10+
* This software may contain code previously used in the BoxBilling project.
11+
* Copyright BoxBilling, Inc 2011-2021
12+
*
13+
* This source file is subject to the Apache-2.0 License that is bundled
14+
* with this source code in the file LICENSE
15+
*/
16+
17+
namespace Box\Mod\Contact\Controller;
18+
19+
class Client implements \FOSSBilling\InjectionAwareInterface
20+
{
21+
protected $di;
22+
23+
public function setDi(\Pimple\Container|null $di): void
24+
{
25+
$this->di = $di;
26+
}
27+
28+
public function getDi(): ?\Pimple\Container
29+
{
30+
return $this->di;
31+
}
32+
33+
/**
34+
* Methods maps client areas urls to corresponding methods
35+
* Always use your module prefix to avoid conflicts with other modules
36+
* in future.
37+
*
38+
* @param \Box_App $app - returned by reference
39+
*/
40+
public function register(\Box_App &$app): void
41+
{
42+
$app->get('/contact', 'get_index', [], static::class);
43+
$app->post('/contact', 'get_index', [], static::class);
44+
}
45+
46+
public function get_index(\Box_App $app)
47+
{
48+
// Initialize variables
49+
$error = '';
50+
$success = '';
51+
52+
// Capture GET parameter and sanitize the domain
53+
$domain = filter_input(INPUT_GET, 'domain', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
54+
55+
// Process form submission if it's a POST request
56+
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
57+
// Capture and sanitize form data
58+
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
59+
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
60+
$message = filter_input(INPUT_POST, 'message', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
61+
62+
// Validate form data
63+
if ($name && $email && $message) {
64+
// Define sender and recipient
65+
$sender = [
66+
'email' => $email,
67+
'name' => $name,
68+
];
69+
$recipient = [
70+
'email' => 'registrant@example.com', // Replace with actual registrant's email
71+
'name' => 'Domain Registrant',
72+
];
73+
74+
// Get email settings
75+
$mod = $this->di['mod']('email');
76+
$settings = $mod->getConfig();
77+
$logEnabled = isset($settings['log_enabled']) && $settings['log_enabled'];
78+
$transport = $settings['mailer'] ?? 'sendmail';
79+
80+
// Prepare the email content and transport
81+
$mail = new \FOSSBilling\Mail($sender, $recipient, "Contact Domain Registrant: " . $domain, $message, $transport, $settings['custom_dsn'] ?? null);
82+
83+
try {
84+
// Attempt to send the email
85+
$mail->send($settings);
86+
87+
// Log activity if enabled
88+
if ($logEnabled) {
89+
$activityService = $this->di['mod_service']('activity');
90+
$activityService->logEmail("Contact Domain Registrant: " . $domain, null, $email, 'registrant@example.com', $message);
91+
}
92+
$success = 'Your message has been sent successfully.';
93+
} catch (\Exception $e) {
94+
$error = 'Failed to send the message. Please try again later.';
95+
$this->di['logger']->setChannel('email')->err($e->getMessage());
96+
}
97+
} else {
98+
$error = 'Please fill in all fields with valid information.';
99+
}
100+
} else {
101+
// Existing GET logic for domain validation
102+
if ($domain) {
103+
$parts = explode('.', $domain);
104+
$sld = '';
105+
$tld = '';
106+
107+
if (count($parts) >= 3) {
108+
$tld = implode('.', array_slice($parts, -2));
109+
$sld = $parts[count($parts) - 3];
110+
} elseif (count($parts) === 2) {
111+
$sld = $parts[0];
112+
$tld = $parts[1];
113+
} else {
114+
$error = "Error: Invalid domain format.";
115+
}
116+
117+
if ($sld && $tld) {
118+
$domainExists = $this->di['db']->getAll(
119+
'SELECT * FROM service_domain WHERE sld = :sld AND tld = :tld',
120+
['sld' => $sld, 'tld' => '.' . $tld]
121+
);
122+
123+
if (!$domainExists) {
124+
$error = "Error: The specified domain does not exist.";
125+
}
126+
} else {
127+
$error = "Error: Unable to extract SLD and TLD from the domain.";
128+
}
129+
} else {
130+
$error = "Error: You must specify a domain.";
131+
}
132+
}
133+
134+
return $app->render('mod_contact_index', [
135+
'domain' => $domain,
136+
'error' => $error,
137+
'success' => $success,
138+
]);
139+
}
140+
141+
}

Contact/Service.php

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
3+
/**
4+
* FOSSBilling.
5+
*
6+
* @copyright FOSSBilling (https://www.fossbilling.org)
7+
* @license Apache-2.0
8+
*
9+
* Copyright FOSSBilling 2022
10+
* This software may contain code previously used in the BoxBilling project.
11+
* Copyright BoxBilling, Inc 2011-2021
12+
*
13+
* This source file is subject to the Apache-2.0 License that is bundled
14+
* with this source code in the file LICENSE
15+
*/
16+
17+
namespace Box\Mod\Contact;
18+
19+
use FOSSBilling\InformationException;
20+
21+
class Service
22+
{
23+
protected $di;
24+
25+
public function setDi(\Pimple\Container|null $di): void
26+
{
27+
$this->di = $di;
28+
}
29+
30+
/**
31+
* Method to install the module. In most cases you will use this
32+
* to create database tables for your module.
33+
*
34+
* If your module isn't very complicated then the extension_meta
35+
* database table might be enough.
36+
*
37+
* @return bool
38+
*
39+
* @throws InformationException
40+
*/
41+
public function install(): bool
42+
{
43+
// Execute SQL script if needed
44+
$db = $this->di['db'];
45+
$db->exec('SELECT NOW()');
46+
47+
// throw new InformationException("Throw exception to terminate module installation process with a message", array(), 123);
48+
return true;
49+
}
50+
51+
/**
52+
* Method to uninstall module. In most cases you will use this
53+
* to remove database tables for your module.
54+
*
55+
* You also can opt to keep the data in the database if you want
56+
* to keep the data for future use.
57+
*
58+
* @return bool
59+
*
60+
* @throws InformationException
61+
*/
62+
public function uninstall(): bool
63+
{
64+
// throw new InformationException("Throw exception to terminate module uninstallation process with a message", array(), 124);
65+
return true;
66+
}
67+
68+
/**
69+
* Method to update module. When you release new version to
70+
* extensions.fossbilling.org then this method will be called
71+
* after the new files are placed.
72+
*
73+
* @param array $manifest - information about the new module version
74+
*
75+
* @return bool
76+
*
77+
* @throws InformationException
78+
*/
79+
public function update(array $manifest): bool
80+
{
81+
// throw new InformationException("Throw exception to terminate module update process with a message", array(), 125);
82+
return true;
83+
}
84+
85+
/**
86+
* Methods is a delegate for one database row.
87+
*
88+
* @param array $row - array representing one database row
89+
* @param string $role - guest|client|admin who is calling this method
90+
* @param bool $deep - true|false deep or light version of result to return to API
91+
*
92+
* @return array
93+
*/
94+
public function toApiArray(array $row, string $role = 'guest', bool $deep = true): array
95+
{
96+
return $row;
97+
}
98+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{% extends request.ajax ? "layout_blank.html.twig" : "layout_default.html.twig" %}
2+
3+
{% block meta_title %}{{ 'Contact Domain Registrant'|trans }}{% endblock %}
4+
5+
{% block body_class %}tmch{% endblock %}
6+
{% block breadcrumb %} <li class="active">{{ 'Contact Domain Registrant'|trans }}</li>{% endblock %}
7+
8+
{% block page_header %}
9+
<article class="page-header">
10+
<h1>{{ 'Contact Domain Registrant'|trans }}</h1>
11+
</article>
12+
{% endblock%}
13+
14+
{% block content %}
15+
<div class="col-md-12">
16+
<div class="card mb-4">
17+
<div class="card-body">
18+
19+
{% if success %}
20+
<div class="alert alert-success">
21+
<i class="fas fa-check-circle fa-fw"></i> {{ success }}
22+
</div>
23+
{% endif %}
24+
25+
{% if error %}
26+
<div class="alert alert-danger">
27+
<i class="fas fa-exclamation-circle fa-fw"></i> {{ error }}
28+
</div>
29+
{% endif %}
30+
31+
{% if domain and not error %}
32+
<form method="POST" action="/contact?domain={{ domain }}">
33+
34+
<h3 class="card-title">Domain: {{ domain }}</h3>
35+
36+
<div class="form-group row mb-4">
37+
<label for="name" class="col-md-4 col-form-label">Your Name:</label>
38+
<div class="col-md-6">
39+
<input type="text" name="name" id="name" class="form-control" required />
40+
</div>
41+
</div>
42+
43+
<div class="form-group row mb-4">
44+
<label for="email" class="col-md-4 col-form-label">Your Email:</label>
45+
<div class="col-md-6">
46+
<input type="email" name="email" id="email" class="form-control" required />
47+
</div>
48+
</div>
49+
50+
<div class="form-group row mb-4">
51+
<label for="message" class="col-md-4 col-form-label">Your Message:</label>
52+
<div class="col-md-6">
53+
<textarea id="message" name="message" class="form-control" rows="4" required></textarea>
54+
</div>
55+
</div>
56+
57+
<div class="text-center">
58+
<button type="submit" class="btn btn-primary">
59+
Send Message
60+
</button>
61+
</div>
62+
63+
</form>
64+
{% endif %}
65+
</div>
66+
</div>
67+
</div>
68+
{% endblock %}

Contact/icon.svg

Lines changed: 1 addition & 0 deletions
Loading

Contact/manifest.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"id": "contact",
3+
"type": "mod",
4+
"name": "Domain Registrant Contact",
5+
"description": "Provides a contact form to reach the registrant of a specified domain",
6+
"icon_url": "icon.svg",
7+
"homepage_url": "https://namingo.org",
8+
"author": "Namingo Team",
9+
"author_url": "https://namingo.org/",
10+
"license": "Apache 2.0 - https://www.apache.org/licenses/LICENSE-2.0",
11+
"version": "1.0.0"
12+
}

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,19 @@
1-
# fossbilling-contact
1+
# Domain Registrant Contact for FOSSBilling
22
Provides a contact form to reach the registrant of a specified domain.
3+
4+
## Installation
5+
6+
```bash
7+
git clone https://github.com/getnamingo/fossbilling-contact
8+
mv fossbilling-contact/Contact /var/www/modules/
9+
```
10+
11+
- Go to Extensions > Overview in the admin panel and activate "Domain Registrant Contact".
12+
13+
## Usage Instructions
14+
15+
The detailed usage instructions for this module are currently being written and will be available soon. This module is specifically designed to work with the Namingo Registrar project, ensuring proper Domain Registrant Contact process. Please check back later for full documentation and guidance on using this module with your Namingo Registrar setup.
16+
17+
## License
18+
19+
Apache License 2.0

0 commit comments

Comments
 (0)