Phonebook extensions mismatch

Hi,

first, thank you for this amazing product. We have bought the full license for unlimited buttons/extensions, and we love FOP2.

FOP2 works great, but we have a weird behavior with phonebook entries in the web frontend.
I've integrated FOP2 phonebook with the CID Superfecta module in Freepbx 12.0.54, and it works.
Extensions display the correct CID.
The FOP web frontend display also correct CID when external calls incoming, but when internal extensions call another extension, the web frontend displays the first entry in the phonebook that match the last 2 numbers of extensions.

I.E. John Smith with ext 52 is visualized as Marc Brown mobile +39 123 457852

All the phones are in the local LAN net.
The Chrome plugin works well.

Thank you for your help.

Regards

Marco

Comments

  • Edit /var/www/html/fop2/checkdir.php and look for this
    if($largo > $significant) {
        $startoffset=$largo-$significant;
    }
    

    Before that you can add another if condition, assuming your extensions are 2 digits, you can set it like this
    if($largo > 2) {
    
    if($largo > $significant) {
        $startoffset=$largo-$significant;
    }
    

    And then put the closing curly bracket just before the Header line:
    }
    Header( "X-JSON: { \"clidnum\": \"$clidnum\", \"clidname\": \"$clidname\", \"picture\": \"$picture\", \"queue\": \"$fromqueue\", \"url\": \"$url\" }");
    
    

    That should prevent callerid numbers less than 3 digits long from looking up for matches in the DB.

  • Forgot to add, you can also add your own extensions in the phonebook, so they will match instead of the other customers. If you have an entry with a phone 52 it will have precedence over 3928237352

    Best regards,
  • Hi Nikolas,
    I found this thread because I am experiencing similar issues.
    Forgot to add, you can also add your own extensions in the phonebook, so they will match instead of the other customers. If you have an entry with a phone 52 it will have precedence over 3928237352

    This does not appear to be the case. My extensions are 3 digits long. When there is an address book entry for that extension, say, 215, and there is another address book entry for someone else , say 55334215, the second (longer) entry is matched, not the shorter (more precisely matching) entry.

    Running FOP2 version 2.31.05 on FreePBX 13.0.191.11. Any thoughts?

  • Experiment with the SQL query that is used in /var/www/html/fop2/checkdir.php and see if it needs modification:

    SELECT concat(firstname,' ',lastname) AS name,company,picture FROM visual_phonebook WHERE (phone1 LIKE '%215' OR phone2 LIKE '%215') AND context='' ORDER BY LENGTH(CONCAT(phone1,phone2)) LIMIT 1

    And see what record you get.. perhaps you have a phone2 field set on your extension (short) but not on your customer, and that makes the order by clause show the customer instead of extension entry? play a bit with it and see, then you can alter checkdir.php to use the correct query.

  • I took a long time to get around to this, but I have had a play, and I think I know what is going on. I have set up a workaround, but I also think I know what is needed for a proper fix.

    THE PROBLEM
    When a user dialled from an extension (3 digits) the lookup would often incorrectly return a name and picture associated with a different address book entry. This happened when the 3 digit extension number appeared anywhere within the longer phone number. For example, calling extension 650, would select entry for user with phone number 12346501

    The issue is that the logic of this select statement did not work:
    $res = $db->consulta("SELECT concat(firstname,' ',lastname) AS name,company,picture FROM visual_phonebook WHERE (phone1 LIKE '%%%s'OR phone2 LIKE '%%%s') AND context='%s' ORDER BY LENGTH(CONCAT(phone1,phone2)) LIMIT 1",$clid_significant,$clid_significant,$context);
    
    The problem is that the LIKE statement was finding all records containing the callerid phone number ANYWHERE within it. So, when the calling extension is 650, it matched on ALL of 1236504, 1234650, 650, 16501245. The ORDER BY statement was then supposed to select the shortest match (which should have been the extension). However, because there are two phone fields, an attempt was made to identify the record with the shortest match by concatenating both numbers in the record, and comparing that length with the concatenated numbers of the other matching records.
    The LIMIT 1 statement then picked the first record.

    This does not work because there is no certainty that the total length of both phone number fields will be shorter for the correct entry.

    Consider this mini-database:
    Calling Extension is 650.
    User A Phone1: 650 Phone2: 12345678
    User B Phone1: 12650348 Phone2: nul

    Both of these records are selected by the above statement. They are then compared by adding the two phone fields, and picking the shortest COMBINED length:
    User A: 3+8=11
    User B: 8+0=8

    User B record is shorter, so it is selected. The correct record is User A.

    MY WORKAROUND
    In Australia, all phone numbers are 10 digits (including area code) – even mobile numbers.
    So, I have set the comparison to EQUALS (rather than LIKE) so that I only get one valid match. I have removed the LENGTH comparison altogether.
    $res = $db->consulta("SELECT concat(firstname,' ',lastname) AS name,company,picture FROM visual_phonebook WHERE (phone1 = '%s' OR phone2 = '%s') AND context='%s' LIMIT 1",$clid_significant,$clid_significant,$context);
    

    This works, except that if the visual phone book entry does not include the area code, or includes spaces, the record is not found.

    FIX REQUIRED
    • We need to be able to strip the spaces out of the visual phonebook phone number entries when comparing;
    • We need to be able to perform a routine on the visual phonebook phone number entries to only compare the significant digits – in the same way that the script does with the caller id number:
    $significant    = 10;
    	$startoffset    = 0;
    	if($largo > $significant) {
            $startoffset=$largo-$significant;
        }
    
        $clid_significant = substr( $decodedClidnum, $startoffset );
    

    When comparing the CLID with the visual phone book entries after stripping spaces and looking at the same significant digits, the EQUALS comparison operator will then work as desired.

    I am not sufficiently expert to figure out how to do this bit. Hopefully what I have said helps, and the proper fix will be simple for you :)
  • edited May 2019
    This is still an issue in FOP2 Version: 2.31.23.

    My above workaround still works, but it would be nice to see a fix coded into the program itself.
  • Hi,
    Part of your analysis is not correct. The query does not find the number anywhere but just the final bit. The like search has the % (wildcard) at the begining only, then the significant digits as retrieved in the callerid.
    I made a quick test with the same data you posted as an example:

    MariaDB [asterisk]> select id,phone1,phone2,firstname from visual_phonebook;
    +----+----------+----------+-----------+
    | id | phone1   | phone2   | firstname |
    +----+----------+----------+-----------+
    |  1 | 650      | 12345678 | User A    |
    |  2 | 12650348 |          | User B    |
    +----+----------+----------+-----------+
    2 rows in set (0.00 sec)
    
    

    Then I run the query to match based on callerid '650':

    MariaDB [asterisk]> SELECT id,phone1,phone2,concat(firstname,' ',lastname) AS name,company,picture FROM visual_phonebook WHERE (phone1 LIKE '%650' OR phone2 LIKE '%650') AND context='' ORDER BY LENGTH(CONCAT(phone1,phone2)) LIMIT 1;
    +----+--------+----------+---------+---------+---------------+
    | id | phone1 | phone2   | name    | company | picture       |
    +----+--------+----------+---------+---------+---------------+
    |  1 | 650    | 12345678 | User A  |         | 1-picture.png |
    +----+--------+----------+---------+---------+---------------+
    1 row in set (0.00 sec)
    
    

    As you see, the User A record is retrieved. Not sure why you were getting the incorrect contact, only the LAST part of the number is matched.

    Regarding normalization of entered numbers in the phonebook, what can I say, people might type spaces, parenthesis, dashes, dots, words, whatever... Its a bit complicated to do that kind of normalization. In general, whenever phone number lists are involved, users should use 'computer friendly' numbers to get consistent results.

    So, a quick way to compare numbers would be to strip any non digit character from it, but MySQL lacks that function, however there are some examples posted on StackOverflow, like this one:

    DROP FUNCTION IF EXISTS STRIP_NON_DIGIT;
    DELIMITER $$
    CREATE FUNCTION STRIP_NON_DIGIT(input VARCHAR(255))
       RETURNS VARCHAR(255)
    BEGIN
       DECLARE output   VARCHAR(255) DEFAULT '';
       DECLARE iterator INT          DEFAULT 1;
       WHILE iterator < (LENGTH(input) + 1) DO
          IF SUBSTRING(input, iterator, 1) IN ( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ) THEN
             SET output = CONCAT(output, SUBSTRING(input, iterator, 1));
          END IF;
          SET iterator = iterator + 1;
       END WHILE;
       RETURN output;
    END
    $$
    

    With that function created on MySQL asterisk database, then you can modify the query in vphonebook.php a bit:

    SELECT id,phone1,phone2,concat(firstname,' ',lastname) AS name,company,picture FROM visual_phonebook WHERE (STRIP_NON_DIGIT(phone1) LIKE '%650' OR STRIP_NON_DIGIT(phone2) LIKE '%650') AND context='' ORDER BY LENGTH(CONCAT(phone1,phone2)) LIMIT 1;
    

    The thing is that I am not much comfortable having users needing to add a Function in MySQL/MariaDB by default... maybe I am just picky and its not a problem at all. What do you think?

Sign In or Register to comment.