Mugo Web main content.

Version history limit in eZ Publish 5

By: Thiago Campos Viana | August 8, 2014 | eZ Publish development tips and ez publish 5

Whenever you edit content in the eZ Publish Administration Interface, eZ Publish stores a new version. eZ Publish has a built-in feature to limit the number of previous versions it stores. However, as of the time of this posting, the eZ Publish 5.x public API to create and update content does not respect the version history limit (which, by default, stores 10 previous versions). We've written a quick function that restores this feature.

If you use the eZ Publish 5.x public API to update content with a script, you will end up with an unlimited number of versions. Storing previous versions you an audit log, enables you to revert to previous versions, and more. Due to storage limits and performance considerations, you don't necessarily want to store all previous versions forever.

The function below is based on the script in ezpublish_legacy/bin/php/cleanupversions.php and makes use of the legacy closure feature. Simply call this function after you've run the update and publish functions of the public API and it will handle the removal of older versions.

/**
 * Check and removes versions according to the content version history limit
 * Use this after $contentService->publishVersion($contentDraftUpdated->versionInfo);
 *
 * @param integer $contentId The content ID we are going to clean up versions
 *
 * @return boolean
 */
public function cleanUpVersions( $contentId )
{
    // We are going to call eZ publish legacy code by calling the legacy runCallBack function
    // For Commands
    // $legacyKernelClosure = $this->getContainer()->get( 'ezpublish_legacy.kernel' );
    // $legacyKernel = $legacyKernelClosure();
    // return $legacyKernel->runCallback( ....
    
    // The legacy runCallBack receives two params
    // $legacyKernel->runCallback->runCallback( [all the code], false );
    // the second parameter makes it not re-initialize the kernel every time
    return $this->getLegacyKernel()->runCallback(
        function () use ( $contentId )
        {
            // Get eZ publish DB instance
            $db = \eZDB::instance();
            // Fetch the object by its ID
            $object = \eZContentObject::fetch( $contentId );
            // Get the total number of versions
            $versionCount = $object->getVersionCount();
            // Get the version limit, so this object should have up to this number of versions
            $versionLimit = \eZContentClass::versionHistoryLimit( $object->attribute( 'content_class' ) );

            // Check if the number of versions is lower than the max number of versions
            // If it is lower, we don't need to remove any existing version
            if ( $versionCount <= $versionLimit )
            {
                // Nothing to do on object #{$object->attribute( 'id' )}
                return true;
            }

            // Get the number of versions to remove
            $versionToRemove = $versionCount - $versionLimit;
            // Get the versions that should be removed
            // offset is 0 and limit is the number of versions to remove
            // so we are going to remove all the returned versions
            $versions = $object->versions( true, array(
                'conditions' => array( 'status' => \eZContentObjectVersion::STATUS_ARCHIVED ),
                'sort' => array( 'modified' => 'asc' ),
                'limit' => array( 'limit' => $versionToRemove, 'offset' => 0 ),
            ) );

            // Loop the versions array, removing all versions
            $db->begin();
            foreach( $versions as $version )
            {
                $version->removeThis();
            }
            $db->commit();
            return true;
        }, false
    );
}