We use cookies to improve your experience. No personal information is gathered and we don't serve ads. Cookies Policy.

ExpressionEngine Logo ExpressionEngine
Features Pricing Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University
Log In or Sign Up
Log In Sign Up
ExpressionEngine Logo
Features Pro new Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University Blog
  • Home
  • Forums

Does EE2 auto-urlencode some urls?

Development and Programming

steph_rose's avatar
steph_rose
17 posts
14 years ago
steph_rose's avatar steph_rose

Alright, I’m hoping there is an easy solution to this and I’m overlooking something.

In EE 1.6.9, I have a custom page with some PHP code in it.

I’m passing a variable through the URL to another page to get filtered results. The variable, in regular readable format, is:

Child & Adolescent Psychiatry

In the PHP code, if I do urlencode([the above]), I get:

Child+% 26+Adolescent+Psychiatry

(I’m putting the space in because it will render otherwise)

In EE2, I’m working this code into a plugin.

Let’s say:

$s = Child & Adolescent Psychiatry

  • If I echo $s, I get the above string, no problem.

  • If I echo urlencode(‘Child & Adolescent Psychiatry’), I get the desired value:

Child+% 26+Adolescent+Psychiatry

  • If I echo urlencode($s), I get what seems to be a double-encoded value:

Child+% 26 amp % 3B+Adolescent+Psychiatry

And this is breaking the GET data.

Any ideas? Does EE2 now, for security reasons, do an extra encode of % signs and whatnot?

       
John Henry Donovan's avatar
John Henry Donovan
12,339 posts
14 years ago
John Henry Donovan's avatar John Henry Donovan

Hi steph_rose,

Can you share some more of your plug-in so we could run a test? I just tried inside a template and performs as expected.

Can you try rawurlencode to see if that works better for you?

echo rawurlencode($s)
       
steph_rose's avatar
steph_rose
17 posts
14 years ago
steph_rose's avatar steph_rose

Example with RAW url encode:

Normal: Vascular & Interventional Radiology - Radiology

Echoing a rawurlencode from in the plugin:

Vascular% 20% 26amp% 3B% 20Interventional% 20Radiology% 20-% 20Radiology

Rawurlencode that gets parsed through variable output:

Vascular% 20% 26amp% 3B% 20Interventional% 20Radiology% 20-% 20Radiology

So it looks like those come out exactly the same; however, I believe the encoding of the percent signs is throwing an Invalid GET Data error.

I’m going to take a deeper look at my plugin and will probably post soon if I don’t figure it out.

However, can you please shed some light on the whole % sign thing in the URL and how EE handles it?

This URL is throwing Invalid GET data (spaces so it doesn’t render):

http://domain.com/doctors/results?ss=Vascular% 20 % 26amp % 3B% 20Interventional % 20Radiology% 20-% 20Radiology&submit=true

       
John Henry Donovan's avatar
John Henry Donovan
12,339 posts
14 years ago
John Henry Donovan's avatar John Henry Donovan

steph_rose,

I think the best thing now would to explain the context on the plug-in and the info being passed to it and what you expect to be returned. Even share some of your plugin with us.

In the meantime I am moving this thread to the development forum but will check in again when you come back with some more details

       
steph_rose's avatar
steph_rose
17 posts
14 years ago
steph_rose's avatar steph_rose

Okay, the idea is this: it’s a doctor with various specialties, and when you click a link on the page for that specialty, you end up on a results page that queried for doctors of said specialty.

As much as I would love to have the specialties normalized (convert Hematology/Oncology-Internal Medicine to something like “hematology-oncology-internal-medicine’, the names aren’t consistent, so it’s impossible to convert a url friendly version back to the official version. I’m now thinking about creating a table with indexes for these unique values, but we’ll see.

Good luck with the code.

function get_doctors_by_specific_specialty($specialty,$name)
    {
        $output        = '';        
        $sp            = "{call dpsp_Get_Physicians_Basic_Data_by_Specific_Specialty(?,?)}";
        $params        = array
        (
            array($specialty,SQLSRV_PARAM_IN),
            array($name . '%',SQLSRV_PARAM_IN)
        );

        $stmt        = $this->query_db($sp,$params);        
        $output        = $this->parse_results($stmt,$specialty);
        
        sqlsrv_free_stmt($stmt);
        return $output;
    }

function parse_results($stmt, $name)
    {
        $output     = '';
        $count        = 0;
        $var_pairs    = array( 'specialties' );
        $all_results     = $this->store_physician_results_in_array($stmt);

        if (count($all_results) != 0)
        {
            $total_results    = sizeof($all_results);        
            foreach ($all_results as $result)
            {
                $tagdata                    = $this->EE->TMPL->tagdata;
                $result['count']            = ++$count;
                $result['total_results']    = $total_results;
                $cond['new_letter']            = ($result['new_letter'] == "yes") ? TRUE : FALSE;
                $cond['has_role']            = (isset($result['role']) && $result['role'] != '') ? TRUE : FALSE;
                $tagdata                    = $this->EE->functions->prep_conditionals($tagdata,$cond);
                $result_edited                 = $this->swap_var_pairs($tagdata,$var_pairs,$result);
                $output                     .= $this->EE->TMPL->parse_variables_row($result_edited, $result);
            }
        }
        else
        {
            return $this->EE->TMPL->no_results();
        }
        
        return $output;
    }

    function store_physician_results_in_array($results)
    {
        $physicians             = array();
        $current_letter            = '';
        $general_specialties    = $this->get_general_specialties_list();
        
        while($row = sqlsrv_fetch_array($results, SQLSRV_FETCH_ASSOC))
        {
            $physician_specialties    = array();
            $phy_letter = strtolower(substr($row['lastname'],0,1));
            $phy_key         = $row['phy_key'];
            $specialties    = explode("|", $row['specialties']);
            
            $i                 = 0;
            foreach($specialties as $specialty)
            {
                // check to see if the specialty becomes a clean URL or if it's an ugly subspecialty (which is where the problem is)
                $s                                        = trim($specialty);
                $physician_specialties[$i]['main']        = (in_array($s,$general_specialties)) ? "true" : "false";
                $physician_specialties[$i]['title']        = $s;
                $url_title = (in_array($s,$general_specialties)) ? array_search($s,$general_specialties) : rawurlencode($s);
                $physician_specialties[$i]['url_title'] = $url_title;
                $i++;
            }
                                
            $physician        =     array
                                (
                                    'letter'        =>    $phy_letter,
                                    'new_letter'    =>     ($current_letter != $phy_letter) ? "yes" : "no",
                                    'key'             =>     $phy_key,
                                    'name_first'    =>    $row['firstname'],
                                    'name_last'        =>    $row['lastname'],
                                    'name_middle'    =>    $row['middlename'],
                                    'name_suffix'    =>    $row['suffix'],
                                    'name_creds'    =>    $row['creds'],
                                    'gender'        =>    $row['sex'],
                                    'photo'            =>    $row['photo'],
                                    'phone_appt'    =>    $this->format_phone($row['apptphone']),
                                    'specialties'    =>    $physician_specialties,
                                    'role'            =>    $row['roles']
                                );    
            $physicians[]     = $physician;
            $current_letter = ($current_letter == $phy_letter) ? $current_letter : $phy_letter;
            
        }
                
        return $physicians;
    }

The result array:

Array
(
    [letter] => a
    [new_letter] => yes
    [key] => 93802
    [name_first] => Abdullah
    [name_last] => Al-Haddad
    [name_middle] => A.
    [name_creds] => M.D.
    [gender] => M
    [photo] => AAl-Haddad.jpg
    [phone_appt] => 305-243-9110
    [specialties] => Array
        (
            [0] => Array
                (
                    [main] => false
                    [title] => Colon & Rectal Surgery
                    [url_title] => Colon+&+Rectal+Surgery
                )
            [1] => Array
                (
                    [main] => true
                    [title] => Surgery
                    [url_title] => surgery
                )
}
 [role] => Assistant Professor
    [count] => 1
    [total_results] => 18
)
       
Michael C. (ProImage)'s avatar
Michael C. (ProImage)
102 posts
13 years ago
Michael C. (ProImage)'s avatar Michael C. (ProImage)

If I may butt in here, I’m having the same issue - granted, in EE1 - but with far simpler code.

Using Nathan Pitman’s Encode/Decode plugin (which has the simplest source imaginable), if I place the following in a template:

{exp:encode_decode style="url" direction="encode"}http://www.example.com{/exp:encode_decode}

I get this result:

http%3A%26%2347%3B%26%2347%3Bwww.example.com (the expected output is http%3A%2F%2Fwww.example.com)

I had to modify the source code of my forum post to get an accurate output in the forums/browser (using empty [i][/i] BBCode tags to selectively break entity parsing), but I’ve previewed it and the above code is accurate… you should be seeing 7 percent signs in the actual output 🐛, and 3 in the desired result.


Allowing the forums and browser to translate the entities in the actual output (i.e. I pasted http%3A%26%2347%3B%26%2347%3Bwww.example.com into my post with no attempt at circumventing the formatting) results in a “successful” interpretation:

http://www.example.com

However, in a [code] block, we get something quite insightful:

http://www.example.com

The [code] block tells EE not to mess with the text, thus what we’re seeing above is only the browser’s interpretation of the entities.

So, it looks like the URL is being encoded using PHP’s htmlspecialchars() (resulting in the “/” bits) before being parsed by urlencode(), since “%26%2347;” = “/”


The only relevant, string-parsing elements of the Encode/Decode plugin (with the given parameters) are as follows:

$str = $TMPL->tagdata;
$string = urlencode($str);
$this->return_data = $string;

If I modify the plugin to work as follows, I get a 1:1 result (no encoding going on by either the plugin or EE whatsoever, meaning “http://www.example.com” goes in, “http://www.example.com” comes out):

$str = $TMPL->tagdata;
$this->return_data = $str;

Ergo, EE’s native parsing functions are using htmlspecialchars() on the variable being passed to the plugin (before the plugin sees it).

       

Reply

Sign In To Reply

ExpressionEngine Home Features Pro Contact Version Support
Learn Docs University Forums
Resources Support Add-Ons Partners Blog
Privacy Terms Trademark Use License

Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.