How to encode a URL as a CakePHP parameter - php

I would like to create a bookmarklet for adding bookmarks. So you just click on the Bookmark this Page JavaScript Snippet in your Bookmarks and you are redirected to the page.
This is my current bookmarklet:
"javascript: location.href='http://…/bookmarks/add/'+encodeURIComponent(document.URL);"
This gives me an URL like this when I click on it on the Bookmarklet page:
http://localhost/~mu/cakemarks/bookmarks/add/http%3A%2F%2Flocalhost%2F~mu%2Fcakemarks%2Fpages%2Fbookmarklet
The server does not like that though:
The requested URL /~mu/cakemarks/bookmarks/add/http://localhost/~mu/cakemarks/pages/bookmarklet was not found on this server.
This gives the desired result, but is pretty useless for my use case:
http://localhost/~mu/cakemarks/bookmarks/add/test-string
There is the CakePHP typical mod_rewrite in progress, and it should transform the last part into a parameter for my BookmarksController::add($url = null) action.
What am I doing wrong?

I had a similar problem, and tried different solutions, only to be confused by the cooperation between CakePHP and my Apache-config.
My solution was to encode the URL in Base64 with JavaScript in browser before sending the request to server.
Your bookmarklet could then look like this:
javascript:(function(){function myb64enc(s){s=window.btoa(s);s=s.replace(/=/g, '');s=s.replace(/\+/g, '-');s=s.replace(/\//g, '_');return s;} window.open('http://…/bookmarks/add/'+myb64enc(window.location));})()
I make two replacements here to make the Base64-encoding URL-safe. Now it's only to reverse those two replacements and Base64-decode at server-side. This way you won't confuse your URL-controller with slashes...

Bases on poplitea's answer I translate troubling characters, / and : manually so that I do not any special function.
function esc(s) {
s=s.replace(/\//g, '__slash__');
s=s.replace(/:/g, '__colon__');
s=s.replace(/#/g, '__hash__');
return s;
}
In PHP I convert it back easily.
$url = str_replace("__slash__", "/", $url);
$url = str_replace("__colon__", ":", $url);
$url = str_replace("__hash__", "#", $url);
I am not sure what happens with chars like ? and so …

Not sure, but hope it helps
you should add this string to yout routs.php
Router::connect (
'/crazycontroller/crazyaction/crazyparams/*',
array('controller'=>'somecontroller', 'action'=>'someaction')
);
and after that your site will able to read url like this
http://site.com/crazycontroller/crazyaction/crazyparams/http://crazy.com

Related

Laravel routes with an optional sub-path

I'm trying to create a Route in routes.php that can handle optional unlimited sub-paths.
Route::get('/path/{url}', function($url){
echo $url;
});
The url's can be the following :
/path/part1
/path/part1/part2
/path/part1/part2/part3
etc.
But because of the / in the url's with a subpath they don't match, so nothing happens. (The echo $url is just for testing, of course).
I now use a trick to avoid this, by using ~ instead of / for the subpaths, and then replace them afterwards, but I would like to know if there's a better way so I can just use / in the URL's.
UPDATE
Found the solution, thanks to Mark :
Route::get('/path/{all}', function($url){
echo $url;
})->where('all', '.*');
There has to be an extent for the url to which you'd want to define your routes for. I suppose the number of sub-routes are/have to be predefined, say you'd want to go with 4 url parts.
If that is the case, then using optional parameters would be the best choice:
Route::get('path/{url1?}/{url2?}/{url3?}/{url4?}',
function($url1 = null, $url2 = null, $url3 = null, $url4 = null){
//check if sub-routes are defined and combine them to produce the desired url
});
Note:
It seems that (:any) parameter is not supported anymore as suggested by #Mark Davidson in the SO answer (I couldn't reproduce it in laravel 5.0).
Meanwhile, you could also use regular expressions to achieve the desired effect, as in the following (might be quite similar to your own approach):
Route::get('/{url}', function ($url) {
// other url parts can be extracted from $url
})->where('url', '.*');
But the only disadvantage in going with the second approach is that you might not know to what extent should you go nested to extract the url sub-parts.
With the former approach though, you know the extent.

How to remove any given $_GET variable from URL with PHP?

I'm puttings filters in links with GET variables like this: http://example.com/list?size=3&color=7 and I'd like to remove any given filter parameter from URL whenever a different value for that particular filter is selected so that it doesn't, for example, repeat the color filter like so:
http://example.com/list?size=3&color=7&color=1
How can I if(isset($_GET['color'])) { removeGet('color'); } ?
You can use parse_url and parse_str to extract parameters like in example below:
$href = 'http://example.com/list?size=3&color=7';
$query = parse_url( $href, PHP_URL_QUERY );
parse_str( $query, $params );
// set custom paramerets
$params['color'] = 1;
// build query string
$query = http_build_query( $params );
// build url
echo explode( '?', $href )[0] . '?' . $query;
In this example explode() is used to extract the part of the url before the query string, and http_build_query to generate query string, you can also use PECL http_build_url() function, if you cannot use PECL use alternative like in this question.
You can't remove variables from GET request, just redirect to address without this var.
if (isset($_GET['color'])) {
header ('Location: http://www.example.com/list?size=' . $_GET['size']);
exit;
}
Note: in URL http://example.com/list?size=3&color=7&color=1 is just one $_GET['color'], not two. Only one of them is taken. You can check, is $_GET['key'] exists, but you don't know how many of them you have in your URL
So, assuming I'm understanding your question correctly.
Your situation is as follows:
- You are building URLs which you put into a webpage as a link ( <a href= )
- You are using the GET syntax/markup (URL?key=value&anotherkey=anothervalue) as a way to assign filters of some sort which the user then receives when they click on a given link
What you want is to be able to modify one of the items in your GET parameter list (http://example.com/list?size=3&color=7&color=1) so you have only one filter key but you can modify the filter value. So instead of the above you would start with: (http://example.com/list?size=3&color=7) but after changing the color 'filter' you would instead have http://example.com/list?size=3&color=1).
Additionally you want to do the above in PHP, (as opposed to JavaScript etc...).
There are a lot of ways to implement the change and the most effective way to do it depends on what you are already doing, most likely.
First, if you are dynamically producing the HTML markup which includes the links with the filter text, (which is what it sounds like), then it makes the most sense to create a PHP array to hold your GET parameters, then write a function that would turn those parameters into the GET string.
New filters would appear when a user refreshed the page, (because, if you are dynamically producing the HTML then a server request is required to rebuild the page).
IF, however, you want to update the link URLs on a live page WITHOUT a reload look into doing it with JavaScript, it will make your life easier.
NOTE: It is likely possible to modify the page, assuming the links are hard coded, & the page is hard coded markup, by opening the page as a file in PHP & making the appropriate change. It's my opinion that this would be a headache and not worth the time & effort AND it would still require a page reload (which you could NOT trigger yourself).
Summary
If you are writing dynamic pages with PHP it shouldn't be a big deal, just create a structure (class or array) and a method/function to write that structure out as a GET string. The structure could then be modified according to your desire before generating the page.
If, however, you are dealing with a static page, I recommend JavaScript (either creating js structures to allow a user to dynamically select filters or utilizing AJAX to build new GET parameter lists with PHP and send that back to the javascript).
(NOTE: I am reminded that I have done something along the lines of modifying links on-the-fly for existing pages by intercepting them before they are displayed to the user [using PHP] but my hands were tied in other areas and I would not recommend it if you have a choice AND it should be noted that this still required a reload...)
Try doing something like this in your back-end script:
$originalValues=array();
foreach($_GET as $filter=>$value)
{
if(empty($originalValues[$filter]))
$originalValues[$filter] = $value;
}
This may do what you want, but it feels hackish. You may want to revise your logic.
Good luck!
just put a link/button send the user to index... like this.
<a class="btn btn-primary m-1" href="http:yoururl/index.php" role="button">Limpar</a>

How can I trim my URL

A have a delete link which goes to another page, call a function, if the function is successful, then I sent the user back to the page where they clicked delete.
I use this to go back:
if ($booking->deleteBooking($_GET['id']))
{
header('Location: ' . $_SERVER['HTTP_REFERER']);
}
My link would look something like this:
/calendar.php?id=1&month=04&day=25&year=2014&t=11&v=true&f=true&reserved=true
Can I trim the link and remove &reserved=true when it's sent back?
Rather than performing string manipulations that could be prone to error, I suggest that you use PHP's URL functions to parse the HTTP_REFERER header and adjust it accordingly:
// parse the referrer
$referer = parse_url($_SERVER['HTTP_REFERER']);
// parse the querystring part
parse_str($referer['query'], $querystring);
// unset the reserved parameter (only if value is 'true'?)
if ($querystring['reserved'] === 'true') unset($querystring['reserved']);
// reconstruct the revised querystring
$referer['query'] = http_build_query($querystring);
// redirect to the adjusted URL
header('Location: ' . http_build_url($referer));
I suggest you avoid regex and str_replace because they will quickly fall flat when your URL structure changes.
I would put this in a class now because this is not the last time you'll need to do this (I just had to do it last week) or some other URL related thing. So, you should go ahead and encapsulate the functionality in one place now rather than later. You can always change the implementation later in one place if you find a better or more correct way to handle the task.
A few fairly important caveats regarding your script and possible solutions...
HTTP_REFERER can't really be relied upon. Browsers are not required to send it and many do not. You can get around that by sending the URL yourself in the query string (properly escaped) or possibly via a hidden form field. Otherwise, your redirect and script is going to fail in a lot of cases! See HTTP Referer not always being passed
You should always exit after sending a Location header if you want an immediate redirect... otherwise your script will keep chugging along happily doing stuff. (database queries, etc, etc) To that end, I would encapsulate your redirect code as well and have done so in my example solution.
http_build_url is not available by default in PHP. It's a pecl_http thing. Ultimately, it's not really required in this case and my example solution works without it.
Example Class Usage:
$referrer = 'http://example.com/calendar.php?id=1&month=04&day=25&year=2014&t=11&v=true&f=true&reserved=true';
$url = new URL($referrer);
$url->remove_param('reserved');
$url->redirect();
Class Code:
class URL
{
public $url = '';
function __construct ($url)
{
$this->url = $url;
}
function redirect ($response_code = 301)
{
header('Location: ' . $this->url, true, $response_code);
exit;
}
function remove_param ($param)
{
// Do nothing to URL without a Query String (hat tip #eggyal)
if (strpos($this->url, '?') === false) return $this->url;
// Split URL into base URL and Query String
list($url, $query) = explode('?', $this->url, 2);
// Parse Query String into array
parse_str($query, $params);
// Remove the parameter in question
unset($params[$param]);
// Rebuild Query String
$query = http_build_query($params);
// Piece URL back together and save to object
$this->url = $url . ($query ? "?$query" : '');
// Return URL in case developer really just wants an instant result
return $this->url;
}
}
Caveat: This will not retain any URL fragments (ie #fragment) In the case of HTTP_REFERER this should not matter as most browsers won't send that anyway. If that is functionality you decide you need, then it can easily be coded in at a later time.
Namespacing: For simplicity's sake, the code examples are not namespaced. However, for real life implementations, I suggest getting in the habit of using "namespace App;" at the top of any in-house class files and calling the class as such "new App\Class();" Especially if you're using or might ever use any third-party code in your project.
Performance Note: Don't worry about performance until it becomes a problem... your time is always the biggest bottleneck... not PHP. Value your time more than PHP's time! PHP will always be faster than spending your time copy pasta coding. Encapsulate your code (in classes or functions) and have time left to go outside and enjoy the weather now and in the future when you need to re-factor.
use preg_replace
preg_replace('/^&reserved=true/', '', $_SERVER['HTTP_REFERER']);

Retrieve content of another website

I want to get the content of another page. The background is that I wanted to make an AJAX request but due to the Same Origin Policy I cannot do this. Now I wanted to write an own PHP script on which I make the AJAX request. The URL looks like the following:
http://domain.com/subfolder/another_subfolder/index.php?id=1234&tx_manager_pi9[parameter]=1&tx_manager_pi9[category]=test&tx_manager_pi9[action]=getInfos&tx_manager_pi9[controller]=Finder&cHash=123456789001233455332
I tried it with fopen, curl and file_get_contents. Nothing from the works. The problem is if I put in the URL as string like
$results = file_get_contents('http://domain.com/subfolder/another_subfolder/index.php?id=1234&tx_manager_pi9[parameter]=1&tx_manager_pi9[category]=test&tx_manager_pi9[action]=getInfos&tx_manager_pi9[controller]=Finder&cHash=123456789001233455332');
it does work. If I put in a variable
$url = 'http://domain.com/subfolder/another_subfolder/index.php?id=1234&tx_manager_pi9[parameter]=1&tx_manager_pi9[category]=test&tx_manager_pi9[action]=getInfos&tx_manager_pi9[controller]=Finder&cHash=123456789001233455332';
$results = file_get_contents($url);
I come to a wrong page. With the specific parameter I get a result. If the parameter are not given correctly it seems that I come to a default page. I can't make a sense out of it.
The same for curl:
$curlSession = curl_init();
$options = array
(
CURLOPT_URL=>$url,
CURLOPT_HEADER=>false,
CURLOPT_RETURNTRANSFER=>true,
CURLOPT_FOLLOWLOCATION=>true
);
curl_setopt_array($curlSession,$options);
$results = curl_exec($curlSession);
This doesn't work. If I put in the URL as string and not as variable I get some results! I thought that the ampersand & or the square brackets [] are the problem but I cannot say this. & should be reserved and [] are no correct URL parameters. But why does the direct input work and not the variable?
I used the variable because I make some replacements with str_replace where I make the query more flexible.
I saw similar questions here (cURL function not working, curl_setopt doesnt work with url as a variable) but there was never posted a real solution.
You have a , instead of a ; in your second code block.
Are you required to be "logged in" to the site that you're visiting? That would explain why it's working in your browser and not through your server script.
If all else is the same, your browser and the PHP functions you listed should return the same results.
Could you provide the actual URL for us to test?
EDIT: Based on the URL you provided, it's working fine for me:
php > $test = file_get_contents("http://www.domain.com/user/user_neu/index.php?id=16518&tx_stusermanager_pi9%5Bindications%5D=1&tx_stusermanager_pi9%5Bcategory%5D=cure&tx_stusermanager_pi9%5Baction%5D=getHousesByIndications&tx_stusermanager_pi9%5Bcontroller%5D=HouseFinder&cHash=88230660f01ads34d73a199b82e976");
php > var_dump($test);
string(29) "16,15,14,13,12,11,17,19,22"
My problem was that I used an encoded URL as starting point. E.g.
http://domain.com/subfolder/another_subfolder/index.php?id=1234&tx_manager_pi9%5Bparameter%5D=%23%23%23param1%23%23%23&tx_manager_pi9%5Bcategory%5D=%23%23%23param2%23%23%23&tx_manager_pi9%5Baction%5D=getInfos&tx_manager_pi9%5Bcontroller%5D=Finder&cHash=123456789001233455332
I made a str_replace on a URL encoded string. Even using urldecode afterwards the URL was not correctly generated for curl, file_get_contents, ...
The correct URL should be something like this
http://domain.com/subfolder/another_subfolder/index.php?id=1234&tx_manager_pi9[parameter]=###param1###&tx_manager_pi9[category]=###param2###&&tx_manager_pi9[action]=getInfos&tx_manager_pi9[controller]=Finder&&cHash=123456789001233455332
i.e. without &, %23, %5B, %5D

How to pass part of url in new link? Using only HTML & PHP

I have been trying to attempt to use the facebook share function in my website but i cant seems to have the right result.
Say:
i have a page called http://www.example.com/product.php?prod=lpd026n&cat=43
and i am using facebook's share function to have visitors to share the page in the FB wall.
i tried writing the link this way but i doesn't seems to be successful:
href="http://www.facebook.com/share.php?u=www.example.com/proddetail.php?<?php print urlencode(#$_SERVER['QUERY_STRING']!=''?'?'.$_SERVER['QUERY_STRING']:'')?>"
as the result the arguments in the URL came out to be in %26, %3D and etc..
Ie: example.com/proddetail.php?prod%3Dlpd026n%26cat%3D43
as some of you may know that the data after '?' is dynamic and i am planing to use the code above in the frame of the page, so it will have different query passed to the share link in every new item.
The end result that i want got to look like this:
http://www.facebook.com/sharer.php?u=http://www.example.com/proddetail.php?prod=lpd026n&cat=43
Not
http://www.facebook.com/share.php?u=http://www.example.com/proddetail.php?prod%3Dlpd026n%26cat%3D43
can anyone help me to solve this problem?
Thanks in advance!
Ps: if you are unclear, please ask me to further clarify.
This URL:
http://www.facebook.com/share.php?u=http://www.example.com/proddetail.php?prod%3Dlpd026n%26cat%3D43
is only partially-encoded. You actually need to fully URL-encode it before passing to FB, so that it won't interfere with FB's URL structure. I'm sure that their script will know how to parse it properly.
The correct method is:
$url = 'http://www.facebook.com/sharer.php?u='.urlencode('http://www.example.com/proddetail.php?prod=lpd026n&cat=43');
// evaluates to:
// http://www.facebook.com/sharer.php?u=http%3A%2F%2Fwww.example.com%2Fproddetail.php%3Fprod%3Dlpd026n%26cat%3D43
Update: build your dynamic query
// Original URL
$url = 'http://www.example.com/proddetail.php';
if ($_SERVER['QUERY_STRING'])
$url .= '?'.$_SERVER['QUERY_STRING'];
// Final URL for FB
$fb_url = 'http://www.facebook.com/share.php?u='.urlencode($url);
This is what urlencode does, what is the problem with the link this way?
Edit: I do not use PHP, but I think the following will do the trick (omitted the urlencode):
href="http://www.facebook.com/share.php?u=www.example.com/proddetail.php?<?php print $_SERVER['QUERY_STRING']?>"
I guess K Prime is right.
u need to encode the whole url because the slashes and ":" are still causing problems in this link ;)
$url = 'http://www.facebook.com/sharer.php?u='.urlencode('http://www.example.com/proddetail.php?prod=lpd026n&cat=43');
should be fine for your purposes.

Categories