Modify destination before URL redirect

Discussion in 'Extensions' started by Ignacioport, Jan 5, 2016.

  1. Ignacioport

    Ignacioport Member

    Joined:
    Dec 24, 2015
    Messages:
    33
    Likes Received:
    4
    S.E:
    Expired
    L.T:
    Regular
    L.C:
    3
    Hello Mailwizz users & Twisted,

    how are you?

    I am trying to create an extension to add Google UTM tags automatically to links based on customer groups settings. I know adding UTM tags is not a big deal right now, but such URLs are not sanitized and I need more flexibility and want it done automatically when it is set up.

    I found that this is the action closest to what I need done:

    Yii::app()->hooks->doAction('frontend_campaigns_after_track_url_before_redirect', $this, $campaign, $subscriber, $url, $destination);

    The ideal scenario would be take $destination, make the needed modifications and redirect. Yet under such action is where the subscribers open tracking occurs, so doing such redirect when the action occur with end up meaning that I would not be capable of tracking opens.

    I believe that moving such hook bellow the snippet in this way might solve my issue:

    /apps/frontend/controllers/CampaignsController.php
    PHP:
             //WHERE HOOK ORIGINALLY WAS
            // since 1.3.5.9
            
    if ($campaign->option->open_tracking == CampaignOption::TEXT_YES && !$subscriber->hasOpenedCampaign($campaign)) {
                
    $track = new CampaignTrackOpen();
                
    $track->campaign_id   $campaign->campaign_id;
                
    $track->subscriber_id $subscriber->subscriber_id;
                
    $track->ip_address    Yii::app()->request->getUserHostAddress();
                
    $track->user_agent    substr(Yii::app()->request->getUserAgent(), 0255);
                if (
    $track->save(false)) {
                    try {
                        
    Yii::app()->hooks->doAction('frontend_campaigns_after_track_opening'$this$track$campaign$subscriber);
                    } catch (
    Exception $e) {}
                }
            }
            
    // MOVED HOOK
            
    Yii::app()->hooks->doAction('frontend_campaigns_after_track_url_before_redirect'$this$campaign$subscriber$url$destination);   
            
    $this->redirect($destinationtrue301);
    Yet I am not very fond of modifying the core and that is why I am posting here. Is there any other way around this?

    Maybe adding a filter to make me capable of modifying $destination via an extension would be a nice solution.

    What do you think?

    Thanks!
     
  2. Ignacioport

    Ignacioport Member

    Joined:
    Dec 24, 2015
    Messages:
    33
    Likes Received:
    4
    S.E:
    Expired
    L.T:
    Regular
    L.C:
    3
    Ok...

    I solved my problem by just copying the snippet from the core to my extension before it redirects.

    I hope this does not cause any issues. If anyone has any other approach to recommend I am all ears (eyes).

    Cheers!
     
  3. twisted1919

    twisted1919 Administrator Staff Member

    Joined:
    Dec 27, 2014
    Messages:
    10,176
    Likes Received:
    2,362
    @Ignacioport -
    It is safe to add
    PHP:
    $destination Yii::app()->hooks->applyFilters('frontend_campaigns_track_url_destination'$destination$this$campaign$subscriber$url);
    right before:
    PHP:
    Yii::app()->hooks->doAction('frontend_campaigns_after_track_url_before_redirect'$this$campaign$subscriber$url$destination);
    So we have:
    PHP:
            $destination str_replace('&''&'$url->destination);
            if (
    preg_match('/\[(.*)?\]/'$destination)) {
                list(,,
    $destination) = CampaignHelper::parseContent($destination$campaign$subscriberfalse);
            }

            
    $destination Yii::app()->hooks->applyFilters('frontend_campaigns_track_url_destination'$destination$this$campaign$subscriber$url);

            
    Yii::app()->hooks->doAction('frontend_campaigns_after_track_url_before_redirect'$this$campaign$subscriber$url$destination);

            
    // since 1.3.5.9
            
    if ($campaign->option->open_tracking == CampaignOption::TEXT_YES && !$subscriber->hasOpenedCampaign($campaign)) {
                
    $track = new CampaignTrackOpen();
                
    $track->campaign_id   $campaign->campaign_id;
                
    $track->subscriber_id $subscriber->subscriber_id;
                
    $track->ip_address    Yii::app()->request->getUserHostAddress();
                
    $track->user_agent    substr(Yii::app()->request->getUserAgent(), 0255);
                if (
    $track->save(false)) {
                    try {
                        
    Yii::app()->hooks->doAction('frontend_campaigns_after_track_opening'$this$track$campaign$subscriber);
                    } catch (
    Exception $e) {}
                }
            }
            
    //

            
    $this->redirect($destinationtrue301);
    This way you can hook into "frontend_campaigns_track_url_destination" from any extension.
    You can add this code to core since will be added by me anyway.
     
  4. twisted1919

    twisted1919 Administrator Staff Member

    Joined:
    Dec 27, 2014
    Messages:
    10,176
    Likes Received:
    2,362
    Actually, if i think better, moving the action hook a bit to the top makes more sense, so this is the final thing:
    PHP:
            $track = new CampaignTrackUrl();
            
    $track->url_id          $url->url_id;
            
    $track->subscriber_id   $subscriber->subscriber_id;
            
    $track->ip_address      Yii::app()->request->getUserHostAddress();
            
    $track->user_agent      substr(Yii::app()->request->getUserAgent(), 0255);

            if (
    $track->save(false)) {
                
    // hook added in 1.2
                
    $this->setData('ipLocationSaved'false);
                try {
                    
    Yii::app()->hooks->doAction('frontend_campaigns_after_track_url'$this$track$campaign$subscriber);
                } catch (
    Exception $e) {

                }
            }

            
    // start change
            
    $url->destination str_replace('&''&'$url->destination);
            
    Yii::app()->hooks->doAction('frontend_campaigns_after_track_url_before_redirect'$this$campaign$subscriber$url);

            
    $destination $url->destination;
            if (
    preg_match('/\[(.*)?\]/'$destination)) {
                list(,,
    $destination) = CampaignHelper::parseContent($destination$campaign$subscriberfalse);
            }
           
    // end change

            // since 1.3.5.9
            
    if ($campaign->option->open_tracking == CampaignOption::TEXT_YES && !$subscriber->hasOpenedCampaign($campaign)) {
                
    $track = new CampaignTrackOpen();
                
    $track->campaign_id   $campaign->campaign_id;
                
    $track->subscriber_id $subscriber->subscriber_id;
                
    $track->ip_address    Yii::app()->request->getUserHostAddress();
                
    $track->user_agent    substr(Yii::app()->request->getUserAgent(), 0255);
                if (
    $track->save(false)) {
                    try {
                        
    Yii::app()->hooks->doAction('frontend_campaigns_after_track_opening'$this$track$campaign$subscriber);
                    } catch (
    Exception $e) {}
                }
            }
            
    //

            
    $this->redirect($destinationtrue301);
    So in your action, you can safely modify $url->destination as you wish.
     
    Ignacioport likes this.
  5. Ignacioport

    Ignacioport Member

    Joined:
    Dec 24, 2015
    Messages:
    33
    Likes Received:
    4
    S.E:
    Expired
    L.T:
    Regular
    L.C:
    3
    Thanks!

    The second solution works like a charm, and it even allows me to easily use custom tags in my new links :)

    So yeah, it makes more sense. Do you plan to add such change in the next update?

    I have another issue for you. To make my extension work i need to get the group_id of the customer which is sending the campaign.

    According to the campaign model $campaign has the group_id attribute

    yet if I did $campaign->group_id or $campaign->group->group_id I ended up with null. This after hooking to the aforementioned hook:

    PHP:
    Yii::app()->hooks->doAction('frontend_campaigns_after_track_url_before_redirect'$this$campaign$subscriber$url);
    Why is it so? Is there something wrong in what I am doing?

    I ended up using $campaign->customer_id to load a customer class and fetch the group_id via that class. But looking at the campaign model I thought this was not necessary.

    Cheers and thanks for all your support!
     
  6. twisted1919

    twisted1919 Administrator Staff Member

    Joined:
    Dec 27, 2014
    Messages:
    10,176
    Likes Received:
    2,362
    @Ignacioport - The above change is already added so all releases will have it, no need to worry about updates ;)
    Related to customer group, when you do $campaign->group->group_id you actually try to load the campaign group, not the customer group.
    So instead, what you need is: $campaign->customer->group_id ;)
     
    Ignacioport likes this.
  7. Ignacioport

    Ignacioport Member

    Joined:
    Dec 24, 2015
    Messages:
    33
    Likes Received:
    4
    S.E:
    Expired
    L.T:
    Regular
    L.C:
    3
    Thanks Again!

    That worked just as expected.

    My bad on not realizing this before.

    Cheers!
     

Share This Page