示例#1
0
文件: Page.php 项目: jbzdak/wikidot
 public function save($args)
 {
     $db = Database::connection();
     $db->begin();
     // simple argument checking
     if (!isset($args['page'])) {
         throw new Wikidot_Facade_Exception_WrongArguments("Page argument must be passed");
     }
     $pm = new WDPermissionManager();
     $now = new ODate();
     // page (existant or not) name
     $arg_page = WDStringUtils::toUnixName($args['page']);
     // parse the rest (beside page name)
     unset($args['page']);
     $this->parseArgs($args, array("performer", "site"));
     try {
         // parse page name to figure out if it points to an existant page
         $page = $this->_parsePage($this->site, $arg_page);
         $new = false;
         // check permissions to edit the page
         $pm->hasPagePermission('edit', $this->performer, $page->getCategory(), $page);
     } catch (Wikidot_Facade_Exception_WrongArguments $e) {
         if ($this->source === null) {
             $this->source = "";
         }
         if ($this->title === null) {
             $this->title = $arg_page;
         }
         $new = true;
         $category_name = preg_replace('/^([^:]*):.*$/', '\\1', $arg_page);
         if ($category_name == $arg_page) {
             $category_name = '_default';
         }
         $category = $this->_getOrCreateCategory($this->site, $category_name);
         $page = new DB_Page();
         $page->setSiteId($this->site->getSiteId());
         $page->setCategoryId($category->getCategoryId());
         $page->setUnixName($arg_page);
         $page->setDateCreated(new ODate());
         $page->setOwnerUserId($this->performer->getUserId());
         $page->save();
         $compiled = new DB_PageCompiled();
         $compiled->setPageId($page->getPageId());
         $compiled->save();
     }
     // get current revision and metadata
     if (!$new) {
         $cur_rev = $page->getCurrentRevision();
         $cur_meta = $cur_rev->getMetadata();
     }
     // construct new metadata
     if ($new) {
         $new_meta = new DB_PageMetadata();
         $new_meta->setUnixName($arg_page);
         $new_meta->setOwnerUserId($this->performer->getUserId());
     } else {
         $new_meta = clone $cur_meta;
         $new_meta->setNew(true);
         $new_meta->setMetadataId(null);
     }
     // construct new revision
     $new_rev = new DB_PageRevision();
     $new_rev->setSiteId($this->site->getSiteId());
     $new_rev->setPageId($page->getPageId());
     $new_rev->setUserId($this->performer->getUserId());
     $new_rev->setDateLastEdited($now);
     if ($new) {
         $new_rev->setRevisionNumber(0);
     } else {
         $new_rev->setRevisionNumber($cur_rev->getRevisionNumber() + 1);
     }
     $src_changed = false;
     $title_changed = false;
     $parent_changed = false;
     $tags_changed = false;
     // handle source change
     if ($new || $this->source !== null && $page->getSource() != $this->source) {
         $new_src = new DB_PageSource();
         $new_src->setText($this->source);
         $new_src->save();
         $new_rev->setSourceId($new_src->getSourceId());
         $src_changed = true;
     } else {
         $new_rev->setSourceId($cur_rev->getSourceId());
         $new_rev->setSinceFullSource($cur_rev->getSinceFullSource());
         $new_rev->setDiffSource($cur_rev->getDiffSource());
     }
     // handle tags change
     if ($this->tags) {
         $new_tags = $this->tags;
         $cur_tags = $page->getTagsAsArray();
         sort($cur_tags);
         sort($new_tags);
         if ($cur_tags != $new_tags) {
             $tags_changed = true;
             $tags_deleted = array();
             $tags_added = array();
             foreach ($cur_tags as $tag) {
                 if (!in_array($tag, $new_tags)) {
                     $c = new Criteria();
                     $c->add('page_id', $page->getPageId());
                     $c->add('tag', $tag);
                     if ($t = DB_PageTagPeer::instance()->selectOne($c)) {
                         $t->delete();
                         $tags_deleted[] = $tag;
                     }
                 }
             }
             foreach ($new_tags as $tag) {
                 if (!in_array($tag, $cur_tags)) {
                     $t = new DB_PageTag();
                     $t->getPageId($page->getPageId());
                     $t->setSiteId($this->site->getSiteId());
                     $t->setTag($tag);
                     $t->save();
                     $tags_added[] = $tag;
                 }
             }
         }
     }
     // handle metadata: title change
     if ($new || $this->title !== null && $cur_meta->getTitle() != $this->title) {
         $new_meta->setTitle($this->title);
         $page->setTitle($this->title);
         $title_changed = true;
     }
     // handle metadata: parent page change
     if ($this->parent_page) {
         if (!$cur_meta->getParentPageId() || $cur_meta->getParentPageId() != $this->parent_page->getPageId()) {
             $new_meta->setParentPageId($this->parent_page->getPageId());
             $parent_changed = true;
         }
     }
     if ($this->clear_parent_page && $page->getParentPageId()) {
         $new_meta->setParentPageId(null);
         $parent_changed = true;
     }
     $meta_changed = $title_changed || $parent_changed;
     // decide whether to use previous metadata or create a new object
     if ($meta_changed) {
         $new_meta->save();
         $new_rev->setMetadataId($new_meta->getMetadataId());
     } else {
         $new_rev->setMetadataId($cur_meta->getMetadataId());
     }
     // set flag on revision
     if ($new) {
         $new_rev->setFlagNew(true);
     } else {
         if ($src_changed) {
             $new_rev->setFlagText(true);
         }
         if ($title_changed) {
             $new_rev->setFlagTitle(true);
         }
         if ($parent_changed) {
             $new_rev->setFlagMeta(true);
         }
     }
     if ($src_changed || $meta_changed || $tags_changed) {
         $new_rev->save();
         $page->setSourceId($new_rev->getSourceId());
         $page->setDateLastEdited($now);
         $page->setMetadataId($new_rev->getMetadataId());
         $page->setRevisionNumber($new_rev->getRevisionNumber());
         $page->setRevisionId($new_rev->getRevisionId());
         $page->save();
         $db->commit();
         $GLOBALS['site'] = $this->site;
         $outdater = new Outdater();
         if ($src_changed) {
             $outdater->pageEvent("source_changed", $page);
         }
         if ($title_changed) {
             $outdater->pageEvent("title_changed", $page);
         }
         if ($parent_changed) {
             $outdater->pageEvent("parent_changed", $page);
         }
         if ($tags_changed) {
             $outdater->pageEvent("tag_changed", $page);
         }
     } else {
         /* This place is reached when API client tries to set source or
          * title or parent page or tags that are already set (in the DB)
          * to the same value.
          * 
          * Let's suppose doing nothing is the desired behavior in this case
          * 
          * Other possible way to react can be raising an exception.
          * But it should be different from Wikidot_Facade_Exception_WrongArguments
          * because this one implies client error (and client does not need
          * to know the exact database state).
          */
     }
 }
示例#2
0
 public function saveTagsEvent($runData)
 {
     // do not create any new revision... :-(
     // or create???
     $user = $runData->getUser();
     $pl = $runData->getParameterList();
     $tags = strtolower(trim($pl->getParameterValue("tags")));
     $pageId = $pl->getParameterValue("pageId");
     $site = $runData->getTemp("site");
     $page = DB_PagePeer::instance()->selectByPrimaryKey($pageId);
     if ($page == null || $page->getSiteId() != $site->getSiteId()) {
         throw new ProcessException(_("Error getting page information."), "no_page");
     }
     $category = $page->getCategory();
     WDPermissionManager::instance()->hasPagePermission('edit', $user, $category, $page);
     if (strlen8($tags) > 256) {
         throw new ProcessException(_('"Tags" field too long.'), "form_error");
     }
     $db = Database::connection();
     $db->begin();
     $c = new Criteria();
     $c->add("page_id", $pageId);
     $dbTags = DB_PageTagPeer::instance()->select($c);
     $tags = preg_split("/[ ,]+/", $tags);
     $tagstmp = array();
     foreach ($tags as $tag) {
         $tagstmp[] = substr($tag, 0, 64);
     }
     $tags = $tagstmp;
     $tags = array_unique($tags);
     foreach ($dbTags as $dbTag) {
         if (in_array($dbTag->getTag(), $tags)) {
             unset($tags[array_search($dbTag->getTag(), $tags)]);
         } else {
             DB_PageTagPeer::instance()->deleteByPrimaryKey($dbTag->getTagId());
         }
     }
     // insert all the other
     foreach ($tags as $tag) {
         if (trim($tag) != '') {
             $dbTag = new DB_PageTag();
             $dbTag->setSiteId($site->getSiteId());
             $dbTag->setPageId($pageId);
             $dbTag->setTag($tag);
             $dbTag->save();
         }
     }
     $od = new Outdater();
     $od->pageEvent("tag_change", $page);
     $db->commit();
     if (GlobalProperties::$UI_SLEEP) {
         sleep(1);
     }
 }
示例#3
0
 public function deletePage($page, $site = null)
 {
     // I hope everything here is within a TRANSACTION!!!
     if (!$page) {
         return;
     }
     if (!$site) {
         $site = DB_SitePeer::instance()->selectByPrimaryKey($page->getSiteId());
     }
     // delete the sources and metadatas
     $db = Database::connection();
     // get descandants first
     $rec = 0;
     $c = new Criteria();
     $c->add("parent_page_id", $page->getPageId());
     $pages = DB_PagePeer::instance()->select($c);
     // ok, these are direct children. need to clear the perent_page_id field
     $descs = array();
     while ($pages !== null && count($pages) > 0 && $rec < 10) {
         $p2 = array();
         foreach ($pages as $p) {
             $c = new Criteria();
             $c->add("parent_page_id", $p->getPageId());
             $ptmp = DB_PagePeer::instance()->select($c);
             $p2 = array_merge($p2, $ptmp);
             if ($rec === 0) {
                 $p->setParentPageId(null);
                 $p->save();
                 // clear metadata
                 $m = $p->getMetadata();
                 $m->setParentPageId(null);
                 $m->save();
             }
         }
         $descs = array_merge($descs, $pages, $p2);
         $pages = $p2;
         $rec++;
     }
     $category = $page->getCategory();
     // sources
     $q = "DELETE FROM page_source WHERE source_id IN (SELECT page_revision.source_id FROM page_revision WHERE page_id='" . $page->getPageId() . "')";
     $db->query($q);
     //metadatas
     $q = "DELETE FROM page_metadata WHERE metadata_id IN (SELECT page_revision.metadata_id FROM page_revision WHERE page_id='" . $page->getPageId() . "')";
     $db->query($q);
     // delete the page too
     $q = "DELETE FROM page WHERE page_id='" . $page->getPageId() . "'";
     $db->query($q);
     // remove from cache too.
     $outdater = new Outdater();
     $outdater->pageEvent('delete', $page->getUnixName());
     // outdate descs too
     foreach ($descs as $desc) {
         $outdater->outdatePageCache($desc);
     }
     // delete the category if empty
     if ($category->getName() != "_default") {
         $c = new Criteria();
         $c->add("category_id", $category->getCategoryId());
         $count = DB_PagePeer::instance()->selectCount($c);
         if ($count == 0) {
             // delete the category
             DB_CategoryPeer::instance()->delete($c);
             $outdater->categoryEvent('delete', $category, $site);
         }
     }
     // remove FILES (if any)
     $path = WIKIDOT_ROOT . "/web/files--sites/" . $site->getUnixName() . "/files/" . $page->getUnixName();
     exec('rm -r ' . escapeshellarg($path) . ' &> /dev/null');
     //
 }
示例#4
0
 public function finalizeEvent($runData, $skipEvcode = false)
 {
     // get the form data
     $pl = $runData->getParameterList();
     if (!$skipEvcode) {
         $evcode = $pl->getParameterValue("evcode", "AMODULE");
         //check if the email vercode is correct
         $evcode2 = $runData->sessionGet('evcode');
         if ($evcode !== $evcode2) {
             throw new ProcessException(_("Invalid email verification code."), "invalid_code");
         }
     }
     $data = $runData->sessionGet("ca_data");
     $name = $data['name'];
     $email = $data['email'];
     $password = $data['password'];
     $lang = $data['language'];
     $db = Database::connection();
     $db->begin();
     // check again if email and nick are not duplicate!
     $c = new Criteria();
     $c->add("lower(email)", strtolower($email));
     $u = DB_OzoneUserPeer::instance()->selectOne($c);
     if ($u != null) {
         $runData->resetSession();
         throw new ProcessException(_("A user with this email already exists. Must have been created meanwhile... " . "Unfortunately you have to repeat the whole procedure. :-("), "user_exists");
     }
     $unixified = WDStringUtils::toUnixName($name);
     $c = new Criteria();
     $c->add("unix_name", $unixified);
     $u = DB_OzoneUserPeer::instance()->selectOne($c);
     if ($u != null) {
         $runData->resetSession();
         throw new ProcessException(_("A user with this name (or very similar) already exists. Must have been created meanwhile... " . "Unfortunately you have to repeat the whole procedure. :-("), "user_exists");
     }
     // add new user!!!
     $nuser = new DB_OzoneUser();
     /* email as the username!!! */
     $nuser->setName($email);
     $nuser->setEmail($email);
     $nuser->setPassword(md5($password));
     $nuser->setNickName($name);
     $nuser->setUnixName($unixified);
     $nuser->setLanguage($lang);
     $date = new ODate();
     $nuser->setRegisteredDate($date);
     $nuser->setLastLogin($date);
     $nuser->save();
     // profile
     $profile = new DB_Profile();
     $profile->setUserId($nuser->getUserId());
     $profile->save();
     $us = new DB_UserSettings();
     $us->setUserId($nuser->getUserId());
     $us->save();
     // profile page
     $c = new Criteria();
     $c->add("unix_name", "profiles");
     $nsite = DB_SitePeer::instance()->selectOne($c);
     $ncategory = DB_CategoryPeer::instance()->selectByName('profile', $nsite->getSiteId());
     $dup = new Duplicator();
     $dup->setOwner($nuser);
     $dup->duplicatePage(DB_PagePeer::instance()->selectByName($nsite->getSiteId(), 'template:profile'), $nsite, $ncategory, 'profile:' . $nuser->getUnixName());
     $page = DB_PagePeer::instance()->selectByName($nsite->getSiteId(), 'profile:' . $nuser->getUnixName());
     $ou = new Outdater();
     $ou->pageEvent('new_page', $page);
     $db->commit();
     /* Handle originalUrl. */
     $originalUrl = $runData->sessionGet('loginOriginalUrl');
     if ($originalUrl) {
         $runData->ajaxResponseAdd('originalUrl', $originalUrl);
         if ($runData->sessionGet('loginOriginalUrlForce')) {
             $runData->ajaxResponseAdd('originalUrlForce', true);
         }
     }
     // reset session etc.
     $runData->resetSession();
     $runData->getSession()->setUserId($nuser->getUserId());
     setcookie("welcome", $nuser->getUserId(), time() + 10000000, "/", GlobalProperties::$SESSION_COOKIE_DOMAIN);
     setcookie(GlobalProperties::$SESSION_COOKIE_NAME_IE, $runData->getSessionId(), null, "/");
 }
示例#5
0
 public function cancelVoteEvent($runData)
 {
     $pl = $runData->getParameterList();
     $site = $runData->getTemp("site");
     $pageId = $pl->getParameterValue("pageId");
     $user = $runData->getUser();
     $page = DB_PagePeer::instance()->selectByPrimaryKey($pageId);
     if (!$pageId || $page == null || $page->getSiteId() != $runData->getTemp("site")->getSiteId()) {
         throw new ProcessException(_("Error getting page information."), "no_page");
     }
     // check if allowed
     if (!$this->canRatePage($user, $page)) {
         // prepare the message
         throw new ProcessException($this->message);
     }
     $db = Database::connection();
     $db->begin();
     $c = new Criteria();
     $c->add("page_id", $page->getPageId());
     $c->add("user_id", $user->getUserId());
     $v = DB_PageRateVotePeer::instance()->selectOne($c);
     if (!$v) {
         $runData->ajaxResponseAdd("points", 0);
         return;
     }
     DB_PageRateVotePeer::instance()->delete($c);
     $rpoints = 0 - $v->getRate();
     // update page points
     $q = "UPDATE page SET rate=COALESCE((" . "SELECT sum(rate) FROM page_rate_vote WHERE page_id = '" . $page->getPageId() . "'),0) " . "WHERE page_id='" . $page->getPageId() . "'";
     $db->query($q);
     $outdater = new Outdater();
     $outdater->pageEvent("page_vote", $page);
     $db->commit();
     $runData->ajaxResponseAdd("points", $rpoints);
 }
示例#6
0
 public function changeScreenNameEvent($runData)
 {
     $user = $runData->getUser();
     $userId = $user->getUserId();
     $profile = $user->getProfile();
     if ($profile->getChangeScreenNameCount() >= 2) {
         throw new ProcessException('Your are allowed to change your screen name only 2 times.');
     }
     $pl = $runData->getParameterList();
     $name = trim($pl->getParameterValue("screenName"));
     if ($name == $user->getNickName()) {
         throw new ProcessException("Your new and current screen names are the same.");
     }
     $db = Database::connection();
     $db->begin();
     $unixified = WDStringUtils::toUnixName($name);
     if (strlen($name) < 2) {
         throw new ProcessException(_("You really should provide the screen name you want to use."));
     }
     if (strlen8($name) > 20) {
         throw new ProcessException(_("Your screen name should not be longer than 20 characters."));
     }
     if (preg_match('/^[ _a-zA-Z0-9-\\!#\\$%\\^\\*\\(\\)]+$/', $name) == 0) {
         throw new ProcessException(_("Only alphanumeric characters (+a few special) can be used in the screen name."));
     }
     if (strlen($unixified) < 2) {
         throw new ProcessException(_("It seems there are too less alphanumeric characters in your screen name"));
     }
     //handle forbidden names
     $unixName = WDStringUtils::toUnixName($name);
     $forbiddenUnixNames = explode("\n", file_get_contents(WIKIDOT_ROOT . '/conf/forbidden_user_names.conf'));
     foreach ($forbiddenUnixNames as $f) {
         if (preg_match($f, $unixName) > 0) {
             throw new ProcessException(_('For some reason this name is not allowed or is reserved for future use.'));
         }
     }
     // check if user does not exist
     $c = new Criteria();
     $c->add("unix_name", $unixified);
     $u = DB_OzoneUserPeer::instance()->selectOne($c);
     if ($u != null) {
         throw new ProcessException(_("A user with this screen name (or very similar) already exists."));
     }
     // rename the profile page
     $c = new Criteria();
     $c->add("unix_name", "profiles");
     $nsite = DB_SitePeer::instance()->selectOne($c);
     $pageName = 'profile:' . $user->getUnixName();
     $c = new Criteria();
     $c->add('site_id', $nsite->getSiteId());
     $c->add('unix_name', $pageName);
     $page = DB_PagePeer::instance()->selectOne($c);
     if (!$page) {
         throw new ProcessException('Internal error');
     }
     $metadata = $page->getMetadata();
     $metadata->setUnixName('profile:' . $unixified);
     $page->setUnixName('profile:' . $unixified);
     $metadata->save();
     $page->save();
     // outdate page cache
     $outdater = new Outdater();
     $outdater->pageEvent("rename", $page, $pageName);
     // now, try to apply new name!!!
     $user->setNickName($name);
     $user->setUnixName($unixified);
     $user->save();
     $profile->setChangeScreenNameCount($profile->getChangeScreenNameCount() + 1);
     $profile->save();
     $db->commit();
 }
示例#7
0
 private function recompileInclusionDeps($page)
 {
     // get deps
     $site = $GLOBALS['site'];
     $c = new Criteria();
     $c->add("site_id", $site->getSiteId());
     if (is_string($page)) {
         $c->add("included_page_name", $page);
     } else {
         $c2 = new Criteria();
         $c2->add("included_page_id", $page->getPageId());
         $c2->addOr("included_page_name", $page->getUnixName());
         $c->addCriteriaAnd($c2);
     }
     $dbinclusions = DB_PageInclusionPeer::instance()->select($c);
     foreach ($dbinclusions as $inc) {
         $page = DB_PagePeer::instance()->selectByPrimaryKey($inc->getIncludingPageId());
         // triger source update (recompile)
         $outdater = new Outdater($this->recurrenceLevel);
         $outdater->pageEvent("source_changed", $page);
     }
 }
示例#8
0
 public function deleteFileEvent($runData)
 {
     $pl = $runData->getParameterList();
     $fileId = $pl->getParameterValue("file_id");
     $destinationPageName = $pl->getParameterValue("destination_page_name");
     $site = $runData->getTemp("site");
     $db = Database::connection();
     $db->begin();
     $file = DB_FilePeer::instance()->selectByPrimaryKey($fileId);
     if ($file == null || $file->getSiteId() != $site->getSiteId()) {
         throw new ProcessException("File does not exist.", "no_file");
     }
     $page = DB_PagePeer::instance()->selectByPrimaryKey($file->getPageId());
     if ($page == null) {
         throw new ProcessException(_("Page does not exist."), "no_page");
     }
     $category = $page->getCategory();
     // now check for permissions!!!
     $user = $runData->getUser();
     WDPermissionManager::instance()->hasPagePermission('delete_file', $user, $category, $page);
     // remove file! and create another revision too...
     @unlink($file->getFilePath());
     // delete resized images if exist
     if ($file->getHasResized()) {
         $cmd = "rm -r " . escapeshellarg($file->getResizedDir());
         exec($cmd);
     }
     DB_FilePeer::instance()->deleteByPrimaryKey($file->getFileId());
     // 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() . '" deleted.');
     $revision->save();
     $page->setRevisionId($revision->getRevisionId());
     $page->setDateLastEdited($now);
     $page->setRevisionNumber($revision->getRevisionNumber());
     $page->save();
     $od = new Outdater();
     $od->pageEvent('file_change', $page);
     $db->commit();
 }