DaPortal
<?php //$Id$
//Copyright (c) 2013-2016 Pierre Pronchery <khorben@defora.org>
//This file is part of DeforaOS Web DaPortal
//
//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
//the Free Software Foundation, version 3 of the License.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program. If not, see <http://www.gnu.org/licenses/>.
require_once('./modules/project/scm.php');
//ProjectContent
class ProjectContent extends ContentMulti
{
//public
//methods
//essential
//ProjectContent::ProjectContent
public function __construct(Engine $engine, Module $module,
$properties = FALSE)
{
$this->fields['synopsis'] = 'Synopsis';
$this->fields['scm'] = 'SCM';
$this->fields['cvsroot'] = 'Repository';
parent::__construct($engine, $module, $properties);
//translations
$this->text_content_by = _('Project from');
$this->text_content_list_title = _('Project list');
$this->text_more_content = _('More projects...');
$this->text_submit = _('Submit');
$this->text_submit_content = _('New project');
}
//accessors
//ProjectContent::canBrowse
public function canBrowse(Engine $engine, Request $request = NULL,
&$error = FALSE)
{
$error = _('No SCM configured for this project');
if(($scm = $this->get('scm')) === FALSE || strlen($scm) == 0)
return FALSE;
return TRUE;
}
//ProjectContent::canDownload
public function canDownload(Engine $engine, Request $request = NULL,
&$error = FALSE)
{
$credentials = $engine->getCredentials();
if(Module::load($engine, 'download') === FALSE)
{
$error = _('The download module is not available');
return FALSE;
}
return TRUE;
}
//ProjectContent::canUpload
public function canUpload(Engine $engine, Request $request = NULL,
&$error = FALSE)
{
$credentials = $engine->getCredentials();
if($this->canDownload($engine, $request, $error) === FALSE)
return FALSE;
//FIXME really implement
return $credentials->isAdmin();
}
//ProjectContent::getColumns
static public function getColumns()
{
return array('icon' => '', 'title' => _('Title'),
'username' => _('Manager'), 'date' => _('Date'),
'synopsis' => _('Description'));
}
//ProjectContent::getMembers
public function getMembers(Engine $engine, $order = FALSE,
$limit = FALSE, $offset = FALSE)
{
$db = $engine->getDatabase();
$query = static::$project_query_list_members;
$args = array('project_id' => $this->getID());
if(($user = $this->getOwner($engine)) === FALSE)
return FALSE;
if(($res = $db->query($engine, $query, $args)) === FALSE)
return FALSE;
$ret = array($user);
foreach($res as $r)
{
$user = new ProjectUser($engine, $r['user_id'],
$r['username']);
$user->setProjectAdmin($this, ($db->isTrue($r['admin']))
? TRUE : FALSE);
$ret[] = $user;
}
return $ret;
}
//ProjectUser::getOwner
public function getOwner(Engine $engine)
{
$db = $engine->getDatabase();
$query = static::$project_query_get_user;
$args = array('project_id' => $this->getID());
if(($res = $db->query($engine, $query, $args)) === FALSE
|| $res->count() != 1)
return FALSE;
$res = $res->current();
$user = new ProjectUser($engine, $res['user_id'],
$res['username']);
$user->setProjectAdmin($this, TRUE);
return $user;
}
//useful
//ProjectContent::display
public function display(Engine $engine, Request $request = NULL)
{
switch(($action = $request->getAction()))
{
case 'download':
case 'gallery':
if($this->canDownload($engine, $request)
=== FALSE)
return parent::display($engine, $request);
//fallback
case 'browse':
case 'members':
case 'timeline':
$title = _('Project: ').$this->getTitle();
$page = new Page(array('title' => $title));
$page->append($this->displayTitle($engine,
$request));
$page->append($this->displayToolbar($engine,
$request));
$method = '_display'.$action;
return $this->$method($engine, $request, $page);
case 'homepage':
default:
return parent::display($engine, $request);
}
}
protected function _displayBrowse(Engine $engine, Request $request,
PageElement $page)
{
$class = get_class($this->getModule());
$error = _('Unknown error');
if($this->canBrowse($engine, $request, $error) === FALSE)
return new PageElement('dialog', array(
'type' => 'error', 'text' => $error));
$error = _('Could not browse the project');
if(($scm = $class::attachSCM($engine, $this->get('scm')))
=== FALSE)
return new PageElement('dialog', array(
'type' => 'error', 'text' => $error));
$browse = $scm->browse($this, $request);
if(!($browse instanceof PageElement))
//FIXME set the proper filename
return $browse;
$vbox = $page->append('vbox');
$page->append($browse);
return $page;
}
protected function _displayDownload(Engine $engine, Request $request,
PageElement $page)
{
$class = get_class($this->getModule());
$db = $engine->getDatabase();
$query = static::$project_query_list_downloads;
$vbox = $page->append('vbox');
//source code
if(($scm = $class::attachSCM($engine, $this->get('scm')))
!== FALSE
&& ($download = $scm->download($this, $request))
!== FALSE)
$page->append($download);
//downloads
$error = 'Could not list downloads';
$args = array('project_id' => $this->getID());
if(($res = $db->query($engine, $query, $args)) === FALSE)
return new PageElement('dialog', array(
'type' => 'error', 'text' => $error));
$vbox->append('title', array('text' => _('Downloads')));
$columns = DownloadProjectContent::getColumns();
unset($columns['project']);
$columns['permissions'] = _('Permissions');
$view = $vbox->append('treeview', array(
'columns' => $columns));
if($this->canUpload($engine, $request))
{
$toolbar = $view->append('toolbar');
$req = $this->getRequest('submit', array(
'type' => 'download'));
$link = $toolbar->append('button', array(
'stock' => 'new',
'request' => $req,
'text' => _('New download')));
}
$module = $this->getModule();
foreach($res as $r)
{
$row = $view->append('row');
$req = new Request($module->getName(), FALSE, $r['id'],
$r['title']);
$icon = Mime::getIcon($engine, $r['title'], 16);
$icon = new PageElement('image', array(
'source' => $icon));
$row->set('icon', $icon);
$filename = new PageElement('link', array(
'request' => $req,
'text' => $r['title']));
$row->set('title', $filename);
$req = new Request('user', FALSE, $r['user_id'],
$r['username']);
$username = new PageElement('link', array(
'stock' => 'user',
'request' => $req,
'text' => $r['username']));
$row->set('username', $username);
$row->set('group', $r['groupname']);
$date = $db->formatDate($r['timestamp']);
$row->set('date', $date);
$permissions = Common::getPermissions($r['mode'],
static::$S_IFDIR);
$permissions = new PageElement('label', array(
'class' => 'preformatted',
'text' => $permissions));
$row->set('permissions', $permissions);
}
return $page;
}
protected function _displayGallery(Engine $engine, Request $request,
PageElement $page)
{
$db = $engine->getDatabase();
$query = static::$project_query_list_screenshots;
$vbox = $page->append('vbox');
//screenshots
$error = _('Could not list screenshots');
$args = array('project_id' => $this->getID());
if(($res = $db->query($engine, $query, $args)) === FALSE)
return new PageElement('dialog', array(
'type' => 'error', 'text' => $error));
$vbox = $page->append('vbox');
$vbox->append('title', array('text' => _('Gallery')));
$view = $vbox->append('treeview', array(
'view' => 'thumbnails'));
foreach($res as $r)
{
$row = $view->append('row');
$req = new Request('download', 'download', $r['id'],
$r['title']);
$thumbnail = new PageElement('image', array(
'request' => $req));
$row->set('thumbnail', $thumbnail);
$label = new PageElement('link', array(
'request' => $req,
'text' => $r['title']));
$row->set('label', $label);
}
return $page;
}
protected function _displayMembers(Engine $engine, Request $request,
PageElement $page)
{
$vbox = $page->append('vbox');
//members
$error = _('Could not list members');
if(($res = $this->getMembers($engine)) === FALSE)
return new PageElement('dialog', array(
'type' => 'error', 'text' => $error));
$vbox = $page->append('vbox');
$vbox->append('title', array('text' => _('Members')));
$columns = array('title' => _('Name'),
'admin' => _('Administrator'));
$view = $vbox->append('treeview', array('columns' => $columns,
'view' => 'details'));
$no = new PageElement('image', array('stock' => 'no',
'size' => 16, 'title' => _('Disabled')));
$yes = new PageElement('image', array('stock' => 'yes',
'size' => 16, 'title' => _('Enabled')));
foreach($res as $user)
{
$r = new Request('user', FALSE, $user->getUserID(),
$user->getUsername());
$link = new PageElement('link', array('request' => $r,
'stock' => 'user',
'text' => $user->getUsername()));
$row = $view->append('row', array('title' => $link));
$row->set('admin', $user->isProjectAdmin($engine, $this)
? $yes : $no);
}
return $page;
}
protected function _displayTimeline(Engine $engine, Request $request,
PageElement $page)
{
$class = get_class($this->getModule());
if($this->canBrowse($engine, $request, $error) === FALSE)
return new PageElement('dialog', array(
'type' => 'error', 'text' => $error));
$vbox = $page->append('vbox');
if(($scm = $class::attachSCM($engine, $this->get('scm')))
=== FALSE)
return new PageElement('dialog', array(
'type' => 'error',
'text' => _('An error occurred')));
$timeline = $scm->timeline($this, $request);
$vbox->append($timeline);
return $page;
}
//ProjectContent::displayContent
public function displayContent(Engine $engine, Request $request)
{
$vbox = new PageElement('vbox');
if(($text = $this->get('synopsis')) !== FALSE
&& strlen($text))
$vbox->append('label', array('class' => 'bold',
'text' => $text));
$vbox->append('htmlview', array(
'text' => HTML::format($engine,
$this->getContent($engine))));
return $vbox;
}
//ProjectContent::displayRow
public function displayRow(Engine $engine, Request $request = NULL)
{
$ret = parent::displayRow($engine, $request);
$ret->set('synopsis', $this->get('synopsis'));
return $ret;
}
//ProjectContent::displayToolbar
public function displayToolbar(Engine $engine, Request $request = NULL)
{
$action = ($request !== NULL) ? $request->getAction() : FALSE;
$actions = array('bug_list' => _('Bug reports'));
if($this->canDownload($engine, $request))
{
$actions['download'] = _('Download');
$actions['gallery'] = _('Gallery');
}
$actions['timeline'] = _('Timeline');
$actions['browse'] = _('Browse');
$actions['members'] = _('Members');
$actions['homepage'] = _('Homepage');
$toolbar = parent::displayToolbar($engine, $request);
if($this->getID() === FALSE)
return $toolbar;
$browse = $this->canBrowse($engine, $request);
foreach($actions as $k => $v)
{
if($k != 'homepage' && $action == $k)
continue;
if(!$browse && ($k == 'browse' || $k == 'timeline'))
continue;
$r = ($k == 'homepage') ? $this->getRequest()
: $this->getRequest($k);
$button = new PageElement('button', array(
'stock' => $k, 'request' => $r,
'text' => $v));
$toolbar->prepend($button);
}
return $toolbar;
}
//ProjectContent::form
public function form(Engine $engine, Request $request)
{
return parent::form($engine, $request);
}
protected function _formSubmit(Engine $engine, Request $request)
{
$vbox = new PageElement('vbox');
$vbox->append('entry', array('name' => 'title',
'text' => _('Title: '),
'value' => $request->get('title')));
$vbox->append('entry', array('name' => 'synopsis',
'text' => _('Synopsis: '),
'value' => $request->get('synopsis')));
$vbox->append('textview', array('name' => 'content',
'text' => _('Description: '),
'value' => $request->get('content')));
//SCM
$combobox = $vbox->append('combobox', array('name' => 'scm',
'text' => _('SCM: '),
'value' => $request->get('scm')));
$combobox->append('label', array('value' => '',
'text' => _('(none)')));
if(($scms = SCMProject::listAll($engine, $this->getModule()))
!== FALSE)
foreach($scms as $scm)
$combobox->append('label', array(
'value' => $scm,
'text' => $scm));
$vbox->append('entry', array('name' => 'cvsroot',
'text' => _('Repository: '),
'value' => $request->get('cvsroot')));
return $vbox;
}
protected function _formUpdate(Engine $engine, Request $request)
{
$vbox = new PageElement('vbox');
//title
if(($value = $request->get('title')) === FALSE)
$value = $this->getTitle();
$vbox->append('entry', array('name' => 'title',
'text' => _('Title: '),
'value' => $value));
//synopsis
if(($value = $request->get('synopsis')) === FALSE)
$value = $this->get('synopsis');
$vbox->append('entry', array('name' => 'synopsis',
'text' => _('Synopsis: '),
'value' => $value));
//description
$label = $vbox->append('label', array(
'text' => _('Description: ')));
if(($value = $request->get('content')) === FALSE)
$value = $this->getContent($engine);
$label->append('textview', array('name' => 'content',
'value' => $value));
//SCM
if(($value = $request->get('scm')) === FALSE)
$value = $this->get('scm');
$combobox = $vbox->append('combobox', array('name' => 'scm',
'text' => _('SCM: '), 'value' => $value));
$combobox->append('label', array('value' => '',
'text' => _('(none)')));
if(($scms = SCMProject::listAll($engine, $this->getModule()))
!== FALSE)
foreach($scms as $scm)
$combobox->append('label', array(
'value' => $scm,
'text' => $scm));
if(($value = $request->get('cvsroot')) === FALSE)
$value = $this->get('cvsroot');
$vbox->append('entry', array('name' => 'cvsroot',
'text' => _('Repository: '),
'value' => $value));
return $vbox;
}
//ProjectContent::loadFromName
static public function loadFromName(Engine $engine, Module $module,
$name)
{
$query = static::$query_load_by_title;
$args = array('module_id' => $module->getID(),
'title' => $name);
if(($res = static::query($engine, $query, $args)) === FALSE
|| $res->count() != 1)
return FALSE;
return static::loadFromResult($engine, $module, $res);
}
//ProjectContent::save
public function save(Engine $engine, Request $request = NULL,
&$error = FALSE)
{
return parent::save($engine, $request, $error);
}
protected function _saveInsert(Engine $engine, Request $request = NULL,
&$error)
{
$database = $engine->getDatabase();
$query = static::$project_query_insert;
$this->set('synopsis', $request->get('synopsis'));
$this->set('scm', $request->get('scm'));
$this->set('cvsroot', $request->get('cvsroot'));
if(parent::_saveInsert($engine, $request, $error) === FALSE)
return FALSE;
$error = _('Could not insert the project');
$args = array('project_id' => $this->getID(),
'synopsis' => $this->get('synopsis'),
'scm' => $this->get('scm'),
'cvsroot' => $this->get('cvsroot'));
if($database->query($engine, $query, $args)
=== FALSE)
return FALSE;
return TRUE;
}
protected function _saveUpdate(Engine $engine, Request $request = NULL,
&$error)
{
$database = $engine->getDatabase();
$query = static::$project_query_update;
$args = array('project_id' => $this->getID());
$fields = array('synopsis', 'scm', 'cvsroot');
if(($ret = parent::_saveUpdate($engine, $request, $error))
=== FALSE)
return FALSE;
$error = _('Could not update the project');
foreach($fields as $f)
{
$args[$f] = $this->get($f);
if($request === NULL)
continue;
if(($v = $request->get($f)) !== FALSE)
$args[$f] = $v;
}
if($database->query($engine, $query, $args) === FALSE)
return FALSE;
foreach($fields as $f)
$this->$f = $args[$f];
return $ret;
}
//protected
//properties
static protected $S_IFDIR = 01000;
static protected $class = 'ProjectContent';
static protected $list_order = 'title ASC';
//queries
//IN: project_id
static protected $project_query_get_user = 'SELECT
user_id, username
FROM daportal_project, daportal_content_enabled
WHERE daportal_project.project_id
=daportal_content_enabled.content_id
AND project_id=:project_id';
//IN: project_id
// synopsis
// cvsroot
static protected $project_query_insert = 'INSERT INTO
daportal_project(project_id, synopsis, scm, cvsroot)
VALUES (:project_id, :synopsis, :scm, :cvsroot)';
//IN: project_id
static protected $project_query_list_downloads = "SELECT
daportal_download.content_id AS id, download.title AS title,
download.timestamp AS timestamp,
daportal_user_enabled.user_id AS user_id, username, groupname,
mode
FROM daportal_project_download, daportal_content project,
daportal_download, daportal_content download,
daportal_user_enabled, daportal_group
WHERE daportal_project_download.project_id=project.content_id
AND daportal_project_download.download_id=daportal_download.content_id
AND daportal_download.content_id=download.content_id
AND download.user_id=daportal_user_enabled.user_id
AND download.group_id=daportal_group.group_id
AND project.public='1' AND project.enabled='1'
AND download.public='1' AND download.enabled='1'
AND project_id=:project_id
ORDER BY download.timestamp DESC";
//IN: project_id
static protected $project_query_list_members = 'SELECT
daportal_user_enabled.user_id AS user_id, username,
daportal_project_user.admin AS admin
FROM daportal_project_user, daportal_user_enabled
WHERE daportal_project_user.user_id
=daportal_user_enabled.user_id
AND project_id=:project_id
ORDER BY username ASC';
//IN: project_id
static protected $project_query_list_screenshots = "SELECT
daportal_download.content_id AS id, download.title title
FROM daportal_project_screenshot, daportal_content project,
daportal_download, daportal_content download
WHERE daportal_project_screenshot.project_id=project.content_id
AND daportal_project_screenshot.download_id
=daportal_download.content_id
AND daportal_download.content_id=download.content_id
AND project.public='1' AND project.enabled='1'
AND download.public='1' AND download.enabled='1'
AND project_id=:project_id
ORDER BY download.timestamp DESC";
//IN: project_id
// synopsis
// scm
// cvsroot
static protected $project_query_update = 'UPDATE daportal_project
SET synopsis=:synopsis, scm=:scm, cvsroot=:cvsroot
WHERE project_id=:project_id';
//IN: module_id
static protected $query_list = 'SELECT content_id AS id, timestamp,
module_id, module, user_id, username, group_id, groupname,
title, content, enabled, public, synopsis, scm, cvsroot
FROM daportal_content_public, daportal_project
WHERE daportal_content_public.content_id=daportal_project.project_id
AND module_id=:module_id';
//IN: module_id
// group_id
static protected $query_list_group = 'SELECT content_id AS id,
timestamp, module_id, module,
daportal_content_public.user_id AS user_id, username,
daportal_content_public.group_id AS group_id,
daportal_group_enabled.groupname AS groupname, title, content,
daportal_content_public.enabled AS enabled, public, synopsis,
scm, cvsroot
FROM daportal_content_public, daportal_user_group,
daportal_group_enabled, daportal_project
WHERE daportal_content_public.content_id=daportal_project.project_id
AND module_id=:module_id
AND daportal_content_public.user_id=daportal_user_group.user_id
AND daportal_user_group.group_id=daportal_group_enabled.group_id
AND (daportal_user_group.group_id=:group_id
OR daportal_content_public.group_id=:group_id)';
//IN: module_id
// user_id
static protected $query_list_user = 'SELECT content_id AS id, timestamp,
module_id, module, user_id, username, group_id, groupname,
title, content, enabled, public, synopsis, scm, cvsroot
FROM daportal_content_public, daportal_project
WHERE daportal_content_public.content_id=daportal_project.project_id
AND module_id=:module_id
AND user_id=:user_id';
//IN: module_id
// user_id
static protected $query_list_user_private = 'SELECT content_id AS id,
timestamp, module_id, module, user_id, username,
group_id, groupname, title, content, enabled, public, synopsis,
scm, cvsroot
FROM daportal_content_enabled, daportal_project
WHERE daportal_content_enabled.content_id=daportal_project.project_id
AND module_id=:module_id
AND user_id=:user_id';
//IN: module_id
// user_id
// content_id
static protected $query_load = "SELECT content_id AS id, timestamp,
module_id, module, user_id, username, group_id, groupname,
title, content, enabled, public, synopsis, scm, cvsroot
FROM daportal_content_enabled, daportal_project
WHERE daportal_content_enabled.content_id=daportal_project.project_id
AND daportal_content_enabled.module_id=:module_id
AND (public='1' OR user_id=:user_id)
AND content_id=:content_id";
//IN: module_id
// title
static protected $query_load_by_title = 'SELECT content_id AS id,
timestamp,
module_id, module, user_id, username, group_id, groupname,
title, content, enabled, public, synopsis, scm, cvsroot
FROM daportal_content_public, daportal_project
WHERE daportal_content_public.content_id=daportal_project.project_id
AND daportal_content_public.module_id=:module_id
AND title=:title';
}
?>