WordPress - Send email from dashboard widget - php

I'm working on a dshboard widget for WordPress. I've successfully added it using add_meta_box function and also tried using wp_add_dashboard_widget and I'm able to see my custom HTML code. I need now to send an email when the submit button is clicked, is this possible?I'm looking to the wordpress codex, but there is no trace of how to manage the widget content, can anyone help me please?
public function setup_ticketing_widget()
{
// Remove Welcome panel.
remove_action( 'welcome_panel', 'wp_welcome_panel' );
// Remove all Dashboard widgets.
global $wp_meta_boxes;
unset( $wp_meta_boxes['dashboard'] );
//
//wp_add_dashboard_widget(
// 'ict-support-ticket',
// __('Richiesta ticket di supporto'),
// [$this, 'ticketing_widget_content'],
//);
// Add custom dashbboard widget.
add_meta_box( 'dashboard_widget_example',
__( 'Richiesta ticket di supporto'),
[$this, 'ticketing_widget_content'],
'dashboard',
'side', // $context: 'advanced', 'normal', 'side', 'column3', 'column4'
'high', // $priority: 'high', 'core', 'default', 'low'
);
}
/*
*
*/
public function ticketing_widget_content()
{
?>
<div id="form-wrappe">
<label id="form-label">Request Type</label>
<select name="support_request_type" id="form-input">
<option value="">-----</option>
<option value="">1</option>
<option value="">2</option>
<option value="">3</option>
</select>
</div>
<div id="form-wrapper">
<lable id="form-label">Email</label>
<input type="text" name="support_request_from" id="form-input">
</div>
<div id="form-wrapper">
<label id="form-label">Messsage</label>
<textarea name="support_request_message" rows="10" id="form-input"></textarea>
</div>
<div id="form-wrapper">
<button id="submit-button">Invia ticket</button>
</div>
<style>
option {
text-transform: uppercase;
}
#form-label {
display: block;
}
#form-input {
width: 100%;
}
#help-text {
display: block;
font-size: 1em !important;
}
#submit-button {
width: 100%;
text-transform: uppercase;
}
#form-wrapper {
margin-top: 1em;
margin-bottom: 1em;
}
</style>
<?php
}
UPDATE
I've created a rest route that will be called from the code using the following code
public function submit_support_ticket( WP_REST_Request $request )
{
$request_type = sanitize_text_field( $request->get_param('reqType') );
$request_issuer = sanitize_email( $request->get_param('issuerEmail') );
$request_message = sanitize_textarea_field( $request->get_param('reqMessage') );
var_dump( $request_type, $request_issuer, $request_message );
switch( $request_type ){
case '1':
$subject = '... WordPress';
break;
case '2':
$subject = '... WordPress';
break;
case '3':
$subject = '... WordPress';
break;
case '4':
$subject = '...';
break;
}
//wp_mail( $to:string|array, $subject:string, $message:string, $headers:string|array, $attachments:string|array )
$to = 'demo#example.org';
$headers[] = 'From: Ticketing System WordPress <demo#example.org>';
$headers[] = 'Cc: User 1 <demo#example.org>';
$headers[] = 'Cc: User 2 <demo#example.org>';
$headers[] = 'Cc: User 3 <demo#example.org>';
if( wp_mail( $to, $subject, $request_message, $headers ) ){
return [
'status' => 'success',
'message' => 'Email sent'
];
} else {
return [
'status' => 'error',
'message' => 'Email not sent'
];
}
}
In my class construct I've used the rest_api_init hook to register the route and this is the JS script part I've added to the function that is responsable to send the ajax request to the route
<script>
const siteURL = window.location.origin
const requestType = document.getElementById('request-type');
const issuerEmail = document.getElementById('issuer-email');
const requestMessage = document.getElementById('request-message');
const submitButton = document.getElementById('submit-button');
//
submitButton.addEventListener('click', (e) => {
e.preventDefault();
console.log(siteURL, requestType.value, issuerEmail.value, requestMessage.value);
fetch(`${siteURL}/wp-json/support/ticketing/send-request`, {
method: 'POST',
body: JSON.stringify({
reqType: requestType.value,
issuerEmail: issuerEmail.value,
reqMessage: requestMessage.value
})
}).then( (res) => {
console.log(res)
}).catch( e => console.log(e) )
});
</script>
I've noticed that the callback that is responsable to send the email will be not fired. Is there something wrong into the implementation?

Related

Get Price for stripe integration (in form elements) in PHP

I integrate Stripe my website,
I find the script (works fine) but I want to put 4 articles to buy, so I need to get the price, and it doesn't work :/ I have put a hidden input, but impossible get the value
first my form (In modal) => I put an input with value 12 for example
<!-- Stylesheet file -->
<link rel="stylesheet" href="css/style.css">
<!-- Stripe JS library -->
<script src="https://js.stripe.com/v3/"></script>
<script src="js/checkout.js" STRIPE_PUBLISHABLE_KEY="<?php echo STRIPE_PUBLISHABLE_KEY; ?>" defer></script>
<div class="panel">
<div class="panel-heading">
<!-- Product Info -->
<p> <?php echo $itemName; ?></p>
<p><b>Price:</b> <?php echo '$'.$itemPrice.' '.$currency; ?></p>
</div>
<div class="panel-body">
<!-- Display status message -->
<div id="paymentResponse" class="hidden"></div>
<!-- Display a payment form -->
<form id="paymentFrm" class="hidden">
<div class="form-group">
<label>NAME</label>
<input type="text" id="name" class="field" placeholder="Enter name" required="" autofocus="">
</div>
<div class="form-group">
<label>EMAIL</label>
<input type="email" id="email" class="field" placeholder="Enter email" required="">
</div>
<input type="hidden" class="field" name="prix" id="prix" value="12" >
<div id="paymentElement">
<!--Stripe.js injects the Payment Element-->
</div>
<!-- Form submit button -->
<button id="submitBtn" class="btn btn-success">
<div class="spinner hidden" id="spinner"></div>
<span id="buttonText">Pay Now</span>
</button>
</form>
<!-- Display processing notification -->
<div id="frmProcess" class="hidden">
<span class="ring"></span> Processing...
</div>
<!-- Display re-initiate button -->
<div id="payReinit" class="hidden">
<button class="btn btn-primary" onClick="window.location.href=window.location.href.split('?')[0]"><i class="rload"></i>Re-initiate Payment</button>
</div>
</div>
</div>
JS :
// Get API Key
let STRIPE_PUBLISHABLE_KEY = document.currentScript.getAttribute('STRIPE_PUBLISHABLE_KEY');
// Create an instance of the Stripe object and set your publishable API key
const stripe = Stripe(STRIPE_PUBLISHABLE_KEY);
// Define card elements
let elements;
// Select payment form element
const paymentFrm = document.querySelector("#paymentFrm");
// Get payment_intent_client_secret param from URL
const clientSecretParam = new URLSearchParams(window.location.search).get(
"payment_intent_client_secret"
);
// Check whether the payment_intent_client_secret is already exist in the URL
setProcessing(true);
if(!clientSecretParam){
setProcessing(false);
// Create an instance of the Elements UI library and attach the client secret
initialize();
}
// Check the PaymentIntent creation status
checkStatus();
// Attach an event handler to payment form
paymentFrm.addEventListener("submit", handleSubmit);
// Fetch a payment intent and capture the client secret
let payment_intent_id;
async function initialize() {
const { id, clientSecret } = await fetch("payment_init.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ request_type:'create_payment_intent' }),
}).then((r) => r.json());
const appearance = {
theme: 'stripe',
rules: {
'.Label': {
fontWeight: 'bold',
textTransform: 'uppercase',
}
}
};
elements = stripe.elements({ clientSecret, appearance });
const paymentElement = elements.create("payment");
paymentElement.mount("#paymentElement");
payment_intent_id = id;
}
// Card form submit handler
async function handleSubmit(e) {
e.preventDefault();
setLoading(true);
let customer_name = document.getElementById("name").value;
let customer_email = document.getElementById("email").value;
let customer_prix = document.getElementById("prix").value;
const { id, customer_id } = await fetch("payment_init.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ request_type:'create_customer', payment_intent_id: payment_intent_id, name: customer_name, email: customer_email, prix: customer_prix }),
}).then((r) => r.json());
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
// Make sure to change this to your payment completion page
return_url: window.location.href+'?customer_id='+customer_id,
},
});
// This point will only be reached if there is an immediate error when
// confirming the payment. Otherwise, your customer will be redirected to
// your `return_url`. For some payment methods like iDEAL, your customer will
// be redirected to an intermediate site first to authorize the payment, then
// redirected to the `return_url`.
if (error.type === "card_error" || error.type === "validation_error") {
showMessage(error.message);
} else {
showMessage("An unexpected error occured.");
}
setLoading(false);
}
// Fetch the PaymentIntent status after payment submission
async function checkStatus() {
const clientSecret = new URLSearchParams(window.location.search).get(
"payment_intent_client_secret"
);
const customerID = new URLSearchParams(window.location.search).get(
"customer_id"
);
if (!clientSecret) {
return;
}
const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret);
if (paymentIntent) {
switch (paymentIntent.status) {
case "succeeded":
// Post the transaction info to the server-side script and redirect to the payment status page
fetch("payment_init.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ request_type:'payment_insert', payment_intent: paymentIntent, customer_id: customerID }),
})
.then(response => response.json())
.then(data => {
if (data.payment_txn_id) {
window.location.href = '?o=shop&pid='+data.payment_txn_id;
} else {
showMessage(data.error);
setReinit();
}
})
.catch(console.error);
break;
case "processing":
showMessage("Your payment is processing.");
setReinit();
break;
case "requires_payment_method":
showMessage("Your payment was not successful, please try again.");
setReinit();
break;
default:
showMessage("Something went wrong.");
setReinit();
break;
}
} else {
showMessage("Something went wrong.");
setReinit();
}
}
// Display message
function showMessage(messageText) {
const messageContainer = document.querySelector("#paymentResponse");
messageContainer.classList.remove("hidden");
messageContainer.textContent = messageText;
setTimeout(function () {
messageContainer.classList.add("hidden");
messageText.textContent = "";
}, 5000);
}
// Show a spinner on payment submission
function setLoading(isLoading) {
if (isLoading) {
// Disable the button and show a spinner
document.querySelector("#submitBtn").disabled = true;
document.querySelector("#spinner").classList.remove("hidden");
document.querySelector("#buttonText").classList.add("hidden");
} else {
// Enable the button and hide spinner
document.querySelector("#submitBtn").disabled = false;
document.querySelector("#spinner").classList.add("hidden");
document.querySelector("#buttonText").classList.remove("hidden");
}
}
// Show a spinner on payment form processing
function setProcessing(isProcessing) {
if (isProcessing) {
paymentFrm.classList.add("hidden");
document.querySelector("#frmProcess").classList.remove("hidden");
} else {
paymentFrm.classList.remove("hidden");
document.querySelector("#frmProcess").classList.add("hidden");
}
}
// Show payment re-initiate button
function setReinit() {
document.querySelector("#frmProcess").classList.add("hidden");
document.querySelector("#payReinit").classList.remove("hidden");
}
and the payment_init.php where i need to get price
<?php
// Include the configuration file
require_once 'config.php';
// Include the database connection file
include_once 'dbConnect.php';
$itemPrice = $_POST['prix'];
// Include the Stripe PHP library
//require_once 'stripe-php/init.php';
require_once('vendor/autoload.php');
// Set API key
\Stripe\Stripe::setApiKey(STRIPE_API_KEY);
// Retrieve JSON from POST body
$jsonStr = file_get_contents('php://input');
$jsonObj = json_decode($jsonStr);
if($jsonObj->request_type == 'create_payment_intent'){
// Define item price and convert to cents
$itemPriceCents = round($itemPrice*100);
// Set content type to JSON
header('Content-Type: application/json');
try {
// Create PaymentIntent with amount and currency
$paymentIntent = \Stripe\PaymentIntent::create([
'amount' => $itemPriceCents,
'currency' => $currency,
'description' => $itemName,
'payment_method_types' => [
'card'
]
]);
$output = [
'id' => $paymentIntent->id,
'clientSecret' => $paymentIntent->client_secret
];
echo json_encode($output);
} catch (Error $e) {
http_response_code(500);
echo json_encode(['error' => $e->getMessage()]);
}
}elseif($jsonObj->request_type == 'create_customer'){
$payment_intent_id = !empty($jsonObj->payment_intent_id)?$jsonObj->payment_intent_id:'';
$name = !empty($jsonObj->name)?$jsonObj->name:'';
$email = !empty($jsonObj->email)?$jsonObj->email:'';
// Ajout client a la base
try {
$customer = \Stripe\Customer::create(array(
'name' => $name,
'email' => $email
));
}catch(Exception $e) {
$api_error = $e->getMessage();
}
if(empty($api_error) && $customer){
try {
// Mise a jour de l'intention avec l'id du client
$paymentIntent = \Stripe\PaymentIntent::update($payment_intent_id, [
'customer' => $customer->id
]);
} catch (Exception $e) {
// pour apres
}
$output = [
'id' => $payment_intent_id,
'customer_id' => $customer->id
];
echo json_encode($output);
}else{
http_response_code(500);
echo json_encode(['error' => $api_error]);
}
}elseif($jsonObj->request_type == 'payment_insert'){
$payment_intent = !empty($jsonObj->payment_intent)?$jsonObj->payment_intent:'';
$customer_id = !empty($jsonObj->customer_id)?$jsonObj->customer_id:'';
// Retrieve customer info
try {
$customer = \Stripe\Customer::retrieve($customer_id);
}catch(Exception $e) {
$api_error = $e->getMessage();
}
// Check whether the charge was successful
if(!empty($payment_intent) && $payment_intent->status == 'succeeded'){
// Transaction details
$transaction_id = $payment_intent->id;
$paid_amount = $payment_intent->amount;
$paid_amount = ($paid_amount/100);
$paid_currency = $payment_intent->currency;
$payment_status = $payment_intent->status;
$customer_name = $customer_email = '';
if(!empty($customer)){
$customer_name = !empty($customer->name)?$customer->name:'';
$customer_email = !empty($customer->email)?$customer->email:'';
}
// Check if any transaction data is exists already with the same TXN ID
$sqlQ = "SELECT id FROM transactions WHERE txn_id = ?";
$stmt = $db->prepare($sqlQ);
$stmt->bind_param("s", $transaction_id);
$stmt->execute();
$stmt->bind_result($row_id);
$stmt->fetch();
$payment_id = 0;
if(!empty($row_id)){
$payment_id = $row_id;
}else{
// Insert transaction data into the database
$sqlQ = "INSERT INTO transactions (customer_name,customer_email,item_name,item_price,item_price_currency,paid_amount,paid_amount_currency,txn_id,payment_status,created,modified) VALUES (?,?,?,?,?,?,?,?,?,NOW(),NOW())";
$stmt = $db->prepare($sqlQ);
$stmt->bind_param("sssdsdsss", $customer_name, $customer_email, $itemName, $itemPrice, $currency, $paid_amount, $paid_currency, $transaction_id, $payment_status);
$insert = $stmt->execute();
if($insert){
$payment_id = $stmt->insert_id;
}
}
$output = [
'payment_txn_id' => base64_encode($transaction_id)
];
echo json_encode($output);
}else{
http_response_code(500);
echo json_encode(['error' => 'Transaction has been failed!']);
}
}
?>

Elementor Custom Widget from Scratch

In a project I have to create a carousel in Elementor which should look like the one below:
carousel design
Using the widget from Elementor I couldn't create a carousel like this so I tried to create my own carousel using Easy-Responsive-jQuery-Carousel:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>jQuery FilmRoll Examples</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="https://www.jqueryscript.net/demo/Easy-Responsive-jQuery-Carousel-Slider-Plugin-FilmRoll/css/bootstrap.min.css">
<link rel="stylesheet" href="https://www.jqueryscript.net/demo/Easy-Responsive-jQuery-Carousel-Slider-Plugin-FilmRoll/css/bootstrap-responsive.min.css">
<style type="text/css">
body {
padding-top: 0;
padding-bottom: 40px;
}
.hero-unit {
text-align: center;
border-radius: 0;
margin: 150px 0 0 0;
background: #1e5799; /* Old browsers */
background: -moz-linear-gradient(top, #1e5799 0%, #338cd6 59%, #ffffff 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#1e5799), color-stop(59%,#338cd6), color-stop(100%,#ffffff)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #1e5799 0%,#338cd6 59%,#ffffff 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #1e5799 0%,#338cd6 59%,#ffffff 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #1e5799 0%,#338cd6 59%,#ffffff 100%); /* IE10+ */
background: linear-gradient(to bottom, #1e5799 0%,#338cd6 59%,#ffffff 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1e5799', endColorstr='#ffffff',GradientType=0 ); /* IE6-9 */
}
.hero-unit h1, .hero-unit p.white { color: white; }
.hero-unit h1 img { vertical-align: bottom; }
.hero-unit p { margin-top: 30px; }
.film_roll_wrapper img {
border: 10px solid white;
box-shadow: 7px 7px 15px #777;
margin-left: 5px;
margin-right: 5px;
transition: all 1s ease;
}
.film_roll_wrapper .active img {
border: 10px solid yellow;
height: 600px;
}
.film_roll_container {
position: relative;
}
.film_roll_child.active {
padding-top: 70px;
}
#media (max-width: 979px) {
body {
padding-top: 0px;
}
.navbar-fixed-top {
margin-bottom: 0;
}
}
#media (max-width: 767px) {
.hero-unit {
margin-left: -20px;
margin-right: -20px;
}
}
</style>
</head>
<body>
<div id='film_roll_1'>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<script src="https://www.jqueryscript.net/demo/Easy-Responsive-jQuery-Carousel-Slider-Plugin-FilmRoll/js/bootstrap.min.js"></script>
<!--<script src="https://www.jqueryscript.net/demo/Easy-Responsive-jQuery-Carousel-Slider-Plugin-FilmRoll/js/jquery.film_roll.js"></script>-->
<script type="text/javascript">
(function() {
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
this.FilmRoll = (function() {
function FilmRoll(options) {
this.options = options != null ? options : {};
this.rotateRight = __bind(this.rotateRight, this);
this.rotateLeft = __bind(this.rotateLeft, this);
this.moveRight = __bind(this.moveRight, this);
this.moveLeft = __bind(this.moveLeft, this);
this.clearScroll = __bind(this.clearScroll, this);
this.configureScroll = __bind(this.configureScroll, this);
this.configureWidths = __bind(this.configureWidths, this);
this.configureHover = __bind(this.configureHover, this);
if (this.options.container) {
this.div = jQuery(this.options.container);
if (this.div.length) {
this.configure();
}
}
}
FilmRoll.prototype.configure = function() {
var first_child, shuttle_width,
_this = this;
this.children = this.div.children();
this.children.wrapAll('<div class="film_roll_wrapper"></div>');
this.children.wrapAll('<div class="film_roll_shuttle"></div>');
this.wrapper = this.div.find('.film_roll_wrapper');
this.shuttle = this.div.find('.film_roll_shuttle');
this.rotation = [];
shuttle_width = this.options.shuttle_width ? parseInt(this.options.shuttle_width, 10) : 10000;
this.shuttle.width(shuttle_width);
this.height = this.options.height ? parseInt(this.options.height, 10) : 0;
this.wrapper.height(this.height);
this.shuttle.height(this.height);
if (!(this.options.no_css === true || document.film_roll_styles_added)) {
jQuery("<style type='text/css'> .film_roll_wrapper {display: block; text-align: center; float: none; position: relative; top: auto; right: auto; bottom: auto; left: auto; z-index: auto; width: 100%; margin: 0 !important; padding: 0 !important; overflow: hidden; width: 100%} .film_roll_shuttle {text-align: left; float: none; position: absolute; top: 0; left:0; right: auto; bottom: auto; margin: 0 !important; padding: 0 !important; z-index: auto} .film_roll_prev, .film_roll_next {position:absolute; top:48%; left:15px; width:40px; height:40px; margin:-20px 0 0 0; padding:0; font-size:60px; font-weight:100; line-height:30px; color:white; text-align: center; background: #222; border: 3px solid white; border-radius:23px; opacity:0.5} .film_roll_prev:hover, .film_roll_next:hover {color:white; text-decoration:none; opacity:0.9} .film_roll_next {left:auto; right:15px} .film_roll_pager {text-align:center} .film_roll_pager a {width:5px; height:5px; border:2px solid #333; border-radius:5px; display:inline-block; margin:0 5px 0 0; transition: all 1s ease} .film_roll_pager a:hover {background: #666} .film_roll_pager a.active {background: #333;} .film_roll_pager span {display:none} .film_roll_child .active{padding-top: 70px!important;} </style>").appendTo('head');
document.film_roll_styles_added = true;
}
if (this.options.pager !== false) {
this.pager = jQuery('<div class="film_roll_pager">');
this.div.append(this.pager);
this.children.each(function(i, e) {
var link;
link = jQuery("<a href='#' data-id='" + e.id + "'><span>" + (i + 1) + "</span></a>");
_this.pager.append(link);
return link.click(function() {
var direction, rotation_index;
_this.index = i;
rotation_index = jQuery.inArray(_this.children[i], _this.rotation);
direction = rotation_index < (_this.children.length / 2) ? 'right' : 'left';
_this.moveToIndex(_this.index, direction, true);
return false;
});
});
}
this.pager_links = this.div.find('.film_roll_pager a');
this.mouse_catcher = jQuery('<div style="position:absolute; top:0; left: 0; height: 100%; width: 100%;" class="film_roll_mouse_catcher"></div>');
this.mouse_catcher.appendTo(this.wrapper).mousemove(function(event) {
_this.clearScroll();
return _this.mouse_catcher.remove();
});
first_child = null;
this.children.each(function(i, e) {
var $el;
$el = jQuery(e);
$el.attr('style', 'position:relative; display:inline-block; vertical-align:middle');
$el.attr('data-film-roll-child-id', i);
$el.addClass("film_roll_child");
return _this.rotation.push(e);
});
if (this.options.prev && this.options.next) {
this.prev = jQuery(this.options.prev);
this.next = jQuery(this.options.next);
} else {
this.wrapper.append('<a class="film_roll_prev" href="#">‹</a>');
this.wrapper.append('<a class="film_roll_next" href="#">›</a>');
this.prev = this.div.find('.film_roll_prev');
this.next = this.div.find('.film_roll_next');
}
this.prev.click(function() {
_this.clearScroll();
return _this.moveRight();
});
this.next.click(function() {
_this.clearScroll();
return _this.moveLeft();
});
this.index = this.options.start_index || 0;
this.interval = this.options.interval || 4000;
this.animation = this.options.animation || this.interval / 4;
jQuery(window).resize(function() {
return _this.resize();
});
jQuery(window).load(function() {
_this.configureWidths();
_this.moveToIndex(_this.index, 'right', true);
if (_this.options.scroll !== false) {
_this.configureScroll();
return _this.configureHover();
}
});
this.div.trigger(jQuery.Event("film_roll:dom_ready"));
return this;
};
FilmRoll.prototype.configureHover = function() {
this.div.hover(this.clearScroll, this.configureScroll);
if (this.options.prev && this.options.next) {
this.prev.hover(this.clearScroll, this.configureScroll);
return this.next.hover(this.clearScroll, this.configureScroll);
}
};
FilmRoll.prototype.configureWidths = function() {
var max_el_height,
_this = this;
this.div.trigger(jQuery.Event("film_roll:before_loaded"));
this.width = max_el_height = 0;
this.children.each(function(i, e) {
var $el, el_height;
$el = jQuery(e);
_this.width += $el.outerWidth(true);
el_height = $el.outerHeight(true);
if (el_height > max_el_height) {
return max_el_height = el_height;
}
});
if (!this.options.height) {
this.height = max_el_height;
}
this.wrapper.height(this.height);
this.shuttle.height(this.height);
this.real_width = this.width;
this.shuttle.width(this.real_width * 2);
return this;
};
FilmRoll.prototype.configureScroll = function() {
var _this = this;
if (this.scrolled !== true) {
this.timer = setInterval(function() {
return _this.moveLeft();
}, this.interval);
this.scrolled = true;
}
return this;
};
FilmRoll.prototype.clearScroll = function() {
if (this.scrolled !== false) {
clearInterval(this.timer);
this.scrolled = false;
}
return this;
};
FilmRoll.prototype.marginLeft = function(rotation_index, offset) {
var child, i, margin, _i, _len, _ref;
if (offset == null) {
offset = 0;
}
margin = 0;
_ref = this.rotation;
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
child = _ref[i];
if (i < rotation_index && i >= offset) {
margin += jQuery(child).outerWidth(true);
}
}
return margin;
};
FilmRoll.prototype.marginRight = function(rotation_index, offset) {
var child, i, margin, _i, _len, _ref;
if (offset == null) {
offset = 0;
}
offset = this.rotation.length - offset - 1;
margin = 0;
_ref = this.rotation;
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
child = _ref[i];
if (i > rotation_index && i <= offset) {
margin += jQuery(child).outerWidth(true);
}
}
return margin;
};
FilmRoll.prototype.moveLeft = function() {
this.index = (this.index + 1) % this.children.length;
this.moveToIndex(this.index, 'left', true);
return false;
};
FilmRoll.prototype.moveRight = function() {
this.index -= 1;
if (this.index < 0) {
this.index = this.children.length - 1;
}
this.moveToIndex(this.index, 'right', true);
return false;
};
FilmRoll.prototype.moveToIndex = function(index, direction, animate) {
var child, new_left_margin, rotation_index, visible_margin, wrapper_width,
_this = this;
if (animate == null) {
animate = true;
}
child = this.children[index];
rotation_index = jQuery.inArray(child, this.rotation);
this.children.removeClass('active');
jQuery(child).addClass('active').trigger(jQuery.Event("film_roll:activate"));
this.pager_links.removeClass('active');
jQuery(this.pager_links[index]).addClass('active');
wrapper_width = this.wrapper.width();
if (wrapper_width < this.real_width) {
visible_margin = (wrapper_width - jQuery(child).outerWidth(true)) / 2;
if (direction === 'right') {
while (rotation_index === 0 || this.marginLeft(rotation_index) < visible_margin) {
this.rotateRight();
rotation_index = jQuery.inArray(child, this.rotation);
}
} else {
while (rotation_index === this.children.length - 1 || this.marginRight(rotation_index) < visible_margin) {
this.rotateLeft();
rotation_index = jQuery.inArray(child, this.rotation);
}
}
new_left_margin = -1 * (this.marginLeft(rotation_index) - visible_margin);
if (animate) {
this.shuttle.stop().animate({
'left': new_left_margin
}, this.animation, 'swing', function() {
return _this.div.trigger(jQuery.Event("film_roll:moved"));
});
} else {
this.shuttle.css('left', new_left_margin);
this.div.trigger(jQuery.Event("film_roll:moved"));
}
} else {
this.shuttle.css('left', (wrapper_width - this.width) / 2);
}
return this;
};
FilmRoll.prototype.resize = function() {
var _this = this;
this.clearScroll();
clearTimeout(this.resize_timer);
this.resize_timer = setTimeout(function() {
_this.configureScroll();
_this.moveToIndex(_this.index, 'left');
return _this.div.trigger(jQuery.Event("film_roll:resized"));
}, 200);
return this;
};
FilmRoll.prototype.rotateLeft = function() {
var _css_left, _first_child, _shuttle_left;
_css_left = this.shuttle.css('left');
_shuttle_left = _css_left ? parseInt(_css_left, 10) : 0;
_first_child = this.rotation.shift();
this.rotation.push(_first_child);
this.shuttle.css('left', _shuttle_left + jQuery(_first_child).outerWidth(true));
return this.shuttle.append(this.shuttle.children().first().detach());
};
FilmRoll.prototype.rotateRight = function() {
var _css_left, _last_child, _shuttle_left;
_css_left = this.shuttle.css('left');
_shuttle_left = _css_left ? parseInt(_css_left, 10) : 0;
_last_child = this.rotation.pop();
this.rotation.unshift(_last_child);
this.shuttle.css('left', _shuttle_left - jQuery(_last_child).outerWidth(true));
return this.shuttle.prepend(this.shuttle.children().last().detach());
};
return FilmRoll;
})();
}).call(this);
</script>
<script type="text/javascript">
(function() {
jQuery(function() {
this.film_rolls || (this.film_rolls = []);
this.film_rolls['film_roll_1'] = new FilmRoll({
container: '#film_roll_1',
height: 750
});
//return true;
});
}).call(this);
</script>
</body>
</html>
The customer wants the carousel to be modified not from Custom FIeld which was easier to do and directly from the Elementor.So I tried to create my own widget for that.
after a tutorial on youtube and using information from the official documentation from Elementor
Website and I created the following files.
The filles are situated in boostrap4-child in a folder call custom_widget_elementor after I created this php files in boostrap4-child theme in a folder call custom_widget_elementor.
//my-widgets.php
<?php
class My_Elementor_Widgets {
protected static $instance = null;
public static function get_instance() {
if ( ! isset( static::$instance ) ) {
static::$instance = new static;
}
return static::$instance;
}
protected function __construct() {
require_once('widget1.php');
add_action( 'elementor/widgets/widgets_registered', [ $this, 'register_widgets' ] );
}
public function register_widgets() {
\Elementor\Plugin::instance()->widgets_manager->register_widget_type( new \Elementor\My_Widget_1() );
}
}
add_action( 'init', 'my_elementor_init' );
function my_elementor_init() {
My_Elementor_Widgets::get_instance();
}
?>
//widget1.php
<?php
namespace Elementor;
class My_Widget_1 extends Widget_Base {
public function get_name() {
return 'title-subtitle';
}
public function get_title() {
return 'title & sub-title';
}
public function get_icon() {
return 'fa fa-font';
}
public function get_categories() {
return [ 'basic' ];
}
protected function _register_controls() {
$this->start_controls_section(
'section_title',
[
'label' => __( 'Content', 'elementor' ),
]
);
$this->add_control(
'title',
[
'label' => __( 'Title', 'elementor' ),
'label_block' => true,
'type' => Controls_Manager::TEXT,
'placeholder' => __( 'Enter your title', 'elementor' ),
]
);
$this->add_control(
'subtitle',
[
'label' => __( 'Sub-title', 'elementor' ),
'label_block' => true,
'type' => Controls_Manager::TEXT,
'placeholder' => __( 'Enter your sub-title', 'elementor' ),
]
);
$this->add_control(
'link',
[
'label' => __( 'Link', 'elementor' ),
'type' => Controls_Manager::URL,
'placeholder' => __( 'https://your-link.com', 'elementor' ),
'default' => [
'url' => '',
]
]
);
$this->end_controls_section();
}
protected function render() {
$settings = $this->get_settings_for_display();
$url = $settings['link']['url'];
echo "<a href='$url'><div class='title'>$settings[title]</div> <div class='subtitle'>$settings[subtitle]</div></a>";
}
protected function _content_template() {
}
}
?>
In child theme in function.php as I see in exemple i write this.
//Function.php
require_once('elementor_custom_catousel/widget1.php');
But this does not work, although I have tried as many examples from the official documentation.that is, when I save, nothing appears in the basic categories in the elementor if i would solve this problem to build a carousel i just need to make html template.
Clearly mentioned on Official Documentation.
First, you need to register "elementor/widgets/widgets_registered" hook with a function. For Themes apply you can apply this way -
//Add Elementor Widgets
add_action('elementor/widgets/widgets_registered', 'widgets_registered');
public function widgets_registered() {
// We check if the Elementor plugin has been installed / activated.
if (defined('ELEMENTOR_PATH') && class_exists('Elementor\Widget_Base')) {
$files_directory = get_template_directory() . '/widgets/*.php';
$files = glob( $files_directory );
foreach($files as $widgets){
require_once $widgets;
}
}
}
Create a directory name "widgets", place all widget files. On this directory all Addons will be registered.

Message successfully sent with ajax and php but no email

I found a template and everything works fine, but I don't know what is going on..
here is HTML code
<form action="#" id="contactform" class="animform"><!-- Contact form -->
<ul>
<li>
<label for="name" class="flabel">Name</label>
<input type="text" name="name" value="" id="name" />
<div class="indicate-name"></div>
</li>
<li>
<label for="email" class="flabel">E-mail</label>
<input type="text" name="email" value="" id="email" />
<div class="indicate-email"></div>
</li>
<li>
<label for="message" class="flabel">Enter your message</label>
<textarea name="message" cols="88" rows="6" id="message"></textarea>
<div class="indicate-message"></div>
</li>
<li>
<button type="submit" name="submit" value="Send your message" class="submit">Send your message</button>
</li>
</ul>
</form><!-- /Contact form -->
and here's jQ code
$(function () {
'use strict';
(function () {
var MIN_NAME_LENGTH = 2,
MIN_TEXT_LENGTH = 5,
NAME_ERROR_TEXT = 'Minimum 2 characters',
EMAIL_ERROR_TEXT = 'Please enter correct e-mail',
MSG_ERROR_TEXT = 'Minimum 5 characters',
ERROR_CLASS_NAME = 'error',
SUCCESS_CLASS_NAME = 'ok',
$contactForm = $('#contactform'),
$formSuccess = $('.form-success'),
$nameField = $contactForm.find('#name'),
$emailField = $contactForm.find('#email'),
$textField = $contactForm.find('#message');
function init() {
_bindEvents();
}
function _bindEvents() {
$('.new-message').click(function() {
$contactForm.delay(600).slideDown(1000);
$formSuccess.slideUp(500);
});
$nameField.live('blur', _nameValidate);
$emailField.live('blur', _emailValidate);
$textField.live('blur', _textValidate);
$contactForm.live('submit', function () {
var status = _nameValidate(true) & _emailValidate(true) & _textValidate(true);
if (!!status) {
_submitForm();
}
return false;
});
}
function _submitForm() {
var data = {
name: $("#form_name").val(),
email: $("#form_email").val(),
message: $("#msg_text").val()
};
$.ajax({
type: "post",
url: "contact.php",
data:{
'name': $nameField.val(),
'email': $emailField.val(),
'message': $textField.val()
},
success: function (msg) {
if (msg === 'SEND') {
$contactForm.slideUp(1000);
$formSuccess.delay(1000).slideDown(500);
setTimeout( function() {
// clear form value, shown labels
$nameField.val('');
$emailField.val('');
$textField.val('');
$contactForm.find( 'label[for="'+$nameField.attr( 'id' )+'"]').css( 'display', 'block').css( 'opacity', 1 );
$contactForm.find( 'label[for="'+$emailField.attr( 'id' )+'"]').css( 'display', 'block').css( 'opacity', 1 );
$contactForm.find( 'label[for="'+$textField.attr( 'id' )+'"]').css( 'display', 'block').css( 'opacity', 1 );
}, 1000 );
}
else {
$contactForm.prepend( '<div class="error">' + msg + '</div>' );
}
},
error: function( t, errorStatus ) {
$contactForm.prepend( '<div class="error">' + errorStatus + '</div>' );
},
beforeSend: function() {
$(".error,.success").remove();
}
});
}
function _nameValidate(errIfEmpty) {
var $memo = $contactForm.find('.indicate-name'),
val = $nameField.val().replace(/\s+$/g, ''),
result = false;
errIfEmpty = errIfEmpty === true ? true : false;
if (!errIfEmpty && val.length === 0) {
$memo
.text('')
.removeClass(SUCCESS_CLASS_NAME)
.removeClass(ERROR_CLASS_NAME);
} else {
if (val.length >= MIN_NAME_LENGTH) {
$memo
.text('')
.removeClass(ERROR_CLASS_NAME)
.addClass(SUCCESS_CLASS_NAME);
result = true;
} else {
$memo
.text(NAME_ERROR_TEXT)
.removeClass(SUCCESS_CLASS_NAME)
.addClass(ERROR_CLASS_NAME);
}
}
return result;
}
function _emailValidate(errIfEmpty) {
var $memo = $contactForm.find('.indicate-email'),
val = $emailField.val().replace(/\s+$/g, ''),
regExp = /^.+#.+\..{2,6}$/i,
result = false;
errIfEmpty = errIfEmpty === true ? true : false;
if (!errIfEmpty && val.length === 0) {
$memo
.text('')
.removeClass(SUCCESS_CLASS_NAME)
.removeClass(ERROR_CLASS_NAME);
} else {
if (regExp.test(val)) {
$memo
.text('')
.removeClass(ERROR_CLASS_NAME)
.addClass(SUCCESS_CLASS_NAME);
result = true;
} else {
$memo
.text(EMAIL_ERROR_TEXT)
.removeClass(SUCCESS_CLASS_NAME)
.addClass(ERROR_CLASS_NAME);
}
}
return result;
}
function _textValidate(errIfEmpty) {
var $memo = $contactForm.find('.indicate-message'),
val = $textField.val().replace(/\s+$/g, ''),
result = false;
errIfEmpty = errIfEmpty === true ? true : false;
if (!errIfEmpty && val.length === 0) {
$memo
.text('')
.removeClass(SUCCESS_CLASS_NAME)
.removeClass(ERROR_CLASS_NAME);
} else {
if (val.length >= MIN_TEXT_LENGTH) {
$memo
.text('')
.removeClass(ERROR_CLASS_NAME)
.addClass(SUCCESS_CLASS_NAME);
result = true;
} else {
$memo
.text(MSG_ERROR_TEXT)
.removeClass(SUCCESS_CLASS_NAME)
.addClass(ERROR_CLASS_NAME);
}
}
return result;
}
init();
})();
});
and this is the php code:
<?php
$to = 'myEmail#anyEmail.com';
$from = $_POST['email'];
$name = $_POST['name'];
$subject = "Message from site";
$theMessage = $_POST['message'];
$message = "This message from \n\n Name: " . $name . "\n\n";
$message .= "Enquiries: " . $theMessage . "\n\n";
$headers = "From: $from\r\n";
$headers .= "Reply-To: $from\r\n";
if (mail($to, $subject, $message, $headers)) {
echo "SEND";
}else{
echo "Error";
}
//print_r(error_get_last());?>
The form does say success, but still not receiving the emails! any ideas?
P.S. I tried two different Emails "hotmail" and "ymail", but the two of them didn't receive anything..
thanks
Send email trought php need a smtp configuration.
The mail() function return true if he successfull order to the system to send the mail.
But if you have trouble with your smtp, the mail will never arrive.
Then you will have to format your headers correctly http://php.net/manual/fr/function.mail.php

Send field form array by AJAX and get it on php in Wordpress

I'm making a plugin on Wordpress to send emails to our clients. I have a trouble with a field array type of form, because i can't get it on PHP function. I can get single fields, as subject or message, but not email field (it's an array creted dynamically for clients that have multiple emails)
Here my form code
echo '<form id="myform" method="post">';
echo "<ul>";
echo "<li><strong>¿Cual es el destinatario del email? (pueden ser varios)</strong></li>";
if( get_field('contactos',$post_id) ):
while( has_sub_field('contactos',$post_id) ):
echo "<li style='margin-left: 45px; margin-top: 15px;'><input type='checkbox' id='emails[]' value='".get_sub_field('email',$post_id)."'>"
.get_sub_field('nombre',$post_id)." (".get_sub_field('email',$post_id)." )</li>";
endwhile;
endif;
echo '<li style="margin-top: 15px;"><strong><label for="subject">Asunto: </label></strong>';
echo '<input id="subject" maxlength="45" size="30" name="subject"></li>';
echo "<p>Texto del mensaje</p>";
echo '<textarea id="cuerpo" class="textarea" name="cuerpo" placeholder="" style="
width: 600px;
height: 200px;
"></textarea><br>';
echo '<li style="margin-top: 35px;"><input id="send" name="submit" type="submit" value="Enviar eMail" class="button button-primary button-large"></li>';
echo "</form>";
Here ajax.js
$( "#myform" ).submit(function( event ) {
event.preventDefault();
alert( "Handler for .submit() called." );
$(function() {
$('#sendingemails').fadeIn();
var subject = $("#subject").val();
var cuerpo = $("#cuerpo").val();
$.ajax({
type: 'POST',
url: GestionAjax.ajaxurl,
data: { action: 'email', subject : subject, cuerpo : cuerpo, emails : $('#emails').serialize() },
// Mostramos un mensaje con la respuesta de PHP
success: function(data) {
alert("enviado");
$('#sendingemails').fadeOut();
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Status: " + textStatus); alert("Error: " + errorThrown);
alert (jsonString);
}
})
});
});
and here the function that recive data:
function AC_ONEmail() {
$emails = array();
$emails = $_POST['emails'];
$message = $_POST['cuerpo'];
$subject = $_POST['subject'];
add_action('phpmailer_init','send_smtp_email');
$headers[] = 'From: '.$current_user->display_name.' '.$current_user->user_email;
add_filter( 'wp_mail_content_type', 'my_custom_email_content_type' );
$message .= '<br><br>'.nl2br($current_user->firma);
foreach ($emails as $email) {
$result=wp_mail( $email, $subject, $message, $headers);
if (!$result) {
global $ts_mail_errors;
global $phpmailer;
if (!isset($ts_mail_errors)) $ts_mail_errors = array();
if (isset($phpmailer)) {
$ts_mail_errors[] = $phpmailer->ErrorInfo;
}
} else {
global $wpdb;
$wpdb->insert(
'wp_comunicaciones',
array(
'post_id' => $idcliente,
'asunto' => $datos2,
'cuerpo' => $message,
'fecha' => date("Ymd"),
'responsable' => $current_user->display_name,
'email' => $email[0]
)
);
/*envio del email a una carpeta del servidor
$mail_string = "From: ".$current_user->user_email."\r\n". "To: ".$value."\r\n"."Subject: ".$_POST['subject']."\r\n"."\r\n".$_POST['cuerpo']."\r\n";
$stream = imap_open("{smtp.office365.com}Elementos enviados", $current_user->cuenta_usuario, $current_user->passwordSMTP);
imap_append($stream, "{smtp.office365.com}Elementos enviados", $mail_string, "\\Seen");
*/
}
}
$arr = array( "asunto" => $_POST['subject'], "cuerpo" => $_POST['cuerpo'], "emails" => $_POST['emails']);
echo json_encode($arr);
wp_die();
}
As i said, i debug vars on console (network tab on chrome), and subject and message have values, but don't clientes (an array type field)
I see a lot of info here, on stackoverflow, i try to do by different ways, but i spend two days on it, and now i need your knowledge. How can i do it?
Thanks
UPDATE SOLUTION
I take a solution
On ajax script i change data line with this data: { action: 'email', datos : $('#myform').serialize() }, and on function that recive data i insert parse_str($_POST['datos'], $arraydatos); Then i take data with $arraydatos['emails'] or field that i want. It works fine!
I take a solution to do it
I change ajax.js with this
$( "#myform" ).submit(function( event ) {
event.preventDefault();
$(function() {
$('#sendingemails').fadeIn();
tinyMCE.triggerSave();
$.ajax({
type: 'POST',
url: GestionAjax.ajaxurl,
data: { action: 'email', datos : $('#myform').serialize() },
// Mostramos un mensaje con la respuesta de PHP
success: function(data) {
alert("eMail enviado con éxito");
$('#sendingemails').fadeOut();
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Status: " + textStatus); alert("Error: " + errorThrown);
alert (jsonString);
}
})
});
});
and on function that recive data i change by this
function AC_ONEmail() {
$current_user = wp_get_current_user();
$attachments = array();
$num_archivos = 0;
parse_str($_POST['datos'], $arraydatos);
add_action('phpmailer_init','send_smtp_email');
add_filter( 'wp_mail_content_type', 'my_custom_email_content_type' );
$headers[] = 'From: '.$current_user->display_name.' '.$current_user->user_email;
$archivos = $arraydatos['archivos'];
foreach ($archivos as $archivo=>$i) {
array_push($attachments, get_attached_file( $i ));
$num_archivos++;
}
$message = $arraydatos['cuerpo'];
$message .= '<br><br>'.nl2br($current_user->firma);
$emails = $arraydatos['emails'];
foreach ($emails as $email) {
$result=wp_mail( $email, $arraydatos['subject'], $message, $headers, $attachments);
if (!$result) {
global $ts_mail_errors;
global $phpmailer;
if (!isset($ts_mail_errors)) $ts_mail_errors = array();
if (isset($phpmailer)) {
$ts_mail_errors[] = $phpmailer->ErrorInfo;
}
} else {
global $wpdb;
$wpdb->insert(
'wp_comunicaciones',
array(
'post_id' => $arraydatos['post_id'],
'asunto' => $arraydatos['subject'],
'cuerpo' => $arraydatos['cuerpo'],
'fecha' => date("Ymd"),
'responsable' => $current_user->display_name,
'email' => $email,
archivos => $num_archivos
)
);
/*$mail_string = "From: ".$current_user->user_email."\r\n". "To: ".$value."\r\n"."Subject: ".$_POST['subject']."\r\n"."\r\n".$_POST['cuerpo']."\r\n";
$stream = imap_open("{smtp.office365.com}Elementos enviados", $current_user->cuenta_usuario, $current_user->passwordSMTP);
imap_append($stream, "{smtp.office365.com}Elementos enviados", $mail_string, "\\Seen");*/
}
}
echo $result;
wp_die();
}
I explain changes. I send all form serialized to php function that recive data. On PHP function i read data and parse it to an array parse_str($_POST['datos'], $arraydatos);.
Then i can get all data with $arraydatos['form_field'], and use it, including form array fields.
For content i use a wp_editor function. To get it on PHP function i include on ajax tinyMCE.triggerSave(). Without it, 'cuerpo' field was empty
Thanks

chat app using jquery/ajax/php/oop codeigniter

Hi this question relates to a recent question I had posted that I'm trying to find at least some help with in general that leads to solve the entire problem.
The following code is not mine and I had to fix it just to get it working to the extent it is now but the problem the algorithm within _get_chat_messages continues to execute the else condition. This doesn't make sense because there's chat message data in Mysql. I'm trying to make this source code work hoping it will lead me in the right direction with refreshing chat message content automatically without forcing browser client refreshes or redirecting headers.
What's causing _get_chat_messages to execute the else condition disregarding the if condition. The if conditions seems to evaluate to TRUE which doesn't make sense.
Any help much appreciated. Thanks.
//JQUERY/AJAX:
$(document).ready(function() {
setInterval(function() { get_chat_messages(); } , 2500);
$("input#chat_message").keypress(function(e) {
if (e.which == 13) {
$("a#submit_message").click();
return false;
}
});
$("#submit_message").click(function() {
var chat_message_content = $("input#chat_message").val();
//this if condition seems to be ignored not sure why?
if (chat_message_content == "") { return false; }
$.post(base_url + "chat/ajax_add_chat_message", { chat_message_content : chat_message_content, chat_id : chat_id, user_id : user_id }, function(data) {
if (data.status == 'ok')
{
var current_content = $("div#chat_viewport").html();
$("div#chat_viewport").html(current_content + data.message_content);
}
else
{
// there was an error do something
}
}, "json");
$("input#chat_message").val("");
return false;
});
function get_chat_messages()
{
$.post(base_url + "chat/ajax_get_chat_messages", { chat_id : chat_id }, function(data) {
if (data.status == 'ok')
{
var current_content = $("div#chat_viewport").html();
$("div#chat_viewport").html(current_content + data.message_content);
}
else
{
// there was an error do something
}
}, "json");
}
get_chat_messages();
});
//CONTROLLER:
class Chat extends CI_Controller {
public function __construct()
{
parent:: __construct();
$this->load->model('chat_model');
}
public function index()
{
/* send in chat id and user id */
$this->view_data['chat_id'] = 1;
// check they are logged in
if (! $this->session->userdata('logged_in')) {
redirect('user/login');
}
$this->view_data['user_id'] = $this->session->userdata('user_id');
$this->session->set_userdata('last_chat_message_id_' . $this->view_data['chat_id'], 0);
$this->view_data['page_title'] = 'web based chat app :)';
$this->view_data['page_content'] = 'view_chat';
$this->load->view('view_main', $this->view_data);
}
public function ajax_add_chat_message()
{
/* Scalar Variable data that needs to be POST'ed to this function
*
* chat_id
* user_id
* chat_message_content
* *
*/
$chat_id = $this->input->post('chat_id');
$user_id = $this->input->post('user_id');
$chat_message_content = $this->input->post('chat_message', TRUE);
$this->chat_model->add_chat_message($chat_id, $user_id, $chat_message_content);
// grab and return all messages
$this->ajax_get_chat_messages($chat_id);
}
public function ajax_get_chat_messages($chat_id)
{
$chat_id = $this->input->post('chat_id');
echo $this->_get_chat_messages($chat_id);
}
private function _get_chat_messages($chat_id)
{
$last_chat_message_id = (int)$this->session->userdata('last_chat_message_id_' . $chat_id);
$chat_messages = $this->chat_model->get_chat_messages($chat_id, $last_chat_message_id);
if ($chat_messages->num_rows() > 0)
{
// store the last chat message id
$last_chat_message_id = $chat_messages->row($chat_messages->num_rows() - 1)->chat_message_id;
$this->session->set_userdata('last_chat_message_id_' . $chat_id, $last_chat_message_id);
// we have some chat let's return it
$chat_messages_html = '<ul>';
foreach ($chat_messages->result() as $chat_message)
{
$li_class = ($this->session->userdata('user_id') == $chat_message->user_id) ? 'class="by_current_user"' : '';
$chat_messages_html .= '<li ' . $li_class . '>' . '<span class="chat_message_header">' . $chat_message->chat_message_timestamp . ' by ' . $chat_message->name . '</span><p class="message_content">' . $chat_message->chat_message_content . '</p></li>';
}
$chat_messages_html .= '</ul>';
$result = array('status' => 'ok', 'content' => $chat_messages_html);
//header('Content-Type: application/json',true);
return json_encode($result);
exit();
}
else
{
// we have no chat yet
$result = array('status' => 'no chat', 'content' => '');
//header('Content-Type: application/json',true);
return json_encode($result);
exit();
}
}
}
//MODEL:
class chat_model extends CI_Model {
public function __construct()
{
parent::__construct();
}
public function add_chat_message($chat_id, $user_id, $chat_message_content)
{
$query_str = "INSERT INTO chat_messages (chat_id, user_id, chat_message_content) VALUES (?, ?, ?)";
$this->db->query($query_str, array($chat_id, $user_id, $chat_message_content));
}
public function get_chat_messages($chat_id, $last_chat_message_id = 0)
{
$query_str = "SELECT
cm.chat_message_id,
cm.user_id,
cm.chat_message_content,
DATE_FORMAT(cm.create_date, '%D of %M %Y at %H:%i:%s') AS chat_message_timestamp,
u.name
FROM chat_messages cm
JOIN users u ON cm.user_id = u.user_id
WHERE cm.chat_id = ?
and cm.chat_message_id > ?
ORDER BY cm.chat_message_id ASC";
$result = $this->db->query($query_str, array($chat_id, $last_chat_message_id));
return $result;
}
}
//VIEW FILE HENCE VIEW_CHAT.PHP
<html>
<head>
<script type="text/javascript" src="/js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="<?php echo base_url() . 'public/';?>chat.js">
</script>
<script type="text/javascript">
var base_url = "<?php echo base_url();?>";
var chat_id = "<?php echo $chat_id; ?>";
var user_id = "<?php echo $user_id; ?>";
</script>
</head>
<body>
<style type="text/css">
div#chat_viewport {
font-family:Verdana, Arial, sans-serif;
padding:5px;
border-top:2px dashed #585858;
min-height:300px;
color:black;
max-height:650px;
overflow:auto;
margin-bottom:10px;
width:750px;
}
div#chat_viewport ul {
list-style-type:none;
padding-left:10px;
}
div#chat_viewport ul li {
margin-top:10px;
width:85%;
}
span.chat_message_header {
font-size:0.7em;
font-family:"MS Trebuchet", Arial, sans-serif;
color:#547980;
}
p.message_content {
margin-top:0px;
margin-bottom:5px;
padding-left:10px;
margin-right:0px;
}
input#chat_message {
margin-top:5px;
border:1px solid #585858;
width:70%;
font-size:1.2em;
margin-right:10px;
}
input#submit_message {
font-size:2em;
padding:5px 10px;
vertical-align:top;
margin-top:5px;
}
div#chat_input { margin-bottom:10px; }
div#chat_viewport ul li.by_current_user span.chat_message_header {
color:#e9561b;
}
</style>
<h1>Let's do some chatting :D</h1>
<div id="chat_viewport">
</div>
<div id="chat_input">
<?php echo form_open('chat/ajax_add_chat_message'); ?>
<input id="chat_message" name="chat_message" type="text" value="" tabindex="1" />
<?php echo form_submit('submit_message','submit_message'); ?>
<?php echo anchor('#', 'Say it', array('title' => 'Send this chat message', 'id' => 'submit_message'));?>
<div class="clearer"></div>
<?php echo form_close(); ?>
</div>
</body>
</html>
I am not sure but I have a feeling that the json that you receive from the server is not formatted properly. See this: jQuery won't parse my JSON from AJAX query

Categories