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
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?
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
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
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
)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.comThe [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).
Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.