init(); } /** * @return static */ public static function i() { bff()->singletonIf('listings.item.claims', static::class); return bff('listings.item.claims'); } /** * Claims predefined reasons list * @param string|null $lang * @return array */ public function getReasons(?string $lang = null): array { return Options::getOptions('listings-item-claim-reasons', $lang ?? $this->locale->current()); } /** * Add claim by user * @param int $itemId * @param int $userId * @param array $reasons claim reasons * @param string $message claim description * @param array $opts [messageMinimum, throttle] * @return bool */ public function add($itemId, $userId, array $reasons, string $message = '', array $opts = []) { if (! $itemId) { $this->errors->reloadPage(); return false; } $opts = $this->defaults($opts, [ 'throttle' => [], 'messageMinimum' => 10, ]); $reason = array_sum($reasons); if (! $reason) { $this->errors->set(_t('item-claim', 'Specify the reason')); return false; } if ($reason & static::WITH_MESSAGE) { if ($opts['messageMinimum'] > 0 && (mb_strlen($message) < $opts['messageMinimum'])) { $this->errors->set(_t('item-claim', 'Describe the reason in more details'), 'comment'); return false; } } if (! empty($opts['throttle'])) { $throttle = is_array($opts['throttle']) ? $opts['throttle'] : []; if ($this->tooManyRequests($throttle['actionKey'] ?? 'listings-item-claim', $throttle)) { return false; } } $claimId = Listings::model()->claimSave(0, [ 'reason' => $reason, 'message' => $message, 'item_id' => $itemId, 'user_id' => $userId, ]); if ($claimId > 0) { $this->counterUpdate(1); Listings::model()->itemSave($itemId, [ 'claims_cnt = claims_cnt + 1' ]); ItemClaim::dispatch($claimId, $itemId, $userId); } return true; } /** * Delete claim by admin * @param int $claimId * @param array $opts [] * @return bool */ public function delete($claimId, array $opts = []) { $success = Listings::model()->claimDelete($claimId); if ($success) { $this->counterUpdate(null); } return $success; } /** * View claim by admin * @param int $claimId * @param array $opts [] * @return bool */ public function view($claimId, array $opts = []) { $viewed = Listings::model()->claimSave($claimId, ['viewed' => 1]); if ($viewed) { $this->counterUpdate(null); } return $viewed; } /** * Build claim text (selected reasons + message) * @param int $reasons selected * @param string|null $message text * @return string */ public function toText(int $reasons, ?string $message = null): string { if (! empty($reasons)) { $list = $this->getReasons(); if (! empty($list)) { $text = []; foreach ($list as $k => $v) { if ($k != self::WITH_MESSAGE && ($k & $reasons)) { $text[] = $v; } } if (($reasons & self::WITH_MESSAGE) && ! empty($message)) { $text[] = $message; } return join(', ', $text); } } return ''; } /** * Actualize total number of new (not viewed) claims * @param int|null $increment * @return void */ public function counterUpdate(?int $increment) { if (is_null($increment)) { $count = Listings::model()->claimsListing(['viewed' => 0], true); $this->app->config()->save($this->counter_key, $count, true); } else { $this->app->config()->saveCount($this->counter_key, $increment, true); } } }