Front-End Editing and Permalinks

By Perchpole - August 8, 2014

Hello, All

For the last few weeks I've been working on a way to add and update records through a front-end form. I've overcome a couple of issues along the way  and it seems to be coming together really well.

The only recurring issue is the way CMSB saves records. When you save a record in the back-end editor CMSB does all sorts of magic in the background. When you update though a front-end form, on the other hand, none of that magic seems to happen! This is particularly true in the case of categories.

Thankfully Dave gave me some code which appeared to solve many of the problems:

  // force update of category metadata for sorting (this may need to be updated in a much future version)
  $categoryTablename = 'category';
  $GLOBALS['escapedTableName'] = mysql_escape( $TABLE_PREFIX . $categoryTablename );
  $GLOBALS['schema']           = loadSchema($categoryTablename); // fake currently loaded schema
  if (!$GLOBALS['schema']) { die("Invalid table name '" .htmlencode($categoryTablename). "'"); }
  include_once(SCRIPT_DIR . '/lib/menus/default/common.php'); // load category menu functions 
  updateCategoryMetadata();


This forces things like breadcrumbs and lineage to update when creating a new category through the front-end form.

However, it does not address the bugbear of all my problems: permalinks.

When I add a category through the front-end form the permalinks field does not update automatically. I am required to go into the category via the back-end editor and save it manually. Only then does the permalink field update.

Obviously this defeats the entire purpose of having front-end editing capability!

Is there a fix?

:0/

Perchpole

Hey Perch,

You need to use this function:

permalink_cms_onSaveUpdatePermalinks($tableName, $isNewRecord, $oldRecord, $recordNum);

If you've included the viewer_functions on the saved/edit page, then you should have access to it. 

You'll need to call it after you've updated/saved the record. You'll also need to make sure that the field that contains the permalink is called permalink, as the function will access the value for the permalink using $_REQUEST['permalink'].

Finally, the function needs to be able to access the schema of the section you're editing, it does this using a global called schema. You can create this using the following code:

$GLOBALS['schema']     = loadSchema( $tableName );

The variables for the function are as follows:

  • tableName - The table name that is being to (looks to be category in your example).
  • $isNewRecord - Boolean value for if you're creating or editing a record. True for new, False for old.
  • $oldRecord - An array of the record before it was saved. If this is a new record just pass in an empty array, if it's an old record use the mysql_get function to get an array of the records content before you update the record with the new data.
  • $recordNum - The record num for the record.

Here is some example code that would update a record in a blog section, and update it's permalink as well:

  
  // load viewer library
  $libraryPath = 'cmsAdmin/lib/viewer_functions.php';
  $dirsToCheck = array('C:/wamp/www/','','../','../../','../../../');
  foreach ($dirsToCheck as $dir) { if (@include_once("$dir$libraryPath")) { break; }}
  if (!function_exists('getRecords')) { die("Couldn't load viewer library, check filepath in sourcecode."); }

  //Set page variables
  $_REQUEST['permalink'] = 'test4000';
  $recordNum             = 6;
  $isNewRecord           = false;
  $tableName             = 'blog';
  $GLOBALS['schema']     = loadSchema( $tableName );

  //Get the old record
  $oldRecord = mysql_get($tableName, $recordNum);

  //Update the record
  mysql_update($tableName, $recordNum, null, array('permalink' => $_REQUEST['permalink']));

  //Update the permalinks
  permalink_cms_onSaveUpdatePermalinks($tableName, $isNewRecord, $oldRecord, $recordNum);

Thanks!

Greg

Greg Thomas







PHP Programmer - interactivetools.com

Hey Perch,

I think you might need to set the permalink into the request array, but everything else looks correct.

  $tablename                        = 'pages';
  $recordNum                        = null;
  $where                            = null;
  $colsToValues                     = array(); // these fields get automatically mysql escaped unless you end fieldname with =
  $colsToValues['createdDate=']     = 'NOW()';
  $colsToValues['createdByUserNum'] = @$CURRENT_USER['num'];
  $colsToValues['name']             = 'New Page';
  $colsToValues['permalink']        = "newpage";
  $_REQUEST['permalink']            = $colsToValues['permalink'];
          
  $newRecordNum = mysql_insert($tablename, $colsToValues, true);
          
  $isNewRecord       = true;
  $oldRecord         = array();
  
  $GLOBALS['escapedTableName'] = mysql_escape( $TABLE_PREFIX . $tablename );
  $GLOBALS['schema']           = loadSchema($tablename); // fake currently loaded schema
  if (!$GLOBALS['schema']) { die("Invalid table name '" .htmlencode($tablename). "'"); }
  include_once(SCRIPT_DIR . '/lib/menus/default/common.php'); // load category menu functions 
  
  permalink_cms_onSaveUpdatePermalinks($tableName, $isNewRecord, $oldRecord, $newRecordNum);
  updateCategoryMetadata();

The function pulls the new permalink name directly from the REQUEST array, so we have to fake the POST/GET variable by setting it manually. 

Cheers!

Greg

Greg Thomas







PHP Programmer - interactivetools.com

Thanks, greg - but it still won't run!

The bottom of the code looks like this now...

  ......
  $colsToValues['permalink']        = "newpage";
  $_REQUEST['permalink']            = $colsToValues['permalink'];
 
  $newRecordNum = mysql_insert($tablename, $colsToValues, true);
 
  $isNewRecord = true;
  $oldRecord   = array();
 
  $GLOBALS['escapedTableName'] = mysql_escape( $TABLE_PREFIX . $tablename );
  $GLOBALS['schema']           = loadSchema($tablename); // fake currently loaded schema
  if (!$GLOBALS['schema']) { die("Invalid table name '" .htmlencode($tablename). "'"); }
  include_once(SCRIPT_DIR . '/lib/menus/default/common.php'); // load category menu functions
  updateCategoryMetadata();
 
  mysql_update($tableName, $newRecordNum, null, array('permalink' => $_REQUEST['permalink']));
  permalink_cms_onSaveUpdatePermalinks($tableName, $isNewRecord, $oldRecord, $newRecordNum);

I added the hi-lighted lines - but something isn't right!

:0/

Perch

Hey Perch, 

Are you getting any errors? Or is it generating a 'false positive', where no errors are displayed, but it isn't actually updating the record?

Cheers,

Greg

Greg Thomas







PHP Programmer - interactivetools.com

Greg -

With the permalink_cms_onSaveUpdatePermalinks line in the code it simply will not run.

If the line is removed a new page is added as expected.

:0/

Perch

When I was testing I had a similar issue, which I resolved by enabling the permalinks plugin, have you got the permalinks plugin enabled at the moment?

Cheers,

Greg

Greg Thomas







PHP Programmer - interactivetools.com

Yes!

Greg -

I think I've got it. The script wasn't running because I was providing a default name for the permalink. You can only do this once! If you try again it will reject the name because it already exists in the database.

What I need to do is (in the short term) find a way to append a random value to the end of my given permalink - to make it unique.

I'm creating a new page every time - so what would work best?

new-page_000001

new-page-000002

etc...?

Perch