Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
dolibarr
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container Registry
Model registry
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Software_Artifact_Infrastructure_Repository
dolibarr
Commits
2476e7bc
Commit
2476e7bc
authored
11 years ago
by
Florian Henry
Browse files
Options
Downloads
Patches
Plain Diff
Start functionnality
parent
7b97214d
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
htdocs/core/modules/modProjet.class.php
+22
-0
22 additions, 0 deletions
htdocs/core/modules/modProjet.class.php
htdocs/projet/admin/project.php
+324
-0
324 additions, 0 deletions
htdocs/projet/admin/project.php
htdocs/projet/tasks/task.php
+72
-1
72 additions, 1 deletion
htdocs/projet/tasks/task.php
with
418 additions
and
1 deletion
htdocs/core/modules/modProjet.class.php
+
22
−
0
View file @
2476e7bc
...
...
@@ -4,6 +4,7 @@
* Copyright (C) 2004 Sebastien Di Cintio <sdicintio@ressource-toi.org>
* Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -92,6 +93,27 @@ class modProjet extends DolibarrModules
$this
->
const
[
$r
][
2
]
=
"DOL_DATA_ROOT/doctemplates/projects"
;
$this
->
const
[
$r
][
3
]
=
""
;
$this
->
const
[
$r
][
4
]
=
0
;
$this
->
const
[
$r
][
0
]
=
"PROJECT_TASK_ADDON_PDF"
;
$this
->
const
[
$r
][
1
]
=
"chaine"
;
$this
->
const
[
$r
][
2
]
=
"baleine"
;
$this
->
const
[
$r
][
3
]
=
'Nom du gestionnaire de generation des task en PDF'
;
$this
->
const
[
$r
][
4
]
=
0
;
$r
++
;
$this
->
const
[
$r
][
0
]
=
"PROJECT_TASK_ADDON"
;
$this
->
const
[
$r
][
1
]
=
"chaine"
;
$this
->
const
[
$r
][
2
]
=
"mod_task_simple"
;
$this
->
const
[
$r
][
3
]
=
'Nom du gestionnaire de numerotation des taches'
;
$this
->
const
[
$r
][
4
]
=
0
;
$r
++
;
$r
++
;
$this
->
const
[
$r
][
0
]
=
"PROJECT_TASK_ADDON_PDF_ODT_PATH"
;
$this
->
const
[
$r
][
1
]
=
"chaine"
;
$this
->
const
[
$r
][
2
]
=
"DOL_DATA_ROOT/doctemplates/tasks"
;
$this
->
const
[
$r
][
3
]
=
""
;
$this
->
const
[
$r
][
4
]
=
0
;
// Boxes
$this
->
boxes
=
array
();
...
...
This diff is collapsed.
Click to expand it.
htdocs/projet/admin/project.php
+
324
−
0
View file @
2476e7bc
...
...
@@ -113,6 +113,51 @@ else if ($action == 'specimen')
}
}
else
if
(
$action
==
'specimentask'
)
{
$modele
=
GETPOST
(
'module'
,
'alpha'
);
$project
=
new
Project
(
$db
);
$project
->
initAsSpecimen
();
// Search template files
$file
=
''
;
$classname
=
''
;
$filefound
=
0
;
$dirmodels
=
array_merge
(
array
(
'/'
),(
array
)
$conf
->
modules_parts
[
'models'
]);
foreach
(
$dirmodels
as
$reldir
)
{
$file
=
dol_buildpath
(
$reldir
.
"core/modules/project/task/pdf/pdf_"
.
$modele
.
".modules.php"
,
0
);
if
(
file_exists
(
$file
))
{
$filefound
=
1
;
$classname
=
"pdf_"
.
$modele
;
break
;
}
}
if
(
$filefound
)
{
require_once
$file
;
$module
=
new
$classname
(
$db
);
if
(
$module
->
write_file
(
$project
,
$langs
)
>
0
)
{
header
(
"Location: "
.
DOL_URL_ROOT
.
"/document.php?modulepart=project_task&file=SPECIMEN.pdf"
);
return
;
}
else
{
$mesg
=
'<div class="error">'
.
$obj
->
error
.
'</div>'
;
dol_syslog
(
$obj
->
error
,
LOG_ERR
);
}
}
else
{
$mesg
=
'<div class="error">'
.
$langs
->
trans
(
"ErrorModuleNotFound"
)
.
'</div>'
;
dol_syslog
(
$langs
->
trans
(
"ErrorModuleNotFound"
),
LOG_ERR
);
}
}
// Activate a model
else
if
(
$action
==
'set'
)
{
...
...
@@ -127,6 +172,14 @@ else if ($action == 'del')
if
(
$conf
->
global
->
PROJECT_ADDON_PDF
==
"
$value
"
)
dolibarr_del_const
(
$db
,
'PROJECT_ADDON_PDF'
,
$conf
->
entity
);
}
}
if
(
$action
==
'deltask'
)
{
$ret
=
delDocumentModel
(
$value
,
'project_task'
);
if
(
$ret
>
0
)
{
if
(
$conf
->
global
->
PROJECT_TASK_ADDON_PDF
==
"
$value
"
)
dolibarr_del_const
(
$db
,
'PROJECT_TASK_ADDON_PDF'
,
$conf
->
entity
);
}
}
// Set default model
else
if
(
$action
==
'setdoc'
)
...
...
@@ -146,6 +199,23 @@ else if ($action == 'setdoc')
}
}
else
if
(
$action
==
'setdoctask'
)
{
if
(
dolibarr_set_const
(
$db
,
"PROJECT_TASK_ADDON_PDF"
,
$value
,
'chaine'
,
0
,
''
,
$conf
->
entity
))
{
// La constante qui a ete lue en avant du nouveau set
// on passe donc par une variable pour avoir un affichage coherent
$conf
->
global
->
PROJECT_TASK_ADDON_PDF
=
$value
;
}
// On active le modele
$ret
=
delDocumentModel
(
$value
,
'project_task'
);
if
(
$ret
>
0
)
{
$ret
=
addDocumentModel
(
$value
,
'project_task'
,
$label
,
$scandir
);
}
}
else
if
(
$action
==
'setmod'
)
{
// TODO Verifier si module numerotation choisi peut etre active
...
...
@@ -154,6 +224,14 @@ else if ($action == 'setmod')
dolibarr_set_const
(
$db
,
"PROJECT_ADDON"
,
$value
,
'chaine'
,
0
,
''
,
$conf
->
entity
);
}
else
if
(
$action
==
'setmodtask'
)
{
// TODO Verifier si module numerotation choisi peut etre active
// par appel methode canBeActivated
dolibarr_set_const
(
$db
,
"PROJECT_TASK_ADDON"
,
$value
,
'chaine'
,
0
,
''
,
$conf
->
entity
);
}
else
if
(
$action
==
'setModuleOptions'
)
{
if
(
dolibarr_set_const
(
$db
,
"PROJECT_ADDON_PDF_ODT_PATH"
,
GETPOST
(
'value1'
),
'chaine'
,
0
,
''
,
$conf
->
entity
))
{
...
...
@@ -162,6 +240,15 @@ else if ($action=='setModuleOptions') {
$conf
->
global
->
PROJECT_ADDON_PDF_ODT_PATH
=
GETPOST
(
'value1'
);
}
}
else
if
(
$action
==
'setModuleOptionsTask'
)
{
if
(
dolibarr_set_const
(
$db
,
"PROJECT_TASK_ADDON_PDF_ODT_PATH"
,
GETPOST
(
'value1'
),
'chaine'
,
0
,
''
,
$conf
->
entity
))
{
// La constante qui a ete lue en avant du nouveau set
// on passe donc par une variable pour avoir un affichage coherent
$conf
->
global
->
PROJECT_TASK_ADDON_PDF_ODT_PATH
=
GETPOST
(
'value1'
);
}
}
/*
* View
*/
...
...
@@ -285,6 +372,106 @@ foreach ($dirmodels as $reldir)
print
'</table><br>'
;
// Task numbering module
print_titre
(
$langs
->
trans
(
"TasksNumberingModules"
));
print
'<table class="noborder" width="100%">'
;
print
'<tr class="liste_titre">'
;
print
'<td width="100">'
.
$langs
->
trans
(
"Name"
)
.
'</td>'
;
print
'<td>'
.
$langs
->
trans
(
"Description"
)
.
'</td>'
;
print
'<td>'
.
$langs
->
trans
(
"Example"
)
.
'</td>'
;
print
'<td align="center" width="60">'
.
$langs
->
trans
(
"Activated"
)
.
'</td>'
;
print
'<td align="center" width="80">'
.
$langs
->
trans
(
"Infos"
)
.
'</td>'
;
print
"</tr>
\n
"
;
clearstatcache
();
foreach
(
$dirmodels
as
$reldir
)
{
$dir
=
dol_buildpath
(
$reldir
.
"core/modules/project/task/"
);
if
(
is_dir
(
$dir
))
{
$handle
=
opendir
(
$dir
);
if
(
is_resource
(
$handle
))
{
$var
=
true
;
while
((
$file
=
readdir
(
$handle
))
!==
false
)
{
if
(
preg_match
(
'/^(mod_.*)\.php$/i'
,
$file
,
$reg
))
{
$file
=
$reg
[
1
];
$classname
=
substr
(
$file
,
4
);
require_once
DOL_DOCUMENT_ROOT
.
"/core/modules/project/task/"
.
$file
.
'.php'
;
$module
=
new
$file
;
// Show modules according to features level
if
(
$module
->
version
==
'development'
&&
$conf
->
global
->
MAIN_FEATURES_LEVEL
<
2
)
continue
;
if
(
$module
->
version
==
'experimental'
&&
$conf
->
global
->
MAIN_FEATURES_LEVEL
<
1
)
continue
;
if
(
$module
->
isEnabled
())
{
$var
=!
$var
;
print
'<tr '
.
$bc
[
$var
]
.
'><td>'
.
$module
->
nom
.
"</td><td>
\n
"
;
print
$module
->
info
();
print
'</td>'
;
// Show example of numbering module
print
'<td nowrap="nowrap">'
;
$tmp
=
$module
->
getExample
();
if
(
preg_match
(
'/^Error/'
,
$tmp
))
print
'<div class="error">'
.
$langs
->
trans
(
$tmp
)
.
'</div>'
;
elseif
(
$tmp
==
'NotConfigured'
)
print
$langs
->
trans
(
$tmp
);
else
print
$tmp
;
print
'</td>'
.
"
\n
"
;
print
'<td align="center">'
;
if
(
$conf
->
global
->
PROJECT_TASK_ADDON
==
'mod_'
.
$classname
)
{
print
img_picto
(
$langs
->
trans
(
"Activated"
),
'switch_on'
);
}
else
{
print
'<a href="'
.
$_SERVER
[
"PHP_SELF"
]
.
'?action=setmodtask&value=mod_'
.
$classname
.
'" alt="'
.
$langs
->
trans
(
"Default"
)
.
'">'
.
img_picto
(
$langs
->
trans
(
"Disabled"
),
'switch_off'
)
.
'</a>'
;
}
print
'</td>'
;
$project
=
new
Project
(
$db
);
$project
->
initAsSpecimen
();
// Info
$htmltooltip
=
''
;
$htmltooltip
.
=
''
.
$langs
->
trans
(
"Version"
)
.
': <b>'
.
$module
->
getVersion
()
.
'</b><br>'
;
$nextval
=
$module
->
getNextValue
(
$mysoc
,
$project
);
if
(
"
$nextval
"
!=
$langs
->
trans
(
"NotAvailable"
))
// Keep " on nextval
{
$htmltooltip
.
=
''
.
$langs
->
trans
(
"NextValue"
)
.
': '
;
if
(
$nextval
)
{
$htmltooltip
.
=
$nextval
.
'<br>'
;
}
else
{
$htmltooltip
.
=
$langs
->
trans
(
$module
->
error
)
.
'<br>'
;
}
}
print
'<td align="center">'
;
print
$form
->
textwithpicto
(
''
,
$htmltooltip
,
1
,
0
);
print
'</td>'
;
print
'</tr>'
;
}
}
}
closedir
(
$handle
);
}
}
}
print
'</table><br>'
;
/*
* Document templates generators
...
...
@@ -412,6 +599,143 @@ foreach ($dirmodels as $reldir)
}
print
'</td>'
;
print
"</tr>
\n
"
;
}
}
}
}
closedir
(
$handle
);
}
}
}
print
'</table><br/>'
;
/*
* Modeles documents for Task
*/
print_titre
(
$langs
->
trans
(
"TaskModelModule"
));
// Defini tableau def de modele
$type
=
'project_task'
;
$def
=
array
();
$sql
=
"SELECT nom"
;
$sql
.
=
" FROM "
.
MAIN_DB_PREFIX
.
"document_model"
;
$sql
.
=
" WHERE type = '"
.
$type
.
"'"
;
$sql
.
=
" AND entity = "
.
$conf
->
entity
;
$resql
=
$db
->
query
(
$sql
);
if
(
$resql
)
{
$i
=
0
;
$num_rows
=
$db
->
num_rows
(
$resql
);
while
(
$i
<
$num_rows
)
{
$array
=
$db
->
fetch_array
(
$resql
);
array_push
(
$def
,
$array
[
0
]);
$i
++
;
}
}
else
{
dol_print_error
(
$db
);
}
print
"<table class=
\"
noborder
\"
width=
\"
100%
\"
>
\n
"
;
print
"<tr class=
\"
liste_titre
\"
>
\n
"
;
print
' <td width="100">'
.
$langs
->
trans
(
"Name"
)
.
"</td>
\n
"
;
print
" <td>"
.
$langs
->
trans
(
"Description"
)
.
"</td>
\n
"
;
print
'<td align="center" width="60">'
.
$langs
->
trans
(
"Activated"
)
.
"</td>
\n
"
;
print
'<td align="center" width="60">'
.
$langs
->
trans
(
"Default"
)
.
"</td>
\n
"
;
print
'<td align="center" width="80">'
.
$langs
->
trans
(
"Infos"
)
.
'</td>'
;
print
"</tr>
\n
"
;
clearstatcache
();
$var
=
true
;
foreach
(
$dirmodels
as
$reldir
)
{
$dir
=
dol_buildpath
(
$reldir
.
"core/modules/project/task/pdf/"
);
if
(
is_dir
(
$dir
))
{
$handle
=
opendir
(
$dir
);
if
(
is_resource
(
$handle
))
{
while
((
$file
=
readdir
(
$handle
))
!==
false
)
{
if
(
preg_match
(
'/\.modules\.php$/i'
,
$file
)
&&
preg_match
(
'/^(pdf_|doc_)/'
,
$file
))
{
if
(
file_exists
(
$dir
.
'/'
.
$file
))
{
$name
=
substr
(
$file
,
4
,
dol_strlen
(
$file
)
-
16
);
$classname
=
substr
(
$file
,
0
,
dol_strlen
(
$file
)
-
12
);
require_once
$dir
.
'/'
.
$file
;
$module
=
new
$classname
(
$db
);
$modulequalified
=
1
;
if
(
$module
->
version
==
'development'
&&
$conf
->
global
->
MAIN_FEATURES_LEVEL
<
2
)
$modulequalified
=
0
;
if
(
$module
->
version
==
'experimental'
&&
$conf
->
global
->
MAIN_FEATURES_LEVEL
<
1
)
$modulequalified
=
0
;
if
(
$modulequalified
)
{
$var
=
!
$var
;
print
'<tr '
.
$bc
[
$var
]
.
'><td width="100">'
;
print
(
empty
(
$module
->
name
)
?
$name
:
$module
->
name
);
print
"</td><td>
\n
"
;
if
(
method_exists
(
$module
,
'info'
))
print
$module
->
info
(
$langs
);
else
print
$module
->
description
;
print
"</td>
\n
"
;
// Active
if
(
in_array
(
$name
,
$def
))
{
print
"<td align=
\"
center
\"
>
\n
"
;
print
'<a href="'
.
$_SERVER
[
"PHP_SELF"
]
.
'?action=deltask&value='
.
$name
.
'&scandir='
.
$module
->
scandir
.
'&label='
.
urlencode
(
$module
->
name
)
.
'">'
;
print
img_picto
(
$langs
->
trans
(
"Enabled"
),
'switch_on'
);
print
'</a>'
;
print
"</td>"
;
}
else
{
print
"<td align=
\"
center
\"
>
\n
"
;
print
'<a href="'
.
$_SERVER
[
"PHP_SELF"
]
.
'?action=settask&value='
.
$name
.
'&scandir='
.
$module
->
scandir
.
'&label='
.
urlencode
(
$module
->
name
)
.
'">'
.
img_picto
(
$langs
->
trans
(
"Disabled"
),
'switch_off'
)
.
'</a>'
;
print
"</td>"
;
}
// Defaut
print
"<td align=
\"
center
\"
>"
;
if
(
$conf
->
global
->
PROJECT_TASK_ADDON_PDF
==
"
$name
"
)
{
print
img_picto
(
$langs
->
trans
(
"Default"
),
'on'
);
}
else
{
print
'<a href="'
.
$_SERVER
[
"PHP_SELF"
]
.
'?action=setdoctask&value='
.
$name
.
'&scandir='
.
$module
->
scandir
.
'&label='
.
urlencode
(
$module
->
name
)
.
'" alt="'
.
$langs
->
trans
(
"Default"
)
.
'">'
.
img_picto
(
$langs
->
trans
(
"Disabled"
),
'off'
)
.
'</a>'
;
}
print
'</td>'
;
// Info
$htmltooltip
=
''
.
$langs
->
trans
(
"Name"
)
.
': '
.
$module
->
name
;
$htmltooltip
.
=
'<br>'
.
$langs
->
trans
(
"Type"
)
.
': '
.
(
$module
->
type
?
$module
->
type
:
$langs
->
trans
(
"Unknown"
));
$htmltooltip
.
=
'<br>'
.
$langs
->
trans
(
"Width"
)
.
'/'
.
$langs
->
trans
(
"Height"
)
.
': '
.
$module
->
page_largeur
.
'/'
.
$module
->
page_hauteur
;
$htmltooltip
.
=
'<br><br><u>'
.
$langs
->
trans
(
"FeaturesSupported"
)
.
':</u>'
;
$htmltooltip
.
=
'<br>'
.
$langs
->
trans
(
"Logo"
)
.
': '
.
yn
(
$module
->
option_logo
,
1
,
1
);
// Preview
print
'<td align="center">'
;
if
(
$module
->
type
==
'pdf'
)
{
print
'<a href="'
.
$_SERVER
[
"PHP_SELF"
]
.
'?action=specimentask&module='
.
$name
.
'">'
.
img_object
(
$langs
->
trans
(
"Preview"
),
'bill'
)
.
'</a>'
;
}
else
{
print
img_object
(
$langs
->
trans
(
"PreviewNotAvailable"
),
'generic'
);
}
print
'</td>'
;
print
"</tr>
\n
"
;
}
}
...
...
This diff is collapsed.
Click to expand it.
htdocs/projet/tasks/task.php
+
72
−
1
View file @
2476e7bc
...
...
@@ -31,6 +31,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once
DOL_DOCUMENT_ROOT
.
'/core/class/extrafields.class.php'
;
require_once
DOL_DOCUMENT_ROOT
.
'/core/lib/date.lib.php'
;
$langs
->
load
(
"projects"
);
$langs
->
load
(
"companies"
);
$id
=
GETPOST
(
'id'
,
'int'
);
$ref
=
GETPOST
(
'ref'
,
'alpha'
);
$action
=
GETPOST
(
'action'
,
'alpha'
);
...
...
@@ -38,6 +41,8 @@ $confirm=GETPOST('confirm','alpha');
$withproject
=
GETPOST
(
'withproject'
,
'int'
);
$project_ref
=
GETPOST
(
'project_ref'
,
'alpha'
);
$planned_workload
=
GETPOST
(
'planned_workloadhour'
);
$taskid
=
GETPOST
(
"id"
,
'int'
);
$taskref
=
GETPOST
(
"ref"
,
'int'
);
// Security check
$socid
=
0
;
...
...
@@ -134,16 +139,63 @@ if (! empty($project_ref) && ! empty($withproject))
}
}
// Build doc
if
(
$action
==
'builddoc'
&&
$user
->
rights
->
projet
->
creer
)
{
if
(
$object
->
fetch
(
$id
)
>=
0
)
{
if
(
GETPOST
(
'model'
))
{
$object
->
setDocModel
(
$user
,
GETPOST
(
'model'
));
}
$outputlangs
=
$langs
;
if
(
GETPOST
(
'lang_id'
))
{
$outputlangs
=
new
Translate
(
""
,
$conf
);
$outputlangs
->
setDefaultLang
(
GETPOST
(
'lang_id'
));
}
$result
=
task_pdf_create
(
$db
,
$object
,
$object
->
modelpdf
,
$outputlangs
);
if
(
$result
<=
0
)
{
dol_print_error
(
$db
,
$result
);
exit
;
}
else
{
header
(
'Location: '
.
$_SERVER
[
"PHP_SELF"
]
.
'?id='
.
$object
->
id
.
(
empty
(
$conf
->
global
->
MAIN_JUMP_TAG
)
?
''
:
'#builddoc'
));
exit
;
}
}
}
// Delete file in doc form
if
(
$action
==
'remove_file'
&&
$user
->
rights
->
projet
->
creer
)
{
require_once
DOL_DOCUMENT_ROOT
.
'/core/lib/files.lib.php'
;
if
(
$object
->
fetch
(
$id
)
>=
0
)
{
$langs
->
load
(
"other"
);
$upload_dir
=
$conf
->
projet
->
dir_output
;
$file
=
$upload_dir
.
'/'
.
GETPOST
(
'file'
);
$ret
=
dol_delete_file
(
$file
);
if
(
$ret
)
setEventMessage
(
$langs
->
trans
(
"FileWasRemoved"
,
GETPOST
(
'urlfile'
)));
else
setEventMessage
(
$langs
->
trans
(
"ErrorFailToDeleteFile"
,
GETPOST
(
'urlfile'
)),
'errors'
);
}
}
/*
* View
*/
$langs
->
load
(
'projects'
);
llxHeader
(
''
,
$langs
->
trans
(
"Task"
));
$form
=
new
Form
(
$db
);
$formother
=
new
FormOther
(
$db
);
$formfile
=
new
FormFile
(
$db
);
if
(
$id
>
0
||
!
empty
(
$ref
))
{
...
...
@@ -434,6 +486,25 @@ if ($id > 0 || ! empty($ref))
}
print
'</div>'
;
print
'<table width="100%"><tr><td width="50%" valign="top">'
;
print
'<a name="builddoc"></a>'
;
// ancre
/*
* Documents generes
*/
$filename
=
dol_sanitizeFileName
(
$projectstatic
->
ref
)
.
"/"
.
dol_sanitizeFileName
(
$object
->
ref
);
$filedir
=
$conf
->
projet
->
dir_output
.
"/"
.
dol_sanitizeFileName
(
$projectstatic
->
ref
)
.
"/"
.
dol_sanitizeFileName
(
$object
->
ref
);
$urlsource
=
$_SERVER
[
"PHP_SELF"
]
.
"?id="
.
$object
->
id
;
$genallowed
=
(
$user
->
rights
->
projet
->
lire
);
$delallowed
=
(
$user
->
rights
->
projet
->
creer
);
$var
=
true
;
$somethingshown
=
$formfile
->
show_documents
(
'project_task'
,
$filename
,
$filedir
,
$urlsource
,
$genallowed
,
$delallowed
,
$object
->
modelpdf
);
print
'</td></tr></table>'
;
}
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment