diff --git a/app/Casts/TimestampOrZero.php b/app/Casts/TimestampOrZero.php new file mode 100644 index 00000000000..7a65fcbf73c --- /dev/null +++ b/app/Casts/TimestampOrZero.php @@ -0,0 +1,27 @@ +. Licensed under the GNU Affero General Public License v3.0. +// See the LICENCE file in the repository root for full licence text. + +declare(strict_types=1); + +namespace App\Casts; + +use Carbon\Carbon; +use Illuminate\Contracts\Database\Eloquent\CastsAttributes; + +/** + * For columns which use unix timestamp as its value and repurpose 0 as null. + */ +class TimestampOrZero implements CastsAttributes +{ + public function get($model, string $key, $value, array $attributes) + { + return $value === null || $value === 0 ? null : Carbon::createFromTimestamp($value); + } + + public function set($model, string $key, $value, array $attributes) + { + return $value === null ? 0 : $value->getTimestamp(); + } +} diff --git a/app/Jobs/Notifications/BroadcastNotificationBase.php b/app/Jobs/Notifications/BroadcastNotificationBase.php index ad99dab6269..503b044fcd0 100644 --- a/app/Jobs/Notifications/BroadcastNotificationBase.php +++ b/app/Jobs/Notifications/BroadcastNotificationBase.php @@ -185,7 +185,7 @@ public function handle() $pushReceiverIds = []; $notification->getConnection()->transaction(function () use ($deliverySettings, $notification, &$pushReceiverIds) { - $timestamp = (string) $this->getTimestamp(); + $timestamp = $this->getTimestamp()->format('Y-m-d H:i:s'); $notificationId = $notification->getKey(); $tempUserNotification = new UserNotification(); diff --git a/app/Models/Forum/Forum.php b/app/Models/Forum/Forum.php index d8875ba8ec6..6fe0daed042 100644 --- a/app/Models/Forum/Forum.php +++ b/app/Models/Forum/Forum.php @@ -5,6 +5,7 @@ namespace App\Models\Forum; +use App\Casts\TimestampOrZero; use App\Models\User; use Carbon\Carbon; use Illuminate\Database\Eloquent\Builder; @@ -26,7 +27,7 @@ * @property string $forum_image * @property int $forum_last_post_id * @property string $forum_last_post_subject - * @property int $forum_last_post_time + * @property \Carbon\Carbon|null $forum_last_post_time * @property string $forum_last_poster_colour * @property int $forum_last_poster_id * @property string $forum_last_poster_name @@ -67,10 +68,9 @@ class Forum extends Model 'allow_topic_covers' => 'boolean', 'enable_indexing' => 'boolean', 'enable_sigs' => 'boolean', - 'forum_last_post_time' => 'datetime', + 'forum_last_post_time' => TimestampOrZero::class, 'moderator_groups' => 'array', ]; - protected $dateFormat = 'U'; protected $primaryKey = 'forum_id'; protected $table = 'phpbb_forums'; @@ -242,16 +242,6 @@ public function setForumLastPosterColourAttribute($value) $this->attributes['forum_last_poster_colour'] = ltrim($value, '#'); } - public function getForumLastPostTimeAttribute($value) - { - return get_time_or_null($value); - } - - public function setForumLastPostTimeAttribute($value) - { - $this->attributes['forum_last_post_time'] = get_timestamp_or_zero($value); - } - // feature forum shall have extra features like sorting and voting public function isFeatureForum() { diff --git a/app/Models/Forum/Post.php b/app/Models/Forum/Post.php index 3f1c04ee3cc..c133bde4d13 100644 --- a/app/Models/Forum/Post.php +++ b/app/Models/Forum/Post.php @@ -5,6 +5,7 @@ namespace App\Models\Forum; +use App\Casts\TimestampOrZero; use App\Exceptions\ModelNotSavedException; use App\Jobs\EsDocument; use App\Jobs\MarkNotificationsRead; @@ -48,7 +49,7 @@ * @property int $post_reported * @property string $post_subject * @property mixed $post_text - * @property int $post_time + * @property \Carbon\Carbon|null $post_time * @property string $post_username * @property int $poster_id * @property string $poster_ip @@ -81,8 +82,10 @@ class Post extends Model implements AfterCommit, Indexable, Traits\ReportableInt public $timestamps = false; protected $casts = [ - 'post_edit_locked' => 'boolean', 'post_approved' => 'boolean', + 'post_edit_locked' => 'boolean', + 'post_edit_time' => TimestampOrZero::class, + 'post_time' => TimestampOrZero::class, ]; private $normalizedUsers = []; @@ -156,26 +159,6 @@ public function getPostEditUserAttribute($value) } } - public function setPostTimeAttribute($value) - { - $this->attributes['post_time'] = get_timestamp_or_zero($value); - } - - public function getPostTimeAttribute($value) - { - return get_time_or_null($value); - } - - public function setPostEditTimeAttribute($value) - { - $this->attributes['post_edit_time'] = get_timestamp_or_zero($value); - } - - public function getPostEditTimeAttribute($value) - { - return get_time_or_null($value); - } - /** * Gets a preview of the post_text by stripping anything that * looks like bbcode or html. diff --git a/app/Models/Forum/Topic.php b/app/Models/Forum/Topic.php index 2ad4fd54c62..1ba4dfd154c 100644 --- a/app/Models/Forum/Topic.php +++ b/app/Models/Forum/Topic.php @@ -5,6 +5,7 @@ namespace App\Models\Forum; +use App\Casts\TimestampOrZero; use App\Jobs\EsDocument; use App\Jobs\UpdateUserForumCache; use App\Jobs\UpdateUserForumTopicFollows; @@ -112,8 +113,13 @@ class Topic extends Model implements AfterCommit protected $casts = [ 'poll_hide_results' => 'boolean', + 'poll_last_vote' => TimestampOrZero::class, + 'poll_start' => TimestampOrZero::class, 'poll_vote_change' => 'boolean', 'topic_approved' => 'boolean', + 'topic_last_post_time' => TimestampOrZero::class, + 'topic_last_view_time' => TimestampOrZero::class, + 'topic_time' => TimestampOrZero::class, ]; public static function createNew($forum, $params, $poll = null) @@ -225,61 +231,11 @@ public function watches() return $this->hasMany(TopicWatch::class); } - public function getPollLastVoteAttribute($value) - { - return get_time_or_null($value); - } - - public function setPollLastVoteAttribute($value) - { - $this->attributes['poll_last_vote'] = get_timestamp_or_zero($value); - } - public function getPollLengthDaysAttribute() { return $this->attributes['poll_length'] / 86400; } - public function getPollStartAttribute($value) - { - return get_time_or_null($value); - } - - public function setPollStartAttribute($value) - { - $this->attributes['poll_start'] = get_timestamp_or_zero($value); - } - - public function getTopicLastPostTimeAttribute($value) - { - return get_time_or_null($value); - } - - public function setTopicLastPostTimeAttribute($value) - { - $this->attributes['topic_last_post_time'] = get_timestamp_or_zero($value); - } - - public function getTopicLastViewTimeAttribute($value) - { - return get_time_or_null($value); - } - - public function setTopicLastViewTimeAttribute($value) - { - $this->attributes['topic_last_view_time'] = get_timestamp_or_zero($value); - } - - public function getTopicTimeAttribute($value) - { - return get_time_or_null($value); - } - - public function setTopicTimeAttribute($value) - { - $this->attributes['topic_time'] = get_timestamp_or_zero($value); - } - public function getTopicFirstPosterColourAttribute($value) { if (present($value)) { diff --git a/app/helpers.php b/app/helpers.php index bff4c134915..81685d9c2bc 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -1684,27 +1684,6 @@ function model_pluck($builder, $key, $class = null) return $result; } -/* - * Returns null if $timestamp is null or 0. - * Used for table which has not null constraints but accepts "empty" value (0). - */ -function get_time_or_null($timestamp) -{ - if ($timestamp !== 0) { - return parse_time_to_carbon($timestamp); - } -} - -/* - * Get unix timestamp of a DateTime (or Carbon\Carbon). - * Returns 0 if $time is null so mysql doesn't explode because of not null - * constraints. - */ -function get_timestamp_or_zero(DateTime $time = null): int -{ - return $time === null ? 0 : $time->getTimestamp(); -} - function null_if_false($value) { return $value === false ? null : $value;