public static function create_for_page($page, $author = null, $approvers = null, $notify = true)
 {
     if (!$author && $author !== FALSE) {
         $author = Member::currentUser();
     }
     // take all members from the PublisherGroups relation on this record as a default
     if (!$approvers) {
         $approvers = $page->whoCanApprove();
     }
     // if no publishers are set, the request will end up nowhere
     if (!$approvers->Count()) {
         user_error("No publishers selected", E_USER_ERROR);
         return null;
     }
     if (!self::can_create($author, $page)) {
         user_error("No create permnission for {$author->ID} on {$page->ID}", E_USER_ERROR);
         return null;
     }
     // get or create a publication request
     $request = $page->OpenWorkflowRequest();
     if (!$request || !$request->ID) {
         $request = new WorkflowPublicationRequest();
         $request->PageID = $page->ID;
     }
     // @todo Check for correct workflow class (a "publication" request might be overwritten with a "deletion" request)
     // @todo reassign original author as a reviewer if present
     $request->AuthorID = $author->ID;
     $request->write();
     // assign publishers to this specific request
     foreach ($approvers as $approver) {
         $request->Approvers()->add($approver);
     }
     // open the request and notify interested parties
     $request->Status = 'AwaitingApproval';
     $request->write();
     return $request;
 }
 function testChangesAreTracked()
 {
     $page = $this->objFromFixture('SiteTree', 'custompublisherpage');
     $custompublishersgroup = $this->objFromFixture('Group', 'custompublishergroup');
     $custompublisher = $this->objFromFixture('Member', 'custompublisher');
     $custompublisher->Groups()->add($custompublishersgroup);
     $customauthorsgroup = $this->objFromFixture('Group', 'customauthorsgroup');
     $customauthor = $this->objFromFixture('Member', 'customauthor');
     $customauthor->Groups()->add($customauthorsgroup);
     $page->PublisherGroups()->add($custompublishersgroup);
     $this->session()->inst_set('loggedInAs', $customauthor->ID);
     $page->Content = 'edited';
     $page->write();
     $request = WorkflowPublicationRequest::create_for_page($page);
     $request->request("Please publish this");
     // We need to sleep a little here to let the time tick up a bit
     sleep(1.25);
     $this->assertEquals(1, $request->Changes()->Count(), 'Change has been tracked for initial publication request');
     $page->write();
     $this->assertEquals(1, $request->Changes()->Count(), 'Changes arent tracked twice without a Status change');
     $change = $request->Changes()->First();
     $this->assertEquals($change->AuthorID, $customauthor->ID, "Change has the correct author assigned");
     $this->assertEquals($change->PageDraftVersion, $page->Version, "Change has the correct draft version");
     $this->session()->inst_set('loggedInAs', $custompublisher->ID);
     $page->Content = "third";
     $page->write();
     $page->doPublish();
     $request->flushCache();
     $this->assertEquals(2, $request->Changes()->Count(), 'Change has been tracked for the publication step');
     $change = $request->Changes()->Last();
     $this->assertEquals($change->AuthorID, $custompublisher->ID, "Change has the correct author assigned");
     $this->assertEquals($page->Version, $change->PageLiveVersion, "Change has the corrent draft version");
     $page->doPublish();
     $page->doPublish();
     $page->doPublish();
     $changes = $request->Changes()->toArray();
     $firstChange = $changes[0];
     $secondChange = $changes[1];
     $this->assertTrue($firstChange->NextChange()->ID == $secondChange->ID);
     $this->assertTrue($secondChange->PreviousChange()->ID == $firstChange->ID);
     $this->assertEquals($firstChange->getStatusDescription(), 'Awaiting Approval');
     $this->assertEquals($firstChange->getDiffLinkToLastPublished(), "admin/compareversions/{$page->ID}/?From=2&To=3");
     $this->assertEquals($secondChange->getDiffLinkToLastPublished(), "admin/compareversions/{$page->ID}/?From=3&To=3");
     $this->assertEquals($secondChange->getDiffLinkToOriginalRequest(), "admin/compareversions/{$page->ID}/?From=2&To=3");
     $this->assertEquals($secondChange->getDiffLinkOriginalToLastPublished(), "admin/compareversions/{$page->ID}/?From=3&To=3");
     $this->assertEquals($secondChange->getDiffLinkToPrevious(), "admin/compareversions/{$page->ID}/?From=2&To=3");
     $this->assertEquals($secondChange->getDiffLinkContentToPrevious(), "<a href=\"admin/compareversions/{$page->ID}/?From=2&To=3\" target=\"_blank\" class=\"externallink\">Show</a>");
     $this->session()->inst_set('loggedInAs', null);
 }