CUSTOM PERMALINK example and BUG in permalink plugin 1.09

By kitsguru - December 6, 2020 - edited: December 6, 2020

In response to: https://www.interactivetools.com/forum/forum-posts.php?postNum=2243305#post2243305

I let the previous post slide as I had no immediate need for it. However I now had time to revisit it and discovered a minor bug in the permalink plugin 1.09 that prevented me from using it. I was trying to have a permalink that looked like

prefix/yyyy-mm-dd/title

The following is the code I used based on the feedback from Daniel.

function permalink_custom_permalinks($tableName, $isNewRecord, $oldRecord)
{
    $schema = loadSchema($tableName);
    $prefix = @$schema['permalink']['defaultValue'];

    // create permalink for events anytime record is saved
    if ($tableName === 'events') {
        $date = date("Y-m-d", strtotime(@$_REQUEST['start_date']));
        $_REQUEST['permalink'] = $prefix . $date . '/' . @$_REQUEST['title']; // create a permalink in the format prefix/yyyy-mm-dd/title

        // trigger_error($_REQUEST['permalink']);
        $_REQUEST['permalink'] = _permalink_generate_formatInputText($_REQUEST['permalink']);
        // trigger_error($_REQUEST['permalink']);
    }
}

The first trigger it looked good but the date was wrong, 'event/1969-12-31/mytitle'

The second trigger, the permalink had the / removed 'event1969-12-31mytitle' and generated an error.

So l looked into the plugin _permalink_generate_formatInputText function. In the permalink 1.09 plugin the line (around 168) that removes all non-alphanumber characters was removing the /

$permalinkText = preg_replace('/[^a-z0-9\-\.\_]+/i', '', $permalinkText);  // remove non-alphanumeric chars

I changed it to exclude the / by adding \/ to the end of the expression:

$permalinkText = preg_replace('/[^a-z0-9\-\.\_\/]+/i', '', $permalinkText);  // remove non-alphanumeric chars

and that part works fine now.

EXCEPT you now need to deal with possible double //, so added this line below "collapse multiple dashes":

$permalinkText = preg_replace("/\/+/", '/', $permalinkText); // JAS collapse multiple slashes

The start_date is composed of multiple parts and assembled upon save. Since the permalink is a pre-save action, you need to use the components. Here is the final version of my function:

/**
 * Creates custom permalinks for the permalinks plugin
 *
 * @param  [string] $tableName
 * @param  [boolean] $isNewRecord - is this a new record
 * @param  [int] $oldRecord   record number
 * @return void
 */
function permalink_custom_permalinks($tableName, $isNewRecord, $oldRecord)
{
    $schema = loadSchema($tableName);
    $prefix = @$schema['permalink']['defaultValue'];

    // create permalink for events anytime record is saved
    if ($tableName === 'events') {
        // when using the datepicker, the startdate is composed of multiple parts
        $date = @$_REQUEST['start_date:year'] 
                . '-' . str_pad(@$_REQUEST['start_date:mon'], 2, "0", STR_PAD_LEFT) 
                . '-' . str_pad(@$_REQUEST['start_date:day'], 2, "0", STR_PAD_LEFT);
        // build the permalink
        $_REQUEST['permalink'] = $prefix . $date . '/' . @$_REQUEST['title'];
        // format it 
        $_REQUEST['permalink'] = _permalink_generate_formatInputText($_REQUEST['permalink']);
    }
}

The output for the permalink is now the desired format: "event/2020-12-06/title". However this lead to another issue in that you could not override this so instead of looking at oldRecord as originally insteaded by the sample function, I decided to look at the permalink itself. If the permalink is empty then generate accordingly, if not empty then leave as is.

if ($tableName === 'events' && empty(@$_REQUEST['permalink'])) {
...
}
Jeff Shields

By Jenna - January 27, 2021

Hi Jeff,

I just noticed this post hasn't gotten a reply. Is this still an ongoing issue for you?

Please let me know. I'd like to help you find a solution if you still need help.

Jenna Cooke - PHP Programmer
interactivetools.com

By kitsguru - January 27, 2021

yes, I have patched my permalink plugin as indicated, but it needs to be rolled into the official version.

Jeff Shields