'new',
'2' => 'taken & not contacted',
'3' => 'contacted',
'4' => 'pending',
'5' => 'followup',
'6' => 'finalized',
'7' => 'rejected',
);
/**
* Load the resources
*/
public function __construct($wpdb, $prefix)
{
$this -> _db = &$wpdb;
$this -> _prefix = $prefix;
}
/**
* Run at plugin activation
*/
public function constructSQL()
{
$sqls = array();
$sqls[] = "CREATE TABLE IF NOT EXISTS `{$this->_prefix}59_leads` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`entity_id` bigint(20) NOT NULL,
`subject` varchar(255) NOT NULL,
`user_comments` text,
`user_name` varchar(256) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
`status` varchar(100) DEFAULT NULL,
`boss_alert` int(1) NOT NULL,
`agent_alert` int(1) NOT NULL,
`type` varchar(10) NOT NULL,
`created_time` varchar(10) DEFAULT NULL,
`reserved_time` varchar(10) DEFAULT NULL,
`completed_time` varchar(10) DEFAULT NULL,
`postdata` text NOT NULL,
`flag` INT(1) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
";
$sqls[] = "CREATE TABLE IF NOT EXISTS `{$this->_prefix}59_tokens` (
`id` INT NOT NULL AUTO_INCREMENT,
`device_token` VARCHAR(255) NOT NULL,
`uid` INT NOT NULL,
`type` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
";
return $sqls;
}
/**
* Run at plugin deactivation
*/
public function destructSQL()
{
// $tableName = $this->_prefix.'59_leads';
// return "DROP TABLE IF EXISTS `{$tableName}`";
}
/**
* Update from old version to current version.
*/
public function updateVersion($version)
{
$version = str_replace('.', '', $version);
if ($version < 101)
{
// new db column
$sql = "ALTER TABLE `{$this -> _prefix}59_tokens` ADD `uid` INT NOT NULL AFTER `device_token`";
$this -> _db -> query($sql);
}
if ($version < 330)
{
$sql = "ALTER TABLE `{$this -> _prefix}59_leads` ADD `agent_alert` int(1) NOT NULL AFTER `boss_alert`";
$this -> _db -> query($sql);
$sql = "UPDATE `{$this -> _prefix}59_leads` SET `agent_alert` = 1";
$this -> _db -> query($sql);
}
}
/**
* Add a new lead into the database
*/
public function add($data)
{
// secure the data
$data['type'] = addslashes($data['type']);
$data['entity_id'] = intval($data['entity_id']);
$data['subject'] = addslashes($data['subject']);
$data['status'] = addslashes($data['status']);
$data['created_time'] = time();
$data['postdata'] = addslashes($data['postdata']);
$sql = "INSERT
INTO `{$this -> _prefix}59_leads` (`type`, `entity_id`, `subject`, `status`, `created_time`, `postdata`)
VALUES ('{$data['type']}','{$data['entity_id']}','{$data['subject']}','{$data['status']}','{$data['created_time']}','{$data['postdata']}')
";
$this -> _db -> query($sql);
return $this -> _db -> insert_id;
}
/**
* Update one lead in the database.
*/
public function update($data, $id = 0)
{
$id = intval($id);
if (!empty($data))
{
$fields = array();
foreach ($data as $key => $value)
{
$value = addslashes($value);
$fields[] = "`{$key}` = '{$value}'";
}
$fields = implode(', ', $fields);
$sql = "UPDATE `{$this -> _prefix}59_leads`
SET $fields
WHERE `id` = '$id'
";
@$this -> _db -> query($sql);
}
else
{
// should never happen
echo 'Error: missing data!';
}
}
/**
* Construct table headers from serialized email data.
*/
public function tableHeaders(&$results)
{
if (!empty($results))
{
$data = end($results);
$postdata = @unserialize($data['postdata']);
if (!empty($postdata))
{
return array_keys($postdata);
}
}
return array();
}
/**
* Get the number of leads this month as a total limit.
*/
public function isLimitReached()
{
$since = strtotime('first day of this month');
$since = addslashes($since);
$total = 0;
$sql = "SELECT COUNT(*) AS `tot`
FROM `{$this -> _prefix}59_leads`
WHERE `created_time` > '{$since}'
";
$results = $this -> _db -> get_row($sql, ARRAY_A);
if (!empty($results))
{
$total = $results['tot'];
}
if ($total > 20 || $total == 20)
{
return true;
}
return false;
}
/**
* how many leads left ?
*/
public function leadsLeft()
{
$since = strtotime('first day of this month');
$since = addslashes($since);
$total = 0;
$sql = "SELECT COUNT(*) AS `tot`
FROM `{$this -> _prefix}59_leads`
WHERE `created_time` > '{$since}'
";
$r = $this -> _db -> get_row($sql, ARRAY_A);
if (!empty($r))
{
$total = $r['tot'];
}
return 20 - $total;
}
/**
* Get the latest contact form 7 leads
* @used: on leads page
*/
public function getNewLeads($entity_id = 0)
{
$entity_id = intval($entity_id);
$sql = "SELECT *
FROM `{$this -> _prefix}59_leads`
WHERE `entity_id` = '{$entity_id}'
AND `user_id` IS NULL
AND `type` = 'form'
ORDER BY `created_time` ASC
";
$results = $this -> _db -> get_results($sql, ARRAY_A);
return $results;
}
/**
* Get the leads that where notified less the 3 times
*/
public function getNotificationCronLeads10()
{
$time = time() - 600;
$sql = "SELECT *
FROM `{$this -> _prefix}59_leads`
WHERE `agent_alert` < 2
AND `user_id` IS NULL
AND `created_time` < '$time'
ORDER BY `created_time` ASC
";
$results = $this -> _db -> get_results($sql, ARRAY_A);
return $results;
}
/**
* Get the leads that where notified less the 3 times
*/
public function getNotificationCronLeads20()
{
$time = time() - 1200;
$sql = "SELECT *
FROM `{$this -> _prefix}59_leads`
WHERE `agent_alert` = 2
AND `user_id` IS NULL
AND `created_time` < '$time'
ORDER BY `created_time` ASC
";
$results = $this -> _db -> get_results($sql, ARRAY_A);
return $results;
}
/**
* Are there new leads since $time ?
*/
public function checkForNewLeads($time = 0)
{
$sql = "SELECT 1
FROM `{$this -> _prefix}59_leads`
WHERE `user_id` IS NULL
AND `created_time` > '$time'
";
$results = $this -> _db -> get_results($sql, ARRAY_A);
if (empty($results))
{
return 1;
}
return $this -> _db -> num_rows;
}
/**
* Get paged cf7 user leads.
* @used: in crm page.
*/
public function getUserLeads($entity_id = 0, $user_id = 0, $page = 0, $filters = array())
{
$page = intval($page);
$entity_id = intval($entity_id);
$user_id = intval($user_id);
$results = array();
$where = (!empty($user_id)) ? " AND `user_id` = '{$user_id}'" : " AND `user_id` IS NOT NULL";
// filters
foreach ($filters as $key => $value)
{
$value = addslashes($value);
if ($key == 'keyword')
{
$where .= " AND (`user_name` LIKE '%{$value}%' OR `postdata` LIKE '%{$value}%')";
}
else
{
$where .= " AND `{$key}` = '{$value}'";
}
}
// paging init
$start = $page * $this->_itemsPerPage;
$sortBy = $_COOKIE['59sec_sb'];if($sortBy=='') $sortBy='grabbed';
$sortDir = $_COOKIE['59sec_sd'];if($sortDir=='') $sortDir='desc';
$sort = "";
if($sortBy=='time' || $sortBy == '')
$sort = "reserved_time - created_time";
else if($sortBy=='grabbed')
$sort = "reserved_time";
else if($sortBy=='agent')
$sort = "user_id";
$sql = "SELECT *
FROM `{$this -> _prefix}59_leads`
WHERE `entity_id` = '{$entity_id}'
AND `type` = 'form'
{$where}
ORDER BY ".$sort." ".$sortDir."
LIMIT {$start}, {$this->_itemsPerPage}
";
$results = $this -> _db -> get_results($sql, ARRAY_A);
return $results;
}
/**
* Set paging links for contact form 7 tables.
* @used: in crm page
*/
public function pagerUserLeads($entity_id = 0, $user_id = 0, $page = 0, $filters = array())
{
$paging = new stdClass();
$paging -> current = intval($page);
$paging -> pages = array();
$entity_id = intval($entity_id);
$user_id = intval($user_id);
$where = (!empty($user_id)) ? " AND `user_id` = '{$user_id}'" : ' AND `user_id` IS NOT NULL';
// filters
foreach ($filters as $key => $value)
{
$value = addslashes($value);
if ($key == 'keyword')
{
$where .= " AND (`user_name` LIKE '%{$value}%' OR `postdata` LIKE '%{$value}%')";
}
else
{
$where .= " AND `{$key}` = '{$value}'";
}
}
$sql = "SELECT COUNT(`ID`) AS `total`
FROM `{$this -> _prefix}59_leads`
WHERE `entity_id` = '{$entity_id}'
AND `type` = 'form'
{$where}
ORDER BY `created_time` ASC
";
$results = $this -> _db -> get_row($sql, ARRAY_A);
$r = (!empty($results)) ? $results : array();
$totalItems = $r['total'];
$nrPages = ceil($totalItems / $this->_itemsPerPage);
if ($totalItems > $this->_itemsPerPage)
{
for ($i = 0; $i < $nrPages; $i++)
{
$paging -> pages[] = array(
'title' => $i + 1,
'page' => $i,
'active' => ($paging -> current == $i) ? 'active' : '',
);
}
}
$paging -> next = $paging -> current + 1;
$paging -> prev = $paging -> current - 1;
if ($paging -> next == $nrPages || $nrPages == 0)
{
$paging -> next = false;
}
if ($paging -> prev < 0 || $nrPages == 0)
{
$paging -> prev = false;
}
return $paging;
}
/**
* Get data for 1 lead.
* @used: in notes.
*/
public function get($id = 0)
{
$id = intval($id);
$sql = "SELECT *
FROM `{$this -> _prefix}59_leads`
WHERE `id` = '{$id}'
";
$results = $this -> _db -> get_row($sql, ARRAY_A);
$r = $this -> stripslashes_deep($results);
return $r;
}
/**
* Get leads that are not grabbed,
* and not send as boss alert yet.
*/
public function getBossAlertLeads($seconds = 60)
{
$time = time() - $seconds;
$results = array();
$sql = "SELECT *
FROM `{$this -> _prefix}59_leads`
WHERE `reserved_time` IS NULL
AND `boss_alert` = '0'
AND `created_time` < $time
";
$results = $this -> _db -> get_results($sql, ARRAY_A);
return $results;
}
/**
* Get leads that are not grabbed,
* and alert the bosses once a day every day.
*/
public function getBossDailyAlerts()
{
$date = date('Y-m-d H:i:s');
$results = array();
$sql = "SELECT *
FROM `{$this -> _prefix}59_leads`
WHERE `reserved_time` IS NULL
AND `boss_alert` = '1'
";
$results = $this -> _db -> get_results($sql, ARRAY_A);
return $results;
}
/**
* Flag to mark first alert
*/
public function bossAlerted(&$lead)
{
$this -> update(array('boss_alert' => 1), $lead['id']);
}
/**
* Increments the device notifications sent statistics
*/
public function agentNotified($lead)
{
if (!empty($lead) && !empty($lead['id']))
{
$count = $lead['agent_alert'];
$count++;
$this -> update(array('agent_alert' => $count), $lead['id']);
}
}
/**
* User Statistics: average response time
*/
public function getAgentAverageResponse($user_id)
{
$user_id = intval($user_id);
$created = 0;
$reserved = 0;
$count = 1;
$sql = "SELECT *
FROM `{$this -> _prefix}59_leads`
WHERE `user_id` = '{$user_id}'
";
$results = $this -> _db -> get_results($sql, ARRAY_A);
if (!empty($results))
{
foreach ($results as $r)
{
$created += $r['created_time'];
$reserved += $r['reserved_time'];
$count++;
}
$created = round($created / $count);
$reserved = round($reserved / $count);
}
$result = $reserved - $created;
if (empty($result))
{
return 'N/A';
}
return $this->timeFormat($created, $reserved);
}
public function getAgentLeads($user_id, $status = '')
{
$user_id = intval($user_id);
$status = addslashes($status);
$where = (!empty($status)) ? "`status` = '{$status}'" : '';
$sql = "SELECT COUNT(*) AS `total`
FROM `{$this -> _prefix}59_leads`
WHERE `user_id` = '{$user_id}'
{$where}
ORDER BY `created_time` ASC
";
$results = $this -> _db -> get_row($sql, ARRAY_A);
if (!empty($results))
{
return $results['total'];
}
return 0;
}
public function getTotalUnansweredLeads()
{
$out = 0;
if (_59SEC_REQUIREMENTS)
{
$forms = (array) get_option('59sec_wpcf7');
$formIds = implode(',', $forms);
$sql = "SELECT COUNT(*) AS `total`
FROM `{$this -> _prefix}59_leads`
WHERE `user_id` IS NULL
AND `type` = 'form'
AND `entity_id` IN ({$formIds})
";
$results = $this -> _db -> get_row($sql, ARRAY_A);
if (!empty($results))
{
$out += $results['total'];
}
}
return $out;
}
public function getTotalLeads($date)
{
$date1 = date('y-m-d 00:00:01', $date);
$date2 = date('y-m-d 23:59:59', $date);
$date1 = strtotime($date1);
$date2 = strtotime($date2);
$sql = "SELECT COUNT(*) AS `total`
FROM `{$this -> _prefix}59_leads`
WHERE `created_time` BETWEEN '{$date1}' AND '{$date2}'
";
$results = $this -> _db -> get_row($sql, ARRAY_A);
if (!empty($results))
{
return $results['total'];
}
return 0;
}
public function getTotalAgentLeads($user_id = 0, $date)
{
$user_id = intval($user_id);
$date1 = date('y-m-d 00:00:01', $date);
$date2 = date('y-m-d 23:59:59', $date);
$date1 = strtotime($date1);
$date2 = strtotime($date2);
$sql = "SELECT COUNT(*) AS `total`
FROM `{$this -> _prefix}59_leads`
WHERE `user_id` = '{$user_id}'
AND `created_time` BETWEEN '{$date1}' AND '{$date2}'
";
$results = $this -> _db -> get_row($sql, ARRAY_A);
if (!empty($results))
{
return $results['total'];
}
return 0;
}
public function saveAppToken($data)
{
$device_token = $data['device_token'];
$device_token = addslashes($device_token);
$type = addslashes($data['type']);
$key = $data['key'];
$user_login = _59sec_desalt($key);
$user = get_user_by('login', $user_login);
$sql = "DELETE
FROM `{$this -> _prefix}59_tokens`
WHERE `device_token` = '{$device_token}'
AND `type` = '{$type}'
";
$this -> _db -> query($sql);
$sql = "INSERT
INTO `{$this -> _prefix}59_tokens` (`device_token`, `uid`, `type`)
VALUES ('{$device_token}', '{$user->ID}', '{$type}')
";
$this -> _db -> query($sql);
}
public function deleteAppToken($data)
{
$device_token = $data['device_token'];
$device_token = addslashes($device_token);
$type = addslashes($data['type']);
$sql = "DELETE
FROM `{$this -> _prefix}59_tokens`
WHERE `device_token` = '{$device_token}'
AND `type` = '{$type}'
";
$this -> _db -> query($sql);
}
function getAppTokens()
{
$results = array();
$sql = "SELECT `device_token` AS `token`, `type`
FROM `{$this -> _prefix}59_tokens`
";
$results = $this -> _db -> get_results($sql, ARRAY_A);
return $results;
}
/**
* Format lead data as email
*/
public function leadAsMail($lead)
{
$lead = (array) $lead;
$message = '';
$create = date('d/m/y H:i:s', $lead['created_time']);
$postdata = (array) unserialize($lead['postdata']);
$message .= "{$lead['subject']}: \n";
$message .= "created: {$create}: \n";
foreach ($postdata as $key => $value)
{
$message .= "{$key}: {$value}\n";
}
return $message."\n\n";
}
public function leadStatusOptions($status = '')
{
$options = '';
foreach($this -> _statuses as $id => $item)
{
$selected = ($id == $status) ? 'selected="selected"' : '';
$options .= "";
}
return $options;
}
public function leadFilterStatusOptions()
{
$options = "";;
$status = (isset($_POST['status'])) ? $_POST['status'] : '';
foreach($this -> _statuses as $id => $item)
{
$selected = ($id == $status) ? 'selected="selected"' : '';
$options .= "";
}
return $options;
}
public function timeFormat($seconds = 0, $to = 0)
{
if (empty($to))
{
$to = time();
}
$seconds = $to - $seconds;
$time = '';
$hours = intval($seconds / 3600);
$seconds = $seconds - ($hours * 3600);
$minutes = intval($seconds / 60);
$seconds = $seconds - ($minutes * 60);
if ($hours > 0)
{
$time .= $hours.'h ';
}
if ($minutes > 0)
{
$time .= $minutes.'min ';
}
$time .= $seconds.'sec';
return $time;
}
public function grabedAt($timestamp = 0)
{
return date('d/m/y H:i', $timestamp);
}
public function getIP()
{
$ip_address = $_SERVER['REMOTE_ADDR'];
if (!empty($ip_address))
{
return $ip_address;
}
return 'unknown';
}
public function stripslashes_deep($value)
{
if (is_array($value))
{
foreach ($value as $key => $data)
{
if ($key != 'postdata')
{
$value[$key]= stripslashes_deep($data);
}
}
}
elseif (is_object($value))
{
$vars = get_object_vars($value);
foreach ($vars as $key => $data)
{
if ($key != 'postdata')
{
$value->{$key} = stripslashes_deep($data);
}
}
}
elseif (is_string($value))
{
$value = stripslashes($value);
}
return $value;
}
function repairSerializedArray($serialized)
{
$tmp = preg_replace('/^a:\d+:\{/', '', $serialized);
// operates on and whittles down the actual argument
return $this -> repairSerializedArray_R($tmp);
}
function repairSerializedArray_R(&$broken)
{
// array and string length can be ignored
// sample serialized data
// a:0:{}
// s:4:"four";
// i:1;
// b:0;
// N;
$data = array();
$index = null;
$len = strlen($broken);
$i = 0;
while(strlen($broken))
{
$i++;
if ($i > $len)
{
break;
}
if (substr($broken, 0, 1) == '}') // end of array
{
$broken = substr($broken, 1);
return $data;
}
else
{
$bite = substr($broken, 0, 2);
switch($bite)
{
case 's:': // key or value
$re = '/^s:\d+:"([^\"]*)";/';
if (preg_match($re, $broken, $m))
{
if ($index === null)
{
$index = $m[1];
}
else
{
$data[$index] = $m[1];
$index = null;
}
$broken = preg_replace($re, '', $broken);
}
break;
case 'i:': // key or value
$re = '/^i:(\d+);/';
if (preg_match($re, $broken, $m))
{
if ($index === null)
{
$index = (int) $m[1];
}
else
{
$data[$index] = (int) $m[1];
$index = null;
}
$broken = preg_replace($re, '', $broken);
}
break;
case 'b:': // value only
$re = '/^b:[01];/';
if (preg_match($re, $broken, $m))
{
$data[$index] = (bool) $m[1];
$index = null;
$broken = preg_replace($re, '', $broken);
}
break;
case 'a:': // value only
$re = '/^a:\d+:\{/';
if (preg_match($re, $broken, $m))
{
$broken = preg_replace('/^a:\d+:\{/', '', $broken);
$data[$index] = $this -> repairSerializedArray_R($broken);
$index = null;
}
break;
case 'N;': // value only
$broken = substr($broken, 2);
$data[$index] = null;
$index = null;
break;
}
}
}
return $data;
}
}