Coder Social home page Coder Social logo

nystudio107 / retour Goto Github PK

View Code? Open in Web Editor NEW
168.0 8.0 25.0 1.88 MB

DEPRECATED Retour allows you to intelligently redirect legacy URLs, so that you don't lose SEO value when rebuilding & restructuring a website.

License: Other

PHP 59.38% CSS 6.83% JavaScript 1.57% HTML 32.22%
craftcms redirects craft-plugin deprecated

retour's Introduction

No Maintenance Intended

DEPRECATED

This Craft CMS 2.x plugin is no longer supported, but it is fully functional, and you may continue to use it as you see fit. The license also allows you to fork it and make changes as needed for legacy support reasons.

The Craft CMS 3.x version of this plugin can be found here: craft-retour and can also be installed via the Craft Plugin Store in the Craft CP.

Retour plugin for Craft CMS

Retour allows you to intelligently redirect legacy URLs, so that you don't lose SEO value when rebuilding & restructuring a website.

Screenshot

Related: Retour for Craft 3.x

Installation

To install Retour, follow these steps:

  1. Download & unzip the file and place the retour directory into your craft/plugins directory
  2. -OR- do a git clone https://github.com/nystudio107/retour.git directly into your craft/plugins folder. You can then update it with git pull
  3. -OR- install with Composer via composer require nystudio107/retour
  4. Install plugin in the Craft Control Panel under Settings > Plugins
  5. The plugin folder should be named retour for Craft to see it. GitHub recently started appending -master (the branch name) to the name of the folder for zip file downloads.

Retour works on Craft 2.4.x, Craft 2.5.x, and Craft 2.6.x.

Retour Overview

Retour allows you to intelligently redirect legacy URLs, so that you don't lose SEO value when rebuilding & restructuring a website.

In addition to supporting traditional exact and RegEx matching of URL patterns, Retour also has a Retour Redirect FieldType that you can add to your entries. This allows you to have dynamic entry redirects that have access to the data in your entries when matching URL patterns.

Retour will also automatically create a redirect for you if you change an entry's slug, or move an entry around in a Structure.

Retour is written to be performant. There is no impact on your website's performance until a 404 exception happens; and even then the resulting matching happens with minimal impact.

Don't just rebuild a website. Transition it with Retour.

Why Use a Plugin for Redirects?

If you have just a few static redirects, then your best bet is to put them in your .htaccess file, or better yet, in your .conf file for your virtual host. However, there are a number of cases where using a plugin to handle it is a better solution:

  1. If you have a large number of redirects, it will slow down every single request your web server handles unnecessarily if they are in .htaccess or .conf
  2. Often the URL patterns from the legacy website do not match the new website URLs in a deterministic way, which makes creating redirects difficult
  3. Sometimes you don't have access to the server config files, or you want to give your client the ability to manage redirects easily

Retour solves these problems:

  1. Retour only attempts to do a redirect after the web server has already thrown a 404 exception. Once a redirect mapping is successfully determined, it also caches the result for speedy resolution of the next redirect request.
  2. Retour also gives you the ability to do Dynamic Entry Redirects that allow you to import a piece of legacy data into your entries to use as a key for determining the new URL mapping. In this way, utterly dissimilar URLs can be mapped for redirection effectively.
  3. It provides an easy to use GUI that the client can use from Craft's AdminCP, and keeps statistics on the 404 hits (and misses)

A Word about .htaccess

People using the Apache webserver are familiar with the .htaccess file, and may even be using it for redirects. It's very likely that you should not be using .htaccess at all; instead you should disable .htaccess via AllowOverride none and make your configuration changes in your webserver configuration files. From Apache HTTP Server Tutorial: .htaccess files

There are two main reasons to avoid the use of .htaccess files.

The first of these is performance. When AllowOverride is set to allow the
use of .htaccess files, httpd will look in every directory for .htaccess
files. Thus, permitting .htaccess files causes a performance hit, whether or
not you actually even use them! Also, the .htaccess file is loaded every
time a document is requested.

Further note that httpd must look for .htaccess files in all higher-level
directories, in order to have a full complement of directives that it must
apply. (See section on how directives are applied.) Thus, if a file is
requested out of a directory /www/htdocs/example, httpd must look for the
following files:

/.htaccess
/www/.htaccess
/www/htdocs/.htaccess
/www/htdocs/example/.htaccess

And so, for each file access out of that directory, there are 4 additional
file-system accesses, even if none of those files are present. (Note that
this would only be the case if .htaccess files were enabled for /, which is
not usually the case.)

In the case of RewriteRule directives, in .htaccess context these regular
expressions must be re-compiled with every request to the directory, whereas
in main server configuration context they are compiled once and cached.
Additionally, the rules themselves are more complicated, as one must work
around the restrictions that come with per-directory context and
mod_rewrite. Consult the Rewrite Guide for more detail on this subject.

As you can see, avoiding the use of .htaccess completely is best if at all possible, and especially avoid it for RewriteRule directives, such as 404 rewrites.

Dynamic Entry Redirects

Retour implements a Retour Redirect FieldType that you can add to your Entry Types. Retour will look for 404 (Not Found) URLs that match the Legacy URL Pattern, and redirect them to this entry's URL.

You also get the context of the entry that you can use when matching legacy URLs; so if you've imported a field called recipeid into your new website, you can the Retour Redirect FieldType look for it in your Legacy URL Pattern, e.g.: /old-recipes/{recipeid}

This allows you to key off of a piece of legacy data that was imported, for the cases when the new URL patterns don't look anything like the Legacy URL Patterns, or follow any pattern that RegEx is useful for matching.

Screenshot

Creating a Retour Redirect Field

Create a Retour Redirect field as you would any other field; then set the default values for it. For new entries, it will default to the values entered here, so you can put your matching pattern in once, rather than having to do it for each entry.

  • Default Legacy URL Pattern - Enter the URL pattern that Retour should match. This matches against the path, the part of the URL after the domain name. You can include tags that output entry properties, such as {title} or {myCustomField} in the text field below. e.g.: Exact Match: /recipes/{recipeid} or RegEx Match: .*RecipeID={recipeid}$ where {recipeid} is a field handle to a field in this entry.
  • Default Pattern Match Type - What type of matching should be done with the Legacy URL Pattern. Details on RegEx matching can be found at regexr.com. If a plugin provides a custom matching function, you can select it here.
  • Default Redirect Type - Select whether the redirect should be permanent or temporary.
  • Redirect Changeable - Whether to allow the user to change the redirect while editing the entry.

Configuring a Retour Redirect Field

  • Legacy URL Pattern - Enter the URL pattern that Retour should match. This matches against the path, the part of the URL after the domain name. You can include tags that output entry properties, such as {title} or {myCustomField} in the text field below. e.g.: Exact Match: /recipes/{recipeid} or RegEx Match: .*RecipeID={recipeid}$ where {recipeid} is a field handle to a field in this entry.
  • Pattern Match Type - What type of matching should be done with the Legacy URL Pattern. Details on RegEx matching can be found at regexr.com. If a plugin provides a custom matching function, you can select it here.
  • Redirect Type - Select whether the redirect should be permanent or temporary.

Note: if you add a Retour Redirect FieldType to an existing Section, or you import data from a foreign source into a Section with a Retour Redirect FieldType, the default values you set for the Retour Redirect FieldType will not be propagated to the entry yet. To cause that to happen, go to Settings->Sections then click on the Section to edit it, and hit Save. This will cause all of the entries in that section to be re-saved, and Retour will fill in the default field values.

Static Redirects

Manually Creating Static Redirects

Static Redirects are useful when the Legacy URL Patterns and the new URL patterns are deterministic. You can create them by clicking on Retour->Redirects and then clicking on the + New Static Redirect button.

  • Legacy URL Pattern - Enter the URL pattern that Retour should match. This matches against the path, the part of the URL after the domain name. e.g.: Exact Match: /recipes/ or RegEx Match: .*RecipeID=(.*)
  • Destination URL - Enter the destination URL that should be redirected to. This can either be a fully qualified URL or a relative URL. e.g.: Exact Match: /new-recipes/ or RegEx Match: /new-recipes/$1
  • Pattern Match Type - What type of matching should be done with the Legacy URL Pattern. Details on RegEx matching can be found at regexr.com. If a plugin provides a custom matching function, you can select it here.
  • Redirect Type - Select whether the redirect should be permanent or temporary.

Importing an Existing .htaccess file

Retour also allows you to import an existing .htaccess file and all of the redirects it contains into Retour by clicking on Retour->Redirects and then clicking on the Import .htaccess File button.

It will import redirects from Redirect and RedirectMatch directives in the file. It will ignore RewriteRules because they don't necessarily have a 1:1 mapping, you can have several RewriteRules that are strung together to figure out the final redirect.

It asks your browser to look for only text files to upload; if the .htaccess file you have isn't a .txt file, you can force it to allow you to upload it by choosing Format: All Files.

Renamed Slug Redirects

If you rename an entry's slug (and the Section the entry is in has URLs), Retour will automatically create a static redirect for you to keep traffic going to the right place. It will also automatically create a static redirect if you move an entry around in a Structure.

It will appear listed under the "Static Redirects" section like any other static redirect.

Retour Statistics

Retour keeps track of every 404 your website receives. You can view them by clicking on Retour->Statistics.

Only one record is saved per URL Pattern, so the database won't get clogged with a ton of records.

Retour Widget

If you'd like to see an overview of the Retour Statistics in your dashboard, you can add a Retour widget to your Dashboard:

Screenshot

It displays the total number of handled and not handled 404s, and the 5 most recent 404 URLs in each category right in your dashboard.

Developer Info

Custom Match Functions via Plugin

Retour allows you to implement a custom matching function via plugin, if the Exact and RegEx matching are not sufficient for your purposes.

In your main plugin class file, simply add this function:

/**
 * retourMatch gives your plugin a chance to use whatever custom logic is needed for URL redirection.  You are passed
 * in an array that contains the details of the redirect.  Do whatever matching logic, then return true if is a
 * matched, false if it is not.
 *
 * You can alter the 'redirectDestUrl' to change what URL they should be redirected to, as well as the 'redirectHttpCode'
 * to change the type of redirect.  None of the changes made are saved in the database.
 *
 * @param mixed An array of arguments that define the redirect
 *            $args = array(
 *                'redirect' => array(
 *                    'id' => the id of the redirect record in the retour_redirects table
 *                    'associatedElementId' => the id of the entry if this is a Dynamic Entry Redirect; 0 otherwise
 *                    'redirectSrcUrl' => the legacy URL as entered by the user
 *                    'redirectSrcUrlParsed' => the redirectSrcUrl after it has been parsed as a micro template for {variables}
 *                        via renderObjectTemplate().  This is typically what you would want to match against.
 *                    'redirectMatchType' => the type of match; this will be set to your plugin's ClassHandle
 *                    'redirectDestUrl' => the destination URL for the entry this redirect is associated with, or the
 *                        destination URL that was manually entered by the user
 *                    'redirectHttpCode' => the redirect HTTP code (typically 301 or 302)
 *                    'hitCount' => the number of times this redirect has been matched, and the redirect done in the browser
 *                    'hitLastTime' => the date and time of the when this redirect was matched
 *                    'locale' => the locale of this redirect
 *                )
 *            );
 * @return bool Return true if it's a match, false otherwise
 */
public function retourMatch($args)
{
    return true;
}

Your plugin will then appear in the list of Pattern Match Types that can be chosen from via Retour->Redirects or via the Retour Redirect FieldType.

Utility Functions

craft.retour.getHttpStatus in your templates will return the HTTP Status code for the current template, so you can display a special message for people who end up on a page via a 301 or 302 redirect.

Retour Roadmap

Some things to do, and ideas for potential features:

  • Craft 3 compatibility
  • Add the ability to mass-import redirects from a CSV file

Brought to you by nystudio107

retour's People

Contributors

benjolabs avatar dommmel avatar erikverheij avatar khalwat avatar mosnar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

retour's Issues

Long URLs causing SQL duplicate key errors

tldr; Retour incorrectly attempts to insert a duplicate Retour_StatsRecord when the URLs are longer than 255 characters.

In RetourService::incrementStatistics($url, $handled), Retour is looking for a record in retour_stats where redirectSrcUrl =' . craft()->db->quoteValue($url) (here). If one isn't found, it adds a new record with redirectSrcUrl = $url (here).

In the former, if $url is more than 255 characters, no results will ever be returned. In the latter, the URL is being truncated in order to fit it into the table.

This means that if the URL is longer than 255 characters, Retour attempts to insert a new record into retour_stats, which has a unique key constraint on redirectSrcUrl, which fails because the truncated URL already exists in the DB.

Consider an example where the field is max 10 characters, where the actual url is helloworld:

  1. Retour calls incrementStatistics('/helloworld')
  2. $result is empty because no records exist where redirectSrcUrl = '/helloworld'
  3. A new Retour_StatsRecord is created with redirectSrcUrl = '/helloworld', which gets truncated on insert to/helloworl`.
  4. Another request is made for /helloworld, so repeat steps 1, 2, and 3. On step 3, the INSERT fails due to unique key redirectSrcUrl = '/helloworl'

Can this handle old urls from .net site?

I have a lot of data that is being imported into CraftCMS. I don't want to write rules to redirect 80K items from old CMS to new CMS and I am trying not to change the domain URL. I want to use this plugin but not sure if I can use
www.example.com///title_name.aspx
www.example.com//title_name.aspx

P.S. I am learning how to use the CMS so let me know if this is a stupid question

Redirect on other trigger besides 404

This is a bit of a feature request. I've run into instances where someone wants/needs a redirect that replaces a current page on their site.

The entry however, may be used to define some kind of navigation element so the entry cannot be disabled/destroyed, and a redirect setup in Retour doesn't get triggered since the page doesn't 404.

I'm not sure if it's feasible ( or efficient ) to check and see if the page has an override specified via a custom field that would redirect it based on a Retour route regardless if it 404's or not, but this sure would be handy in a few instances.

We've worked around it by creating a dead template that does something like an {% exit 404 %} on load, but this seems pretty nasty. Thought I'd throw this here for discussion.

404 Page error

I updated to latest version and the 404 page gives the following error:

CException

The attribuut "Craft\Retour_StatsRecord.referrerUrl" is not defined.

column 'redirectSrcUrl' can't have a default value

Trying to install the plugin and I get the following error

CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1101 BLOB, TEXT, GEOMETRY or JSON column 'redirectSrcUrl' can't have a default value

I'm syncing a local development site with a remote live site. The plugin was installed successfully on the local site, but I have problems installing it on the live site. I synced the databases back and forth, so I thought this was a problem with the tables already being there.

Unfortunately, I scrubbed retour from the database and i'm still getting this error. If there's any insight into how to install the plugin I would be very grateful.

Urls with slashes on the end are having the final slash stripped when added from stats

When I click the blue +button on stats, it takes an unhandled re-direct like

/categories/Inkjet-Papers-By-Brand/Hahnemuhle-Papers/?p=categories/Inkjet-Papers-By-Brand/Hahnemuhle-Papers/

and in the nee redirect page the legacy url pattern becomes
/categories/Inkjet-Papers-By-Brand/Hahnemuhle-Papers/?p=categories/Inkjet-Papers-By-Brand/Hahnemuhle-Papers - notice the lack of trailing slash.

So the created re-direct then does not work for the full url

Thanks!

Error setting up on a Craft 2.4 website

I'm getting an error Variable "continueEditingUrl" does not exist when trying to access the settings page after installing on a Craft 2.4.2684 website.

It's coming from /retour/templates/settings.twig(39) where you call {{ continueEditingUrl }}. However, from what I can see continueEditingUrl isn't defined anywhere.

Thanks in advance

Enhancement: Bulk add/import

Would be great to have a way to add a bulk lot of URLs + redirects at once, either by pasting CSV format text into a textarea, or by importing a CSV file with specified columns (to match the db table columns i guess).

Redirect Evaluation Order

I'm wondering if it would be possible to program Retour so that when it is comparing a URL with potential redirects, it loops through only Exact Matches before comparing to RegEx Matches.

The scenario that brought this to mind is this:
We recently redesigned our site and there are a number of old URLs that follow the pattern http://www.site.com/product/p/product-page-here-ab-1. Thankfully, most of the new URLs follow almost exactly the same pattern, http://www.site.com/product/product-page-here-ab-1, so it's just a matter of creating the RegEx match and capturing the slug.

Where I run into problems is when the old page URL is along the lines of http://www.site.com/product/p/product-page-here, but the new one changed for whatever reason (http://www.site.com/product/p/new-fancy-name-here-ab-1). If the RegEx redirect was added first, Retour (it seems) executes that redirect first, even though there is an exact redirect between the old and new link. That ends up redirecting to http://www.site.com/product/product-page-here, which still 404s.

The workaround I've found is to enter all the Exact Matches first, then enter the RegEx Match after so it is executed last. Since RegEx casts a wide net, it seems to make sense checking against Exact Matches first. Maybe there is a scenario I'm not thinking of where this wouldn't work. What do you think?

410 gone functionality

It would be cool if your retourplugin would have a functionality for 410 gone errors so google would remove abandoned path's

changing an entry link from /url-1 to /url-2 to /url-1 shows both redirects in the redirects list

Hi khal,
Just trying your Retour plugin for the first time, so far appears to work great so thanks for your efforts in to making it!
Just wanted to ask if there’s anything in there to deal with where a situation where the page is on /url-1, changes to /url-2, then back to /url-1, it appears at the moment that no redirect loop is happening and technically works absolutely fine, but I can see both the redirects in the dashboard still on the list at /admin/retour/redirects

Substitution in destination URL?

Is it possible to provide support for regex substitutions in the destination url? In my case the incoming URLs are uppercase while the destination is lowercase. I tried to use \L$1 without success.

Thanks!

404 error when clearing stats in Craft Admin

Nothing major, but noticed when clearing stats in the retour plugin it returns a 404 error page within craft admin panel. In my instance it is hitting this URL;
/cms/retour/clearStats/statistics/

Redirects

Hi

Is there a way to set it up that retour clear stats automatically after a certain amount of time, as the statistics table is getting seriously massive on the site that we have. It reached 81MB before it was manually cleared.

Thanks

Locale issues with fieldtype

Problem 1:

  • Marking a field as "translatable" doesn't seem to change behavior.

The field data should persist across all locales if it is not translatable, but it doesn't.

Problem 2:

Retour Redirect fields don't seem to care what locale the field is entered in, nor what locale the request comes from *

Example:

  • site.com sets locale to us
  • site.co.uk sets locale to uk
  • Entry has no redirect in us
  • Entry has redirect /oldurl/ in uk

Expected behavour:

  • site.com/oldurl should do nothing (404)
  • site.co.uk/oldurl should redirect to site.co.uk/newurl

Actual:

  • both site.com/oldurl and site.co.uk/oldurl redirect to /newurl

Problem 3:

Duplicate patterns don't save without any validation errors

  • enter foobar pattern in entry1
  • enter foobar pattern in entry2

Entry is saved with no validation errors, but entry2 will not have saved the redirect data. The silent failing is a problem, as is the underlying requirement that they be unique, as patterns could be the same across different locales but potentially routing to different uris.

Example (both destinations are same entry, with different locale slugs):

  • site.com/oldurlsite.com/newurl
  • site.co.uk/oldurlsite.co.uk/newurl-with-british-slug

On save entry slug changes

When changes a slug of an entry we see it only works without a trailing slash. We think te code in zRetourFieldType.php

if (craft()->config->get('addTrailingSlashesToUrls'))
        {
            $url = rtrim($url, '/') . '/';
        }

Doesnt get excuted when you save an entry. Is this true? If so is it possible to add this?

Option to preserve query strings

As per discussion regarding the change in 1.0.17 to strip query strings before matching URLs, can there be an option to still preserve and re-add that query string after the url has been matched? This is necessary in some instances, for example where the query string needs to be preserved for tracking (ie utm_ params for GA, or gclid params for AdWords) or where a referring site may have added arbitrary params.

Example is...

Legacy URL Pattern: /products/internet
Destination URL: /internet
Incoming URL: /products/internet?utm_source=email&utm_campaign=newsletter-august
Redirected URL: /internet?utm_source=email&utm_campaign=newsletter-august

As you suggested, [x] Preserve Query String could be a default setting, then you could override per entry/static redirect.

SQL Error on Create: "BLOB/TEXT column 'redirectSrcUrl' can't have a default value"

Installation SQL needs to be modified as Blob/text fields cannot have a default value.
https://dev.mysql.com/doc/refman/5.7/en/blob.html

CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1101 BLOB/TEXT column 'redirectSrcUrl' can't have a default value. The SQL statement executed was: CREATE TABLE `craft_retour_redirects` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`associatedElementId` INT(11) NOT NULL,
`redirectSrcUrl` text NULL DEFAULT "",
`redirectSrcUrlParsed` VARCHAR(255) NULL DEFAULT "",
`redirectMatchType` VARCHAR(255) NULL DEFAULT "match",
`redirectDestUrl` VARCHAR(255) NULL DEFAULT "",
`redirectHttpCode` INT(10) NULL DEFAULT 301,
`hitCount` INT(10) NULL DEFAULT 0,
`hitLastTime` datetime NULL DEFAULT "2017-02-13 04:06:53",
`locale` CHAR(12) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`dateCreated` datetime NOT NULL,
`dateUpdated` datetime NOT NULL,
`uid` CHAR(36) NOT NULL DEFAULT 0,
PRIMARY KEY (id)
) ENGINE=InnoDb DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Create deletion event handlers

There are currently no entry deletion event handlers, so redirects do not get removed as they are deleted.

I'll send a PR if I have time.

Retour statistics crashes page

Hi Andrew,

I have an issue when clicking on retour statistics - the page doesn't refresh, it simply hangs trying to process the request, then eventually after 30 seconds or so it displays a 500 error page.

What logs should I check to give you more info?

Thanks for a great plugin.
Adam

'Quick Add' from statistics page not working

The recently-added feature of being able to add a redirect straight from a 404 off the statistics list doesn't seem to work for me - it just reloads the same page with the destination url field empty again. (If i add it via the new static redirect process instead, it works.) (also, using v1.0.13)

Craft addTrailingSlashesToUrls config setting is ignored for internal redirectDestUrl

The addTrailingSlashesToUrls system config setting isn't taken into account when redirecting to local URLs. This is mostly an issue for dynamic entry redirects because the redirectDestUrl is automatically determined by Retour, which doesn't have a trailing slash by default.

What I expected: I have that config item set to true, and I expected Retour's dynamic entry redirects to redirect to a destination URL with a trailing slash.

What happened instead: Retour redirects to a destination URL without a trailing slash.

.htaccess import fails silently

Hi there,

Thanks for your work on Retour - great little plugin for a migration we've just launched today.

We're having a problem importing our .htaccess file which seems to just fail silently. We've tried a few different combinations;

  • .htaccess direct from the source. This includes redirects but also has some other rules included in it
  • the same file, renamed to htaccess.txt. This time though we removed the additional rules

The rules are formatted like this:

RewriteRule ^about-us$ /about-us/our-people [R=301,L]
RewriteRule ^our-mission$ /what-we-do/our-mission [R=301,L]

We can't see any errors in the Craft logs, or our server logs. Are we doing something wrong, or could there be an issue with the plugin?

Any guidance would be much appreciated – thank you.

Undefined index notices on 404s

I had a PR I thought quickly fixed this...but it seems it broke something else, so I'm just posting this issue for now.

( ! ) Notice: Undefined index: redirectMatchType in /Users/timkelty/Sites/paddling/craft/plugins/retour/services/RetourService.php on line 176

( ! ) Notice: Undefined index: redirectMatchType in /Users/timkelty/Sites/paddling/craft/plugins/retour/services/RetourService.php on line 214

[bug report] 'referrerUrl' doesn't have a default value

On Retour 1.0.14 / MySQL 5.7.10 , if a user directly hits a URL that 404s(ie with no referrer set) the following error is thrown:

CDbException

CDbCommand failed to execute the SQL statement: SQLSTATE[HY000]: General error: 1364 Field 'referrerUrl' doesn't have a default value. The SQL statement executed was: INSERT INTO `craft_retour_stats` (`redirectSrcUrl`, `hitCount`, `hitLastTime`, `handledByRetour`, `uid`, `dateUpdated`, `dateCreated`) VALUES (:yp0, :yp1, :yp2, :yp3, :yp4, :yp5, :yp6). Bound with :yp0='/dfg', :yp1=1, :yp2='2016-07-11 10:04:00', :yp3=0, :yp4='dc7bd1b0-9fb8-45ca-b588-a77d69902eaa', :yp5='2016-07-11 10:04:00', :yp6='2016-07-11 10:04:00' (/home/vagrant/code/craft/app/framework/db/CDbCommand.php:358)

#0 /home/vagrant/code/craft/app/framework/db/ar/CActiveRecord.php(1081): CDbCommand->execute()
#1 /home/vagrant/code/craft/app/framework/db/ar/CActiveRecord.php(810): CActiveRecord->insert(NULL)
#2 /home/vagrant/code/plugins/retour/services/RetourService.php(333): CActiveRecord->save()
#3 /home/vagrant/code/plugins/retour/RetourPlugin.php(51): Craft\RetourService->incrementStatistics('/dfg', 0)
#4 /home/vagrant/code/craft/app/framework/base/CComponent.php(567): Craft\RetourPlugin->Craft\{closure}(Object(CExceptionEvent))
#5 /home/vagrant/code/craft/app/framework/base/CApplication.php(874): CComponent->raiseEvent('onexception', Object(CExceptionEvent))
#6 /home/vagrant/code/craft/app/framework/base/CApplication.php(745): CApplication->onException(Object(CExceptionEvent))
#7 [internal function]: CApplication->handleException(Object(Craft\HttpException))
#8 {main}

Umlaut issue

The plugin won't recognise legacy URL patterns if they contain Umlauts so that the default 404 page will be displayed instead of the redirect.

Statistics Filter

Is it possible to filter the statistics of retour?

The amount of Wordpress crawling is insane.

Remove individual statistics

Would be useful to remove individual statistics, this would benefit developers who are testing something on the live but then don’t want a client who also looks at the statistics and get confused.

Fieldtype registering new redirect on empty field

Since updating to v1.0.8, if I edit an existing entry, and don't enter anything in the url pattern field, it still saves a new dynamic redirect with an empty pattern. This means that when I edit another entry and the same thing happens, it errors because a url pattern '' already exists in the database, and won't save the entry. Error is as follows:
Internal Server Error CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'craft_retour_redirects_redirectSrcUrlParsed_unq_idx']

URL for 410 errors

Referring to this ticket

As far as I understand the redirect field doesn't work when using the 410 error code.

I have a lot of invalid image assets so I thought about creating an image which states "this resource is no longer available" and adding this image as a redirect path.

Would this be possible?

Retour only shows the first 100 static redirects in CP view

Note that by this I don't mean that it shows the first 100 redirects by default. I mean that it only shows the first 100 redirects, even after I try to page through them all. The interface implies that it's loading all existing redirects, but it stops at 100.

I suspect this was done for performance reasons, which is understandable, but a better route to take would be to lazy load them in the interface.

As always, thank you for your work on this!

Exact match pattern match not working with Retour field

The exact pattern match doesn't appear to be working with the Retour Fields I'm setting up. I've added the field to the section and gone into Settings > Sections > [section] and clicked save. I've also manually saved a few entries just to be safe.

I've successfully tested a static redirect, so I know at a base level the plugin is working.

Here's a screen shot of the corresponding retour field config (I've imported the entries using Feed Me, so the slugs should definitely trigger match):
retour-field

Here's the field in one of the tested entries.
retour-field-entry

Here's a grab of the Retour Redirects page.
retour-redirects

And here's the Statistics page.
retour-stats

The site is running Craft 2.6.2798 and Retour 1.0.15.

I'm guessing this is a user error on my part, but I'm not quite sure what I might be missing. Any insight would be much appreciated.

Error on Install

Getting an error trying to install using Craft CMS 2.6.2960. Installing locally using Laravel Valet.

CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1101 BLOB, TEXT, GEOMETRY or JSON column 'redirectSrcUrl' can't have a default value. The SQL statement executed was: CREATE TABLE `craft_retour_redirects` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`associatedElementId` INT(11) NOT NULL,
`redirectSrcUrl` text NULL DEFAULT "",
`redirectSrcUrlParsed` VARCHAR(255) NULL DEFAULT "",
`redirectMatchType` VARCHAR(255) NULL DEFAULT "match",
`redirectDestUrl` VARCHAR(255) NULL DEFAULT "",
`redirectHttpCode` INT(10) NULL DEFAULT 301,
`hitCount` INT(10) NULL DEFAULT 0,
`hitLastTime` datetime NULL DEFAULT "2017-02-05 03:22:55",
`locale` CHAR(12) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`dateCreated` datetime NOT NULL,
`dateUpdated` datetime NOT NULL,
`uid` CHAR(36) NOT NULL DEFAULT 0,
PRIMARY KEY (id)
) ENGINE=InnoDb DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Records with empty redirectSrcUrlParsed being created

I'm still seeing this issue with the latest version, so the check must need to be somewhere else as well.
#35

Example:

{% if object.legacyId %}/buyersguide/accessories/showProduct.html.*prodID={legacyId}{% endif %}

Is resulting in an empty redirectSrcUrlParsed, and therefore all my 404s go to this entry.

I'm not quite sure how those rows are getting created, as I can't recreate it if I delete that row and re-save the entry...

CDbException error on installation

When I click the Install button in Craft Admin -> Plugins on our staging server, I'm getting a CDbException error. It worked fine on my local environment (running MAMP with PHP 5.6.10 and Apache), but our staging on Digital Ocean (via Forge) is running PHP 7.1 and Nginx.

(I know, I know, we're in the process of moving to Vagrant to help troubleshoot these kinds of things! :) )

Here is the error on our staging server (URL has been redacted, apologies for the formatting):

CDbException

CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1101 BLOB, TEXT, GEOMETRY or JSON column 'redirectSrcUrl' can't have a default value. The SQL statement executed was: CREATE TABLE `craft_retour_redirects` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`associatedElementId` INT(11) NOT NULL,
`redirectSrcUrl` text NULL DEFAULT "",
`redirectSrcUrlParsed` VARCHAR(255) NULL DEFAULT "",
`redirectMatchType` VARCHAR(255) NULL DEFAULT "match",
`redirectDestUrl` VARCHAR(255) NULL DEFAULT "",
`redirectHttpCode` INT(10) NULL DEFAULT 301,
`hitCount` INT(10) NULL DEFAULT 0,
`hitLastTime` datetime NULL DEFAULT "2017-01-30 16:30:40",
`locale` CHAR(12) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`dateCreated` datetime NOT NULL,
`dateUpdated` datetime NOT NULL,
`uid` CHAR(36) NOT NULL DEFAULT 0,
PRIMARY KEY (id)
) ENGINE=InnoDb DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

/home/forge/[oursiteURL]/craft/app/framework/db/CDbCommand.php(358)

346         {
347             if($this->_connection->enableProfiling)
348                 Yii::endProfile('system.db.CDbCommand.execute('.$this->getText().$par.')','system.db.CDbCommand.execute');
349 
350             $errorInfo=$e instanceof PDOException ? $e->errorInfo : null;
351             $message=$e->getMessage();
352             Yii::log(Yii::t('yii','CDbCommand::execute() failed: {error}. The SQL statement executed was: {sql}.',
353                 array('{error}'=>$message, '{sql}'=>$this->getText().$par)),CLogger::LEVEL_ERROR,'system.db.CDbCommand');
354 
355             if(YII_DEBUG)
356                 $message.='. The SQL statement executed was: '.$this->getText().$par;
357 
358             throw new CDbException(Yii::t('yii','CDbCommand failed to execute the SQL statement: {error}',
359                 array('{error}'=>$message)),(int)$e->getCode(),$errorInfo);
360         }
361     }
362 
363     /**
364      * Executes the SQL statement and returns query result.
365      * This method is for executing an SQL query that returns result set.
366      * @param array $params input parameters (name=>value) for the SQL execution. This is an alternative
367      * to {@link bindParam} and {@link bindValue}. If you have multiple input parameters, passing
368      * them in this way can improve the performance. Note that if you pass parameters in this way,
369      * you cannot bind parameters or values using {@link bindParam} or {@link bindValue}, and vice versa.
370      * Please also note that all values are treated as strings in this case, if you need them to be handled as
Stack Trace
#0  
+  /home/forge/[oursiteURL]/craft/app/framework/db/CDbCommand.php(1352): CDbCommand->execute()
#1  
–  /home/forge/[oursiteURL]/craft/app/etc/db/DbCommand.php(507): CDbCommand->createTable("craft_retour_redirects", array("id" => "pk", "associatedElementId" => "INT(11) NOT NULL", "redirectSrcUrl" => "text NULL DEFAULT """, "redirectSrcUrlParsed" => "VARCHAR(255) NULL DEFAULT """, ...), null)
502         {
503             $columns[$col] = DbHelper::generateColumnDefinition($settings);
504         }
505 
506         // Create the table
507         return parent::createTable($table, $columns, $options);
508     }
509 
510     /**
511      * @param $table
512      * @param $newName
#2  
–  /home/forge/[oursiteURL]/craft/app/records/BaseRecord.php(301): Craft\DbCommand->createTable("craft_retour_redirects", array("id" => "pk", "associatedElementId" => "INT(11) NOT NULL", "redirectSrcUrl" => "text NULL DEFAULT """, "redirectSrcUrlParsed" => "VARCHAR(255) NULL DEFAULT """, ...), null, true)
296                 $addIdColumn = false;
297             }
298         }
299 
300         // Create the table
301         craft()->db->createCommand()->createTable($table, $columns, null, $addIdColumn);
302 
303         // Create the indexes
304         foreach ($indexes as $index)
305         {
306             $columns = ArrayHelper::stringToArray($index['columns']);
#3  
–  /home/forge/[oursiteURL]/craft/app/etc/plugins/BasePlugin.php(160): Craft\BaseRecord->createTable()
155         $records = $this->getRecords('install');
156 
157         // Create all tables first
158         foreach ($records as $record)
159         {
160             $record->createTable();
161         }
162 
163         // Then add the foreign keys
164         foreach ($records as $record)
165         {
#4  
+  /home/forge/[oursiteURL]/craft/app/services/PluginsService.php(411): Craft\BasePlugin->createTables()
#5  
+  /home/forge/[oursiteURL]/craft/app/controllers/PluginsController.php(44): Craft\PluginsService->installPlugin("Retour")
#6  
+  /home/forge/[oursiteURL]/craft/app/framework/web/actions/CInlineAction.php(49): Craft\PluginsController->actionInstallPlugin()
#7  
+  /home/forge/[oursiteURL]/craft/app/framework/web/CController.php(308): CInlineAction->runWithParams(array())
#8  
+  /home/forge/[oursiteURL]/craft/app/framework/web/CController.php(286): CController->runAction(CInlineAction)
#9  
+  /home/forge/[oursiteURL]/craft/app/framework/web/CController.php(265): CController->runActionWithFilters(CInlineAction, array())
#10 
+  /home/forge/[oursiteURL]/craft/app/framework/web/CWebApplication.php(282): CController->run("installPlugin")
#11 
+  /home/forge/[oursiteURL]/craft/app/etc/web/WebApp.php(817): CWebApplication->runController("plugins/installPlugin")
#12 
+  /home/forge/[oursiteURL]/craft/app/etc/web/WebApp.php(287): Craft\WebApp->_processActionRequest()
#13 
+  /home/forge/[oursiteURL]/craft/app/framework/base/CApplication.php(185): Craft\WebApp->processRequest()
#14 
+  /home/forge/[oursiteURL]/craft/app/index.php(62): CApplication->run()
#15 
+  /home/forge/[oursiteURL]/content/index.php(19): require_once("/home/forge/[oursiteURL]/craft/app/index.php")
2017-01-30 16:30:40 nginx/1.11.5 / Craft CMS 2.6.2958

RegEx pattern match not working with Retour field

Initially I noticed this when I was using FeedMe to import and having a default RegEx pattern to match.

My pattern was as follows: \/editorial\/(.*)\/(.*)\/{slug}$. This passes RegEx validation.

Only one row is ever inserted into craft_retour_redirects for that pattern. It really doesn't matter what the pattern is, only one row is ever inserted.

If I switch from RegEx to Exact Match, rows get inserted and redirects work fine.

I also tried to add in entries manually with the same issue.

Fatal error on Entry save

Hello,

I've installed Retour (1.0.15) but haven't configured anything in it yet. When I go to save an Entry, this error is shown:

Fatal error: Using $this when not in object context in /var/www/html/craft/plugins/retour/RetourPlugin.php on line 88

If I disable the plugin, everything works fine. This may be an issue with my setup but I did want to bring it up here just in case.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.