PHP 8 Compatibility

This commit is contained in:
Frédéric Guillot
2022-02-05 11:49:03 -08:00
committed by GitHub
parent 61e63ef9e0
commit f5bb55bdb8
558 changed files with 6262 additions and 21691 deletions

View File

@@ -7,7 +7,6 @@ on:
jobs: jobs:
jshint: jshint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: kanboard/tests:latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Install jshint - name: Install jshint

3
.gitignore vendored
View File

@@ -21,4 +21,5 @@ data/config.php
*.bak *.bak
/config.php /config.php
!docker/var/wwww/app/config.php !docker/var/wwww/app/config.php
node_modules node_modules
.phpunit.result.cache

View File

@@ -9,12 +9,12 @@ EXPOSE 80 443
ARG VERSION ARG VERSION
RUN apk --no-cache --update add \ RUN apk --no-cache --update add \
tzdata openssl unzip nginx bash ca-certificates s6 curl ssmtp mailx php7 php7-phar php7-curl \ tzdata openssl unzip nginx bash ca-certificates s6 curl ssmtp mailx php8 php8-phar php8-curl \
php7-fpm php7-json php7-zlib php7-xml php7-dom php7-ctype php7-opcache php7-zip php7-iconv \ php8-fpm php8-json php8-zlib php8-xml php8-dom php8-ctype php8-opcache php8-zip php8-iconv \
php7-pdo php7-pdo_mysql php7-pdo_sqlite php7-pdo_pgsql php7-mbstring php7-session php7-bcmath \ php8-pdo php8-pdo_mysql php8-pdo_sqlite php8-pdo_pgsql php8-mbstring php8-session php8-bcmath \
php7-gd php7-mcrypt php7-openssl php7-sockets php7-posix php7-ldap php7-simplexml && \ php8-gd php8-openssl php8-sockets php8-posix php8-ldap php8-simplexml && \
rm -rf /var/www/localhost && \ rm -rf /var/www/localhost && \
rm -f /etc/php7/php-fpm.d/www.conf rm -f /etc/php8/php-fpm.d/www.conf
ADD . /var/www/app ADD . /var/www/app
ADD docker/ / ADD docker/ /

View File

@@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2021 Frédéric Guillot Copyright (c) 2014-2022 Frédéric Guillot
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -83,8 +83,10 @@ class TaskEmail extends Base
$subject = $this->getParam('subject'); $subject = $this->getParam('subject');
foreach ($data["task"] as $key => $value) { foreach ($data["task"] as $key => $value) {
$placeholder = sprintf('{{%s}}', $key); if ($value !== null) {
$subject = str_replace($placeholder, $value, $subject); $placeholder = sprintf('{{%s}}', $key);
$subject = str_replace($placeholder, $value, $subject);
}
} }
if (! empty($user['email'])) { if (! empty($user['email'])) {

View File

@@ -14,12 +14,10 @@ class CommentListController extends BaseController
{ {
public function show() public function show()
{ {
$project = $this->getProject();
$task = $this->getTask(); $task = $this->getTask();
$commentSortingDirection = $this->userMetadataCacheDecorator->get(UserMetadataModel::KEY_COMMENT_SORTING_DIRECTION, 'ASC'); $commentSortingDirection = $this->userMetadataCacheDecorator->get(UserMetadataModel::KEY_COMMENT_SORTING_DIRECTION, 'ASC');
$this->response->html($this->template->render('comment_list/show', array( $this->response->html($this->template->render('comment_list/show', array(
'project' => $project,
'task' => $task, 'task' => $task,
'comments' => $this->commentModel->getAll($task['id'], $commentSortingDirection), 'comments' => $this->commentModel->getAll($task['id'], $commentSortingDirection),
'editable' => $this->helper->user->hasProjectAccess('CommentController', 'edit', $task['project_id']), 'editable' => $this->helper->user->hasProjectAccess('CommentController', 'edit', $task['project_id']),

View File

@@ -38,7 +38,7 @@ class TaskAjaxController extends BaseController
$filter->withFilter(new TaskIdExclusionFilter(array($exclude_task_id))); $filter->withFilter(new TaskIdExclusionFilter(array($exclude_task_id)));
} }
if (ctype_digit($search)) { if (ctype_digit((string) $search)) {
$filter->withFilter(new TaskIdFilter($search)); $filter->withFilter(new TaskIdFilter($search));
} else { } else {
$filter->withFilter(new TaskTitleFilter($search)); $filter->withFilter(new TaskTitleFilter($search));

View File

@@ -175,7 +175,7 @@ class DateParser extends Base
*/ */
public function getTimestamp($value) public function getTimestamp($value)
{ {
if (ctype_digit($value)) { if (ctype_digit((string) $value)) {
return (int) $value; return (int) $value;
} }
@@ -263,7 +263,7 @@ class DateParser extends Base
*/ */
public function getTimestampFromIsoFormat($value) public function getTimestampFromIsoFormat($value)
{ {
return $this->removeTimeFromTimestamp(ctype_digit($value) ? $value : strtotime($value)); return $this->removeTimeFromTimestamp(ctype_digit((string) $value) ? $value : strtotime($value));
} }
/** /**
@@ -291,7 +291,7 @@ class DateParser extends Base
{ {
foreach ($fields as $field) { foreach ($fields as $field) {
if (! empty($values[$field])) { if (! empty($values[$field])) {
if (ctype_digit($values[$field])) { if (ctype_digit((string) $values[$field])) {
$values[$field] = date($format, $values[$field]); $values[$field] = date($format, $values[$field]);
} }
} else { } else {

View File

@@ -112,7 +112,7 @@ class RememberMeCookie extends Base
'', '',
time() - 3600, time() - 3600,
$this->helper->url->dir(), $this->helper->url->dir(),
null, '',
$this->request->isHTTPS(), $this->request->isHTTPS(),
true true
); );

View File

@@ -79,7 +79,7 @@ class Request extends Base
*/ */
public function getIntegerParam($name, $default_value = 0) public function getIntegerParam($name, $default_value = 0)
{ {
return isset($this->get[$name]) && ctype_digit($this->get[$name]) ? (int) $this->get[$name] : $default_value; return isset($this->get[$name]) && ctype_digit((string) $this->get[$name]) ? (int) $this->get[$name] : $default_value;
} }
/** /**

View File

@@ -318,7 +318,7 @@ class User
* @access public * @access public
* @return string * @return string
*/ */
public function getGroupAdminDn() public function getGroupAdminDn(): string
{ {
return strtolower(LDAP_GROUP_ADMIN_DN); return strtolower(LDAP_GROUP_ADMIN_DN);
} }
@@ -329,7 +329,7 @@ class User
* @access public * @access public
* @return string * @return string
*/ */
public function getGroupManagerDn() public function getGroupManagerDn(): string
{ {
return LDAP_GROUP_MANAGER_DN; return LDAP_GROUP_MANAGER_DN;
} }

View File

@@ -24,32 +24,38 @@ class SessionHandler implements SessionHandlerInterface
$this->db = $db; $this->db = $db;
} }
#[\ReturnTypeWillChange]
public function close() public function close()
{ {
return true; return true;
} }
#[\ReturnTypeWillChange]
public function destroy($sessionID) public function destroy($sessionID)
{ {
return $this->db->table(self::TABLE)->eq('id', $sessionID)->remove(); return $this->db->table(self::TABLE)->eq('id', $sessionID)->remove();
} }
#[\ReturnTypeWillChange]
public function gc($maxlifetime) public function gc($maxlifetime)
{ {
return $this->db->table(self::TABLE)->lt('expire_at', time())->remove(); return $this->db->table(self::TABLE)->lt('expire_at', time())->remove();
} }
#[\ReturnTypeWillChange]
public function open($savePath, $name) public function open($savePath, $name)
{ {
return true; return true;
} }
#[\ReturnTypeWillChange]
public function read($sessionID) public function read($sessionID)
{ {
$result = $this->db->table(self::TABLE)->eq('id', $sessionID)->findOneColumn('data'); $result = $this->db->table(self::TABLE)->eq('id', $sessionID)->findOneColumn('data');
return $result ?: ''; return $result ?: '';
} }
#[\ReturnTypeWillChange]
public function write($sessionID, $data) public function write($sessionID, $data)
{ {
$lifetime = time() + (ini_get('session.gc_maxlifetime') ?: 1440); $lifetime = time() + (ini_get('session.gc_maxlifetime') ?: 1440);

View File

@@ -61,7 +61,7 @@ class Translator
array_unshift($args, $this->get($identifier, $identifier)); array_unshift($args, $this->get($identifier, $identifier));
foreach ($args as &$arg) { foreach ($args as &$arg) {
$arg = htmlspecialchars($arg, ENT_QUOTES, 'UTF-8', false); $arg = htmlspecialchars((string) $arg, ENT_QUOTES, 'UTF-8', false);
} }
return call_user_func_array( return call_user_func_array(

View File

@@ -41,6 +41,7 @@ class GenericEvent extends BaseEvent implements ArrayAccess
return $this->container; return $this->container;
} }
#[\ReturnTypeWillChange]
public function offsetSet($offset, $value) public function offsetSet($offset, $value)
{ {
if (is_null($offset)) { if (is_null($offset)) {
@@ -50,16 +51,19 @@ class GenericEvent extends BaseEvent implements ArrayAccess
} }
} }
#[\ReturnTypeWillChange]
public function offsetExists($offset) public function offsetExists($offset)
{ {
return isset($this->container[$offset]); return isset($this->container[$offset]);
} }
#[\ReturnTypeWillChange]
public function offsetUnset($offset) public function offsetUnset($offset)
{ {
unset($this->container[$offset]); unset($this->container[$offset]);
} }
#[\ReturnTypeWillChange]
public function offsetGet($offset) public function offsetGet($offset)
{ {
return isset($this->container[$offset]) ? $this->container[$offset] : null; return isset($this->container[$offset]) ? $this->container[$offset] : null;

View File

@@ -27,6 +27,7 @@ class EventIteratorBuilder implements Iterator {
return $this; return $this;
} }
#[\ReturnTypeWillChange]
public function rewind() { public function rewind() {
$this->position = 0; $this->position = 0;
} }
@@ -34,18 +35,22 @@ class EventIteratorBuilder implements Iterator {
/** /**
* @return BaseEventBuilder * @return BaseEventBuilder
*/ */
#[\ReturnTypeWillChange]
public function current() { public function current() {
return $this->builders[$this->position]; return $this->builders[$this->position];
} }
#[\ReturnTypeWillChange]
public function key() { public function key() {
return $this->position; return $this->position;
} }
#[\ReturnTypeWillChange]
public function next() { public function next() {
++$this->position; ++$this->position;
} }
#[\ReturnTypeWillChange]
public function valid() { public function valid() {
return isset($this->builders[$this->position]); return isset($this->builders[$this->position]);
} }

View File

@@ -32,7 +32,7 @@ class ProjectStatusFilter extends BaseFilter implements FilterInterface
*/ */
public function apply() public function apply()
{ {
if (is_int($this->value) || ctype_digit($this->value)) { if (is_int($this->value) || ctype_digit((string) $this->value)) {
$this->query->eq(ProjectModel::TABLE.'.is_active', $this->value); $this->query->eq(ProjectModel::TABLE.'.is_active', $this->value);
} elseif ($this->value === 'inactive' || $this->value === 'closed' || $this->value === 'disabled') { } elseif ($this->value === 'inactive' || $this->value === 'closed' || $this->value === 'disabled') {
$this->query->eq(ProjectModel::TABLE.'.is_active', 0); $this->query->eq(ProjectModel::TABLE.'.is_active', 0);

View File

@@ -32,7 +32,7 @@ class ProjectTypeFilter extends BaseFilter implements FilterInterface
*/ */
public function apply() public function apply()
{ {
if (is_int($this->value) || ctype_digit($this->value)) { if (is_int($this->value) || ctype_digit((string) $this->value)) {
$this->query->eq(ProjectModel::TABLE.'.is_private', $this->value); $this->query->eq(ProjectModel::TABLE.'.is_private', $this->value);
} elseif ($this->value === 'private') { } elseif ($this->value === 'private') {
$this->query->eq(ProjectModel::TABLE.'.is_private', ProjectModel::TYPE_PRIVATE); $this->query->eq(ProjectModel::TABLE.'.is_private', ProjectModel::TYPE_PRIVATE);

View File

@@ -54,7 +54,7 @@ class TaskAssigneeFilter extends BaseFilter implements FilterInterface
*/ */
public function apply() public function apply()
{ {
if (is_int($this->value) || ctype_digit($this->value)) { if (is_int($this->value) || ctype_digit((string) $this->value)) {
$this->query->eq(TaskModel::TABLE.'.owner_id', $this->value); $this->query->eq(TaskModel::TABLE.'.owner_id', $this->value);
} else { } else {
switch ($this->value) { switch ($this->value) {

View File

@@ -33,7 +33,7 @@ class TaskCategoryFilter extends BaseFilter implements FilterInterface
*/ */
public function apply() public function apply()
{ {
if (is_int($this->value) || ctype_digit($this->value)) { if (is_int($this->value) || ctype_digit((string) $this->value)) {
$this->query->eq(TaskModel::TABLE.'.category_id', $this->value); $this->query->eq(TaskModel::TABLE.'.category_id', $this->value);
} elseif ($this->value === 'none') { } elseif ($this->value === 'none') {
$this->query->eq(TaskModel::TABLE.'.category_id', 0); $this->query->eq(TaskModel::TABLE.'.category_id', 0);

View File

@@ -33,7 +33,7 @@ class TaskColumnFilter extends BaseFilter implements FilterInterface
*/ */
public function apply() public function apply()
{ {
if (is_int($this->value) || ctype_digit($this->value)) { if (is_int($this->value) || ctype_digit((string) $this->value)) {
$this->query->eq(TaskModel::TABLE.'.column_id', $this->value); $this->query->eq(TaskModel::TABLE.'.column_id', $this->value);
} else { } else {
$this->query->eq(ColumnModel::TABLE.'.title', $this->value); $this->query->eq(ColumnModel::TABLE.'.title', $this->value);

View File

@@ -53,7 +53,7 @@ class TaskCreatorFilter extends BaseFilter implements FilterInterface
*/ */
public function apply() public function apply()
{ {
if (is_int($this->value) || ctype_digit($this->value)) { if (is_int($this->value) || ctype_digit((string) $this->value)) {
$this->query->eq(TaskModel::TABLE.'.creator_id', $this->value); $this->query->eq(TaskModel::TABLE.'.creator_id', $this->value);
} else { } else {
switch ($this->value) { switch ($this->value) {

View File

@@ -33,7 +33,7 @@ class TaskProjectFilter extends BaseFilter implements FilterInterface
*/ */
public function apply() public function apply()
{ {
if (is_int($this->value) || ctype_digit($this->value)) { if (is_int($this->value) || ctype_digit((string) $this->value)) {
$this->query->eq(TaskModel::TABLE.'.project_id', $this->value); $this->query->eq(TaskModel::TABLE.'.project_id', $this->value);
} else { } else {
$this->query->ilike(ProjectModel::TABLE.'.name', $this->value); $this->query->ilike(ProjectModel::TABLE.'.name', $this->value);

View File

@@ -34,7 +34,7 @@ class TaskStatusFilter extends BaseFilter implements FilterInterface
{ {
if ($this->value === 'open' || $this->value === 'closed') { if ($this->value === 'open' || $this->value === 'closed') {
$this->query->eq(TaskModel::TABLE.'.is_active', $this->value === 'open' ? TaskModel::STATUS_OPEN : TaskModel::STATUS_CLOSED); $this->query->eq(TaskModel::TABLE.'.is_active', $this->value === 'open' ? TaskModel::STATUS_OPEN : TaskModel::STATUS_CLOSED);
} elseif (is_int($this->value) || ctype_digit($this->value)) { } elseif (is_int($this->value) || ctype_digit((string) $this->value)) {
$this->query->eq(TaskModel::TABLE.'.is_active', $this->value); $this->query->eq(TaskModel::TABLE.'.is_active', $this->value);
} }

View File

@@ -106,7 +106,7 @@ class TaskSubtaskAssigneeFilter extends BaseFilter implements FilterInterface
*/ */
protected function applySubQueryFilter(Table $subquery) protected function applySubQueryFilter(Table $subquery)
{ {
if (is_int($this->value) || ctype_digit($this->value)) { if (is_int($this->value) || ctype_digit((string) $this->value)) {
$subquery->eq(SubtaskModel::TABLE.'.user_id', $this->value); $subquery->eq(SubtaskModel::TABLE.'.user_id', $this->value);
} else { } else {
switch ($this->value) { switch ($this->value) {

View File

@@ -32,7 +32,7 @@ class TaskTitleFilter extends BaseFilter implements FilterInterface
*/ */
public function apply() public function apply()
{ {
if (ctype_digit($this->value) || (strlen($this->value) > 1 && $this->value[0] === '#' && ctype_digit(substr($this->value, 1)))) { if (ctype_digit((string) $this->value) || (strlen($this->value) > 1 && $this->value[0] === '#' && ctype_digit(substr($this->value, 1)))) {
$this->query->beginOr(); $this->query->beginOr();
$this->query->eq(TaskModel::TABLE.'.id', str_replace('#', '', $this->value)); $this->query->eq(TaskModel::TABLE.'.id', str_replace('#', '', $this->value));
$this->query->ilike(TaskModel::TABLE.'.title', '%'.$this->value.'%'); $this->query->ilike(TaskModel::TABLE.'.title', '%'.$this->value.'%');

View File

@@ -38,7 +38,7 @@ class DateHelper extends Base
return ''; return '';
} }
if (! ctype_digit($value)) { if (! ctype_digit((string) $value)) {
$value = strtotime($value); $value = strtotime($value);
} }

View File

@@ -58,7 +58,7 @@ class UserMentionJob extends BaseJob
{ {
$users = array(); $users = array();
if (preg_match_all('/@([^\s,!:?]+)/', $text, $matches)) { if ($text !== null && preg_match_all('/@([^\s,!:?]+)/', $text, $matches)) {
array_walk($matches[1], function (&$username) { $username = rtrim($username, '.'); }); array_walk($matches[1], function (&$username) { $username = rtrim($username, '.'); });
$users = $this->db->table(UserModel::TABLE) $users = $this->db->table(UserModel::TABLE)
->columns('id', 'username', 'name', 'email', 'language') ->columns('id', 'username', 'name', 'email', 'language')

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitcoin', 'XBT - Bitcoin' => 'XBT - Bitcoin',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitcoin', 'XBT - Bitcoin' => 'XBT - Bitcoin',
'You must select a file to upload as your avatar!' => 'Vælg fil som overføres som profil billede!', 'You must select a file to upload as your avatar!' => 'Vælg fil som overføres som profil billede!',
'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Overført fil er ikke et gyldigt billede! (*.gif, *.jpg, *.jpeg eller *.png)', 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Overført fil er ikke et gyldigt billede! (*.gif, *.jpg, *.jpeg eller *.png)',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitcoin', 'XBT - Bitcoin' => 'XBT - Bitcoin',
'You must select a file to upload as your avatar!' => 'Sie müssen eine Datei auswählen, die als Avatar hochgeladen werden soll!', 'You must select a file to upload as your avatar!' => 'Sie müssen eine Datei auswählen, die als Avatar hochgeladen werden soll!',
'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Die hochgeladene Datei ist kein gültiges Bild! (Nur *.gif, *.jpg, *.jpeg and *.png sind erlaubt!)', 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Die hochgeladene Datei ist kein gültiges Bild! (Nur *.gif, *.jpg, *.jpeg and *.png sind erlaubt!)',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitcoin', 'XBT - Bitcoin' => 'XBT - Bitcoin',
'You must select a file to upload as your avatar!' => 'Du musst eine Datei auswählen, die als Avatar hochgeladen werden soll!', 'You must select a file to upload as your avatar!' => 'Du musst eine Datei auswählen, die als Avatar hochgeladen werden soll!',
'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Die hochgeladene Datei ist kein gültiges Bild! (Nur *.gif, *.jpg, *.jpeg and *.png sind erlaubt!)', 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Die hochgeladene Datei ist kein gültiges Bild! (Nur *.gif, *.jpg, *.jpeg and *.png sind erlaubt!)',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitcoin', 'XBT - Bitcoin' => 'XBT - Bitcoin',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitcoin', 'XBT - Bitcoin' => 'XBT - Bitcoin',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - بیت کوین', 'XBT - Bitcoin' => 'XBT - بیت کوین',
'You must select a file to upload as your avatar!' => 'برای بارگذاری تصویر نمایه تان باید فایلی انتخاب کنید!', 'You must select a file to upload as your avatar!' => 'برای بارگذاری تصویر نمایه تان باید فایلی انتخاب کنید!',
'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'فایلی که بارگذاری کردید یک تصویر معتبر نیست! (فقط *.gif, *.jpg, *.jpeg و *.png مجاز هستند!)', 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'فایلی که بارگذاری کردید یک تصویر معتبر نیست! (فقط *.gif, *.jpg, *.jpeg و *.png مجاز هستند!)',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitcoin', 'XBT - Bitcoin' => 'XBT - Bitcoin',
'You must select a file to upload as your avatar!' => 'Vous devez sélectionner un fichier à télécharger pour votre avatar !', 'You must select a file to upload as your avatar!' => 'Vous devez sélectionner un fichier à télécharger pour votre avatar !',
'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Le fichier que vous avez téléchargé n\'est pas une image valide ! (Seuls * .gif, * .jpg, * .jpeg et * .png sont autorisés !)', 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Le fichier que vous avez téléchargé n\'est pas une image valide ! (Seuls * .gif, * .jpg, * .jpeg et * .png sont autorisés !)',
'Automatically set the due date when the task is moved away from a specific column' => 'Changer automatiquement la date d\'échéance lorsque la tâche est déplacée dans une colonne spécifique',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT bitcoin', 'XBT - Bitcoin' => 'XBT bitcoin',
'You must select a file to upload as your avatar!' => 'Ki kell választania egy fájlt a profilképként való feltöltéshez!', 'You must select a file to upload as your avatar!' => 'Ki kell választania egy fájlt a profilképként való feltöltéshez!',
'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'A feltöltött fájl nem érvényes kép! Csak *.gif, *.jpg, *.jpeg és *.png engedélyezett.', 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'A feltöltött fájl nem érvényes kép! Csak *.gif, *.jpg, *.jpeg és *.png engedélyezett.',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitcoin', 'XBT - Bitcoin' => 'XBT - Bitcoin',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitcoin', 'XBT - Bitcoin' => 'XBT - Bitcoin',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - биткоин', 'XBT - Bitcoin' => 'XBT - биткоин',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitcoin', 'XBT - Bitcoin' => 'XBT - Bitcoin',
'You must select a file to upload as your avatar!' => 'Musisz wybrać plik, który chcesz przesłać jako swój awatar!', 'You must select a file to upload as your avatar!' => 'Musisz wybrać plik, który chcesz przesłać jako swój awatar!',
'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Przesłany plik nie jest prawidłowym obrazem! (Tylko *.gif, *.jpg, *.jpeg i *.png są dozwolone!)', 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Przesłany plik nie jest prawidłowym obrazem! (Tylko *.gif, *.jpg, *.jpeg i *.png są dozwolone!)',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitcoin', 'XBT - Bitcoin' => 'XBT - Bitcoin',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitcoin', 'XBT - Bitcoin' => 'XBT - Bitcoin',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Биткоин', 'XBT - Bitcoin' => 'XBT - Биткоин',
'You must select a file to upload as your avatar!' => 'Вы должны выбрать файл для загрузки в качестве аватара!', 'You must select a file to upload as your avatar!' => 'Вы должны выбрать файл для загрузки в качестве аватара!',
'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Выбранный вами файл не является изображением! (Допустимые расширения: *.gif, *.jpg, *.jpeg, *.png)', 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Выбранный вами файл не является изображением! (Допустимые расширения: *.gif, *.jpg, *.jpeg, *.png)',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT Bitcoin', 'XBT - Bitcoin' => 'XBT Bitcoin',
'You must select a file to upload as your avatar!' => 'Musíte zvoliť súbor na nahratie ako svoj avatar', 'You must select a file to upload as your avatar!' => 'Musíte zvoliť súbor na nahratie ako svoj avatar',
'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'nahraný súbor nie je paltný obrázok! (Povolené sú len *.gif, *.jpg, *.jpeg a *.png!)', 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'nahraný súbor nie je paltný obrázok! (Povolené sú len *.gif, *.jpg, *.jpeg a *.png!)',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitkoin', 'XBT - Bitcoin' => 'XBT - Bitkoin',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1148,6 +1148,40 @@ return array(
'Remove this role' => 'Ta bort denna rollen', 'Remove this role' => 'Ta bort denna rollen',
'There is no restriction for this role.' => 'Det finns inga restriktioner för denna rollen', 'There is no restriction for this role.' => 'Det finns inga restriktioner för denna rollen',
'Only moving task between those columns is permitted' => 'Endast tillåtet att flytta uppgifter mellan dessa kolumner', 'Only moving task between those columns is permitted' => 'Endast tillåtet att flytta uppgifter mellan dessa kolumner',
// 'Close a task in a specific column when not moved during a given period' => '',
// 'Edit columns' => '',
// 'The column restriction has been created successfully.' => '',
// 'Unable to create this column restriction.' => '',
// 'Column restriction removed successfully.' => '',
// 'Unable to remove this restriction.' => '',
// 'Your custom project role has been created successfully.' => '',
// 'Unable to create custom project role.' => '',
// 'Your custom project role has been updated successfully.' => '',
// 'Unable to update custom project role.' => '',
// 'Custom project role removed successfully.' => '',
// 'Unable to remove this project role.' => '',
// 'The project restriction has been created successfully.' => '',
// 'Unable to create this project restriction.' => '',
// 'Project restriction removed successfully.' => '',
// 'You cannot create tasks in this column.' => '',
// 'Task creation is permitted for this column' => '',
// 'Closing or opening a task is permitted for this column' => '',
// 'Task creation is blocked for this column' => '',
// 'Closing or opening a task is blocked for this column' => '',
// 'Task creation is not permitted' => '',
// 'Closing or opening a task is not permitted' => '',
// 'New drag and drop restriction for the role "%s"' => '',
// 'People belonging to this role will be able to move tasks only between the source and the destination column.' => '',
// 'Remove a column restriction' => '',
// 'Do you really want to remove this column restriction: "%s" to "%s"?' => '',
// 'New column restriction for the role "%s"' => '',
// 'Rule' => '',
// 'Do you really want to remove this column restriction?' => '',
// 'Custom roles' => '',
// 'New custom project role' => '',
// 'Edit custom project role' => '',
// 'Remove a custom role' => '',
// 'Do you really want to remove this custom role: "%s"? All people assigned to this role will become project member.' => '',
'There is no custom role for this project.' => 'Det finns ingen anpassad roll för detta projekt.', 'There is no custom role for this project.' => 'Det finns ingen anpassad roll för detta projekt.',
'New project restriction for the role "%s"' => 'Ny projektrestriktion för roll "%s"', 'New project restriction for the role "%s"' => 'Ny projektrestriktion för roll "%s"',
'Restriction' => 'Restriktion', 'Restriction' => 'Restriktion',
@@ -1390,7 +1424,8 @@ return array(
'MXN - Mexican Peso' => 'MXN - Mexikansk peso', 'MXN - Mexican Peso' => 'MXN - Mexikansk peso',
'Estimated vs actual time per column' => 'Uppskattad kontra faktisk tid per kolumn', 'Estimated vs actual time per column' => 'Uppskattad kontra faktisk tid per kolumn',
'HUF - Hungarian Forint' => 'HUF - Ungersk forint', 'HUF - Hungarian Forint' => 'HUF - Ungersk forint',
'XBT - bitcoin' => 'XBT - bitcoin', // 'XBT - Bitcoin' => '',
'You must select a file to upload as your avatar!' => 'Du måste välja en fil att uppladda som din avatar!', 'You must select a file to upload as your avatar!' => 'Du måste välja en fil att uppladda som din avatar!',
'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Filen du laddade upp är inte ett giltigt bildformat! (Endast *.gif *.jpg *.jpeg samt *.png är tillåtet!)', 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => 'Filen du laddade upp är inte ett giltigt bildformat! (Endast *.gif *.jpg *.jpeg samt *.png är tillåtet!)',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - Bitcoin', 'XBT - Bitcoin' => 'XBT - Bitcoin',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT Біткоїн', 'XBT - Bitcoin' => 'XBT Біткоїн',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
'XBT - Bitcoin' => 'XBT - 比特币', 'XBT - Bitcoin' => 'XBT - 比特币',
'You must select a file to upload as your avatar!' => '你必须选择一张图片作为你的头像', 'You must select a file to upload as your avatar!' => '你必须选择一张图片作为你的头像',
'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '你所上传的文件不是有效图像!(只有*.gif, *.jpg, *.jpeg and *.png才被允许)', 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '你所上传的文件不是有效图像!(只有*.gif, *.jpg, *.jpeg and *.png才被允许)',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -1427,4 +1427,5 @@ return array(
// 'XBT - Bitcoin' => '', // 'XBT - Bitcoin' => '',
// 'You must select a file to upload as your avatar!' => '', // 'You must select a file to upload as your avatar!' => '',
// 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '', // 'The file you uploaded is not a valid image! (Only *.gif, *.jpg, *.jpeg and *.png are allowed!)' => '',
// 'Automatically set the due date when the task is moved away from a specific column' => '',
); );

View File

@@ -18,7 +18,6 @@
<?= $this->render('comment/show', array( <?= $this->render('comment/show', array(
'comment' => $comment, 'comment' => $comment,
'task' => $task, 'task' => $task,
'project' => $project,
'editable' => $editable, 'editable' => $editable,
'is_public' => isset($is_public) && $is_public, 'is_public' => isset($is_public) && $is_public,
)) ?> )) ?>

View File

@@ -34,8 +34,3 @@ foreach (array('gd', 'mbstring', 'hash', 'openssl', 'json', 'hash', 'ctype', 'fi
if (ini_get('arg_separator.output') === '&amp;') { if (ini_get('arg_separator.output') === '&amp;') {
ini_set('arg_separator.output', '&'); ini_set('arg_separator.output', '&');
} }
// Make sure we can read files with "\r", "\r\n" and "\n"
if (ini_get('auto_detect_line_endings') != 1) {
ini_set("auto_detect_line_endings", 1);
}

File diff suppressed because one or more lines are too long

View File

@@ -28,13 +28,14 @@
"ext-session" : "*", "ext-session" : "*",
"christian-riesen/otp" : "1.4.3", "christian-riesen/otp" : "1.4.3",
"eluceo/ical": "0.16.1", "eluceo/ical": "0.16.1",
"erusev/parsedown" : "^1.7", "erusev/parsedown" : "1.7.4",
"pimple/pimple" : "3.5.0", "pimple/pimple" : "3.5.0",
"psr/log": "~1.0", "psr/log": "1.1.4",
"swiftmailer/swiftmailer" : "5.4.8", "swiftmailer/swiftmailer" : "5.4.8",
"symfony/console" : "4.2.12", "symfony/console" : "4.4.37",
"symfony/event-dispatcher" : "3.4.2", "symfony/event-dispatcher" : "4.4.37",
"gregwar/captcha": "1.1.9" "gregwar/captcha": "1.1.9",
"symfony/finder": "5.4.3"
}, },
"autoload" : { "autoload" : {
"classmap" : ["app/"], "classmap" : ["app/"],
@@ -56,7 +57,7 @@
}, },
"require-dev" : { "require-dev" : {
"symfony/stopwatch" : "5.4.3", "symfony/stopwatch" : "5.4.3",
"phpunit/phpunit" : "^7", "phpunit/phpunit" : "9.5.13",
"roave/security-advisories": "dev-master" "roave/security-advisories": "dev-master"
} }
} }

2016
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -16,4 +16,4 @@ pm.start_servers = 1
pm.min_spare_servers = 1 pm.min_spare_servers = 1
pm.max_spare_servers = 3 pm.max_spare_servers = 3
pm.max_requests = 2048 pm.max_requests = 2048
include = /etc/php7/php-fpm.d/env.conf include = /etc/php8/php-fpm.d/env.conf

View File

@@ -1,2 +1,2 @@
#!/bin/execlineb -P #!/bin/execlineb -P
php-fpm7 -F php-fpm8 -F

View File

@@ -13,7 +13,7 @@ class Integer extends Base
return ctype_digit(substr($data[$this->field], 1)); return ctype_digit(substr($data[$this->field], 1));
} }
return ctype_digit($data[$this->field]); return ctype_digit((string) $data[$this->field]);
} }
else { else {
return is_int($data[$this->field]); return is_int($data[$this->field]);

View File

@@ -10,7 +10,7 @@ class ActionProcedureTest extends BaseProcedureTest
{ {
$actions = $this->app->getAvailableActions(); $actions = $this->app->getAvailableActions();
$this->assertNotEmpty($actions); $this->assertNotEmpty($actions);
$this->assertInternalType('array', $actions); $this->assertIsArray($actions);
$this->assertArrayHasKey('\Kanboard\Action\TaskCloseColumn', $actions); $this->assertArrayHasKey('\Kanboard\Action\TaskCloseColumn', $actions);
} }
@@ -18,7 +18,7 @@ class ActionProcedureTest extends BaseProcedureTest
{ {
$events = $this->app->getAvailableActionEvents(); $events = $this->app->getAvailableActionEvents();
$this->assertNotEmpty($events); $this->assertNotEmpty($events);
$this->assertInternalType('array', $events); $this->assertIsArray($events);
$this->assertArrayHasKey('task.move.column', $events); $this->assertArrayHasKey('task.move.column', $events);
} }
@@ -26,7 +26,7 @@ class ActionProcedureTest extends BaseProcedureTest
{ {
$events = $this->app->getCompatibleActionEvents('\Kanboard\Action\TaskCloseColumn'); $events = $this->app->getCompatibleActionEvents('\Kanboard\Action\TaskCloseColumn');
$this->assertNotEmpty($events); $this->assertNotEmpty($events);
$this->assertInternalType('array', $events); $this->assertIsArray($events);
$this->assertArrayHasKey('task.move.column', $events); $this->assertArrayHasKey('task.move.column', $events);
} }
@@ -49,7 +49,7 @@ class ActionProcedureTest extends BaseProcedureTest
{ {
$actions = $this->app->getActions($this->projectId); $actions = $this->app->getActions($this->projectId);
$this->assertNotEmpty($actions); $this->assertNotEmpty($actions);
$this->assertInternalType('array', $actions); $this->assertIsArray($actions);
$this->assertArrayHasKey('id', $actions[0]); $this->assertArrayHasKey('id', $actions[0]);
$this->assertArrayHasKey('project_id', $actions[0]); $this->assertArrayHasKey('project_id', $actions[0]);
$this->assertArrayHasKey('event_name', $actions[0]); $this->assertArrayHasKey('event_name', $actions[0]);

View File

@@ -27,7 +27,7 @@ abstract class BaseProcedureTest extends PHPUnit\Framework\TestCase
protected $username = 'test-user'; protected $username = 'test-user';
protected $userId; protected $userId;
public function setUp() protected function setUp(): void
{ {
$this->setUpAppClient(); $this->setUpAppClient();
$this->setUpAdminUser(); $this->setUpAdminUser();

View File

@@ -40,7 +40,7 @@ class CategoryProcedureTest extends BaseProcedureTest
{ {
$category = $this->app->getCategory($this->categoryId); $category = $this->app->getCategory($this->categoryId);
$this->assertInternalType('array', $category); $this->assertIsArray($category);
$this->assertEquals($this->categoryId, $category['id']); $this->assertEquals($this->categoryId, $category['id']);
$this->assertEquals('Category', $category['name']); $this->assertEquals('Category', $category['name']);
$this->assertEquals($this->projectId, $category['project_id']); $this->assertEquals($this->projectId, $category['project_id']);

View File

@@ -43,11 +43,11 @@ class LinkProcedureTest extends BaseProcedureTest
{ {
$link_id = $this->app->createLink(array('label' => 'test')); $link_id = $this->app->createLink(array('label' => 'test'));
$this->assertNotFalse($link_id); $this->assertNotFalse($link_id);
$this->assertInternalType('int', $link_id); $this->assertIsInt($link_id);
$link_id = $this->app->createLink(array('label' => 'foo', 'opposite_label' => 'bar')); $link_id = $this->app->createLink(array('label' => 'foo', 'opposite_label' => 'bar'));
$this->assertNotFalse($link_id); $this->assertNotFalse($link_id);
$this->assertInternalType('int', $link_id); $this->assertIsInt($link_id);
} }
public function testUpdateLink() public function testUpdateLink()

View File

@@ -46,7 +46,7 @@ class ProjectProcedureTest extends BaseProcedureTest
{ {
$projects = $this->app->getAllProjects(); $projects = $this->app->getAllProjects();
$this->assertNotEmpty($projects); $this->assertNotEmpty($projects);
$this->assertInternalType('array', $projects); $this->assertIsArray($projects);
$this->assertArrayHasKey('board', $projects[0]['url']); $this->assertArrayHasKey('board', $projects[0]['url']);
$this->assertArrayHasKey('list', $projects[0]['url']); $this->assertArrayHasKey('list', $projects[0]['url']);
} }
@@ -54,14 +54,14 @@ class ProjectProcedureTest extends BaseProcedureTest
public function assertGetProjectActivity() public function assertGetProjectActivity()
{ {
$activities = $this->app->getProjectActivity($this->projectId); $activities = $this->app->getProjectActivity($this->projectId);
$this->assertInternalType('array', $activities); $this->assertIsArray($activities);
$this->assertCount(0, $activities); $this->assertCount(0, $activities);
} }
public function assertGetProjectsActivity() public function assertGetProjectsActivity()
{ {
$activities = $this->app->getProjectActivities(array('project_ids' => array($this->projectId))); $activities = $this->app->getProjectActivities(array('project_ids' => array($this->projectId)));
$this->assertInternalType('array', $activities); $this->assertIsArray($activities);
$this->assertCount(0, $activities); $this->assertCount(0, $activities);
} }

View File

@@ -31,7 +31,7 @@ class SwimlaneProcedureTest extends BaseProcedureTest
public function assertGetSwimlane() public function assertGetSwimlane()
{ {
$swimlane = $this->app->getSwimlane($this->swimlaneId); $swimlane = $this->app->getSwimlane($this->swimlaneId);
$this->assertInternalType('array', $swimlane); $this->assertIsArray($swimlane);
$this->assertEquals('Swimlane 1', $swimlane['name']); $this->assertEquals('Swimlane 1', $swimlane['name']);
} }

View File

@@ -44,7 +44,7 @@ class TaskProcedureTest extends BaseProcedureTest
public function assertGetAllTasks() public function assertGetAllTasks()
{ {
$tasks = $this->app->getAllTasks($this->projectId); $tasks = $this->app->getAllTasks($this->projectId);
$this->assertInternalType('array', $tasks); $this->assertIsArray($tasks);
$this->assertNotEmpty($tasks); $this->assertNotEmpty($tasks);
$this->assertArrayHasKey('url', $tasks[0]); $this->assertArrayHasKey('url', $tasks[0]);
} }

View File

@@ -32,7 +32,7 @@ class UserProcedureTest extends BaseProcedureTest
public function assertGetAllUsers() public function assertGetAllUsers()
{ {
$users = $this->app->getAllUsers(); $users = $this->app->getAllUsers();
$this->assertInternalType('array', $users); $this->assertIsArray($users);
$this->assertNotEmpty($users); $this->assertNotEmpty($users);
} }

View File

@@ -43,7 +43,7 @@ class AverageLeadCycleTimeAnalyticTest extends Base
$stats = $averageLeadCycleTimeAnalytic->build(1); $stats = $averageLeadCycleTimeAnalytic->build(1);
$this->assertEquals(5, $stats['count']); $this->assertEquals(5, $stats['count']);
$this->assertEquals(3600 + 1800 + 3600 + 2*3600, $stats['total_lead_time'], '', 5); $this->assertEquals(3600 + 1800 + 3600 + 2*3600, $stats['total_lead_time'], '', 10);
$this->assertEquals(1800 + 900, $stats['total_cycle_time'], '', 5); $this->assertEquals(1800 + 900, $stats['total_cycle_time'], '', 5);
$this->assertEquals((3600 + 1800 + 3600 + 2*3600) / 5, $stats['avg_lead_time'], '', 5); $this->assertEquals((3600 + 1800 + 3600 + 2*3600) / 5, $stats['avg_lead_time'], '', 5);
$this->assertEquals((1800 + 900) / 5, $stats['avg_cycle_time'], '', 5); $this->assertEquals((1800 + 900) / 5, $stats['avg_cycle_time'], '', 5);

View File

@@ -8,7 +8,7 @@ require_once __DIR__.'/../Base.php';
class ReverseProxyAuthTest extends Base class ReverseProxyAuthTest extends Base
{ {
public function setUp() protected function setUp(): void
{ {
parent::setUp(); parent::setUp();

View File

@@ -20,7 +20,7 @@ abstract class Base extends PHPUnit\Framework\TestCase
*/ */
protected $dispatcher; protected $dispatcher;
public function setUp() protected function setUp(): void
{ {
date_default_timezone_set('UTC'); date_default_timezone_set('UTC');
$_SESSION = array(); $_SESSION = array();
@@ -98,7 +98,7 @@ abstract class Base extends PHPUnit\Framework\TestCase
$loader->register(); $loader->register();
} }
public function tearDown() protected function tearDown(): void
{ {
$this->container['db']->closeConnection(); $this->container['db']->closeConnection();
unset ($this->container); unset ($this->container);

View File

@@ -41,7 +41,7 @@ class FileCacheTest extends \Base
*/ */
public static $functions; public static $functions;
public function setUp() protected function setUp(): void
{ {
parent::setup(); parent::setup();
@@ -58,7 +58,7 @@ class FileCacheTest extends \Base
->getMock(); ->getMock();
} }
public function tearDown() protected function tearDown(): void
{ {
parent::tearDown(); parent::tearDown();
self::$functions = null; self::$functions = null;
@@ -71,7 +71,7 @@ class FileCacheTest extends \Base
$cache = new FileCache(); $cache = new FileCache();
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('is_dir') ->method('is_dir')
->with( ->with(
$this->equalTo(CACHE_DIR) $this->equalTo(CACHE_DIR)
@@ -79,7 +79,7 @@ class FileCacheTest extends \Base
->will($this->returnValue(false)); ->will($this->returnValue(false));
self::$functions self::$functions
->expects($this->at(1)) ->expects($this->once())
->method('mkdir') ->method('mkdir')
->with( ->with(
$this->equalTo(CACHE_DIR), $this->equalTo(CACHE_DIR),
@@ -88,7 +88,7 @@ class FileCacheTest extends \Base
->will($this->returnValue(true)); ->will($this->returnValue(true));
self::$functions self::$functions
->expects($this->at(2)) ->expects($this->once())
->method('file_put_contents') ->method('file_put_contents')
->with( ->with(
$this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key), $this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key),
@@ -106,7 +106,7 @@ class FileCacheTest extends \Base
$cache = new FileCache(); $cache = new FileCache();
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('file_exists') ->method('file_exists')
->with( ->with(
$this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key) $this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key)
@@ -114,7 +114,7 @@ class FileCacheTest extends \Base
->will($this->returnValue(true)); ->will($this->returnValue(true));
self::$functions self::$functions
->expects($this->at(1)) ->expects($this->once())
->method('file_get_contents') ->method('file_get_contents')
->with( ->with(
$this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key) $this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key)
@@ -130,7 +130,7 @@ class FileCacheTest extends \Base
$cache = new FileCache(); $cache = new FileCache();
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('file_exists') ->method('file_exists')
->with( ->with(
$this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key) $this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key)
@@ -146,7 +146,7 @@ class FileCacheTest extends \Base
$cache = new FileCache(); $cache = new FileCache();
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('file_exists') ->method('file_exists')
->with( ->with(
$this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key) $this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key)
@@ -166,7 +166,7 @@ class FileCacheTest extends \Base
$cache = new FileCache(); $cache = new FileCache();
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('file_exists') ->method('file_exists')
->with( ->with(
$this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key) $this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key)
@@ -174,7 +174,7 @@ class FileCacheTest extends \Base
->will($this->returnValue(true)); ->will($this->returnValue(true));
self::$functions self::$functions
->expects($this->at(1)) ->expects($this->once())
->method('unlink') ->method('unlink')
->with( ->with(
$this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key) $this->equalTo(CACHE_DIR.DIRECTORY_SEPARATOR.$key)

View File

@@ -13,7 +13,7 @@ class RememberMeCookieTest extends \Base
{ {
public static $functions; public static $functions;
public function setUp() protected function setUp(): void
{ {
parent::setup(); parent::setup();
@@ -25,7 +25,7 @@ class RememberMeCookieTest extends \Base
->getMock(); ->getMock();
} }
public function tearDown() protected function tearDown(): void
{ {
parent::tearDown(); parent::tearDown();
self::$functions = null; self::$functions = null;

View File

@@ -42,7 +42,7 @@ class ClientTest extends \Base
{ {
public static $functions; public static $functions;
public function setUp() protected function setUp(): void
{ {
parent::setup(); parent::setup();
@@ -60,7 +60,7 @@ class ClientTest extends \Base
->getMock(); ->getMock();
} }
public function tearDown() protected function tearDown(): void
{ {
parent::tearDown(); parent::tearDown();
self::$functions = null; self::$functions = null;

View File

@@ -11,7 +11,7 @@ class LdapGroupTest extends Base
private $client; private $client;
private $group; private $group;
public function setUp() protected function setUp(): void
{ {
parent::setUp(); parent::setUp();

View File

@@ -15,7 +15,7 @@ class LdapUserTest extends Base
private $user; private $user;
private $group; private $group;
public function setUp() protected function setUp(): void
{ {
parent::setUp(); parent::setUp();

View File

@@ -19,7 +19,7 @@ class QueryTest extends \Base
public static $functions; public static $functions;
private $client; private $client;
public function setUp() protected function setUp(): void
{ {
parent::setup(); parent::setup();
@@ -39,7 +39,7 @@ class QueryTest extends \Base
->getMock(); ->getMock();
} }
public function tearDown() protected function tearDown(): void
{ {
parent::tearDown(); parent::tearDown();
self::$functions = null; self::$functions = null;

View File

@@ -53,7 +53,7 @@ class FileStorageTest extends \Base
{ {
public static $functions; public static $functions;
public function setUp() protected function setUp(): void
{ {
parent::setup(); parent::setup();
@@ -73,7 +73,7 @@ class FileStorageTest extends \Base
->getMock(); ->getMock();
} }
public function tearDown() protected function tearDown(): void
{ {
parent::tearDown(); parent::tearDown();
self::$functions = null; self::$functions = null;
@@ -85,7 +85,7 @@ class FileStorageTest extends \Base
$storage = new FileStorage('somewhere'); $storage = new FileStorage('somewhere');
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('is_dir') ->method('is_dir')
->with( ->with(
$this->equalTo('somewhere') $this->equalTo('somewhere')
@@ -93,7 +93,7 @@ class FileStorageTest extends \Base
->will($this->returnValue(false)); ->will($this->returnValue(false));
self::$functions self::$functions
->expects($this->at(1)) ->expects($this->once())
->method('mkdir') ->method('mkdir')
->with( ->with(
$this->equalTo('somewhere') $this->equalTo('somewhere')
@@ -101,7 +101,7 @@ class FileStorageTest extends \Base
->will($this->returnValue(true)); ->will($this->returnValue(true));
self::$functions self::$functions
->expects($this->at(2)) ->expects($this->once())
->method('file_put_contents') ->method('file_put_contents')
->with( ->with(
$this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey'), $this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey'),
@@ -118,7 +118,7 @@ class FileStorageTest extends \Base
$storage = new FileStorage('somewhere'); $storage = new FileStorage('somewhere');
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('is_dir') ->method('is_dir')
->with( ->with(
$this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'my') $this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'my')
@@ -126,7 +126,7 @@ class FileStorageTest extends \Base
->will($this->returnValue(false)); ->will($this->returnValue(false));
self::$functions self::$functions
->expects($this->at(1)) ->expects($this->once())
->method('mkdir') ->method('mkdir')
->with( ->with(
$this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'my') $this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'my')
@@ -134,7 +134,7 @@ class FileStorageTest extends \Base
->will($this->returnValue(true)); ->will($this->returnValue(true));
self::$functions self::$functions
->expects($this->at(2)) ->expects($this->once())
->method('file_put_contents') ->method('file_put_contents')
->with( ->with(
$this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'my'.DIRECTORY_SEPARATOR.'key'), $this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'my'.DIRECTORY_SEPARATOR.'key'),
@@ -150,11 +150,13 @@ class FileStorageTest extends \Base
*/ */
public function testPutWhenNotAbleToCreateFolder() public function testPutWhenNotAbleToCreateFolder()
{ {
$this->expectException(\Kanboard\Core\ObjectStorage\ObjectStorageException::class);
$data = 'data'; $data = 'data';
$storage = new FileStorage('somewhere'); $storage = new FileStorage('somewhere');
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('is_dir') ->method('is_dir')
->with( ->with(
$this->equalTo('somewhere') $this->equalTo('somewhere')
@@ -162,7 +164,7 @@ class FileStorageTest extends \Base
->will($this->returnValue(false)); ->will($this->returnValue(false));
self::$functions self::$functions
->expects($this->at(1)) ->expects($this->once())
->method('mkdir') ->method('mkdir')
->with( ->with(
$this->equalTo('somewhere') $this->equalTo('somewhere')
@@ -177,7 +179,7 @@ class FileStorageTest extends \Base
$storage = new FileStorage('somewhere'); $storage = new FileStorage('somewhere');
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('file_exists') ->method('file_exists')
->with( ->with(
$this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey') $this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey')
@@ -185,7 +187,7 @@ class FileStorageTest extends \Base
->will($this->returnValue(true)); ->will($this->returnValue(true));
self::$functions self::$functions
->expects($this->at(1)) ->expects($this->once())
->method('file_get_contents') ->method('file_get_contents')
->with( ->with(
$this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey') $this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey')
@@ -202,8 +204,10 @@ class FileStorageTest extends \Base
{ {
$storage = new FileStorage('somewhere'); $storage = new FileStorage('somewhere');
$this->expectException(\Kanboard\Core\ObjectStorage\ObjectStorageException::class);
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('file_exists') ->method('file_exists')
->with( ->with(
$this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey') $this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey')
@@ -218,7 +222,7 @@ class FileStorageTest extends \Base
$storage = new FileStorage('somewhere'); $storage = new FileStorage('somewhere');
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('file_exists') ->method('file_exists')
->with( ->with(
$this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey') $this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey')
@@ -226,7 +230,7 @@ class FileStorageTest extends \Base
->will($this->returnValue(true)); ->will($this->returnValue(true));
self::$functions self::$functions
->expects($this->at(1)) ->expects($this->once())
->method('readfile') ->method('readfile')
->with( ->with(
$this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey') $this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey')
@@ -242,7 +246,7 @@ class FileStorageTest extends \Base
$storage = new FileStorage('somewhere'); $storage = new FileStorage('somewhere');
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('file_exists') ->method('file_exists')
->with( ->with(
$this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey') $this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey')
@@ -250,7 +254,7 @@ class FileStorageTest extends \Base
->will($this->returnValue(true)); ->will($this->returnValue(true));
self::$functions self::$functions
->expects($this->at(1)) ->expects($this->once())
->method('unlink') ->method('unlink')
->with( ->with(
$this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey') $this->equalTo('somewhere'.DIRECTORY_SEPARATOR.'mykey')
@@ -265,7 +269,7 @@ class FileStorageTest extends \Base
$storage = new FileStorage('somewhere'); $storage = new FileStorage('somewhere');
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('is_dir') ->method('is_dir')
->with( ->with(
$this->equalTo('somewhere') $this->equalTo('somewhere')
@@ -273,7 +277,7 @@ class FileStorageTest extends \Base
->will($this->returnValue(true)); ->will($this->returnValue(true));
self::$functions self::$functions
->expects($this->at(1)) ->expects($this->once())
->method('rename') ->method('rename')
->with( ->with(
$this->equalTo('src_file'), $this->equalTo('src_file'),
@@ -289,7 +293,7 @@ class FileStorageTest extends \Base
$storage = new FileStorage('somewhere'); $storage = new FileStorage('somewhere');
self::$functions self::$functions
->expects($this->at(0)) ->expects($this->once())
->method('is_dir') ->method('is_dir')
->with( ->with(
$this->equalTo('somewhere') $this->equalTo('somewhere')
@@ -297,7 +301,7 @@ class FileStorageTest extends \Base
->will($this->returnValue(true)); ->will($this->returnValue(true));
self::$functions self::$functions
->expects($this->at(1)) ->expects($this->once())
->method('move_uploaded_file') ->method('move_uploaded_file')
->with( ->with(
$this->equalTo('src_file'), $this->equalTo('src_file'),

View File

@@ -46,7 +46,7 @@ class HookTest extends Base
return array($p); return array($p);
}); });
$hook->on('myhook', function () { $hook->on('myhook', function ($p) {
return array('D'); return array('D');
}); });

View File

@@ -86,8 +86,8 @@ class AuthenticationManagerTest extends Base
$this->assertTrue($authManager->preAuthentication()); $this->assertTrue($authManager->preAuthentication());
$called = $this->container['dispatcher']->getCalledListeners(); $called = $this->container['dispatcher']->getCalledListeners();
$this->assertArrayHasKey(AuthenticationManager::EVENT_SUCCESS.'.AuthenticationManagerTest::onSuccess', $called); $this->assertCount(1, $called);
$this->assertArrayNotHasKey(AuthenticationManager::EVENT_FAILURE.'.AuthenticationManagerTest::onFailure', $called); $this->assertEquals('auth.success', $called[0]['event']);
} }
public function testPreAuthenticationFailed() public function testPreAuthenticationFailed()
@@ -102,8 +102,7 @@ class AuthenticationManagerTest extends Base
$this->assertFalse($authManager->preAuthentication()); $this->assertFalse($authManager->preAuthentication());
$called = $this->container['dispatcher']->getCalledListeners(); $called = $this->container['dispatcher']->getCalledListeners();
$this->assertArrayNotHasKey(AuthenticationManager::EVENT_SUCCESS.'.AuthenticationManagerTest::onSuccess', $called); $this->assertCount(0, $called);
$this->assertArrayNotHasKey(AuthenticationManager::EVENT_FAILURE.'.AuthenticationManagerTest::onFailure', $called);
} }
public function testPasswordAuthenticationSuccessful() public function testPasswordAuthenticationSuccessful()
@@ -117,8 +116,8 @@ class AuthenticationManagerTest extends Base
$this->assertTrue($authManager->passwordAuthentication('admin', 'admin')); $this->assertTrue($authManager->passwordAuthentication('admin', 'admin'));
$called = $this->container['dispatcher']->getCalledListeners(); $called = $this->container['dispatcher']->getCalledListeners();
$this->assertArrayHasKey(AuthenticationManager::EVENT_SUCCESS.'.AuthenticationManagerTest::onSuccess', $called); $this->assertCount(1, $called);
$this->assertArrayNotHasKey(AuthenticationManager::EVENT_FAILURE.'.AuthenticationManagerTest::onFailure', $called); $this->assertEquals('auth.success', $called[0]['event']);
} }
public function testPasswordAuthenticationFailed() public function testPasswordAuthenticationFailed()
@@ -132,8 +131,8 @@ class AuthenticationManagerTest extends Base
$this->assertFalse($authManager->passwordAuthentication('admin', 'wrong password')); $this->assertFalse($authManager->passwordAuthentication('admin', 'wrong password'));
$called = $this->container['dispatcher']->getCalledListeners(); $called = $this->container['dispatcher']->getCalledListeners();
$this->assertArrayNotHasKey(AuthenticationManager::EVENT_SUCCESS.'.AuthenticationManagerTest::onSuccess', $called); $this->assertCount(1, $called);
$this->assertArrayHasKey(AuthenticationManager::EVENT_FAILURE.'.AuthenticationManagerTest::onFailure', $called); $this->assertEquals('auth.failure', $called[0]['event']);
} }
public function onSuccess($event) public function onSuccess($event)

View File

@@ -6,7 +6,7 @@ use Kanboard\Core\Translator;
class TranslatorTest extends Base class TranslatorTest extends Base
{ {
public function setUp() protected function setUp(): void
{ {
parent::setUp(); parent::setUp();
Translator::unload(); Translator::unload();

View File

@@ -12,7 +12,7 @@ class UserSyncTest extends Base
{ {
$user = new LdapUserProvider('ldapId', 'bob', 'Bob', '', Role::APP_MANAGER, array()); $user = new LdapUserProvider('ldapId', 'bob', 'Bob', '', Role::APP_MANAGER, array());
$userSync = new UserSync($this->container); $userSync = new UserSync($this->container);
$result = $userSync->synchronize($user);
$profile = array( $profile = array(
'id' => 2, 'id' => 2,
'username' => 'bob', 'username' => 'bob',
@@ -22,7 +22,9 @@ class UserSyncTest extends Base
'is_ldap_user' => 1, 'is_ldap_user' => 1,
); );
$this->assertArraySubset($profile, $userSync->synchronize($user)); foreach ($profile as $key => $value) {
$this->assertEquals($value, $result[$key]);
}
} }
public function testSynchronizeExistingUser() public function testSynchronizeExistingUser()
@@ -38,7 +40,10 @@ class UserSyncTest extends Base
'role' => Role::APP_MANAGER, 'role' => Role::APP_MANAGER,
); );
$this->assertArraySubset($profile, $userSync->synchronize($user)); $result = $userSync->synchronize($user);
foreach ($profile as $key => $value) {
$this->assertEquals($value, $result[$key]);
}
$user = new LdapUserProvider('ldapId', 'admin', '', '', Role::APP_ADMIN, array()); $user = new LdapUserProvider('ldapId', 'admin', '', '', Role::APP_ADMIN, array());
@@ -50,6 +55,9 @@ class UserSyncTest extends Base
'role' => Role::APP_ADMIN, 'role' => Role::APP_ADMIN,
); );
$this->assertArraySubset($profile, $userSync->synchronize($user)); $result = $userSync->synchronize($user);
foreach ($profile as $key => $value) {
$this->assertEquals($value, $result[$key]);
}
} }
} }

View File

@@ -24,7 +24,7 @@ class MetadataCacheDecoratorTest extends Base
*/ */
protected $metadataCacheDecorator; protected $metadataCacheDecorator;
public function setUp() protected function setUp(): void
{ {
parent::setUp(); parent::setUp();
@@ -61,11 +61,11 @@ class MetadataCacheDecoratorTest extends Base
->method('set'); ->method('set');
$this->metadataModelMock $this->metadataModelMock
->expects($this->at(0)) ->expects($this->once())
->method('save'); ->method('save');
$this->metadataModelMock $this->metadataModelMock
->expects($this->at(1)) ->expects($this->once())
->method('getAll') ->method('getAll')
->with($this->entityId) ->with($this->entityId)
; ;
@@ -100,14 +100,14 @@ class MetadataCacheDecoratorTest extends Base
public function testGetWithoutCache() public function testGetWithoutCache()
{ {
$this->cacheMock $this->cacheMock
->expects($this->at(0)) ->expects($this->once())
->method('get') ->method('get')
->with($this->cachePrefix.$this->entityId) ->with($this->cachePrefix.$this->entityId)
->will($this->returnValue(null)) ->will($this->returnValue(null))
; ;
$this->cacheMock $this->cacheMock
->expects($this->at(1)) ->expects($this->once())
->method('set') ->method('set')
->with( ->with(
$this->cachePrefix.$this->entityId, $this->cachePrefix.$this->entityId,

View File

@@ -121,7 +121,7 @@ class HookHelperTest extends Base
$this->container['helper'] $this->container['helper']
->asset ->asset
->expects($this->at(0)) ->expects($this->once())
->method('css') ->method('css')
->with( ->with(
$this->equalTo('skin.css') $this->equalTo('skin.css')
@@ -130,7 +130,7 @@ class HookHelperTest extends Base
$this->container['helper'] $this->container['helper']
->asset ->asset
->expects($this->at(1)) ->expects($this->once())
->method('js') ->method('js')
->with( ->with(
$this->equalTo('skin.js') $this->equalTo('skin.js')
@@ -141,7 +141,7 @@ class HookHelperTest extends Base
$hookHelper->attach('test1', 'skin.css'); $hookHelper->attach('test1', 'skin.css');
$hookHelper->attach('test2', 'skin.js'); $hookHelper->attach('test2', 'skin.js');
$this->assertContains('<link rel="stylesheet" href="skin.css"></link>', $hookHelper->asset('css', 'test1')); $this->assertStringContainsString('<link rel="stylesheet" href="skin.css"></link>', $hookHelper->asset('css', 'test1'));
$this->assertContains('<script src="skin.js"></script>', $hookHelper->asset('js', 'test2')); $this->assertStringContainsString('<script src="skin.js"></script>', $hookHelper->asset('js', 'test2'));
} }
} }

View File

@@ -36,7 +36,7 @@ class ProjectActivityHelperTest extends Base
$this->assertNotEmpty($events[0]['event_content']); $this->assertNotEmpty($events[0]['event_content']);
$this->assertNotEmpty($events[0]['event_title']); $this->assertNotEmpty($events[0]['event_title']);
$this->assertNotEmpty($events[0]['author']); $this->assertNotEmpty($events[0]['author']);
$this->assertInternalType('array', $events[0]['task']); $this->assertIsArray($events[0]['task']);
} }
public function testGetProjectsEvents() public function testGetProjectsEvents()
@@ -66,7 +66,7 @@ class ProjectActivityHelperTest extends Base
$this->assertNotEmpty($events[0]['event_content']); $this->assertNotEmpty($events[0]['event_content']);
$this->assertNotEmpty($events[0]['event_title']); $this->assertNotEmpty($events[0]['event_title']);
$this->assertNotEmpty($events[0]['author']); $this->assertNotEmpty($events[0]['author']);
$this->assertInternalType('array', $events[0]['task']); $this->assertIsArray($events[0]['task']);
} }
public function testGetTaskEvents() public function testGetTaskEvents()
@@ -92,6 +92,6 @@ class ProjectActivityHelperTest extends Base
$this->assertNotEmpty($events[0]['event_content']); $this->assertNotEmpty($events[0]['event_content']);
$this->assertNotEmpty($events[0]['event_title']); $this->assertNotEmpty($events[0]['event_title']);
$this->assertNotEmpty($events[0]['author']); $this->assertNotEmpty($events[0]['author']);
$this->assertInternalType('array', $events[0]['task']); $this->assertIsArray($events[0]['task']);
} }
} }

View File

@@ -45,9 +45,10 @@ class CommentEventJobTest extends Base
$this->assertTrue($commentModel->remove(1)); $this->assertTrue($commentModel->remove(1));
$called = $this->container['dispatcher']->getCalledListeners(); $called = $this->container['dispatcher']->getCalledListeners();
$this->assertArrayHasKey(CommentModel::EVENT_CREATE.'.closure', $called); $this->assertCount(3, $called);
$this->assertArrayHasKey(CommentModel::EVENT_UPDATE.'.closure', $called); $this->assertEquals(CommentModel::EVENT_CREATE, $called[0]['event']);
$this->assertArrayHasKey(CommentModel::EVENT_DELETE.'.closure', $called); $this->assertEquals(CommentModel::EVENT_UPDATE, $called[1]['event']);
$this->assertEquals(CommentModel::EVENT_DELETE, $called[2]['event']);
} }
public function testThatUserMentionJobIsCalled() public function testThatUserMentionJobIsCalled()

View File

@@ -38,6 +38,7 @@ class ProjectFileEventJobTest extends Base
$this->assertEquals(1, $projectFileModel->create(1, 'Test', '/tmp/test', 123)); $this->assertEquals(1, $projectFileModel->create(1, 'Test', '/tmp/test', 123));
$called = $this->container['dispatcher']->getCalledListeners(); $called = $this->container['dispatcher']->getCalledListeners();
$this->assertArrayHasKey(ProjectFileModel::EVENT_CREATE.'.closure', $called); $this->assertCount(1, $called);
$this->assertEquals(ProjectFileModel::EVENT_CREATE, $called[0]['event']);
} }
} }

Some files were not shown because too many files have changed in this diff Show More