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). */ } }
public function render($runData) { // quickly check - show or not. $pl = $runData->getParameterList(); $pageName = $runData->getTemp("pageUnixName"); $page = $runData->getTemp("page"); //$pl->getParameterValue("page", "MODULE"); // get category name and get the category by name. // this should be enchanced to use memcache later // to get category to avoid db connection. // extract category name if (strpos($pageName, ':') != false) { // ok, there is category! $exp = explode(':', $pageName); $categoryName = $exp[0]; } else { $categoryName = "_default"; } $site = $runData->getTemp("site"); $category = DB_CategoryPeer::instance()->selectByName($categoryName, $site->getSiteId()); $user = $runData->getUser(); $pm = new WDPermissionManager(); $pm->setThrowExceptions(false); $pm->setCheckIpBlocks(false); // to avoid database connection. if (!$pm->hasPagePermission('options', $user, $category, $pageName, $site)) { return ''; } $showDiscuss = $pl->getParameterValue("showDiscuss"); if ($showDiscuss) { $threadId = $pl->getParameterValue("threadId"); $pageUnixName = $pl->getParameterValue("pageUnixName"); } $showRate = $category->getRatingEnabledEff(); // now a nasty part - make it inline such that // the Smarty engine does need to be initialized. // nasty way but saves a LOT of time with caching enabled. $otext = ''; if ($page) { $otext .= '<div id="page-info">' . _('page_revision') . ': ' . $page->getRevisionNumber() . ', ' . _('last_edited') . ': <span class="odate">' . $page->getDateLastEdited()->getTimestamp() . '|%e %b %Y, %H:%M %Z (%O ' . _('ago') . ')</span>' . '</div>'; } $otext .= ' <div id="page-options-bottom" class="page-options-bottom"> <a href="javascript:;" id="edit-button">' . _('edit') . '</a>'; if ($showRate && $page) { $otext .= '<a href="javascript:;" id="pagerate-button">' . _('rate') . ' (<span id="prw54355">' . ($page->getRate() > 0 ? '+' : '') . $page->getRate() . '</span>)</a>'; } $otext .= '<a href="javascript:;" id="tags-button">' . _('tags') . '</a>'; if ($showDiscuss && $page) { if ($threadId) { $no = $page->getTemp("numberPosts"); $otext .= '<a href="/forum/t-' . $threadId . '/' . $pageUnixName . '" id="discuss-button">' . _('discuss') . ' (' . $no . ')</a>'; } else { $otext .= '<a href="javascript:;" id="discuss-button" onclick="WIKIDOT.page.listeners.createPageDiscussion(event)">' . _('discuss') . '</a> '; } } $otext .= ' <a href="javascript:;" id="history-button">' . _('history') . '</a> <a href="javascript:;" id="files-button">' . _('files') . '</a> ' . '<a href="javascript:;" id="print-button">' . _('print') . '</a> ' . '<a href="javascript:;" id="site-tools-button">' . _('site tools') . '</a>'; if ($site->getPrivate()) { } $otext .= '<a href="javascript:;" id="more-options-button">+ ' . _('options') . '</a> </div> <div id="page-options-bottom-2" class="page-options-bottom" style="display:none"> <a href="javascript:;" id="edit-sections-button">' . _('edit sections') . '</a> <a href="javascript:;" id="edit-append-button">' . _('append') . '</a> <a href="javascript:;" id="backlinks-button">' . _('backlinks') . '</a> <a href="javascript:;" id="view-source-button">' . _('view source') . '</a> <a href="javascript:;" id="parent-page-button">' . _('parent') . '</a> <a href="javascript:;" id="page-block-button">' . _('block') . '</a> <a href="javascript:;" id="rename-move-button">' . _('rename') . '</a> <a href="javascript:;" id="delete-button">' . _('delete') . '</a> </div> <div id="page-options-area-bottom"> </div> '; return $otext; }