setTitle(_t('@users', 'Account') . ' / ' . _t('@listings', 'My listings')); $this->setKey('account.listings'); $this->setTemplate('account/items', 'listings'); $this->setContentTitle(_t('listings', 'Listings')); } public function blocks() { $this->addBlock('listBlock', function () { $view = $this->app->filter('listings.account.list.view', ListBlock::class); return new $view(); }); } public function handle() { $this->userId = $this->request->userId(); if ($status = $this->checkAccountStatus()) { return $status; } $this->fillFilter(); return $this; } public function checkAccountStatus() { if (! $this->userId) { return Listings::showInlineMessage(_t('users', 'To access your profile you need to Log In'), [ 'auth' => true, ]); } if (Listings::publisher(Listings::PUBLISHER_COMPANY) && !User::companyID()) { return Listings::showInlineMessage(_t('listings.my', 'Open company to be able to publish listings.', [ 'open_link' => 'href="' . Business::url('company.open') . '"', ])); } return false; } public function data() { $data = parent::data(); $filter = $this->prepareFilter(); /** @var ListBlock $list */ $list = $this->getBlock('listBlock'); $list->loadItems($filter); $data['counters'] = []; foreach ($this->statusList as $k => $v) { $filterCopy = $filter; $v['filter']($filterCopy); unset($this->statusList[$k]['filter']); $data['counters'][$k] = Listings::model()->itemsListMy($filterCopy, true); } # список категорий (фильтр) $catsList = [0 => ['id' => 0, 'title' => _t('listings', 'All Categories')]]; $catsList += Listings::model()->itemsListCategoriesMain([ 'user_id' => $this->userId, 'company_id' => $this->companyId, ]); $data['cats'] = &$catsList; $data['categoryData'] = $catsList[$this->categoryId] ?? $catsList[0]; $data['cats'] = Listings::template('account/items.cats', $data); if ($this->isAJAX()) { return $this->ajaxResponseForm([ 'pages' => $this->pages, 'list' => (string)$list, 'cats' => $data['cats'], 'total' => $this->total, 'counters' => $data['counters'], ]); } $data['company_id'] = User::companyID(); $data['company'] = ($this->companyId ? 1 : 0); $data['empty'] = !$this->total; $data['alerts'] = []; $data['errors'] = $this->errors->get(); # проверим превышение лимита, для вывода сообщения в кабинете Listings::limitsExceed([ 'user_id' => $this->userId, 'company_id' => $this->companyId, ], [ 'silent' => true, 'getAlert' => function ($html) use (&$data) { $data['alerts'][] = $html; } ]); if (bff::servicesEnabled('listings')) { # бесплатное поднятие $up = Listings::itemServices('up'); if ($up && $up->getFreePeriod() > 0) { $data['upFree'] = true; } } return $data; } public function fillFilter() { $this->filter = [ 'user_id' => $this->userId, 'company_id' => $this->companyId, ]; $this->categoryId = $this->input->postget('c', TYPE_UINT); $this->query = $this->input->postget('qq', TYPE_NOTAGS); $this->query = $this->input->cleanSearchString($this->query, 50); $this->page = $this->input->postget('page', TYPE_UINT); $this->pageSize = $this->input->postget('pp', TYPE_INT); $this->pageSizesList = [ -1 => ['t' => _t('pgn', 'show all'), 'c' => 100], 15 => ['t' => _t('pgn', '[cnt] per page', ['cnt' => 15]), 'c' => 15], 25 => ['t' => _t('pgn', '[cnt] per page', ['cnt' => 25]), 'c' => 25], 50 => ['t' => _t('pgn', '[cnt] per page', ['cnt' => 50]), 'c' => 50], ]; if (! isset($this->pageSizesList[$this->pageSize])) { $this->pageSize = 15; } $this->orderBy = $this->input->postget('or', TYPE_UINT); $this->orderByList = [ 0 => ['t' => _t('listings.my', 'The newest')], 1 => ['t' => _t('listings.my', 'Oldest')], ]; $this->statusId = $this->input->postget('status', TYPE_UINT); if (Listings::premoderation()) { $this->statusList = $this->app->filter('listings.items.my.status.list', [ 1 => [ 'title' => _t('listings.my', 'Active'), 'left' => false, 'right' => 2, 'filter' => function (&$filter) { $filter['is_publicated'] = 1; $filter['status'] = Listings::STATUS_PUBLICATED; unset($filter['is_moderating']); return $filter; } ], 2 => [ 'title' => _t('listings.my', 'On check'), 'left' => 1, 'right' => 3, 'filter' => function (&$filter) { $filter['is_publicated'] = 0; $filter['status'] = ['!=', Listings::STATUS_DELETED]; $filter['is_moderating'] = 1; return $filter; } ], 3 => [ 'title' => _t('listings.my', 'Inactive'), 'left' => 2, 'right' => 4, 'filter' => function (&$filter) { $filter['is_publicated'] = 0; $filter['status'] = Listings::STATUS_PUBLICATED_OUT; $filter['is_moderating'] = 0; return $filter; } ], 4 => [ 'title' => _t('listings.my', 'Blocked'), 'left' => 3, 'right' => false, 'filter' => function (&$filter) { $filter['is_publicated'] = 0; $filter['status'] = Listings::STATUS_BLOCKED; $filter['is_moderating'] = 0; return $filter; } ], ]); } else { $this->statusList = $this->app->filter('listings.items.my.status.list', [ 1 => [ 'title' => _t('listings.my', 'Active'), 'left' => false, 'right' => 2, 'filter' => function (&$filter) { $filter['is_publicated'] = 1; $filter['status'] = Listings::STATUS_PUBLICATED; return $filter; } ], 2 => [ 'title' => _t('listings.my', 'On check'), 'left' => 1, 'right' => 3, 'filter' => function (&$filter) { $filter['is_publicated'] = 0; $filter['status'] = Listings::STATUS_BLOCKED; return $filter; } ], 3 => [ 'title' => _t('listings.my', 'Inactive'), 'left' => 2, 'right' => false, 'filter' => function (&$filter) { $filter['is_publicated'] = 0; $filter['status'] = Listings::STATUS_PUBLICATED_OUT; return $filter; } ], ]); } if (! array_key_exists($this->statusId, $this->statusList)) { $this->statusId = key($this->statusList); } } public function prepareFilter(): array { $filter = $this->filter; if ($this->categoryId > 0) { $filter[':cat-filter'] = $this->categoryId; } if (! empty($this->query)) { $filter[':query'] = $this->query; } # дополняем фильтрами по статусу $this->statusList[$this->statusId]['filter']($filter); return $filter; } /** * Массовая публикация по ссылке из уведомления listings_item_unpublicated_soon_group */ public function onEmailPublicateAction() { do { $day = $this->input->get('day', TYPE_NOTAGS); if (empty($day)) { break; } $day = strtotime($day); if (! $day || $day < time() || ($day - Listings::PUBLICATION_SOON_LEFT) > time()) { break; } $itemsList = Listings::model()->itemsUserUnpublicateDay($this->userId, $day); if (empty($itemsList)) { break; } $itemsId = []; foreach ($itemsList as $v) { $itemsId[] = $v['id']; } # Force current company ID todo $this->companyId = User::companyID(); if ( Listings::limitsExceed([ 'user_id' => $this->userId, 'id' => $itemsId, ]) ) { break; } if (! $this->errors->no()) { break; } $cnt = Listings::model()->itemsRefresh([ 'id' => $itemsId, 'user_id' => $this->userId, 'status' => Listings::STATUS_PUBLICATED, ]); if ($cnt) { $this->messages[] = _t('listings', 'The publishing for [cnt] has been extended.', [ 'cnt' => tpl::declension($cnt, _t('listings', 'listings;listings;listings')), ]); } } while (false); return null; # отрисовываем страницу } /** * Массовое поднятие объявлений по ссылке из уведомления listings_item_upfree_group */ public function onEmailUpFreeAction() { do { if (! bff::servicesEnabled('listings')) { break; } if ($up = Listings::itemServices('up')) { $up->emailUpFree($this->messages); } } while (false); return null; # отрисовываем страницу } /** * Массовая публикация * @return bff\http\Response */ public function onMassPublicateAction() { do { $itemsId = $this->massItemsIDs(); if ($this->errors->any()) { break; } if ( Listings::limitsExceed([ 'user_id' => $this->userId, 'company_id' => $this->companyId, 'id' => $itemsId, ]) ) { break; } $publicateFilter = [ 'id' => $itemsId, 'user_id' => $this->userId, 'is_publicated' => 0, 'status' => Listings::STATUS_PUBLICATED_OUT, ]; if (Listings::premoderation()) { $publicateFilter[] = 'moderated > 0'; } $cnt = Listings::model()->itemsPublicate($publicateFilter, Listings::itemPublicationPeriod()->refreshTo()); $this->respond('cnt', $cnt); if (! empty($cnt)) { $this->respond('message', _t('listings.my', 'Selected listings were published successfully')); } } while (false); return $this->massRespond(); } /** * Массовое снятие с публикации * @return bff\http\Response */ public function onMassUnpublicateAction() { $itemsId = $this->massItemsIDs(); if ($this->errors->no()) { $cnt = Listings::model()->itemsUnpublicate([ 'id' => $itemsId, 'user_id' => $this->userId, 'is_publicated' => 1, 'status' => Listings::STATUS_PUBLICATED, ]); $this->respond('cnt', $cnt); if (! empty($cnt)) { $this->respond('message', _t('listings.my', 'Selected listings were removed from published successfully')); } } return $this->massRespond(); } /** * Массовое продление * @return bff\http\Response */ public function onMassRefreshAction() { do { $itemsId = $this->massItemsIDs(); if ($this->errors->any()) { break; } if ( Listings::limitsExceed([ 'id' => $itemsId, 'user_id' => $this->userId, 'company_id' => $this->companyId, ]) ) { break; } $cnt = Listings::model()->itemsRefresh([ 'id' => $itemsId, 'user_id' => $this->userId, 'is_publicated' => 1, 'status' => Listings::STATUS_PUBLICATED, ]); $this->respond('cnt', $cnt); if (! empty($cnt)) { $this->respond('message', _t('listings.my', 'Selected listings were prolonged successfully')); } } while (false); return $this->massRespond(); } /** * Массовое удаление * @return bff\http\Response */ public function onMassDeleteAction() { do { $itemsId = $this->massItemsIDs(); if ($this->errors->any()) { break; } $cnt = Listings::model()->itemsUpdateByFilter([ 'publicated_to' => $this->db->now(), # помечаем дату снятия с публикации 'status_prev = status', 'status_changed' => $this->db->now(), 'status' => Listings::STATUS_DELETED, 'deleted' => 1, 'is_publicated' => 0, 'is_moderating' => 0, ], [ 'id' => $itemsId, 'user_id' => $this->userId, # для удаления доступны только снятые с публикации или заблокированные 'is_publicated' => 0, 'status' => [Listings::STATUS_PUBLICATED_OUT, Listings::STATUS_BLOCKED], 'deleted' => 0, ], [ 'context' => 'user-cabinet-mass-delete', ]); $this->respond('cnt', $cnt); if ($cnt) { $this->respond('message', _t('listings', 'Selected listings were successfully deleted')); $this->respond('id', $itemsId); } } while (false); return $this->massRespond(); } /** * Массовое поднятие бесплатно * @return bff\http\Response */ public function onMassUpFreeAction() { do { $itemsId = $this->massItemsIDs(); if ($this->errors->any()) { break; } $up = Listings::itemServices('up'); if ($up) { $up->upFreeMass($itemsId, $response); } } while (false); return $this->massRespond(); } /** * Получение id объявлений для массовых операций * @return array|mixed */ protected function massItemsIDs() { do { if (! $this->isRequestValid()) { $this->errors->reloadPage(); break; } $ids = $this->input->post('i', TYPE_ARRAY_UINT); if (empty($ids)) { $this->errors->set(_t('listings.my', 'You need to select at leas one listing')); break; } if ($this->input->post('select_all', TYPE_UINT)) { $filter = $this->prepareFilter(); $ids = $this->getBlock('listBlock')->loadItems($filter, true); if (empty($ids)) { $this->errors->reloadPage(); break; } } return $ids; } while (false); return []; } /** * Ajax ответ для массовых операций * @return bff\http\Response */ protected function massRespond() { $alerts = []; # проверим превышение лимита, для вывода алерта в кабинете Listings::limitsExceed([ 'user_id' => $this->userId, 'company_id' => $this->companyId, ], [ 'silent' => true, 'getAlert' => function ($html) use (&$alerts) { $alerts[] = $html; } ]); $this->respond('alerts', join('', $alerts)); return $this->getActionResponse(); } }