diff --git a/application/classes/actions/ActionContent.class.php b/application/classes/actions/ActionContent.class.php index 8fae32d0..d9ca3c5f 100644 --- a/application/classes/actions/ActionContent.class.php +++ b/application/classes/actions/ActionContent.class.php @@ -87,6 +87,7 @@ class ActionContent extends Action $this->AddEventPreg('/^published$/i', '/^(page([1-9]\d{0,5}))?$/i', 'EventShowTopics'); $this->AddEventPreg('/^drafts$/i', '/^(page([1-9]\d{0,5}))?$/i', 'EventShowTopics'); + $this->AddEventPreg('/^deferred$/i', '/^(page([1-9]\d{0,5}))?$/i', 'EventShowTopics'); $this->AddEventPreg('/^ajax$/i', '/^add$/i', '/^$/i', 'EventAjaxAdd'); $this->AddEventPreg('/^ajax$/i', '/^edit$/i', '/^$/i', 'EventAjaxEdit'); @@ -116,8 +117,13 @@ class ActionContent extends Action /** * Получаем список топиков */ - $aResult = $this->Topic_GetTopicsPersonalByUser($this->oUserCurrent->getId(), - $this->sCurrentEvent == 'published' ? 1 : 0, $iPage, Config::Get('module.topic.per_page')); + if ($this->sCurrentEvent == 'deferred') { + $aResult = $this->Topic_GetTopicsPersonalDeferredByUser($this->oUserCurrent->getId(), $iPage, Config::Get('module.topic.per_page')); + $this->SetTemplateAction('drafts'); + } else { + $aResult = $this->Topic_GetTopicsPersonalByUser($this->oUserCurrent->getId(), + $this->sCurrentEvent == 'published' ? 1 : 0, $iPage, Config::Get('module.topic.per_page')); + } $aTopics = $aResult['collection']; /** * Формируем постраничность @@ -340,20 +346,6 @@ class ActionContent extends Action if (!$oTopic->getTags() or !$oTopic->getTypeObject()->getParam('allow_tags')) { $oTopic->setTags(''); } - /** - * Публикуем или сохраняем в черновиках - */ - $bSendNotify = false; - if (!isset($_REQUEST['is_draft'])) { - $oTopic->setPublish(1); - if ($oTopic->getPublishDraft() == 0) { - $oTopic->setPublishDraft(1); - $oTopic->setDatePublish(date("Y-m-d H:i:s")); - $bSendNotify = true; - } - } else { - $oTopic->setPublish(0); - } /** * Принудительный вывод на главную */ @@ -388,6 +380,27 @@ class ActionContent extends Action $this->Hook_Run('topic_edit_validate_before', array('oTopic' => $oTopic)); if ($oTopic->_Validate()) { + /** + * Публикуем или сохраняем в черновиках + */ + $bSendNotify = false; + if (!isset($_REQUEST['is_draft'])) { + $oTopic->setPublish(1); + if ($oTopic->getPublishDraft() == 0) { + $oTopic->setPublishDraft(1); + $oTopic->setDatePublish(date("Y-m-d H:i:s")); + $bSendNotify = true; + } + } else { + $oTopic->setPublish(0); + } + /** + * Отложенная публикация + */ + if ($oTopic->getPublishDateRaw()) { + $oTopic->setDatePublish(date("Y-m-d H:i:s", $oTopic->getPublishDateRaw())); + $bSendNotify = false; + } $oBlog = $oTopic->getBlog(); /** * Получаемый и устанавливаем разрезанный текст по тегу @@ -433,7 +446,7 @@ class ActionContent extends Action * Добавляем событие в ленту */ $this->Stream_write($oTopic->getUserId(), 'add_topic', $oTopic->getId(), - $oTopic->getPublish() && $oBlog->getType() != 'close'); + $oTopic->getPublish() && $oBlog->getType() != 'close', $oTopic->getDatePublish()); /** * Рассылаем о новом топике подписчикам блога */ @@ -526,6 +539,9 @@ class ActionContent extends Action $this->Hook_Run('topic_add_validate_before', array('oTopic' => $oTopic)); if ($oTopic->_Validate()) { + if ($oTopic->getPublishDateRaw()) { + $oTopic->setDatePublish(date("Y-m-d H:i:s", $oTopic->getPublishDateRaw())); + } $oBlog = $oTopic->getBlog(); /** * Получаем и устанавливаем разрезанный текст по тегу @@ -578,15 +594,14 @@ class ActionContent extends Action /** * Делаем рассылку спама всем, кто состоит в этом блоге */ - if ($oTopic->getPublish() == 1 and $oBlog->getType() != 'personal') { + if ($oTopic->getPublish() == 1 and $oBlog->getType() != 'personal' and strtotime($oTopic->getDatePublish()) <= time()) { $this->Topic_SendNotifyTopicNew($oTopic, $oUser); } /** * Добавляем событие в ленту */ $this->Stream_write($oTopic->getUserId(), 'add_topic', $oTopic->getId(), - $oTopic->getPublish() && $oBlog->getType() != 'close'); - + $oTopic->getPublish() && $oBlog->getType() != 'close', $oTopic->getDatePublish()); $this->Viewer_AssignAjax('sUrlRedirect', $oTopic->getUrl()); $this->Message_AddNotice($this->Lang_Get('topic.add.notices.create_complete'), $this->Lang_Get('common.attention')); diff --git a/application/classes/modules/stream/Stream.class.php b/application/classes/modules/stream/Stream.class.php index af584daa..27b3509c 100644 --- a/application/classes/modules/stream/Stream.class.php +++ b/application/classes/modules/stream/Stream.class.php @@ -177,9 +177,10 @@ class ModuleStream extends Module * @param string $sEventType Тип события * @param int $iTargetId ID владельца * @param int $iPublish Статус + * @param string|int|null $sDateCreate Дата создания события * @return bool */ - public function Write($iUserId, $sEventType, $iTargetId, $iPublish = 1) + public function Write($iUserId, $sEventType, $iTargetId, $iPublish = 1, $sDateCreate = null) { $iPublish = (int)$iPublish; if (!$this->IsAllowEventType($sEventType)) { @@ -218,6 +219,11 @@ class ModuleStream extends Module } if ($iPublish) { + if (is_null($sDateCreate)) { + $sDateCreate = date("Y-m-d H:i:s"); + } elseif (is_numeric($sDateCreate)) { + $sDateCreate = date("Y-m-d H:i:s", $sDateCreate); + } /** * Создаем новое событие */ @@ -225,7 +231,7 @@ class ModuleStream extends Module $oEvent->setEventType($sEventType); $oEvent->setUserId($iUserId); $oEvent->setTargetId($iTargetId); - $oEvent->setDateAdded(date("Y-m-d H:i:s")); + $oEvent->setDateAdded($sDateCreate); $oEvent->setPublish($iPublish); $this->AddEvent($oEvent); } diff --git a/application/classes/modules/stream/mapper/Stream.mapper.class.php b/application/classes/modules/stream/mapper/Stream.mapper.class.php index 7b815a1a..bb09e48e 100644 --- a/application/classes/modules/stream/mapper/Stream.mapper.class.php +++ b/application/classes/modules/stream/mapper/Stream.mapper.class.php @@ -116,13 +116,14 @@ class ModuleStream_MapperStream extends Mapper event_type IN (?a) { AND user_id IN (?a) } AND publish = 1 + AND date_added <= ? { AND id < ?d } ORDER BY id DESC { LIMIT 0,?d }'; $aReturn = array(); if ($aRows = $this->oDb->select($sql, $aEventTypes, - (!is_null($aUsersList) and count($aUsersList)) ? $aUsersList : DBSIMPLE_SKIP, + (!is_null($aUsersList) and count($aUsersList)) ? $aUsersList : DBSIMPLE_SKIP, date('Y-m-d H:i:s'), !is_null($iFromId) ? $iFromId : DBSIMPLE_SKIP, !is_null($iCount) ? $iCount : DBSIMPLE_SKIP) ) { foreach ($aRows as $aRow) { @@ -148,9 +149,9 @@ class ModuleStream_MapperStream extends Mapper WHERE event_type IN (?a) { AND user_id IN (?a) } - AND publish = 1 '; + AND publish = 1 AND date_added <= ? '; if ($aRow = $this->oDb->selectRow($sql, $aEventTypes, - (!is_null($aUserId) and count($aUserId)) ? $aUserId : DBSIMPLE_SKIP) + (!is_null($aUserId) and count($aUserId)) ? $aUserId : DBSIMPLE_SKIP, date('Y-m-d H:i:s')) ) { return $aRow['c']; } diff --git a/application/classes/modules/topic/Topic.class.php b/application/classes/modules/topic/Topic.class.php index 15f7633b..8dc3346f 100644 --- a/application/classes/modules/topic/Topic.class.php +++ b/application/classes/modules/topic/Topic.class.php @@ -30,6 +30,7 @@ class ModuleTopic extends Module const TOPIC_TYPE_STATE_ACTIVE = 1; const TOPIC_TYPE_STATE_NOT_ACTIVE = 0; + /** * Объект маппера * @@ -631,6 +632,14 @@ class ModuleTopic extends Module : $this->Favourite_GetCountFavouriteOpenTopicsByUserId($sUserId); } + public function GetTimelifeCacheForTopics() + { + if ($sDate = $this->oMapperTopic->GetNextTopicDatePublish()) { + return abs(strtotime($sDate) - time()); + } + return 60 * 60 * 24 * 1; + } + /** * Список топиков по фильтру * @@ -652,7 +661,7 @@ class ModuleTopic extends Module 'count' => $iCount ); $this->Cache_Set($data, "topic_filter_{$s}_{$iPage}_{$iPerPage}", array('topic_update', 'topic_new'), - 60 * 60 * 24 * 3); + $this->GetTimelifeCacheForTopics()); } $data['collection'] = $this->GetTopicsAdditionalData($data['collection'], $aAllowData); return $data; @@ -669,7 +678,7 @@ class ModuleTopic extends Module $s = serialize($aFilter); if (false === ($data = $this->Cache_Get("topic_count_{$s}"))) { $data = $this->oMapperTopic->GetCountTopics($aFilter); - $this->Cache_Set($data, "topic_count_{$s}", array('topic_update', 'topic_new'), 60 * 60 * 24 * 1); + $this->Cache_Set($data, "topic_count_{$s}", array('topic_update', 'topic_new'), $this->GetTimelifeCacheForTopics()); } return $data; } @@ -688,6 +697,21 @@ class ModuleTopic extends Module )); } + /** + * Количество отложенных у пользователя + * + * @param int $iUserId ID пользователя + * @return int + */ + public function GetCountDeferredTopicsByUserId($iUserId) + { + return $this->GetCountTopicsByFilter(array( + 'user_id' => $iUserId, + 'topic_publish_only' => 1, + 'topic_new' => date('Y-m-d H:i:s', time() + 1) + )); + } + /** * Получает список хороших топиков для вывода на главную страницу(из всех блогов, как коллективных так и персональных) * @@ -1028,6 +1052,34 @@ class ModuleTopic extends Module return $this->GetTopicsByFilter($aFilter, $iPage, $iPerPage); } + /** + * Получает список отложенных топиков по юзеру + * + * @param int $sUserId ID пользователя + * @param int $iPage Номер страницы + * @param int $iPerPage Количество элементов на страницу + * @return array + */ + public function GetTopicsPersonalDeferredByUser($sUserId, $iPage, $iPerPage) + { + $aFilter = array( + 'topic_publish_only' => 1, + 'topic_new' => date('Y-m-d H:i:s', time() + 1), + 'user_id' => $sUserId, + 'blog_type' => array('open', 'personal'), + ); + /** + * Если пользователь смотрит свой профиль, то добавляем в выдачу + * закрытые блоги в которых он состоит + */ + if ($this->oUserCurrent && $this->oUserCurrent->getId() == $sUserId) { + $aFilter['blog_type'][] = 'close'; + } + $this->Hook_Run('get_topics_by_custom_filter', + array('aFilter' => &$aFilter, 'iPage' => $iPage, 'iPerPage' => $iPerPage, 'sMethod' => __FUNCTION__)); + return $this->GetTopicsByFilter($aFilter, $iPage, $iPerPage); + } + /** * Возвращает количество топиков которые создал юзер * diff --git a/application/classes/modules/topic/entity/Topic.entity.class.php b/application/classes/modules/topic/entity/Topic.entity.class.php index 6066a488..39638d8f 100644 --- a/application/classes/modules/topic/entity/Topic.entity.class.php +++ b/application/classes/modules/topic/entity/Topic.entity.class.php @@ -87,6 +87,7 @@ class ModuleTopic_EntityTopic extends Entity $this->aValidateRules[] = array('blogs_id_raw', 'blogs'); $this->aValidateRules[] = array('topic_text_source', 'topic_unique'); $this->aValidateRules[] = array('topic_slug_raw', 'slug_check'); + $this->aValidateRules[] = array('publish_date_raw', 'publish_date_check'); } /** @@ -132,6 +133,46 @@ class ModuleTopic_EntityTopic extends Entity return $this->Lang_Get('topic.add.notices.error_type'); } + /** + * Проверка даты отложенной публикации + * + * @param array $aValue Проверяемое значение + * @param array $aParams Параметры + * @return bool|string + */ + public function ValidatePublishDateCheck($aValue, $aParams) + { + $oTopicType = $this->getTypeObject(); + $oUser = $this->getUserCreator(); + if ($oTopicType and $oTopicType->isAllowCreateDeferredTopic($oUser)) { + if ((!$this->getId() or !$this->getPublishDraft() or ($this->getDatePublish() and strtotime($this->getDatePublish()) > time())) and isset($aValue['date']) and is_string($aValue['date']) and isset($aValue['time']) and is_string($aValue['time'])) { + $sDateFull = $aValue['date'] . ' ' . $aValue['time']; + if ($this->Validate_Validate('date', $sDateFull, array('format' => 'dd.MM.yyyy HH:mm', 'allowEmpty' => true))) { + $sDateFull = strtotime($sDateFull); // для охвата всей минуты + /** + * Переводим дату к серверному часовому поясу + */ + if ($oUser = $this->getUserCreator() and $sTz = $oUser->getSettingsTimezone()) { + $oNow = new DateTime(null, new DateTimeZone($sTz)); + $iTz = $oNow->getOffset() / 3600; + $iDiff = (date('I') + $iTz - (strtotime(date("Y-m-d H:i:s")) - strtotime(gmdate("Y-m-d H:i:s"))) / 3600) * 3600; + $sDateFull = $sDateFull - $iDiff; + } + if ($sDateFull >= strtotime(date('Y-m-d H:i:00'))) { + $this->setPublishDateRaw($sDateFull); + return true; + } else { + return $this->Lang_Get('topic.add.notices.error_publish_date'); + } + } else { + return $this->Lang_Get('topic.add.notices.error_publish_date'); + } + } + } + $this->setPublishDateRaw(null); + return true; + } + /** * Проверка URL топика * diff --git a/application/classes/modules/topic/entity/TopicType.entity.class.php b/application/classes/modules/topic/entity/TopicType.entity.class.php index bb802dc7..1b1bf1c2 100644 --- a/application/classes/modules/topic/entity/TopicType.entity.class.php +++ b/application/classes/modules/topic/entity/TopicType.entity.class.php @@ -47,6 +47,8 @@ class ModuleTopic_EntityTopicType extends Entity $aParamsResult['allow_preview'] = (isset($aParams['allow_preview']) and $aParams['allow_preview']) ? true : false; $aParamsResult['allow_text'] = (isset($aParams['allow_text']) and $aParams['allow_text']) ? true : false; $aParamsResult['allow_tags'] = (isset($aParams['allow_tags']) and $aParams['allow_tags']) ? true : false; + $aParamsResult['allow_deferred_all'] = (isset($aParams['allow_deferred_all']) and $aParams['allow_deferred_all']) ? true : false; + $aParamsResult['allow_deferred_admin'] = (isset($aParams['allow_deferred_admin']) and $aParams['allow_deferred_admin']) ? true : false; $aParamsResult['css_icon'] = (isset($aParams['css_icon']) and is_string($aParams['css_icon']) and $aParams['css_icon']) ? htmlspecialchars($aParams['css_icon']) : null; $this->setParams($aParamsResult); @@ -133,4 +135,12 @@ class ModuleTopic_EntityTopicType extends Entity { return 'topic_' . $this->getCode(); } + + public function isAllowCreateDeferredTopic($oUser) + { + if (!$oUser) { + return false; + } + return $this->getParam('allow_deferred_all') or ($this->getParam('allow_deferred_admin') and $oUser->isAdministrator()); + } } \ No newline at end of file diff --git a/application/classes/modules/topic/mapper/Topic.mapper.class.php b/application/classes/modules/topic/mapper/Topic.mapper.class.php index d83c729e..d679b9f0 100644 --- a/application/classes/modules/topic/mapper/Topic.mapper.class.php +++ b/application/classes/modules/topic/mapper/Topic.mapper.class.php @@ -341,18 +341,20 @@ class ModuleTopic_MapperTopic extends Mapper { $sql = " SELECT - topic_id + tt.topic_id FROM - " . Config::Get('db.table.topic_tag') . " - WHERE - topic_tag_text = ? - { AND blog_id NOT IN (?a) } - ORDER BY topic_id DESC + " . Config::Get('db.table.topic_tag') . " as tt, + " . Config::Get('db.table.topic') . " as t + WHERE + tt.topic_tag_text = ? + AND tt.topic_id = t.topic_id AND t.topic_publish = 1 AND t.topic_date_publish <= ? + { AND tt.blog_id NOT IN (?a) } + ORDER BY tt.topic_id DESC LIMIT ?d, ?d "; $aTopics = array(); if ($aRows = $this->oDb->selectPage( - $iCount, $sql, $sTag, + $iCount, $sql, $sTag, date('Y-m-d H:i:s'), (is_array($aExcludeBlog) && count($aExcludeBlog)) ? $aExcludeBlog : DBSIMPLE_SKIP, ($iCurrPage - 1) * $iPerPage, $iPerPage ) @@ -414,9 +416,10 @@ class ModuleTopic_MapperTopic extends Mapper tt.topic_tag_text, count(tt.topic_tag_text) as count FROM - " . Config::Get('db.table.topic_tag') . " as tt + " . Config::Get('db.table.topic_tag') . " as tt, + " . Config::Get('db.table.topic') . " as t WHERE - 1=1 + tt.topic_id = t.topic_id AND t.topic_publish = 1 AND t.topic_date_publish <= ? {AND tt.topic_id NOT IN(?a) } GROUP BY tt.topic_tag_text @@ -427,7 +430,7 @@ class ModuleTopic_MapperTopic extends Mapper $aReturn = array(); $aReturnSort = array(); if ($aRows = $this->oDb->select( - $sql, + $sql, date('Y-m-d H:i:s'), (is_array($aExcludeTopic) && count($aExcludeTopic)) ? $aExcludeTopic : DBSIMPLE_SKIP, $iLimit ) @@ -458,7 +461,8 @@ class ModuleTopic_MapperTopic extends Mapper count(tt.topic_tag_text) as count FROM " . Config::Get('db.table.topic_tag') . " as tt, - " . Config::Get('db.table.blog') . " as b + " . Config::Get('db.table.blog') . " as b, + " . Config::Get('db.table.topic') . " as t WHERE 1 = 1 { AND tt.user_id = ?d } @@ -466,6 +470,8 @@ class ModuleTopic_MapperTopic extends Mapper tt.blog_id = b.blog_id AND b.blog_type <> 'close' + AND + tt.topic_id = t.topic_id AND t.topic_publish = 1 AND t.topic_date_publish <= ? GROUP BY tt.topic_tag_text ORDER BY @@ -474,7 +480,7 @@ class ModuleTopic_MapperTopic extends Mapper "; $aReturn = array(); $aReturnSort = array(); - if ($aRows = $this->oDb->select($sql, is_null($iUserId) ? DBSIMPLE_SKIP : $iUserId, $iLimit)) { + if ($aRows = $this->oDb->select($sql, is_null($iUserId) ? DBSIMPLE_SKIP : $iUserId, date('Y-m-d H:i:s'), $iLimit)) { foreach ($aRows as $aRow) { $aReturn[mb_strtolower($aRow['topic_tag_text'], 'UTF-8')] = $aRow; } @@ -590,7 +596,7 @@ class ModuleTopic_MapperTopic extends Mapper */ protected function buildFilter($aFilter) { - $sDateNow=date('Y-m-d H:i:s'); + $sDateNow = date('Y-m-d H:i:s'); $sWhere = ''; if (isset($aFilter['topic_date_more'])) { $sWhere .= " AND t.topic_date_publish > " . $this->oDb->escape($aFilter['topic_date_more']); @@ -601,6 +607,9 @@ class ModuleTopic_MapperTopic extends Mapper if (isset($aFilter['topic_publish'])) { $sWhere .= " AND t.topic_publish = " . (int)$aFilter['topic_publish'] . " AND t.topic_date_publish <= '{$sDateNow}' "; } + if (isset($aFilter['topic_publish_only'])) { + $sWhere .= " AND t.topic_publish = " . (int)$aFilter['topic_publish_only'] . " "; + } if (isset($aFilter['topic_rating']) and is_array($aFilter['topic_rating'])) { $sPublishIndex = ''; if (isset($aFilter['topic_rating']['publish_index']) and $aFilter['topic_rating']['publish_index'] == 1) { @@ -793,8 +802,8 @@ class ModuleTopic_MapperTopic extends Mapper */ public function MoveTopics($sBlogId, $sBlogIdNew) { - $aFields=array('blog_id','blog_id2','blog_id3','blog_id4','blog_id5'); - foreach($aFields as $sField) { + $aFields = array('blog_id', 'blog_id2', 'blog_id3', 'blog_id4', 'blog_id5'); + foreach ($aFields as $sField) { $sql = "UPDATE " . Config::Get('db.table.topic') . " SET {$sField} = ?d @@ -1003,4 +1012,13 @@ class ModuleTopic_MapperTopic extends Mapper } return false; } + + public function GetNextTopicDatePublish() + { + $sql = 'SELECT min(topic_date_publish) FROM ' . Config::Get('db.table.topic') . ' WHERE topic_date_publish > ? and topic_publish = 1'; + if ($sDate = $this->oDb->selectCell($sql, date('Y-m-d H:i:s'))) { + return $sDate; + } + return null; + } } \ No newline at end of file diff --git a/application/classes/modules/user/User.class.php b/application/classes/modules/user/User.class.php index c35772c0..0f480d21 100644 --- a/application/classes/modules/user/User.class.php +++ b/application/classes/modules/user/User.class.php @@ -453,6 +453,7 @@ class ModuleUser extends Module if ($this->oUserCurrent) { $this->Viewer_Assign('iUserCurrentCountTalkNew', $this->Talk_GetCountTalkNew($this->oUserCurrent->getId())); $this->Viewer_Assign('iUserCurrentCountTopicDraft', $this->Topic_GetCountDraftTopicsByUserId($this->oUserCurrent->getId())); + $this->Viewer_Assign('iUserCurrentCountTopicDeferred', $this->Topic_GetCountDeferredTopicsByUserId($this->oUserCurrent->getId())); $this->Viewer_Assign('iUserCurrentCountWall', $this->Wall_GetCountWall(array('wall_user_id' => $this->oUserCurrent->getId(), 'pid' => null))); $this->Viewer_Assign('iUserCurrentCountFriends', $this->User_GetCountUsersFriend($this->oUserCurrent->getId())); diff --git a/application/frontend/components/topic/css/topic.css b/application/frontend/components/topic/css/topic.css index f89b442e..d32bb74a 100644 --- a/application/frontend/components/topic/css/topic.css +++ b/application/frontend/components/topic/css/topic.css @@ -106,6 +106,10 @@ padding: 0; } +.ls-topic-info-item.ls-topic-info-item--date--deferred { + color: #ff0000; +} + /** * Responsive styles */ diff --git a/application/frontend/components/topic/topic-add.tpl b/application/frontend/components/topic/topic-add.tpl index 3e3f0993..1d70b2ec 100644 --- a/application/frontend/components/topic/topic-add.tpl +++ b/application/frontend/components/topic/topic-add.tpl @@ -132,6 +132,33 @@ targetId = ( $topic ) ? $topic->getId() : ''} {/if} + {if $type->isAllowCreateDeferredTopic($oUserCurrent)} + {if !$topic or !$topic->getPublishDraft() or ($topic->getDatePublish() and strtotime($topic->getDatePublish()) > time())} + {$iDatePublish = null} + {if $topic} + {$iDatePublish = strtotime($topic->getDatePublish())} + {if $iDatePublish < time()} + {$iDatePublish = null} + {/if} + {/if} +
+
{lang 'topic.add.fields.publish_date.label'}:
+ {component 'field.date' mods = 'inline' + name = "topic[publish_date_raw][date]" + inputAttributes=[ "data-lsdate-format" => 'DD.MM.YYYY' ] + inputClasses = "js-field-date-default" + placeholder = {lang 'topic.add.fields.publish_date.label_date'} + value = ($iDatePublish) ? {date_format date=$iDatePublish format='d.m.Y'} : ''} + + {component 'field.time' mods = 'inline' + name = "topic[publish_date_raw][time]" + inputAttributes=[ "data-lstime-time-format" => 'H:i' ] + inputClasses = "js-field-time-default" + placeholder = {lang 'topic.add.fields.publish_date.label_time'} + value = ($iDatePublish) ? {date_format date=$iDatePublish format='H:i'} : ''} +
+ {/if} + {/if} {* Запретить комментарии *} {component 'field' template='checkbox' diff --git a/application/frontend/components/topic/topic.tpl b/application/frontend/components/topic/topic.tpl index 6eca2bf9..011331af 100644 --- a/application/frontend/components/topic/topic.tpl +++ b/application/frontend/components/topic/topic.tpl @@ -57,8 +57,9 @@ {/foreach} {/if} -
  • -
  • +
  • diff --git a/application/frontend/i18n/ru.php b/application/frontend/i18n/ru.php index 7efd17d3..45e7bd86 100644 --- a/application/frontend/i18n/ru.php +++ b/application/frontend/i18n/ru.php @@ -1048,6 +1048,8 @@ return array( 'topics' => 'Топики', 'topic_plural' => 'топик;топика;топиков', 'drafts' => 'Черновики', + 'deferred' => 'Отложенные', + 'is_deferred' => 'Это отложенная публикация', 'read_more' => 'Читать дальше', 'author' => 'Автор топика', 'tags' => '___tags.tags___', @@ -1108,6 +1110,11 @@ return array( 'label' => 'Принудительно пропустить вывод на главную', 'note' => 'Если отметить эту галку, то топик никогда не будет выведен на главную страницу (опция доступна только администраторам)' ), + 'publish_date' => array( + 'label' => 'Дата отложенной публикации', + 'label_date' => 'Дата', + 'label_time' => 'Время', + ), ), // Кнопки 'button' => array( @@ -1125,6 +1132,7 @@ return array( 'error_type' => 'Неверный тип топика', // TODO: Remove? 'error_slug' => 'Необходимо указать URL топика', 'error_favourite_draft' => 'Топик из черновиков нельзя добавить в избранное', + 'error_publish_date' => 'Необходимо указать корректную дату публикации в будущем', 'time_limit' => 'Вам нельзя создавать топики слишком часто', 'rating_limit' => 'Вам не хватает рейтинга для создания топика', 'update_complete' => 'Обновление прошло успешно', diff --git a/application/frontend/skin/developer/layouts/layout.content.form.tpl b/application/frontend/skin/developer/layouts/layout.content.form.tpl index e691411a..d285b777 100644 --- a/application/frontend/skin/developer/layouts/layout.content.form.tpl +++ b/application/frontend/skin/developer/layouts/layout.content.form.tpl @@ -23,6 +23,14 @@ 'count' => $iUserCurrentCountTopicDraft ]} + {* Пункт "Отложенные" *} + {$_items[] = [ + 'name' => 'deferred', + 'url' => "{router page='content'}deferred/", + 'text' => $aLang.topic.deferred, + 'count' => $iUserCurrentCountTopicDeferred + ]} + {$layoutNav = [[ name => 'content_form', activeItem => $sMenuSubItemSelect, diff --git a/application/frontend/skin/synio/components/topic/css/topic.css b/application/frontend/skin/synio/components/topic/css/topic.css index 1b4ecabf..fec4b7e9 100644 --- a/application/frontend/skin/synio/components/topic/css/topic.css +++ b/application/frontend/skin/synio/components/topic/css/topic.css @@ -120,6 +120,10 @@ top: -2px; } +.ls-topic-info-item.ls-topic-info-item--date--deferred { + color: #ff0000; +} + /* Ссылка на комментарии */ .ls-topic-info-item.ls-topic-info-item--comments a { text-decoration: none; diff --git a/application/frontend/skin/synio/components/topic/topic.tpl b/application/frontend/skin/synio/components/topic/topic.tpl index 402c2667..f24e8f66 100644 --- a/application/frontend/skin/synio/components/topic/topic.tpl +++ b/application/frontend/skin/synio/components/topic/topic.tpl @@ -169,8 +169,9 @@ {* Дата *} -
  • -
  • +
  • diff --git a/application/frontend/skin/synio/layouts/layout.content.form.tpl b/application/frontend/skin/synio/layouts/layout.content.form.tpl index e691411a..e04b3554 100644 --- a/application/frontend/skin/synio/layouts/layout.content.form.tpl +++ b/application/frontend/skin/synio/layouts/layout.content.form.tpl @@ -23,6 +23,14 @@ 'count' => $iUserCurrentCountTopicDraft ]} + {* Пункт "Отложенные" *} + {$_items[] = [ + 'name' => 'deferred', + 'url' => "{router page='content'}deferred/", + 'text' => $aLang.topic.deferred, + 'count' => $iUserCurrentCountTopicDeferred + ]} + {$layoutNav = [[ name => 'content_form', activeItem => $sMenuSubItemSelect,