Compare commits
20 commits
Author | SHA1 | Date | |
---|---|---|---|
6f9e4ccc8d | |||
8854947866 | |||
9456a01c34 | |||
724dec5a61 | |||
21da4e580f | |||
3f0728b945 | |||
08b7a7d825 | |||
d6588b6f1a | |||
853bb50ab6 | |||
30de910e73 | |||
5bf96a8d02 | |||
73310dbbdc | |||
0fe01a0336 | |||
1bdc620153 | |||
3ac9274b1f | |||
a597290a01 | |||
c28cecd570 | |||
c2e374964a | |||
3dc8c8b08a | |||
48b4b80447 |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
config.json
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"database": {
|
||||
"driver": "mysql",
|
||||
"pdo": true,
|
||||
"hostname": "localhost",
|
||||
"username": "root",
|
||||
"password": "",
|
||||
|
@ -19,14 +20,19 @@
|
|||
"port": 11211
|
||||
},
|
||||
"class_map": {
|
||||
"user": "User",
|
||||
"interestgroup": "InterestGroup",
|
||||
"project": "Project",
|
||||
"repository": "Repository",
|
||||
"ticket": "Ticket"
|
||||
"user": "User",
|
||||
"interestgroup": "InterestGroup",
|
||||
"project": "Project",
|
||||
"repository": "Repository",
|
||||
"ticket": "Ticket",
|
||||
"tickettag": "TicketTag",
|
||||
"ticketmessage": "TicketMessage",
|
||||
"ticketattachment": "TicketAttachment",
|
||||
"logentry": "LogEntry"
|
||||
},
|
||||
"components": [
|
||||
"router",
|
||||
"errorhandler"
|
||||
]
|
||||
],
|
||||
"salt": "abcdef"
|
||||
}
|
28
public_html/authenticators/project.php
Normal file
28
public_html/authenticators/project.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
/*
|
||||
* Cryto Team is more free software. It is licensed under the WTFPL, which
|
||||
* allows you to do pretty much anything with it, without having to
|
||||
* ask permission. Commercial use is allowed, and no attribution is
|
||||
* required. We do politely request that you share your modifications
|
||||
* to benefit other developers, but you are under no enforced
|
||||
* obligation to do so :)
|
||||
*
|
||||
* Please read the accompanying LICENSE document for the full WTFPL
|
||||
* licensing text.
|
||||
*/
|
||||
|
||||
if(!isset($_APP)) { die("Unauthorized."); }
|
||||
|
||||
$uSlug = $router->uParameters[1];
|
||||
|
||||
try
|
||||
{
|
||||
$sProject = Project::CreateFromQuery("SELECT * FROM projects WHERE `Slug` = :Slug", array(":Slug" => $uSlug), 0, true);
|
||||
NewTemplater::SetGlobalVariable("project-name", $sProject->sName);
|
||||
NewTemplater::SetGlobalVariable("project-url", "/project/{$sProject->sSlug}");
|
||||
$sRouterAuthenticated = true;
|
||||
}
|
||||
catch (NotFoundException $e)
|
||||
{
|
||||
throw new RouterException("Project does not exist");
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/*
|
||||
* projectname is more free software. It is licensed under the WTFPL, which
|
||||
* Cryto Team is more free software. It is licensed under the WTFPL, which
|
||||
* allows you to do pretty much anything with it, without having to
|
||||
* ask permission. Commercial use is allowed, and no attribution is
|
||||
* required. We do politely request that you share your modifications
|
||||
|
|
|
@ -23,6 +23,9 @@ class Project extends CPHPDatabaseRecordClass
|
|||
'string' => array(
|
||||
'Name' => "Name",
|
||||
'ShortDescription' => "ShortDescription",
|
||||
'Slug' => "Slug"
|
||||
),
|
||||
'simplehtml' => array(
|
||||
'LongDescription' => "LongDescription"
|
||||
),
|
||||
'numeric' => array(
|
||||
|
|
|
@ -25,17 +25,76 @@ class Ticket extends CPHPDatabaseRecordClass
|
|||
),
|
||||
'numeric' => array(
|
||||
'Status' => "Status",
|
||||
'CreatorId' => "UserId",
|
||||
'CreatorId' => "CreatorId",
|
||||
'OwnerId' => "OwnerId",
|
||||
'Priority' => "Priority",
|
||||
'ProjectId' => "ProjectId"
|
||||
),
|
||||
"timestamp" => array(
|
||||
'CreationDate' => "CreationDate"
|
||||
),
|
||||
'user' => array(
|
||||
'Creator' => "UserId",
|
||||
'Creator' => "CreatorId",
|
||||
'Owner' => "OwnerId"
|
||||
),
|
||||
'project' => array(
|
||||
'Project' => "ProjectId"
|
||||
)
|
||||
);
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
switch($name)
|
||||
{
|
||||
case "sStatusName":
|
||||
return $this->GetStatusName();
|
||||
break;
|
||||
case "sPriorityName":
|
||||
return $this->GetPriorityName();
|
||||
break;
|
||||
default:
|
||||
return parent::__get($name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function GetStatusName()
|
||||
{
|
||||
switch($this->sStatus)
|
||||
{
|
||||
case NEWTICKET:
|
||||
return "New";
|
||||
case OPEN:
|
||||
return "Open";
|
||||
case CLOSED:
|
||||
return "Closed";
|
||||
case INVALID:
|
||||
return "Invalid";
|
||||
case NEEDS_REVIEW:
|
||||
return "Needs Review";
|
||||
case IN_PROGRESS:
|
||||
return "In Progress";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public function GetPriorityName()
|
||||
{
|
||||
switch($this->sPriority)
|
||||
{
|
||||
case PRIORITY_LOWEST:
|
||||
return "Lowest";
|
||||
case PRIORITY_LOW:
|
||||
return "Low";
|
||||
case PRIORITY_NORMAL:
|
||||
return "Normal";
|
||||
case PRIORITY_HIGH:
|
||||
return "High";
|
||||
case PRIORITY_CRITICAL:
|
||||
return "Critical";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class TicketMessage extends CPHPDatabaseRecordClass
|
|||
public $verify_query = "SELECT * FROM ticket_messages WHERE `Id` = :Id";
|
||||
|
||||
public $prototype = array(
|
||||
'string' => array(
|
||||
'simplehtml' => array(
|
||||
'Body' => "Body"
|
||||
),
|
||||
'boolean' => array(
|
||||
|
@ -34,6 +34,9 @@ class TicketMessage extends CPHPDatabaseRecordClass
|
|||
'timestamp' => array(
|
||||
'Date' => "Date"
|
||||
),
|
||||
'boolean' => array(
|
||||
'IsEvent' => "Event"
|
||||
),
|
||||
'user' => array(
|
||||
'Author' => "UserId"
|
||||
),
|
||||
|
@ -44,4 +47,94 @@ class TicketMessage extends CPHPDatabaseRecordClass
|
|||
'Project' => "ProjectId"
|
||||
)
|
||||
);
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
switch($name)
|
||||
{
|
||||
case "sComponent":
|
||||
return $this->GetComponentName();
|
||||
break;
|
||||
case "sOperation":
|
||||
return $this->GetOperationName();
|
||||
break;
|
||||
default:
|
||||
return parent::__get($name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function UnpackEvent()
|
||||
{
|
||||
if(empty($this->uEventData))
|
||||
{
|
||||
$this->uEventData = json_decode($this->uBody);
|
||||
}
|
||||
}
|
||||
|
||||
public function GetComponentName()
|
||||
{
|
||||
$this->UnpackEvent();
|
||||
|
||||
switch($this->uEventData->component)
|
||||
{
|
||||
case STATUS:
|
||||
return "status";
|
||||
case PRIORITY:
|
||||
return "priority";
|
||||
case OWNER:
|
||||
return "owner";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public function GetOperationName()
|
||||
{
|
||||
$this->UnpackEvent();
|
||||
|
||||
if($this->uEventData->component == OWNER)
|
||||
{
|
||||
$sEventUser = new User($this->uEventData->operation);
|
||||
return $sEventUser->sDisplayName;
|
||||
}
|
||||
elseif($this->uEventData->component == PRIORITY)
|
||||
{
|
||||
switch($this->uEventData->operation)
|
||||
{
|
||||
case PRIORITY_LOWEST:
|
||||
return "Lowest";
|
||||
case PRIORITY_LOW:
|
||||
return "Low";
|
||||
case PRIORITY_NORMAL:
|
||||
return "Normal";
|
||||
case PRIORITY_HIGH:
|
||||
return "High";
|
||||
case PRIORITY_CRITICAL:
|
||||
return "Critical";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
elseif($this->uEventData->component == STATUS)
|
||||
{
|
||||
switch($this->uEventData->operation)
|
||||
{
|
||||
case NEWTICKET:
|
||||
return "New";
|
||||
case OPEN:
|
||||
return "Open";
|
||||
case CLOSED:
|
||||
return "Closed";
|
||||
case INVALID:
|
||||
return "Invalid";
|
||||
case NEEDS_REVIEW:
|
||||
return "Needs Review";
|
||||
case IN_PROGRESS:
|
||||
return "In Progress";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
13
public_html/debug.createuser.php
Normal file
13
public_html/debug.createuser.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
require("include/base.php");
|
||||
|
||||
$sUser = new User(0);
|
||||
$sUser->uUsername = "test";
|
||||
$sUser->uPassword = "test";
|
||||
$sUser->uDisplayName = "Test user";
|
||||
$sUser->uEmailAddress = "test@test.com";
|
||||
$sUser->uIsActivated = true;
|
||||
$sUser->uIsAdmin = true;
|
||||
$sUser->GenerateSalt();
|
||||
$sUser->GenerateHash();
|
||||
$sUser->InsertIntoDatabase();
|
|
@ -5,6 +5,8 @@ require("cphp/base.php");
|
|||
|
||||
$_APP = true;
|
||||
|
||||
require("constants.php");
|
||||
|
||||
function __autoload($class_name)
|
||||
{
|
||||
global $_APP;
|
||||
|
|
|
@ -16,15 +16,20 @@ if(!isset($_APP)) { die("Unauthorized."); }
|
|||
$constants = array(
|
||||
"PRIORITY_LOWEST" => 1,
|
||||
"PRIORITY_LOW" => 2,
|
||||
"PRIORITY_MEDIUM" => 3,
|
||||
"PRIORITY_NORMAL" => 3,
|
||||
"PRIORITY_HIGH" => 4,
|
||||
"PRIORITY_CRITICAL" => 5,
|
||||
|
||||
"OPEN" => 1,
|
||||
"CLOSED" => 2,
|
||||
"INVALID" => 3,
|
||||
"NEEDS_REVIEW" => 4,
|
||||
"IN_PROGRESS" => 5
|
||||
"NEWTICKET" => 1,
|
||||
"OPEN" => 2,
|
||||
"CLOSED" => 3,
|
||||
"INVALID" => 4,
|
||||
"NEEDS_REVIEW" => 5,
|
||||
"IN_PROGRESS" => 6,
|
||||
|
||||
"STATUS" => 1,
|
||||
"PRIORITY" => 2,
|
||||
"OWNER" => 3,
|
||||
|
||||
"ATTACHMENT_FILE" => 1,
|
||||
"ATTACHMENT_COMMIT" => 2,
|
||||
|
@ -40,7 +45,7 @@ $constants = array(
|
|||
"COMMIT" => 4,
|
||||
"FORUMPOST" => 5,
|
||||
"INVITATION" => 6,
|
||||
"DESCRIPTION" => 7
|
||||
"DESCRIPTION" => 7,
|
||||
|
||||
"CREATE" => 1,
|
||||
"DELETE" => 2,
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<?php
|
||||
require("include/base.php");
|
||||
/*
|
||||
* Cryto Team is more free software. It is licensed under the WTFPL, which
|
||||
* allows you to do pretty much anything with it, without having to
|
||||
* ask permission. Commercial use is allowed, and no attribution is
|
||||
* required. We do politely request that you share your modifications
|
||||
* to benefit other developers, but you are under no enforced
|
||||
* obligation to do so :)
|
||||
*
|
||||
* Please read the accompanying LICENSE document for the full WTFPL
|
||||
* licensing text.
|
||||
*/
|
||||
|
||||
echo(Templater::AdvancedParse("layout", $locale->strings, array(
|
||||
"project-name" => "Demo project",
|
||||
"long-description" => "A large, multi-paragraph description of the project would go here.",
|
||||
"no-downloads" => false,
|
||||
"stable-version" => "1.5.3",
|
||||
"experimental-version" => "1.6.1",
|
||||
"line-count" => "62,671",
|
||||
"ticket-count" => 12,
|
||||
"tickets" => array(),
|
||||
"more-tickets" => false
|
||||
)));
|
||||
require("rewrite.php");
|
||||
|
|
17
public_html/modules/error/404.php
Normal file
17
public_html/modules/error/404.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/*
|
||||
* Cryto Team is more free software. It is licensed under the WTFPL, which
|
||||
* allows you to do pretty much anything with it, without having to
|
||||
* ask permission. Commercial use is allowed, and no attribution is
|
||||
* required. We do politely request that you share your modifications
|
||||
* to benefit other developers, but you are under no enforced
|
||||
* obligation to do so :)
|
||||
*
|
||||
* Please read the accompanying LICENSE document for the full WTFPL
|
||||
* licensing text.
|
||||
*/
|
||||
|
||||
if(!isset($_APP)) { die("Unauthorized."); }
|
||||
|
||||
http_status_code(404);
|
||||
$sPageContents = NewTemplater::Render("error/404", $locale->strings, array());
|
16
public_html/modules/home/index.php
Normal file
16
public_html/modules/home/index.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/*
|
||||
* Cryto Team is more free software. It is licensed under the WTFPL, which
|
||||
* allows you to do pretty much anything with it, without having to
|
||||
* ask permission. Commercial use is allowed, and no attribution is
|
||||
* required. We do politely request that you share your modifications
|
||||
* to benefit other developers, but you are under no enforced
|
||||
* obligation to do so :)
|
||||
*
|
||||
* Please read the accompanying LICENSE document for the full WTFPL
|
||||
* licensing text.
|
||||
*/
|
||||
|
||||
if(!isset($_APP)) { die("Unauthorized."); }
|
||||
|
||||
$sPageContents = "hi";
|
27
public_html/modules/project/index.php
Normal file
27
public_html/modules/project/index.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
/*
|
||||
* Cryto Team is more free software. It is licensed under the WTFPL, which
|
||||
* allows you to do pretty much anything with it, without having to
|
||||
* ask permission. Commercial use is allowed, and no attribution is
|
||||
* required. We do politely request that you share your modifications
|
||||
* to benefit other developers, but you are under no enforced
|
||||
* obligation to do so :)
|
||||
*
|
||||
* Please read the accompanying LICENSE document for the full WTFPL
|
||||
* licensing text.
|
||||
*/
|
||||
|
||||
if(!isset($_APP)) { die("Unauthorized."); }
|
||||
|
||||
$sPageTitle = "Overview";
|
||||
$sCurrentPage = "overview";
|
||||
$sPageContents = Templater::AdvancedParse("project/index", $locale->strings, array(
|
||||
"long-description" => $sProject->sLongDescription,
|
||||
"no-downloads" => false,
|
||||
"stable-version" => "1.5.3",
|
||||
"experimental-version" => "1.6.1",
|
||||
"line-count" => "62,671",
|
||||
"ticket-count" => 12,
|
||||
"tickets" => array(),
|
||||
"more-tickets" => false
|
||||
));
|
44
public_html/modules/project/tickets/index.php
Normal file
44
public_html/modules/project/tickets/index.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
/*
|
||||
* Cryto Team is more free software. It is licensed under the WTFPL, which
|
||||
* allows you to do pretty much anything with it, without having to
|
||||
* ask permission. Commercial use is allowed, and no attribution is
|
||||
* required. We do politely request that you share your modifications
|
||||
* to benefit other developers, but you are under no enforced
|
||||
* obligation to do so :)
|
||||
*
|
||||
* Please read the accompanying LICENSE document for the full WTFPL
|
||||
* licensing text.
|
||||
*/
|
||||
|
||||
if(!isset($_APP)) { die("Unauthorized."); }
|
||||
|
||||
$sPageTitle = "Tickets";
|
||||
$sCurrentPage = "tickets";
|
||||
|
||||
$sTickets = array();
|
||||
|
||||
try
|
||||
{
|
||||
$result = Ticket::CreateFromQuery("SELECT * FROM tickets WHERE `ProjectId` = :ProjectId", array(":ProjectId" => $sProject->sId));
|
||||
}
|
||||
catch (NotFoundException $e)
|
||||
{
|
||||
$result = array();
|
||||
}
|
||||
|
||||
foreach($result as $sTicket)
|
||||
{
|
||||
$sTickets[] = array(
|
||||
"id" => $sTicket->sId,
|
||||
"title" => $sTicket->sSubject,
|
||||
"priority" => $sTicket->sPriorityName,
|
||||
"priority-lowercase" => strtolower($sTicket->sPriorityName),
|
||||
"status" => $sTicket->sStatusName,
|
||||
"status-lowercase" => strtolower($sTicket->sStatusName)
|
||||
);
|
||||
}
|
||||
|
||||
$sPageContents = NewTemplater::Render("project/tickets/index", $locale->strings, array(
|
||||
"tickets" => $sTickets
|
||||
));
|
77
public_html/modules/project/tickets/view.php
Normal file
77
public_html/modules/project/tickets/view.php
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
/*
|
||||
* Cryto Team is more free software. It is licensed under the WTFPL, which
|
||||
* allows you to do pretty much anything with it, without having to
|
||||
* ask permission. Commercial use is allowed, and no attribution is
|
||||
* required. We do politely request that you share your modifications
|
||||
* to benefit other developers, but you are under no enforced
|
||||
* obligation to do so :)
|
||||
*
|
||||
* Please read the accompanying LICENSE document for the full WTFPL
|
||||
* licensing text.
|
||||
*/
|
||||
|
||||
if(!isset($_APP)) { die("Unauthorized."); }
|
||||
|
||||
$sCurrentPage = "tickets";
|
||||
|
||||
try
|
||||
{
|
||||
$sTicket = new Ticket($router->uParameters[2]);
|
||||
|
||||
$sInitialMessage = TicketMessage::CreateFromQuery("SELECT * FROM ticket_messages WHERE `TicketId` = :TicketId AND `FirstMessage` = 1",
|
||||
array(":TicketId" => $sTicket->sId), 0, true);
|
||||
|
||||
$sUpdates = array();
|
||||
|
||||
try
|
||||
{
|
||||
$result = TicketMessage::CreateFromQuery("SELECT * FROM ticket_messages WHERE `TicketId` = :TicketId AND `FirstMessage` = 0 ORDER BY `Date` ASC",
|
||||
array(":TicketId" => $sTicket->sId), 0);
|
||||
}
|
||||
catch (NotFoundException $e)
|
||||
{
|
||||
$result = array();
|
||||
}
|
||||
|
||||
foreach($result as $sMessage)
|
||||
{
|
||||
if($sMessage->sIsEvent)
|
||||
{
|
||||
$uEventData = json_decode($sMessage->uBody);
|
||||
|
||||
$sUpdates[] = array(
|
||||
"event" => true,
|
||||
"user" => $sMessage->sAuthor->sDisplayName,
|
||||
"component" => $sMessage->sComponent,
|
||||
"operation" => $sMessage->sOperation,
|
||||
"date" => time_ago($sMessage->sDate, $locale)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sUpdates[] = array(
|
||||
"event" => false,
|
||||
"author" => $sMessage->sAuthor->sDisplayName,
|
||||
"body" => $sMessage->sBody,
|
||||
"date" => time_ago($sMessage->sDate, $locale)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$sPageContents = NewTemplater::Render("project/tickets/view", $locale->strings, array(
|
||||
"title" => $sTicket->sSubject,
|
||||
"priority" => $sTicket->sPriorityName,
|
||||
"status" => $sTicket->sStatusName,
|
||||
"owner" => $sTicket->sOwner->sDisplayName,
|
||||
"creator" => $sTicket->sCreator->sDisplayName,
|
||||
"date" => local_from_unix($sTicket->sCreationDate, $locale->datetime_long),
|
||||
"body" => $sInitialMessage->sBody,
|
||||
"updates" => $sUpdates
|
||||
));
|
||||
}
|
||||
catch (NotFoundException $e)
|
||||
{
|
||||
pretty_dump($e);
|
||||
require("modules/error/404.php");
|
||||
}
|
96
public_html/rewrite.php
Normal file
96
public_html/rewrite.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
/*
|
||||
* Cryto Team is more free software. It is licensed under the WTFPL, which
|
||||
* allows you to do pretty much anything with it, without having to
|
||||
* ask permission. Commercial use is allowed, and no attribution is
|
||||
* required. We do politely request that you share your modifications
|
||||
* to benefit other developers, but you are under no enforced
|
||||
* obligation to do so :)
|
||||
*
|
||||
* Please read the accompanying LICENSE document for the full WTFPL
|
||||
* licensing text.
|
||||
*/
|
||||
|
||||
require("include/base.php");
|
||||
|
||||
$sPageTitle = "";
|
||||
$sPageContents = "";
|
||||
$sCurrentPage = "";
|
||||
|
||||
/* Define the different routes for the application */
|
||||
|
||||
$routes = array(
|
||||
"home" => array(
|
||||
"^/$" => "modules/home/index.php"
|
||||
),
|
||||
"project" => array(
|
||||
"^/project/([a-zA-Z0-9_-]+)$" => "modules/project/index.php",
|
||||
"^/project/([a-zA-Z0-9_-]+)/tickets$" => "modules/project/tickets/index.php",
|
||||
"^/project/([a-zA-Z0-9_-]+)/ticket/([0-9]+)$" => "modules/project/tickets/view.php"
|
||||
)
|
||||
);
|
||||
|
||||
/* Define the preset values for the route "categories" */
|
||||
|
||||
$presets = array(
|
||||
"home" => array(
|
||||
"_page_type" => "home"
|
||||
),
|
||||
"project" => array(
|
||||
"_page_type" => "project",
|
||||
"authenticator" => "authenticators/project.php",
|
||||
"auth_error" => ""
|
||||
)
|
||||
);
|
||||
|
||||
/* Generate a routing table */
|
||||
|
||||
$router = new CPHPRouter();
|
||||
$router->allow_slash = true;
|
||||
$router->ignore_query = true;
|
||||
$router->routes = array(0 => array());
|
||||
|
||||
foreach($routes as $category => $items)
|
||||
{
|
||||
foreach($items as $route => $target)
|
||||
{
|
||||
$router->routes[0][$route] = $presets[$category];
|
||||
$router->routes[0][$route]['target'] = $target;
|
||||
}
|
||||
}
|
||||
|
||||
/* Route the actual request */
|
||||
|
||||
try
|
||||
{
|
||||
$router->RouteRequest();
|
||||
}
|
||||
catch (RouterException $e)
|
||||
{
|
||||
require("modules/error/404.php");
|
||||
}
|
||||
|
||||
/* Render the resulting page */
|
||||
|
||||
if(empty($router->uVariables['page_type']) || $router->uVariables['page_type'] == "home")
|
||||
{
|
||||
$sContents = NewTemplater::Render("home/layout", $locale->strings, array(
|
||||
"contents" => $sPageContents
|
||||
));
|
||||
}
|
||||
elseif($router->uVariables['page_type'] == "project")
|
||||
{
|
||||
$sContents = NewTemplater::Render("project/layout", $locale->strings, array(
|
||||
"contents" => $sPageContents,
|
||||
"current-page" => $sCurrentPage
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
die();
|
||||
}
|
||||
|
||||
echo(NewTemplater::Render("layout", $locale->strings, array(
|
||||
"contents" => $sContents
|
||||
)));
|
||||
|
156
public_html/static/404.js
Normal file
156
public_html/static/404.js
Normal file
|
@ -0,0 +1,156 @@
|
|||
var engine;
|
||||
|
||||
$(function(){
|
||||
engine = new Engine({
|
||||
"enable_sound": false
|
||||
});
|
||||
|
||||
loader = new engine.Preloader();
|
||||
loader.Run({
|
||||
onfinish: InitializeEffect
|
||||
});
|
||||
});
|
||||
|
||||
function InitializeEffect()
|
||||
{
|
||||
engine.AddItems({
|
||||
objects: {
|
||||
controller: {
|
||||
grid_w: 60,
|
||||
grid_h: 18,
|
||||
tile_w: 16,
|
||||
tile_h: 16,
|
||||
numbers: [],
|
||||
colored: [],
|
||||
OnCreate: function(event){
|
||||
for(var x = 0; x < this.grid_w; x++)
|
||||
{
|
||||
this.numbers[x] = [];
|
||||
this.colored[x] = [];
|
||||
}
|
||||
|
||||
this.RegenerateNumbers();
|
||||
},
|
||||
OnMouseMove: function(event){
|
||||
this.SetMouse(event.x, event.y);
|
||||
},
|
||||
OnStep: function(event){
|
||||
if(this.scene.step_counter % 15 == 0)
|
||||
{
|
||||
this.RegenerateNumbers();
|
||||
return true;
|
||||
}
|
||||
},
|
||||
OnDraw: function(event){
|
||||
for(var x = 0; x < this.grid_w; x++)
|
||||
{
|
||||
for(var y = 0; y < this.grid_h; y++)
|
||||
{
|
||||
if(this.colored[x][y])
|
||||
{
|
||||
//var text = (this.colored[x][y]) ? "0" : this.numbers[x][y];
|
||||
var text = this.numbers[x][y];
|
||||
|
||||
this.scene.DrawText(text, {
|
||||
x: x * this.tile_w,
|
||||
y: y * this.tile_h,
|
||||
color: (this.colored[x][y]) ? "blue" : "silver"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
RegenerateNumbers: function(){
|
||||
for(var x = 0; x < this.grid_w; x++)
|
||||
{
|
||||
for(var y = 0; y < this.grid_h; y++)
|
||||
{
|
||||
this.numbers[x][y] = engine.Random.Choose(0, 1);
|
||||
this.colored[x][y] = false;
|
||||
}
|
||||
}
|
||||
|
||||
this.ApplyMouse();
|
||||
},
|
||||
SetMouse: function(x, y){
|
||||
this.mouse_x = x;
|
||||
this.mouse_y = y;
|
||||
this.ApplyMouse();
|
||||
},
|
||||
ApplyMouse: function(){
|
||||
this.ClearColored();
|
||||
|
||||
var matrix_w = 9;
|
||||
var matrix_h = 14;
|
||||
var matrix = [
|
||||
[0, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[0, 0, 1, 1, 1, 1, 1, 1, 1],
|
||||
[0, 0, 0, 1, 1, 1, 1, 1, 1],
|
||||
[0, 0, 0, 0, 1, 1, 1, 1, 1],
|
||||
[0, 0, 0, 0, 0, 1, 1, 1, 1],
|
||||
[0, 0, 0, 0, 0, 0, 1, 1, 1],
|
||||
[0, 0, 0, 0, 0, 0, 0, 1, 1],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 1],
|
||||
[0, 0, 0, 0, 0, 1, 1, 1, 1],
|
||||
[0, 0, 1, 0, 0, 1, 1, 1, 1],
|
||||
[0, 1, 1, 1, 0, 0, 1, 1, 1],
|
||||
[1, 1, 1, 1, 0, 0, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1, 0, 0, 1, 1],
|
||||
[1, 1, 1, 1, 1, 0, 0, 1, 1]
|
||||
];
|
||||
|
||||
for(var my = 0; my < matrix_h; my++)
|
||||
{
|
||||
for(var mx = 0; mx < matrix_w; mx++)
|
||||
{
|
||||
if(matrix[my][mx] == 0)
|
||||
{
|
||||
var target_x = Math.round(this.mouse_x / this.tile_w + mx);
|
||||
var target_y = Math.round(this.mouse_y / this.tile_h + my) + 1;
|
||||
|
||||
//console.log(target_x, target_y);
|
||||
|
||||
if(target_x >= 0 && target_x < this.grid_w && target_y >= 0 && target_y < this.grid_h)
|
||||
{
|
||||
this.colored[target_x][target_y] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(this.scene)
|
||||
{
|
||||
this.scene.Redraw();
|
||||
}
|
||||
},
|
||||
ClearColored: function(){
|
||||
for(var x = 0; x < this.grid_w; x++)
|
||||
{
|
||||
for(var y = 0; y < this.grid_h; y++)
|
||||
{
|
||||
this.colored[x][y] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scenes: {
|
||||
main: {
|
||||
width: 960,
|
||||
height: 288,
|
||||
fps: 30,
|
||||
OnLoad: function(event){
|
||||
this.Add("controller");
|
||||
},
|
||||
OnMouseMove: function(event){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var canvas = $("#404canvas")[0];
|
||||
engine.GetScene("main").Attach(canvas);
|
||||
|
||||
$("#404canvas").show();
|
||||
}
|
1456
public_html/static/engine.js
Normal file
1456
public_html/static/engine.js
Normal file
File diff suppressed because it is too large
Load diff
4
public_html/static/jquery.js
vendored
Normal file
4
public_html/static/jquery.js
vendored
Normal file
File diff suppressed because one or more lines are too long
42
public_html/static/script.js
Normal file
42
public_html/static/script.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Cryto Team is more free software. It is licensed under the WTFPL, which
|
||||
* allows you to do pretty much anything with it, without having to
|
||||
* ask permission. Commercial use is allowed, and no attribution is
|
||||
* required. We do politely request that you share your modifications
|
||||
* to benefit other developers, but you are under no enforced
|
||||
* obligation to do so :)
|
||||
*
|
||||
* Please read the accompanying LICENSE document for the full WTFPL
|
||||
* licensing text.
|
||||
*/
|
||||
|
||||
$(function(){
|
||||
$('.clickable').click(function(event)
|
||||
{
|
||||
if($(this).data('url'))
|
||||
{
|
||||
url = $(this).data('url');
|
||||
|
||||
if(event.which == 1)
|
||||
{
|
||||
if($(this).hasClass('external'))
|
||||
{
|
||||
window.open(url);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.location = url;
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
else if(event.which == 2)
|
||||
{
|
||||
window.open(url);
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
|
@ -1,9 +1,9 @@
|
|||
@font-face {
|
||||
font-family: "FontAwesome";
|
||||
src: url('/static/fontawesome-webfont.eot');
|
||||
src: url('/static/fontawesome-webfont.eot?#iefix') format('eot'), url('/static/fontawesome-webfont.woff') format('woff'), url('/static/fontawesome-webfont.ttf') format('truetype'), url('/static/fontawesome-webfont.svg#FontAwesome') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-family: "FontAwesome";
|
||||
src: url('/static/fontawesome-webfont.eot');
|
||||
src: url('/static/fontawesome-webfont.eot?#iefix') format('eot'), url('/static/fontawesome-webfont.woff') format('woff'), url('/static/fontawesome-webfont.ttf') format('truetype'), url('/static/fontawesome-webfont.svg#FontAwesome') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
body
|
||||
|
@ -17,6 +17,28 @@ body
|
|||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
** Clickable rows **
|
||||
************************************************/
|
||||
|
||||
table tr.clickable
|
||||
{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
table tr.clickable a
|
||||
{
|
||||
/* This gets rid of the link styling for fallback hyperlinks in clickable table rows. */
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
** Page layout **
|
||||
************************************************/
|
||||
|
||||
.wrapper
|
||||
{
|
||||
width: 960px;
|
||||
|
@ -46,12 +68,18 @@ body
|
|||
margin: 0px;
|
||||
}
|
||||
|
||||
/*.header h2:before
|
||||
.footer
|
||||
{
|
||||
font-weight: normal;
|
||||
content: ";";
|
||||
margin: 0px 16px;
|
||||
}*/
|
||||
border-top: 3px solid black;
|
||||
margin-top: 12px;
|
||||
padding-top: 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
** Page menu **
|
||||
************************************************/
|
||||
|
||||
.menu
|
||||
{
|
||||
|
@ -95,30 +123,27 @@ body
|
|||
color: white;
|
||||
}
|
||||
|
||||
.main
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
.footer
|
||||
{
|
||||
border-top: 3px solid black;
|
||||
margin-top: 12px;
|
||||
padding-top: 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/************************************************
|
||||
** Sections **
|
||||
************************************************/
|
||||
|
||||
section
|
||||
{
|
||||
padding: 12px 0px;
|
||||
}
|
||||
|
||||
section h3
|
||||
div.section
|
||||
{
|
||||
margin: 12px 0px;
|
||||
}
|
||||
|
||||
section h3, div.section h3
|
||||
{
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
section p
|
||||
section p, div.section p
|
||||
{
|
||||
font-size: 14px;
|
||||
}
|
||||
|
@ -128,6 +153,11 @@ p.lead
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
** Asides **
|
||||
************************************************/
|
||||
|
||||
aside
|
||||
{
|
||||
float: right;
|
||||
|
@ -156,58 +186,96 @@ aside section h3
|
|||
font-size: 19px;
|
||||
}
|
||||
|
||||
section.statistics ul, section.tickets ul
|
||||
/************************************************
|
||||
** Generic table styling **
|
||||
************************************************/
|
||||
|
||||
table
|
||||
{
|
||||
width: 100%;
|
||||
border-spacing: 0px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table th, table td
|
||||
{
|
||||
text-align: left;
|
||||
padding: 7px 7px;
|
||||
border-left: 1px solid #252525;
|
||||
border-right: 1px solid #252525;
|
||||
}
|
||||
|
||||
table th
|
||||
{
|
||||
background-color: black;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
table td
|
||||
{
|
||||
border: 1px solid #A1A1A1;
|
||||
}
|
||||
|
||||
table th.empty table td.empty
|
||||
{
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
table td
|
||||
{
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
** Overview asides **
|
||||
************************************************/
|
||||
|
||||
aside section.statistics ul, section.tickets ul
|
||||
{
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
section.statistics
|
||||
aside section.tickets, section.tickets a
|
||||
{
|
||||
/*color: #ECFFBF;*/
|
||||
}
|
||||
|
||||
section.tickets, section.tickets a
|
||||
{
|
||||
/*color: #FFFBD5;*/
|
||||
font-size: 12px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
section.tickets strong
|
||||
aside section.tickets strong
|
||||
{
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
section.tickets ul li
|
||||
aside section.tickets ul li
|
||||
{
|
||||
margin-top: -1px;
|
||||
margin-bottom: 0px;
|
||||
/*border-top: 1px solid #FFE8BF;
|
||||
border-bottom: 1px solid #FFE8BF;*/
|
||||
border-top: 1px solid #FFFFFF;
|
||||
border-bottom: 1px solid #FFFFFF;
|
||||
padding: 6px 0px;
|
||||
}
|
||||
|
||||
section.tickets ul li.more
|
||||
aside section.tickets ul li.more
|
||||
{
|
||||
text-align: right;
|
||||
border: none;
|
||||
}
|
||||
|
||||
section.tickets ul li.more a
|
||||
aside section.tickets ul li.more a
|
||||
{
|
||||
padding: 3px 6px;
|
||||
}
|
||||
|
||||
section.tickets ul li.more a:hover
|
||||
aside section.tickets ul li.more a:hover
|
||||
{
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
section.download a.download
|
||||
aside section.download a.download
|
||||
{
|
||||
margin-top: 10px;
|
||||
display: block;
|
||||
|
@ -218,7 +286,7 @@ section.download a.download
|
|||
|
||||
}
|
||||
|
||||
section.download a.download:hover
|
||||
aside section.download a.download:hover
|
||||
{
|
||||
color: white;
|
||||
background-color: #0C0C0C;
|
||||
|
@ -226,13 +294,13 @@ section.download a.download:hover
|
|||
|
||||
}
|
||||
|
||||
section.download a.download strong
|
||||
aside section.download a.download strong
|
||||
{
|
||||
display: block;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
section.download a.download b:before
|
||||
aside section.download a.download b:before
|
||||
{
|
||||
display: block;
|
||||
float: left;
|
||||
|
@ -245,12 +313,174 @@ section.download a.download b:before
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
section.download a.download b.stable:before
|
||||
aside section.download a.download b.stable:before
|
||||
{
|
||||
content: "\f019";
|
||||
}
|
||||
|
||||
section.download a.download b.experimental:before
|
||||
aside section.download a.download b.experimental:before
|
||||
{
|
||||
content: "\f0c3";
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
** Tickets **
|
||||
************************************************/
|
||||
|
||||
section.tickets tr.priority-low
|
||||
{
|
||||
color: #2B2B2B;
|
||||
background-color: #EDEDED;
|
||||
}
|
||||
|
||||
section.tickets tr.priority-low:hover
|
||||
{
|
||||
background-color: #E3E3E3;
|
||||
}
|
||||
|
||||
section.tickets tr.priority-normal
|
||||
{
|
||||
color: black;
|
||||
background-color: #E7F7F7;
|
||||
}
|
||||
|
||||
section.tickets tr.priority-normal:hover
|
||||
{
|
||||
background-color: #DEEEEE;
|
||||
}
|
||||
|
||||
section.tickets tr.priority-high
|
||||
{
|
||||
background-color: #F7D6D6;
|
||||
}
|
||||
|
||||
section.tickets tr.priority-high:hover
|
||||
{
|
||||
background-color: #EECECE;
|
||||
}
|
||||
|
||||
section.tickets tr.priority-high td.priority
|
||||
{
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
section.tickets tr.status-closed
|
||||
{
|
||||
color: gray;
|
||||
background-color: #D0D0D0;
|
||||
}
|
||||
|
||||
section.tickets tr.status-closed:hover
|
||||
{
|
||||
background-color: #C7C7C7;
|
||||
}
|
||||
|
||||
section.tickets tr.status-closed.priority-high td.priority
|
||||
{
|
||||
color: #656565;
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
** Ticket lookup **
|
||||
************************************************/
|
||||
|
||||
|
||||
.section.ticket-original
|
||||
{
|
||||
border: 1px solid #373737;
|
||||
}
|
||||
|
||||
.section.ticket-original h2
|
||||
{
|
||||
margin: 0px;
|
||||
padding: 9px 8px;
|
||||
background-color: #373737;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.section.ticket-original .metadata
|
||||
{
|
||||
margin: 11px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.section.ticket-original .metadata .currentdata, .section.ticket-original .metadata .originaldata
|
||||
{
|
||||
float: left;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.section.ticket-original .metadata .key
|
||||
{
|
||||
font-weight: bold;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.section.ticket-original .metadata > div > div
|
||||
{
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.section.ticket-original .body
|
||||
{
|
||||
margin: 11px;
|
||||
padding-left: 4px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.section.ticket-updates > div
|
||||
{
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.section.ticket-updates .message
|
||||
{
|
||||
border: 1px solid #373737;
|
||||
padding: 11px;
|
||||
}
|
||||
|
||||
.section.ticket-updates .message .metadata
|
||||
{
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.section.ticket-updates .message .metadata .author
|
||||
{
|
||||
font-weight: bold;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.section.ticket-updates .message .metadata .date
|
||||
{
|
||||
float: right;
|
||||
color: #585858;
|
||||
}
|
||||
|
||||
.section.ticket-updates .message p
|
||||
{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.section.ticket-updates .event
|
||||
{
|
||||
color: white;
|
||||
background-color: #373737;
|
||||
padding: 12px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.section.ticket-updates .event .author, .section.ticket-updates .event .value
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.section.ticket-updates .event .date
|
||||
{
|
||||
float: right;
|
||||
color: #DADADA;
|
||||
}
|
||||
|
|
10
public_html/templates/error/404.tpl
Normal file
10
public_html/templates/error/404.tpl
Normal file
|
@ -0,0 +1,10 @@
|
|||
<script src="/static/engine.js"></script>
|
||||
<script src="/static/404.js"></script>
|
||||
|
||||
<div class="section" style="position: relative; height: 288px;">
|
||||
<canvas id="404canvas" style="z-index: 2; position: absolute; top: 0px; left: 0px;"></canvas>
|
||||
<div style="z-index: 1; position: absolute; top: 0px; left: 12px;">
|
||||
<h2>404 Page not found</h2>
|
||||
The requested page could not be found.
|
||||
</div>
|
||||
</div>
|
13
public_html/templates/home/layout.tpl
Normal file
13
public_html/templates/home/layout.tpl
Normal file
|
@ -0,0 +1,13 @@
|
|||
<div class="header">
|
||||
<h1>Team</h1>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<ul class="menu">
|
||||
<!-- <li class="active"><a href="#">Overview</a></li>
|
||||
<li><a href="#">Account</a></li>
|
||||
<li class="clear"></li> -->
|
||||
</ul>
|
||||
<div class="main">
|
||||
{%?contents}
|
||||
<div class="clear"></div>
|
||||
</div>
|
|
@ -4,78 +4,12 @@
|
|||
<title>Cryto Team</title>
|
||||
<link href='http://fonts.googleapis.com/css?family=Nobile:400,400italic,700,700italic' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<script src="/static/jquery.js"></script>
|
||||
<script src="/static/script.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<div class="header">
|
||||
<h1>Team</h1>
|
||||
<h2>{%?project-name}</h2>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<ul class="menu">
|
||||
<li class="active"><a href="#">Overview</a></li>
|
||||
<li><a href="#">Downloads</a></li>
|
||||
<li><a href="#">Code</a></li>
|
||||
<li><a href="#">Tickets</a></li>
|
||||
<li><a href="#">Forum</a></li>
|
||||
<li><a href="#">Contributors</a></li>
|
||||
<li><a href="#">Invitations</a></li>
|
||||
<li class="clear"></li>
|
||||
</ul>
|
||||
<div class="main">
|
||||
<aside>
|
||||
<section class="download">
|
||||
<h3>Downloads</h3>
|
||||
{%if isempty|stable-version == false}
|
||||
<a href="download/stable" class="download">
|
||||
<b class="stable"></b>
|
||||
<strong>Latest stable</strong>
|
||||
{%?stable-version}
|
||||
</a>
|
||||
{%/if}
|
||||
{%if isempty|experimental-version == false}
|
||||
<a href="download/experimental" class="download">
|
||||
<b class="experimental"></b>
|
||||
<strong>Latest testing</strong>
|
||||
{%?experimental-version}
|
||||
</a>
|
||||
{%/if}
|
||||
|
||||
{%if no-downloads == true}
|
||||
There are no downloads for this project yet.
|
||||
{%/if}
|
||||
</section>
|
||||
<section class="statistics">
|
||||
<h3>Statistics</h3>
|
||||
<ul>
|
||||
<li><strong>{%?line-count}</strong> lines of code</li>
|
||||
<!-- <li><strong>0</strong> commits</li>
|
||||
<li><strong>0</strong> contributors</li> -->
|
||||
<li><strong>{%?ticket-count}</strong> open tickets</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="tickets">
|
||||
<h3>Latest tickets</h3>
|
||||
<ul>
|
||||
{%if isempty|tickets == false}
|
||||
{%foreach ticket in tickets}
|
||||
<li><strong>{%?ticket[title]}</strong> {%?ticket[date]}</li>
|
||||
{%/foreach}
|
||||
{%if more-tickets == true}
|
||||
<li class="more"><a href="tickets">more...</a></li>
|
||||
{%/if}
|
||||
{%else}
|
||||
No tickets.
|
||||
{%/if}
|
||||
</ul>
|
||||
</section>
|
||||
</aside>
|
||||
<section class="intro">
|
||||
<h3>Introduction</h3>
|
||||
{%?long-description}
|
||||
</section>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
{%?contents}
|
||||
<div class="footer">
|
||||
Cryto Team is a free project management and hosting service for non-profit projects. <a href="/signup">Sign up today!</a>
|
||||
</div>
|
||||
|
|
51
public_html/templates/project/index.tpl
Normal file
51
public_html/templates/project/index.tpl
Normal file
|
@ -0,0 +1,51 @@
|
|||
<aside>
|
||||
<section class="download">
|
||||
<h3>Downloads</h3>
|
||||
{%if isempty|stable-version == false}
|
||||
<a href="{%?project-url}/download/stable" class="download">
|
||||
<b class="stable"></b>
|
||||
<strong>Latest stable</strong>
|
||||
{%?stable-version}
|
||||
</a>
|
||||
{%/if}
|
||||
{%if isempty|experimental-version == false}
|
||||
<a href="{%?project-url}/download/experimental" class="download">
|
||||
<b class="experimental"></b>
|
||||
<strong>Latest testing</strong>
|
||||
{%?experimental-version}
|
||||
</a>
|
||||
{%/if}
|
||||
|
||||
{%if no-downloads == true}
|
||||
There are no downloads for this project yet.
|
||||
{%/if}
|
||||
</section>
|
||||
<section class="statistics">
|
||||
<h3>Statistics</h3>
|
||||
<ul>
|
||||
<li><strong>{%?line-count}</strong> lines of code</li>
|
||||
<!-- <li><strong>0</strong> commits</li>
|
||||
<li><strong>0</strong> contributors</li> -->
|
||||
<li><strong>{%?ticket-count}</strong> open tickets</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="tickets">
|
||||
<h3>Latest tickets</h3>
|
||||
<ul>
|
||||
{%if isempty|tickets == false}
|
||||
{%foreach ticket in tickets}
|
||||
<li><strong>{%?ticket[title]}</strong> {%?ticket[date]}</li>
|
||||
{%/foreach}
|
||||
{%if more-tickets == true}
|
||||
<li class="more"><a href="{%?project-url}/tickets">more...</a></li>
|
||||
{%/if}
|
||||
{%else}
|
||||
No tickets.
|
||||
{%/if}
|
||||
</ul>
|
||||
</section>
|
||||
</aside>
|
||||
<section class="intro">
|
||||
<h3>Introduction</h3>
|
||||
{%?long-description}
|
||||
</section>
|
19
public_html/templates/project/layout.tpl
Normal file
19
public_html/templates/project/layout.tpl
Normal file
|
@ -0,0 +1,19 @@
|
|||
<div class="header">
|
||||
<h1>Team</h1>
|
||||
<h2>{%?project-name}</h2>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<ul class="menu">
|
||||
<li {%if current-page == "overview"}class="active"{%/if}><a href="{%?project-url}">Overview</a></li>
|
||||
<li {%if current-page == "downloads"}class="active"{%/if}><a href="{%?project-url}/downloads">Downloads</a></li>
|
||||
<li {%if current-page == "code"}class="active"{%/if}><a href="{%?project-url}/code">Code</a></li>
|
||||
<li {%if current-page == "tickets"}class="active"{%/if}><a href="{%?project-url}/tickets">Tickets</a></li>
|
||||
<li {%if current-page == "forum"}class="active"{%/if}><a href="{%?project-url}/forum">Forum</a></li>
|
||||
<li {%if current-page == "contributors"}class="active"{%/if}><a href="{%?project-url}/contributors">Contributors</a></li>
|
||||
<li {%if current-page == "invitations"}class="active"{%/if}><a href="{%?project-url}/invitations">Invitations</a></li>
|
||||
<li class="clear"></li>
|
||||
</ul>
|
||||
<div class="main">
|
||||
{%?contents}
|
||||
<div class="clear"></div>
|
||||
</div>
|
18
public_html/templates/project/tickets/index.tpl
Normal file
18
public_html/templates/project/tickets/index.tpl
Normal file
|
@ -0,0 +1,18 @@
|
|||
<section class="tickets">
|
||||
<table>
|
||||
<tr>
|
||||
<th class="empty"></th>
|
||||
<th>Title</th>
|
||||
<th>Priority</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
{%foreach ticket in tickets}
|
||||
<tr class="clickable priority-{%?ticket[priority-lowercase]} status-{%?ticket[status-lowercase]}" data-url="{%?project-url}/ticket/{%?ticket[id]}">
|
||||
<td class="id">#{%?ticket[id]}</td>
|
||||
<td class="title"><a href="{%?project-url}/ticket/{%?ticket[id]}">{%?ticket[title]}</a></td>
|
||||
<td class="priority">{%?ticket[priority]}</td>
|
||||
<td class="status">{%?ticket[status]}</td>
|
||||
</tr>
|
||||
{%/foreach}
|
||||
</table>
|
||||
</section>
|
58
public_html/templates/project/tickets/view.tpl
Normal file
58
public_html/templates/project/tickets/view.tpl
Normal file
|
@ -0,0 +1,58 @@
|
|||
<div class="section ticket-original">
|
||||
<h2>{%?title}</h2>
|
||||
<div class="metadata">
|
||||
<div class="currentdata">
|
||||
<div class="priority">
|
||||
<span class="key">Priority:</span>
|
||||
<span class="value">{%?priority}</span>
|
||||
</div>
|
||||
<div class="status">
|
||||
<span class="key">Status:</span>
|
||||
<span class="value">{%?status}</span>
|
||||
</div>
|
||||
<div class="owner">
|
||||
<span class="key">Owner:</span>
|
||||
<span class="value">{%?owner}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="originaldata">
|
||||
<div class="creator">
|
||||
<span class="key">Creator:</span>
|
||||
<span class="value">{%?creator}</span>
|
||||
</div>
|
||||
<div class="date">
|
||||
<span class="key">Date:</span>
|
||||
<span class="value">{%?date}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="body">
|
||||
{%?body}
|
||||
</div>
|
||||
</div>
|
||||
<div class="section ticket-updates">
|
||||
{%foreach update in updates}
|
||||
{%if update[event] == true}
|
||||
<div class="event">
|
||||
{%if update[component] == "owner"}
|
||||
<span class="author">{%?update[user]}</span> changed the owner to <span class="value">{%?update[operation]}</span>.
|
||||
{%elseif update[component] == "status"}
|
||||
<span class="author">{%?update[user]}</span> changed the ticket status to <span class="value">{%?update[operation]}</span>.
|
||||
{%elseif update[component] == "priority"}
|
||||
<span class="author">{%?update[user]}</span> changed the priority to <span class="value">{%?update[operation]}</span>.
|
||||
{%/if}
|
||||
<div class="date">{%?update[date]}</div>
|
||||
</div>
|
||||
{%else}
|
||||
<div class="message">
|
||||
<div class="metadata">
|
||||
<span class="author">{%?update[author]}</span>
|
||||
<span class="date">{%?update[date]}</span>
|
||||
</div>
|
||||
|
||||
<p>{%?update[body]}</p>
|
||||
</div>
|
||||
{%/if}
|
||||
{%/foreach}
|
||||
</div>
|
Loading…
Reference in a new issue