+* @version 0.1.0
+* @package Mail
+*
+**/
+ class Mail{
+ /**
+ * @var string $to The email address, (or addresses, if comma separated), of the person to which this email should be sent.
+ **/
+ public $to;
+
+ /**
+ * @var string $from The email address that this mail will be delivered from. Bear in mind that this can be anything, but that if the email
+ * domain doesn't match the actual domain the message was sent from, some email clients will reject the message as spam.
+ **/
+ public $from;
+
+ /**
+ * @var string $subject The subject line of the email
+ **/
+ public $subject;
+
+ /**
+ * @var string $text_content The plaintext version of the message to be sent.
+ **/
+ public $text_content;
+
+ /**
+ * @var string $html_content The HTML version of the message to be sent.
+ **/
+ public $html_content;
+
+ /**
+ * @var string $body The complete body of the email that will be sent, including all mixed content.
+ **/
+ private $body;
+
+ /**
+ * @var array $attachments An array of file paths pointing to the attachments that should be included with this email.
+ **/
+ private $attachments;
+
+ /**
+ * @var array $headers An array of the headers that will be included in this email.
+ **/
+ private $headers;
+
+ /**
+ * @var string $header_string The string, (and therefore final), representation of the headers for this email message.
+ **/
+ private $header_string;
+
+ /**
+ * @var string $boundary_hash The string that acts as a separator between the various mixed parts of the email message.
+ **/
+ private $boundary_hash;
+
+ /**
+ * @var boolean $sent Whether or not this email message was successfully sent.
+ **/
+ private $sent;
+
+
+ /**
+ * Upon initialization of a Mail object, you have to pass it certain vital pieces of information.
+ *
+ * At a minimum, an email must consist of a receiver address, a sender address, and a subject.
+ * The body can be left blank.
+ **/
+ public function __construct($to, $from, $subject, $text_content = "", $html_content = ""){
+ $this->to = $to;
+ $this->from = $from;
+ $this->subject = $this->convert_utf8($subject);
+ $this->text_content = $text_content;
+ $this->html_content = $html_content;
+ $this->body = "";
+ $this->attachments = array();
+ $this->base64_attachments = array();
+ $this->headers = array();
+ $this->boundary_hash = md5(date('r', time()));
+ }
+
+ /**
+ * The send() method processes all headers, body elements and attachments and then actually sends the resulting final email.
+ **/
+ public function send(){
+ $this->prepare_headers();
+ $this->prepare_body();
+ if(!empty($this->attachments)){
+ $this->prepare_attachments();
+ }
+ if(!empty($this->base64_attachments)){
+ $this->prepare_base64_attachments();
+ }
+ $this->sent = mail($this->to, $this->subject, $this->body, $this->header_string);
+ return $this->sent;
+ }
+
+ /**
+ * This method allows the user to add a new header to the message
+ * @param string $header The text for the header the user wants to add. Note that this string must be a properly formatted email header.
+ **/
+ public function add_header($header){
+ $this->headers[] = $header;
+ }
+
+ /**
+ * Add a filepath to the list of files to be sent with this email.
+ * @param string $file The path to the file that should be sent.
+ **/
+ public function add_attachment($file){
+ $this->attachments[] = $file;
+ }
+ public function add_base64_attachment($name,$data){
+ $this->base64_attachments[] = array('name'=>$name, 'data'=>$data);
+ }
+ private function prepare_body(){
+ $this->body .= "--PHP-mixed-{$this->boundary_hash}\n";
+ $this->body .= "Content-Type: multipart/alternative; boundary=\"PHP-alt-{$this->boundary_hash}\"\n\n";
+ if(!empty($this->text_content)) $this->prepare_text();
+ if(!empty($this->html_content)) $this->prepare_html();
+ $this->body .= "--PHP-alt-{$this->boundary_hash}--\n\n";
+ }
+
+ private function prepare_headers(){
+ $this->set_default_headers();
+ $this->header_string = implode(PHP_EOL, $this->headers).PHP_EOL;
+ }
+
+ private function set_default_headers(){
+ $this->headers[] = 'MIME-Version: 1.0';
+ $this->headers[] = "From: {$this->from}";
+ # We'll assume a multi-part message so that we can include an HTML and a text version of the email at the
+ # very least. If there are attachments, we'll be doing the same thing.
+ $this->headers[] = "Content-type: multipart/mixed; boundary=\"PHP-mixed-{$this->boundary_hash}\"";
+ }
+
+ private function prepare_base64_attachments(){
+ foreach($this->base64_attachments as $attachment){
+
+ $this->body .= "--PHP-mixed-{$this->boundary_hash}\n";
+ $this->body .= "Content-Type: application/octet-stream; name=\"{$attachment['name']}\"\n";
+ $this->body .= "Content-Transfer-Encoding: base64\n";
+ $this->body .= "Content-Disposition: attachment\n\n";
+ $this->body .= chunk_split($attachment['data']);
+ $this->body .= "\n\n";
+ }
+ $this->body .= "--PHP-mixed-{$this->boundary_hash}--\n\n";
+ }
+
+ private function prepare_attachments(){
+ foreach($this->attachments as $attachment){
+ $file_name = basename($attachment);
+
+ $file_name = $this->convert_utf8($file_name);
+ $this->body .= "--PHP-mixed-{$this->boundary_hash}\n";
+ $this->body .= "Content-Type: application/octet-stream; name=\"{$file_name}\"\n";
+ $this->body .= "Content-Transfer-Encoding: base64\n";
+ $this->body .= "Content-Disposition: attachment\n\n";
+ $this->body .= chunk_split(base64_encode(file_get_contents($attachment)));
+ $this->body .= "\n\n";
+ }
+ $this->body .= "--PHP-mixed-{$this->boundary_hash}--\n\n";
+ }
+
+
+ private function prepare_text(){
+ $this->body .= "--PHP-alt-{$this->boundary_hash}\n";
+ $this->body .= "Content-Type: text/plain; charset=\"utf-8\"\n";
+ $this->body .= "Content-Transfer-Encoding: 8bit\n\n";
+ $this->body .= $this->text_content."\n\n";
+ }
+
+ private function prepare_html(){
+ $this->body .= "--PHP-alt-{$this->boundary_hash}\n";
+ $this->body .= "Content-Type: text/html; charset=\"utf-8\"\n";
+ $this->body .= "Content-Transfer-Encoding: 8bit\n\n";
+ $this->body .= $this->html_content."\n\n";
+ }
+ //convert to utf8
+ private function convert_utf8($subject){
+ return '=?UTF-8?B?'.base64_encode($subject).'?=';
+ }
+
+ }
\ No newline at end of file
diff --git a/screenshot.png b/screenshot.png
new file mode 100644
index 0000000..6df2d0f
--- /dev/null
+++ b/screenshot.png
Binary files differ
diff --git a/script.js b/script.js
new file mode 100644
index 0000000..8ed7614
--- /dev/null
+++ b/script.js
@@ -0,0 +1,165 @@
+$(document).ready(function() {
+ // Function to update the iframe content
+ function updateIframeContent() {
+ var textareaContent = $("#html_content").val();
+ $("#iframe_id").attr("srcdoc", textareaContent);
+ }
+
+ // Add a click event handler for the "Render" tab
+ $("#pills-render-tab").on("click", function() {
+ updateIframeContent();
+ });
+
+ // Initially update the iframe content
+ updateIframeContent();
+});
+
+
+// Function to initialize the iframe resizing
+function initResizableIframe() {
+ const iframe = document.getElementById('iframe_id');
+
+ // Function to update the iframe's height based on its content
+ function updateIframeHeight() {
+ const iframeDocument = iframe.contentWindow.document;
+ const newHeight = iframeDocument.body.scrollHeight || 'auto';
+ iframe.style.height = newHeight + 'px';
+ }
+
+ // Attach the update function to iframe's load event and window's resize event
+ iframe.onload = updateIframeHeight;
+ window.addEventListener('resize', updateIframeHeight);
+
+ // Initialize the iframe height
+ updateIframeHeight();
+}
+
+// Call the initialization function when the document is ready
+document.addEventListener('DOMContentLoaded', initResizableIframe);
+
+
+$(document).ready(function() {
+ let headerCount = 1;
+
+ // Add Header button click event
+ $("#addHeaderButton").click(function() {
+ // Create a new header/value/delete form
+ var newRow = $('');
+
+ // Append the new header/value/delete form to the form group
+ $(".header-row").append(newRow);
+ $("#headerCount").val(headerCount);
+ // Increment the headerCount for the next set
+ headerCount++;
+ });
+
+ // Delete button click event
+ $(document).on("click", ".delete-button", function() {
+ // Remove the parent row when the delete button is clicked
+ $(this).closest(".form-row").remove();// Decrement the headerCount when a row is deleted
+ });
+});
+
+// to display ile name when attachment is chosen
+$(document).ready(function () {
+ // Add an event listener to the file input
+ $('#attachment').change(function () {
+ // Get the name of the selected file
+ var fileName = $(this).val().split('\\').pop();
+ // Update the label text with the file name
+ $('.custom-file-label').html(fileName);
+ });
+});
+
+
+let lastSubmittedData = null;
+
+function submitForm() {
+ // Create a FormData object to easily handle form data, including file uploads
+ const formData = new FormData(document.getElementById('emailForm'));
+
+ // Get the headerCount value from the hidden input
+ let headerCount = parseInt(document.getElementById('headerCount').value);
+
+ // Convert dynamic header inputs into an array of objects
+ const headers = [];
+ let newHeaderCount = 0;
+
+ for (let i = 1; i <= headerCount; i++) {
+ const headerNameInput = document.querySelector(`[name="header_name_${i}"]`);
+ const headerValueInput = document.querySelector(`[name="header_value_${i}"]`);
+
+ // Check if both headerNameInput and headerValueInput exist
+ if (headerNameInput && headerValueInput) {
+ const headerName = headerNameInput.value;
+ const headerValue = headerValueInput.value;
+
+ // Check if both headerName and headerValue exist
+ if (headerName && headerValue) {
+ newHeaderCount++;
+
+ // Rename the input fields to reflect new IDs
+ headerNameInput.name = `header_name_${newHeaderCount}`;
+ headerValueInput.name = `header_value_${newHeaderCount}`;
+
+ headers.push({ name: headerNameInput.name, value: headerValueInput.name });
+ }
+ }
+ }
+
+
+ // Update the headerCount hidden input with the new count
+ document.getElementById('headerCount').value = newHeaderCount;
+ headerCount = parseInt(document.getElementById('headerCount').value);
+
+ // Add the headers as a JSON string to the FormData
+ formData.append('headers', JSON.stringify(headers));
+
+ // Convert form data to a JSON string for comparison
+ const currentData = JSON.stringify(Array.from(formData.entries()));
+
+ // Check if the form data has changed
+ if (currentData === lastSubmittedData) {
+ const resultElement = document.getElementById('result');
+ resultElement.textContent = "Already tried to send this data";
+ resultElement.style.color = "red";
+ return;
+ }
+
+ // Save the current form data for future comparison
+ lastSubmittedData = currentData;
+
+ // Send the form data to "submit.php"
+ fetch('submit.php', {
+ method: 'POST',
+ body: formData,
+ })
+ .then(response => response.text()) // Read the response as plain text
+ .then(data => {
+ // Handle the response from the server here
+ const resultElement = document.getElementById('result');
+ resultElement.textContent = data;
+ if (data === "Success") {
+ resultElement.style.color = "lightgreen";
+ } else {
+ resultElement.style.color = "red";
+ }
+ })
+ .catch(error => {
+ // Handle errors here
+ console.error('Error:', error);
+ });
+}
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..cb03465
--- /dev/null
+++ b/style.css
@@ -0,0 +1,19 @@
+.hidden-textarea {
+ display: none;
+}
+.resizable-iframe {
+ resize: both;
+ overflow: auto;
+}
+.btn-danger {
+ margin-top: 30px;
+}
+body{
+ background-color: #333;
+ color: #ccc;
+}
+.wrapper{
+ width: 65%;
+ margin: auto;
+}
+.wrapper h1,.wrapper h2,.wrapper h3,.wrapper h4{ text-align:center; }
\ No newline at end of file
diff --git a/submit.php b/submit.php
new file mode 100644
index 0000000..7ca3125
--- /dev/null
+++ b/submit.php
@@ -0,0 +1,85 @@
+ $value) {
+ if (strpos($key, 'header_name_') === 0) {
+ $id = substr($key, strlen('header_name_'));
+ $headerName = $value;
+ $headerValueKey = 'header_value_' . $id;
+ if (isset($_POST[$headerValueKey])) {
+ $headerValue = $_POST[$headerValueKey];
+ $mail->add_header($headerName.": ".$headerValue);
+ }
+ }
+ }
+
+ // Check if an attachment is provided
+ if (isset($_FILES['attachment']) && $_FILES['attachment']['error'] === 0) {
+ // Handle the uploaded file
+ $uploadedFile = $_FILES['attachment'];
+ $uploadedFilePath = $uploadDirectory . $uploadedFile['name'];
+
+ // Move the uploaded file to the desired directory
+ if (move_uploaded_file($uploadedFile['tmp_name'], $uploadedFilePath)) {
+ // Add the attachment to the email
+ $mail->add_attachment($uploadedFilePath);
+ } else {
+ echo "Failed to upload the attachment.";
+ }
+ }
+
+
+ // Send the email
+ if ($mail->send()) {
+ echo "Success";
+ } else {
+ echo "Failed to send the email.";
+ }
+ }
+ } else {
+ echo "Invalid password.";
+ }
+} else {
+ echo "Invalid request.";
+}
+?>