From 4ce17f05e2f550b4254b309748f705b93d36ba76 Mon Sep 17 00:00:00 2001 From: Blake Robertson Date: Tue, 24 Sep 2013 03:33:03 -0400 Subject: [PATCH] 3.5.6 --> 3.6.6 Lots of performance changes, new features, bug fixes --- RELEASE-NOTES | 11 + .../modules/Asterisk/asteriskLogger.php | 782 ++++++---- .../modules/Asterisk/include/AsteriskJS.php | 49 +- .../modules/Asterisk/include/callCreate.php | 108 +- .../modules/Asterisk/include/callinize_db.php | 1354 +++++++++-------- .../modules/Asterisk/include/css/asterisk.css | 19 +- .../include/images/click-to-dial-calling.gif | Bin 0 -> 9339 bytes .../Asterisk/include/images/click-to-dial.png | Bin 0 -> 5953 bytes .../Asterisk/include/javascript/callPopups.js | 72 +- .../Asterisk/include/javascript/dialout.js | 117 +- .../include/template/call-template.tmpl | 4 +- .../modules/Asterisk/language/en_us.lang.php | 1 + .../Configurator/asterisk_config_meta.php | 1 + .../Configurator/asterisk_configurator.tpl | 79 +- .../asterisk_configurator_table.tpl | 189 ++- .../configuratorGeneratorUtil.php | 27 +- .../Configurator/language/en_us.lang.php | 8 + .../modules/Users/language/en_us.lang.php | 3 +- TODO.txt | 4 - manifest.php | 137 +- manifest_updater.php | 2 + scripts/post_install.php | 4 +- 22 files changed, 1640 insertions(+), 1331 deletions(-) create mode 100644 SugarModules/modules/Asterisk/include/images/click-to-dial-calling.gif create mode 100644 SugarModules/modules/Asterisk/include/images/click-to-dial.png diff --git a/RELEASE-NOTES b/RELEASE-NOTES index b8f8ff2..de9cb9e 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,5 +1,16 @@ IMPORTANT: when upgrading, please see the instructions in the User Manual +##Version 3.6.0 (2013-07-28) +* Enhancements +** Click To Dial is more intelligent, it always relates call to the record clicked. Before if multiple matching phone numbers, before if phone number matched multiple contacts it showed radio buttons. +** New config option "Max Call Popups" controls the maximum number of popups that will appear on a users screen. +** The 'X' button is easier to click to close call popups. +** (Basic/Pro Only) - Calls to Queues and RingGroups now popup on callee's screen before answering. +* Bug Fixes +** dial_events_log in admin config now works. +** Admin Checkboxes always appeared as checked. + + ##Version 3.5.4 (2013-07-08) * New User Interface * Ability to specify which contact and account phone fields are searched. diff --git a/SugarModules/modules/Asterisk/asteriskLogger.php b/SugarModules/modules/Asterisk/asteriskLogger.php index d61d9ad..53801aa 100644 --- a/SugarModules/modules/Asterisk/asteriskLogger.php +++ b/SugarModules/modules/Asterisk/asteriskLogger.php @@ -189,12 +189,13 @@ function call($method, $params) { $sugarSoapCredential = md5($sugar_config['asterisk_soappass']); // Here we check if LDAP Authentication is used, if so we must build credential differently -$q = mysql_query('select value from config where category=\'system\' and name=\'ldap_enabled\''); +$q = mysql_query('SELECT VALUE FROM config WHERE category=\'system\' AND name=\'ldap_enabled\''); $r = mysql_fetch_assoc($q); if ($r['value'] != 1) { $sugarSoapCredential = md5($sugar_config['asterisk_soappass']); } else { - $q = mysql_query('select value from config where category=\'ldap\' and name=\'enc_key\''); + logLine("Using LDAP credentials for SOAP."); + $q = mysql_query('SELECT VALUE FROM config WHERE category=\'ldap\' AND name=\'enc_key\''); $r = mysql_fetch_assoc($q); $ldap_enc_key = substr(md5($r['value']), 0, 24); $sugarSoapCredential = bin2hex(mcrypt_cbc(MCRYPT_3DES, $ldap_enc_key, $sugar_config['asterisk_soappass'], MCRYPT_ENCRYPT, 'password')); @@ -222,7 +223,7 @@ function call($method, $params) { $soapSessionId = $soapClient->sessionid; $userGUID = $soapClient->call('get_user_id', array( $soapSessionId - )); + )); if (is_array($userGUID) && array_key_exists("error", $userGUID) && $userGUID['error']['number'] != 0) { logLine(" **WARNING Unable to make initial SOAP Call " . $userGUID['error']['number'] . " " . $userGUID['error']['name'] . " // " . $userGUID['error']['description'] . "**\n"); @@ -341,7 +342,7 @@ function call($method, $params) { logLine("[Asterisk Manager Interface (AMI) Connection]\n"); - $amiSocket = fsockopen($asteriskServer, $asteriskManagerPort, $errno, $errstr, 5); // connect to Asterisk server + $amiSocket = fsockopen($asteriskServer, $asteriskManagerPort, $errno, $errstr, 5); // connect to Asterisk server if (!$amiSocket) { logLine(" __ ERROR $errno connecting to Asterisk: $errstr __"); sleep(5); // retry connecting @@ -435,6 +436,8 @@ function call($method, $params) { logLine("! Dial Event src=" . $e['Channel'] . " dest=" . $e['Destination'] . "\n"); //Asterisk Manager 1.1 + dev_LogString('Event begin' . getTimestamp() . " " . $e['event']); + $eChannel = $e['Channel']; // Attempt to make compatible with AMI 1.0 @@ -454,28 +457,39 @@ function call($method, $params) { // We'll need this later to record the call when finished, but create it right here // to get the ID // - $set_entry_params = array( - 'session' => $soapSessionId, - 'module_name' => 'Calls', - 'name_value_list' => array( - array( - 'name' => 'name', - 'value' => $mod_strings['YAAI']['CALL_AUTOMATIC_RECORD'] - ), - array( - 'name' => 'status', - 'value' => $mod_strings['YAAI']['CALL_IN_LIMBO'] - ), - array( - 'name' => 'assigned_user_id', - 'value' => $userGUID + if( $sugar_config['asterisk_logger_sql_mode'] ) { + // SQL MODE + $callRecordId = createCallId(); + $query = "INSERT INTO calls (id, name, status, assigned_user_id) VALUES ('{$callRecordId}', '{$mod_strings['YAAI']['CALL_AUTOMATIC_RECORD']}', '{$mod_strings['YAAI']['CALL_IN_LIMBO']}', '{$userGUID}')"; + mysql_checked_query($query); + } + else { + // SOAP MODE + $set_entry_params = array( + 'session' => $soapSessionId, + 'module_name' => 'Calls', + 'name_value_list' => array( + array( + 'name' => 'name', + 'value' => $mod_strings['YAAI']['CALL_AUTOMATIC_RECORD'] + ), + array( + 'name' => 'status', + 'value' => $mod_strings['YAAI']['CALL_IN_LIMBO'] + ), + array( + 'name' => 'assigned_user_id', + 'value' => $userGUID + ) ) - ) - ); - $soapResult = $soapClient->call('set_entry', $set_entry_params); - //print_r( $soapResult ); - $callRecordId = $soapResult['id']; + ); + $soapResult = $soapClient->call('set_entry', $set_entry_params); + //print_r( $soapResult ); + $callRecordId = $soapResult['id']; + } logLine("! Successfully created CALL record with id=" . $callRecordId . "\n"); + dev_logString("! Successfully created CALL record with id=" . $callRecordId . "\n"); + //dev_LogString('Replaced SOAP Call complete' . getTimestamp() . " " . $e['event']); $call = NULL; @@ -522,44 +536,32 @@ function call($method, $params) { // Check if both ends of the call are internal (then delete created (** Automatic record **) record) // 2nd condition looks for Local/RG-52-4102152497 if ((preg_match($asteriskMatchInternal, $eChannel) && preg_match($asteriskMatchInternal, $eDestination)) || - preg_match($rgDetectRegex, $eDestination) || - preg_match($rgCellRingRegex, $eChannel)) { + preg_match($rgDetectRegex, $eDestination) || + preg_match($rgCellRingRegex, $eChannel)) { deleteCall($callRecordId); logLine("INTERNAL call detected, Deleting Call Record $callRecordId\n"); - - // FIXME Delete this! Trying to visualize internal call for RingGroups - /* - $userExtension = extractExtensionNumberFromChannel($eDestination); - $inboundExtension = NULL; - if (!empty($e['Queue']) ) { - $inboundExtension = $e['Queue']; - } - else { - // Extract from eDestination - $inboundExtension = extractExtensionNumberFromChannel($eDestination); - } - $query = sprintf("INSERT INTO asterisk_log (asterisk_id, call_record_id, channel, remote_channel, callstate, direction, CallerID, timestamp_call, asterisk_dest_id,user_extension,inbound_extension) VALUES('%s','%s','%s','%s','%s','%s','%s',%s,'%s','%s','%s')", AMI_getUniqueIdFromEvent($e), $callRecordId, $eDestination, $eChannel, 'Dial', 'X', $tmpCallerID, 'FROM_UNIXTIME(' . time() . ')', $e['DestUniqueID'], $userExtension, $inboundExtension); - $callDirection = 'Inbound'; - logLine("INTERNAL FIXME REMOVE state detected... $asteriskMatchInternal is astMatchInternal eChannel= " . $eChannel . ' eDestination=' . $eDestination . "\n"); - mysql_checked_query($query); - */ - - // HERE We detect if this is the outbound call to a cell phone... - /* - $query = "SELECT * FROM asterisk_log WHERE channel like '%" . $e['ConnectedLineNum'] . "%' AND callerID = '" . $tmpCallerID . "'"; - $result = mysql_checked_query($query); - while ($pd = mysql_fetch_array($result)) { - callinize_push("207", $tmpCallerID,$pd['call_record_id'], $e['ConnectedLineNum'] ); // FIXME - } - */ } else { //Asterisk Manager 1.1 (If the call is internal, this will be skipped) if (preg_match($asteriskMatchInternal, $eChannel) && !preg_match($asteriskMatchInternal, $eDestination)) { $userExtension = extractExtensionNumberFromChannel($eChannel); - $query = sprintf("INSERT INTO asterisk_log (asterisk_id, call_record_id, channel, remote_channel, callstate, direction, CallerID, timestamp_call,user_extension) VALUES('%s','%s','%s','%s','%s','%s','%s',%s,'%s')", AMI_getUniqueIdFromEvent($e)/*BR: In an attempt to make Dial End work for Outbound calls switching this over to use Unique ID... I have no idea why DestId was used originally... TBD $e['DestUniqueID']*/, $callRecordId, $eChannel, $eDestination, 'NeedID', 'O', $tmpCallerID, 'FROM_UNIXTIME(' . time() . ')', $userExtension); - dev_logString("Insert Outbound"); - $callDirection = 'Outbound'; - logLine("OUTBOUND state detected... $asteriskMatchInternal is astMatchInternal eChannel= " . $eChannel . ' eDestination=' . $eDestination . "\n"); + //check whether call was already input during click to dial + $asteriskId = AMI_getUniqueIdFromEvent($e); + dev_logString("Entering outbound inbound"); + + if(findLoggedCallByAsteriskId($asteriskId) === FALSE){ + logLine ($asteriskId . "updated inside false"); + $query = sprintf("INSERT INTO asterisk_log (asterisk_id, call_record_id, channel, remote_channel, callstate, direction, CallerID, timestamp_call,user_extension) VALUES('%s','%s','%s','%s','%s','%s','%s',%s,'%s')", AMI_getUniqueIdFromEvent($e)/*BR: In an attempt to make Dial End work for Outbound calls switching this over to use Unique ID... I have no idea why DestId was used originally... TBD $e['DestUniqueID']*/, $callRecordId, $eChannel, $eDestination, 'NeedID', 'O', $tmpCallerID, 'FROM_UNIXTIME(' . time() . ')', $userExtension); + dev_logString("Insert Outbound"); + $callDirection = 'Outbound'; + logLine("OUTBOUND state detected... $asteriskMatchInternal is astMatchInternal eChannel= " . $eChannel . ' eDestination=' . $eDestination . "\n"); + }else{ + //update record created from the click to dial with the callRecordID + logLine ($asteriskId . "updated outside false"); + $query = "UPDATE asterisk_log SET asterisk_dest_id = '{$e['DestUniqueID']}', callerID = '{$tmpCallerID}' , call_record_id = '{$callRecordId}', remote_channel = '{$eDestination}' WHERE asterisk_id = '{$asteriskId}'"; + dev_logString("Update Outbound"); + $callDirection = 'Outbound'; + logLine("OUTBOUND CLICK-TO-DIAL state detected... $asteriskMatchInternal is astMatchInternal eChannel= " . $eChannel . ' eDestination=' . $eDestination . "\n"); + } } else if (!preg_match($asteriskMatchInternal, $eChannel)) { $userExtension = extractExtensionNumberFromChannel($eDestination); if( $e['Event'] == 'Join' && !empty($e['Queue'])) { @@ -579,12 +581,12 @@ function call($method, $params) { // Here we are looking back in time... + // We are adding some special logic to handle the case of an inbound call being answered by someone on their cell phone. // We look into the call log to see if there are events with the same asterisk_id (which implies it's the same original call that's branched off to several different extensions). // We then look at the original call record's inbound extension and use it! - if( $FOLLOWME == 1) { $asteriskId = AMI_getUniqueIdFromEvent($e); - $query = sprintf("select user_extension, inbound_extension from asterisk_log where asterisk_id = '$asteriskId' order by id asc"); + $query = sprintf("SELECT user_extension, inbound_extension FROM asterisk_log WHERE asterisk_id = '$asteriskId' ORDER BY id ASC"); $res = mysql_checked_query($query); $prevRowDetails = mysql_fetch_array($res); if( !empty( $prevRowDetails['inbound_extension'])) { @@ -598,39 +600,44 @@ function call($method, $params) { } } } - - - - logLine(" inbound_extension = " . $inboundExtension ); $query = sprintf("INSERT INTO asterisk_log (asterisk_id, call_record_id, channel, remote_channel, callstate, direction, CallerID, timestamp_call, asterisk_dest_id,user_extension,inbound_extension,user_device) VALUES('%s','%s','%s','%s','%s','%s','%s',%s,'%s','%s','%s','%s')", AMI_getUniqueIdFromEvent($e), $callRecordId, $eDestination, $eChannel, 'Dial', 'I', $tmpCallerID, 'FROM_UNIXTIME(' . time() . ')', $e['DestUniqueID'], $userExtension, $inboundExtension, $userDevice); $callDirection = 'Inbound'; dev_logString("Insert Inbound"); + dev_LogString('Query created' . getTimestamp()); logLine("Inbound state detected... $asteriskMatchInternal is astMatchInternal eChannel= " . $eChannel . ' eDestination=' . $eDestination . "\n"); } mysql_checked_query($query); + dev_LogString('Query complete' . getTimestamp() . " " . $e['event']); + // // Update CALL record with direction... // - $set_entry_params = array( - 'session' => $soapSessionId, - 'module_name' => 'Calls', - 'name_value_list' => array( - array( - 'name' => 'id', - 'value' => $callRecordId - ), - array( - 'name' => 'direction', - 'value' => $callDirection - ) - ) - ); - $soapResult = $soapClient->call('set_entry', $set_entry_params); + if( $sugar_config['asterisk_use_sql_mode'] ) { + $query = "UPDATE calls SET direction = '{$callDirection}' WHERE id = '{$callRecordId}'"; + mysql_checked_query($query); + } + else { + $set_entry_params = array( + 'session' => $soapSessionId, + 'module_name' => 'Calls', + 'name_value_list' => array( + array( + 'name' => 'id', + 'value' => $callRecordId + ), + array( + 'name' => 'direction', + 'value' => $callDirection + ) + ) + ); + $soapResult = $soapClient->call('set_entry', $set_entry_params); + } } } @@ -639,6 +646,7 @@ function call($method, $params) { // // NewCallerid == 1.1, Newcallerid == 1.0 if ($e['Event'] == 'NewCallerid' || $e['Event'] == 'Newcallerid') { + $id = AMI_getUniqueIdFromEvent($e); $tmpCallerID = AMI_getCallerIdFromEvent($e); if ((strlen($calloutPrefix) > 0) && (strpos($tmpCallerID, $calloutPrefix) === 0)) { @@ -650,6 +658,31 @@ function call($method, $params) { mysql_checked_query($query); } + // + // CLICK TO DIAL OUTBOUND HANDLING - WE ALREADY KNOW THE ASSOCIATED RECORD SO NO NEED TO LOOK IT UP + // + + if ($e['Event'] == 'NewAccountCode' && strpos($e['AccountCode'], "LICKTODIAL") != false) { + $id = AMI_getUniqueIdFromEvent($e); + if (findLoggedCallByAsteriskId($id) === FALSE) { + logLine("The AccountCode is" . $e['AccountCode']); + logLine(" Account Code ID is: $id\n"); + $time = time(); + $callerID = stripExtensionFromAccountCode($e['Channel']); + $result = findCallDetailsByClickToDialString($e['AccountCode']); + $beanLink = build_link($result['module'], $result['record']); + $query = "INSERT INTO asterisk_log (asterisk_id, callstate, direction, callerID, channel, timestamp_call, bean_module, bean_id, bean_name, bean_link, user_extension) " + . "VALUES('{$id}', 'Connected', 'O', '{$result['number']}', '{$e['Channel']}', FROM_UNIXTIME('{$time}'), '{$result['dbtable']}', '{$result['record']}', '{$result['query']['name']}', '{$beanLink}', '{$callerID}')"; + logLine($query); + //. "bean_link='" . $result['query'][''] . "' " + //. "bean_description='" . $result['parent_module'] . "' " + //. "bean_description='" . $result['parent_id'] . "' " + //. "bean_description='" . $result['parent_name'] . "' " + //. "bean_description='" . $result['parent_link'] . "'"; + mysql_checked_query($query); + } + } + // Had to switch to using Dial End commands because when using hangups I couldn't do calls to cell phones properly... (basically there are so many // hangup events it killed me... @@ -682,7 +715,7 @@ function call($method, $params) { // TODO verify configurator boolean issues will not present a problem for this. if( $sugar_config['asterisk_only_log_calls_matching_user_extension'] && (empty($direction['user_extension'] ) || - !findUserByAsteriskExtension($direction['user_extension']))) + !findUserByAsteriskExtension($direction['user_extension']))) { logLine(" ## Deleting callid = " . $direction['call_record_id'] . " because it didn't match any user extension"); deleteCall( $direction['call_record_id']); @@ -691,7 +724,7 @@ function call($method, $params) { // // Fetch associated call record // - $callRecord = findCallByAsteriskId($id); + $callRecord = findCallByAsteriskId($id); if ($callRecord) { logLine("### [$id] FOUND outbound CALL\n"); // @@ -699,7 +732,7 @@ function call($method, $params) { // $rawData = $callRecord['bitter']; // raw data from asterisk_log $query = sprintf("UPDATE asterisk_log SET callstate='%s', timestamp_hangup=%s WHERE asterisk_id='%s'", //asterisk_dest_id was asterisk_id - 'Hangup', 'FROM_UNIXTIME(' . time() . ')', $id); + 'Hangup', 'FROM_UNIXTIME(' . time() . ')', $id); dev_logString("Hungup $id"); $updateResult = mysql_checked_query($query); if ($updateResult) { @@ -751,13 +784,13 @@ function call($method, $params) { // } else { // $callStatus = 'Missed'; // $callName = $mod_strings['YAAI']['CALL_NAME_MISSED']; - // $callDescription = "{$mod_strings['YAAI']['CALL_DESCRIPTION_MISSED']} ({$e['Cause-txt']}\n"; + // $callDescription = "{$mod_strings['YAAI']['CALL_DESCRIPTION_MISSED']} ({$e['Cause-txt']}\n"; // $callDescription .= "------------------\n"; // $callDescription .= sprintf(" %-20s : %-40s\n", $mod_strings['YAAI']['CALL_DESCRIPTION_PHONE_NUMBER'], $rawData['callerID']); - // if( $rawData['opencnam'] ) { - // $callName .= " - " . $rawData['opencnam']; - // $callDescription .= sprintf(" %-20s : %-40s\n", $mod_strings['YAAI']['CALL_DESCRIPTION_CALLER_ID'], $rawData['opencnam']); - // } + // if( $rawData['opencnam'] ) { + // $callName .= " - " . $rawData['opencnam']; + // $callDescription .= sprintf(" %-20s : %-40s\n", $mod_strings['YAAI']['CALL_DESCRIPTION_CALLER_ID'], $rawData['opencnam']); + // } // logLine("Adding OUTBOUND Failed Call, id=$id, call_id = " . $callRecord['sweet']['id'] . "\n"); // } // Establish Relationships with the Call and Contact/Account @@ -769,6 +802,8 @@ function call($method, $params) { logLine("Bean Id already set by callListener to: " . $direction['bean_id'] . "\n"); $beanID = $direction['bean_id']; $beanType = ucfirst($direction['bean_module']); + //$parentType = ucfirst($direction['bean_module']); + //$parentID = $beanID; } else { $beans = findSugarBeanByPhoneNumber($rawData['callerID'],true,false); if( $beans != null && count($beans) == 1 ) { @@ -783,6 +818,8 @@ function call($method, $params) { if ($beanType == "Accounts") { $parentType = "Accounts"; $parentID = $beanID; + //changing parent id to accounts instead of what was set in relationship between above + logLine(" Setting relationship to Accounts instead of the bean in setRelationshipBetweenCallAndBean" . "\n"); } //var_dump($parentType); @@ -800,76 +837,103 @@ function call($method, $params) { gitimg_log("call-out"); - $soapResult = $soapClient->call('set_entry', array( - 'session' => $soapSessionId, - 'module_name' => 'Calls', - 'name_value_list' => array( - array( - 'name' => 'id', - 'value' => $callRecord['sweet']['id'] - ), - array( - 'name' => 'name', - 'value' => $callName - ), - array( - 'name' => 'duration_hours', - 'value' => $callDurationHours - ), - array( - 'name' => 'duration_minutes', - 'value' => $callDurationMinutes - ), - array( - 'name' => 'status', - 'value' => $callStatus - ), - array( - 'name' => 'description', - 'value' => $callDescription - ), - array( - 'name' => 'asterisk_caller_id_c', - 'value' => $rawData['callerID'] - ), - array( - 'name' => 'asterisk_call_id_c', - 'value' => empty($rawData['asterisk_id2']) ? $rawData['asterisk_id'] : $rawData['asterisk_id2'] - ), - array( - 'name' => 'asterisk_user_extension_c', - 'value' => $direction['user_extension'] - ), - - array( - 'name' => 'asterisk_inbound_extension_c', - 'value' => $direction['inbound_extension'] - ), - - array( - 'name' => 'date_start', - 'value' => gmdate('Y-m-d H:i:s', $callStart) - ), - array( - 'name' => 'parent_type', - 'value' => $parentType - ), - array( - 'name' => 'parent_id', - 'value' => $parentID - ), - array( - 'name' => 'assigned_user_id', - 'value' => $assignedUser + $dateStart = gmdate('Y-m-d H:i:s', $callStart); + $asteriskCallIDC = empty($rawData['asterisk_id2']) ? $rawData['asterisk_id'] : $rawData['asterisk_id2']; + $dUserExtension = $direction['user_extension']; + $dInboundExtension = $direction['inbound_extension']; + $crSweetID = $callRecord['sweet']['id']; + + if( $sugar_config['asterisk_use_sql_mode'] ) { + $query = "UPDATE calls, calls_cstm + SET name='{$callName}', + duration_hours='{$callDurationHours}', + duration_minutes='{$callDurationMinutes}', + status='{$callStatus}', + description='{$callDescription}', + asterisk_caller_id_c='{$rawData['callerID']}', + asterisk_call_id_c='{$asteriskCallIDC}', + asterisk_user_ext_c='{$dUserExtension}', + asterisk_inbound_ext_c='{$dInboundExtension}', + date_start='{$dateStart}' + parent_type='{$parentType}', + parent_id='{$parentID}', + assigned_user_id='{$assignedUser}' + WHERE calls.id = '{$crSweetID}' + AND calls_cstm.id_c = '{$crSweetID}'"; + mysql_checked_query($query); + } + else { + $soapResult = $soapClient->call('set_entry', array( + 'session' => $soapSessionId, + 'module_name' => 'Calls', + 'name_value_list' => array( + array( + 'name' => 'id', + 'value' => $callRecord['sweet']['id'] + ), + array( + 'name' => 'name', + 'value' => $callName + ), + array( + 'name' => 'duration_hours', + 'value' => $callDurationHours + ), + array( + 'name' => 'duration_minutes', + 'value' => $callDurationMinutes + ), + array( + 'name' => 'status', + 'value' => $callStatus + ), + array( + 'name' => 'description', + 'value' => $callDescription + ), + array( + 'name' => 'asterisk_caller_id_c', + 'value' => $rawData['callerID'] + ), + array( + 'name' => 'asterisk_call_id_c', + 'value' => empty($rawData['asterisk_id2']) ? $rawData['asterisk_id'] : $rawData['asterisk_id2'] + ), + array( + 'name' => 'asterisk_user_ext_c', + 'value' => $direction['user_extension'] + ), + + array( + 'name' => 'asterisk_inbound_ext_c', + 'value' => $direction['inbound_extension'] + ), + + array( + 'name' => 'date_start', + 'value' => gmdate('Y-m-d H:i:s', $callStart) + ), + array( + 'name' => 'parent_type', + 'value' => $parentType + ), + array( + 'name' => 'parent_id', + 'value' => $parentID + ), + array( + 'name' => 'assigned_user_id', + 'value' => $assignedUser + ) ) - ) - )); + )); + } } } else { logLine("[$id] FAILED TO FIND A CALL (note: there are two hangups per call, so this might not be an error)\n"); } } else { - //-----------------[ INBOUND HANGUP HANDLING ]---------------------- + //-----------------[ INBOUND HANGUP HANDLING ]---------------------- $id = AMI_getUniqueIdFromEvent($e); // @@ -886,7 +950,7 @@ function call($method, $params) { $rawData = $callRecord['bitter']; // raw data from asterisk_log // 2013 - march removed hangup_cause=%d, hangup_cause_txt='%s' $query = sprintf("UPDATE asterisk_log SET callstate='%s', timestamp_hangup=%s, answered='%s' WHERE asterisk_id='%s'", //asterisk_dest_id was asterisk_id - 'Hangup', 'FROM_UNIXTIME(' . time() . ')', was_call_answered($id), $id); + 'Hangup', 'FROM_UNIXTIME(' . time() . ')', was_call_answered($id), $id); dev_logString("Hungup Inbound $id"); $updateResult = mysql_checked_query($query); if ($updateResult) { @@ -985,69 +1049,91 @@ function call($method, $params) { gitimg_log("call-in"); - $soapResult = $soapClient->call('set_entry', array( - 'session' => $soapSessionId, - 'module_name' => 'Calls', - 'name_value_list' => array( - array( - 'name' => 'id', - 'value' => $callRecord['sweet']['id'] - ), - array( - 'name' => 'name', - 'value' => $callName - ), - array( - 'name' => 'duration_hours', - 'value' => $callDurationHours - ), - array( - 'name' => 'duration_minutes', - 'value' => $callDurationMinutes - ), - array( - 'name' => 'status', - 'value' => $callStatus - ), - array( - 'name' => 'description', - 'value' => $callDescription - ), - array( - 'name' => 'asterisk_caller_id_c', - 'value' => $rawData['callerID'] - ), - array( - 'name' => 'asterisk_call_id_c', - 'value' => $rawData['asterisk_id'] - ), - array( - 'name' => 'asterisk_user_extension_c', - 'value' => $direction['user_extension'] - ), - - array( - 'name' => 'asterisk_inbound_extension_c', - 'value' => $direction['inbound_extension'] - ), - array( - 'name' => 'date_start', - 'value' => gmdate('Y-m-d H:i:s', $callStart) - ), - array( - 'name' => 'parent_type', - 'value' => $parentType - ), - array( - 'name' => 'parent_id', - 'value' => $parentID - ), - array( - 'name' => 'assigned_user_id', - 'value' => $assignedUser + + if( $sugar_config['asterisk_use_sql_mode'] ) { + $query = "UPDATE calls, calls_cstm + SET name='{$callName}', + duration_hours='{$callDurationHours}', + duration_minutes='{$callDurationMinutes}', + status='{$callStatus}', + description='{$callDescription}', + asterisk_caller_id_c='{$rawData['callerID']}', + asterisk_call_id_c='{$rawData['asterisk_id']}', + asterisk_user_ext_c='{$direction['user_extension']}', + asterisk_inbound_ext_c='{$direction['inbound_extension']}', + parent_type='{$parentType}', + parent_id='{$parentID}', + assigned_user_id='{$assignedUser}' + WHERE calls.id = '{$callRecord['sweet']['id']}' + AND calls_cstm.id_c = '{$callRecord['sweet']['id']}'"; + mysql_checked_query($query); + } + else { + $soapResult = $soapClient->call('set_entry', array( + 'session' => $soapSessionId, + 'module_name' => 'Calls', + 'name_value_list' => array( + array( + 'name' => 'id', + 'value' => $callRecord['sweet']['id'] + ), + array( + 'name' => 'name', + 'value' => $callName + ), + array( + 'name' => 'duration_hours', + 'value' => $callDurationHours + ), + array( + 'name' => 'duration_minutes', + 'value' => $callDurationMinutes + ), + array( + 'name' => 'status', + 'value' => $callStatus + ), + array( + 'name' => 'description', + 'value' => $callDescription + ), + array( + 'name' => 'asterisk_caller_id_c', + 'value' => $rawData['callerID'] + ), + array( + 'name' => 'asterisk_call_id_c', + 'value' => $rawData['asterisk_id'] + ), + array( + 'name' => 'asterisk_user_ext_c', + 'value' => $direction['user_extension'] + ), + + array( + 'name' => 'asterisk_inbound_ext_c', + 'value' => $direction['inbound_extension'] + ), + array( + 'name' => 'date_start', + 'value' => gmdate('Y-m-d H:i:s', $callStart) + ), + array( + 'name' => 'parent_type', + 'value' => $parentType + ), + array( + 'name' => 'parent_id', + 'value' => $parentID + ), + array( + 'name' => 'assigned_user_id', + 'value' => $assignedUser + ) ) - ) - )); + )); + } + } // End Inbound Case // In case of multiple extensions when a call is not answered, every extensions produces a failed call record, // this will keep the first of those records but delete the rest. (LIMIT 1,999999999999 in query returns all but first match.) @@ -1121,7 +1207,7 @@ function call($method, $params) { $result = mysql_checked_query($query); // TODO clean up all these logLines. if (mysql_num_rows($result) > 1) { - logLine("RG-Bridge ERROR: MULTIPLE MATCHING LINES IN ASTERISK LOG... BRIDGE LOGIC ISN'T BULLETPROOF\n"); + logLine("RG-Bridge ERROR: MULTIPLE MATCHING LINES IN ASTERISK LOG... BRIDGE LOGIC ISN'T BULLETPROOF\n"); // NOTE: I'm not aware of this line ever occurring... so maybe it is bulletproof. } else if (mysql_num_rows($result) == 1) { logLine(" RG-Bridge Detected changing the channel to: {$e['Channel2']}\n"); $result_id = mysql_fetch_array($result); @@ -1173,13 +1259,13 @@ function call($method, $params) { } } - //Asterisk Manager 1.0 (Only)... This is the equivalent of bridge - if($e['Event'] == 'Link') - { - $query = "UPDATE asterisk_log SET callstate='Connected', timestamp_link=FROM_UNIXTIME(".time().") WHERE asterisk_id='" . $e['Uniqueid1'] . "' OR asterisk_id='" . $e['Uniqueid2'] . "'"; - $rc = mysql_checked_query($query); - // NOTE: AMI v1.0 will not support Ring Groups and Queues like AMI v1.1 does until it's ported. - }; + //Asterisk Manager 1.0 (Only)... This is the equivalent of bridge + if($e['Event'] == 'Link') + { + $query = "UPDATE asterisk_log SET callstate='Connected', timestamp_link=FROM_UNIXTIME(".time().") WHERE asterisk_id='" . $e['Uniqueid1'] . "' OR asterisk_id='" . $e['Uniqueid2'] . "'"; + $rc = mysql_checked_query($query); + // NOTE: AMI v1.0 will not support Ring Groups and Queues like AMI v1.1 does until it's ported. + }; // Reset event buffer $event = ''; @@ -1229,6 +1315,57 @@ function call($method, $params) { // Helper functions * // ****************** +function createCallId(){ + $query = "SELECT UUID() AS id"; + $result = mysql_checked_query($query); + $result = mysql_fetch_assoc($result); + return $result['id']; + + return $id; +} + +function findParentDetailsByBean($beanId, $module) +{ + if ($module === 'Leads') { + $query = "SELECT CONCAT_WS(' ', first_name, last_name) AS recordName, name AS accountName, l.description AS beanDescription, a.description AS accountDescription, department, title + FROM leads as l + LEFT JOIN accounts AS a ON l.account_id = a.id + WHERE l.id = '{$beanId}'"; + } + + if ($module === 'Contacts') { + $query = "SELECT CONCAT_WS(' ', first_name, last_name) AS recordName, name AS accountName, c.description AS beanDescription, a.description AS accountDescription, department, title + FROM contacts AS c + LEFT JOIN accounts_contacts AS ac ON c.id = ac.contact_id + LEFT JOIN accounts AS a ON ac.account_id = a.id + WHERE c.id = '{$beanId}'"; + } + + if (!$query) { + logLine("findContactDetailsByBean was passed a module value that is not supported. No data will be returned"); + return FALSE; + } + $queryResult = mysql_checked_query($query); + if (!$queryResult) { + logLine("! Contact lookup failed in findParentDetailsByBean"); + return FALSE; + } + + return mysql_fetch_assoc($queryResult); +} + +function queryEmailAddressBySugarId($id) +{ + $emailSql = "SELECT email_addresses.email_address + FROM email_addr_bean_rel + LEFT JOIN email_addresses ON email_addr_bean_rel.email_address_id = email_addresses.id + WHERE email_addr_bean_rel.bean_id = '{$id}'"; + logLine("Email SQL: " . $emailSql); + $queryEmailResult = mysql_checked_query($emailSql); + $emailRow = mysql_fetch_assoc($queryEmailResult); + return $emailRow['email_address']; +} + /** * Removes calls from asterisk_log that have expired or closed. * 1) Call Popup Closed Manually by user in sugar. @@ -1246,7 +1383,7 @@ function purgeExpiredEventsFromDb() { $five_hours_ago = date('Y-m-d H:i:s', time() - 5 * 60 * 60); // BR: 2013-04-30 fixed bug where closing the call popup before the call was over the duration would potentially not get set right. - $query = " DELETE FROM asterisk_log WHERE (uistate = 'Closed' AND timestamp_hangup is not NULL) OR ( timestamp_hangup is not NULL AND '$calls_expire_time' > timestamp_hangup ) OR ('$five_hours_ago' > timestamp_call )"; + $query = "DELETE FROM asterisk_log WHERE (uistate = 'Closed' AND timestamp_hangup is not NULL) OR ( timestamp_hangup is not NULL AND '$calls_expire_time' > timestamp_hangup ) OR ('$five_hours_ago' > timestamp_call )"; //logLine( "Debug Purge Query: " . $query ); mysql_checked_query($query); $rowsDeleted = mysql_affected_rows(); @@ -1294,14 +1431,14 @@ function dumpEvent(&$event) { // $eventType == 'Newchannel' || if ($eventType == 'Newexten' || $eventType == 'UserEvent' || $eventType == 'AGIExec' || $eventType == 'Newstate' || $eventType == 'ExtensionStatus') { logLine("! AMI Event '" . $eventType . " suppressed.\n"); - - if( $eventType == 'Newexten') { - dumpEventHelper($event, "c:/newexten.log"); - } + +// if( $eventType == 'Newexten') { +// dumpEventHelper($event, "c:/newexten.log"); +// } return; } - switch($eventType) { + switch($eventType) { case "Dial": dev_DialPrinter($event); break; case "Bridge": dev_BridgePrinter($event); break; case "Join": dev_JoinPrinter($event); break; @@ -1321,24 +1458,31 @@ function dumpEventHelper(&$event, $logFile = "default" ) { logLine("! ---------------------------------------------------------------------\n", $logFile); } +function getIfSet($e, $key, $default='') { + if( isset($e[$key]) ) { + return $e[$key]; + } + return $default; +} + function dev_DialPrinter(&$e) { - dev_GenericEventPrinter("Dial", $e['SubEvent'], $e['UniqueID'], $e['DestUniqueID'], $e['Channel'], $e['Destination'], $e["CallerIDNum"], $e['DialString']); + dev_GenericEventPrinter("Dial", getIfSet( $e, 'SubEvent'), getIfSet( $e, 'UniqueID'), getIfSet( $e, 'DestUniqueID'), getIfSet( $e, 'Channel'), getIfSet( $e, 'Destination'), getIfSet( $e, 'CallerIDNum'), getIfSet( $e, 'DialString')); } function dev_BridgePrinter(&$e) { - dev_GenericEventPrinter("Bridge", $e['Bridgestate'], $e['Uniqueid1'], $e['Uniqueid2'], $e['Channel1'], $e['Channel2'], $e["CallerID1"], $e['CallerID2']); + dev_GenericEventPrinter("Bridge", getIfSet( $e, 'Bridgestate'), getIfSet( $e, 'Uniqueid1'), getIfSet( $e, 'Uniqueid2'), getIfSet( $e, 'Channel1'), getIfSet( $e, 'Channel2'), getIfSet( $e, 'CallerID1'), getIfSet( $e, 'CallerID2')); } function dev_JoinPrinter(&$e) { - dev_GenericEventPrinter("Join", $e['Position'], $e['Uniqueid'], "--", $e['Channel'], "--", $e["CallerIDNum"], $e['Queue']); + dev_GenericEventPrinter("Join", getIfSet( $e, 'Position'), getIfSet( $e, 'Uniqueid'), "--", getIfSet( $e, 'Channel'), "--", $e["CallerIDNum"], getIfSet( $e, 'Queue')); } function dev_HangupPrinter(&$e) { - dev_GenericEventPrinter("Hangup", $e['Cause'], $e['Uniqueid'], '--', $e['Channel'], '--', $e["CallerIDNum"], $e['ConnectedLineNum']); + dev_GenericEventPrinter("Hangup", getIfSet( $e, 'Cause'), getIfSet( $e, 'Uniqueid'), '--', getIfSet( $e, 'Channel'), '--', $e["CallerIDNum"], getIfSet( $e, 'ConnectedLineNum')); } function dev_NewChannelPrinter(&$e) { - dev_GenericEventPrinter("NewChan", $e['ChannelStateDesc'], $e['Uniqueid'], '--', $e['Channel'], '--', $e["CallerIDNum"], $e['Exten']); + dev_GenericEventPrinter("NewChan", getIfSet( $e, 'ChannelStateDesc'), getIfSet( $e, 'Uniqueid'), '--', getIfSet( $e, 'Channel'), '--', $e["CallerIDNum"], getIfSet( $e, 'Exten')); } function dev_logString($str) { @@ -1386,7 +1530,7 @@ function dev_GenericEventPrinter($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7 $s .= colorize(str_pad($arg8, 20, "_", STR_PAD_BOTH)); $s = preg_replace("/_/", " ", $s); $s = - logLine( $s ."", $dial_events_log); + logLine( $s ."", $dial_events_log); } } @@ -1429,6 +1573,22 @@ function deleteCall($callRecordId) { } } +// +// Locate whether call exists in asterisk_log database +// + +function findLoggedCallByAsteriskId($asteriskId){ + $query = "SELECT id FROM asterisk_log WHERE asterisk_id='{$asteriskId}' OR asterisk_dest_id='{$asteriskId}'"; + $results = mysql_checked_query($query); + $numRows = mysql_num_rows($results); + if($numRows > 0){ + return TRUE; + }else{ + return FALSE; + } +} + + // // Locate associated record in "Calls" module // @@ -1440,7 +1600,7 @@ function findCallByAsteriskId($asteriskId) { // First, fetch row in asterisk_log... // - $sql = sprintf("SELECT * from asterisk_log WHERE asterisk_id='$asteriskId'", $asteriskId); + $sql = sprintf("SELECT * FROM asterisk_log WHERE asterisk_id='$asteriskId'", $asteriskId); $queryResult = mysql_checked_query($sql); if ($queryResult === FALSE) { logLine("Asterisk ID NOT FOUND in asterisk_log (db query returned FALSE)"); @@ -1458,7 +1618,7 @@ function findCallByAsteriskId($asteriskId) { 'session' => $soapSessionId, 'module_name' => 'Calls', 'id' => $callRecId - )); + )); $resultDecoded = decode_name_value_list($soapResult['entry_list'][0]['name_value_list']); // echo ("# ** Soap call successfull, dumping result ******************************\n"); // var_dump($soapResult); @@ -1503,7 +1663,7 @@ function findCallByAsteriskDestId($asteriskDestId) { 'session' => $soapSessionId, 'module_name' => 'Calls', 'id' => $callRecId - )); + )); $resultDecoded = decode_name_value_list($soapResult['entry_list'][0]['name_value_list']); // echo ("# ** Soap call successfull, dumping result ******************************\n"); @@ -1552,44 +1712,34 @@ function decode_name_value_list(&$nvl) { function findSugarBeanByPhoneNumber($origPhoneNumber,$stopOnFind=false, $returnMultipleMatches=false) { global $sugar_config; require_once("include/sugar_rest.php"); - $url = $sugar_config["site_url"] . '/custom/service/callinize/rest.php'; - $sugar = new Sugar_REST($url,$sugar_config['asterisk_soapuser'], $sugar_config['asterisk_soappass']); + $url = $sugar_config["site_url"] . '/custom/service/callinize/rest.php'; + $sugar = new Sugar_REST($url, $sugar_config['asterisk_soapuser'], $sugar_config['asterisk_soappass']); $params = array(); $params['phone_number'] = $origPhoneNumber; - // @@@@ BEGIN CALLINIZE COMMUNITY ONLY @@@@ - $params['module_order'] = "accounts,contacts"; - // @@@@ END CALLINIZE COMMUNITY ONLY @@@@ $params['stop_on_find'] = $stopOnFind; $beans = $sugar->custom_method("find_beans_with_phone_number", $params); $retVal = null; - if( count($beans) == 1 ) { + if (count($beans) == 1) { $retVal = $beans; // Do not return beans[0]! - } - else if( count($beans) > 1 ) { - // Check if all beans are from the same parent - $firstParentId = $beans[0]['parent_id']; - $moreThanOneParent = false; - for( $i=1; $i < count($beans); $i++ ) { - if( $beans[$i]['parent_id'] !== $firstParentId) { - $moreThanOneParent = true; - break; - } - } - if( $moreThanOneParent ) { - logLine("Found Multiple matching beans and they have different parents. Logging to noone"); - if( $returnMultipleMatches ) { - $retVal = $beans; - } - else { - $retVal = null; + } else if (count($beans) > 1) { + //below code is primarily used for mobile version + if ($returnMultipleMatches === true) { + $retVal = $beans; + //below code is primarily used for desktop version + } else { + // Check if all beans are from the same parent + $firstParentId = $beans[0]['parent_id']; + $moreThanOneParent = false; + for ($i = 1; $i < count($beans); $i++) { + if ($beans[$i]['parent_id'] !== $firstParentId) { + $moreThanOneParent = true; + break; + } } - } - else { - logLine("Found multiple matching beans but they all share the same parent. Logging to parent"); - if( !empty($firstParentId) ) { + if (!$moreThanOneParent && !empty($firstParentId)) { $retVal = array(); $retVal['bean_id'] = $beans[0]['parent_id']; $retVal['bean_name'] = $beans[0]['parent_name']; @@ -1733,7 +1883,7 @@ function findSugarObjectByPhoneNumber($aPhoneNumber) { if( endsWith($currCol,"_c") ) { $tablePrefix = "contacts_cstm."; } - array_push($phoneFields, $tablePrefix . $currCol . " REGEXP '" . $regje . "'" ); + array_push($phoneFields, $tablePrefix . $currCol . " REGEXP '" . $regje . "'" ); } } $phoneFieldsWherePortion = implode(' OR ', $phoneFields); @@ -1829,6 +1979,33 @@ function findSugarObjectByPhoneNumber($aPhoneNumber) { return FALSE; } +function findCallDetailsByClickToDialString($string){ + logLine($string); + $record = substr($string, -36); + logLine($record); + //example CLICKTODIAL-+14151111111-Leads-58314dd3-3ca6-2a21-94f4-517876c1d81e + $split = explode("-", $string); + $number = $split[1]; + $module = $split[2]; + $dbtable = strtolower($split[2]); + $query = "SELECT * FROM {$dbtable} WHERE id='{$record}'"; + logLine($query); + $results = mysql_checked_query($query); + if($results){ + $result = mysql_fetch_array($results); + if(!$result['name']){ + $result['name'] = "{$result['first_name']} {$result['last_name']}"; + } + return array( + 'dbtable' => $dbtable, + 'module' => $module, + 'record' => $record, + 'number' => $number, + 'query' => $result + ); + } +} + // Function only necessary in case of the original query used. // Replace a phone number to search with a universal-match-anyway(tm) expression to be used // in a SQL 'LIKE' condition - eg 1234 --> %1%2%3%4% @@ -1923,7 +2100,7 @@ function setRelationshipBetweenCallAndBean($callRecordId, $beanType, $beanId) { isSoapResultAnError($soapResult); } else { logLine("! Call is not related to any record (no matches)"); - //logLine("! Invalid Arguments passed to setRelationshipBetweenCallAndBean callRecordId=$callRecordId, beanId=$beanId, beanType=$beanType\n"); + logLine("! Invalid Arguments passed to setRelationshipBetweenCallAndBean callRecordId=$callRecordId, beanId=$beanId, beanType=$beanType\n"); } } @@ -2003,8 +2180,8 @@ function findUserByAsteriskExtension($aExtension) { // The 4 conditions are necessary 1) To match single extension case, 2) to match first extension in the list // 3) to match one in the middle of list, 4) matches one at the end of a list. $qry = "select id,user_name from users join users_cstm on users.id = users_cstm.id_c where " . - "(users_cstm.asterisk_ext_c='$aExtension' or users_cstm.asterisk_ext_c LIKE '$aExtension,%' " . - "OR users_cstm.asterisk_ext_c LIKE '%,$aExtension,%' OR users_cstm.asterisk_ext_c LIKE '%,$aExtension') and status='Active'"; + "(users_cstm.asterisk_ext_c='$aExtension' or users_cstm.asterisk_ext_c LIKE '$aExtension,%' " . + "OR users_cstm.asterisk_ext_c LIKE '%,$aExtension,%' OR users_cstm.asterisk_ext_c LIKE '%,$aExtension') and status='Active'"; $result = mysql_checked_query($qry); if ($result) { @@ -2130,21 +2307,6 @@ function mt_end($len=4){ return round($time_end - $mt_time, $len); } -/** - * Performs an async get request (doesn't wait for response) - * Note: One limitation of this approach is it will not work if server does any URL rewriting - */ -function gitimg_log($event) { - $host = "gitimg.com"; - $path = "/rs/track/blak3r/yaai-stats/$event/increment"; - $fp = fsockopen($host,80, $errno, $errstr, 30); - $out = "GET " . $path . " HTTP/1.1\r\n"; - $out.= "Host: " . $host . "\r\n"; - $out.= "Connection: Close\r\n\r\n"; - fwrite($fp, $out); - fclose($fp); -} - function logLine($str, $logFile = "default") { global $sugar_config; @@ -2165,15 +2327,15 @@ function logLine($str, $logFile = "default") { else { $myFile = $logFile; } - // try { - $fh = fopen($myFile, 'a'); - fwrite($fh, $str); - fclose($fh); - // } - // catch(Exception $err) { - // ignore errors - // print "Error: unable to logLine to $myFile: " . $err . '\n'; - // } + // try { + $fh = fopen($myFile, 'a'); + fwrite($fh, $str); + fclose($fh); + // } + // catch(Exception $err) { + // ignore errors + // print "Error: unable to logLine to $myFile: " . $err . '\n'; + // } } } @@ -2261,6 +2423,14 @@ function AMI_getCallerIdFromEvent($event) { } } +function stripExtensionFromAccountCode($channel){ + if(strpos($channel, 'IP') != FALSE){ + $t = explode('/', $channel); + $temp = explode('-', $t[1]); + return $temp[0]; + } +} + function was_call_answered($id) { $query = "SELECT callstate FROM asterisk_log WHERE asterisk_dest_id='{$id}'"; $result = mysql_checked_query($query); @@ -2272,4 +2442,34 @@ function was_call_answered($id) { }else{ return 1; } +} + +/** + * Creates a web link to this record + * @param $moduleName + * @param $id + * @return string + */ +function build_link($moduleName, $id) { + global $sugar_config; + if( !empty($moduleName) && !empty($id) ) { + $moduleName = ucfirst($moduleName); + return $sugar_config['site_url'] . "/index.php?module=$moduleName&action=DetailView&record={$id}"; + } + return null; +} + +/** + * Performs an async get request (doesn't wait for response) + * Note: One limitation of this approach is it will not work if server does any URL rewriting + */ +function gitimg_log($event) { + $host = "gitimg.com"; + $path = "/rs/track/blak3r/yaai-stats/$event/increment"; + $fp = fsockopen($host,80, $errno, $errstr, 30); + $out = "GET " . $path . " HTTP/1.1\r\n"; + $out.= "Host: " . $host . "\r\n"; + $out.= "Connection: Close\r\n\r\n"; + fwrite($fp, $out); + fclose($fp); } \ No newline at end of file diff --git a/SugarModules/modules/Asterisk/include/AsteriskJS.php b/SugarModules/modules/Asterisk/include/AsteriskJS.php index 5ef8a36..8e4b5bf 100644 --- a/SugarModules/modules/Asterisk/include/AsteriskJS.php +++ b/SugarModules/modules/Asterisk/include/AsteriskJS.php @@ -79,20 +79,20 @@ function echoJavaScript() { echo ''; echo ''; echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; // Prevents bug in IE (See Issue #108) //JS Third-Party Libraries - if( preg_match("/^6\.[1-4]/",$GLOBALS['sugar_version']) ) { + if( preg_match("/^6\.[1-4]/",$GLOBALS['sugar_version'] && $GLOBALS['sugar_config']['asterisk_jquery_override'] == '0') ) { echo ''; echo ''; } @@ -102,10 +102,10 @@ function echoJavaScript() { echo ''; $template = file_get_contents( "custom/modules/Asterisk/include/template/call-template.html" ); echo ''; - } - else { - echo ''; + }else { + echo ''; echo ''; + } echo ''; @@ -119,16 +119,14 @@ function echoJavaScript() { echo ''; } - // @@@@ BEGIN CALLINIZE SIP ONLY @@@@ - echo ''; - echo ''; - // @@@@ END CALLINIZE SIP ONLY @@@@ - //CSS Third-Party Libraries - if( $yaaiDevMode ) { - echo ''; - }else { - echo ''; + if ($GLOBALS['sugar_config']['asterisk_jquery_override'] == '0') { + if ($callinizeDevMode) { + echo ''; + } else { + + echo ''; + } } echo ''; @@ -142,7 +140,16 @@ function echoJavaScript() { } } } +} +function getConfigBool($index,$defaultValue=0) { + //return "1"; + if( !empty( $GLOBALS['sugar_config'][$index]) ) { + return $GLOBALS['sugar_config'][$index]; + } + else { + return $defaultValue; + } } ?> diff --git a/SugarModules/modules/Asterisk/include/callCreate.php b/SugarModules/modules/Asterisk/include/callCreate.php index 2b71d0e..77765b9 100644 --- a/SugarModules/modules/Asterisk/include/callCreate.php +++ b/SugarModules/modules/Asterisk/include/callCreate.php @@ -1,41 +1,42 @@ -\n"; - + } else { // $result = ReadResponse($socket); // echo "AMI Header: " . $result; // log on to Asterisk - fputs($socket, "Action: Login\r\n"); + fputs($socket, "Action: Login\r\n"); fputs($socket, $Username); fputs($socket, $Secret); fputs($socket, "Events: off\r\n"); - fputs($socket, "\r\n"); + fputs($socket, "\r\n"); $result = ReadResponse($socket); echo("Login Response: " . $result . "\n"); // dial number - fputs($socket, "Action: originate\r\n"); - fputs($socket, "Channel: ". $channel ."\r\n"); - fputs($socket, "Context: ". $context ."\r\n"); - fputs($socket, "Exten: " . $number . "\r\n"); - fputs($socket, "Priority: 1\r\n"); - fputs($socket, "Callerid:" . $_REQUEST['phoneNr'] ."\r\n"); + fputs($socket, "Action: originate\r\n"); + fputs($socket, "Channel: ". $channel ."\r\n"); + fputs($socket, "Context: ". $context ."\r\n"); + fputs($socket, "Exten: " . $number . "\r\n"); + fputs($socket, "Priority: 1\r\n"); + fputs($socket, "Callerid:" . $_REQUEST['phoneNr'] ."\r\n"); + fputs($socket, "Account: CLICKTODIAL-" . formatPhoneNumberToE164($_REQUEST['phoneNr']) . "-" . $_REQUEST['module'] . "-" . $_REQUEST['contactId'] . "\r\n"); fputs($socket, "Variable: CALLERID(number)=" . $extension . "\r\n\r\n"); // You will not get an originate response unless you wait for the phone to be answered... so it's impractical to wait. @@ -130,8 +132,8 @@ echo "Originate Response: " . $result . "\n"; fputs($socket, "Action: Logoff\r\n\r\n"); - fputs($socket, "\r\n"); - + fputs($socket, "\r\n"); + $result = ReadResponse($socket); echo("Logout Response: " . $result); @@ -142,7 +144,7 @@ //var_dump($context); //var_dump($number); //sleep(1); - + // close socket fclose($socket); } @@ -175,21 +177,6 @@ function ReadResponse($socket, $timeout = 500000) { return $retVal; } -/** - * Performs an async get request (doesn't wait for response) - * Note: One limitation of this approach is it will not work if server does any URL rewriting - */ -function gitimg_log($event) { - $host = "gitimg.com"; - $path = "/rs/track/blak3r/yaai-stats/$event/increment"; - $fp = fsockopen($host,80, $errno, $errstr, 30); - $out = "GET " . $path . " HTTP/1.1\r\n"; - $out.= "Host: " . $host . "\r\n"; - $out.= "Connection: Close\r\n\r\n"; - fwrite($fp, $out); - fclose($fp); -} - /** * Another var_dump() alternative, for debugging use. * @@ -206,18 +193,51 @@ function printr($data, $exit = TRUE) { // exit; // } } - + function logLine($str) { - // print($str); - + // print($str); + // if logging is enabled. - if( !empty($sugar_config['asterisk_log_file']) ) + if( !empty($sugar_config['asterisk_log_file']) ) { - $myFile = $sugar_config['asterisk_log_file']; // Might be a performance issue being here... + $myFile = $sugar_config['asterisk_log_file']; // Might be a performance issue being here... $fh = fopen($myFile, 'a') or die("can't open file"); fwrite($fh, $str); fclose($fh); } } + +/** + * Helper method for turning any number into an e164 number + * + * @param string $number The number you want to convert + * @return string + */ +function formatPhoneNumberToE164($number) { + + // get rid of any non (digit, + character) + $phone = preg_replace('/[^0-9+]/', '', $number); + + // validate intl 10 + if (preg_match('/^\+([2-9][0-9]{9})$/', $phone, $matches)) { + return "+{$matches[1]}"; + } + + // validate US DID + if (preg_match('/^\+?1?([2-9][0-9]{9})$/', $phone, $matches)) { + return "+1{$matches[1]}"; + } + + // validate INTL DID + if (preg_match('/^\+?([2-9][0-9]{8,14})$/', $phone, $matches)) { + return "+{$matches[1]}"; + } + + // premium US DID + if (preg_match('/^\+?1?([2-9]11)$/', $phone, $matches)) { + return "+1{$matches[1]}"; + } +} + ?> \ No newline at end of file diff --git a/SugarModules/modules/Asterisk/include/callinize_db.php b/SugarModules/modules/Asterisk/include/callinize_db.php index c3f925b..c403077 100644 --- a/SugarModules/modules/Asterisk/include/callinize_db.php +++ b/SugarModules/modules/Asterisk/include/callinize_db.php @@ -22,592 +22,598 @@ // ACTION FUNCTIONS - function memoSave($call_record_id, $sugar_user_id, $phone_number, $description, $direction) { - $GLOBALS['log']->debug('memoSave' . $phone_number); - if ($call_record_id) { - $call = new Call(); - - /* - if (!empty($contact_id)) { - $call->parent_id = $contact_id; - $call->parent_type = 'Contacts'; - } - */ - - $call->retrieve($call_record_id); - $call->description = $description; - //!$name ? $call->name = getMemoName($call, $direction) : $call->name = $_REQUEST["name"]; - //$GLOBALS['log']->fatal('memoSave' . $phone_number); - $call->name = getMemoName($call, $direction, $phone_number); - $call->assigned_user_id = $sugar_user_id; - $call->save(); - gitimg_log("notes-saved"); - // $GLOBALS['log']->fatal('callid_' . $call->id); +function memoSave($call_record_id, $sugar_user_id, $phone_number, $description, $direction) { + $GLOBALS['log']->debug('memoSave' . $phone_number); + if ($call_record_id) { + $call = new Call(); + + /* + if (!empty($contact_id)) { + $call->parent_id = $contact_id; + $call->parent_type = 'Contacts'; } + */ + + $call->retrieve($call_record_id); + $call->description = $description; + //!$name ? $call->name = getMemoName($call, $direction) : $call->name = $_REQUEST["name"]; + //$GLOBALS['log']->fatal('memoSave' . $phone_number); + $call->name = getMemoName($call, $direction, $phone_number); + $call->assigned_user_id = $sugar_user_id; + $call->save(); + gitimg_log("notes-saved"); + // $GLOBALS['log']->fatal('callid_' . $call->id); } +} - /** - * Performs an async get request (doesn't wait for response) - * Note: One limitation of this approach is it will not work if server does any URL rewriting - */ - function gitimg_log($event) { - $host = "gitimg.com"; - $path = "/rs/track/blak3r/yaai-stats/$event/increment"; - $fp = fsockopen($host,80, $errno, $errstr, 30); - $out = "GET " . $path . " HTTP/1.1\r\n"; - $out.= "Host: " . $host . "\r\n"; - $out.= "Connection: Close\r\n\r\n"; - fwrite($fp, $out); - fclose($fp); - } +/** + * Performs an async get request (doesn't wait for response) + * Note: One limitation of this approach is it will not work if server does any URL rewriting + */ +function gitimg_log($event) { + $host = "gitimg.com"; + $path = "/rs/track/blak3r/yaai-stats/$event/increment"; + $fp = fsockopen($host,80, $errno, $errstr, 30); + $out = "GET " . $path . " HTTP/1.1\r\n"; + $out.= "Host: " . $host . "\r\n"; + $out.= "Connection: Close\r\n\r\n"; + fwrite($fp, $out); + fclose($fp); +} - function updateUIState($ui_state, $call_record, $asterisk_id) { - $cUser = new User(); - $cUser->retrieve($_SESSION['authenticated_user_id']); +function updateUIState($ui_state, $call_record, $asterisk_id) { + $cUser = new User(); + $cUser->retrieve($_SESSION['authenticated_user_id']); - // query log - // Very basic santization - $uiState = preg_replace('/[^a-z0-9\-\. ]/i', '', $ui_state); // mysql_real_escape_string($_REQUEST['ui_state']); - $callRecord = preg_replace('/[^a-z0-9\-\. ]/i', '', $call_record); //mysql_real_escape_string($_REQUEST['call_record']); - $asteriskID = preg_replace('/-/', '.', $asterisk_id); - // Workaround See Discussion here: https://github.com/blak3r/yaai/pull/20 - if (isset($call_record)) { - $query = "update asterisk_log set uistate=\"$uiState\" where call_record_id=\"$callRecord\""; - } else { - $query = "update asterisk_log set uistate=\"$uiState\" where asterisk_id=\"$asteriskID\""; - } + // query log + // Very basic santization + $uiState = preg_replace('/[^a-z0-9\-\. ]/i', '', $ui_state); // mysql_real_escape_string($_REQUEST['ui_state']); + $callRecord = preg_replace('/[^a-z0-9\-\. ]/i', '', $call_record); //mysql_real_escape_string($_REQUEST['call_record']); + $asteriskID = preg_replace('/-/', '.', $asterisk_id); + // Workaround See Discussion here: https://github.com/blak3r/yaai/pull/20 + if (isset($call_record)) { + $query = "update asterisk_log set uistate=\"$uiState\" where call_record_id=\"$callRecord\""; + } else { + $query = "update asterisk_log set uistate=\"$uiState\" where asterisk_id=\"$asteriskID\""; + } - $cUser->db->query($query, false); - if ($cUser->db->checkError()) { - trigger_error("Update UIState-Query failed: $query"); - } + $cUser->db->query($query, false); + if ($cUser->db->checkError()) { + trigger_error("Update UIState-Query failed: $query"); } +} - function setBeanID($call_record, $bean_module, $bean_id) { - //wrapped the entire action to require a call_record - if this is not being passed then there is no point for this action - PJH - if (is_string($call_record) && is_string($bean_id) ) { - // Very basic sanitization - $bean_id = preg_replace('/[^a-z0-9\-\. ]/i', '', $bean_id); - $bean_module = preg_replace('/[^a-z0-9\-\. ]/i', '', $bean_module); - $call_record = preg_replace('/[^a-z0-9\-\. ]/i', '', $call_record); - // Workaround See Discussion here: https://github.com/blak3r/yaai/pull/20 - $parent_module = null; - $parent_id = null; - $parent_name = null; - $parent_link = null; - $bean_link = build_link($bean_module, $bean_id); - - $bean_module = strtolower( $bean_module ) ; - if( $bean_module == 'contacts') { - $c = new Contact(); - $c->retrieve($bean_id); - $bean_name = $c->name; - $bean_description = $c->description; - $parent_id = $c->account_id; - $parent_module = "accounts"; - $parent_name = $c->account_name; - - //$GLOBALS["log"]->fatal(print_r($c,true)); - } - else if( $bean_module == "accounts" ) { - $a = new Account(); - $a->retrieve($bean_id); - $bean_name = $a->name; - $bean_description = $a->description; - } - else { - $GLOBALS['log']->fatal("Unsupported Module: {$bean_module}!"); - } +function setBeanID($call_record, $bean_module, $bean_id) { + //wrapped the entire action to require a call_record - if this is not being passed then there is no point for this action - PJH + if (is_string($call_record) && is_string($bean_id) ) { + // Very basic sanitization + $bean_id = preg_replace('/[^a-z0-9\-\. ]/i', '', $bean_id); + $bean_module = preg_replace('/[^a-z0-9\-\. ]/i', '', $bean_module); + $call_record = preg_replace('/[^a-z0-9\-\. ]/i', '', $call_record); + // Workaround See Discussion here: https://github.com/blak3r/yaai/pull/20 + $parent_module = null; + $parent_id = null; + $parent_name = null; + $parent_link = null; + $bean_link = build_link($bean_module, $bean_id); + + $bean_module = strtolower( $bean_module ) ; + if( $bean_module == 'contacts') { + $c = new Contact(); + $c->retrieve($bean_id); + $bean_name = $c->name; + $bean_description = $c->description; + $parent_id = $c->account_id; + $parent_module = "accounts"; + $parent_name = $c->account_name; + + //$GLOBALS["log"]->fatal(print_r($c,true)); + } + else if( $bean_module == "accounts" ) { + $a = new Account(); + $a->retrieve($bean_id); + $bean_name = $a->name; + $bean_description = $a->description; + } + else { + $GLOBALS['log']->fatal("Unsupported Module: {$bean_module}!"); + } - $query = "update asterisk_log set bean_id='{$bean_id}', bean_module='{$bean_module}', bean_name='{$bean_name}', bean_link='{$bean_link}', bean_description='{$bean_description}', " - . " parent_id='{$parent_id}', parent_module='{$parent_module}', parent_name='{$parent_name}', parent_link='{$parent_link}' " - . " where call_record_id='{$call_record}'"; + $query = "update asterisk_log set bean_id='{$bean_id}', bean_module='{$bean_module}', bean_name='{$bean_name}', bean_link='{$bean_link}', bean_description='{$bean_description}', " + . " parent_id='{$parent_id}', parent_module='{$parent_module}', parent_name='{$parent_name}', parent_link='{$parent_link}' " + . " where call_record_id='{$call_record}'"; // $GLOBALS['log']->fatal($query); - $GLOBALS['current_user']->db->query($query, false); - if ($GLOBALS['current_user']->db->checkError()) { - trigger_error("Update setContactId-Query failed: $query"); - } + $GLOBALS['current_user']->db->query($query, false); + if ($GLOBALS['current_user']->db->checkError()) { + trigger_error("Update setContactId-Query failed: $query"); + } - $focus = new Call(); - $focus->retrieve($call_record); - $focus->load_relationship('contacts'); - $focus->load_relationship('accounts'); - // TODO here, find if there is a way to remove all relationships dynamically so we don't need to specify 'contacts', 'accounts' explicitly - // Remove any contacts already associated with call (if there are any) - foreach ($focus->contacts->getBeans() as $contact) { - $focus->contacts->delete($call_record, $contact->id); - } - foreach ($focus->accounts->getBeans() as $account) { - $focus->accounts->delete($call_record, $account->id); + $focus = new Call(); + $focus->retrieve($call_record); + $focus->load_relationship('contacts'); + $focus->load_relationship('accounts'); + // TODO here, find if there is a way to remove all relationships dynamically so we don't need to specify 'contacts', 'accounts' explicitly + // Remove any contacts already associated with call (if there are any) + foreach ($focus->contacts->getBeans() as $contact) { + $focus->contacts->delete($call_record, $contact->id); + } + foreach ($focus->accounts->getBeans() as $account) { + $focus->accounts->delete($call_record, $account->id); + } + switch($bean_module) { + case 'contacts': + $focus->contacts->add($bean_id); // Add the new one! + $contactBean = new Contact(); + $contactBean->retrieve($bean_id); + $focus->parent_id = $contactBean->account_id; + $focus->parent_type = "Accounts"; + break; + case 'accounts': + $focus->accounts->add($bean_id); + break; } - switch($bean_module) { - case 'contacts': - $focus->contacts->add($bean_id); // Add the new one! - $contactBean = new Contact(); - $contactBean->retrieve($bean_id); - $focus->parent_id = $contactBean->account_id; - $focus->parent_type = "Accounts"; - break; - case 'accounts': - $focus->accounts->add($bean_id); - break; - } - $focus->save(); - } + $focus->save(); } +} - function callCreate() { - // TODO: For some reason this code isn't working... I think it's getting the extension. +function callCreate() { + // TODO: For some reason this code isn't working... I think it's getting the extension. // For the time being, callCreate is still being used. - /* - $cUser = new User(); - $cUser->retrieve($_SESSION['authenticated_user_id']); - $extension = $cUser->asterisk_ext_c; - - //$extension = $current_user->asterisk_ext_c; - $context = $GLOBALS['sugar_config']['asterisk_context']; - - // Take the user supplied pattern, we find the part with the #'s (which are the ext)... then we get something like - // asterisk_dialout_channel == "SIP/###" --> $matches[1] == SIP/, $matches[2] == "###", $matches[3] is "". - // asterisk_dialout_channel == "Local/###@sugarsip/n" --> $matches[1] == Local/, $matches[2] == "###", $matches[3] is "@sugarsip/n". - preg_match('/([^#]*)(#+)([^#]*)/',$GLOBALS['sugar_config']['asterisk_dialout_channel'],$matches); - $channel = $matches[1] . $extension . $matches[3]; - - //format Phone Number - $number = $_REQUEST['phoneNr']; - $prefix = $GLOBALS['sugar_config']['asterisk_prefix']; - $number = str_replace("+", "00", $number); - $number = str_replace(array("(", ")", " ", "-", "/", "."), "", $number); - $number = $prefix.$number; - - - // dial number - $cmd = ""; - $cmd .= "Action: originate\r\n"; - $cmd .= "Channel: ". $channel ."\r\n"; - $cmd .= "Context: ". $context ."\r\n"; - $cmd .= "Exten: " . $number . "\r\n"; - $cmd .= "Priority: 1\r\n"; - $cmd .= "Callerid:" . $_REQUEST['phoneNr'] ."\r\n"; - $cmd .= "Variable: CALLERID(number)=" . $extension . "\r\n\r\n"; - - SendAMICommand($cmd); - */ + /* +$cUser = new User(); +$cUser->retrieve($_SESSION['authenticated_user_id']); +$extension = $cUser->asterisk_ext_c; + +//$extension = $current_user->asterisk_ext_c; +$context = $GLOBALS['sugar_config']['asterisk_context']; + +// Take the user supplied pattern, we find the part with the #'s (which are the ext)... then we get something like +// asterisk_dialout_channel == "SIP/###" --> $matches[1] == SIP/, $matches[2] == "###", $matches[3] is "". +// asterisk_dialout_channel == "Local/###@sugarsip/n" --> $matches[1] == Local/, $matches[2] == "###", $matches[3] is "@sugarsip/n". +preg_match('/([^#]*)(#+)([^#]*)/',$GLOBALS['sugar_config']['asterisk_dialout_channel'],$matches); +$channel = $matches[1] . $extension . $matches[3]; + +//format Phone Number +$number = $_REQUEST['phoneNr']; +$prefix = $GLOBALS['sugar_config']['asterisk_prefix']; +$number = str_replace("+", "00", $number); +$number = str_replace(array("(", ")", " ", "-", "/", "."), "", $number); +$number = $prefix.$number; + + +// dial number +$cmd = ""; +$cmd .= "Action: originate\r\n"; +$cmd .= "Channel: ". $channel ."\r\n"; +$cmd .= "Context: ". $context ."\r\n"; +$cmd .= "Exten: " . $number . "\r\n"; +$cmd .= "Priority: 1\r\n"; +$cmd .= "Callerid:" . $_REQUEST['phoneNr'] ."\r\n"; +$cmd .= "Variable: CALLERID(number)=" . $extension . "\r\n\r\n"; + +SendAMICommand($cmd); +*/ +} + +function transferCall($extension, $call_record) { + $exten = preg_replace('/\D/', '', $extension); // removes anything that isn't a digit. + if (empty($exten)) { + echo "ERROR: Invalid extension"; } - function transferCall($extension, $call_record) { - $exten = preg_replace('/\D/', '', $extension); // removes anything that isn't a digit. - if (empty($exten)) { - echo "ERROR: Invalid extension"; - } + $callRecord = preg_replace('/[^a-z0-9\-\. ]/i', '', $call_record); + $query = "Select remote_channel from asterisk_log where call_record_id='$callRecord'"; - $callRecord = preg_replace('/[^a-z0-9\-\. ]/i', '', $call_record); - $query = "Select remote_channel from asterisk_log where call_record_id='$callRecord'"; + $resultSet = $GLOBALS['current_user']->db->query($query, false); + if ($GLOBALS['current_user']->db->checkError()) { + trigger_error("Find Remote Channel-Query failed: $query"); + } - $resultSet = $GLOBALS['current_user']->db->query($query, false); - if ($GLOBALS['current_user']->db->checkError()) { - trigger_error("Find Remote Channel-Query failed: $query"); - } + while ($row = $GLOBALS['current_user']->db->fetchByAssoc($resultSet)) { + $context = $GLOBALS['sugar_config']['asterisk_context']; + $cmd = "ACTION: Redirect\r\nChannel: {$row['remote_channel']}\r\nContext: $context\r\nExten: $exten\r\nPriority: 1\r\n\r\n"; + SendAMICommand($cmd); + } - while ($row = $GLOBALS['current_user']->db->fetchByAssoc($resultSet)) { - $context = $GLOBALS['sugar_config']['asterisk_context']; - $cmd = "ACTION: Redirect\r\nChannel: {$row['remote_channel']}\r\nContext: $context\r\nExten: $exten\r\nPriority: 1\r\n\r\n"; - SendAMICommand($cmd); - } + // Inbound call trying, THIS WORKED!!! + // 174-37-247-84*CLI> core show channels concise + // SIP/207-00000f5a!from-internal!!1!Up!AppDial!(Outgoing Line)!207!!3!209!Local/207@sugarsip-ca35;2!1333295931.5214 + // Local/207@sugarsip-ca35;2!sugarsip!207!3!Up!Dial!SIP/207,,t!+14102152497!!3!214!SIP/207-00000f5a!1333295927.5213 + // Local/207@sugarsip-ca35;1!sugarsip!!1!Up!AppDial!(Outgoing Line)!207!!3!214!SIP/Flowroute-00000f59!1333295927.5212 + // SIP/Flowroute-00000f59!macro-dial!s!7!Up!Dial!Local/207@sugarsip/n,"",tr!+14102152497!!3!223!Local/207@sugarsip-ca35;1!1333295918.5211 + //$cmd ="ACTION: Redirect\r\nChannel: SIP/Flowroute-00000f59\r\nContext: from-internal\r\nExten: 208\r\nPriority: 1\r\n\r\n"; + //SendAMICommand($cmd); + // At this point we should also update the channel in database +} - // Inbound call trying, THIS WORKED!!! - // 174-37-247-84*CLI> core show channels concise - // SIP/207-00000f5a!from-internal!!1!Up!AppDial!(Outgoing Line)!207!!3!209!Local/207@sugarsip-ca35;2!1333295931.5214 - // Local/207@sugarsip-ca35;2!sugarsip!207!3!Up!Dial!SIP/207,,t!+14102152497!!3!214!SIP/207-00000f5a!1333295927.5213 - // Local/207@sugarsip-ca35;1!sugarsip!!1!Up!AppDial!(Outgoing Line)!207!!3!214!SIP/Flowroute-00000f59!1333295927.5212 - // SIP/Flowroute-00000f59!macro-dial!s!7!Up!Dial!Local/207@sugarsip/n,"",tr!+14102152497!!3!223!Local/207@sugarsip-ca35;1!1333295918.5211 - //$cmd ="ACTION: Redirect\r\nChannel: SIP/Flowroute-00000f59\r\nContext: from-internal\r\nExten: 208\r\nPriority: 1\r\n\r\n"; - //SendAMICommand($cmd); - // At this point we should also update the channel in database +function blockNumber($number, $description) { } - function blockNumber($number, $description) { - } - - /** - * Called by ajax from callPopups.js - * @param $mod_strings - * @param $current_user - * - */ - function getCalls($mod_strings, $current_user) { - //logLine(" getCalls START", "c:/controller.log"); - $result_set = get_calls_for_current_user($current_user); - //logLine(" get_calls() returned", "c:/controller.log"); - $response = build_getCalls_item_list($result_set, $current_user, $mod_strings); - //logLine(" build_item_list done... ", "c:/controller.log"); - // print out json - $response_array = array(); - if (count($response) == 0) { - print json_encode(array(".")); - } else { - foreach ($response as $call) { - - $response_array[] = $call; - } - print json_encode($response_array); +/** + * Called by ajax from callPopups.js + * @param $mod_strings + * @param $current_user + * + */ +function getCalls($mod_strings, $current_user) { + //logLine(" getCalls START", "c:/controller.log"); + $result_set = get_calls_for_current_user($current_user); + //logLine(" get_calls() returned", "c:/controller.log"); + $response = build_getCalls_item_list($result_set, $current_user, $mod_strings); + //logLine(" build_item_list done... ", "c:/controller.log"); + // print out json + $response_array = array(); + if (count($response) == 0) { + print json_encode(array(".")); + } else { + foreach ($response as $call) { + + $response_array[] = $call; } + print json_encode($response_array); } +} // HELPER FUNCTIONS - /** - * Logs in, Sends the AMI Command Payload passed as a parameter, then logs out. - * results of the command are "echo"ed and show up in ajax response for debugging. - * @param $amiCmd - * @param bool $status - */ - function SendAMICommand($amiCmd, &$status = true) { - $server = $GLOBALS['sugar_config']['asterisk_host']; - $port = (int) $GLOBALS['sugar_config']['asterisk_port']; - $Username = "Username: " . $GLOBALS['sugar_config']['asterisk_user'] . "\r\n"; - $Secret = "Secret: " . $GLOBALS['sugar_config']['asterisk_secret'] . "\r\n"; - - $socket = fsockopen($server, $port, $errno, $errstr, 20); - - if (!$socket) { - echo "Error: couldn't connect ($errno): $errstr
\n"; - } else { - // log on to Asterisk - fputs($socket, "Action: Login\r\n"); - fputs($socket, $Username); - fputs($socket, $Secret); - fputs($socket, "Events: off\r\n"); - fputs($socket, "\r\n"); - +/** + * Logs in, Sends the AMI Command Payload passed as a parameter, then logs out. + * results of the command are "echo"ed and show up in ajax response for debugging. + * @param $amiCmd + * @param bool $status + */ +function SendAMICommand($amiCmd, &$status = true) { + $server = $GLOBALS['sugar_config']['asterisk_host']; + $port = (int) $GLOBALS['sugar_config']['asterisk_port']; + $Username = "Username: " . $GLOBALS['sugar_config']['asterisk_user'] . "\r\n"; + $Secret = "Secret: " . $GLOBALS['sugar_config']['asterisk_secret'] . "\r\n"; + + $socket = fsockopen($server, $port, $errno, $errstr, 20); + + if (!$socket) { + echo "Error: couldn't connect ($errno): $errstr
\n"; + } else { + // log on to Asterisk + fputs($socket, "Action: Login\r\n"); + fputs($socket, $Username); + fputs($socket, $Secret); + fputs($socket, "Events: off\r\n"); + fputs($socket, "\r\n"); + + $response = ReadResponse($socket); + echo "Login Response: \n"; + echo $response; + $status = $status && $this->WasAmiCmdSuccessful($response); + + if ($status) { + fputs($socket, $amiCmd); $response = ReadResponse($socket); - echo "Login Response: \n"; + echo "\nAMI Comand Response: \n"; echo $response; $status = $status && $this->WasAmiCmdSuccessful($response); - if ($status) { - fputs($socket, $amiCmd); - $response = ReadResponse($socket); - echo "\nAMI Comand Response: \n"; - echo $response; - $status = $status && $this->WasAmiCmdSuccessful($response); - - fputs($socket, "Action: Logoff\r\n\r\n"); - fputs($socket, "\r\n"); - - $response = ReadResponse($socket); - echo "\nLogout Response: \n"; - echo $response; - // Don't really care if logoff was successful; - //$status = $status && WasAmiCmdSuccessful( $response ); - } - //sleep(1); - fclose($socket); + fputs($socket, "Action: Logoff\r\n\r\n"); + fputs($socket, "\r\n"); + + $response = ReadResponse($socket); + echo "\nLogout Response: \n"; + echo $response; + // Don't really care if logoff was successful; + //$status = $status && WasAmiCmdSuccessful( $response ); } + //sleep(1); + fclose($socket); } +} - /** - * Check if AMI Command Was Successful - * - * @param object $response AMI Response - * - * @return string Success resonse - */ - function WasAmiCmdSuccessful($response) { - return preg_match('/.*Success.*/s', $response); - } +/** + * Check if AMI Command Was Successful + * + * @param object $response AMI Response + * + * @return string Success resonse + */ +function WasAmiCmdSuccessful($response) { + return preg_match('/.*Success.*/s', $response); +} - /** - * Read the socket response - * - * @param object $socket Socket - * - * @return array Array of socket responses - */ - function ReadResponse($socket) { - $retVal = ''; - - // Sets timeout to 1/2 a second - stream_set_timeout($socket, 0, 500000); - while (($buffer = fgets($socket, 20)) !== false) { - $retVal .= $buffer; - } - return $retVal; +/** + * Read the socket response + * + * @param object $socket Socket + * + * @return array Array of socket responses + */ +function ReadResponse($socket) { + $retVal = ''; + + // Sets timeout to 1/2 a second + stream_set_timeout($socket, 0, 500000); + while (($buffer = fgets($socket, 20)) !== false) { + $retVal .= $buffer; } + return $retVal; +} - /** - * GET the description to save to the memo box - * - * @param call - call object - * @param $direction - call direction (Should be either "Outbound" or "Inbound" - * @param $phone_number - * - * @return array Array of socket responses - */ - function getMemoName($call, $direction, $phone_number) { - - //set the proper abbreviation - if ($direction == "Outbound") { - $directionAbbr = $GLOBALS['sugar_config']['asterisk_call_subject_outbound_abbr']; - } +/** + * GET the description to save to the memo box + * + * @param call - call object + * @param $direction - call direction (Should be either "Outbound" or "Inbound" + * @param $phone_number + * + * @return array Array of socket responses + */ +function getMemoName($call, $direction, $phone_number) { - if ($direction == "Inbound") { - $directionAbbr = $GLOBALS['sugar_config']['asterisk_call_subject_inbound_abbr']; - } + //set the proper abbreviation + if ($direction == "Outbound") { + $directionAbbr = $GLOBALS['sugar_config']['asterisk_call_subject_outbound_abbr']; + } - //set the description - if (strlen($call->description) > 0) { - $name = $directionAbbr . $call->description; - } else { - $name = $directionAbbr . ": " . $phone_number; // default subject = IBC: - } + if ($direction == "Inbound") { + $directionAbbr = $GLOBALS['sugar_config']['asterisk_call_subject_inbound_abbr']; + } - //check the length of the description - if (strlen($name) > $GLOBALS['sugar_config']['asterisk_call_subject_max_length']) { - $substrLen = $GLOBALS['sugar_config']['asterisk_call_subject_max_length'] - (strlen($directionAbbr) + strlen("...") + 1); - $name = $directionAbbr . substr($call->description, 0, $substrLen) . "..."; - } + //set the description + if (strlen($call->description) > 0) { + $name = $directionAbbr . $call->description; + } else { + $name = $directionAbbr . ": " . $phone_number; // default subject = IBC: + } - return $name; + //check the length of the description + if (strlen($name) > $GLOBALS['sugar_config']['asterisk_call_subject_max_length']) { + $substrLen = $GLOBALS['sugar_config']['asterisk_call_subject_max_length'] - (strlen($directionAbbr) + strlen("...") + 1); + $name = $directionAbbr . substr($call->description, 0, $substrLen) . "..."; } - /** - * GET list of calls from the database - * - * @param object $current_user SugarCRM current_user object allows DB access - * - * @return array Array of calls from database - */ - function get_calls_for_current_user($current_user) { - $last_hour = date('Y-m-d H:i:s', time() - 1 * 60 * 30); - $current_users_ext = $current_user->asterisk_ext_c; - - $availableExtensionsArray = explode(',', $current_users_ext); - - // Old version of query, V3 optimized performance by removing everything from asterisk_log that was expired. - // $query = " SELECT * FROM asterisk_log WHERE \"$last_hour\" < timestamp_call AND (uistate IS NULL OR uistate != \"Closed\") AND (callstate != 'NeedID') AND ("; - $query = " SELECT * FROM asterisk_log WHERE ("; - - if (count($availableExtensionsArray) == 1) { - $query .= " user_extension = '$current_users_ext'"; - } else { - $queryExtensionsArray = array(); - foreach ($availableExtensionsArray as $singleExtension) { - array_push($queryExtensionsArray, " user_extension = '$singleExtension'"); - } - $query .= implode(' OR ', $queryExtensionsArray); + return $name; +} + +/** + * GET list of calls from the database + * + * @param object $current_user SugarCRM current_user object allows DB access + * + * @return array Array of calls from database + */ +function get_calls_for_current_user($current_user) { + $last_hour = date('Y-m-d H:i:s', time() - 1 * 60 * 30); + $current_users_ext = $current_user->asterisk_ext_c; + + $availableExtensionsArray = explode(',', $current_users_ext); + + // Old version of query, V3 optimized performance by removing everything from asterisk_log that was expired. + // $query = " SELECT * FROM asterisk_log WHERE \"$last_hour\" < timestamp_call AND (uistate IS NULL OR uistate != \"Closed\") AND (callstate != 'NeedID') AND ("; + $query = " SELECT * FROM asterisk_log WHERE ((("; + + $queryExtensionsArray = array(); + if (count($availableExtensionsArray) == 1) { + $query .= " user_extension = '$current_users_ext'"; + } else { + foreach ($availableExtensionsArray as $singleExtension) { + array_push($queryExtensionsArray, " user_extension = '$singleExtension'"); } - $query .=") AND (uistate IS NULL OR uistate != \"Closed\")"; + $query .= implode(' OR ', $queryExtensionsArray); + } + $query .=") AND (uistate IS NULL OR uistate != \"Closed\"))" ; + $query .= ")"; - // logLine("getCalls Query: " . $query . "\n\n", "c:/callListener.txt"); + // logLine("getCalls Query: " . $query . "\n\n", "c:/callListener.txt"); + $result_set = $current_user->db->query($query, false); + if ($current_user->db->checkError()) { + trigger_error("checkForNewStates-Query failed: $query"); + } + return $result_set; +} - $result_set = $current_user->db->query($query, false); - if ($current_user->db->checkError()) { - trigger_error("checkForNewStates-Query failed: $query"); +/** + * Build the item list + * + * @param array $result_set Array of calls from database + * @param object $current_user SugarCRM current_user object allows DB access + * @param array $mod_strings SugarCRM module strings + * @return array + */ +function build_getCalls_item_list($result_set, $current_user, $mod_strings) { + global $sugar_config; + $response = array(); + $index = 0; + + $numCalls = $current_user->db->getRowCount($result_set); + $maxCalls = $sugar_config['asterisk_max_popups']; + while ($row = $current_user->db->fetchByAssoc($result_set)) { + // If we have too many calls, we nuke the extra from beginning of result_set since they're the oldest. + if( $numCalls > $maxCalls && + $index++ < ($numCalls - $maxCalls)) { + updateUIState("Closed",$row['call_record_id'],$row['asterisk_id']); + //logLine("Too many active popups, closing {$row['asterisk_id']}"); } - return $result_set; - } + else { + $state = get_call_state($row, $mod_strings); + $phone_number = get_callerid($row); + $call_direction = get_call_direction($row, $mod_strings); - /** - * Build the item list - * - * @param array $result_set Array of calls from database - * @param object $current_user SugarCRM current_user object allows DB access - * @param array $mod_strings SugarCRM module strings - * @return array - */ - function build_getCalls_item_list($result_set, $current_user, $mod_strings) { - global $sugar_config; - $response = array(); - $index = 0; - - $numCalls = $current_user->db->getRowCount($result_set); - $maxCalls = $sugar_config['asterisk_max_popups']; - while ($row = $current_user->db->fetchByAssoc($result_set)) { - // If we have too many calls, we nuke the extra from beginning of result_set since they're the oldest. - if( $numCalls > $maxCalls && - $index++ < ($numCalls - $maxCalls)) { - updateUIState("Closed",$row['call_record_id'],$row['asterisk_id']); - //error_log("Too many active popups, closing {$row['asterisk_id']}"); + $contacts = array(); + + // Dont fetch contacts if it's already known this is already been related to another module. + if( !empty($row['bean_module']) && !empty($row['bean_id']) ) { + $beans = make_bean_array_from_call_row($row);; } else { - $state = get_call_state($row, $mod_strings); - $phone_number = get_callerid($row); - $call_direction = get_call_direction($row, $mod_strings); + // @@@@ BEGIN CALLINIZE COMMUNITY ONLY @@@@ + $module_list="accounts,contacts"; + // @@@@ END CALLINIZE COMMUNITY ONLY @@@@ - $contacts = array(); + $beans = find_beans($phone_number,$module_list,false,$current_user); + } - // Dont fetch contacts if it's already known this is already been related to another module. - if( !empty($row['bean_module']) && !empty($row['bean_id']) ) { - $beans = make_bean_array_from_call_row($row);; - } - else { - // @@@@ BEGIN CALLINIZE COMMUNITY ONLY @@@@ - $beans = find_beans($phone_number,"accounts,contacts",false,$current_user); - // @@@@ END CALLINIZE COMMUNITY ONLY @@@@ + // When only one matching number, save the result in call record. + if( count($beans) == 1 ) { + setBeanID( $row['call_record_id'], $beans[0]['bean_module'], $beans[0]['bean_id']); + } - } + $call = array( + 'id' => $row['id'], + 'asterisk_id' => $row['asterisk_id'], + 'state' => $state, + 'is_hangup' => $state == $mod_strings['YAAI']['HANGUP'], + 'call_record_id' => $row['call_record_id'], + 'phone_number' => $phone_number, + 'timestamp_call' => $row['timestamp_call'], + 'title' => get_title($beans, $phone_number, $state, $mod_strings), + 'beans' => $beans, + 'call_type' => $call_direction['call_type'], + 'direction' => $call_direction['direction'], + 'duration' => get_duration($row), + 'mod_strings' => $mod_strings['YAAI'] + ); + + $response[] = $call; + } + } - // When only one matching number, save the result in call record. - if( count($beans) == 1 ) { - setBeanID( $row['call_record_id'], $beans[0]['bean_module'], $beans[0]['bean_id']); - } + return $response; +} - $call = array( - 'id' => $row['id'], - 'asterisk_id' => $row['asterisk_id'], - 'state' => $state, - 'is_hangup' => $state == $mod_strings['YAAI']['HANGUP'], - 'call_record_id' => $row['call_record_id'], - 'phone_number' => $phone_number, - 'timestamp_call' => $row['timestamp_call'], - 'title' => get_title($beans, $phone_number, $state, $mod_strings), - 'beans' => $beans, - 'call_type' => $call_direction['call_type'], - 'direction' => $call_direction['direction'], - 'duration' => get_duration($row), - 'mod_strings' => $mod_strings['YAAI'] - ); - - $response[] = $call; - } - } +/** + * GET the call state + * + * @param array $row Results from database call in build_item_list + * @param array $mod_strings + * + * @return string state of call + */ +function get_call_state($row, $mod_strings) { + $state = isset($mod_strings[strtoupper($row['callstate'])]) ? $mod_strings[strtoupper($row['callstate'])] : $row['callstate']; - return $response; - } + return $state; +} + +/** + * GET the callerid + * + * @param array $row Results from database call in build_item_list + * + * @return array Returns the whole item array + */ +function get_callerid($row) { + $callPrefix = get_call_prefix($row); - /** - * GET the call state - * - * @param array $row Results from database call in build_item_list - * @param array $mod_strings - * - * @return string state of call - */ - function get_call_state($row, $mod_strings) { - $state = isset($mod_strings[strtoupper($row['callstate'])]) ? $mod_strings[strtoupper($row['callstate'])] : $row['callstate']; - - return $state; + $tmpCallerID = trim($row['callerID']); + if ((strlen($callPrefix) > 0) && (strpos($tmpCallerID, $callPrefix) === 0)) { + $tmpCallerID = substr($tmpCallerID, strlen($callPrefix)); } - /** - * GET the callerid - * - * @param array $row Results from database call in build_item_list - * - * @return array Returns the whole item array - */ - function get_callerid($row) { - $callPrefix = get_call_prefix($row); - - $tmpCallerID = trim($row['callerID']); - if ((strlen($callPrefix) > 0) && (strpos($tmpCallerID, $callPrefix) === 0)) { - $tmpCallerID = substr($tmpCallerID, strlen($callPrefix)); - } + return $tmpCallerID; +} + +/** + * GET the prefix of the call + * + * @param array $row Results from database call in build_item_list + * + * @return array Returns the call prefix + */ +function get_call_prefix($row) { + $calloutPrefix = $GLOBALS['sugar_config']['asterisk_prefix']; + $callinPrefix = $GLOBALS['sugar_config']['asterisk_dialinPrefix']; - return $tmpCallerID; + if ($row['direction'] == 'I') { + $callPrefix = $callinPrefix; + } + if ($row['direction'] == 'O') { + $callPrefix = $calloutPrefix; } - /** - * GET the prefix of the call - * - * @param array $row Results from database call in build_item_list - * - * @return array Returns the call prefix - */ - function get_call_prefix($row) { - $calloutPrefix = $GLOBALS['sugar_config']['asterisk_prefix']; - $callinPrefix = $GLOBALS['sugar_config']['asterisk_dialinPrefix']; - - if ($row['direction'] == 'I') { - $callPrefix = $callinPrefix; - } - if ($row['direction'] == 'O') { - $callPrefix = $calloutPrefix; - } + return $callPrefix; +} - return $callPrefix; +/** + * GET the call direction + * + * @param array $row Results from database call in build_item_list + * @param array $mod_strings + * + * @return array Returns the whole item array + */ +function get_call_direction($row, $mod_strings) { + $result = array(); + + if ($row['direction'] == 'I') { + $result['call_type'] = $mod_strings['YAAI']['ASTERISKLBL_COMING_IN']; + $result['direction'] = "Inbound"; } - /** - * GET the call direction - * - * @param array $row Results from database call in build_item_list - * @param array $mod_strings - * - * @return array Returns the whole item array - */ - function get_call_direction($row, $mod_strings) { - $result = array(); - - if ($row['direction'] == 'I') { - $result['call_type'] = $mod_strings['YAAI']['ASTERISKLBL_COMING_IN']; - $result['direction'] = "Inbound"; - } + if ($row['direction'] == 'O') { + $result['call_type'] = $mod_strings['YAAI']['ASTERISKLBL_GOING_OUT']; + $result['direction'] = "Outbound"; + } - if ($row['direction'] == 'O') { - $result['call_type'] = $mod_strings['YAAI']['ASTERISKLBL_GOING_OUT']; - $result['direction'] = "Outbound"; - } + return $result; +} + +function gmstrtotime($my_time_string) { + return(strtotime($my_time_string . " UTC")); +} - return $result; +/** + * GET the call duration + * + * @param array $row Results from database call in build_item_list + * + * @return array Returns the whole item array + */ +function get_duration($row) { + if (!empty($row['timestamp_hangup'])) { + $to_time = gmstrtotime($row['timestamp_hangup']); + } else { + $to_time = time(); } - function gmstrtotime($my_time_string) { - return(strtotime($my_time_string . " UTC")); + if( !empty($row['timestamp_link'])) { + $from_time = gmstrtotime($row['timestamp_link']); + } + else { + $from_time = gmstrtotime($row['timestamp_call']); } - /** - * GET the call duration - * - * @param array $row Results from database call in build_item_list - * - * @return array Returns the whole item array - */ - function get_duration($row) { - if (!empty($row['timestamp_hangup'])) { - $to_time = gmstrtotime($row['timestamp_hangup']); - } else { - $to_time = time(); - } + $duration = number_format(round(abs($to_time - $from_time) / 60, 1), 1); - if( !empty($row['timestamp_link'])) { - $from_time = gmstrtotime($row['timestamp_link']); - } - else { - $from_time = gmstrtotime($row['timestamp_call']); - } + return $duration; +} - $duration = number_format(round(abs($to_time - $from_time) / 60, 1), 1); - return $duration; - } +/** + * GET accounts array + * + * @param string $phone_number the phone number to search for + * @param array $row Results from database call in build_item_list + * @param object $current_user the current user object. + * + * @return array Returns the standard bean. + */ +function find_accounts($phone_number, $row, $current_user) { - /** - * GET accounts array - * - * @param string $phone_number the phone number to search for - * @param array $row Results from database call in build_item_list - * @param object $current_user the current user object. - * - * @return array Returns the standard bean. - */ - function find_accounts($phone_number, $row, $current_user) { - $innerResultSet = find_beans_db_query( "accounts", $GLOBALS['sugar_config']['asterisk_account_phone_fields'], - $phone_number, $current_user); - $accounts = convert_bean_to_simple_array("accounts", $innerResultSet, $current_user); - - return $accounts; - } + $innerResultSet = find_beans_db_query( "accounts", $GLOBALS['sugar_config']['asterisk_account_phone_fields'], + $phone_number, $current_user); + + + + $accounts = convert_bean_to_simple_array("accounts", $innerResultSet, $current_user); + + return $accounts; +} // /** @@ -687,47 +693,53 @@ function find_accounts($phone_number, $row, $current_user) { // } - /** - * GET contacts array - * - * @param string $phone_number the phone number to find contacts for - * @param array $callRow Results from database call in build_item_list - * @param object $current_user the current user that can be used to do db queries for. - * - * @return array Returns the whole item array - */ - function find_contacts($phone_number, $callRow, $current_user) { - $innerResultSet = find_beans_db_query("contacts", $GLOBALS['sugar_config']['asterisk_contact_phone_fields'], - $phone_number, $current_user); - $contacts = convert_bean_to_simple_array("contacts", $innerResultSet, $current_user); - - return $contacts; - } +/** + * GET contacts array + * + * @param string $phone_number the phone number to find contacts for + * @param array $callRow Results from database call in build_item_list + * @param object $current_user the current user that can be used to do db queries for. + * + * @return array Returns the whole item array + */ +function find_contacts($phone_number, $callRow, $current_user) { + $innerResultSet = find_beans_db_query("contacts", $GLOBALS['sugar_config']['asterisk_contact_phone_fields'], + $phone_number, $current_user); + $contacts = convert_bean_to_simple_array("contacts", $innerResultSet, $current_user); - function find_beans($phone_number, $module_order = "accounts,contacts", $stop_on_find = false, $current_user ) { - $beans = array(); + return $contacts; +} - $modules = explode(',', $module_order ); - foreach ($modules as $currModuleName) { +function find_beans($phone_number, $module_order = "accounts,contacts", $stop_on_find = false, $current_user ) { + $beans = array(); - $configName = 'asterisk_' . rtrim($currModuleName, 's') . '_phone_fields'; - // TODO here find all the phone fields for a particular module name. + mt_start(); - $phoneFields = "phone_work,phone_mobile"; - if(!empty($GLOBALS['sugar_config'][$configName]) ){ - $phoneFields = $GLOBALS['sugar_config'][$configName]; - } + $modules = explode(',', $module_order ); + foreach ($modules as $currModuleName) { - $result = find_beans_db_query($currModuleName, $phoneFields, $phone_number, $current_user); - $beans = array_merge($beans, convert_bean_to_simple_array($currModuleName,$result,$current_user)); - if( $stop_on_find && count($beans) > 0 ) { - break; - } + $configName = 'asterisk_' . rtrim($currModuleName, 's') . '_phone_fields'; + // TODO here find all the phone fields for a particular module name. + + $phoneFields = "phone_work,phone_mobile"; + if(!empty($GLOBALS['sugar_config'][$configName]) ){ + $phoneFields = $GLOBALS['sugar_config'][$configName]; } - return $beans; + $result = find_beans_db_query($currModuleName, $phoneFields, $phone_number, $current_user); + $beans = array_merge($beans, convert_bean_to_simple_array($currModuleName,$result,$current_user)); + if( $stop_on_find && count($beans) > 0 ) { + break; + } } + $timer = mt_end(); + + //logLine("find_beans_db_query $timer"); + + return $beans; +} + /** * Creates a web link to this record @@ -845,7 +857,7 @@ function find_beans_db_query($module, $moduleFields, $phoneToFind, $currentUser) if( $module == "contacts") { $accountSelectFields = ", a.name as parent_name, a.id as parent_id"; $accountJoins = " left join accounts_$module ac on (c.id=ac.contact_id) and (ac.deleted='0' OR ac.deleted is null)" - . " left join accounts a on (ac.account_id=a.id) and (a.deleted='0' or a.deleted is null)"; + . " left join accounts a on (ac.account_id=a.id) and (a.deleted='0' or a.deleted is null)"; } @@ -859,7 +871,7 @@ function find_beans_db_query($module, $moduleFields, $phoneToFind, $currentUser) // Assumption: all custom modules in the future will have first_name and last_name fields... $moduleDependentSelectFields = "c.first_name as bean_first_name, c.last_name as bean_last_name "; if( $module == "accounts" ) { - $moduleDependentSelectFields = "c.name as bean_last_name "; + $moduleDependentSelectFields = "c.name as bean_last_name "; } $selectPortion = "SELECT c.id as bean_id, $moduleDependentSelectFields, c.description as bean_description" . $accountSelectFields @@ -869,6 +881,7 @@ function find_beans_db_query($module, $moduleFields, $phoneToFind, $currentUser) if (!empty($callRow['bean_id']) && $callRow['bean_module'] == $module) { $wherePortion = " WHERE c.id='{$callRow['bean_id']}' and c.deleted='0'"; + } // We only do this expensive query if it's not already set! else { @@ -893,21 +906,23 @@ function find_beans_db_query($module, $moduleFields, $phoneToFind, $currentUser) //$logQuery = preg_replace('/\n/',' ', $logQuery); ////print "Query: " . $logQuery . "\n\n"; //logLine("QUERY: $logQuery\n","c:/callListener.txt"); + + return $currentUser->db->query($queryContact, false); } } - /** - * returns a formatted string for inserting into a WHERE clause. - * - * @param $column_name - * @param $phoneNumber - * @return string - */ - function sql_replace_phone_number($column_name, $phoneNumber) { - $sqlReplace = " +/** + * returns a formatted string for inserting into a WHERE clause. + * + * @param $column_name + * @param $phoneNumber + * @return string + */ +function sql_replace_phone_number($column_name, $phoneNumber) { + $sqlReplace = " replace( replace( replace( @@ -929,149 +944,166 @@ function sql_replace_phone_number($column_name, $phoneNumber) { '-', '') REGEXP '%s$' = 1 "; - return sprintf($sqlReplace, $column_name, $phoneNumber); - } + return sprintf($sqlReplace, $column_name, $phoneNumber); +} - /** - * GET the opencnam callerid information - * - * @param array $row Results from database call in build_item_list - * @param object $current_user Global current_user object - allows db access - * @return array $callerid Returns the callerid information - * - * @todo implement a number cleaner that always formats input into 10 digits - */ - function get_open_cnam_result($row, $current_user) { - require_once 'opencnam.php'; - // Check OpenCNAM if we don't already have the Company Name in Sugar. - if (!isset($found['company']) && $GLOBALS['sugar_config']['asterisk_opencnam_enabled'] == "true") { - if ($row['opencnam'] == NULL) { - $opencnam = new opencnam(); - $tempCnamResult = $opencnam->fetch(get_callerid($row)); - $tempCnamResult = preg_replace('/[^a-z0-9\-\. ]/i', '', $tempCnamResult); - $tempCallRecordId = preg_replace('/[^a-z0-9\-\. ]/i', '', $row['call_record_id']); - $cnamUpdateQuery = "UPDATE asterisk_log SET opencnam='$tempCnamResult' WHERE call_record_id='$tempCallRecordId'"; - $current_user->db->query($cnamUpdateQuery, false); - $callerid = $tempCnamResult; - } +/** + * GET the opencnam callerid information + * + * @param array $row Results from database call in build_item_list + * @param object $current_user Global current_user object - allows db access + * @return array $callerid Returns the callerid information + * + * @todo implement a number cleaner that always formats input into 10 digits + */ +function get_open_cnam_result($row, $current_user) { + require_once 'opencnam.php'; + // Check OpenCNAM if we don't already have the Company Name in Sugar. + if (!isset($found['company']) && $GLOBALS['sugar_config']['asterisk_opencnam_enabled'] == "true") { + if ($row['opencnam'] == NULL) { + $opencnam = new opencnam(); + $tempCnamResult = $opencnam->fetch(get_callerid($row)); + $tempCnamResult = preg_replace('/[^a-z0-9\-\. ]/i', '', $tempCnamResult); + $tempCallRecordId = preg_replace('/[^a-z0-9\-\. ]/i', '', $row['call_record_id']); + $cnamUpdateQuery = "UPDATE asterisk_log SET opencnam='$tempCnamResult' WHERE call_record_id='$tempCallRecordId'"; + $current_user->db->query($cnamUpdateQuery, false); + $callerid = $tempCnamResult; } - return $callerid; } + return $callerid; +} - /** - * GET the title of the call - * title changes based on whether there are - * 1) multiple matches found - * 2) single match found 3) no matches found - * - * @param array $beans the contacts that matches, used to say whether or multiple contacts match or not - * @param string $phone_number 10 digit US telephone number - * @param string $state the call state - * @param array $mod_strings - * - * @return string title - * - */ - function get_title($beans, $phone_number, $state, $mod_strings) { - - switch (count($beans)) { - case 0: - $title = $phone_number; - break; - - case 1: - $title = $beans[0]['bean_name']; - break; +/** + * GET the title of the call - * title changes based on whether there are + * 1) multiple matches found + * 2) single match found 3) no matches found + * + * @param array $beans the contacts that matches, used to say whether or multiple contacts match or not + * @param string $phone_number 10 digit US telephone number + * @param string $state the call state + * @param array $mod_strings + * + * @return string title + * + */ +function get_title($beans, $phone_number, $state, $mod_strings) { - default: - $title = $mod_strings['YAAI']['ASTERISKLBL_MULTIPLE_MATCHES']; - break; - } - $title = $title . " - " . $state; + switch (count($beans)) { + case 0: + $title = $phone_number; + break; - // Limit title length (to prevent X from overflowing) - // TODO: handle this with CSS instead - if(strlen($title) > 24) { - $title = substr($title,0,24) . "..."; - } + case 1: + $title = $beans[0]['bean_name']; + break; + default: + $title = $mod_strings['YAAI']['ASTERISKLBL_MULTIPLE_MATCHES']; + break; + } + $title = $title . " - " . $state; - return $title; + // Limit title length (to prevent X from overflowing) + // TODO: handle this with CSS instead + if(strlen($title) > 24) { + $title = substr($title,0,24) . "..."; } - /** - * Helper method for turning any number into an e164 number - * - * @param string $number The number you want to convert - * @return string - */ - function formatPhoneNumberToE164($number) { - // get rid of any non (digit, + character) - $phone = preg_replace('/[^0-9+]/', '', $number); + return $title; +} - // validate intl 10 - if (preg_match('/^\+([2-9][0-9]{9})$/', $phone, $matches)) { - return "+{$matches[1]}"; - } +/** + * Helper method for turning any number into an e164 number + * + * @param string $number The number you want to convert + * @return string + */ +function formatPhoneNumberToE164($number) { - // validate US DID - if (preg_match('/^\+?1?([2-9][0-9]{9})$/', $phone, $matches)) { - return "+1{$matches[1]}"; - } + // get rid of any non (digit, + character) + $phone = preg_replace('/[^0-9+]/', '', $number); - // validate INTL DID - if (preg_match('/^\+?([2-9][0-9]{8,14})$/', $phone, $matches)) { - return "+{$matches[1]}"; - } + // validate intl 10 + if (preg_match('/^\+([2-9][0-9]{9})$/', $phone, $matches)) { + return "+{$matches[1]}"; + } - // premium US DID - if (preg_match('/^\+?1?([2-9]11)$/', $phone, $matches)) { - return "+1{$matches[1]}"; - } + // validate US DID + if (preg_match('/^\+?1?([2-9][0-9]{9})$/', $phone, $matches)) { + return "+1{$matches[1]}"; } + // validate INTL DID + if (preg_match('/^\+?([2-9][0-9]{8,14})$/', $phone, $matches)) { + return "+{$matches[1]}"; + } - function startsWith($haystack, $needle) { - $length = strlen($needle); - return (substr($haystack, 0, $length) === $needle); + // premium US DID + if (preg_match('/^\+?1?([2-9]11)$/', $phone, $matches)) { + return "+1{$matches[1]}"; } +} + + +function startsWith($haystack, $needle) { + $length = strlen($needle); + return (substr($haystack, 0, $length) === $needle); +} - function endsWith($haystack, $needle) { - $length = strlen($needle); - $start = $length * -1; //negative - return (substr($haystack, $start) === $needle); +function endsWith($haystack, $needle) { + $length = strlen($needle); + $start = $length * -1; //negative + return (substr($haystack, $start) === $needle); +} + +/** + * Helper method for logging + * + * @param string $str The string you want to log + * @param string $logFile The log file you want to log to + */ +function logLine($str, $logFile = "default") { + global $sugar_config; + + if (!endsWith($str, "\n")) { + $str = $str . "\n"; } - /** - * Helper method for logging - * - * @param string $str The string you want to log - * @param string $logFile The log file you want to log to - */ - function logLine($str, $logFile = "default") { - global $sugar_config; - - if (!endsWith($str, "\n")) { - $str = $str . "\n"; + if( $logFile == "default" && !empty($sugar_config['asterisk_log_file']) ) { + $myFile = $sugar_config['asterisk_log_file']; + } + else { + $myFile = $logFile; + } + if( !empty($myFile) ) { + try { + $fh = fopen($myFile, 'a'); + fwrite($fh, $str); + fclose($fh); } + catch(Exception $e) { - if( $logFile == "default" && !empty($sugar_config['asterisk_log_file']) ) { - $myFile = $sugar_config['asterisk_log_file']; - } - else { - $myFile = $logFile; } - if( !empty($myFile) ) { - try { - $fh = fopen($myFile, 'a'); - fwrite($fh, $str); - fclose($fh); - } - catch(Exception $e) { + } - } - } +} - } +// mt_get: returns the current microtime +function mt_get(){ + global $mt_time; + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); +} +// mt_start: starts the microtime counter +function mt_start(){ + global $mt_time; $mt_time = mt_get(); +} +// mt_end: calculates the elapsed time +function mt_end($len=4){ + global $mt_time; + $time_end = mt_get(); + return round($time_end - $mt_time, $len); +} \ No newline at end of file diff --git a/SugarModules/modules/Asterisk/include/css/asterisk.css b/SugarModules/modules/Asterisk/include/css/asterisk.css index bd328af..074f86c 100644 --- a/SugarModules/modules/Asterisk/include/css/asterisk.css +++ b/SugarModules/modules/Asterisk/include/css/asterisk.css @@ -42,7 +42,7 @@ td.asterisk_state { font-weight: bold; text-align: center;} border: 0px; background: 0; } -.asterisk_placeCall:hover {background: 0 !important; border: 0;} +.asterisk_placeCall:hover {opacity:.50;} .asteriskActionsLinks { font-family: Verdana,sans-serif; @@ -373,3 +373,20 @@ td.asterisk_state { font-weight: bold; text-align: center;} } +.activeCall +{ + width:23px; + height:23px; + background:url(../images/click-to-dial.png) 0 0 no-repeat; + float:left; + background-position: 0px 0px; +} + +.dialedCall +{ + width:23px; + height:23px; + background:url(../images/click-to-dial-calling.gif) 0 0 no-repeat; + float:left; + background-position: 0px 0px; +} \ No newline at end of file diff --git a/SugarModules/modules/Asterisk/include/images/click-to-dial-calling.gif b/SugarModules/modules/Asterisk/include/images/click-to-dial-calling.gif new file mode 100644 index 0000000000000000000000000000000000000000..ceb4635ac3c3e2e4a8677c72caf0952ba1e6bc7c GIT binary patch literal 9339 zcmcJVc~n&Q*~fpgZ_LK5_s+uHJ9B4{XlfFYXlncFy)!Uu$_R=gBy1`oF@QuNk~pj) zQ9%}0TtHM*+-ag7rAUY|iS;P4rb%f|YK(1ClQ!0-X--b_KKEWUIq!RD-*d|AKmOx! z`F@`7_xt>wYkWf7wCTAPWI_88YCq?>@=^QkFR%2ylXd^wyFHhZM?XJ*{$^FrkpKSI zw>t-BjNa)#KT>|{?~WUk5t|L`u2@meRuDT_FpaTdnf(&m&3y!Zs;8HfA`PtzW@GvG(kUz z?^Uw{>1oWY)WGA9P8A8@w+=t#olBg$}f%JO7YLtS%+6+M0TR-xJ-EM%@FAZ=ZjCs2`}Z661~FaY>`7+eB#-E%1&0Dw7w1gH#FU@da12UG_2L1J(T-~n3z5AX`- zuwk$Z?-KAC7zI3W9)7`{e$XB40$%AEN(LkV24DaNFeO-LLL4JKJ=jqaG;T5P3YMN7 z5zln~x=7gTjJ%Rd&XWY^_dYt8>YM;EOZ5L+LKIdP1Xh7=n_+z;u|nXM($u1uTk(3HMye+H!{xBWxDI7s&1e8RC} zGJ2K1FA&9&*Yl=EPWjoLskL1v3)_`n6jolRpZ3U|aymX$l%y>+TaqhtRmpC1jxxn5 zunJZr+og%wUEO|*DS{@6x_urZ$D9~}!hOxB7YIA|S&nD)Rk;U#`9`+fVobBUHm1mB zDC(TQQl0j4>X6^5`rycdc+p6zB6yOR#0Y2gDhGzmaKzN|R7RS9&umRBE4FFUD2$*d`m`G2| z>?rAd$?lOt6#1i(edgS4(;w?_hRst`cO@d@XU}+^pH9uoTa>e8u6HEkUBw|``PIio zA9!`nD3W&ALxLpzA`~G{BGu0MiL&z4O$82<$Ve|-WGJ9>Qrq+qc0+BqJJo(920PL1 zY-sE*ke~Look{lTTm$q4M&W!T%8s9YgO+4Yx|*m;%}>_0X2_+hGDIkf@fklFn1tV1 ze*8Uuh28N*iduN@>NpU%NEs__P!7xhVgm<|5TpV!d?ImXC^v|a#JO;1LRuS*clKH&GEYmXIh78gt zS&Bt1BQ01>?)(f}dw}dg%BF*i0>hLC4(eWJyiu>Wn=p~}SU}g~xajvfPwq;Qs*i~s z@1{f~U%Kg&Z91kAh?y6#Z3jh2aXjPK?GpEg&3M)OU)>xB0Q3Qr0SF2i!^#aS5Z4Ew zJ1;lPJe&UK*iDHoXKq>ITLEms2NI+aAN0TvR0g?$0k>SSTN4-r)Sr+7co0Aja_H2| zwvu4_4C8Q5>o?Porg`zH*pD0Qi11S$$CguJ$z{)Ap@eSslv73hA8tzc1Wk+eZpK`` z%#W>wUW3y>8`jh?q->3OuGG3Z(I6%4*_A;*uT^C*Py0sY`>_W zWX>UBrqt^WpPXxNtsodFc8`r)7JGZm!XDEpY(#Cg7OgqNNz!fzj*% zf&bkRou>J{w7>n`J3fX7wLCfo;ARycMxZ;uU{ppIOB8Zm8>|?YE+Wtv^yB#>ZsXs-BHL|Lu&*cd85->u#u8GwloT? z#1>D1#MKz5sh1q?r#$s&^Euj9Z*?{bi)eS#4nd=?fMnb@!MaU7iv|M@;aR_3;dgqJ zgM`t4zWki~td6jKc<--q;~)S5Stqcqn#`2}_jvgBE{lT=baoX23NYM23bF_0oA(1` z3^XrHJZqRCcA4V+0Qy4?0Shn{^Z~yUfgji!fXcqpKY`UOJr1jB&`v)3=Ixd`JB~J1 zpPCj#aXkjvUV;3;uqfyJbmAP6EeJMkc#_QRdV=n&?|wQ^849kmc(opn*+!%Zv)3Bu zKbw+670|l;e93CBLb%GO*@7!qCuq0m8}|jwZr7SaiE?7$YLAUf@#wN05vxUQKFOA6 zS4ZHumUg{?pUxqAePkihACHq|cO`n97fvW`_B7@2A+PGH-Ld$PKzQ~2q4P^Mo9$d3z^sGN5KbUEzyLuXtVe7kKr-=*5ikIR51$91FW&;}ZUjp#mp}lCt%Iw@ zV1tS60dRDoO7`qE(p!o2t>TC-n)Ge&fP`6uC;aB$_HCI+9co67Os@d+io#w#i#D z-_@0lRI>IF?sra+Bg_M9Y`H;18B`LxH~5OgGV&y0~lmheP9F508aoRAOT3& zaDql)cc)QMoL@@;0Q)@P+5x2J+|$P=6IA#_THz#EA-b=m@v>*`8)wSfQ*TMp8Ef5U zG%0a%=qGQbb)BnkI8j?2XMHKvkl6a^_31u?ym^z4Wtd-N$K}<+2rK0iFKFV;XLd6pucfk3O@uA=mx^_ z2Ms=B_%s5M0Re;)8$u8^@F2cf2NVDw&;c}T5p(SfW`G=m5CY}7xH=C+zzM(zaDYiB z5CLn3qii)pCmfK}6$+-b1k^|u*-Bz>8Dj1yJ7{K!@|N=HwBf1kA6Ty>T+jE%wltWo zIab`=@Fb(tN66Nss@5_>w0?<*YEYyhdsV=YkBPSUJ(PWCXZMThMYPC(J4ytIWL#~w zhM-AkZE8bZov*g-bePOlqI`6E8;Ure<;Eq_H#cC4HR{L`;vBX}e|!mb329#NdisN& z0ZhHmE48Z2myAb%jia&0GQ<)8SOyOKUdokmF$_Mqfj0qf7e0|#$8g6aKmj$(L14oT z5J822-hcw&0D*_g5ulhr2-2f$B>;gpTdHe|l>{F4eqyY#);3HPwA3_s4~K5-%BtIW zap^b6K0G|j@|U0C-QxTL;ndh!Zb=Y(abCkZ#!4EK8yUH5v95t~FZWqjB1gk^obpkd zk)b}NW2?_gk{dT2pXXH?YffOAxjPT;4LEj?hea}DrB7}a#0f*$Qf%Lfy&cCGssJ~L ziIt(u*%U#ftFL6Mj#H5;k_H|3*;4V@7fVt(;I4-LTYrZD}` z6`(rTC+wvN?7@c)-vFRJ#2mkyPIwjY3zGCWJd;@h%-ic~ij_Y#59V7VtK(+p3Q%fJ zg8fThlF~7``uA^k=h$a;RQsnT8mX>*b*jRajgBm{b8Q@HmN^PEB3Q4-od1 z<#vOm!*8e&?xsyu(tRFlm8&;Wq?ES6N$(Wn7Ft@2j!N3@e9dFTvt+9*`_1}=s!%9n zf7PxOvI>#a?~}7rYb=Da%8V_HvRd;!t`M>g6=S`^0hc}O6B*(M zWCaU=g8Xg-B>1I=t!D0K0l>fuAT)S{k0L+`JopkHj22L9n0XYx8rJJ zHBW8JRqWM2xz4W6d2BRw-}`9-v^T=mIcLE%f|&8AGhexWqnqCGR_+u*d4s`N;8|{v z%%`oHNM9DPq?c^+lR0f$m#Y10jB3m!R6A%>0lp?zvZ^>U^GMvj6Y>J&UMWN`#M@m) zO0ACch79_CT$iCfgEXY9zkte!xK1>^iYqgm2T+~mRr!{9tNiF|d0JahZj@B}S;oII z!4H>hV8G8f@L)@pdnCiKL#*&V0O@%uU=c6`C=1d*T#Vpu$`az#hv!wqlbkoLO6de*RV(`JN7r zbGpa7iIVTb(Iiz|&8RSh3By)HhPUX2@Mdj|vB?njne#|NeM7fa`cj-PDpGEZm#@dD zI8&=U4sUH*>bJGpv&AiE&<;P<)P|=L+Sgl+=NKPlqkLtp3ZG!TQJJQ1#V~!e%Y1FN z{X%z*&1gFi|F86CYXD>i@j)&aXkK?vuHkQha!f#2dQ~iJWL~) zdk7?cBjU>!7=c^BD%|Qdp*3)7tOl6)gz92t3Yt0i!R;AnLs!DwZjA!Jc0y#0wVA(q zj6Cd;gc|?8pb5Vdr@0f_w&+|%T$HD%nsL?p>?;}=8NxKrx=eb;goUi>ViD3BXr(G- zOWz$rW*WEY#IyC=Ls(RtEAd3Y} zamy&E4=~uA2WIzf0F{Rr*u|71!9K^hq305dy>~!9vEH~h3OpvHlcgsHc^h2rd91Ex zazp)f|8x(84-xakUgeza8t2ocOD z@*;!!KWq*Zp%!M<-bwy?V&)~c8hu&wdVOq*^YPVXlEsU1C#?-$F-;3dZ z$2J0xfHZ=chxp;E0jR*J^SuBtcnqvHxMbpE2|%)My?=hkZb)1yKmq|3$SSsXxJ>%b zeIY#tpAXorD5xt-5HE~QCO_MZ*XXwYF%^B|dfNE5tHfIEne?L{#9JP5v;`PGO;0M9day}7~nGN=v8v;FW9*ALvce!v8p z^VcF)VfKqZn_xfR3^ad2Ynf&AvkzB+a0}9Z$*5V9Tr(lt82!h*y>U_N3Qktonj>Mx7XMIeJ(KKma12?E$Wm!36Ab${nvk zNbtc}E02@|sE4({n*gBk#S9!+2XO!40>&Ryhf3xfP1m-#Fn>o)84$5OPq%_jBw3{pi_~zgK;ieBHwng zJE}t$_UonxcmF+f3+8JpY&nq zA$|B(X7dP^{s&*oI0F=q5qR(k2e5$ffC5IJzf}MPkROtWdnE8@@H(CbzZ&sJ3or>V z0U*HVKLjE@Idcnq(tpYtHLvvT2*GX<)zK9`y4N;5-JrY(v;)?cDgmV4rQZvKQd@Lx!ha6yoVt@nrlmyPIQ9)5Lv>; e{1NROci8Z$hKLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000bZNklQYg7gjOQ=)@Pzzfq>!xxN$(AKTvPDv|#HT1emt4M< zkA2VVJo{%x9<7!V6+8W<3mh!4_ulWEd(OG%d~*rQvar@TG4x{qAZ?)mFt(8P5)*(9 zK(l{MTP)ZcZZ`-36aW^02LNX)AOILPaKRSUrNp9b>l~0$zcc`5X+idFti1P;>Z;nm z&~>e#6tY(*=6ZfBh)fPZ4nW>MQNdPV&@LddNE~nq0K2lFh{!K)YiO)}3IvM)DiI3p z`}x9R{8()M%cEkDU3R(40$@?kytvH)c8<=ugtdiUT2TDMSLSQ`FOT|XW@agmPiH*5 z?iU3A1AcGK0}JzsK9bgRBt;muyG#e1vi->e5CHfA_*@DYRW>=lAhqszc*|bX)XlS} z1{V7+O)B9CEzqo4&2!~DCMIH^iV`c^;0E=~i`z&$KpX&nW)&M7Y9D&JvF`qVVo}}@ zn;skDc*1HQcluHo%+qtN=<|ekW3*&TY;*TmDMkNentkM zJK!t;eqknG*&KQBwW@0INgZjH_i|fI&F5QMnZ2UOy3zI9NqT%_A+)@-!f}B#7YK2Z z*Xzx6pP5Qk)|nDb6LqoCY*(;?ohKQyh*TbylDiHKlxGLprYpB$d?yKQ^SMf2~{@uK*(d<`(VZDBaerNYwGx} zb-N7+HQgaBjIY!qfbKb8KUk$+(mEURQFhDr@wV1_N^Vzu=|4uDEM^Wrw=5)lkb znaSmX6&pQ zzRP;ZpP2@+GoLmT6UI2hkaAJ+GK#@10N}io$*^Q0pVPB5V|jITQK>DfHG-;0M_?fj^0$yExTNzuF;HjoHf_`Ht7$Me_lAkVSZrxJ;CCva{9$H^Kp0+k#sc)tOZ`Iz^bhmQoO*7`K4rfd^i4c{HF9NjVsTbJV;UAE2HC}yw$NXv?+PaJ9eUQ@UNcZtzkd>l(zZc+1xv zx3%0wJ-&Hx7xi#U$*j5w{5GV>asiSq3gT`uhD%D`(6vaB8dmYLW3ljRTI zSMiTxpz&J`g{@1mnaO{hUhM7kOKj4063h9$Eh(Cq8XffdC=CEEo?Wc*i=ICNoe9z& zRSbxM-8@tMt!ty#&iVsvq3E_+wTf>047rf@g=!2h z%bA<_SKdp=vba_-dB)s^K8Ju{JoyX>x)6wOQJ zLE6qF3xFElBosC@2qS&n%KJ*r;>4hQIntzQuFHf!loT-lC^5*Y98b>&f}Zi(O~PDV zqnHhZJevE<;<}G~e#SI(t1v&4GZyFa;mQqEwMob%&vOl$!gvf*n}taTmccfg2I1vJ zG9PIcb6f5UrSEA8IKXDH<#$GkIPzzPL3}rtHdNEpCm5DeT%U_ZDeyZcMIH~kGnXQu z$l8~@KzSnYe-PFP?66;PFmz!EJ&ijh}pYw+0 z@DkjKg7r{~g8hx@d=9QVuw>B#nJ=@7jp5)!|IpU_uTEmYIR91w@*WtAfvYgcLGX}4JK>LD!4~wZ3U{9 zhperjswU7u>Sa4KDU~mJQ(QOr4b-Bb=HZBDuCg$x?g!Vr`@IET6TC#De!NMS~%c$sl{Dtv3_dt|I+=5q8Ex{E36XpDDi@E z!`eTpTnmFTtCUi(Q^Rn>fV zcX#(kAAJ;0CX-xCOG{7`#rxaa+ao7Wo;=~yqmGV_uh65>C_6DR@i&%hXquM$nd!ud6Tk26?VU4ClW1ycdi;$y-uU6v)KupOAAHaU01XWduh!Ss z*WBcmwzjtBC!ToXd5WSa_XNjrl^n-?IWRCVIyg9(?C$Q)T)K2g-@0{cMR|F7c=P7X z+L0qie&62S{ycWK!=Q}z&40k}u^XJcBE7qzgioU$OTn!)z;CBFiIWsf! z%L4}ve5z@h8Hq$5Z)|K#_w@Ai0YGJC<@W(d#o4lW`0(LltE;P;d*a=9-~IID$&>wd zon8dc58&gesj2_y>+74ND2m#%XU~q_-rg<%2m}I+07Av!3jn%~9Xoc`J+Wuc9vZ-; z4eqeAB>T3G|k|7Ua({IRpE(7qX19|;0I4X{q(DQ_wL>3O!oKp z|MffXymP=s{GGLr0%!*?0ALQl9=ja>`p}_6eeQt5CiU6={(f!i)~!22p%4QA!C-J# zYinzwtE=m>tIKEr5&%X3Tm=xbn@1mjSVu=kq1bZRysu4?q`%z1fB#Ry;qdjVok%2p zJvljfbo=)0{|Nx8RO;aV{ri6bK)F?IaV&Qla#~T8^u>!8+1A$9Eutt=0O0fawuQst z9}@)OAqc|b^?DzC?6Jpwz;QjaCAC+bKrj~X5`0>x}Se34dE}s{Vf}Iud>FMc(uC6Y4Jf5mZB;t`}*?RB2 z_xjG9IrDD-dI6+wsD>r7Wv#*3xxEd*p8)tafGmK|0Gzf{Q7z?`_3#!Az^v`65danT jt&Ia%cItSk@qYsVH7fR%Wg``I00000NkvXXu0mjf 1 && ( !/(class="?phone"?|id="?#phone|class="?asterisk_placeCall"?)/.test($(this).html()) || /EDV.show_edit/.test($(this).html()) ) ) - { - var contactId = $('input[name="record"]', document.forms['DetailView']).attr('value'); - if (!contactId) - { - contactId = $('input[name="mass[]"]', $(this).parents('tr:first')).attr('value'); - } - - if( window.callinize_user_extension ) { - $(this).append('   '); - } - else { - $(this).append('   '); - } - - $('.asterisk_placeCall', this).click(function() - { - var call = $.get('index.php?entryPoint=AsteriskCallCreate', - {phoneNr : phoneNr, contactId: contactId}, - function(data){ - console.log("CreateCall Action Response: " + data); - if( data.indexOf('Error') != -1 || data.indexOf("ERROR") != -1 ) { - alert("Click to Dial Failed:\n\n------------\n" + data + "\n------------\n"); // Shows error message on ClickToDial failure. - } - call = null; - }); - - // Wait for 5 seconds - setTimeout(function() - { - // If the request is still running, abort it. - if ( call ) - { - call.abort(); - }; - }, 20000); - }); - } - }); + if (phoneNr.length > 1 && ( !/(class="?phone"?|id="?#phone|class="?asterisk_placeCall"?)/.test($(this).html()) || /EDV.show_edit/.test($(this).html()) )) { + var contactId = $('input[name="record"]', document.forms['DetailView']).attr('value'); + if (!contactId) { + contactId = $('input[name="mass[]"]', $(this).parents('tr:first')).attr('value'); + } + + if (window.callinize_user_extension) { + $(this).append('
'); + } + else { + $(this).append('   '); + } + + $('.asterisk_placeCall', this).click(function () { + + var record = $(this).attr('record'); + //change to spinner + $("div").find("[record='" + record + "']").removeClass('activeCall').addClass('dialedCall'); + + + + var call = $.get('index.php?entryPoint=AsteriskCallCreate', + {phoneNr: phoneNr, contactId: contactId, module:getModule()}, + function (data) { + console.log("CreateCall Action Response: " + data); + if (data.indexOf('Error') != -1 || data.indexOf("ERROR") != -1) { + alert("Click to Dial Failed:\n\n------------\n" + data + "\n------------\n"); // Shows error message on ClickToDial failure. + } + call = null; + }); + + //remove spinner + setTimeout(function () { + $("div").find("[record='" + record + "']").removeClass('dialedCall').addClass('activeCall'); + }, 5000); + + // Wait for 5 seconds + setTimeout(function () { + // If the request is still running, abort it. + if (call) { + call.abort(); + } + ; + + + }, 20000); + }); + } + + function getModule(){ + if(window.module_sugar_grp1 == undefined){ + return getUrlParam('module'); + }else{ + return window.module_sugar_grp1; + } + } + + //internal function to assist in getting sugarcrm url parameters + function getUrlParam(name) { + + var decodedUri = decodeURIComponent(window.location.href); + var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(decodedUri); + if (!results) { + return null; + } else { + return results[1]; + } + } + }); }); \ No newline at end of file diff --git a/SugarModules/modules/Asterisk/include/template/call-template.tmpl b/SugarModules/modules/Asterisk/include/template/call-template.tmpl index 293e039..492816d 100644 --- a/SugarModules/modules/Asterisk/include/template/call-template.tmpl +++ b/SugarModules/modules/Asterisk/include/template/call-template.tmpl @@ -1,8 +1,8 @@ (function() { var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; templates['call-template.html'] = template(function (Handlebars,depth0,helpers,partials,data) { - this.compilerInfo = [3,'>= 1.0.0-rc.4']; -helpers = helpers || Handlebars.helpers; data = data || {}; + this.compilerInfo = [4,'>= 1.0.0']; +helpers = this.merge(helpers, Handlebars.helpers); data = data || {}; var buffer = "", stack1, functionType="function", escapeExpression=this.escapeExpression, self=this; function program1(depth0,data) { diff --git a/SugarModules/modules/Asterisk/language/en_us.lang.php b/SugarModules/modules/Asterisk/language/en_us.lang.php index 146adea..c238249 100644 --- a/SugarModules/modules/Asterisk/language/en_us.lang.php +++ b/SugarModules/modules/Asterisk/language/en_us.lang.php @@ -79,6 +79,7 @@ 'BLOCK' => 'Block', 'SAVE' => 'Save Memo', 'ASTERISKLBL_USER_EXT' => 'User Ext', + 'ASTERISKLBL_USER_EXT' => 'User Ext', 'ASTERISKLBL_INBOUND_EXT' => 'Inbound Ext', 'RELATE_TO_CONTACT' => 'Relate to Contact', 'RELATE_TO_LEAD' => 'Relate to Lead', diff --git a/SugarModules/modules/Configurator/asterisk_config_meta.php b/SugarModules/modules/Configurator/asterisk_config_meta.php index a083536..04217e7 100644 --- a/SugarModules/modules/Configurator/asterisk_config_meta.php +++ b/SugarModules/modules/Configurator/asterisk_config_meta.php @@ -31,6 +31,7 @@ //$config_meta['asterisk_gravatar_enabled'] = array('default' => 'false','section'=>'Misc') ; $config_meta['asterisk_short_call_status'] = array('default' => "Held",'section'=>'Misc'); $config_meta['asterisk_hide_call_popups_after_mins'] = array('default' => '60','section'=>'Misc'); +$config_meta['jquery_override'] = array('type'=>"bool", 'default' => '0', 'section'=>'Misc'); $config_meta['asterisk_log_file'] = array('default' => '', 'section'=>'Logging'); $config_meta['asterisk_event_log_file'] = array('default' => '', 'section'=>'Logging'); diff --git a/SugarModules/modules/Configurator/asterisk_configurator.tpl b/SugarModules/modules/Configurator/asterisk_configurator.tpl index a5b9e74..a7f99bc 100644 --- a/SugarModules/modules/Configurator/asterisk_configurator.tpl +++ b/SugarModules/modules/Configurator/asterisk_configurator.tpl @@ -37,69 +37,11 @@

Callinize Logo
-Config Logo
- - - - - - - - - - - -
  -
-
-
-

Upgrade Today

-

Upgrade from the community edition and get awesome features like:

-

    -
  • Mobile App - Log/Create/Track from Anywhere!
  • -
  • Support for Leads and custom phone fields.
  • -
  • Call Recording / Playback in Sugar
  • -
  • Operator Panel - Web switchboard for Asterisk
  • -
  • Customer Support
  • -
-       -
-
-
- -
  - - -
- @@ -167,20 +109,7 @@
Callinize has automatically logged: {$callsLogged} calls for you!
- - - + {literal} diff --git a/SugarModules/modules/Configurator/asterisk_configurator_table.tpl b/SugarModules/modules/Configurator/asterisk_configurator_table.tpl index 1db7e31..9fccd82 100644 --- a/SugarModules/modules/Configurator/asterisk_configurator_table.tpl +++ b/SugarModules/modules/Configurator/asterisk_configurator_table.tpl @@ -371,6 +371,41 @@ + + + {$MOD.LBL_JQUERY_OVERRIDE} + {if !empty($MOD.LBL_JQUERY_OVERRIDE_DESC)} + [?]: + {/if} + + + + {if empty($config.jquery_override)} + {assign var='jquery_override' value=$asterisk_config.jquery_override} + {if $asterisk_config.jquery_override == '1' } + {assign var='isCheckedjquery_override' value='checked'} + {assign var="caseNumjquery_override" value="Case1a: Config not set, default value = 1"} + {else} + {assign var='isCheckedjquery_override' value=''} + {assign var="caseNumjquery_override" value="CASE1b: Config not set, using default value = 0"} + {/if} + {else} + {assign var='jquery_override' value=$config.jquery_override} + {if $config.jquery_override == '1' } + {assign var='isCheckedjquery_override' value='checked'} + {assign var="caseNumjquery_override" value="CASE2a: Config is set, value = 1"} + {else} + {assign var='isCheckedjquery_override' value=''} + {assign var="caseNumjquery_override" value="CASE2b: Config is set, value = 0"} + {/if} + {/if} + + + + + +   +   

Logging

@@ -417,19 +452,29 @@ {/if} - {if empty($config.asterisk_block_button_enabled )} + + {if empty($config.asterisk_block_button_enabled)} {assign var='asterisk_block_button_enabled' value=$asterisk_config.asterisk_block_button_enabled} - {if $asterisk_config.asterisk_block_button_enabled } - {assign var='isChecked' value='checked'} + {if $asterisk_config.asterisk_block_button_enabled == '1' } + {assign var='isCheckedasterisk_block_button_enabled' value='checked'} + {assign var="caseNumasterisk_block_button_enabled" value="Case1a: Config not set, default value = 1"} + {else} + {assign var='isCheckedasterisk_block_button_enabled' value=''} + {assign var="caseNumasterisk_block_button_enabled" value="CASE1b: Config not set, using default value = 0"} {/if} {else} {assign var='asterisk_block_button_enabled' value=$config.asterisk_block_button_enabled} - {if $config.asterisk_block_button_enabled } - {assign var='isChecked' value='checked'} + {if $config.asterisk_block_button_enabled == '1' } + {assign var='isCheckedasterisk_block_button_enabled' value='checked'} + {assign var="caseNumasterisk_block_button_enabled" value="CASE2a: Config is set, value = 1"} + {else} + {assign var='isCheckedasterisk_block_button_enabled' value=''} + {assign var="caseNumasterisk_block_button_enabled" value="CASE2b: Config is set, value = 0"} {/if} {/if} - + + {$MOD.LBL_ASTERISK_TRANSFER_BUTTON_ENABLED} @@ -438,19 +483,29 @@ {/if} - {if empty($config.asterisk_transfer_button_enabled )} + + {if empty($config.asterisk_transfer_button_enabled)} {assign var='asterisk_transfer_button_enabled' value=$asterisk_config.asterisk_transfer_button_enabled} - {if $asterisk_config.asterisk_transfer_button_enabled } - {assign var='isChecked' value='checked'} + {if $asterisk_config.asterisk_transfer_button_enabled == '1' } + {assign var='isCheckedasterisk_transfer_button_enabled' value='checked'} + {assign var="caseNumasterisk_transfer_button_enabled" value="Case1a: Config not set, default value = 1"} + {else} + {assign var='isCheckedasterisk_transfer_button_enabled' value=''} + {assign var="caseNumasterisk_transfer_button_enabled" value="CASE1b: Config not set, using default value = 0"} {/if} {else} {assign var='asterisk_transfer_button_enabled' value=$config.asterisk_transfer_button_enabled} - {if $config.asterisk_transfer_button_enabled } - {assign var='isChecked' value='checked'} + {if $config.asterisk_transfer_button_enabled == '1' } + {assign var='isCheckedasterisk_transfer_button_enabled' value='checked'} + {assign var="caseNumasterisk_transfer_button_enabled" value="CASE2a: Config is set, value = 1"} + {else} + {assign var='isCheckedasterisk_transfer_button_enabled' value=''} + {assign var="caseNumasterisk_transfer_button_enabled" value="CASE2b: Config is set, value = 0"} {/if} {/if} - + + @@ -463,19 +518,29 @@ {/if} - {if empty($config.asterisk_relate_to_account_enabled )} + + {if empty($config.asterisk_relate_to_account_enabled)} {assign var='asterisk_relate_to_account_enabled' value=$asterisk_config.asterisk_relate_to_account_enabled} - {if $asterisk_config.asterisk_relate_to_account_enabled } - {assign var='isChecked' value='checked'} + {if $asterisk_config.asterisk_relate_to_account_enabled == '1' } + {assign var='isCheckedasterisk_relate_to_account_enabled' value='checked'} + {assign var="caseNumasterisk_relate_to_account_enabled" value="Case1a: Config not set, default value = 1"} + {else} + {assign var='isCheckedasterisk_relate_to_account_enabled' value=''} + {assign var="caseNumasterisk_relate_to_account_enabled" value="CASE1b: Config not set, using default value = 0"} {/if} {else} {assign var='asterisk_relate_to_account_enabled' value=$config.asterisk_relate_to_account_enabled} - {if $config.asterisk_relate_to_account_enabled } - {assign var='isChecked' value='checked'} + {if $config.asterisk_relate_to_account_enabled == '1' } + {assign var='isCheckedasterisk_relate_to_account_enabled' value='checked'} + {assign var="caseNumasterisk_relate_to_account_enabled" value="CASE2a: Config is set, value = 1"} + {else} + {assign var='isCheckedasterisk_relate_to_account_enabled' value=''} + {assign var="caseNumasterisk_relate_to_account_enabled" value="CASE2b: Config is set, value = 0"} {/if} {/if} - + + {$MOD.LBL_ASTERISK_RELATE_TO_CONTACT_ENABLED} @@ -484,19 +549,29 @@ {/if} - {if empty($config.asterisk_relate_to_contact_enabled )} + + {if empty($config.asterisk_relate_to_contact_enabled)} {assign var='asterisk_relate_to_contact_enabled' value=$asterisk_config.asterisk_relate_to_contact_enabled} - {if $asterisk_config.asterisk_relate_to_contact_enabled } - {assign var='isChecked' value='checked'} + {if $asterisk_config.asterisk_relate_to_contact_enabled == '1' } + {assign var='isCheckedasterisk_relate_to_contact_enabled' value='checked'} + {assign var="caseNumasterisk_relate_to_contact_enabled" value="Case1a: Config not set, default value = 1"} + {else} + {assign var='isCheckedasterisk_relate_to_contact_enabled' value=''} + {assign var="caseNumasterisk_relate_to_contact_enabled" value="CASE1b: Config not set, using default value = 0"} {/if} {else} {assign var='asterisk_relate_to_contact_enabled' value=$config.asterisk_relate_to_contact_enabled} - {if $config.asterisk_relate_to_contact_enabled } - {assign var='isChecked' value='checked'} + {if $config.asterisk_relate_to_contact_enabled == '1' } + {assign var='isCheckedasterisk_relate_to_contact_enabled' value='checked'} + {assign var="caseNumasterisk_relate_to_contact_enabled" value="CASE2a: Config is set, value = 1"} + {else} + {assign var='isCheckedasterisk_relate_to_contact_enabled' value=''} + {assign var="caseNumasterisk_relate_to_contact_enabled" value="CASE2b: Config is set, value = 0"} {/if} {/if} - + + @@ -509,19 +584,29 @@ {/if} - {if empty($config.asterisk_create_new_contact_enabled )} + + {if empty($config.asterisk_create_new_contact_enabled)} {assign var='asterisk_create_new_contact_enabled' value=$asterisk_config.asterisk_create_new_contact_enabled} - {if $asterisk_config.asterisk_create_new_contact_enabled } - {assign var='isChecked' value='checked'} + {if $asterisk_config.asterisk_create_new_contact_enabled == '1' } + {assign var='isCheckedasterisk_create_new_contact_enabled' value='checked'} + {assign var="caseNumasterisk_create_new_contact_enabled" value="Case1a: Config not set, default value = 1"} + {else} + {assign var='isCheckedasterisk_create_new_contact_enabled' value=''} + {assign var="caseNumasterisk_create_new_contact_enabled" value="CASE1b: Config not set, using default value = 0"} {/if} {else} {assign var='asterisk_create_new_contact_enabled' value=$config.asterisk_create_new_contact_enabled} - {if $config.asterisk_create_new_contact_enabled } - {assign var='isChecked' value='checked'} + {if $config.asterisk_create_new_contact_enabled == '1' } + {assign var='isCheckedasterisk_create_new_contact_enabled' value='checked'} + {assign var="caseNumasterisk_create_new_contact_enabled" value="CASE2a: Config is set, value = 1"} + {else} + {assign var='isCheckedasterisk_create_new_contact_enabled' value=''} + {assign var="caseNumasterisk_create_new_contact_enabled" value="CASE2b: Config is set, value = 0"} {/if} {/if} - + +    @@ -572,19 +657,29 @@ {/if} - {if empty($config.asterisk_callinize_dev )} + + {if empty($config.asterisk_callinize_dev)} {assign var='asterisk_callinize_dev' value=$asterisk_config.asterisk_callinize_dev} - {if $asterisk_config.asterisk_callinize_dev } - {assign var='isChecked' value='checked'} + {if $asterisk_config.asterisk_callinize_dev == '1' } + {assign var='isCheckedasterisk_callinize_dev' value='checked'} + {assign var="caseNumasterisk_callinize_dev" value="Case1a: Config not set, default value = 1"} + {else} + {assign var='isCheckedasterisk_callinize_dev' value=''} + {assign var="caseNumasterisk_callinize_dev" value="CASE1b: Config not set, using default value = 0"} {/if} {else} {assign var='asterisk_callinize_dev' value=$config.asterisk_callinize_dev} - {if $config.asterisk_callinize_dev } - {assign var='isChecked' value='checked'} + {if $config.asterisk_callinize_dev == '1' } + {assign var='isCheckedasterisk_callinize_dev' value='checked'} + {assign var="caseNumasterisk_callinize_dev" value="CASE2a: Config is set, value = 1"} + {else} + {assign var='isCheckedasterisk_callinize_dev' value=''} + {assign var="caseNumasterisk_callinize_dev" value="CASE2b: Config is set, value = 0"} {/if} {/if} - + + {$MOD.LBL_ASTERISK_CALLINIZE_DEBUG} @@ -593,18 +688,28 @@ {/if} - {if empty($config.asterisk_callinize_debug )} + + {if empty($config.asterisk_callinize_debug)} {assign var='asterisk_callinize_debug' value=$asterisk_config.asterisk_callinize_debug} - {if $asterisk_config.asterisk_callinize_debug } - {assign var='isChecked' value='checked'} + {if $asterisk_config.asterisk_callinize_debug == '1' } + {assign var='isCheckedasterisk_callinize_debug' value='checked'} + {assign var="caseNumasterisk_callinize_debug" value="Case1a: Config not set, default value = 1"} + {else} + {assign var='isCheckedasterisk_callinize_debug' value=''} + {assign var="caseNumasterisk_callinize_debug" value="CASE1b: Config not set, using default value = 0"} {/if} {else} {assign var='asterisk_callinize_debug' value=$config.asterisk_callinize_debug} - {if $config.asterisk_callinize_debug } - {assign var='isChecked' value='checked'} + {if $config.asterisk_callinize_debug == '1' } + {assign var='isCheckedasterisk_callinize_debug' value='checked'} + {assign var="caseNumasterisk_callinize_debug" value="CASE2a: Config is set, value = 1"} + {else} + {assign var='isCheckedasterisk_callinize_debug' value=''} + {assign var="caseNumasterisk_callinize_debug" value="CASE2b: Config is set, value = 0"} {/if} {/if} - + + diff --git a/SugarModules/modules/Configurator/configuratorGeneratorUtil.php b/SugarModules/modules/Configurator/configuratorGeneratorUtil.php index 18ad821..8565f72 100644 --- a/SugarModules/modules/Configurator/configuratorGeneratorUtil.php +++ b/SugarModules/modules/Configurator/configuratorGeneratorUtil.php @@ -42,19 +42,29 @@ {/if} - {if empty($config.@@NORMAL@@ )} + + {if empty($config.@@NORMAL@@)} {assign var='@@NORMAL@@' value=$asterisk_config.@@NORMAL@@} - {if $asterisk_config.@@NORMAL@@ } - {assign var='isChecked' value='checked'} + {if $asterisk_config.@@NORMAL@@ == '1' } + {assign var='isChecked@@NORMAL@@' value='checked'} + {assign var="caseNum@@NORMAL@@" value="Case1a: Config not set, default value = 1"} + {else} + {assign var='isChecked@@NORMAL@@' value=''} + {assign var="caseNum@@NORMAL@@" value="CASE1b: Config not set, using default value = 0"} {/if} {else} {assign var='@@NORMAL@@' value=$config.@@NORMAL@@} - {if $config.@@NORMAL@@ } - {assign var='isChecked' value='checked'} + {if $config.@@NORMAL@@ == '1' } + {assign var='isChecked@@NORMAL@@' value='checked'} + {assign var="caseNum@@NORMAL@@" value="CASE2a: Config is set, value = 1"} + {else} + {assign var='isChecked@@NORMAL@@' value=''} + {assign var="caseNum@@NORMAL@@" value="CASE2b: Config is set, value = 0"} {/if} {/if} - + + END2; @@ -86,7 +96,6 @@ if( $value['type'] == "bool") { $type = "checkbox"; // checkbox is too hard to support since it's value isn't submitted when form is posted and it's unchecked! $in = $columnSmartyBool; - } else { $type = $value['type']; @@ -94,8 +103,8 @@ } $out = str_replace( - array('@@UPPER@@','@@NORMAL@@','@@TYPE@@','@@CHECKED@@'), - array(strtoupper($key),$key,$type,$checked), + array('@@UPPER@@','@@NORMAL@@','@@TYPE@@'), + array(strtoupper($key),$key,$type), $in); print $out . "\n\n"; diff --git a/SugarModules/modules/Configurator/language/en_us.lang.php b/SugarModules/modules/Configurator/language/en_us.lang.php index 7592fdf..ff739e2 100644 --- a/SugarModules/modules/Configurator/language/en_us.lang.php +++ b/SugarModules/modules/Configurator/language/en_us.lang.php @@ -91,6 +91,8 @@ $mod_strings['LBL_ASTERISK_HIDE_CALL_POPUPS_AFTER_MINS_DESC'] = 'Specifies how long the user has to take notes in call popups before they disappear. Default is 60 minutes.'; $mod_strings['LBL_ASTERISK_DIGITS_TO_MATCH'] = 'Digits to Match'; $mod_strings['LBL_ASTERISK_DIGITS_TO_MATCH_DESC'] = 'Specifies the number of digits to match in a phone number. For example, if only 8 is specified just the last 8 digits are matched. This can be helpful if you have local numbers come in with less digits then international or long distance numbers. Setting this number too low you run the risk of matching multiple contacts for the same phone number.'; +$mod_strings['LBL_ASTERISK_LOGGER_SQL_MODE'] = 'SQL Performance Mode (Experimental)'; +$mod_strings['LBL_ASTERISK_LOGGER_SQL_MODE_DESC'] = 'When checked, the logger script will do direct SQL queries to the Calls module instead of making SOAP calls whenever possible. The performance of this mode is better and should be used on very active asterisk installations to prevent popup delay. The downside of this mode is if you use any workflow rules that get triggered on the Calls object they will not be fired.'; $mod_strings['LBL_ASTERISK_LOG_FILE'] = 'Log File Path for asteriskLogger'; @@ -137,5 +139,11 @@ $mod_strings['LBL_ASTERISK_CALLINIZE_DEBUG'] = "Debug Mode Enabled"; $mod_strings['LBL_ASTERISK_CALLINIZE_DEBUG_DESC'] = "Provides debug information about call popups in the Console.log (should be 0 in production)."; +$mod_strings['LBL_ASTERISK_CALLINIZE_DEBUG'] = "Debug Mode Enabled"; +$mod_strings['LBL_ASTERISK_CALLINIZE_DEBUG_DESC'] = "Provides debug information about call popups in the Console.log (should be 0 in production)."; + +$mod_strings['LBL_JQUERY_OVERRIDE'] = "Jquery Override"; +$mod_strings['LBL_JQUERY_OVERRIDE_DESC'] = "If you have conflicts with multiple jquery libraries being loaded, set this override"; + ?> \ No newline at end of file diff --git a/SugarModules/modules/Users/language/en_us.lang.php b/SugarModules/modules/Users/language/en_us.lang.php index 48e2091..7b80c89 100644 --- a/SugarModules/modules/Users/language/en_us.lang.php +++ b/SugarModules/modules/Users/language/en_us.lang.php @@ -37,7 +37,8 @@ if (!isset($mod_strings)) { $mod_strings = array(); } $mod_strings['LBL_ASTERISK_OPTIONS_TITLE'] = 'Asterisk options'; -$mod_strings['LBL_ASTERISK_EXT'] = 'Asterisk Extension'; +$mod_strings['LBL_ASTERISK_EXT'] = 'Personal Extension(s)'; +$mod_strings['LBL_ASTERISK_USER_QUEUES'] = 'Queues/RG\'s (comma separated no spaces)'; $mod_strings['LBL_ASTERISK_EXT_DESC'] = 'Asterisk extension assigned to this user (usually a two or three digit number)'; $mod_strings['LBL_ASTERISK_INBOUND'] = 'Call notification'; $mod_strings['LBL_ASTERISK_OUTBOUND'] = 'Magic dial buttons'; diff --git a/TODO.txt b/TODO.txt index f1a6da9..3d31ee4 100644 --- a/TODO.txt +++ b/TODO.txt @@ -55,16 +55,12 @@ Versions Developed with: * Better handling for answering on mobile phone. (currently a chat box still appears). * Would be cool if it could give you voicemail also. -* Ability to record the call? -* Have Button to create a new contact when number isn't recognized. ==[ Configuration Changes Needed]=== -Add gravatar one, Add opencnam enabled / apikey -$rgDetectRegex = "/^Local\/RG/i"; // TODO make this a configuration option $rgCellRingRegex = "/^Local\/\d{7,10}/i";// TODO make this a configuration option.... This detects in a RG when an outside line is called (usually for a cellphone)... for some reason the cell shows up as the Channel (aka the source)... We detect this by finding a number thats at least 7-10 characters long.. Add option to save short calls (ie inbound calls that weren't answered) as failed (which shows up in activities) or Held. * Need configurable Channel detection in order to assign calls to users when they answer on cell phones. diff --git a/manifest.php b/manifest.php index fd664ad..2245fe3 100644 --- a/manifest.php +++ b/manifest.php @@ -45,7 +45,7 @@ 'regex_matches' => array ( 1 => '6\.4\.\d', - 2 => '6\.[0-6]\.\d', /** matches 6.1.x,6.2.x,6.3.x,6.4.x,6.5.x,6.6.x **/ + 2 => '6\.[0-7]\.\d', /** matches 6.1.x,6.2.x,6.3.x,6.4.x,6.5.x,6.6.x **/ ), ), 'acceptable_sugar_flavors' => @@ -61,9 +61,9 @@ 'icon' => '', 'is_uninstallable' => true, 'name' => 'Callinize - community Edition', - 'published_date' => 'Jul 26, 2013', + 'published_date' => 'Sep 19, 2013', 'type' => 'module', - 'version' => '3.5.6b', + 'version' => '3.6.6', 'remove_tables' => 'true', /** This does absolutely nothing since our asterisk log table is created manually instead of as a bean **/ ); @@ -363,95 +363,28 @@ 'ext4' => NULL, ), array ( - 'id' => 'Usersfop_user', - 'name' => 'asterisk_fop_user_c', - 'label' => 'LBL_ASTERISK_FOP_USER', + 'id' => 'Callsasterisk_call_id_c', + 'name' => 'asterisk_call_id_c', + 'label' => 'LBL_ASTERISK_CALL_ID', 'comments' => NULL, - 'help' => NULL, - 'module' => 'Users', + 'help' => 'This is the unique id assigned to this call by the PBX, Useful for debugging but otherwise no reason to display to an end user.', + 'module' => 'Calls', 'type' => 'varchar', - 'max_size' => '20', + 'max_size' => '45', 'require_option' => '0', 'default_value' => NULL, - 'date_modified' => '2009-05-22 00:00:00', + 'date_modified' => '2009-06-18 15:38:48', 'deleted' => '0', 'audited' => '0', 'mass_update' => '0', 'duplicate_merge' => '0', - 'reportable' => '1', + 'reportable' => '0', + 'importable' => 'true', 'ext1' => NULL, 'ext2' => NULL, 'ext3' => NULL, 'ext4' => NULL, ), - array ( - 'id' => 'Usersfop_pass', - 'name' => 'asterisk_fop_pass_c', - 'label' => 'LBL_ASTERISK_FOP_PASS', - 'comments' => NULL, - 'help' => NULL, - 'module' => 'Users', - 'type' => 'varchar', - 'max_size' => '20', - 'require_option' => '0', - 'default_value' => NULL, - 'date_modified' => '2009-05-22 00:00:00', - 'deleted' => '0', - 'audited' => '0', - 'mass_update' => '0', - 'duplicate_merge' => '0', - 'reportable' => '1', - 'ext1' => NULL, - 'ext2' => NULL, - 'ext3' => NULL, - 'ext4' => NULL, - ), -// array ( -// 'id' => 'Callsasterisk_call_id_c', -// 'name' => 'asterisk_call_id_c', -// 'label' => 'LBL_ASTERISK_CALL_ID', -// 'comments' => NULL, -// 'help' => 'This is the unique id assigned to this call by the PBX, No reason to display this data.', -// 'module' => 'Calls', -// 'type' => 'varchar', -// 'max_size' => '45', -// 'require_option' => '0', -// 'default_value' => NULL, -// 'date_modified' => '2009-06-18 15:38:48', -// 'deleted' => '0', -// 'audited' => '0', -// 'mass_update' => '0', -// 'duplicate_merge' => '0', -// 'reportable' => '0', -// 'importable' => 'true', -// 'ext1' => NULL, -// 'ext2' => NULL, -// 'ext3' => NULL, -// 'ext4' => NULL, -// ), -// array ( -// 'id' => 'Callsasterisk_recording_buttons_c', -// 'name' => 'asterisk_recording_buttons_c', -// 'label' => 'LBL_ASTERISK_RECORDING_BUTTONS', -// 'comments' => NULL, -// 'help' => 'This is the play/download buttons for recordings', -// 'module' => 'Calls', -// 'type' => 'html', -// 'max_size' => '45', -// 'require_option' => '0', -// 'default_value' => '
hello
', -// 'date_modified' => '2009-06-18 15:38:48', -// 'deleted' => '0', -// 'audited' => '0', -// 'mass_update' => '0', -// 'duplicate_merge' => '0', -// 'reportable' => '0', -// 'importable' => 'true', -// 'ext1' => NULL, -// 'ext2' => NULL, -// 'ext3' => NULL, -// 'ext4' => NULL, -// ), array ( 'id' => 'Callsasterisk_caller_id_c', @@ -522,29 +455,29 @@ 'ext3' => NULL, 'ext4' => NULL, ), - array ( - 'id' => 'Callsasterisk_record_c', - 'name' => 'asterisk_record_c', - 'label' => 'LBL_ASTERISK_RECORD"', - 'comments' => NULL, - 'help' => 'Specifies whether or this call recording should be available in Sugar.', - 'module' => 'Calls', - 'type' => 'bool', - 'max_size' => '45', - 'require_option' => '0', - 'default_value' => 0, - 'date_modified' => '2009-06-18 15:38:48', - 'deleted' => '0', - 'audited' => '0', - 'mass_update' => '0', - 'duplicate_merge' => '0', - 'reportable' => '0', - 'importable' => 'true', - 'ext1' => NULL, - 'ext2' => NULL, - 'ext3' => NULL, - 'ext4' => NULL, - ), +// array ( +// 'id' => 'Callsasterisk_record_c', +// 'name' => 'asterisk_record_c', +// 'label' => 'LBL_ASTERISK_RECORD"', +// 'comments' => NULL, +// 'help' => 'Specifies whether or this call recording should be available in Sugar.', +// 'module' => 'Calls', +// 'type' => 'bool', +// 'max_size' => '45', +// 'require_option' => '0', +// 'default_value' => 0, +// 'date_modified' => '2009-06-18 15:38:48', +// 'deleted' => '0', +// 'audited' => '0', +// 'mass_update' => '0', +// 'duplicate_merge' => '0', +// 'reportable' => '0', +// 'importable' => 'true', +// 'ext1' => NULL, +// 'ext2' => NULL, +// 'ext3' => NULL, +// 'ext4' => NULL, +// ), ), "logic_hooks" => diff --git a/manifest_updater.php b/manifest_updater.php index 8e111d7..11e3859 100644 --- a/manifest_updater.php +++ b/manifest_updater.php @@ -3,6 +3,8 @@ /** * Simple script to update manifest version / date. + * + * NOTE: THIS IS NO LONGER USED SINCE WE MOVED TO ANT TO BUILD */ diff --git a/scripts/post_install.php b/scripts/post_install.php index ed30c82..f412a30 100644 --- a/scripts/post_install.php +++ b/scripts/post_install.php @@ -67,8 +67,8 @@ function post_install() { ?>

- -YAAI Logo
+ +Callinize Logo
Please review the documentation! There are several additional steps that must be taken.
The User Guide can be found on the Project website here: https://github.com/blak3r/yaai/wiki/User-Manual. Please note the fairly comprehensive troubleshooting section at the end of the manual.