* @since 1.0.0 */ protected static array $columns = [ 'task_id' => ['name' => 'task_id', 'type' => 'int', 'internal' => 'id'], 'task_title' => ['name' => 'task_title', 'type' => 'string', 'internal' => 'title'], 'task_desc' => ['name' => 'task_desc', 'type' => 'string', 'internal' => 'description'], 'task_desc_raw' => ['name' => 'task_desc_raw', 'type' => 'string', 'internal' => 'descriptionRaw'], 'task_type' => ['name' => 'task_type', 'type' => 'int', 'internal' => 'type'], 'task_status' => ['name' => 'task_status', 'type' => 'int', 'internal' => 'status'], 'task_closable' => ['name' => 'task_closable', 'type' => 'bool', 'internal' => 'isClosable'], 'task_editable' => ['name' => 'task_editable', 'type' => 'bool', 'internal' => 'isEditable'], 'task_priority' => ['name' => 'task_priority', 'type' => 'int', 'internal' => 'priority'], 'task_due' => ['name' => 'task_due', 'type' => 'DateTime', 'internal' => 'due'], 'task_done' => ['name' => 'task_done', 'type' => 'DateTime', 'internal' => 'done'], 'task_schedule' => ['name' => 'task_schedule', 'type' => 'int', 'internal' => 'schedule'], 'task_start' => ['name' => 'task_start', 'type' => 'DateTime', 'internal' => 'start'], 'task_created_by' => ['name' => 'task_created_by', 'type' => 'int', 'internal' => 'createdBy', 'readonly' => true], 'task_created_at' => ['name' => 'task_created_at', 'type' => 'DateTime', 'internal' => 'createdAt', 'readonly' => true], ]; /** * Has many relation. * * @var array * @since 1.0.0 */ protected static array $hasMany = [ 'taskElements' => [ 'mapper' => TaskElementMapper::class, 'table' => 'task_element', 'external' => 'task_element_task', 'self' => null, ], 'media' => [ 'mapper' => MediaMapper::class, 'table' => 'task_media', 'external' => 'task_media_src', 'self' => 'task_media_dst', ], 'tags' => [ 'mapper' => MediaMapper::class, 'table' => 'task_tag', 'external' => 'task_tag_src', 'self' => 'task_tag_dst', ], ]; /** * Belongs to. * * @var array * @since 1.0.0 */ protected static array $belongsTo = [ 'createdBy' => [ 'mapper' => AccountMapper::class, 'self' => 'task_created_by', ], ]; /** * Has one relation. * * @var array * @since 1.0.0 */ protected static array $ownsOne = [ 'schedule' => [ 'mapper' => ScheduleMapper::class, 'self' => 'task_schedule', ], ]; /** * Primary table. * * @var string * @since 1.0.0 */ protected static string $table = 'task'; /** * Created at. * * @var string * @since 1.0.0 */ protected static string $createdAt = 'task_created_at'; /** * Primary field name. * * @var string * @since 1.0.0 */ protected static string $primaryField = 'task_id'; /** * Get open tasks by createdBy * * @param int $user User * * @return Task[] * * @since 1.0.0 */ public static function getOpenCreatedBy(int $user) : array { $depth = 3; $query = self::getQuery(); $query->where(self::$table . '_' . $depth . '.task_created_by', '=', $user) ->where(self::$table . '_' . $depth . '.task_status', '=', TaskStatus::OPEN); return self::getAllByQuery($query); } /** * Get open tasks for user * * @param int $user User * * @return Task[] * * @since 1.0.0 */ public static function getOpenTo(int $user) : array { $depth = 3; $query = self::getQuery(); $query->innerJoin(TaskElementMapper::getTable()) ->on(self::$table . '_' . $depth . '.task_id', '=', TaskElementMapper::getTable() . '.task_element_task') ->innerJoin(AccountRelationMapper::getTable()) ->on(TaskElementMapper::getTable() . '.task_element_id', '=', AccountRelationMapper::getTable() . '.task_account_task_element') ->where(self::$table . '_' . $depth . '.task_status', '=', TaskStatus::OPEN) ->andWhere(AccountRelationMapper::getTable() . '.task_account_account', '=', $user) ->andWhere(AccountRelationMapper::getTable() . '.task_account_duty', '=', DutyType::TO); return self::getAllByQuery($query); } /** * Get open tasks for mentioned user * * @param int $user User * * @return Task[] * * @since 1.0.0 */ public static function getOpenAny(int $user) : array { $depth = 3; $query = self::getQuery(); $query->innerJoin(TaskElementMapper::getTable()) ->on(self::$table . '_' . $depth . '.task_id', '=', TaskElementMapper::getTable() . '.task_element_task') ->innerJoin(AccountRelationMapper::getTable()) ->on(TaskElementMapper::getTable() . '.task_element_id', '=', AccountRelationMapper::getTable() . '.task_account_task_element') ->where(self::$table . '_' . $depth . '.task_status', '=', TaskStatus::OPEN) ->andWhere(AccountRelationMapper::getTable() . '.task_account_account', '=', $user); return self::getAllByQuery($query); } /** * Get open tasks by cc * * @param int $user User * * @return Task[] * * @since 1.0.0 */ public static function getOpenCC(int $user) : array { $depth = 3; $query = self::getQuery(); $query->innerJoin(TaskElementMapper::getTable()) ->on(self::$table . '_' . $depth . '.task_id', '=', TaskElementMapper::getTable() . '.task_element_task') ->innerJoin(AccountRelationMapper::getTable()) ->on(TaskElementMapper::getTable() . '.task_element_id', '=', AccountRelationMapper::getTable() . '.task_account_task_element') ->where(self::$table . '_' . $depth . '.task_status', '=', TaskStatus::OPEN) ->andWhere(AccountRelationMapper::getTable() . '.task_account_account', '=', $user) ->andWhere(AccountRelationMapper::getTable() . '.task_account_duty', '=', DutyType::CC); return self::getAllByQuery($query); } /** * Get tasks created by user * * @param int $user User * * @return Task[] * * @since 1.0.0 */ public static function getCreatedBy(int $user) : array { $depth = 3; $query = self::getQuery(); $query->where(self::$table . '_' . $depth . '.task_created_by', '=', $user); return self::getAllByQuery($query); } /** * Get tasks sent to user * * @param int $user User * * @return Task[] * * @since 1.0.0 */ public static function getTo(int $user) : array { $depth = 3; $query = self::getQuery(); $query->innerJoin(TaskElementMapper::getTable()) ->on(self::$table . '_' . $depth . '.task_id', '=', TaskElementMapper::getTable() . '.task_element_task') ->innerJoin(AccountRelationMapper::getTable()) ->on(TaskElementMapper::getTable() . '.task_element_id', '=', AccountRelationMapper::getTable() . '.task_account_task_element') ->where(AccountRelationMapper::getTable() . '.task_account_account', '=', $user) ->andWhere(AccountRelationMapper::getTable() . '.task_account_duty', '=', DutyType::TO); return self::getAllByQuery($query); } /** * Get tasks cc to user * * @param int $user User * * @return Task[] * * @since 1.0.0 */ public static function getCC(int $user) : array { $depth = 3; $query = self::getQuery(); $query->innerJoin(TaskElementMapper::getTable()) ->on(self::$table . '_' . $depth . '.task_id', '=', TaskElementMapper::getTable() . '.task_element_task') ->innerJoin(AccountRelationMapper::getTable()) ->on(TaskElementMapper::getTable() . '.task_element_id', '=', AccountRelationMapper::getTable() . '.task_account_task_element') ->where(AccountRelationMapper::getTable() . '.task_account_account', '=', $user) ->andWhere(AccountRelationMapper::getTable() . '.task_account_duty', '=', DutyType::CC); return self::getAllByQuery($query); } /** * Get tasks that have something to do with the user * * @param int $user User * * @return Task[] * * @since 1.0.0 */ public static function getAny(int $user) : array { $depth = 3; $query = self::getQuery(); $query->innerJoin(TaskElementMapper::getTable()) ->on(self::$table . '_' . $depth . '.task_id', '=', TaskElementMapper::getTable() . '.task_element_task') ->innerJoin(AccountRelationMapper::getTable()) ->on(TaskElementMapper::getTable() . '.task_element_id', '=', AccountRelationMapper::getTable() . '.task_account_task_element') ->where(AccountRelationMapper::getTable() . '.task_account_account', '=', $user) ->orWhere(self::$table . '_' . $depth . '.task_created_by', '=', $user) ->orderBy(TaskElementMapper::getTable() . '.' . TaskElementMapper::getCreatedAt(), 'DESC'); return self::getAllByQuery($query); } /** * Get tasks that have something to do with the user * * @param int $user User * @param mixed $pivot Pivot * @param string $column Sort column/pivot column * @param int $limit Result limit * @param string $order Order of the elements * @param int $relations Load relations * @param int $depth Relation depth * * @return Task[] * * @since 1.0.0 */ public static function getAnyBeforePivot( int $user, $pivot, string $column = null, int $limit = 50, string $order = 'ASC', int $relations = RelationType::ALL, int $depth = 3 ) : array { $depth = 3; $userWhere = new Where(self::$db); $userWhere->where(AccountRelationMapper::getTable() . '.task_account_account', '=', $user) ->orWhere(self::$table . '_' . $depth . '.task_created_by', '=', $user); $query = self::getQuery(); $query->innerJoin(TaskElementMapper::getTable()) ->on(self::$table . '_' . $depth . '.task_id', '=', TaskElementMapper::getTable() . '.task_element_task') ->innerJoin(AccountRelationMapper::getTable()) ->on(TaskElementMapper::getTable() . '.task_element_id', '=', AccountRelationMapper::getTable() . '.task_account_task_element') ->where($userWhere) ->andWhere(static::$table . '_' . $depth . '.' . ($column !== null ? self::getColumnByMember($column) : static::$primaryField), '<', $pivot) ->orderBy(static::$table . '_' . $depth . '.' . ($column !== null ? self::getColumnByMember($column) : static::$primaryField), $order) ->limit($limit); return self::getAllByQuery($query); } /** * Get tasks that have something to do with the user * * @param int $user User * @param mixed $pivot Pivot * @param string $column Sort column/pivot column * @param int $limit Result limit * @param string $order Order of the elements * @param int $relations Load relations * @param int $depth Relation depth * * @return Task[] * * @since 1.0.0 */ public static function getAnyAfterPivot( int $user, $pivot, string $column = null, int $limit = 50, string $order = 'ASC', int $relations = RelationType::ALL, int $depth = 3 ) : array { $depth = 3; $userWhere = new Where(self::$db); $userWhere->where(AccountRelationMapper::getTable() . '.task_account_account', '=', $user) ->orWhere(self::$table . '_' . $depth . '.task_created_by', '=', $user); $query = self::getQuery(); $query->innerJoin(TaskElementMapper::getTable()) ->on(self::$table . '_' . $depth . '.task_id', '=', TaskElementMapper::getTable() . '.task_element_task') ->innerJoin(AccountRelationMapper::getTable()) ->on(TaskElementMapper::getTable() . '.task_element_id', '=', AccountRelationMapper::getTable() . '.task_account_task_element') ->where($userWhere) ->andWhere(static::$table . '_' . $depth . '.' . ($column !== null ? self::getColumnByMember($column) : static::$primaryField), '>', $pivot) ->orderBy(static::$table . '_' . $depth . '.' . ($column !== null ? self::getColumnByMember($column) : static::$primaryField), $order) ->limit($limit); return self::getAllByQuery($query); } /** * Check if a user has reading permission for a task * * @param int $user User id * @param int $task Task id * * @return bool * * @since 1.0.0 */ public static function hasReadingPermission(int $user, int $task) : bool { $depth = 1; $userWhere = new Where(self::$db); $userWhere->where(AccountRelationMapper::getTable() . '.task_account_account', '=', $user) ->orWhere(self::$table . '_' . $depth . '.task_created_by', '=', $user); $query = new Builder(self::$db); $query->selectAs(self::$table . '_' . $depth . '.' . self::$primaryField, self::$primaryField . '_' . $depth) ->fromAs(self::$table, self::$table . '_' . $depth) ->innerJoin(TaskElementMapper::getTable()) ->on(self::$table . '_' . $depth . '.task_id', '=', TaskElementMapper::getTable() . '.task_element_task') ->innerJoin(AccountRelationMapper::getTable()) ->on(TaskElementMapper::getTable() . '.task_element_id', '=', AccountRelationMapper::getTable() . '.task_account_task_element') ->where($userWhere) ->andWhere(self::$table . '_' . $depth . '.' . self::$primaryField, '=', $task); return !empty(self::getAllByQuery($query, RelationType::ALL, 1)); } /** * Count unread task * * @param int $user User * * @return int * * @since 1.0.0 */ public static function countUnread(int $user) : int { try { $query = new Builder(self::$db); $query->count('*') ->from(self::$table) ->innerJoin(TaskElementMapper::getTable()) ->on(self::$table . '.task_id', '=', TaskElementMapper::getTable() . '.task_element_task') ->innerJoin(AccountRelationMapper::getTable()) ->on(TaskElementMapper::getTable() . '.task_element_id', '=', AccountRelationMapper::getTable() . '.task_account_task_element') ->where(self::$table . '.task_status', '=', TaskStatus::OPEN) ->andWhere(AccountRelationMapper::getTable() . '.task_account_account', '=', $user); $sth = self::$db->con->prepare($query->toSql()); $sth->execute(); $fetched = $sth->fetchAll(); if ($fetched === false) { return -1; } $count = $fetched[0][0] ?? 0; } catch (\Exception $e) { return -1; } return $count; } }