Adding Content Locking to Custom Content Types

An ItemWrapper, as described in the Universe Search section, is required to add content locking to custom content types.

Add the following function to the ItemWrapper class file:

/**
* Indicates whether or not the content type has content locking implemented * @return boolean
*/
public function hasContentLocking ()
{
  return true;
}

Content will now be lockable and unlockable via Univers Search, but these locks will not take effect until all relevant scripts have controls implemented to check the lock status. For an example of how to do this, see the following files:

  • public_html/jadu/websections/websection_events_list.php
  • public_html/jadu/websections/websection_events.php

List Level

Content locking can be included at list level to indicate which items are locked before they’re opened. Include the ContentLock Class:

include_once('websections/JaduContentLock.php');

Initialise the datamapper:

$contentTypeDataMapper = new Jadu_ContentType_DataMapper($db, new Jadu_CacheManager());
$contentType = $contentTypeDataMapper->getByTableName(CustomContentType_TABLE);

For each row in the list, the following will output a generic ‘item is locked by User’ message.

print getGenericEditingListHtml(
  $contentType->getPageIDsForType($CustomContentType->id),
  $CustomContentType->id,
  $contentType->id);

Item Level

As standard in Continuum CMS, locked content can not be viewed or changed by anyone but the lock owner, but can be made live/offline by other users.

To add content locking to an item in this way, the following example can be adapted:

Processing stage

Include the class:

require_once('websections/JaduContentLock.php');

For the breadcrumb actions message

if (isset($_GET['contentLocked'])) {
    $statusMessage = "This item has been locked for private editing";
}

if (isset($_GET['lockRelease'])) {
    $statusMessage = "A content lock release request has been sent";
}

Initialise the datamapper:

$contentTypeDataMapper = new Jadu_ContentType_DataMapper($db, new Jadu_CacheManager());
$contentType = $contentTypeDataMapper->getByTableName(CustomContentType_TABLE);

Get any content lock existing for this item:

$contentLock = getContentLockByItem(
    (isset($_GET['CustomContentTypeID']) ? (int) $_GET['CustomContentTypeID'] : -1),
    $contentType->getID());

Get some data to assist the content locking functions (allows a lock to be set on an item of content during the first time it’s saved):

$lockTimeoutDate = formatDateTime(FORMAT_DATE_INPUT, $contentLock->lockTimeout);

or

$lockTimeoutDate = formatDateTime(FORMAT_DATE_INPUT, DEFAULT_CONTENT_LOCK_TIME*60);

or

$lockTimeoutDate = $_POST['newlockTimeoutDate'];

The variable $lockTimeoutTime can be set as above, but using FORMAT_TIME_INPUT instead of FORMAT_DATE_INPUT.

To check for an existing content lock set by a user other than the current:

if ($contentLock->id > -1 && $contentLock->lockedByAdminID != $adminID) {
    // any actions allowed despite lock here
}

When saving an item, validate the content lock first.

$errors = array_merge(
  $errors,
  validateContentLock($_POST['newlockTimeoutDate'],
  $_POST['newlockTimeoutTime']));

If the lock is new or different from that in the database, it must be set during the save routine, otherwise it will be set only in the lock content lightbox.

//if content lock is new
if ($contentLock->id === -1 ||
    $contentLock->lockTimeout != convertDateTimeToTimestamp($_POST['newlockTimeoutDate'].'
     '.$_POST['newlockTimeoutTime'], FORMAT_DATE_INPUT . ' ' .
      FORMAT_TIME_INPUT)) {

  // Delete any old content lock
  deleteContentLock($contentLock->id, $adminID, $admin->adminLevelID);

  // Add the content lock
  $newContentLock = new ContentLock();
  $newContentLock->lockedByAdminID = $adminID;
  $newContentLock->contentItemID = $CustomContentType->id;
  $newContentLock->contentTypeID = $contentType->getID();

  //retrieve the new lock
  $contentLock = getContentLockByItem($CustomContentType->id, $contentType->getID());
}

To remove a content lock (e.g. when submitting an item for approval):

deleteContentLock($contentLock->id, $adminID, $admin->adminLevelID);
$contentLock = getContentLockByItem($event->id, $contentType->getID());

To avoid setting a new content lock on an existing item where one didn’t exist, the default times set above must be invalidated before output

if ($contentLock->id === -1) {
  $lockTimeoutDate = formatDateTime(FORMAT_DATE_INPUT, time());
  $lockTimeoutTime = formatDateTime(FORMAT_TIME_INPUT, time());
}

Output Stage

Hidden fields to enable content locking (required):

<!-- Content Locking Fields -->
<input type="hidden" id="newlockTimeoutDate" name="newlockTimeoutDate"
  value="<?php print $lockTimeoutDate; ?>" />
<input type="hidden" id="newlockTimeoutTime" name="newlockTimeoutTime"
  value="<?php print $lockTimeoutTime; ?>" />

To add links / output to relevant lightboxes when the content is locked, dependent on authority level:

<?php
  if ($admin->adminLevelID === getMostAuthoritativeWorkflowAdminLevel()->id) {
?>
  <div class="not_yet">
    <a title="Unlock this CustomContentType"
      onclick="loadLightbox('content_lock_release_submit', 'lb', 'destination=
      <?php print urlencode("/custom/CustomContentType.php?
      CustomContentTypeID=$CustomContentType->id").
      "&contentLockID=".$contentLock->id; ?>');
      return false;" href="#">Unlock this CustomContentType</a></div>
<?php
  } else {
    $arguments = "contentLockID=" . $contentLock->id;
    $lockContentReleaseLightBox = "loadLightbox('content_lock_release', 'lb', '$arguments');";
?>
  <div class="not_yet">
    If you need this content to be unlocked please
      <a title="alert the webmasters"
      onclick="<?php print $lockContentReleaseLightBox; ?>;
      return false;" href="#">
        alert the webmasters
      </a>
    </div>
<?php
  }
?>

To add lock/unlock links to the Actions button

<?php
  $extraArguments = "";
  if ($CustomContentType>id > -1) {
    $extraArguments = "+'&contentItemID=".$CustomContentType->id.
      "&contentType ID=".$contentType->id."'";
  }

  $lockContentLightBox = "return loadLightbox('content_lock', 'lb',
    'contentLockDateTarget=newlockTimeoutDate&
    contentLockTimeTarget=newlockTimeoutTime&
    existingLockDate='+$('newlockTimeoutDate').value+'&
    existingLockTime='+$('newlockTimeoutTime').value".$extraArguments.");";

  if ($contentLock->id > -1 ||
    ($CustomContentType>id < 1 && DEFAULT_CONTENT_ LOCK_TIME >= 1)) {
?>
  <li>
    <a class="unlock" id="lockText"
      onclick="<?php print $lockContentLightBox; ?>;
      return false;" href="#">
      Unlock
    </a>
  </li>
<?php
  } else {
?>
  <li>
    <a class="lock" id="lockText"
      onclick="<?php print $lockContentLightBox; ?>;
      return false;" href="#">
      Lock
    </a>
  </li>
<?php
  }
?>

For the lock icon (the id enables interaction with the contentLock lightbox)

if ($contentLock->id > -1 || ($CustomContentType->id < 1 && DEFAULT_CONTENT_LOCK_TIME >= 1)) {
  print '<img src="../assets/img/lockedBBBBBB.png" class="unlock" id="lockIcon" />';
} else {
  print '<img src="../assets/img/unlockedBBBBBB.png" class="lock" id="lockIcon" />';
}

Autolocking

Autolocking requires autosave; if autosave has been implemented for this content type, autolocking can be implemented by adapting the following:

Before including head.php:

addJavascript('javacript/who_is_editing.js');

Page specific JavaScript:

// Initialise who_is_editing
var whoIsEditing = new WhoIsEditing('<?php print $autosavePageID; ?>', {
  checkFrequency: '<?php print defined('AUTOSAVE_FREQUENCY') ? AUTOSAVE_FREQUENCY : 15; ?>'
});

Event.observe(window, 'load', function() {
  //run straight away
  whoIsEditing.load();
});

To check if this item should be ‘autoLocked’, find any recent autosaves by another user:

foreach (getRecentAutosavesForPage($autosavePageID) as $recentAutoSave) {
  if ($recentAutoSave->adminID != $admin->id) {
    $otherUserEditingID = $recentAutoSave->adminID;
    break;
  }
}

An example of how core ContentTypes behave for autolocks:

<?php
  if ($otherUserEditingID > -1) {
?>
  <p class="edit_doc">
    <a href="./websection_events_list.php">Back to events list</a>
  </p>
  <div class="not_yet">
    <h3>
    <?php print encodeHtml($CustomContentType>title); ?> is currently being edited by
    <?php print getAdministrator($otherUserEditingID)->name; ?>
    </h3>
  </div>
<?php
  $arguments = "lockedByAdminID=" . $otherUserEditingID .
    "&contentItemID=" . $CustomContentType>id .
    "&contentTypeID=" . $contentType->id;
  $autolockReleaseLightbox = "loadLightbox('autolock_release', 'lb', '$arguments');";
?>
  <div class="not_yet">
    If you need access to this content you can
    <a title="Send message" onclick="
    <?php print $autolockReleaseLightbox; ?>; return false;"
    href="#"> send <?php print getAdministrator($otherUserEditingID)->name; ?> a message
    </a>.
  </div>
<?php
  }
?>

results matching ""

    No results matching ""