/** * Checks if a deviation is in the club and stops execution if it isn't * * @param string $favme * @param bool $throw If true an Exception will be thrown instead of responding */ static function checkDeviationInClub($favme, $throw = false) { $Status = self::isDeviationInClub($favme); if ($Status !== true) { $errmsg = $Status === false ? "The deviation has not been submitted to/accepted by the group yet" : "There was an issue while checking the acceptance status (Error code: {$Status})"; if ($throw) { throw new \Exception($errmsg); } Response::fail($errmsg); } }
} if (isset($_REQUEST['unlink']) || isset($_REQUEST['everywhere'])) { $col = 'user'; $val = $currentUser->id; $username = Users::validateName('username', null, true); if (isset($username)) { if (!Permission::sufficient('staff') || isset($_REQUEST['unlink'])) { Response::fail(); } /** @var $TargetUser User */ $TargetUser = $Database->where('name', $username)->getOne('users', 'id,name'); if (empty($TargetUser)) { Response::fail("Target user doesn't exist"); } if ($TargetUser->id !== $currentUser->id) { $val = $TargetUser->id; } else { unset($TargetUser); } } } else { $col = 'id'; $val = $currentUser->Session['id']; } if (!$Database->where($col, $val)->delete('sessions')) { Response::fail('Could not remove information from database'); } if (empty($TargetUser)) { Cookie::delete('access', Cookie::HTTPONLY); } Response::done();
} $insert = array('preview' => $Image->preview, 'fullsize' => $Image->fullsize); $season = Episodes::validateSeason(Episodes::ALLOW_MOVIES); $episode = Episodes::validateEpisode(); $epdata = Episodes::getActual($season, $episode, Episodes::ALLOW_MOVIES); if (empty($epdata)) { Response::fail("The specified episode (S{$season}E{$episode}) does not exist"); } $insert['season'] = $epdata->season; $insert['episode'] = $epdata->episode; $ByID = $currentUser->id; if (Permission::sufficient('developer')) { $username = Posts::validatePostAs(); if (isset($username)) { $PostAs = Users::get($username, 'name', 'id,role'); if (empty($PostAs)) { Response::fail('The user you wanted to post as does not exist'); } if ($type === 'reservation' && !Permission::sufficient('member', $PostAs->role) && !isset($_POST['allow_nonmember'])) { Response::fail('The user you wanted to post as is not a club member, do you want to post as them anyway?', array('canforce' => true)); } $ByID = $PostAs->id; } } $insert[$type === 'reservation' ? 'reserved_by' : 'requested_by'] = $ByID; Posts::checkPostDetails($type, $insert); $PostID = $Database->insert("{$type}s", $insert, 'id'); if (!$PostID) { Response::dbError(); } Response::done(array('id' => $PostID));
} $title = Episodes::removeTitlePrefix($value); if (Input::checkStringLength($title, $range, $code)) { return $code; } $value = "{$match[1]}: {$title}"; } else { if (Input::checkStringLength($value, $range, $code)) { return $code; } } }, array(Input::IN_RANGE => [5, 35], Input::CUSTOM_ERROR_MESSAGES => array(Input::ERROR_MISSING => "{$What} title is missing", Input::ERROR_RANGE => "{$What} title must be between @min and @max characters", 'prefix-movieonly' => "Prefixes can only be used for movies"))))->out(); CoreUtils::checkStringValidity($insert['title'], "{$What} title", INVERSE_EP_TITLE_PATTERN); $airs = (new Input('airs', 'timestamp', array(Input::CUSTOM_ERROR_MESSAGES => array(Input::ERROR_MISSING => 'No air date & time specified', Input::ERROR_INVALID => 'Invalid air date and/or time (@value) specified'))))->out(); if (empty($airs)) { Response::fail('Please specify an air date & time'); } $insert['airs'] = date('c', strtotime('this minute', $airs)); if ($editing) { if (!$Database->whereEp($Episode)->update('episodes', $insert)) { Response::dbError('Updating episode failed'); } } else { if (!$Database->insert('episodes', $insert)) { Response::dbError('Episode creation failed'); } } if (!$editing || $SeasonChanged || $EpisodeChanged) { if ($isMovie) { if ($EpisodeChanged) { $TagName = CGUtils::checkEpisodeTagName("movie#{$insert['episode']}");
use App\RegExp; use App\Response; /** @var $data string */ if (!Permission::sufficient('staff') || !POST_REQUEST) { CoreUtils::notFound(); } CSRFProtection::protect(); if (!preg_match(new RegExp('^([gs]et)/([a-z_]+)$'), CoreUtils::trim($data), $_match)) { Response::fail('Setting key invalid'); } $getting = $_match[1] === 'get'; $key = $_match[2]; $currvalue = GlobalSettings::get($key); if ($getting) { Response::done(array('value' => $currvalue)); } if (!isset($_POST['value'])) { Response::fail('Missing setting value'); } try { $newvalue = GlobalSettings::process($key); } catch (Exception $e) { Response::fail('Preference value error: ' . $e->getMessage()); } if ($newvalue === $currvalue) { Response::done(array('value' => $newvalue)); } if (!GlobalSettings::set($key, $newvalue)) { Response::dbError(); } Response::done(array('value' => $newvalue));
/** * Caches information about a deviation in the 'deviation_cache' table * Returns null on failure * * @param string $ID * @param null|string $type * @param bool $mass * * @return array|null */ static function getCachedSubmission($ID, $type = 'fav.me', $mass = false) { global $Database, $FULLSIZE_MATCH_REGEX; if ($type === 'sta.sh') { $ID = CoreUtils::nomralizeStashID($ID); } $Deviation = $Database->where('id', $ID)->where('provider', $type)->getOne('deviation_cache'); $cacheExhausted = self::$_MASS_CACHE_USED > self::$_MASS_CACHE_LIMIT; $cacheExpired = empty($Deviation['updated_on']) ? true : strtotime($Deviation['updated_on']) + Time::$IN_SECONDS['hour'] * 12 < time(); $lastRequestSuccessful = !self::$_CACHE_BAILOUT; $localDataMissing = empty($Deviation); $massCachingWithinLimit = $mass && !$cacheExhausted; $notMassCachingAndCacheExpired = !$mass && $cacheExpired; if ($lastRequestSuccessful && ($localDataMissing || ($massCachingWithinLimit && $cacheExpired || $notMassCachingAndCacheExpired))) { try { $json = self::oEmbed($ID, $type); if (empty($json)) { throw new \Exception(); } } catch (\Exception $e) { if (!empty($Deviation)) { $Database->where('id', $Deviation['id'])->update('deviation_cache', array('updated_on' => date('c', time() + Time::$IN_SECONDS['minute']))); } $ErrorMSG = "Saving local data for {$ID}@{$type} failed: " . $e->getMessage(); if (!Permission::sufficient('developer')) { trigger_error($ErrorMSG); } if (POST_REQUEST) { Response::fail($ErrorMSG); } else { echo "<div class='notice fail'><label>da_cache_deviation({$ID}, {$type})</label><p>{$ErrorMSG}</p></div>"; } self::$_CACHE_BAILOUT = true; return $Deviation; } $insert = array('title' => preg_replace(new RegExp('\\\\\''), "'", $json['title']), 'preview' => URL::makeHttps($json['thumbnail_url']), 'fullsize' => URL::makeHttps(isset($json['fullsize_url']) ? $json['fullsize_url'] : $json['url']), 'provider' => $type, 'author' => $json['author_name'], 'updated_on' => date('c')); if (!preg_match($FULLSIZE_MATCH_REGEX, $insert['fullsize'])) { $fullsize_attempt = CoreUtils::getFullsizeURL($ID, $type); if (is_string($fullsize_attempt)) { $insert['fullsize'] = $fullsize_attempt; } } if (empty($Deviation)) { $Deviation = $Database->where('id', $ID)->where('provider', $type)->getOne('deviation_cache'); } if (empty($Deviation)) { $insert['id'] = $ID; $Database->insert('deviation_cache', $insert); } else { $Database->where('id', $Deviation['id'])->update('deviation_cache', $insert); $insert['id'] = $ID; } self::$_MASS_CACHE_USED++; $Deviation = $insert; } else { if (!empty($Deviation['updated_on'])) { $Deviation['updated_on'] = date('c', strtotime($Deviation['updated_on'])); if (self::$_CACHE_BAILOUT) { $Database->where('id', $Deviation['id'])->update('deviation_cache', array('updated_on' => $Deviation['updated_on'])); } } } return $Deviation; }
$query = $creating ? $Database->insert('usefullinks', $data) : $Database->where('id', $Link['id'])->update('usefullinks', $data); if (!$query) { Response::dbError(); } Response::done(); break; default: CoreUtils::notFound(); } } else { if ($data === 'reorder') { $list = (new Input('list', 'int[]', array(Input::CUSTOM_ERROR_MESSAGES => array(Input::ERROR_MISSING => 'Missing ordering information'))))->out(); $order = 1; foreach ($list as $id) { if (!$Database->where('id', $id)->update('usefullinks', array('order' => $order++))) { Response::fail("Updating link #{$id} failed, process halted"); } } Response::done(); } else { CoreUtils::notFound(); } } break; default: CoreUtils::notFound(); } } if (empty($task)) { CoreUtils::loadPage(array('title' => 'Admin Area', 'do-css', 'js' => array('Sortable', $do))); }
/** * Check maximum simultaneous reservation count * * @param bool $return_as_bool * * @return bool|null */ static function reservationLimitExceeded(bool $return_as_bool = false) { global $Database, $currentUser; $reservations = $Database->rawQuerySingle('SELECT ( (SELECT COUNT(*) as "count" FROM reservations res WHERE res.reserved_by = u.id && res.deviation_id IS NULL) +(SELECT COUNT(*) as "count" FROM requests req WHERE req.reserved_by = u.id && req.deviation_id IS NULL) ) as "count" FROM users u WHERE u.id = ?', array($currentUser->id)); $overTheLimit = isset($reservations['count']) && $reservations['count'] >= 4; if ($return_as_bool) { return $overTheLimit; } if ($overTheLimit) { Response::fail("You've already reserved {$reservations['count']} images, and you can't have more than 4 pending reservations at a time. You can review your reservations on your <a href='/user'>Account page</a>, finish at least one of them before trying to reserve another image."); } }
if (!empty($search['hits']['hits'])) { $ids = []; foreach ($search['hits']['hits'] as $hit) { $ids[] = $hit['_id']; } $Ponies = $CGDb->where('id IN (' . implode(',', $ids) . ')')->orderBy('order', 'ASC')->get('appearances'); } } if (!$elasticAvail) { $_EntryCount = $CGDb->where('ishuman', $EQG)->where('id != 0')->count('appearances'); $Pagination = new Pagination('cg', $AppearancesPerPage, $_EntryCount); $Ponies = Appearances::get($EQG, $Pagination->getLimit()); } if (isset($_REQUEST['GOFAST'])) { if (empty($Ponies[0]['id'])) { Response::fail('The search returned no results.'); } Response::done(array('goto' => "{$CGPath}/v/{$Ponies[0]['id']}-" . Appearances::getSafeLabel($Ponies[0]))); } CoreUtils::fixPath("{$CGPath}/{$Pagination->page}" . (!empty($Restrictions) ? "?q={$SearchQuery}" : '')); $heading = ($EQG ? 'EQG ' : '') . "{$Color} Guide"; $title .= "Page {$Pagination->page} - {$heading}"; if (isset($_GET['js'])) { $Pagination->respond(Appearances::getHTML($Ponies, NOWRAP), '#list'); } $settings = array('title' => $title, 'heading' => $heading, 'css' => array($do), 'js' => array('jquery.qtip', 'jquery.ctxmenu', $do, 'paginate')); if (Permission::sufficient('staff')) { $settings['css'] = array_merge($settings['css'], $GUIDE_MANAGE_CSS); $settings['js'] = array_merge($settings['js'], $GUIDE_MANAGE_JS); } CoreUtils::loadPage($settings);
if (preg_match(new RegExp('^(un-)?banish/' . USERNAME_PATTERN . '$'), $data, $_match)) { $Action = (empty($_match[1]) ? 'Ban' : 'Un-ban') . 'ish'; $action = strtolower($Action); $un = $_match[2]; $targetUser = Users::get($un, 'name'); if (empty($targetUser)) { Response::fail('User not found'); } if ($targetUser->id === $currentUser->id) { Response::fail("You cannot {$action} yourself"); } if (Permission::sufficient('staff', $targetUser->role)) { Response::fail("You cannot {$action} people within the assistant or any higher group"); } if ($action == 'banish' && $targetUser->role === 'ban' || $action == 'un-banish' && $targetUser->role !== 'ban') { Response::fail("This user has already been {$action}ed"); } $reason = (new Input('reason', 'string', array(Input::IN_RANGE => [5, 255], Input::CUSTOM_ERROR_MESSAGES => array(Input::ERROR_MISSING => 'Please specify a reason', Input::ERROR_RANGE => 'Reason length must be between @min and @max characters'))))->out(); $changes = array('role' => $action == 'banish' ? 'ban' : 'user'); $Database->where('id', $targetUser->id)->update('users', $changes); Logs::action($action, array('target' => $targetUser->id, 'reason' => $reason)); $changes['role'] = Permission::ROLES_ASSOC[$changes['role']]; $changes['badge'] = Permission::labelInitials($changes['role']); if ($action == 'banish') { Response::done($changes); } Response::success("We welcome {$targetUser->name} back with open hooves!", $changes); } else { CoreUtils::notFound(); } }
static function safeMarkRead($NotifID, $action = null) { try { Notifications::markRead($NotifID, $action); } catch (ServerConnectionFailureException $e) { error_log("Notification server down!\n" . $e->getMessage()); Response::fail('Notification server is down! Please <a class="send-feedback">let us know</a>.'); } catch (\Exception $e) { error_log("SocketEvent Error\n" . $e->getMessage()); Response::fail('SocketEvent Error: ' . $e->getMessage()); } }
/** * Checks the image which allows a request to be finished * * @param string|null $ReserverID * * @return array */ static function checkRequestFinishingImage($ReserverID = null) { global $Database; $deviation = (new Input('deviation', 'string', array(Input::CUSTOM_ERROR_MESSAGES => array(Input::ERROR_MISSING => 'Please specify a deviation URL'))))->out(); try { $Image = new ImageProvider($deviation, array('fav.me', 'dA')); foreach (Posts::$TYPES as $what) { if ($Database->where('deviation_id', $Image->id)->has("{$what}s")) { Response::fail("This exact deviation has already been marked as the finished version of a different {$what}"); } } $return = array('deviation_id' => $Image->id); $Deviation = DeviantArt::getCachedSubmission($Image->id); if (!empty($Deviation['author'])) { $Author = Users::get($Deviation['author'], 'name'); if (!empty($Author)) { if (!isset($_POST['allow_overwrite_reserver']) && !empty($ReserverID) && $Author->id !== $ReserverID) { global $currentUser; $sameUser = $currentUser->id === $ReserverID; $person = $sameUser ? 'you' : 'the user who reserved this post'; Response::fail("You've linked to an image which was not submitted by {$person}. If this was intentional, press Continue to proceed with marking the post finished <b>but</b> note that it will make {$Author->name} the new reserver." . ($sameUser ? "<br><br>This means that you'll no longer be able to interact with this post until {$Author->name} or an administrator cancels the reservation on it." : ''), array('retry' => true)); } $return['reserved_by'] = $Author->id; } } if (CoreUtils::isDeviationInClub($return['deviation_id']) === true) { $return['lock'] = true; } return $return; } catch (MismatchedProviderException $e) { Response::fail('The finished vector must be uploaded to DeviantArt, ' . $e->getActualProvider() . ' links are not allowed'); } catch (\Exception $e) { Response::fail($e->getMessage()); } }
static function reindex() { global $CGDb; $elasticClient = CoreUtils::elasticClient(); try { $elasticClient->indices()->delete(CGUtils::ELASTIC_BASE); } catch (ElasticMissing404Exception $e) { $message = JSON::decode($e->getMessage()); // Eat exception if the index we're re-creating does not exist yet if ($message['error']['type'] !== 'index_not_found_exception' || $message['error']['index'] !== CGUtils::ELASTIC_BASE['index']) { throw $e; } } catch (ElasticNoNodesAvailableException $e) { Response::fail('Re-index failed, ElasticSearch server is down!'); } $params = array_merge(CGUtils::ELASTIC_BASE, ["body" => ["mappings" => ["entry" => ["_all" => ["enabled" => false], "properties" => ["label" => ["type" => "text", "analyzer" => "overkill"], "order" => ["type" => "integer"], "ishuman" => ["type" => "boolean"], "private" => ["type" => "boolean"], "tags" => ["type" => "text", "analyzer" => "overkill"]]]], "settings" => ["analysis" => ["analyzer" => ["overkill" => ["type" => "custom", "tokenizer" => "overkill", "filter" => ["lowercase"]]], "tokenizer" => ["overkill" => ["type" => "edge_ngram", "min_gram" => 2, "max_gram" => 6, "token_chars" => ["letter", "digit"]]]]]]]); $elasticClient->indices()->create(array_merge($params)); $Appearances = $CGDb->where('id != 0')->get('appearances', null, self::ELASTIC_COLUMNS); $params = array('body' => []); foreach ($Appearances as $i => $a) { $meta = self::getElasticMeta($a); $params['body'][] = ['index' => ['_index' => $meta['index'], '_type' => $meta['type'], '_id' => $meta['id']]]; $params['body'][] = self::getElasticBody($a); if ($i % 100 == 0) { $elasticClient->bulk($params); $params = ['body' => []]; } } if (!empty($params['body'])) { $elasticClient->bulk($params); } Response::success('Re-index completed'); }
if (empty(Notifications::$ACTIONABLE_NOTIF_OPTIONS[$Notif['type']][$read_action])) { Response::fail("Invalid read action ({$action}) specified for notification type {$Notif['type']}"); } /** @var $data array */ $data = !empty($Notif['data']) ? JSON::decode($Notif['data']) : null; switch ($Notif['type']) { case "post-passon": $Post = $Database->where('id', $data['id'])->getOne("{$data['type']}s"); if (empty($Post)) { Posts::clearTransferAttempts($Post, $data['type'], 'del'); Response::fail("The {$data['type']} doesn't exist or has been deleted"); } if ($read_action === 'true') { if ($Post['reserved_by'] !== $currentUser->id) { Posts::clearTransferAttempts($Post, $data['type'], 'perm', null, $currentUser->id); Response::fail('You are not allowed to transfer this reservation'); } Notifications::safeMarkRead($Notif['id'], $read_action); Notifications::send($data['user'], "post-passallow", array('id' => $data['id'], 'type' => $data['type'], 'by' => $currentUser->id)); $Database->where('id', $data['id'])->update("{$data['type']}s", array('reserved_by' => $data['user'], 'reserved_at' => date('c'))); Posts::clearTransferAttempts($Post, $data['type'], 'deny'); Logs::action('res_transfer', array('id' => $data['id'], 'type' => $data['type'], 'to' => $data['user'])); } else { Notifications::safeMarkRead($Notif['id'], $read_action); Notifications::send($data['user'], "post-passdeny", array('id' => $data['id'], 'type' => $data['type'], 'by' => $currentUser->id)); } Response::done(); break; default: Notifications::safeMarkRead($Notif['id'], $read_action); }