There various ways you could go about this. You could have all your links point to a redirect page with the redirect url as a parameter and handle your tracking and redirection there. You could also highjack the click with javascript and send an ajax request to a route that would handle the tracking.
Hmmm, thanks for the ideas. I think i am going to search some more info about sending ajax requests to a route. Thx
illuminate3 said:
How about firing an event?
Can you be more specific? I'm kind of a newbie :)
I'm no sure, but I think Knockout.js can help you.!
So... I guess your feeds class is some kind of model in a class like this right ?
<?php
class Feeds extends Eloquent {
protected $table = 'feeds';
}
// then you would writes some function to record the updated click count
public function addclick() {
// assume you have a clicks field in your DB
$this->clicks = $this->clicks + 1;
$this->save();
}
// in your routes you probably have some kind of reference to a controller that is displaying your links ??
like this ??
Route::get('/feeds/{feed_id}', array( 'as' => 'feeds.show', 'uses' => 'FeedsController@show'));
// so then in your FeedsController show(feed_id) method
// you would just call the add click function before returning the view of the feed..
// something like this
public function show($id) {
$feed = Feeds::find($id)->first();
$feed->addclick();
$data['feed'] = $feed;
return View::make( 'feeds.show', $data );
}
// let me know if it works
Hijack the click, send an ajax request to your server, update the database, send a response back to the client, then redirect to the site. I'll write some pseudo-ish jquery:
$('a').click(function(evt) {
evt.preventDefault();
var link = $(this).attr('href');
$.ajax({
method: post,
url: '/link-tracking',
data: {
href: link
}
});
}).done(function(url) { // pass the url back to the client after you incremented it
window.location = url;
});
abelgo said:
So... I guess your feeds class is some kind of model in a class like this right ?
<?php class Feeds extends Eloquent { protected $table = 'feeds'; } // then you would writes some function to record the updated click count public function addclick() { // assume you have a clicks field in your DB $this->clicks = $this->clicks + 1; $this->save(); } // in your routes you probably have some kind of reference to a controller that is displaying your links ?? like this ?? Route::get('/feeds/{feed_id}', array( 'as' => 'feeds.show', 'uses' => 'FeedsController@show')); // so then in your FeedsController show(feed_id) method // you would just call the add click function before returning the view of the feed.. // something like this public function show($id) { $feed = Feeds::find($id)->first(); $feed->addclick(); $data['feed'] = $feed; return View::make( 'feeds.show', $data ); } // let me know if it works
Yep this kind of works :) the first problem was that this link didn't work $feed = Feeds::find($id)->first(); (i don't know why ??!?) but i replaced it for $feed = Feed::where('id','=',$id)->first(); And it increments the clicks.
But the main problem is that i didn't wanted to have this kind of route Route::get('/feeds/{feed_id}', array( 'as' => 'feeds.show', 'uses' => 'FeedsController@show'));
in my FeedsController i only have public function index() {
$feeds = Feed::with('site')->orderBy('dh_publicacao', 'desc')->paginate(20);
// return $feeds;
return View::make('feeds.index', compact('feeds'));
}
in my feeds.index view i show all the feeds with a link to the original site i could use the option u gave me if I only knew how to open the feed_link in another page and reload the feeds.index view at the same point it was. (if i make a return Redirect::back(); it goes to the to pof the page :( )
You don't need to do :
$feed = Feeds::find($id)->first();
as find()
already returns only one single result.
So, your complete implementation becomes :
.../route.php
Route::get('feeds', 'FeedController@index');
Route::get('feed/{id}', 'FeedController@show');
../app/controller/FeedController.php
class FeedController extends BaseController
{
/**
* Show index of feeds
*
* @return Response
*/
public function index()
{
$feeds = Feed::with('site')
->orderBy('dh_publicacao', 'desc')
->paginate(20);
return View::make('feeds.index', compact('feeds'));
}
/**
* Send user to feed site
*
* @return Redirect
*/
public function show($id)
{
$feed = Feed::find($id);
$url = $feed->site->url;
$feed->increment('clicks')->save();
return Redirect::to($url);
}
}
Now you can just link all the feeds to your show route :
../views/feeds/index.blade.php
...
@foreach ($feeds as $feed)
{{ link_to_action('FeedController@show', $feed->title , array($feed->id) }}
@endforeach
...
I think my question is how can i make a link that opens something like href="{{$feed->feed_link}}" and at the same time executes the route Route::get('/feeds/{feed_id}', array( 'as' => 'feeds.show', 'uses' => 'FeedsController@show'))
At this point i have this that redirects to the route
<div class="panel-heading">{{ link_to("feeds/$feed->id",$feed->titulo) }}but i need to open the link and execute the route only to add the click on the database. In the same view I have another link to the home site. I needed when someone clicks that link to increase the clicks to
<div class="panel-heading"><a href = "{{ $feed->site->site }}">{{ $feed->site->nome }}</a> Is it possible to keep this kind of link and also execute the route '/feeds/{feed_id}'Drifeter said:
but i need to open the link and execute the route only to add the click on the database. In the same view
If you want it to be on the same page, the only way I see is hijack the click and send ajax request as suggested by @AnthonyVipond !
AnthonyVipond said:
Hijack the click, send an ajax request to your server, update the database, send a response back to the client, then redirect to the site. I'll write some pseudo-ish jquery:
$('a').click(function(evt) { evt.preventDefault(); var link = $(this).attr('href'); $.ajax({ method: post, url: '/link-tracking', data: { href: link } }); }).done(function(url) { // pass the url back to the client after you incremented it window.location = url; });
Yeah but this is the laravel forum ? There are a ton of different ways to do this in different platforms and different languages. I mean one simple way might be to just install Google analytics. The question was how to do it in lavavel not in java script or jquery Python or even cgi.
Nice. I like the way you even used the increment() function.
Im still operating on the paranoia level with laravel. As I often find things don't work quite as I expect or get caught out with typos that are hard to debug, So I tend to write code as basic as possible to avoid unknown problems such as ..
$this->clicks = $this->clicks + 1;
When I was starting our I often got caught our by following some earlier documentation where
Model::find(id) and Model::get(id) appeared to both return the collection of objects rather than the single opject.
This was a bit counter intuitive for the beginner as I would have expected Model::get(id) with a single ID and using hasOne relationship to return one object but it didn't; ?? The solution was to always add a ->first() call to the collection to ensure you got the one opject.
Model::get(id)->first()
Not sure if this has changed now in laravel 4. but I think Model::get(id) still returns the collection even with hasOne relationship
Drifeter said:
I think my question is how can i make a link that opens something like href="{{$feed->feed_link}}" and at the same time executes the route Route::get('/feeds/{feed_id}', array( 'as' => 'feeds.show', 'uses' => 'FeedsController@show'))
At this point i have this that redirects to the route
<div class="panel-heading">{{ link_to("feeds/$feed->id",$feed->titulo) }}but i need to open the link and execute the route only to add the click on the database. In the same view I have another link to the home site. I needed when someone clicks that link to increase the clicks to
<div class="panel-heading"><a href = "{{ $feed->site->site }}">{{ $feed->site->nome }}</a> Is it possible to keep this kind of link and also execute the route '/feeds/{feed_id}'
I tend to agree with the other guys your expanding the scope of what we understood you originally wanted to do .
What you seem to be saying is that when ever some one clicks on any link any where you want to increment a click count in your database then show the link is that correct ??
If I was going to do that in laravel I would use a filter.
You can experiment by creating a new filter or use the existing ones like before or after request.
Try this.
Add a Route filter called clicked in filters.php
Route::filter('clicked', function()
{
// Get the url the user clicked on from the request object
$url = Request::url();
// find the feed that they click
// keeping it very simple
$feed = Feed::where( 'url' , '=' , $url )->first();
// if the url is not in the feeds table do nothing otherwise increment clicks
if( ! is_null($feed) ){
$feed->increment('clicks')->save();
}
});
Now wrap all your routes you want to record clicks on with the filter
Like so ..
routes.php
// clicked before code in the filter runs before processing any request
Route::group( array('before'=>'clicked' , ), function() {
Route::get('feeds', 'FeedController@index');
Route::get('feed/{id}', 'FeedController@show');
}
Bingo any url requested in the feeds table gets an updated click count when requested
If the link is not on your site you can use a Redirect after running the click update
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community