Source of file TruncateVersionsTask.php
Size: 7,156 Bytes - Last Modified: 2022-01-13T10:00:58+00:00
/var/www/docs.ssmods.com/process/src/src/Tasks/TruncateVersionsTask.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 | <?php namespace Axllent\VersionTruncator\Tasks; use Axllent\VersionTruncator\VersionTruncator; use SilverStripe\CMS\Model\SiteTree; use SilverStripe\Control\Director; use SilverStripe\Core\ClassInfo; use SilverStripe\Dev\BuildTask; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DB; use SilverStripe\ORM\Queries\SQLSelect; use SilverStripe\Versioned\Versioned; /** * Prunes the database of old SiteTree versions & drafts */ class TruncateVersionsTask extends BuildTask { /** * URL segment * * @var string */ private static $segment = 'TruncateVersionsTask'; /** * Task title * * @var string */ protected $title = 'Prune old DataObject versions'; /** * Task description * * @var string */ protected $description = 'Delete old versioned DataObject versions from the database'; /** * Run task * * @param HTTPRequest $request HTTP request * * @return HTTPResponse */ public function run($request) { if (!Director::is_cli()) { print '<h3>Select a task:</h3> <p>You do not normally need to run these tasks, as pruning is run automatically whenever a versioned DataObject is published.</p> <ul> <li> <p> <a href="?prune=1">Prune all</a> - Prune all published versioned DataObjects according to your policies. This is normally not required as pruning is done automatically when any versioned record is published. </p> </li> <li> <p> <a href="?files=1">Prune deleted files</a> - Deleted all versions of deleted files. </p> </li> <li> <p> <a href="?reset=1" onclick="return Confirm()">Reset all</a> - This prunes ALL previous versions for all published versioned DataObjects, keeping only the latest single <strong>published</strong> version.<br /> This deletes all references to old pages, drafts, and previous pages with different URLSegments (redirects). Unpublished DataObjects, including those that have drafts are not modified. </p> </li> </ul> <script type="text/javascript"> function Confirm(q) { var question = "WARNING: Please confirm you wish to delete ALL historical " + "versions for all versioned DataObjects?"; if (confirm(question)) { return true; } return false; } </script> '; } $reset = $request->getVar('reset'); $prune = $request->getVar('prune'); $files = $request->getVar('files'); if ($reset) { $this->_reset(); } elseif ($prune) { $this->_prune(); } elseif ($files) { $this->_pruneDeletedFileVersions(); } } /** * Prune all published DataObjects which are published according to config * * @return void */ private function _prune() { $classes = $this->_getAllVersionedDataClasses(); DB::alteration_message('Pruning all DataObjects'); $total = 0; foreach ($classes as $class) { $records = Versioned::get_by_stage($class, Versioned::DRAFT); $deleted = 0; foreach ($records as $r) { if ($r->isLiveVersion()) { $deleted += $r->doVersionCleanup(); } } if ($deleted > 0) { DB::alteration_message( 'Deleted ' . $deleted . ' versioned ' . $class . ' records' ); $total += $deleted; } } DB::alteration_message('Completed, pruned ' . $total . ' records'); } /** * Prune versions of deleted files/folders * * @return HTTPResponse */ private function _pruneDeletedFileVersions() { DB::alteration_message('Pruning all deleted File DataObjects'); $query = new SQLSelect(); $query->setSelect(['RecordID']); $query->setFrom('File_Versions'); $query->addWhere( [ '"WasDeleted" = ?' => 1, ] ); $to_delete = []; $results = $query->execute(); foreach ($results as $result) { array_push($to_delete, $result['RecordID']); } if (!count($to_delete)) { DB::alteration_message('Completed, pruned 0 File records'); return; } $deleteSQL = sprintf( 'DELETE FROM File_Versions WHERE "RecordID" IN (%s)', implode(',', $to_delete) ); DB::query($deleteSQL); $deleted = DB::affected_rows(); DB::alteration_message('Completed, pruned ' . $deleted . ' File records'); } /** * Delete all previous records of published records * * @return HTTPResponse */ private function _reset() { DB::alteration_message('Pruning all published records'); $classes = $this->_getAllVersionedDataClasses(); $total = 0; foreach ($classes as $class) { $records = Versioned::get_by_stage($class, Versioned::DRAFT); $deleted = 0; // set to minimum $class::config()->set('keep_versions', 1); $class::config()->set('keep_drafts', 0); $class::config()->set('keep_redirects', false); foreach ($records as $r) { if ($r->isLiveVersion()) { $deleted += $r->doVersionCleanup(); } } if ($deleted > 0) { DB::alteration_message( 'Deleted ' . $deleted . ' versioned ' . $class . ' records' ); $total += $deleted; } } DB::alteration_message('Completed, pruned ' . $total . ' records'); $this->_pruneDeletedFileVersions(); } /** * Get all versioned database classes * * @return array */ private function _getAllVersionedDataClasses() { $all_classes = ClassInfo::subclassesFor(DataObject::class); $versioned_classes = []; foreach ($all_classes as $c) { if (DataObject::has_extension($c, Versioned::class)) { array_push($versioned_classes, $c); } } return array_reverse($versioned_classes); } } |