예제 #1
0
파일: Ozone.php 프로젝트: jbzdak/wikidot
 public static function init()
 {
     // create db connection
     // see if tmp directories exist - and create if not
     $dir = PathManager::smartyCompileDir();
     if (!file_exists($dir)) {
         mkdirfull($dir);
     }
     $dir = PathManager::smartyCacheDir();
     if (!file_exists($dir)) {
         mkdirfull($dir);
     }
     $dir = PathManager::smartyMacroTemplateDir();
     if (!file_exists($dir)) {
         mkdirfull($dir);
     }
     // connect to memcache server
     if (GlobalProperties::$USE_MEMCACHE == true) {
         self::$memcache = new Memcache();
         self::$memcache->connect(GlobalProperties::$MEMCACHE_HOST, GlobalProperties::$MEMCACHE_PORT);
         self::$memcache->setCompressThreshold(5000);
     } else {
         self::$memcache = new DummyMemcache();
     }
 }
예제 #2
0
 /**
  *
  * Renders a token into text matching the requested format.
  *
  * @access public
  *
  * @param array $options The "options" portion of the token (second
  * element).
  *
  * @return string The text rendered from the token options.
  *
  */
 function token($options)
 {
     $content = $options['content'];
     $hashcode = md5($content);
     $runData = Ozone::getRunData();
     $site = $runData->getTemp('site');
     $dir = $site->getLocalFilesPath() . '/math/inline';
     if (!file_exists($dir)) {
         mkdirfull($dir);
     }
     $tmpDir = WIKIDOT_ROOT . '/tmp/math';
     if (!file_exists($tmpDir)) {
         mkdirfull($tmpDir);
     }
     $imgFile = $hashcode . '.png';
     if (!file_exists($dir . '/' . $imgFile)) {
         $renderer = new LatexRenderer();
         $renderer->setTmpDir($tmpDir);
         $renderer->setOutputDir($dir);
         $renderer->setDensity(110);
         $content2 = '$' . $content . '$';
         $renderer->render($content2, $hashcode);
     }
     if (!file_exists($dir . '/' . $imgFile)) {
         return '<span class="error-inline">' . _('The equation has not been processed correctly. Most prabably it has syntax error(s).') . '	</span>';
     }
     $out = '<img class="math-inline" src="/local--math/inline/' . $imgFile . '" alt="' . htmlentities($content) . '" />';
     return $out;
     $content = $options['content'];
     $hashcode = md5($content);
     $runData = Ozone::getRunData();
     $site = $runData->getTemp('site');
     $dir = $site->getLocalFilesPath() . '/math/inline';
     if (!file_exists($dir)) {
         mkdirfull($dir);
     }
     $imgFile = $hashcode . '.png';
     $imgFile = $hashcode . '.png';
     $out = '<img src="http://' . $site->getDomain() . '/local--math/inline/' . $imgFile . '" alt="' . htmlentities($content) . '" />';
     return $out;
 }
예제 #3
0
파일: Math.php 프로젝트: jbzdak/wikidot
 /**
  *
  * Renders a token into text matching the requested format.
  *
  * @access public
  *
  * @param array $options The "options" portion of the token (second
  * element).
  *
  * @return string The text rendered from the token options.
  *
  */
 function token($options)
 {
     $content = $options['content'];
     $type = $options['type'];
     $hashcode = md5($content . '..' . $type);
     $runData = Ozone::getRunData();
     $site = $runData->getTemp('site');
     $dir = $site->getLocalFilesPath() . '/math/eqs';
     if (!file_exists($dir)) {
         mkdirfull($dir);
     }
     $tmpDir = WIKIDOT_ROOT . '/tmp/math';
     if (!file_exists($tmpDir)) {
         mkdirfull($tmpDir);
     }
     $imgFile = $hashcode . '.png';
     if (!file_exists($dir . '/' . $imgFile)) {
         $renderer = new LatexRenderer();
         $renderer->setTmpDir($tmpDir);
         $renderer->setOutputDir($dir);
         if ($type == 'eqnarray') {
             $content2 = "\\begin{eqnarray*}\n" . $content . "\n\\end{eqnarray*}";
         } else {
             $content2 = "\\begin{equation*}\n" . $content . "\n\\end{equation}";
         }
         $renderer->render($content2, $hashcode);
     }
     if (!file_exists($dir . '/' . $imgFile)) {
         return '<div class="error-block">' . _('The equation has not been processed correctly. Most prabably it has syntax error(s).') . '</div>';
     }
     $label = $options['label'];
     $idPrefix = $this->getConf("id_prefix");
     $idString = ' id="equation-' . $idPrefix . $options['id'] . '" ';
     $equationNumberLabel = '<span class="equation-number">(' . $options['id'] . ')</span>';
     $out = '<div class="math-equation"' . $idString . '><img src="/local--math/eqs/' . $imgFile . '" alt="' . htmlentities($content) . '" /></div>';
     return $equationNumberLabel . $out;
 }
예제 #4
0
 public function restoreSiteEvent($runData)
 {
     $pl = $runData->getParameterList();
     $siteId = $pl->getParameterValue('siteId');
     $unixName = trim($pl->getParameterValue('unixName'));
     $c = new Criteria();
     $c->add('site_id', $siteId);
     $c->add('deleted', true);
     $site = DB_SitePeer::instance()->selectOne($c);
     if (!$site) {
         throw new ProcessException(_('Error selecting a site to restore.'));
     }
     // check if allowed
     $user = $runData->getUser();
     $c = new Criteria();
     $c->add("user_id", $user->getUserId());
     $c->add("site_id", $site->getSiteId());
     $c->add("founder", true);
     $rel = DB_AdminPeer::instance()->selectOne($c);
     if (!$rel) {
         throw new ProcessException(_("Sorry, you have no permissions to restore this site."));
     }
     $db = Database::connection();
     $db->begin();
     // validate unix name
     $errors = array();
     if ($unixName === null || strlen($unixName) < 3 || strlen(WDStringUtils::toUnixName($unixName)) < 3) {
         $errors['unixname'] = _("Web address must be present and should be at least 3 characters long.");
     } elseif (strlen($unixName) > 30) {
         $errors['unixname'] = _("Web address name should not be longer than 30 characters.");
     } elseif (preg_match("/^[a-z0-9\\-]+\$/", $unixName) == 0) {
         $errors['unixname'] = _('Only lowercase alphanumeric and "-" (dash) characters allowed in the web address.');
     } elseif (preg_match("/\\-\\-/", $unixName) !== 0) {
         $errors['unixname'] = _('Only lowercase alphanumeric and "-" (dash) characters allowed in the web address. Double-dash (--) is not allowed.');
     } else {
         $unixName = WDStringUtils::toUnixName($unixName);
         if (!$runData->getUser()->getSuperAdmin()) {
             //	handle forbidden names
             $forbiddenUnixNames = explode("\n", file_get_contents(WIKIDOT_ROOT . '/conf/forbidden_site_names.conf'));
             foreach ($forbiddenUnixNames as $f) {
                 if (preg_match($f, $unixName) > 0) {
                     $errors['unixname'] = _('For some reason this web address is not allowed or is reserved for future use.');
                 }
             }
         }
         // check if the domain is not taken.
         $c = new Criteria();
         $c->add("unix_name", $unixName);
         $ss = DB_SitePeer::instance()->selectOne($c);
         if ($ss) {
             $errors['unixname'] = _('Sorry, this web address is already used by another site.');
         }
     }
     if (isset($errors['unixname'])) {
         throw new ProcessException($errors['unixname']);
     }
     $oldUnixName = $site->getUnixName();
     $oldLocalPath = $site->getLocalFilesPath();
     $site->setUnixName($unixName);
     // 	rename the files
     mkdirfull(dirname($site->getLocalFilesPath()));
     @rename($oldLocalPath, $site->getLocalFilesPath());
     $site->setDeleted(false);
     $site->setCustomDomain(null);
     $site->save();
     $db->commit();
     $runData->ajaxResponseAdd('unixName', $site->getUnixName());
 }
예제 #5
0
 public function createSiteEvent($runData)
 {
     WDPermissionManager::instance()->canBecomeAdmin($runData->getUser());
     $pl = $runData->getParameterList();
     $name = trim($pl->getParameterValue("name"));
     $unixName = trim($pl->getParameterValue("unixname"));
     $tagline = trim($pl->getParameterValue("tagline"));
     $templateId = $pl->getParameterValue("template");
     $private = (bool) $pl->getParameterValue("private");
     // validate form data:
     $errors = array();
     if (strlen($name) < 1) {
         $errors['name'] = _("Site name must be present.");
     } elseif (strlen8($name) > 30) {
         $errors['name'] = _("Site name should not be longer than 30 characters.");
     }
     // site unix name *************
     if ($unixName === null || strlen($unixName) < 3) {
         $errors['unixname'] = _("Web address must be present and should be at least 3 characters long.");
     } elseif (strlen($unixName) > 30) {
         $errors['unixname'] = _("Web address name should not be longer than 30 characters.");
     } elseif (preg_match("/^[a-z0-9\\-]+\$/", $unixName) == 0) {
         $errors['unixname'] = _('Only lowercase alphanumeric and "-" (dash) characters allowed in the web address.');
     } elseif (preg_match("/\\-\\-/", $unixName) !== 0) {
         $errors['unixname'] = _('Only lowercase alphanumeric and "-" (dash) characters allowed in the web address. Double-dash (--) is not allowed.');
     } else {
         $unixName = WDStringUtils::toUnixName($unixName);
         if (!$runData->getUser()->getSuperAdmin()) {
             //	handle forbidden names
             $forbiddenUnixNames = explode("\n", file_get_contents(WIKIDOT_ROOT . '/conf/forbidden_site_names.conf'));
             foreach ($forbiddenUnixNames as $f) {
                 if (preg_match($f, $unixName) > 0) {
                     $errors['unixname'] = _('For some reason this web address is not allowed or is reserved for future use.');
                 }
             }
         }
         // check if the domain is not taken.
         $c = new Criteria();
         $c->add("unix_name", $unixName);
         $ss = DB_SitePeer::instance()->selectOne($c);
         if ($ss) {
             $errors['unixname'] = _('Sorry, this web address is already used by another site.');
         }
     }
     // template
     if (!$templateId) {
         $errors['template'] = _('Please choose a template for your site');
     }
     if (strlen8($tagline) > 50) {
         $errors['tagline'] = _("Tagline should not be longer than 50 characters");
     }
     // TOS
     if (!$pl->getParameterValue("tos")) {
         $errors['tos'] = _("Please read and agree to the Terms of Service.");
     }
     if (count($errors) > 0) {
         $runData->ajaxResponseAdd("formErrors", $errors);
         throw new ProcessException("Form errors", "form_errors");
     }
     // and now... CREATE THE SITE!!!!!!!!!!!!!!!!
     $dup = new Duplicator();
     $dup->setOwner($runData->getUser());
     $db = Database::connection();
     $db->begin();
     $templateSite = DB_SitePeer::instance()->selectByPrimaryKey($templateId);
     if (!preg_match(';^template\\-;', $templateSite->getUnixName())) {
         throw new ProcessException('Error');
     }
     $site = new DB_Site();
     $site->setName($name);
     $site->setSubtitle($tagline);
     $site->setUnixName($unixName);
     $site->setLanguage($templateSite->getLanguage());
     $site->setDateCreated(new ODate());
     $site->setPrivate($private);
     if ($private) {
         // change file flag too
         $flagDir = WIKIDOT_ROOT . '/web/files--sites/' . $site->getUnixName() . '/flags';
         $flagFile = $flagDir . '/private';
         mkdirfull($flagDir);
         //just to make sure
         if (!file_exists($flagFile)) {
             file_put_contents($flagFile, "private");
         }
     }
     $site->save();
     $dup->addExcludedCategory("forum");
     // should be initialized independently
     $dup->addExcludedCategory("profile");
     $dup->duplicateSite($templateSite, $site);
     // index the site too
     $ind = Indexer::instance();
     $c = new Criteria();
     $c->add("site_id", $site->getSiteId());
     $pages = DB_PagePeer::instance()->select($c);
     foreach ($pages as $p) {
         $ind->indexPage($p);
     }
     $db->commit();
     // clear captcha code
     $runData->sessionDel("captchaCode");
     $runData->ajaxResponseAdd("siteUnixName", $unixName);
 }
예제 #6
0
파일: Backuper.php 프로젝트: jbzdak/wikidot
 public function backup()
 {
     $site = DB_SitePeer::instance()->selectByPrimaryKey($this->siteId);
     if (!$site) {
         throw new ProcessException(_("Site can not be found"));
     }
     // prepare working directory
     $wdir = WIKIDOT_ROOT . '/tmp/sitebackups/' . $site->getUnixName() . '/work';
     @exec('rm -r ' . $wdir . ' &> /dev/null');
     mkdirfull($wdir);
     if ($this->backupSource) {
         mkdirfull($wdir . '/source');
         // iterate through pages
         $c = new Criteria();
         $c->add("site_id", $site->getSiteId());
         $pages = DB_PagePeer::instance()->select($c);
         foreach ($pages as $page) {
             $source = $page->getCurrentRevision()->getSourceText();
             $filename = $page->getUnixName() . '.txt';
             $filename = str_replace(':', '_', $filename);
             file_put_contents($wdir . '/source/' . $filename, $source);
         }
     }
     if ($this->backupFiles) {
         mkdirfull($wdir . '/files');
         /*	$c = new Criteria();
         			$c->add("site_id", $site->getSiteId());
         			$pages = DB_PagePeer::instance()->select($c);
         			
         			foreach($pages as $page){
         				// get the files
         				$c = new Criteria();
         				$c->add("page_id", $page->getPageId());
         				$files = DB_FilePeer::instance()->select($c);
         				if(count($files)>0){
         					$path = $wdir.'/files/'.$page->getUnixName();
         					mkdirfull($path);
         					foreach($files as $file){
         						copy($file->getFilePath(), $path);
         					}
         				}
         			}	*/
         $path0 = WIKIDOT_ROOT . '/web/files--sites/' . $site->getUnixName() . '/files/';
         $cmd = "cp -r " . $path0 . '*' . ' ' . $wdir . '/files/' . ' &> /dev/null';
         @exec($cmd);
         // fix colon:
         $dirstmp = ls($wdir . '/files/', '*:*');
         foreach ($dirstmp as $dd) {
             @rename($wdir . '/files/' . $dd, $wdir . '/files/' . str_replace(':', '_', $dd));
         }
     }
     // zip the content
     $cmd = 'cd ' . $wdir . ' && zip -r backup *';
     exec($cmd);
     $zipfile = $wdir . '/backup.zip';
     if (!file_exists($zipfile)) {
         throw new ProcessException("Error creating backup.");
     }
     // dest dir
     @exec('rm -r ' . WIKIDOT_ROOT . '/web/files--sites/' . $site->getUnixName() . '/backup/' . ' &> /dev/null');
     $rand = md5(rand(10000, 99999) . time());
     $ddir = WIKIDOT_ROOT . '/web/files--sites/' . $site->getUnixName() . '/backup/' . $rand . '/';
     mkdirfull($ddir);
     copy($zipfile, $ddir . 'backup.zip');
     // clear the working dir
     @exec('rm -r ' . escapeshellarg($wdir) . ' &> /dev/null');
     $this->rand = $rand;
 }
예제 #7
0
 public function savePrivateSettingsEvent($runData)
 {
     $pl = $runData->getParameterList();
     $site = $runData->getTemp("site");
     $private = (bool) $pl->getParameterValue("private");
     $landing = trim($pl->getParameterValue("landingPage"));
     $hideNav = (bool) $pl->getParameterValue("hideNav");
     $viewers = $pl->getParameterValue("viewers");
     $viewers = explode(',', $viewers);
     $settings = $site->getSettings();
     $maxMembers = $settings->getMaxPrivateMembers();
     $maxViewers = $settings->getMaxPrivateViewers();
     // check if not >=10 members
     if ($private) {
         $c = new Criteria();
         $c->add("site_id", $site->getSiteId());
         $cmem = DB_MemberPeer::instance()->selectCount($c);
         if ($cmem > $maxMembers) {
             throw new ProcessException(sprintf(_('Sorry, at the moment max %d member limit apply for private Wikis. The Site would have to be upgraded to allow more members.'), $maxMembers));
         }
     }
     if (count($viewers) >= $maxViewers) {
         throw new ProcessException(sprintf(_('Sorry, at the moment max %d viewer limit apply.'), $maxViewers));
     }
     // check landing
     if ($landing == "" || strlen($landing) > 80) {
         throw new ProcessException(_('Landing page is not valid'));
     }
     $db = Database::connection();
     $db->begin();
     if ($site->getPrivate() != $private) {
         $site->setPrivate($private);
         $site->save();
         // change file flag too
         $flagDir = $site->getLocalFilesPath() . '/flags';
         $flagFile = $flagDir . '/private';
         if ($private) {
             mkdirfull($flagDir);
             //just to make sure
             if (!file_exists($flagFile)) {
                 file_put_contents($flagFile, "private");
             }
         } else {
             if (file_exists($flagFile)) {
                 unlink($flagFile);
             }
         }
     }
     $settings = $site->getSettings();
     if ($settings->getPrivateLandingPage() != $landing) {
         $settings->setPrivateLandingPage($landing);
         $settings->save();
     }
     if ($settings->getHideNavigationUnauthorized() != $hideNav) {
         $settings->setHideNavigationUnauthorized($hideNav);
         $settings->save();
     }
     // handle viewers
     $c = new Criteria();
     $c->add("site_id", $site->getSiteId());
     $dbViewers = DB_SiteViewerPeer::instance()->select($c);
     $viewers = array_unique($viewers);
     foreach ($dbViewers as $dbViewer) {
         if (in_array($dbViewer->getUserId(), $viewers)) {
             unset($viewers[array_search($dbViewer->getUserId(), $viewers)]);
         } else {
             DB_SiteViewerPeer::instance()->deleteByPrimaryKey($dbViewer->getViewerId());
         }
     }
     // insert all other
     foreach ($viewers as $viewer) {
         if (trim($viewer) != '') {
             $dbViewer = new DB_SiteViewer();
             $dbViewer->setSiteId($site->getSiteId());
             $dbViewer->setUserId($viewer);
             $dbViewer->save();
         }
     }
     $db->commit();
     if (GlobalProperties::$UI_SLEEP) {
         sleep(1);
     }
 }
예제 #8
0
 public function setAvatarEvent($runData)
 {
     $userId = $runData->getUserId();
     $pl = $runData->getParameterList();
     $im48 = $pl->getParameterValue("im48");
     $im16 = $pl->getParameterValue("im16");
     $avatarDir = WIKIDOT_ROOT . '/web/files--common/images/avatars/';
     $avatarDir .= '' . floor($userId / 1000) . '/' . $userId;
     mkdirfull($avatarDir);
     $tmpDir = WIKIDOT_ROOT . '/web/files--common/tmp/avatars-upload';
     rename($tmpDir . '/' . $im48, $avatarDir . '/a48.png');
     rename($tmpDir . '/' . $im16, $avatarDir . '/a16.png');
     unlink($tmpDir . '/' . str_replace('.png', '', $im48));
     unlink($tmpDir . '/' . str_replace('.png', '', $im16));
 }
예제 #9
0
 public function moveFileEvent($runData)
 {
     $pl = $runData->getParameterList();
     $fileId = $pl->getParameterValue("file_id");
     $destinationPageName = $pl->getParameterValue("destination_page_name");
     $site = $runData->getTemp("site");
     $db = Database::connection();
     $db->begin();
     $user = $runData->getUser();
     $file = DB_FilePeer::instance()->selectByPrimaryKey($fileId);
     $page = DB_PagePeer::instance()->selectByPrimaryKey($file->getPageId());
     if ($file == null || $file->getSiteId() != $site->getSiteId()) {
         throw new ProcessException(_("Error getting file data."), "file_error");
     }
     if ($page == null || $page->getSiteId() != $runData->getTemp("site")->getSiteId()) {
         throw new ProcessException(_("Error getting file information."), "no_page");
     }
     $categoryFrom = $page->getCategory();
     // now check for permissions!!!
     WDPermissionManager::instance()->hasPagePermission('move_file', $user, $categoryFrom, $page);
     if ($destinationPageName == $page->getUnixName()) {
         throw new ProcessException(_("There is not point in moving the file to the same (current)  page..."), "no_destination");
     }
     $destinationPage = DB_PagePeer::instance()->selectByName($site->getSiteId(), $destinationPageName);
     if ($destinationPage == null) {
         throw new ProcessException(_("Destination page does not exist."), "no_destination");
     }
     // check for permissions now to attach the file to a new page.
     $categoryTo = $destinationPage->getCategory();
     try {
         WDPermissionManager::instance()->hasPagePermission('attach_file', $user, $categoryTo, $destinationPage);
     } catch (Exception $e) {
         throw new ProcessException(_("No permission to add file to the specifed new page."), "no_destination_permission");
     }
     try {
         WDPermissionManager::instance()->hasPagePermission('replace_file', $user, $categoryTo, $destinationPage);
         $overwritePermission = true;
     } catch (Exception $e) {
         $overwritePermission = false;
     }
     // check if file exists in the destination page
     $force = $pl->getParameterValue("force");
     if ($force && $overwritePermission) {
         // delete any file by this name in the page
         $c = new Criteria();
         $c->add("page_id", $destinationPage->getPageId());
         $c->add("filename", $file->getFilename());
         DB_FilePeer::instance()->delete($c);
     }
     $c = new Criteria();
     $c->add("page_id", $destinationPage->getPageId());
     $c->add("filename", $file->getFilename());
     $conflictFile = DB_FilePeer::instance()->selectOne($c);
     if ($conflictFile != null) {
         // file already exists!!! ask what to do!
         // check permissions to overwrite?
         $runData->contextAdd("page", $page);
         $runData->contextAdd("destinationPage", $destinationPage);
         $runData->contextAdd("file", $file);
         $runData->setModuleTemplate("files/FileMoveExistsWinModule");
         $runData->contextAdd("hasPermission", $overwritePermission);
         $runData->ajaxResponseAdd("status", "file_exists");
         $db->commit();
         return;
     }
     // ok, move along. nothing to watch.
     $oldPath = $file->getFilePath();
     $oldRDir = $file->getResizedDir();
     $file->setPageId($destinationPage->getPageId());
     $file->save();
     $newPath = $file->getFilePath();
     $newRDir = $file->getResizedDir();
     $dir = dirname($newPath);
     mkdirfull($dir);
     if (rename($oldPath, $newPath) == false) {
         throw new ProcessException(_("Error moving files."), "error_moving");
     }
     if ($file->getHasResized()) {
         $resizedDir = $site->getLocalFilesPath() . "/resized-images/" . $destinationPage->getUnixName();
         mkdirfull($resizedDir);
         if (rename("{$oldRDir}", "{$newRDir}") == false) {
             throw new ProcessException(_("Error moving resized files."), "error_moving");
         }
     }
     $runData->ajaxResponseAdd("moved", true);
     // create new revisions of $page and $destinationPage
     // create a new revision
     $revision = $page->getCurrentRevision();
     $revision->setNew(true);
     $revision->setRevisionId(null);
     $revision->resetFlags();
     $revision->setFlagFile(true);
     $revision->setRevisionNumber($revision->getRevisionNumber() + 1);
     $now = new ODate();
     $revision->setDateLastEdited($now);
     $userId = $runData->getUserId();
     if ($userId == null) {
         $userString = $runData->createIpString();
     }
     if ($userId) {
         $revision->setUserId($userId);
         $page->setLastEditUserId($userId);
     } else {
         $revision->setUserId(0);
         $page->setLastEditUserId(0);
         $revision->setUserString($userString);
         $page->setLastEditUserString($userString);
     }
     $revision->setComments('File "' . $file->getFilename() . '" moved away to page "' . $destinationPage->getUnixName() . '".');
     $revision->save();
     $page->setRevisionId($revision->getRevisionId());
     $page->setDateLastEdited($now);
     $page->setRevisionNumber($revision->getRevisionNumber());
     $page->save();
     // and destinationPage
     // create a new revision
     $revision = $destinationPage->getCurrentRevision();
     $revision->setNew(true);
     $revision->setRevisionId(null);
     $revision->resetFlags();
     $revision->setFlagFile(true);
     $revision->setRevisionNumber($revision->getRevisionNumber() + 1);
     $revision->setDateLastEdited($now);
     if ($userId) {
         $revision->setUserId($userId);
         $destinationPage->setLastEditUserId($userId);
     } else {
         $revision->setUserId(0);
         $destinationPage->setLastEditUserId(0);
         $revision->setUserString($userString);
         $destinationPage->setLastEditUserString($userString);
     }
     $revision->setComments('File "' . $file->getFilename() . '" moved from page "' . $page->getUnixName() . '".');
     $revision->save();
     $destinationPage->setRevisionId($revision->getRevisionId());
     $destinationPage->setDateLastEdited($now);
     $destinationPage->setRevisionNumber($revision->getRevisionNumber());
     $destinationPage->save();
     $od = new Outdater();
     $od->pageEvent('file_change', $page);
     $od->pageEvent('file_change', $destinationPage);
     $db->commit();
 }