/** * Can the user create this new Title? (called for action 'create', 'edit', * 'upload', 'createpage', 'move-target' on a new title) * @param Title $title A new Title (=not known/not stored) in a Wikiplace namespace * @param User $user A logged in user * @return array Empty array = can, array containing i18n key + args = cannot */ public static function wikiplaceUserCanCreate(&$title, &$user) { // in userCan() calling this function, we already checked that user is loggedin $msg; $user_id = $user->getId(); // ensure we are not creating a duplicate in wikiplace if (class_exists('TitleKey') && ($duplicate = TitleKey::exactMatchTitle($title))) { wfDebugLog('wikiplaces-debug', "user cannot create {$title->getPrefixedDBkey()} duplicate {$duplicate->getPrefixedDBkey()} exists"); return array('wp-duplicate-exists', $duplicate->getPrefixedDBkey()); } // ensure to keep "talk page" <-> "regular page" mirrored named if ($title->isTalkPage()) { // ensure to not create a talk having a subject in different case ( ie: Talk:wp/page but wp/PAGE exists ) $subject = $title->getSubjectPage(); if (!$subject->isKnown() && class_exists('TitleKey') && ($duplicate_subject = TitleKey::exactMatchTitle($subject))) { // the subject page doesn't exist, but there is a subject page with different case, abort wfDebugLog('wikiplaces-debug', "user cannot create {$title->getPrefixedDBkey()} duplicate subject {$duplicate_subject->getPrefixedDBkey()} exists"); return array('wp-duplicate-related', $duplicate_subject->getPrefixedDBkey(), $duplicate_subject->getTalkPage()->getPrefixedDBkey()); } } else { // ensure to not create an article with an existing talk in different case $talk = $title->getTalkPage(); if (!$talk->isKnown() && class_exists('TitleKey') && ($duplicate_talk = TitleKey::exactMatchTitle($talk))) { // the talk page doesn't exist, but there is a talk page with different case, abort wfDebugLog('wikiplaces-debug', "user cannot create {$title->getPrefixedDBkey()} duplicate talk {$duplicate_talk->getPrefixedDBkey()} exists"); return array('wp-duplicate-related', $duplicate_talk->getPrefixedDBkey(), $duplicate_talk->getSubjectPage()->getPrefixedDBkey()); } } if (WpPage::isHomepage($title)) { // this is a new Wikiplace $msg = 'new wikiplace'; if (($reason = WpSubscription::userCanCreateWikiplace($user_id)) !== true) { $result = array($reason); $msg .= ', ' . $reason; } elseif (WpWikiplace::isBlacklistedWikiplaceName($title->getDBkey())) { $result = array('badtitletext'); $msg .= ', blacklisted name'; } elseif (preg_match('/[.]/', $title->getText())) { $result = array('badtitletext'); $msg .= ', bad character in page title'; } else { $result = array(); } } else { // this can be regular article or talk or file) $namespace = $title->getNamespace(); if ($namespace == NS_FILE || $namespace == NS_FILE_TALK) { // the user is uploading a file or creating a file talk $msg = 'new file/file_talk'; $db_key = $title->getDBkey(); if (WpPage::isPublic($namespace, $db_key)) { $msg .= ', in public space'; $result = array(); } elseif (WpPage::isAdmin($namespace, $db_key)) { $msg .= ', in admin space'; if ($user->isAllowed(WP_ADMIN_RIGHT)) { $result = array(); } else { $msg .= ', user not admin'; $result = array('protectedpage'); } } else { $msg .= ', attached to a wikiplace'; $wp = WpWikiplace::getBySubpage($db_key, $title->getNamespace()); if ($wp === null) { $result = array('wp-no-container-found'); // no wikiplace can contain this, so cannot create it $msg .= ', cannot find existing container Wikiplace'; } elseif ($user->isAllowed(WP_ADMIN_RIGHT)) { // admin is working for someone else $result = array(); $msg .= ', admin is working for someone else'; } elseif (!$wp->isOwner($user_id) && !WpMember::IsMember($wp, $user)) { // !owner and !member => DENY $result = array('wp-not-owner-or-member'); $msg .= ', current user is neither the owner nor a member of the Wikiplace'; } else { $reason; if ($namespace == NS_FILE) { $reason = WpSubscription::userCanUploadNewFile($user_id, $wp); } else { $reason = WpSubscription::userCanCreateNewPage($user, $wp); } if ($reason !== true) { $result = array($reason); // no active subscription or page creation quota is exceeded $msg .= ', ' . $reason; } else { $result = array(); } } } } else { // the user is creating a new page (regular or talk, but not a file or file_talk) $msg = ', new subpage'; $wp = WpWikiplace::getBySubpage($title->getDBkey(), $title->getNamespace()); if ($wp === null) { $result = array('wp-no-container-found'); // no wikiplace can contain this subpage, so cannot create it $msg .= ', cannot find existing container Wikiplace'; } elseif ($user->isAllowed(WP_ADMIN_RIGHT)) { // admin is creating a subpage for someone else $result = array(); $msg .= ', admin is creating a subpage for someone else'; } elseif (!$wp->isOwner($user_id) && !WpMember::IsMember($wp, $user)) { // !owner and !member => DENY $result = array('wp-not-owner-or-member'); $msg .= ', current user is neither the owner nor a member of the Wikiplace'; } elseif (($reason = WpSubscription::userCanCreateNewPage($user, $wp)) !== true) { $result = array($reason); // no active subscription or page creation quota is exceeded $msg .= ', ' . $reason; } else { $result = array(); } } } wfDebugLog('wikiplaces-debug', "user can" . (empty($result) ? '' : 'not') . " create {$title->getFullText()}: {$msg}"); return $result; }