Add guess link to phone app

lcollong

FabriKant d'applications web
Hi,

I had the need to let a phone number field act as a direct call when Fabrik's app is used from a smartphone.
The "guess link" standard feature is building a link but without using the "phone possibility" (href="tel:010101010").

I've modified the file plugins/fabrik_element/field/field.php. If a field element is set to "input type: phone Number" in advanced tab and guess link is set to yes, it makes the phone number click launching the phone app.

Maybe it could also be achieved with the JLayouts ?

Here is my code. I could make a github request but one may do it a better way (fabrik helper ?)....

PHP:
 protected function _guessLinkType(&$value, $data)
    {
        $params = $this->getParams();

        if ($params->get('guess_linktype') == '1')
        {
            $w = new FabrikWorker;
            $opts = $this->linkOpts();
            $title = $params->get('link_title', '');
            $attrs = $params->get('link_attributes', '');
           
            $inputType = $params->get('password');  /////<----- ADDED LINE

            if (!empty($attrs))
            {
                $attrs = $w->parseMessageForPlaceHolder($attrs);
                $attrs = explode(' ', $attrs);

                foreach ($attrs as $attr)
                {
                    list($k, $v) = explode('=', $attr);
                    $opts[$k] = trim($v, '"');
                }
            }
            else
            {
                $attrs = array();
            }

            if ((new MediaHelper)->isImage($value))
            {
                $alt = empty($title) ? '' : 'alt="' . strip_tags($w->parseMessageForPlaceHolder($title, $data)) . '"';
                $value = '<img src="' . $value . '" ' . $alt . ' ' . implode(' ', $attrs) . ' />';
            }
///// begin of ADDED BLOCK           
            elseif ($inputType == '2') // if input type is "phone number" add a smartphone link to call the phone number
            {
                $value = '<a href="tel:' . preg_replace('/\D/', '', $value) . '">'.$value.'</a>';
            }
///// end of ADDED BLOCK           
            else
            {
                if (FabrikWorker::isEmail($value) || JString::stristr($value, 'http'))
                {
                }
                elseif (JString::stristr($value, 'www.'))
                {
                    $value = 'http://' . $value;
                }

                if ($title !== '')
                {
                    $opts['title'] = strip_tags($w->parseMessageForPlaceHolder($title, $data));
                }

                $label = FArrayHelper::getValue($opts, 'title', '') !== '' ? $opts['title'] : $value;

                $value = FabrikHelperHTML::a($value, $label, $opts);
            }
        }
    }

If any better suggestions ?
 
Sorry, but why? In both iOS and Android, a tap on any phone number in a browser let's me easily call the number...
 
At least in my case, the phone number is inactive. Tapping on it has no effect. May be a question of element type (text vs integer ?) or template or browser version... I don't know... I heard that firefox is guessing it. I'm using chrome on Android. And several other users are also complaining.
But with this special href link, it launches the phone app directly with the phone number in all circumstances. One tap on the phone, one tab on the call button and that's it ! Your're calling the contact. Small change, great improvement !
 
Curious, I just checked again. You're right, seems only iOS Safari seems to interpret any "not too short" number in text, including the ones with spaces and without +, as phone number and highlights them as link, while other browsers and Android are pickier (or more stubborn?). In iOS, Google Chrome even ignores +xx xxxx xxxx or +xxxxxxxxxx formats.

So, yeah, if your application depends on it, you want to do something like what you're doing.
 
To keep the title and attribute features I would do (but I didn't test)
Code:
protected function _guessLinkType(&$value, $data)
    {
        $params = $this->getParams();

        if ($params->get('guess_linktype') == '1')
        {
            $w = new FabrikWorker;
            $opts = $this->linkOpts();
            $title = $params->get('link_title', '');
            $attrs = $params->get('link_attributes', '');
          
            $inputType = $params->get('password');  /////<----- ADDED LINE

            if (!empty($attrs))
            {
                $attrs = $w->parseMessageForPlaceHolder($attrs);
                $attrs = explode(' ', $attrs);

                foreach ($attrs as $attr)
                {
                    list($k, $v) = explode('=', $attr);
                    $opts[$k] = trim($v, '"');
                }
            }
            else
            {
                $attrs = array();
            }

            if ((new MediaHelper)->isImage($value))
            {
                $alt = empty($title) ? '' : 'alt="' . strip_tags($w->parseMessageForPlaceHolder($title, $data)) . '"';
                $value = '<img src="' . $value . '" ' . $alt . ' ' . implode(' ', $attrs) . ' />';
            }
       
            else
            {
                if (FabrikWorker::isEmail($value) || JString::stristr($value, 'http'))
                {
                }
                elseif (JString::stristr($value, 'www.'))
                {
                    $value = 'http://' . $value;
                }
///// begin of ADDED BLOCK         
               elseif ($inputType == '2') // if input type is "phone number" add a smartphone link to call the phone number
               {
                     $value = 'tel:' . preg_replace('/\D/', '', $value);
                }
///// end of ADDED BLOCK 

                if ($title !== '')
                {
                    $opts['title'] = strip_tags($w->parseMessageForPlaceHolder($title, $data));
                }

                $label = FArrayHelper::getValue($opts, 'title', '') !== '' ? $opts['title'] : $value;

                $value = FabrikHelperHTML::a($value, $label, $opts);
            }
        }
    }
 
Good point. However, I have to test again (last 3 lines) in order to preserve the original value as label otherwise it shows the whole url without white space which is not comfortable. Also my version show a "tel" label when the field is empty.... still to be tuned ! :)

PHP:
protected function _guessLinkType(&$value, $data)
    {
        $params = $this->getParams();

        if ($params->get('guess_linktype') == '1')
        {
            $w = new FabrikWorker;
            $opts = $this->linkOpts();
            $title = $params->get('link_title', '');
            $attrs = $params->get('link_attributes', '');
       
            $inputType = $params->get('password');  /////<----- ADDED LINE

            if (!empty($attrs))
            {
                $attrs = $w->parseMessageForPlaceHolder($attrs);
                $attrs = explode(' ', $attrs);

                foreach ($attrs as $attr)
                {
                    list($k, $v) = explode('=', $attr);
                    $opts[$k] = trim($v, '"');
                }
            }
            else
            {
                $attrs = array();
            }

            if ((new MediaHelper)->isImage($value))
            {
                $alt = empty($title) ? '' : 'alt="' . strip_tags($w->parseMessageForPlaceHolder($title, $data)) . '"';
                $value = '<img src="' . $value . '" ' . $alt . ' ' . implode(' ', $attrs) . ' />';
            }
     
            else
            {
                if (FabrikWorker::isEmail($value) || JString::stristr($value, 'http'))
                {
                }
                elseif (JString::stristr($value, 'www.'))
                {
                    $value = 'http://' . $value;
                }
///// begin of ADDED BLOCK      
               elseif ($inputType == '2') // if input type is "phone number" add a smartphone link to call the phone number
               {
                     $label = $value;
                     $value = 'tel:' . preg_replace('/\D/', '', $value);
                }
///// end of ADDED BLOCK

                if ($title !== '')
                {
                    $opts['title'] = strip_tags($w->parseMessageForPlaceHolder($title, $data));
                }

                $newValue = $inputType == '2' ? $label : $value;   // added extra test
              
                $label = FArrayHelper::getValue($opts, 'title', '') !== '' ? $opts['title'] : $newValue; // in order to keep original value

                $value = FabrikHelperHTML::a($value, $label, $opts);
            }
        }
    }
 
My final contribution which seems to work in all case....

PHP:
    protected function _guessLinkType(&$value, $data)
    {
        $params = $this->getParams();

        if ($params->get('guess_linktype') == '1')
        {
            $w = new FabrikWorker;
            $opts = $this->linkOpts();
            $title = $params->get('link_title', '');
            $attrs = $params->get('link_attributes', '');

/////<----- ADDED LINES        
            $inputType = $params->get('password');
            $telHref  = false;
/////----->
            if (!empty($attrs))
            {
                $attrs = $w->parseMessageForPlaceHolder($attrs);
                $attrs = explode(' ', $attrs);

                foreach ($attrs as $attr)
                {
                    list($k, $v) = explode('=', $attr);
                    $opts[$k] = trim($v, '"');
                }

            }
            else
            {
                $attrs = array();
            }

            if ((new MediaHelper)->isImage($value))
            {
                $alt = empty($title) ? '' : 'alt="' . strip_tags($w->parseMessageForPlaceHolder($title, $data)) . '"';
                $value = '<img src="' . $value . '" ' . $alt . ' ' . implode(' ', $attrs) . ' />';
            }
      
            else
            {
                if (FabrikWorker::isEmail($value) || JString::stristr($value, 'http'))
                {
                }
                elseif (JString::stristr($value, 'www.'))
                {
                    $value = 'http://' . $value;
                }
///// begin of ADDED BLOCK       
                elseif ($inputType == '2' && !empty($value))
                // if input type is "phone number" add a smartphone link to call the phone number in one click
                {
                    $telHref = true;
                    $label = $value;
                    $value = 'tel:' . preg_replace('/\D/', '', $value);
                }
///// end of ADDED BLOCK

                if ($title !== '')
                {
                    $opts['title'] = strip_tags($w->parseMessageForPlaceHolder($title, $data));
                }

                $newValue = $telHref ? $label : $value;  ////// added line (preserve original value as label)
               
                $label = FArrayHelper::getValue($opts, 'title', '') !== '' ? $opts['title'] : $newValue;  ///// modified line

                $value = FabrikHelperHTML::a($value, $label, $opts);
            }
        }
    }
 
Thanks, this will be very useful for me too, but I wanted to make sure before testing it that it didn't bother the standard guess link. Thanks in advance for the answer
 
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top