Just configured from Wine's GIT
svn path=/; revision=1
This commit is contained in:
2
include/.cvsignore
Normal file
2
include/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
config.php
|
||||
stderr
|
||||
1
include/.htaccess
Normal file
1
include/.htaccess
Normal file
@@ -0,0 +1 @@
|
||||
deny from all
|
||||
628
include/appData.php
Normal file
628
include/appData.php
Normal file
@@ -0,0 +1,628 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Functions related to application data
|
||||
*/
|
||||
|
||||
require_once(BASE."include/util.php");
|
||||
|
||||
class appData
|
||||
{
|
||||
var $iId;
|
||||
var $iAppId;
|
||||
var $iVersionId;
|
||||
var $iSubmitterId;
|
||||
var $sSubmitTime;
|
||||
var $sDescription;
|
||||
var $bQueued;
|
||||
|
||||
function appData($iId = null, $oRow = null, $oObject = null)
|
||||
{
|
||||
if(!$iId && !$oRow)
|
||||
return;
|
||||
|
||||
/* Since all objects stored in the appData table have a number of common
|
||||
members, we can import such an object into an appData one without
|
||||
making an SQL query */
|
||||
if($oObject && $iId)
|
||||
{
|
||||
$this->iSubmitterId = $oObject->iSubmitterId;
|
||||
$this->sDescription = $oObject->sDescription;
|
||||
$this->iAppId = $oObject->iAppId;
|
||||
$this->iVersionId = $oObject->iVersionId;
|
||||
$this->sSubmitTime = $oObject->sSubmitTime;
|
||||
$this->iId = $iId;
|
||||
$this->bQueued = $oObject->bQueued;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$oRow)
|
||||
{
|
||||
$hResult = query_parameters("SELECT * FROM appData WHERE id = '?'", $iId);
|
||||
$oRow = query_fetch_object($hResult);
|
||||
}
|
||||
|
||||
if($oRow)
|
||||
{
|
||||
$this->iSubmitterId = $oRow->submitterId;
|
||||
$this->iAppId = $oRow->appId;
|
||||
$this->iVersionId = $oRow->versionId;
|
||||
$this->sSubmitTime = $oRow->submitTime;
|
||||
$this->iId = $iId;
|
||||
$this->bQueued = ($oRow->sState == 'accepted') ? false : true;
|
||||
$this->sDescription = $oRow->description;
|
||||
}
|
||||
}
|
||||
|
||||
function purge()
|
||||
{
|
||||
return $this->delete();
|
||||
}
|
||||
|
||||
function delete()
|
||||
{
|
||||
if(!$this->canEdit())
|
||||
return FALSE;
|
||||
|
||||
$sQuery = "DELETE FROM appData WHERE id = '?'";
|
||||
|
||||
$hResult = query_parameters($sQuery, $this->iId);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
function reQueue()
|
||||
{
|
||||
if(!$this->canEdit())
|
||||
return FALSE;
|
||||
|
||||
$sQuery = "UPDATE appData SET state = '?' WHERE id = '?'";
|
||||
$hResult = query_parameters($sQuery, 'queued', $this->iId);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function reject()
|
||||
{
|
||||
if(!$this->canEdit())
|
||||
return FALSE;
|
||||
|
||||
$sQuery = "UPDATE appData SET state = '?' WHERE id = '?'";
|
||||
$hResult = query_parameters($sQuery, 'rejected', $this->iId);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function update()
|
||||
{
|
||||
if(!$this->canEdit())
|
||||
return FALSE;
|
||||
|
||||
$sQuery = "UPDATE appData SET versionId = '?', appId = '?', description = '?'
|
||||
WHERE id = '?'";
|
||||
$hResult = query_parameters($sQuery, $this->iVersionId, $this->iAppId,
|
||||
$this->sDescription, $this->iId);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function objectGetParent($sClass = '')
|
||||
{
|
||||
if($this->iVersionId)
|
||||
return new version($this->iVersionId);
|
||||
else
|
||||
return new application($this->iAppId);
|
||||
}
|
||||
|
||||
public function objectSetParent($iNewId, $sClass = '')
|
||||
{
|
||||
if($this->iVersionId)
|
||||
$this->iVersionId = $iNewId;
|
||||
else
|
||||
$this->iAppId = $iNewId;
|
||||
}
|
||||
|
||||
function listSubmittedBy($iUserId, $bQueued = true)
|
||||
{
|
||||
$sExtra = '';
|
||||
if($bQueued) // downloadurls are only queued together with versions
|
||||
$sExtra = " AND appData.type != 'downloadurl' ";
|
||||
|
||||
$hResult = query_parameters("SELECT * FROM appData WHERE
|
||||
appData.submitterId = '?'
|
||||
AND
|
||||
appData.state = '?' $sExtra
|
||||
ORDER BY appData.id",
|
||||
$iUserId, $bQueued ? 'queued' : 'accepted');
|
||||
|
||||
if(!$hResult || !query_num_rows($hResult))
|
||||
return false;
|
||||
|
||||
$oTable = new table();
|
||||
$oTable->setWidth("100%");
|
||||
$oTable->setAlign("center");
|
||||
|
||||
$oTableRow = new tableRow();
|
||||
|
||||
$oTableRow->addTextCell("Version");
|
||||
$oTableRow->addTextCell("Type");
|
||||
$oTableRow->addTextCell("Description");
|
||||
$oTableRow->addTextCell("Submission Date");
|
||||
|
||||
if($bQueued)
|
||||
$oTableRow->addTextCell("Action");
|
||||
|
||||
$oTableRow->setClass("color4");
|
||||
$oTable->addRow($oTableRow);
|
||||
|
||||
for($i = 1; $oRow = query_fetch_object($hResult); $i++)
|
||||
{
|
||||
$oTableRow = new tableRow();
|
||||
if($oRow->versionId)
|
||||
{
|
||||
$oVersion = new version($oRow->versionId);
|
||||
$sLink = "<a href=\"".$oVersion->objectMakeUrl()."\">".
|
||||
$oVersion->fullName($oVersion->iVersionId)."</a>";
|
||||
} else
|
||||
{
|
||||
$oApp = new application($this->appId);
|
||||
$sLink = $oApp->objectMakeLink();
|
||||
}
|
||||
|
||||
$oTableRow->addTextCell($sLink);
|
||||
$oTableRow->addTextCell($oRow->type);
|
||||
$oTableRow->addTextCell($oRow->description);
|
||||
$oTableRow->addTextCell(print_date(mysqldatetime_to_unixtimestamp($oRow->submitTime)));
|
||||
|
||||
if($bQueued)
|
||||
{
|
||||
$oM = new objectManager($oRow->type);
|
||||
$oM->setReturnTo(array_key_exists('REQUEST_URI', $_SERVER) ? $_SERVER['REQUEST_URI'] : "");
|
||||
$shDeleteLink = '<a href="'.$oM->makeUrl("delete", $oRow->id, "Delete entry").'">delete</a>';
|
||||
$shEditLink = '<a href="'.$oM->makeUrl("edit", $oRow->id, "Edit entry").'">edit</a>';
|
||||
$oTableRow->addTextCell("[ $shEditLink ] [ $shDeleteLink ]");
|
||||
}
|
||||
|
||||
$oTableRow->setClass(($i % 2) ? "color0" : "color1");
|
||||
$oTable->addRow($oTableRow);
|
||||
}
|
||||
|
||||
return $oTable->getString();
|
||||
|
||||
}
|
||||
|
||||
/* Get appData for a given version/application, optionally filter by type */
|
||||
function getData($iId, $sType, $bIsVersion = TRUE, $bQueued = FALSE, $bRejected = FALSE)
|
||||
{
|
||||
$iAppId = 0;
|
||||
$iVersionId = 0;
|
||||
|
||||
if($bIsVersion)
|
||||
$iVersionId = $iId;
|
||||
else
|
||||
$iAppId = $iId;
|
||||
|
||||
$sState = objectManager::getStateString($bQueued, $bRejected);
|
||||
|
||||
$hResult = query_parameters("SELECT * FROM appData WHERE appId = '?' AND
|
||||
versionId = '?' AND TYPE = '?' AND state = '?'",
|
||||
$iAppId, $iVersionId, $sType, $sState);
|
||||
|
||||
if(!$hResult || !query_num_rows($hResult))
|
||||
return FALSE;
|
||||
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
function objectGetEntriesCount($sState, $sType = null, $oFilters = null)
|
||||
{
|
||||
/* Not implemented for appData */
|
||||
if($sState == 'rejected')
|
||||
return FALSE;
|
||||
|
||||
$sSelectType = "";
|
||||
$sWhereFilter = '';
|
||||
|
||||
if($oFilters)
|
||||
{
|
||||
$aOptions = $oFilters->getOptions();
|
||||
if($aOptions['appCategory'])
|
||||
{
|
||||
$oCategory = new category($aOptions['appCategory']);
|
||||
$sWhereFilter .= ' AND ' . $oCategory->getSqlQueryPart();
|
||||
}
|
||||
}
|
||||
|
||||
if(($sState != 'accepted') &&
|
||||
!$_SESSION['current']->hasPriv("admin"))
|
||||
{
|
||||
$sQuery = "SELECT COUNT(DISTINCT appData.id) as count FROM appData,
|
||||
appMaintainers, appVersion, appFamily WHERE
|
||||
appFamily.appId = appVersion.appId
|
||||
AND
|
||||
appMaintainers.state = 'accepted'
|
||||
AND
|
||||
appMaintainers.userId = '?'
|
||||
AND
|
||||
(
|
||||
(
|
||||
appMaintainers.appId = appFamily.appId
|
||||
OR
|
||||
appMaintainers.appId = appVersion.appId
|
||||
)
|
||||
AND
|
||||
appMaintainers.superMaintainer = '1'
|
||||
AND
|
||||
(
|
||||
appData.appId = appMaintainers.appId
|
||||
OR
|
||||
(
|
||||
appData.versionId = appVersion.versionId
|
||||
AND
|
||||
appVersion.appId = appMaintainers.appId
|
||||
)
|
||||
)
|
||||
OR
|
||||
(
|
||||
appMaintainers.superMaintainer = '0'
|
||||
AND
|
||||
appMaintainers.versionId = appVersion.versionId
|
||||
AND
|
||||
appMaintainers.versionId = appData.versionId
|
||||
)
|
||||
)
|
||||
AND
|
||||
appVersion.state = 'accepted'
|
||||
AND
|
||||
appFamily.state = 'accepted'$sWhereFilter";
|
||||
|
||||
if($sState != 'all')
|
||||
$sQuery .= " AND appData.state = '$sState'";
|
||||
|
||||
if($sType)
|
||||
{
|
||||
$sQuery .= " AND type = '?'";
|
||||
$hResult = query_parameters($sQuery, $_SESSION['current']->iUserId,
|
||||
$sType);
|
||||
} else
|
||||
{
|
||||
$hResult = query_parameters($sQuery, $_SESSION['current']->iUserId);
|
||||
}
|
||||
} else
|
||||
{
|
||||
if($sState != 'all')
|
||||
$sAppDataQueued = " AND appData.state = '$sState'";
|
||||
else
|
||||
$sAppDataQueued = '';
|
||||
|
||||
if($sType)
|
||||
$sSelectType = " AND type = '?'";
|
||||
|
||||
$sQuery = "(SELECT COUNT(DISTINCT appData.id) as count FROM appData,
|
||||
appFamily WHERE
|
||||
(
|
||||
appData.appId = appFamily.appId
|
||||
AND
|
||||
appData.versionId = '0'
|
||||
)
|
||||
AND
|
||||
appFamily.state = 'accepted'$sAppDataQueued$sSelectType$sWhereFilter) UNION
|
||||
(
|
||||
SELECT COUNT(DISTINCT appData.id) as count FROM appData,
|
||||
appFamily, appVersion WHERE
|
||||
appFamily.appId = appVersion.appId
|
||||
AND
|
||||
(
|
||||
appData.versionId = appVersion.versionId
|
||||
)
|
||||
AND
|
||||
appVersion.state = 'accepted'
|
||||
AND
|
||||
appFamily.state = 'accepted'$sAppDataQueued$sSelectType$sWhereFilter)";
|
||||
|
||||
if($sType)
|
||||
$hResult = query_parameters($sQuery, $sType, $sType);
|
||||
else
|
||||
$hResult = query_parameters($sQuery);
|
||||
}
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
for($iCount = 0; $oRow = query_fetch_object($hResult);)
|
||||
$iCount += $oRow->count;
|
||||
|
||||
return $iCount;
|
||||
}
|
||||
|
||||
function objectGetHeader($sType)
|
||||
{
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->AddTextCell("Submission Date");
|
||||
$oTableRow->AddTextCell("Submitter");
|
||||
$oTableRow->AddTextCell("Application");
|
||||
$oTableRow->AddTextCell("Version");
|
||||
return $oTableRow;
|
||||
}
|
||||
|
||||
function objectGetEntries($sState, $iRows = 0, $iStart = 0, $sOrderBy = '', $bAscending = true, $sType = null, $oFilters = null)
|
||||
{
|
||||
/* Not implemented for appData */
|
||||
if($sState == 'rejected')
|
||||
return FALSE;
|
||||
|
||||
$sSelectType = "";
|
||||
$sLimit = "";
|
||||
$sWhereFilter = '';
|
||||
|
||||
if($oFilters)
|
||||
{
|
||||
$aOptions = $oFilters->getOptions();
|
||||
if($aOptions['appCategory'])
|
||||
{
|
||||
$oCategory = new category($aOptions['appCategory']);
|
||||
$sWhereFilter .= ' AND ' . $oCategory->getSqlQueryPart();
|
||||
}
|
||||
}
|
||||
|
||||
if($sState != 'accepted' && !$_SESSION['current']->hasPriv("admin"))
|
||||
{
|
||||
$sQuery = "SELECT DISTINCT appData.* FROM appData, appMaintainers,
|
||||
appVersion, appFamily WHERE
|
||||
appFamily.appId = appVersion.appId
|
||||
AND
|
||||
appMaintainers.state = 'accepted'
|
||||
AND
|
||||
appMaintainers.userId = '?'
|
||||
AND
|
||||
(
|
||||
(
|
||||
(
|
||||
appMaintainers.appId = appFamily.appId
|
||||
OR
|
||||
appMaintainers.appId = appVersion.appId
|
||||
)
|
||||
AND
|
||||
appMaintainers.superMaintainer = '1'
|
||||
AND
|
||||
(
|
||||
appData.appId = appMaintainers.appId
|
||||
OR
|
||||
(
|
||||
appData.versionId = appVersion.versionId
|
||||
AND
|
||||
appVersion.appId = appMaintainers.appId
|
||||
)
|
||||
)
|
||||
)
|
||||
OR
|
||||
(
|
||||
appMaintainers.superMaintainer = '0'
|
||||
AND
|
||||
appMaintainers.versionId = appVersion.versionId
|
||||
AND
|
||||
appMaintainers.versionId = appData.versionId
|
||||
)
|
||||
)
|
||||
AND
|
||||
appVersion.state = 'accepted'
|
||||
AND
|
||||
appFamily.state = 'accepted'
|
||||
AND
|
||||
appData.state = '?'
|
||||
AND
|
||||
appData.type = '?'
|
||||
$sWhereFilter
|
||||
ORDER BY appFamily.appName";
|
||||
if(!$iRows && !$iStart)
|
||||
{
|
||||
$hResult = query_parameters($sQuery, $_SESSION['current']->iUserId,
|
||||
$sState, $sType);
|
||||
} else
|
||||
{
|
||||
if(!$iRows)
|
||||
$iRows = appData::objectGetEntriesCount($sState, $sType, $oFilters);
|
||||
$sQuery .= " LIMIT ?,?";
|
||||
$hResult = query_parameters($sQuery, $_SESSION['current']->iUserId,
|
||||
$sState, $sType,
|
||||
$iStart, $iRows);
|
||||
}
|
||||
} else
|
||||
{
|
||||
if($iStart || $iRows)
|
||||
$sLimit = " LIMIT ?,?";
|
||||
|
||||
$sQuery =
|
||||
"(
|
||||
SELECT DISTINCT appData.* FROM appData,
|
||||
appFamily WHERE
|
||||
(
|
||||
appData.appId = appFamily.appId
|
||||
AND
|
||||
appData.versionId = '0'
|
||||
)
|
||||
AND
|
||||
appFamily.state = 'accepted'
|
||||
AND
|
||||
appData.state = '?'
|
||||
AND
|
||||
appData.type = '?' $sWhereFilter ORDER BY appFamily.appName $sLimit
|
||||
)
|
||||
UNION
|
||||
(
|
||||
SELECT DISTINCT appData.* FROM appData,
|
||||
appFamily, appVersion WHERE
|
||||
appFamily.appId = appVersion.appId
|
||||
AND
|
||||
(
|
||||
appData.versionId = appVersion.versionId
|
||||
)
|
||||
AND
|
||||
appVersion.state = 'accepted'
|
||||
AND
|
||||
appFamily.state = 'accepted'
|
||||
AND
|
||||
appData.state = '?'
|
||||
AND
|
||||
appData.type = '?' $sWhereFilter ORDER BY appFamily.appName $sLimit
|
||||
)";
|
||||
if(!$iRows && !$iStart)
|
||||
{
|
||||
$hResult = query_parameters($sQuery, $sState, $sType,
|
||||
$sState, $sType);
|
||||
} else
|
||||
{
|
||||
if(!$iRows)
|
||||
$iRows = appData::objectGetEntriesCount($sState, $sType, $oFilters);
|
||||
$hResult = query_parameters($sQuery, $sState, $sType,
|
||||
$iStart, $iRows,
|
||||
$sState, $sType,
|
||||
$iStart, $iRows);
|
||||
}
|
||||
}
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
function canEdit()
|
||||
{
|
||||
if($_SESSION['current']->hasPriv("admin"))
|
||||
return TRUE;
|
||||
if($this)
|
||||
{
|
||||
if($this->bQueued && $this->iSubmitterId == $_SESSION['current']->iUserId)
|
||||
return true;
|
||||
|
||||
if($this->iVersionId)
|
||||
{
|
||||
$oVersion = new version($this->iVersionId);
|
||||
if($oVersion->canEdit())
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
} else if($this->iAppId)
|
||||
{
|
||||
$oApp = new application($this->iAppId);
|
||||
if($oApp->canEdit())
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
function mustBeQueued()
|
||||
{
|
||||
if($_SESSION['current']->hasPriv("admin"))
|
||||
return FALSE;
|
||||
if($this)
|
||||
{
|
||||
if($this->iVersionId)
|
||||
{
|
||||
$oVersion = new version($this->iVersionId);
|
||||
if($oVersion->canEdit() && $oVersion->objectGetState() == 'accepted')
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
} else if($this->iAppId)
|
||||
{
|
||||
$oApp = new application($this->iAppId);
|
||||
if($oApp->canEdit() && $oApp->objectGetState() == 'accepted')
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
} else
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
function objectGetTableRow()
|
||||
{
|
||||
$oVersion = new Version($this->iVersionId);
|
||||
|
||||
if(!$this->iAppId)
|
||||
$this->iAppId = $oVersion->iAppId;
|
||||
|
||||
$oApp = new Application($this->iAppId);
|
||||
$oUser = new User($this->iSubmitterId);
|
||||
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->AddTextCell(print_date(mysqldatetime_to_unixtimestamp($this->sSubmitTime)));
|
||||
$oTableRow->AddTextCell($oUser->objectMakeLink());
|
||||
$oTableRow->AddTextCell($oApp->objectMakeLink());
|
||||
$oTableRow->AddTextCell($this->iVersionId ? $oVersion->objectMakeLink() : "N/A");
|
||||
|
||||
// create the object manager specific row
|
||||
$oOMTableRow = new OMTableRow($oTableRow);
|
||||
|
||||
return $oOMTableRow;
|
||||
}
|
||||
|
||||
function objectDisplayQueueProcessingHelp()
|
||||
{
|
||||
$sHelp = "<p>This is a list of application data submitted by users. ".
|
||||
"Please inspect the data carefully before accepting or rejecting it.</p>";
|
||||
echo $sHelp;
|
||||
}
|
||||
|
||||
/* Output the part of an appData editor which is the same for all data types */
|
||||
function outputEditorGeneric()
|
||||
{
|
||||
$oVersion = new version($this->iVersionId);
|
||||
if($oVersion->iVersionId)
|
||||
{
|
||||
$this->iAppId = $oVersion->iAppId;
|
||||
$sVersionName = $oVersion->objectMakeLink();
|
||||
}
|
||||
else
|
||||
$sVersionName = "N/A";
|
||||
|
||||
$oApp = new Application($this->iAppId);
|
||||
|
||||
// view application details
|
||||
echo html_frame_start("New Application Data Form",600,"",0);
|
||||
echo "<table width='100%' border=0 cellpadding=2 cellspacing=0>\n";
|
||||
|
||||
// app name
|
||||
echo '<tr valign=top><td class=color0><b>App Name</b></td>',"\n";
|
||||
echo "<td>".$oApp->objectMakeLink()."</td></tr>\n";
|
||||
|
||||
// version
|
||||
echo '<tr valign=top><td class=color0><b>App Version</b></td>',"\n";
|
||||
echo "<td>$sVersionName</td></tr>\n";
|
||||
|
||||
//dataDescription
|
||||
echo '<tr valign=top><td class=color0><b>Description</b></td>',"\n";
|
||||
echo '<td><textarea name="sDescription" rows=10 cols=35>'.stripslashes($this->sDescription).'</textarea></td></tr>',"\n";
|
||||
}
|
||||
|
||||
function getDefaultReply()
|
||||
{
|
||||
$sReplyText = "Enter a personalized reason for acceptance or rejection of the".
|
||||
" submitted application data here";
|
||||
return $sReplyText;
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->iId;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
41
include/appdb.php
Normal file
41
include/appdb.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
function log_category_visit($catId)
|
||||
{
|
||||
global $REMOTE_ADDR;
|
||||
|
||||
$result = query_parameters("SELECT * FROM catHitStats WHERE ip = '?' AND catId = '?'",
|
||||
$REMOTE_ADDR, $catId);
|
||||
if($result && query_num_rows($result) == 1)
|
||||
{
|
||||
$oStatsRow = query_fetch_object($result);
|
||||
query_parameters("UPDATE catHitStats SET count = count + 1 WHERE catHitId = '?'",
|
||||
$oStatsRow->catHitId);
|
||||
} else
|
||||
{
|
||||
query_parameters("INSERT INTO catHitStats (appHitId, time, ip, catId, count) ".
|
||||
"VALUES (?, ?, '?', '?', '?')",
|
||||
"null", "null", $REMOTE_ADDR, $catId, "1");
|
||||
}
|
||||
}
|
||||
|
||||
function log_application_visit($appId)
|
||||
{
|
||||
global $REMOTE_ADDR;
|
||||
|
||||
$result = query_parameters("SELECT * FROM appHitStats WHERE ip = '?' AND appId = '?'",
|
||||
$REMOTE_ADDR, $appId);
|
||||
if($result && query_num_rows($result) == 1)
|
||||
{
|
||||
$stats = query_fetch_object($result);
|
||||
query_parameters("UPDATE appHitStats SET count = count + 1 WHERE appHitId = '?'",
|
||||
$stats->appHitId);
|
||||
} else
|
||||
{
|
||||
query_parameters("INSERT INTO appHitStats (appHitId, time, ip, appId, count) ".
|
||||
"VALUES (?, ?, '?', '?', '?')",
|
||||
"null", "null", $REMOTE_ADDR, $appId, "1");
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
1459
include/application.php
Normal file
1459
include/application.php
Normal file
File diff suppressed because it is too large
Load Diff
466
include/application_queue.php
Normal file
466
include/application_queue.php
Normal file
@@ -0,0 +1,466 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class for submitting/processing applications
|
||||
*/
|
||||
|
||||
class application_queue
|
||||
{
|
||||
var $oVersionQueue;
|
||||
var $oApp;
|
||||
var $oVendor;
|
||||
|
||||
function application_queue($iAppId = null, $oRow = null)
|
||||
{
|
||||
$this->oApp = new application($iAppId, $oRow);
|
||||
|
||||
$iVersionId = null;
|
||||
$iVendorId = null;
|
||||
|
||||
/* If this is an existing application then there must be a version
|
||||
accompanying it */
|
||||
if($this->oApp->iAppId)
|
||||
{
|
||||
/* Normal users do not get a aVersionsIds property, so we have to fetch
|
||||
the versionId manually. Normal users only have access to rejected
|
||||
applications, unless they submitted them */
|
||||
if($_SESSION['current']->hasPriv("admin"))
|
||||
{
|
||||
$iVersionId = $this->oApp->aVersionsIds[0];
|
||||
} else if($this->oApp->objectGetState() == 'rejected' ||
|
||||
($this->oApp->objectGetState() == 'queued' &&
|
||||
$this->oApp->objectGetSubmitterId() == $_SESSION['current']->iUserId))
|
||||
{
|
||||
$sQuery = "SELECT versionId FROM appVersion WHERE appId = '?' LIMIT 1";
|
||||
$hResult = query_parameters($sQuery, $this->oApp->iAppId);
|
||||
if($hResult)
|
||||
{
|
||||
if($oRow = query_fetch_object($hResult))
|
||||
$iVersionId = $oRow->versionId;
|
||||
}
|
||||
}
|
||||
$iVendorId = $this->oApp->iVendorId;
|
||||
}
|
||||
|
||||
$this->oVendor = new vendor($iVendorId);
|
||||
|
||||
$this->oVersionQueue = new version_queue($iVersionId);
|
||||
}
|
||||
|
||||
function create()
|
||||
{
|
||||
$bSuccess = TRUE;
|
||||
|
||||
/* Create a new vendor if an existing one was not selected, and
|
||||
assign the application to it */
|
||||
if(!$this->oApp->iVendorId)
|
||||
{
|
||||
$this->oVendor->create();
|
||||
$this->oApp->iVendorId = $this->oVendor->iVendorId;
|
||||
}
|
||||
|
||||
if(!$this->oApp->create())
|
||||
$bSuccess = FALSE;
|
||||
|
||||
/* Assign the version to the new application */
|
||||
$this->oVersionQueue->oVersion->iAppId = $this->oApp->iAppId;
|
||||
|
||||
if(!$this->oVersionQueue->create())
|
||||
$bSuccess = FALSE;
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
|
||||
function update()
|
||||
{
|
||||
$bSuccess = TRUE;
|
||||
|
||||
/* If the vendor was already un-queued then the edit vendor form would not
|
||||
have been displayed, and so the vendor name will not be set. Thus only
|
||||
update the vendor if the name is set */
|
||||
if($this->oVendor->sName)
|
||||
$this->oVendor->update();
|
||||
|
||||
if(!$this->oApp->update())
|
||||
$bSuccess = FALSE;
|
||||
|
||||
if(!$this->oVersionQueue->update())
|
||||
$bSuccess = FALSE;
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
|
||||
function unQueue()
|
||||
{
|
||||
/* The vendor is not necessarily queued, as it could have existed on
|
||||
beforehand */
|
||||
if($this->oVendor->objectGetState() != 'accepted')
|
||||
$this->oVendor->unQueue();
|
||||
|
||||
$this->oApp->unQueue();
|
||||
$this->oVersionQueue->unQueue();
|
||||
|
||||
/* Has anyone submitted new versions while the app was queued?
|
||||
If so we need to change their state from pending to queued */
|
||||
$aOtherVersions = $this->oApp->objectGetChildrenClassSpecific('version');
|
||||
foreach($aOtherVersions as $oVersion)
|
||||
{
|
||||
if($oVersion->objectGetState() == 'pending')
|
||||
{
|
||||
$oVersion->objectSetState('queued');
|
||||
$oVersion->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function reQueue()
|
||||
{
|
||||
$this->oApp->reQueue();
|
||||
$this->oVersionQueue->reQueue();
|
||||
}
|
||||
|
||||
function reject()
|
||||
{
|
||||
$this->oVersionQueue->reject();
|
||||
$this->oApp->reject();
|
||||
}
|
||||
|
||||
function purge()
|
||||
{
|
||||
$bSuccess = TRUE;
|
||||
|
||||
if(!$this->oApp->purge())
|
||||
$bSuccess = FALSE;
|
||||
|
||||
/* When deleting a duplicate app in the application queue, the version is moved
|
||||
to another app and so when application_queue::delete() is called there is
|
||||
no version child to delete, so check if the versionId is valid */
|
||||
if($this->oVersionQueue->oVersion->iVersionId)
|
||||
{
|
||||
if(!$this->oVersionQueue->purge())
|
||||
$bSuccess = FALSE;
|
||||
}
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
|
||||
function delete()
|
||||
{
|
||||
$bSuccess = TRUE;
|
||||
|
||||
if(!$this->oApp->delete())
|
||||
$bSuccess = FALSE;
|
||||
|
||||
/* When deleting a duplicate app in the application queue, the version is moved
|
||||
to another app and so when application_queue::delete() is called there is
|
||||
no version child to delete, so check if the versionId is valid */
|
||||
if($this->oVersionQueue->oVersion->iVersionId)
|
||||
{
|
||||
if(!$this->oVersionQueue->delete())
|
||||
$bSuccess = FALSE;
|
||||
}
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
|
||||
function objectGetChildren($bIncludeDeleted = false)
|
||||
{
|
||||
return $this->oApp->objectGetChildren($bIncludeDeleted);
|
||||
}
|
||||
|
||||
function objectGetSubmitterId()
|
||||
{
|
||||
return $this->oApp->objectGetSubmitterId();
|
||||
}
|
||||
|
||||
function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return $this->oApp->objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction);
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return $this->oApp->objectGetMail($sAction, $bMailSubmitter, $bParentAction);
|
||||
}
|
||||
|
||||
public function objectShowPreview()
|
||||
{
|
||||
if($this->oApp->sName)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function outputEditor($aClean = array())
|
||||
{
|
||||
/* We ask the user for the application name first so as to avoid duplicate
|
||||
submissons; a list of potential duplicates is displayed on the next page */
|
||||
if(!$this->oApp->sName)
|
||||
{
|
||||
echo "<div style='margin:auto; width: 500px; border:1px solid; background-color:#eee; padding:2px; '>\n";
|
||||
echo "<div style='font-weight:bold; padding:3px;'>\n";
|
||||
echo "Application name:\n";
|
||||
echo "</div>\n";
|
||||
echo "<div style='padding:5px;'>\n";
|
||||
echo "<center><input type=\"text\" name=\"sAppName\" style='width:485px;'></center>\n";
|
||||
echo "</div>\n";
|
||||
echo "<input type=\"hidden\" name=\"sSub\" value=\"view\">\n";
|
||||
echo "<input type=\"hidden\" name=\"sAppType\" value=\"application\">\n";
|
||||
echo "</div>\n";
|
||||
} else
|
||||
{
|
||||
/* Show potential duplicates */
|
||||
echo html_frame_start("Potential duplicate applications in the ".
|
||||
"database","90%","",0);
|
||||
$this->displayDuplicates();
|
||||
echo html_frame_end(" ");
|
||||
|
||||
$this->oApp->outputEditor();
|
||||
|
||||
/* Display the new vendor form for new applications or if we
|
||||
are processing an application and the vendor is queued */
|
||||
if(!$this->oApp->iAppId || $this->oVendor->objectGetState() != 'accepted')
|
||||
{
|
||||
echo html_frame_start("New Developer", "90%");
|
||||
$this->oVendor->outputEditor();
|
||||
echo html_frame_end();
|
||||
}
|
||||
|
||||
$this->oVersionQueue->oVersion->outputEditor();
|
||||
|
||||
global $aClean;
|
||||
|
||||
echo $this->oVersionQueue->oDownloadUrl->outputEditorSingle(
|
||||
$this->oVersionQueue->oVersion->iVersionId, $aClean);
|
||||
|
||||
$this->oVersionQueue->oTestDataQueue->outputEditor();
|
||||
|
||||
/* Allow the user to choose whether to preview the application view
|
||||
or the version view. Application view is default */
|
||||
echo html_frame_start("Select What to Preview");
|
||||
$sPreviewVersion = $aClean['bPreviewVersion'] ? $aClean['bPreviewVersion'] : "";
|
||||
|
||||
$shPreviewApp = '';
|
||||
$shPreviewVersion = '';
|
||||
|
||||
if($sPreviewVersion == "true")
|
||||
$shPreviewVersion = ' checked="checked"';
|
||||
else
|
||||
$shPreviewApp = ' checked="checked"';
|
||||
|
||||
echo "<input type=\"radio\" name=\"bPreviewVersion\"$shPreviewApp value=\"false\"> Preview application<br>\n";
|
||||
echo "<input type=\"radio\" name=\"bPreviewVersion\"$shPreviewVersion value=\"true\"> Preview version\n";
|
||||
echo html_frame_end();
|
||||
}
|
||||
}
|
||||
|
||||
function getOutputEditorValues($aClean)
|
||||
{
|
||||
$this->oApp->getOutputEditorValues($aClean);
|
||||
$this->oVersionQueue->getOutputEditorValues($aClean);
|
||||
$this->oVendor->getOutputEditorValues($aClean);
|
||||
}
|
||||
|
||||
function checkOutputEditorInput($aClean)
|
||||
{
|
||||
/* We want outputEditor() to be called again so we can display the main
|
||||
app form. No erros are displayed since we only return TRUE */
|
||||
if($this->oApp->sName && !$aClean['bMainAppForm'])
|
||||
return TRUE;
|
||||
|
||||
$sErrors = $this->oApp->checkOutputEditorInput($aClean);
|
||||
$sErrors .= $this->oVersionQueue->checkOutputEditorInput($aClean);
|
||||
return $sErrors;
|
||||
}
|
||||
|
||||
function objectGetState()
|
||||
{
|
||||
return $this->oApp->objectGetState();
|
||||
}
|
||||
|
||||
function canEdit()
|
||||
{
|
||||
return $this->oApp->canEdit();
|
||||
}
|
||||
|
||||
function mustBeQueued()
|
||||
{
|
||||
return $this->oApp->mustBeQueued();
|
||||
}
|
||||
|
||||
function displayDuplicates()
|
||||
{
|
||||
echo "<b>Like matches</b><br />\n";
|
||||
$this->displayDuplicateTable(searchForApplication($this->oApp->sName, $this->oApp->objectGetId()));
|
||||
echo "<br />\n";
|
||||
echo "<b>Partial matches</b><br />\n";
|
||||
$this->displayDuplicateTable(searchForApplicationPartial($this->oApp->sName, $this->oApp->objectGetId()));
|
||||
}
|
||||
|
||||
function displayDuplicateTable($hResult)
|
||||
{
|
||||
/* Exit if the MySQL handle is invalid */
|
||||
if($hResult === FALSE)
|
||||
return FALSE;
|
||||
|
||||
/* There's no point in displaying an empty table */
|
||||
if($hResult === null || (query_num_rows($hResult) == 0))
|
||||
{
|
||||
echo "No matches.<br>\n";
|
||||
return;
|
||||
}
|
||||
|
||||
$aHeader = array(
|
||||
"Application name",
|
||||
"Description",
|
||||
"No. versions"
|
||||
);
|
||||
|
||||
/* We can only move data if the current application already exists, and
|
||||
we have admin privileges */
|
||||
if($this->oApp->iAppId && $_SESSION['current']->hasPriv("admin"))
|
||||
{
|
||||
$bCanMove = TRUE;
|
||||
$aHeader[] = array("Move data", 'width="80"');
|
||||
} else
|
||||
{
|
||||
$bCanMove = FALSE;
|
||||
}
|
||||
|
||||
echo "<table cellpadding='5px'>";
|
||||
echo html_tr($aHeader, "color4");
|
||||
|
||||
for($i = 0; $oRow = query_fetch_object($hResult); $i++)
|
||||
{
|
||||
$oApp = new application($oRow->appId);
|
||||
$aCells = array(
|
||||
$oApp->objectMakeLink(),
|
||||
util_trim_description($oApp->sDescription),
|
||||
sizeof($oApp->aVersionsIds)
|
||||
);
|
||||
|
||||
if($bCanMove)
|
||||
{
|
||||
$aCells[] = "<a href=\"objectManager.php?sClass=application_queue&".
|
||||
"bIsQueue=true&sAction=moveChildren&iId=".
|
||||
$this->oApp->iAppId."&iNewId=".$oApp->iAppId.
|
||||
"\">Move data</a>";
|
||||
}
|
||||
echo html_tr($aCells, ($i % 2) ? "color0" : "color1");
|
||||
}
|
||||
echo "</table>";
|
||||
}
|
||||
|
||||
function objectGetCustomVars($sAction)
|
||||
{
|
||||
switch($sAction)
|
||||
{
|
||||
case "preview":
|
||||
return array("bPreviewVersion");
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function display($aClean = array())
|
||||
{
|
||||
/* Cache the version object if it is not in the database */
|
||||
if(!$this->oVersionQueue->objectGetId())
|
||||
$this->oApp->aVersions = array($this->oVersionQueue->oVersion);
|
||||
|
||||
$sPreviewVersion = $aClean['bPreviewVersion'] ? $aClean['bPreviewVersion'] : "";
|
||||
|
||||
if($sPreviewVersion == "true")
|
||||
{
|
||||
$this->oVersionQueue->oVersion->oApp = $this->oApp;
|
||||
$this->oVersionQueue->display();
|
||||
} else
|
||||
{
|
||||
$this->oApp->display();
|
||||
}
|
||||
}
|
||||
|
||||
function objectMakeUrl()
|
||||
{
|
||||
return $this->oApp->objectMakeUrl();
|
||||
}
|
||||
|
||||
function objectMakeLink()
|
||||
{
|
||||
return $this->oApp->objectMakeLink();
|
||||
}
|
||||
|
||||
function objectGetItemsPerPage($sState = 'accepted')
|
||||
{
|
||||
return $this->oApp->objectGetItemsPerPage($sState);
|
||||
}
|
||||
|
||||
function objectGetEntriesCount($sState)
|
||||
{
|
||||
return $this->oApp->objectGetEntriesCount($sState);
|
||||
}
|
||||
|
||||
public static function objectGetDefaultSort()
|
||||
{
|
||||
return application::objectGetDefaultSort();
|
||||
}
|
||||
|
||||
function objectGetEntries($sState, $iRows = 0, $iStart = 0, $sOrderBy = "appId", $bAscending = TRUE)
|
||||
{
|
||||
return $this->oApp->objectGetEntries($sState, $iRows, $iStart,
|
||||
$sOrderBy, $bAscending);
|
||||
}
|
||||
|
||||
public static function objectGetSortableFields()
|
||||
{
|
||||
return application::objectGetSortableFields();
|
||||
}
|
||||
|
||||
function objectGetHeader($sState)
|
||||
{
|
||||
return $this->oApp->objectGetHeader($sState);
|
||||
}
|
||||
|
||||
function objectGetTableRow()
|
||||
{
|
||||
return $this->oApp->objectGetTableRow();
|
||||
}
|
||||
|
||||
function objectMoveChildren($iNewId)
|
||||
{
|
||||
return $this->oApp->objectMoveChildren($iNewId);
|
||||
}
|
||||
|
||||
function objectDisplayQueueProcessingHelp()
|
||||
{
|
||||
return application::objectDisplayQueueProcessingHelp();
|
||||
}
|
||||
|
||||
function objectDisplayAddItemHelp()
|
||||
{
|
||||
$this->oApp->objectDisplayAddItemHelp();
|
||||
}
|
||||
|
||||
function allowAnonymousSubmissions()
|
||||
{
|
||||
return application::allowAnonymousSubmissions();
|
||||
}
|
||||
|
||||
function objectAllowPurgingRejected()
|
||||
{
|
||||
return $this->oApp->objectAllowPurgingRejected();
|
||||
}
|
||||
|
||||
public function objectGetSubmitTime()
|
||||
{
|
||||
return $this->oApp->objectGetSubmitTime();
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->oApp->objectGetId();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
686
include/bugs.php
Normal file
686
include/bugs.php
Normal file
@@ -0,0 +1,686 @@
|
||||
<?php
|
||||
require_once(BASE."include/util.php");
|
||||
require_once(BASE."include/application.php");
|
||||
/******************************************/
|
||||
/* bug class and related functions */
|
||||
/******************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Bug Link class for handling Bug Links and thumbnails
|
||||
*/
|
||||
class Bug
|
||||
{
|
||||
var $iLinkId;
|
||||
|
||||
// parameters necessary to create a new Bug with Bug::create()
|
||||
var $iVersionId;
|
||||
var $iBug_id;
|
||||
|
||||
// values retrieved from bugzilla
|
||||
var $sShort_desc;
|
||||
var $sBug_status;
|
||||
var $sResolution;
|
||||
var $sSubmitTime;
|
||||
var $iSubmitterId;
|
||||
var $bQueued;
|
||||
|
||||
/**
|
||||
* Constructor, fetches the data and bug objects if $ilinkId is given.
|
||||
*/
|
||||
function bug($iLinkId = null, $oRow = null)
|
||||
{
|
||||
if(!$iLinkId && !$oRow)
|
||||
return;
|
||||
|
||||
if(!$oRow)
|
||||
{
|
||||
$sQuery = "SELECT * FROM buglinks
|
||||
WHERE linkId = '?'";
|
||||
if($hResult = query_parameters($sQuery, $iLinkId))
|
||||
{
|
||||
$oRow = query_fetch_object($hResult);
|
||||
}
|
||||
}
|
||||
|
||||
if($oRow)
|
||||
{
|
||||
$this->iLinkId = $oRow->linkId;
|
||||
$this->iBug_id = $oRow->bug_id;
|
||||
$this->iVersionId = $oRow->versionId;
|
||||
$this->bQueued = ($oRow->state=='queued') ? true : false;
|
||||
$this->sSubmitTime = $oRow->submitTime;
|
||||
$this->iSubmitterId = $oRow->submitterId;
|
||||
/* lets fill in some blanks */
|
||||
if ($this->iBug_id)
|
||||
{
|
||||
$sQuery = "SELECT *
|
||||
FROM bugs
|
||||
WHERE bug_id = ".$this->iBug_id;
|
||||
if($hResult = query_bugzilladb($sQuery))
|
||||
{
|
||||
$oRow = query_fetch_object($hResult);
|
||||
if($oRow)
|
||||
{
|
||||
$this->sShort_desc = $oRow->short_desc;
|
||||
$this->sBug_status = $oRow->bug_status;
|
||||
$this->sResolution = $oRow->resolution;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new Bug.
|
||||
*/
|
||||
function create()
|
||||
{
|
||||
$oVersion = new Version($this->iVersionId);
|
||||
|
||||
// Security, if we are not an administrator or a maintainer,
|
||||
// the Bug must be queued.
|
||||
if($this->mustBeQueued())
|
||||
{
|
||||
$this->bQueued = true;
|
||||
} else
|
||||
{
|
||||
$this->bQueued = false;
|
||||
}
|
||||
|
||||
/* lets check for a valid bug id */
|
||||
if(!is_numeric($this->iBug_id))
|
||||
{
|
||||
addmsg($this->iBug_id." is not a valid bug number.", "red");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check that bug # exists in bugzilla*/
|
||||
$sQuery = "SELECT *
|
||||
FROM bugs
|
||||
WHERE bug_id = ".$this->iBug_id;
|
||||
if(query_num_rows(query_bugzilladb($sQuery, "checking bugzilla")) == 0)
|
||||
{
|
||||
addmsg("There is no bug in Bugzilla with that bug number.", "red");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check for duplicates */
|
||||
if($this->isDuplicate())
|
||||
{
|
||||
addmsg("The Bug link has already been submitted.", "red");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* passed the checks so lets insert the puppy! */
|
||||
$hResult = query_parameters("INSERT INTO buglinks (versionId, bug_id, ".
|
||||
"submitTime, submitterId, state) ".
|
||||
"VALUES('?', '?', ?, '?', '?')",
|
||||
$this->iVersionId, $this->iBug_id,
|
||||
"NOW()",
|
||||
$_SESSION['current']->iUserId,
|
||||
$this->bQueued ? 'queued' : 'accepted');
|
||||
if($hResult)
|
||||
{
|
||||
$this->iLinkId = query_appdb_insert_id();
|
||||
|
||||
$this->SendNotificationMail();
|
||||
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
addmsg("Error while creating a new Bug link.", "red");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function purge()
|
||||
{
|
||||
return $this->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the Bug from the database.
|
||||
* and request its deletion from the filesystem (including the thumbnail).
|
||||
*
|
||||
* Return true if successful, false if an error occurs
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
$sQuery = "DELETE FROM buglinks
|
||||
WHERE linkId = '?'";
|
||||
if(!($hResult = query_parameters($sQuery, $this->iLinkId)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move Bug out of the queue.
|
||||
*/
|
||||
function unQueue()
|
||||
{
|
||||
// If we are not in the queue, we can't move the Bug out of the queue.
|
||||
if(!$this->bQueued)
|
||||
return false;
|
||||
|
||||
if(query_parameters("UPDATE buglinks SET state = '?' WHERE linkId='?'",
|
||||
'accepted', $this->iLinkId))
|
||||
{
|
||||
$this->bQueued = false;
|
||||
// we send an e-mail to interested people
|
||||
$this->mailSubmitter();
|
||||
$this->SendNotificationMail();
|
||||
// the Bug has been unqueued
|
||||
addmsg("The Bug has been unqueued.", "green");
|
||||
}
|
||||
}
|
||||
|
||||
function update()
|
||||
{
|
||||
$oBug = new bug($this->iLinkId);
|
||||
|
||||
// There is no need to have two links to a bug. The update is still
|
||||
// considered successful
|
||||
if($this->isDuplicate())
|
||||
return $this->delete();
|
||||
|
||||
if($this->iVersionId && $this->iVersionId != $oBug->iVersionId)
|
||||
{
|
||||
$hResult = query_parameters("UPDATE buglinks SET versionId = '?'
|
||||
WHERE linkId = '?'",
|
||||
$this->iVersionId, $this->iLinkId);
|
||||
|
||||
if(!$hResult)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Checks whether the version already has a link for this bug */
|
||||
public function isDuplicate()
|
||||
{
|
||||
$sQuery = "SELECT COUNT(linkId) as count
|
||||
FROM buglinks
|
||||
WHERE versionId = '?'
|
||||
AND bug_id = '?'";
|
||||
if($hResult = query_parameters($sQuery, $this->iVersionId, $this->iBug_id))
|
||||
{
|
||||
if(($oRow = query_fetch_object($hResult)))
|
||||
{
|
||||
return $oRow->count > 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function mailSubmitter($bRejected=false)
|
||||
{
|
||||
global $aClean;
|
||||
if(!isset($aClean['sReplyText']))
|
||||
$aClean['sReplyText'] = "";
|
||||
|
||||
if($this->iSubmitterId)
|
||||
{
|
||||
$oSubmitter = new User($this->iSubmitterId);
|
||||
$sAppName = Version::fullName($this->iVersionId);
|
||||
if(!$bRejected)
|
||||
{
|
||||
$sSubject = "Submitted Bug Link accepted";
|
||||
$sMsg = "The bug link you submitted between Bug ".$this->iBug_id." and ".
|
||||
$sAppName." has been accepted.";
|
||||
} else
|
||||
{
|
||||
$sSubject = "Submitted Bug Link rejected";
|
||||
$sMsg = "The bug link you submitted between Bug ".$this->iBug_id." and ".
|
||||
$sAppName." has been deleted.";
|
||||
}
|
||||
$sMsg .= $aClean['sReplyText']."\n";
|
||||
$sMsg .= "We appreciate your help in making the Application Database better for all users.";
|
||||
|
||||
mail_appdb($oSubmitter->sEmail, $sSubject ,$sMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function SendNotificationMail($bDeleted=false)
|
||||
{
|
||||
$sAppName = version::fullName($this->iVersionId);
|
||||
$oVersion = new version($this->iVersionId);
|
||||
|
||||
//show the application version URL and the bug URL
|
||||
$sMsg = $oVersion->objectMakeUrl()."\n\n";
|
||||
$sMsg .= BUGZILLA_ROOT."show_bug.cgi?id=".$this->iBug_id."\n";
|
||||
|
||||
if(!$bDeleted)
|
||||
{
|
||||
if(!$this->bQueued)
|
||||
{
|
||||
$sSubject = "Link between Bug ".$this->iBug_id." and ".$sAppName." added by ".$_SESSION['current']->sRealname;
|
||||
if($this->iSubmitterId)
|
||||
{
|
||||
$oSubmitter = new User($this->iSubmitterId);
|
||||
$sMsg .= "This Bug Link has been submitted by ".$oSubmitter->sRealname.".\n";
|
||||
}
|
||||
addmsg("The Bug Link was successfully added into the database.", "green");
|
||||
} else // Bug Link queued.
|
||||
{
|
||||
$sSubject = "Link between Bug ".$this->iBug_id." and ".$sAppName." submitted by ".$_SESSION['current']->sRealname;
|
||||
$sMsg .= "This Bug Link has been queued.\n";
|
||||
addmsg("The Bug Link you submitted will be added to the database after being reviewed.", "green");
|
||||
}
|
||||
} else // Bug Link deleted.
|
||||
{
|
||||
$sSubject = "Link between Bug ".$this->iBug_id." and ".$sAppName." deleted by ".$_SESSION['current']->sRealname;
|
||||
addmsg("Bug Link deleted.", "green");
|
||||
}
|
||||
|
||||
$sEmail = User::get_notify_email_address_list(null, $this->iVersionId);
|
||||
if($sEmail)
|
||||
{
|
||||
mail_appdb($sEmail, $sSubject ,$sMsg);
|
||||
}
|
||||
}
|
||||
|
||||
function objectGetSubmitterId()
|
||||
{
|
||||
return $this->iSubmitterId;
|
||||
}
|
||||
|
||||
function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return new mailOptions();
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
/* We don't do this at the moment */
|
||||
return array(null, null, null);
|
||||
}
|
||||
|
||||
public function objectGetParent($sClass = '')
|
||||
{
|
||||
return new version($this->iVersionId);
|
||||
}
|
||||
|
||||
public function objectSetParent($iNewId, $sClass = '')
|
||||
{
|
||||
$this->iVersionId = $iNewId;
|
||||
}
|
||||
|
||||
function objectGetChildren($bIncludeDeleted = false)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/* Get a list of bugs submitted by a given user */
|
||||
function listSubmittedBy($iUserId, $bQueued = true)
|
||||
{
|
||||
$hResult = query_parameters("SELECT appFamily.appName, buglinks.versionId, appVersion.versionName, buglinks.submitTime, buglinks.bug_id, buglinks.linkId FROM buglinks, appFamily, appVersion WHERE appFamily.appId = appVersion.appId AND buglinks.versionId = appVersion.versionId AND buglinks.state = '?' AND buglinks.submitterId = '?' ORDER BY buglinks.versionId", $bQueued ? 'queued' : 'accepted', $iUserId);
|
||||
|
||||
if(!$hResult || !query_num_rows($hResult))
|
||||
return FALSE;
|
||||
|
||||
$oTable = new Table();
|
||||
$oTable->SetWidth("100%");
|
||||
$oTable->SetAlign("center");
|
||||
|
||||
// setup the table header
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->AddTextCell('Version');
|
||||
$oTableRow->AddTextCell('Bug #', 'width="50"');
|
||||
$oTableRow->AddTextCell('Status', 'width="80"');
|
||||
$oTableRow->AddTextCell('Resolution', 'width="110"');
|
||||
$oTableRow->AddTextCell('Description', 'Submit time');
|
||||
$oTableRow->AddTextCell('Submit time');
|
||||
|
||||
if($bQueued)
|
||||
$oTableRow->addTextCell('Action');
|
||||
|
||||
$oTableRow->SetClass('color4');
|
||||
$oTable->AddRow($oTableRow);
|
||||
|
||||
for($i = 1; $oRow = query_fetch_object($hResult); $i++)
|
||||
{
|
||||
$oTableRow = new TableRow();
|
||||
|
||||
$oTableRow->AddTextCell(version::fullNameLink($oRow->versionId));
|
||||
$oTableRow->AddTextCell('<a href="'.BUGZILLA_ROOT.'show_bug.cgi?id='.$oRow->bug_id.'">'.$oRow->bug_id.'</a>');
|
||||
$oTableRow->AddTextCell($oBug->sBug_status);
|
||||
$oTableRow->AddTextCell($oBug->sResolution);
|
||||
$oTableRow->AddTextCell($oBug->sShort_desc);
|
||||
$oTableRow->AddTextCell(print_date(mysqldatetime_to_unixtimestamp($oRow->submitTime)));
|
||||
|
||||
if($bQueued)
|
||||
{
|
||||
$oM = new objectManager('bug');
|
||||
$oM->setReturnTo(array_key_exists('REQUEST_URI', $_SERVER) ? $_SERVER['REQUEST_URI'] : "");
|
||||
$shDeleteLink = '<a href="'.$oM->makeUrl('delete', $oRow->linkId, 'Delete entry').'">delete</a>';
|
||||
$oTableRow->addTextCell(" [ $shDeleteLink ]");
|
||||
}
|
||||
|
||||
$oTableRow->SetClass(($i % 2 ) ? 'color0' : 'color1');
|
||||
$oTable->AddRow($oTableRow);
|
||||
}
|
||||
|
||||
return $oTable->GetString();
|
||||
}
|
||||
|
||||
function isOpen()
|
||||
{
|
||||
return ($this->sBug_status != 'RESOLVED' && $this->sBug_status != 'CLOSED');
|
||||
}
|
||||
|
||||
function allowAnonymousSubmissions()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function mustBeQueued()
|
||||
{
|
||||
$oVersion = new version($this->iVersionId);
|
||||
|
||||
if($_SESSION['current']->hasPriv("admin") ||
|
||||
$_SESSION['current']->isMaintainer($oVersion->iVersionId) ||
|
||||
$_SESSION['current']->isSuperMaintainer($oVersion->iAppId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->iLinkId;
|
||||
}
|
||||
|
||||
function objectGetEntries($sState, $iRows = 0, $iStart = 0, $sOrderBy = '', $bAscending = true)
|
||||
{
|
||||
$sLimit = "";
|
||||
|
||||
/* Selecting 0 rows makes no sense, so we assume the user
|
||||
wants to select all of them
|
||||
after an offset given by iStart */
|
||||
if(!$iRows)
|
||||
$iRows = bug::objectGetEntriesCount($sState);
|
||||
|
||||
$sQuery = "select * from buglinks where state = '?' LIMIT ?, ?";
|
||||
$hResult = query_parameters($sQuery, $sState, $iStart, $iRows);
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
function objectGetEntriesCount($sState)
|
||||
{
|
||||
$sQuery = "select count(*) as cnt from buglinks where state = '?'";
|
||||
$hResult = query_parameters($sQuery, $sState);
|
||||
$oRow = mysql_fetch_object($hResult);
|
||||
return $oRow->cnt;
|
||||
}
|
||||
|
||||
function objectGetHeader()
|
||||
{
|
||||
$oTableRow = new TableRow();
|
||||
|
||||
$oTableRow->AddTextCell("Bug #");
|
||||
|
||||
$oTableCell = new TableCell("Status");
|
||||
$oTableCell->SetAlign("center");
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
$oTableRow->AddTextCell("Bug Description");
|
||||
|
||||
$oTableCell = new TableCell("Application Name");
|
||||
$oTableCell->SetAlign("center");
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
$oTableCell = new TableCell("Application Description");
|
||||
$oTableCell->SetAlign("center");
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
$oTableCell = new TableCell("Version");
|
||||
$oTableCell->SetAlign("center");
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
return $oTableRow;
|
||||
}
|
||||
|
||||
// returns a table row
|
||||
function objectGetTableRow()
|
||||
{
|
||||
$oTableRow = new TableRow();
|
||||
|
||||
$oVersion = new version($this->iVersionId);
|
||||
$oApp = new application($oVersion->iAppId);
|
||||
|
||||
$oTableCell = new TableCell($this->iBug_id);
|
||||
$oTableCell->SetAlign("center");
|
||||
$oTableCell->SetCellLink(BUGZILLA_ROOT.'show_bug.cgi?id='.$this->iBug_id);
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
$oTableCell = new TableCell($this->sBug_status);
|
||||
$oTableCell->SetAlign("center");
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
$oTableRow->AddTextCell($this->sShort_desc);
|
||||
|
||||
$oTableRow->AddTextCell($oApp->objectMakeLink());
|
||||
|
||||
$oTableRow->AddTextCell(util_trim_description($oApp->sDescription));
|
||||
|
||||
$oTableRow->AddTextCell($oVersion->objectMakeLink());
|
||||
|
||||
$oOMTableRow = new OMTableRow($oTableRow);
|
||||
|
||||
// enable the deletion link, the objectManager will check
|
||||
// for appropriate permissions before adding the link
|
||||
$oOMTableRow->SetHasDeleteLink(true);
|
||||
|
||||
return $oOMTableRow;
|
||||
}
|
||||
|
||||
function objectMakeUrl()
|
||||
{
|
||||
$oManager = new objectManager("bug", "View Bug");
|
||||
return $oManager->makeUrl("view", $this->objectGetId());
|
||||
}
|
||||
|
||||
function objectMakeLink()
|
||||
{
|
||||
$sLink = "<a href=\"".$this->objectMakeUrl()."\">".
|
||||
$this->sShort_desc."</a>";
|
||||
return $sLink;
|
||||
}
|
||||
|
||||
function objectGetState()
|
||||
{
|
||||
return ($this->bQueued) ? 'queued' : 'accepted';
|
||||
}
|
||||
|
||||
function canEdit()
|
||||
{
|
||||
if($_SESSION['current']->hasPriv("admin"))
|
||||
{
|
||||
return true;
|
||||
} else if($this->iVersionId)
|
||||
{
|
||||
if(maintainer::isUserMaintainer($_SESSION['current'],
|
||||
$this->iVersionId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if($this->iSubmitterId == $_SESSION['current']->iUserId)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function objectGetItemsPerPage($sState = 'accepted')
|
||||
{
|
||||
$aItemsPerPage = array(25, 50, 100, 200);
|
||||
$iDefaultPerPage = 25;
|
||||
return array($aItemsPerPage, $iDefaultPerPage);
|
||||
}
|
||||
|
||||
function display()
|
||||
{
|
||||
$oTable = new Table();
|
||||
$oTable->SetAlign("center");
|
||||
$oTable->SetClass("color0");
|
||||
$oTable->SetCellPadding(2);
|
||||
|
||||
$oHeaderRow = $this->objectGetHeader();
|
||||
$oHeaderRow->SetClass("color4");
|
||||
$oTable->AddRow($oHeaderRow);
|
||||
|
||||
$oDataRow = $this->objectGetTableRow();
|
||||
$oDataRow->GetTableRow()->SetClass("color0");
|
||||
$oTable->AddRow($oDataRow);
|
||||
|
||||
echo $oTable->GetString();
|
||||
}
|
||||
|
||||
function objectHideReject()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// NOTE: we don't have any editing support for this entry at this time
|
||||
// so output the entry and a field to identify the bug id
|
||||
function outputEditor()
|
||||
{
|
||||
$this->display();
|
||||
echo '<input type="hidden" name="iBuglinkId" value="'.$this->iBug_id.'">';
|
||||
echo '<input type="hidden" name="iVersionId" value="'.$this->iVersionId.'">';
|
||||
}
|
||||
|
||||
function getOutputEditorValues($aClean)
|
||||
{
|
||||
$this->iBug_id = $aClean['iBuglinkId'];
|
||||
|
||||
if($aClean['iVersionId'])
|
||||
$this->iVersionId = $aClean['iVersionId'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Bug Link functions that are not part of the class
|
||||
*/
|
||||
|
||||
function view_version_bugs($iVersionId = null, $aBuglinkIds)
|
||||
{
|
||||
global $aClean;
|
||||
|
||||
$bCanEdit = FALSE;
|
||||
$oVersion = new Version($iVersionId);
|
||||
|
||||
// Security, if we are an administrator or a maintainer, we can remove or ok links.
|
||||
if(($_SESSION['current']->hasPriv("admin") ||
|
||||
$_SESSION['current']->isMaintainer($oVersion->iVersionId) ||
|
||||
$_SESSION['current']->isSuperMaintainer($oVersion->iAppId)))
|
||||
{
|
||||
$bCanEdit = TRUE;
|
||||
}
|
||||
|
||||
//start format table
|
||||
if($_SESSION['current']->isLoggedIn())
|
||||
{
|
||||
echo "<form method=post action='".APPDB_ROOT."objectManager.php'>\n";
|
||||
}
|
||||
echo html_frame_start("Known bugs","98%",'',0);
|
||||
echo "<table width=\"100%\" border=\"0\" cellpadding=\"3\" cellspacing=\"1\">\n\n";
|
||||
echo "<tr class=color4>\n";
|
||||
echo " <td align=center width=\"80\">Bug #</td>\n";
|
||||
echo " <td>Description</td>\n";
|
||||
echo " <td align=center width=\"80\">Status</td>\n";
|
||||
echo " <td align=center width=\"80\">Resolution</td>\n";
|
||||
echo " <td align=center width=\"80\">Other apps affected</td>\n";
|
||||
|
||||
if($bCanEdit == true)
|
||||
{
|
||||
echo " <td align=center width=\"80\">Delete</td>\n";
|
||||
echo " <td align=center width=\"80\">Checked</td>\n";
|
||||
}
|
||||
echo "</tr>\n\n";
|
||||
|
||||
$c = 0;
|
||||
foreach($aBuglinkIds as $iBuglinkId)
|
||||
{
|
||||
$oBuglink = new Bug($iBuglinkId);
|
||||
|
||||
if (
|
||||
(!isset($aClean['sAllBugs']) && $oBuglink->isOpen() )
|
||||
||
|
||||
isset($aClean['sAllBugs'])
|
||||
)
|
||||
{
|
||||
// set row color
|
||||
$bgcolor = ($c % 2 == 0) ? "color0" : "color1";
|
||||
|
||||
//display row
|
||||
echo "<tr class=$bgcolor>\n";
|
||||
echo "<td align=center><a href='".BUGZILLA_ROOT."show_bug.cgi?id=".$oBuglink->iBug_id."'>".$oBuglink->iBug_id."</a></td>\n";
|
||||
echo "<td>".$oBuglink->sShort_desc."</td>\n";
|
||||
echo "<td align=center>".$oBuglink->sBug_status."</td>","\n";
|
||||
echo "<td align=center>".$oBuglink->sResolution."</td>","\n";
|
||||
echo "<td align=center><a href='viewbugs.php?bug_id=".$oBuglink->iBug_id."'>View</a></td>\n";
|
||||
|
||||
|
||||
if($bCanEdit == true)
|
||||
{
|
||||
$oM = new objectManager("bug");
|
||||
$oM->setReturnTo($oVersion->objectMakeUrl());
|
||||
echo "<td align=center>[<a href='".$oM->makeUrl("delete", $oBuglink->iLinkId)."&sSubmit=delete'>delete</a>]</td>\n";
|
||||
if ($oBuglink->bQueued)
|
||||
{
|
||||
echo "<td align=center>[<a href='".$oM->makeUrl("edit", $oBuglink->iLinkId)."&sSubmit=Submit&bIsQueue=true'>OK</a>]</td>\n";
|
||||
} else
|
||||
{
|
||||
echo "<td align=center>Yes</td>\n";
|
||||
}
|
||||
|
||||
}
|
||||
echo "</tr>\n\n";
|
||||
|
||||
|
||||
$c++;
|
||||
}
|
||||
}
|
||||
|
||||
if($_SESSION['current']->isLoggedIn())
|
||||
{
|
||||
echo '<input type="hidden" name="iVersionId" value="'.$iVersionId.'">',"\n";
|
||||
echo '<tr class=color3><td align=center>',"\n";
|
||||
$sBuglinkId = isset($aClean['buglinkId']) ? $aClean['buglinkId'] : '';
|
||||
echo '<input type="text" name="iBuglinkId" value="'.$sBuglinkId.'" size="8"></td>',"\n";
|
||||
echo '<input type="hidden" name="sSubmit" value="Submit">',"\n";
|
||||
echo '<input type="hidden" name="sClass" value="bug">',"\n";
|
||||
echo '<input type="hidden" name="sReturnTo" value="'.$oVersion->objectMakeUrl().'">',"\n";
|
||||
echo '<td><input type="submit" name="sSub" value="Submit a new bug link."></td>',"\n";
|
||||
echo '<td colspan=6></td></tr></form>',"\n";
|
||||
}
|
||||
echo '</table>',"\n";
|
||||
|
||||
// show only open link
|
||||
if ( isset( $aClean['sAllBugs'] ) )
|
||||
{
|
||||
$sURL = str_replace( '&sAllBugs', '', $_SERVER['REQUEST_URI'] );
|
||||
$sLink = '<a href="' . htmlentities($sURL) . '">Show open bugs</a>';
|
||||
}
|
||||
// show all link
|
||||
else
|
||||
{
|
||||
$sURL = $_SERVER['REQUEST_URI'] . '&sAllBugs';
|
||||
$sLink = '<a href="' . htmlentities($sURL) . '">Show all bugs</a>';
|
||||
}
|
||||
|
||||
echo '<div style="text-align:right;">' . $sLink .'</div>';
|
||||
echo html_frame_end();
|
||||
}
|
||||
|
||||
?>
|
||||
576
include/category.php
Normal file
576
include/category.php
Normal file
@@ -0,0 +1,576 @@
|
||||
<?php
|
||||
/***************************************************/
|
||||
/* this class represents a category + its children */
|
||||
/***************************************************/
|
||||
|
||||
/**
|
||||
* Category class for handling categories.
|
||||
*/
|
||||
class Category {
|
||||
var $iCatId;
|
||||
var $iParentId;
|
||||
var $sName;
|
||||
var $sDescription;
|
||||
var $aApplicationsIds; // an array that contains the appId of every application linked to this category
|
||||
var $aSubcatsIds; // an array that contains the appId of every application linked to this category
|
||||
|
||||
|
||||
/**
|
||||
* constructor, fetches the data.
|
||||
*/
|
||||
function Category($iCatId = null)
|
||||
{
|
||||
// we are working on an existing category
|
||||
if($iCatId=="0" || $iCatId)
|
||||
{
|
||||
/*
|
||||
* We fetch the data related to this vendor.
|
||||
*/
|
||||
$sQuery = "SELECT *
|
||||
FROM appCategory
|
||||
WHERE catId = '?' ORDER BY catName;";
|
||||
if($hResult = query_parameters($sQuery, $iCatId))
|
||||
{
|
||||
$oRow = query_fetch_object($hResult);
|
||||
if($oRow)
|
||||
{
|
||||
$this->iCatId = $iCatId;
|
||||
$this->iParentId = $oRow->catParent;
|
||||
$this->sName = $oRow->catName;
|
||||
$this->sDescription = $oRow->catDescription;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We fetch applicationsIds.
|
||||
*/
|
||||
$sQuery = "SELECT appId
|
||||
FROM appFamily
|
||||
WHERE catId = '?'
|
||||
AND state = 'accepted' ORDER BY appName";
|
||||
if($hResult = query_parameters($sQuery, $iCatId))
|
||||
{
|
||||
while($oRow = query_fetch_object($hResult))
|
||||
{
|
||||
$this->aApplicationsIds[] = $oRow->appId;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We fetch subcatIds.
|
||||
*/
|
||||
$sQuery = "SELECT catId
|
||||
FROM appCategory
|
||||
WHERE catParent = '?' ORDER BY catName;";
|
||||
if($hResult = query_parameters($sQuery, $iCatId))
|
||||
{
|
||||
while($oRow = query_fetch_object($hResult))
|
||||
{
|
||||
$this->aSubcatsIds[] = $oRow->catId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new category.
|
||||
*/
|
||||
function create()
|
||||
{
|
||||
$hResult = query_parameters("INSERT INTO appCategory (catName, catDescription, catParent) ".
|
||||
"VALUES('?', '?', '?')",
|
||||
$this->sName, $this->sDescription, $this->iParentId);
|
||||
if($hResult)
|
||||
{
|
||||
$this->iCatId = query_appdb_insert_id();
|
||||
$this->category($this->iCatId);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update category.
|
||||
* Returns true on success and false on failure.
|
||||
*/
|
||||
function update()
|
||||
{
|
||||
if(!query_parameters("UPDATE appCategory SET catName = '?', catDescription = '?', catParent = '?' WHERE catId = '?'",
|
||||
$this->sName, $this->sDescription, $this->iParentId, $this->iCatId))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deletes the category from the database.
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
if(!$this->canEdit())
|
||||
return false;
|
||||
|
||||
if(sizeof($this->aApplicationsIds)>0)
|
||||
return FALSE;
|
||||
|
||||
$sQuery = "DELETE FROM appCategory
|
||||
WHERE catId = '?'
|
||||
LIMIT 1";
|
||||
query_parameters($sQuery, $this->iCatId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return new mailOptions();
|
||||
}
|
||||
|
||||
function objectGetChildren()
|
||||
{
|
||||
/* We don't have any (or we do, sort of, but we don't use them for anything at the moment) */
|
||||
return array();
|
||||
}
|
||||
|
||||
/* Get a category's subcategory objects. Names are indented according
|
||||
to subcategory level */
|
||||
function getSubCatList($iLevel = 0)
|
||||
{
|
||||
$aOut = array();
|
||||
$iId = $this->iCatId ? $this->iCatId : 0;
|
||||
|
||||
$sIndent = '';
|
||||
for($i = 0; $i < $iLevel; $i++)
|
||||
$sIndent .= ' ';
|
||||
|
||||
$hResult = query_parameters("SELECT * FROM appCategory WHERE catParent = '?'
|
||||
ORDER BY catName", $iId);
|
||||
|
||||
while($oRow = mysql_fetch_object($hResult))
|
||||
{
|
||||
$oCat = new category($oRow->catId);
|
||||
$oCat->sName = $sIndent.$oCat->sName;
|
||||
$aOut[] = $oCat;
|
||||
$aOut = array_merge($aOut, $oCat->getSubCatList($iLevel + 1));
|
||||
}
|
||||
return $aOut;
|
||||
}
|
||||
|
||||
/* Get all category objects, ordered and with category names indented
|
||||
according to subcategory level.
|
||||
Optionally includes the 'Main' top category. */
|
||||
static function getOrderedList($bIncludeMain = false)
|
||||
{
|
||||
$oCat = new category();
|
||||
|
||||
if(!$bIncludeMain)
|
||||
return $oCat->getSubCatList(0);
|
||||
|
||||
$oCat->sName = 'Main';
|
||||
$aCats = array($oCat);
|
||||
$aCats = array_merge($aCats, $oCat->getSubCatList(1));
|
||||
|
||||
return $aCats;
|
||||
}
|
||||
|
||||
/* Returns an SQL statement that will match items in the current category
|
||||
and all sub-categories */
|
||||
public function getSqlQueryPart()
|
||||
{
|
||||
$sRet = '';
|
||||
$aSubCats = $this->getSubCatList();
|
||||
$sRet .= " ( catId = '{$this->iCatId}' ";
|
||||
foreach($aSubCats as $oCat)
|
||||
{
|
||||
$iCatId = $oCat->objectGetId();
|
||||
$sRet .= " OR catId = '$iCatId' ";
|
||||
}
|
||||
$sRet .= ") ";
|
||||
|
||||
return $sRet;
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
/* We don't send notification mails */
|
||||
return array(null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a path like:
|
||||
*
|
||||
* { ROOT, Games, Simulation }
|
||||
*/
|
||||
function getCategoryPath()
|
||||
{
|
||||
$aPath = array();
|
||||
$iCatId = $this->iCatId;
|
||||
|
||||
/* loop, working up through categories until we have no parent */
|
||||
while($iCatId != 0)
|
||||
{
|
||||
$hResult = query_parameters("SELECT catName, catId, catParent FROM appCategory WHERE catId = '?'",
|
||||
$iCatId);
|
||||
if(!$hResult || query_num_rows($hResult) != 1)
|
||||
break;
|
||||
$oCatRow = query_fetch_object($hResult);
|
||||
$aPath[] = array($oCatRow->catId, $oCatRow->catName);
|
||||
$iCatId = $oCatRow->catParent;
|
||||
}
|
||||
$aPath[] = array(0, "ROOT");
|
||||
return array_reverse($aPath);
|
||||
}
|
||||
|
||||
/* return the total number of applications in this category */
|
||||
function getApplicationCount($depth = null)
|
||||
{
|
||||
$MAX_DEPTH = 5;
|
||||
|
||||
if($depth)
|
||||
$depth++;
|
||||
else
|
||||
$depth = 0;
|
||||
|
||||
/* if we've reached our max depth, just return 0 and stop recursing */
|
||||
if($depth >= $MAX_DEPTH)
|
||||
return 0;
|
||||
|
||||
$totalApps = 0;
|
||||
|
||||
/* add on all apps in each category this category includes */
|
||||
if($this->aSubcatsIds)
|
||||
{
|
||||
while(list($i, $iSubcatId) = each($this->aSubcatsIds))
|
||||
{
|
||||
$subCat = new Category($iSubcatId);
|
||||
$totalApps += $subCat->getApplicationCount($depth);
|
||||
}
|
||||
}
|
||||
|
||||
$totalApps += sizeof($this->aApplicationsIds); /* add on the apps at this category level */
|
||||
|
||||
return $totalApps;
|
||||
}
|
||||
|
||||
/**
|
||||
* create the Category: line at the top of appdb pages$
|
||||
*/
|
||||
function make_cat_path($aPath, $iAppId = '', $iVersionId = '')
|
||||
{
|
||||
$sStr = "";
|
||||
$iCatCount = 0;
|
||||
while(list($iCatIdx, list($iCatId, $sName)) = each($aPath))
|
||||
{
|
||||
if($sName == "ROOT")
|
||||
$sCatname = "Main";
|
||||
else
|
||||
$sCatname = $sName;
|
||||
|
||||
if ($iCatCount > 0) $sStr .= " > ";
|
||||
$sStr .= html_ahref($sCatname,"objectManager.php?sClass=category&iId=$iCatId&sAction=view&sTitle=Browse+Applications");
|
||||
$iCatCount++;
|
||||
}
|
||||
|
||||
if($iAppId)
|
||||
{
|
||||
$oApp = new Application($iAppId);
|
||||
if($iVersionId)
|
||||
{
|
||||
$oVersion = new Version($iVersionId);
|
||||
$sStr .= " > ".$oApp->objectMakeLink();
|
||||
$sStr .= " > ".$oVersion->sName;
|
||||
} else
|
||||
{
|
||||
$sStr .= " > ".$oApp->sName;
|
||||
}
|
||||
}
|
||||
|
||||
return $sStr;
|
||||
}
|
||||
|
||||
public function objectGetState()
|
||||
{
|
||||
// We currenly don't queue categories
|
||||
return 'accepted';
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->iCatId;
|
||||
}
|
||||
|
||||
public function objectMakeLink()
|
||||
{
|
||||
return '<a href="'.$this->objectMakeUrl()."\">{$this->sName}</a>'";
|
||||
}
|
||||
|
||||
public function objectMakeUrl()
|
||||
{
|
||||
return BASE."objectManager.php?sClass=category&sAction=view&iId={$this->iCatId}&sTitle=Browse+Applications";
|
||||
}
|
||||
|
||||
public function objectAllowNullId($sAction)
|
||||
{
|
||||
switch($sAction)
|
||||
{
|
||||
case 'view':
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function objectGetSubmitterId()
|
||||
{
|
||||
/* We don't log that */
|
||||
return 0;
|
||||
}
|
||||
|
||||
function objectGetCustomVars($sAction)
|
||||
{
|
||||
switch($sAction)
|
||||
{
|
||||
case 'add':
|
||||
return array('iParentId');
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function outputEditor($aValues = null)
|
||||
{
|
||||
$aCategories = category::getOrderedList(true);
|
||||
$aCatNames = array();
|
||||
$aCatIds = array();
|
||||
|
||||
$iParentId = $this->iParentId;
|
||||
if(!$iParentId && $aValues)
|
||||
$iParentId = getInput('iParentId', $aValues);
|
||||
|
||||
foreach($aCategories as $oCategory)
|
||||
{
|
||||
$aCatNames[] = $oCategory->sName;
|
||||
$aCatIds[] = $oCategory->objectGetId();
|
||||
}
|
||||
|
||||
echo "<table border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"2\">
|
||||
<tr>
|
||||
<td width=\"15%\" class=\"box-label\"><b>Category name</b></td>
|
||||
<td class=\"box-body\">
|
||||
<input type=\"text\" size=\"50\" name=\"sName\" value=\"".$this->sName."\">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width=\"15%\" class=\"box-label\"><b>Description</b></td>
|
||||
<td class=\"box-body\">
|
||||
<input type=\"text\" size=\"50\" name=\"sDescription\" value=\"".$this->sDescription."\">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width=\"15%\" class=\"box-label\"><b>Parent</b></td>
|
||||
<td class=\"box-body\">
|
||||
".html_select("iParentId",$aCatIds,$iParentId, $aCatNames)."
|
||||
</td>
|
||||
</tr>
|
||||
</table>";
|
||||
}
|
||||
|
||||
function allowAnonymousSubmissions()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function getOutputEditorValues($aClean)
|
||||
{
|
||||
$this->sName = $aClean['sName'];
|
||||
$this->iParentId = $aClean['iParentId'];
|
||||
$this->sDescription = $aClean['sDescription'];
|
||||
}
|
||||
|
||||
function mustBeQueued()
|
||||
{
|
||||
return $_SESSION['current']->hasPriv('admin');
|
||||
}
|
||||
|
||||
function canEdit()
|
||||
{
|
||||
return $_SESSION['current']->hasPriv('admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* display the full path of the Category we are looking at
|
||||
*/
|
||||
function displayPath($appId, $versionId = '')
|
||||
{
|
||||
$sCatFullPath = Category::make_cat_path($this->getCategoryPath(), $appId, $versionId);
|
||||
echo html_frame_start("",'98%','',2);
|
||||
echo "<p><b>Category: ". $sCatFullPath ."</b><br>\n";
|
||||
echo html_frame_end();
|
||||
}
|
||||
|
||||
public function display()
|
||||
{
|
||||
// list sub categories
|
||||
$sCatFullPath = Category::make_cat_path($this->getCategoryPath());
|
||||
$aSubs = $this->aSubcatsIds;
|
||||
|
||||
echo "<div class='default_container'>\n";
|
||||
|
||||
// Allow editing categories
|
||||
if($this->canEdit())
|
||||
{
|
||||
$oM = new objectManager('category', '', $this->iCatId);
|
||||
$oM->setReturnTo($this->objectMakeUrl());
|
||||
echo "<p>\n";
|
||||
echo '<a href="'.$oM->makeUrl('add', null, 'Add Category')."&iParentId={$this->iCatId}\">Add</a>";;
|
||||
if($this->iCatId) // We can't edit the 'Main' category
|
||||
{
|
||||
echo ' ';
|
||||
echo '<a href="'.$oM->makeUrl('edit', $this->iCatId, 'Edit Category').'">Edit</a>';
|
||||
echo ' ';
|
||||
echo '<a href="'.$oM->makeUrl('delete', $this->iCatId, 'Delete Category').'">Delete</a>';
|
||||
}
|
||||
echo "</p>\n";
|
||||
}
|
||||
|
||||
// Output sub-categories
|
||||
if($aSubs)
|
||||
{
|
||||
echo html_frame_start("",'98%','',2);
|
||||
echo "<p><b>Category: ". $sCatFullPath ."</b><br>\n";
|
||||
echo html_frame_end();
|
||||
|
||||
echo html_frame_start("","98%","",0);
|
||||
|
||||
$oTable = new Table();
|
||||
$oTable->SetWidth("100%");
|
||||
$oTable->SetBorder(0);
|
||||
$oTable->SetCellPadding(3);
|
||||
$oTable->SetCellSpacing(1);
|
||||
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->SetClass("color4");
|
||||
$oTableRow->AddTextCell("Sub Category");
|
||||
$oTableRow->AddTextCell("Description");
|
||||
$oTableRow->AddTextCell("No. Apps");
|
||||
$oTable->SetHeader($oTableRow);
|
||||
|
||||
while(list($i,$iSubcatId) = each($aSubs))
|
||||
{
|
||||
$oSubCat= new Category($iSubcatId);
|
||||
|
||||
//set row color
|
||||
$sColor = ($i % 2) ? "color0" : "color1";
|
||||
|
||||
$oTableRowHighlight = GetStandardRowHighlight($i);
|
||||
|
||||
$sUrl = $oSubCat->objectMakeUrl();
|
||||
|
||||
$oTableRowClick = new TableRowClick($sUrl);
|
||||
$oTableRowClick->SetHighlight($oTableRowHighlight);
|
||||
|
||||
//get number of apps in this sub-category
|
||||
$iAppcount = $oSubCat->getApplicationCount();
|
||||
|
||||
//format desc
|
||||
$sDesc = substr(stripslashes($oSubCat->sDescription),0,70);
|
||||
|
||||
//display row
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->SetClass($sColor);
|
||||
$oTableRow->SetRowClick($oTableRowClick);
|
||||
|
||||
$oTableCell = new TableCell($oSubCat->sName);
|
||||
$oTableCell->SetCellLink($sUrl);
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
$oTableRow->AddTextCell("$sDesc ");
|
||||
$oTableRow->AddTextCell("$iAppcount ");
|
||||
|
||||
$oTable->AddRow($oTableRow);
|
||||
}
|
||||
|
||||
// output the table
|
||||
echo $oTable->GetString();
|
||||
|
||||
echo html_frame_end( count($aSubs) . ' categories');
|
||||
}
|
||||
|
||||
|
||||
// list applications in this category
|
||||
$aApps = $this->aApplicationsIds;
|
||||
if($aApps)
|
||||
{
|
||||
echo html_frame_start("",'98%','',2);
|
||||
echo "<p><b>Category: ". $sCatFullPath ."</b><br>\n";
|
||||
echo html_frame_end();
|
||||
|
||||
echo html_frame_start("","98%","",0);
|
||||
|
||||
$oTable = new Table();
|
||||
$oTable->SetWidth("100%");
|
||||
$oTable->SetBorder(0);
|
||||
$oTable->SetCellPadding(3);
|
||||
$oTable->SetCellSpacing(1);
|
||||
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->SetClass("color4");
|
||||
$oTableRow->AddTextCell("Application name");
|
||||
$oTableRow->AddTextCell("Description");
|
||||
$oTableRow->AddTextCell("No. Versions");
|
||||
|
||||
$oTable->SetHeader($oTableRow);
|
||||
|
||||
while(list($i, $iAppId) = each($aApps))
|
||||
{
|
||||
$oApp = new Application($iAppId);
|
||||
|
||||
//set row color
|
||||
$sColor = ($i % 2) ? "color0" : "color1";
|
||||
|
||||
$oTableRowHighlight = GetStandardRowHighlight($i);
|
||||
|
||||
$sUrl = $oApp->objectMakeUrl();
|
||||
|
||||
$oTableRowClick = new TableRowClick($sUrl);
|
||||
$oTableRowClick->SetHighlight($oTableRowHighlight);
|
||||
|
||||
//format desc
|
||||
$sDesc = util_trim_description($oApp->sDescription);
|
||||
|
||||
//display row
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->SetRowClick($oTableRowClick);
|
||||
$oTableRow->SetClass($sColor);
|
||||
$oTableRow->AddTextCell($oApp->objectMakeLink());
|
||||
$oTableRow->AddTextCell("$sDesc ");
|
||||
$oTableRow->AddTextCell(sizeof($oApp->aVersionsIds));
|
||||
|
||||
$oTable->AddRow($oTableRow);
|
||||
}
|
||||
|
||||
// output table
|
||||
echo $oTable->GetString();
|
||||
|
||||
echo html_frame_end( count($aApps) . " applications in this category");
|
||||
}
|
||||
|
||||
// Show a message if this category is empty
|
||||
if(!$aApps && !$aSubs)
|
||||
{
|
||||
echo html_frame_start("",'98%','',2);
|
||||
echo "<p><b>Category: ". $sCatFullPath ."</b><br>\n";
|
||||
echo html_frame_end();
|
||||
|
||||
echo html_frame_start('','90%','',2);
|
||||
echo 'This category has no sub-categories or applications';
|
||||
echo html_frame_end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
796
include/comment.php
Normal file
796
include/comment.php
Normal file
@@ -0,0 +1,796 @@
|
||||
<?php
|
||||
/***************************************/
|
||||
/* comment class and related functions */
|
||||
/***************************************/
|
||||
require_once(BASE."include/user.php");
|
||||
|
||||
/**
|
||||
* Comment class for handling comments
|
||||
*/
|
||||
class Comment {
|
||||
var $iCommentId;
|
||||
|
||||
// variables necessary for creating a comment
|
||||
var $iParentId;
|
||||
var $sSubject;
|
||||
var $sBody;
|
||||
var $iVersionId;
|
||||
|
||||
|
||||
var $iAppId;
|
||||
var $sDateCreated;
|
||||
var $sHostname;
|
||||
var $oOwner;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* If $iCommentId is provided, fetches comment.
|
||||
*/
|
||||
function Comment($iCommentId = null, $oRow = null)
|
||||
{
|
||||
if(!$iCommentId && !$oRow)
|
||||
return;
|
||||
|
||||
if(!$oRow)
|
||||
{
|
||||
$sQuery = "SELECT appComments.*, appVersion.appId AS appId
|
||||
FROM appComments, appVersion
|
||||
WHERE appComments.versionId = appVersion.versionId
|
||||
AND commentId = '?'";
|
||||
$hResult = query_parameters($sQuery, $iCommentId);
|
||||
$oRow = query_fetch_object($hResult);
|
||||
}
|
||||
|
||||
if($oRow)
|
||||
{
|
||||
$this->iCommentId = $oRow->commentId;
|
||||
$this->iParentId = $oRow->parentId;
|
||||
|
||||
$oVersion = new version($this->iVersionId);
|
||||
$this->iAppId = $oVersion->iAppId;
|
||||
|
||||
$this->iVersionId = $oRow->versionId;
|
||||
$this->sSubject = $oRow->subject;
|
||||
$this->sBody = $oRow->body;
|
||||
$this->sDateCreated = $oRow->time;
|
||||
$this->sHostname = $oRow->hostname;
|
||||
$this->oOwner = new User($oRow->userId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Creates a new comment.
|
||||
* Informs interested people about the creation.
|
||||
* Returns true on success, false on failure
|
||||
*/
|
||||
function create()
|
||||
{
|
||||
$hResult = query_parameters("INSERT INTO appComments
|
||||
(parentId, versionId, subject, ".
|
||||
"body, userId, time, hostname)
|
||||
VALUES ('?', '?', '?', '?', '?', ?, '?')",
|
||||
$this->iParentId, $this->iVersionId,
|
||||
$this->sSubject, $this->sBody,
|
||||
$_SESSION['current']->iUserId,
|
||||
"NOW()", get_remote());
|
||||
|
||||
if($hResult)
|
||||
{
|
||||
$this->comment(query_appdb_insert_id());
|
||||
$sEmail = User::get_notify_email_address_list($this->iAppId, $this->iVersionId);
|
||||
$sEmail .= $this->oOwner->sEmail." ";
|
||||
|
||||
// fetches e-mails from parent comments, all parents are notified that a
|
||||
// comment was added to the thread
|
||||
$iParentId = $this->iParentId;
|
||||
while($iParentId)
|
||||
{
|
||||
$oParent = new Comment($iParentId);
|
||||
$sEmail .= $oParent->oOwner->sEmail." ";
|
||||
$iParentId = $oParent->iParentId;
|
||||
}
|
||||
if($sEmail)
|
||||
{
|
||||
$aEmailArray = explode(" ", $sEmail); /* break the long email string into parts by spaces */
|
||||
$aEmailArray = array_unique($aEmailArray); /* remove duplicates */
|
||||
|
||||
/* build the single string of all emails up */
|
||||
$sEmail = "";
|
||||
foreach($aEmailArray as $key=>$value)
|
||||
{
|
||||
$sEmail.="$value ";
|
||||
}
|
||||
|
||||
$sSubject = "Comment for '".Application::lookup_name($this->iAppId)." ".Version::lookup_name($this->iVersionId)."' added by ".$_SESSION['current']->sRealname;
|
||||
$sMsg = "To reply to this email please use the link provided below.\n";
|
||||
$sMsg .= "DO NOT reply via your email client as it will not reach the person who wrote the comment\n";
|
||||
$sMsg .= $this->objectMakeUrl()."\n";
|
||||
$sMsg .= "\n";
|
||||
$sMsg .= "Subject: ".$this->sSubject."\r\n";
|
||||
$sMsg .= "\n";
|
||||
$sMsg .= $this->sBody."\r\n";
|
||||
mail_appdb($sEmail, $sSubject ,$sMsg);
|
||||
}
|
||||
addmsg("Comment created.", "green");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
addmsg("Error while creating a new comment", "red");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update comment.
|
||||
* FIXME: Informs interested people about the modification.
|
||||
* Returns true on success and false on failure.
|
||||
*/
|
||||
function update($sSubject=null, $sBody=null, $iParentId=null, $iVersionId=null)
|
||||
{
|
||||
$oComment = new comment($this->iCommentId);
|
||||
|
||||
if(!$iVersionId && $this->iVersionId != $oComment->iVersionId)
|
||||
$iVersionId = $this->iVersionId;
|
||||
if(!$iParentId && $this->iParentId != $oComment->iParentId)
|
||||
$iParentId = $this->iParentId;
|
||||
|
||||
if ($iParentId)
|
||||
{
|
||||
if (!query_parameters("UPDATE appComments SET parentId = '?' WHERE commentId = '?'",
|
||||
$iParentId, $this->iCommentId))
|
||||
return false;
|
||||
$this->iParentId = $iParentId;
|
||||
}
|
||||
|
||||
if ($iVersionId)
|
||||
{
|
||||
if (!query_parameters("UPDATE appComments SET versionId = '?' WHERE commentId = '?'",
|
||||
$iVersionId, $this->iCommentId))
|
||||
return false;
|
||||
$this->iVersionId = $iVersionId;
|
||||
// FIXME: we need to refetch $this->iAppId.
|
||||
}
|
||||
|
||||
if ($sSubject)
|
||||
{
|
||||
if (!query_parameters("UPDATE appComments SET subject = '?' WHERE commentId = '?'",
|
||||
$sSubject, $this->iCommentId))
|
||||
return false;
|
||||
$this->sSubject = $sSubject;
|
||||
}
|
||||
|
||||
if ($sBody)
|
||||
{
|
||||
if (!query_parameters("UPDATE appComments SET body = '?' WHERE commentId = '?'",
|
||||
$sBody, $this->iCommentId))
|
||||
return false;
|
||||
$this->sBody = $sBody;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function purge()
|
||||
{
|
||||
return $this->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the current comment from the database.
|
||||
* Informs interested people about the deletion.
|
||||
* Returns true on success and false on failure.
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
$hResult = query_parameters("DELETE FROM appComments WHERE commentId = '?'", $this->iCommentId);
|
||||
if ($hResult)
|
||||
{
|
||||
$aChildren = $this->objectGetChildren();
|
||||
|
||||
foreach($aChildren as $oComment)
|
||||
$oComment->delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function get_comment_count_for_versionid($iVersionId)
|
||||
{
|
||||
$sQuery = "SELECT count(*) as cnt from appComments where versionId = '?'";
|
||||
$hResult = query_parameters($sQuery, $iVersionId);
|
||||
if(!$hResult) return 0;
|
||||
|
||||
$oRow = query_fetch_object($hResult);
|
||||
return $oRow->cnt;
|
||||
}
|
||||
|
||||
function getOutputEditorValues($aClean)
|
||||
{
|
||||
$this->sSubject = $aClean['sSubject'];
|
||||
$this->sBody = $aClean['sBody'];
|
||||
$this->iParentId = $aClean['iThread'];
|
||||
|
||||
if($aClean['iVersionId'])
|
||||
$this->iVersionId = $aClean['iVersionId'];
|
||||
|
||||
if(!$this->oOwner)
|
||||
$this->oOwner = $_SESSION['current'];
|
||||
|
||||
if(!$this->sDateCreated)
|
||||
$this->sDateCreated = date("l F jS Y, H:i");
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the body of one comment.
|
||||
*/
|
||||
function view_comment_body($iCommentId)
|
||||
{
|
||||
$hResult = Comment::grab_comment($iCommentId);
|
||||
|
||||
if ($hResult)
|
||||
{
|
||||
$oRow = query_fetch_object($hResult);
|
||||
Comment::view_app_comment($oRow);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* display a single comment (in $oRow)
|
||||
*/
|
||||
function view_app_comment($oRow, $bShowAppName = false)
|
||||
{
|
||||
$oComment = new comment(null, $oRow);
|
||||
$oComment->output_comment($bShowAppName);
|
||||
}
|
||||
|
||||
private function output_comment($bShowAppName = false)
|
||||
{
|
||||
echo html_frame_start('','98%');
|
||||
echo '<table width="100%" border="0" cellpadding="2" cellspacing="1">',"\n";
|
||||
|
||||
// message header
|
||||
echo "<tr bgcolor=\"#E0E0E0\"><td><a name=Comment-".$this->iCommentId."></a>\n";
|
||||
echo " <b>".$this->sSubject."</b><br>\n";
|
||||
|
||||
if($bShowAppName)
|
||||
echo 'Application: ' . version::fullNameLink($this->iVersionId) . "<br>\n";
|
||||
|
||||
echo " by ".forum_lookup_user($this->oOwner->iUserId)." on ".$this->sDateCreated."<br>\n";
|
||||
echo "</td></tr><tr><td>\n";
|
||||
|
||||
// body
|
||||
echo htmlify_urls($this->sBody), "<br><br>\n";
|
||||
|
||||
$oVersion = new version($this->iVersionId);
|
||||
$oM = new objectManager("comment", "Post new comment");
|
||||
$oM->setReturnTo($oVersion->objectMakeUrl());
|
||||
// reply post buttons
|
||||
echo " [<a href=\"".$oM->makeUrl("add")."&iVersionId=$this->iVersionId\"><small>post new</small></a>] \n";
|
||||
echo " [<a href=\"".$oM->makeUrl("add")."&iVersionId=$this->iVersionId".
|
||||
"&iThread=$this->iCommentId\"><small>reply to this</small></a>] \n";
|
||||
|
||||
echo "</td></tr>\n";
|
||||
|
||||
// delete message button, for admins
|
||||
if ($this->canEdit())
|
||||
{
|
||||
echo "<tr>";
|
||||
echo "<td><form method=\"post\" name=\"sMessage\" action=\"".BASE."objectManager.php\"><input type=\"submit\" value=\"Delete\" class=\"button\">\n";
|
||||
echo "<input type=\"hidden\" name=\"iId\" value=\"$this->iCommentId\">";
|
||||
echo "<input type=\"hidden\" name=\"sClass\" value=\"comment\">";
|
||||
echo "<input type=\"hidden\" name=\"bQueued\" value=\"false\">";
|
||||
echo "<input type=\"hidden\" name=\"sAction\" value=\"delete\">";
|
||||
echo "<input type=\"hidden\" name=\"sTitle\" value=\"Delete comment\">";
|
||||
echo "<input type=\"hidden\" name=\"sReturnTo\" value=\"".$oVersion->objectMakeUrl()."\">";
|
||||
echo "</form>\n";
|
||||
echo "</td></tr>";
|
||||
}
|
||||
|
||||
echo "</table>\n";
|
||||
|
||||
echo html_frame_end();
|
||||
}
|
||||
|
||||
function display()
|
||||
{
|
||||
$this->output_comment();
|
||||
}
|
||||
|
||||
/**
|
||||
* grab single comment for commentId
|
||||
*/
|
||||
function grab_comment($iCommentId)
|
||||
{
|
||||
$iCommentId = query_escape_string($iCommentId);
|
||||
|
||||
if($iCommentId)
|
||||
{
|
||||
$sQuery = "SELECT from_unixtime(unix_timestamp(appComments.time), \"%W %M %D %Y, %k:%i\") as time, ".
|
||||
"appComments.commentId, appComments.parentId, appComments.versionId, appComments.userId, appComments.subject, appComments.body, appVersion.appId ".
|
||||
"FROM appComments, appVersion WHERE appComments.commentId = '$iCommentId'";
|
||||
|
||||
$hResult = query_appdb($sQuery);
|
||||
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* grab comments for appId / versionId
|
||||
* if parentId is not -1 only comments for that thread are returned
|
||||
*/
|
||||
function grab_comments($iVersionId, $iParentId = null)
|
||||
{
|
||||
/* TODO: remove the logging when we figure out where the */
|
||||
/* invalid $iVersionId is coming */
|
||||
/* if $iVersionId is invalid we should log where we came from */
|
||||
/* so we can debug the problem */
|
||||
if($iVersionId == "")
|
||||
{
|
||||
error_log::logBackTrace("logging iVersionId oddity");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* escape input so we can use query_appdb() without concern */
|
||||
$iVersionId = query_escape_string($iVersionId);
|
||||
$iParentId = query_escape_string($iParentId);
|
||||
|
||||
/* NOTE: we must compare against NULL here because $iParentId of 0 is valid */
|
||||
if($iParentId)
|
||||
{
|
||||
$sExtra = "AND parentId = '".$iParentId."' ";
|
||||
$sOrderingMode = "ASC";
|
||||
} else
|
||||
{
|
||||
$sExtra = "AND parentId = '0'";
|
||||
$sOrderingMode = "DESC";
|
||||
}
|
||||
|
||||
$sQuery = "SELECT from_unixtime(unix_timestamp(appComments.time), \"%W %M %D %Y, %k:%i\") as time, ".
|
||||
"appComments.commentId, appComments.parentId, appComments.versionId, appComments.userId, appComments.subject, appComments.body, appVersion.appId ".
|
||||
"FROM appComments, appVersion WHERE appComments.versionId = appVersion.versionId AND appComments.versionId = '".$iVersionId."' ".
|
||||
$sExtra.
|
||||
"ORDER BY appComments.time $sOrderingMode";
|
||||
|
||||
$hResult = query_appdb($sQuery);
|
||||
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* display nested comments
|
||||
* handle is a db result set
|
||||
*/
|
||||
function do_display_comments_nested($hResult)
|
||||
{
|
||||
while($oRow = query_fetch_object($hResult))
|
||||
{
|
||||
Comment::view_app_comment($oRow);
|
||||
$hResult2 = Comment::grab_comments($oRow->versionId, $oRow->commentId);
|
||||
if($hResult && query_num_rows($hResult2))
|
||||
{
|
||||
echo "<blockquote>\n";
|
||||
Comment::do_display_comments_nested($hResult2);
|
||||
echo "</blockquote>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function display_comments_nested($versionId, $threadId)
|
||||
{
|
||||
$hResult = Comment::grab_comments($versionId, $threadId);
|
||||
Comment::do_display_comments_nested($hResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the link to show the comment.
|
||||
*/
|
||||
function comment_link($oRow)
|
||||
{
|
||||
$sLink = "commentview.php?iAppId={$oRow->appId}&iVersionId=".
|
||||
"{$oRow->versionId}&iThreadId={$oRow->parentId}";
|
||||
|
||||
$sOnClick = "showComment('{$oRow->commentId}');";
|
||||
|
||||
/**
|
||||
* The return false line in the onClick is used to handle javascript
|
||||
* being disabled so we can fail gracefully to the old style.
|
||||
*/
|
||||
return "<li><a href=\"$sLink\" onclick=\"$sOnClick return false;\">$oRow->subject</a>".
|
||||
' by '.forum_lookup_user($oRow->userId)." on
|
||||
{$oRow->time}<div id=\"{$oRow->commentId}\"></div></li>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* display threaded comments
|
||||
* handle is a db result set
|
||||
*/
|
||||
function do_display_comments_threaded($hResult, $is_main)
|
||||
{
|
||||
if (!$is_main)
|
||||
echo "<ul>\n";
|
||||
|
||||
while ($oRow = query_fetch_object($hResult))
|
||||
{
|
||||
if ($is_main)
|
||||
{
|
||||
Comment::view_app_comment($oRow);
|
||||
} else
|
||||
{
|
||||
$link = Comment::comment_link($oRow);
|
||||
echo "$link";
|
||||
}
|
||||
|
||||
$hResult2 = Comment::grab_comments($oRow->versionId, $oRow->commentId);
|
||||
if ($hResult2 && query_num_rows($hResult2))
|
||||
{
|
||||
echo "<blockquote>\n";
|
||||
Comment::do_display_comments_threaded($hResult2, 0);
|
||||
echo "</blockquote>\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!$is_main)
|
||||
echo "</ul>\n";
|
||||
}
|
||||
|
||||
function canEdit()
|
||||
{
|
||||
if($_SESSION['current']->hasPriv("admin"))
|
||||
return TRUE;
|
||||
|
||||
$oVersion = new version($this->iVersionId);
|
||||
return $oVersion->canEdit();
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->iCommentId;
|
||||
}
|
||||
|
||||
function objectGetSubmitterId()
|
||||
{
|
||||
return $this->oOwner->iUserId;
|
||||
}
|
||||
|
||||
function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
$oOptions = new mailOptions();
|
||||
|
||||
if($sAction == "delete" && $bParentAction)
|
||||
$oOptions->bMailOnce = TRUE;
|
||||
|
||||
return $oOptions;
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
$sSubject = "";
|
||||
$sMessage = "";
|
||||
$aRecipients = null;
|
||||
|
||||
$oVersion = new version($this->iVersionId);
|
||||
$sVerName = version::fullName($this->iVersionId);
|
||||
|
||||
if($bMailSubmitter)
|
||||
{
|
||||
switch($sAction)
|
||||
{
|
||||
case "delete":
|
||||
if($bParentAction)
|
||||
{
|
||||
$sSubject = "Comments for $sVerName deleted";
|
||||
$sMessage = "Your comments for $sVerName were deleted because the";
|
||||
$sMessage .= "version was removed from the database";
|
||||
} else
|
||||
{
|
||||
$sSubject = "Comment for $sVerName deleted";
|
||||
$sMessage = $oVersion->objectMakeUrl()."\n";
|
||||
$sMessage .= "\n";
|
||||
$sMessage .= "This comment was made on ".substr($this->sDateCreated,0,10)."\n";
|
||||
$sMessage .= "\n";
|
||||
$sMessage .= "Subject: ".$this->sSubject."\r\n";
|
||||
$sMessage .= "\n";
|
||||
$sMessage .= $this->sBody."\r\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
switch($sAction)
|
||||
{
|
||||
case "delete":
|
||||
if(!$bParentAction)
|
||||
{
|
||||
$sSubject = "Comment for $sVerName deleted";
|
||||
$sMessage = $oVersion->objectMakeUrl()."\n";
|
||||
$sMessage .= "\n";
|
||||
$sMessage .= "This comment was made on ".substr($this->sDateCreated,0,10)." by ".$this->oOwner->sRealname."\n";
|
||||
$sMessage .= "\n";
|
||||
$sMessage .= "Subject: ".$this->sSubject."\r\n";
|
||||
$sMessage .= "\n";
|
||||
$sMessage .= $this->sBody."\r\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
$aRecipients = User::get_notify_email_address_list($this->iAppId, $this->iVersionId);
|
||||
}
|
||||
return array($sSubject, $sMessage, $aRecipients);
|
||||
}
|
||||
|
||||
public function objectGetParent($sClass = '')
|
||||
{
|
||||
switch($sClass)
|
||||
{
|
||||
case 'version':
|
||||
return new version($this->iVersionId);
|
||||
|
||||
case 'comment':
|
||||
return new comment($this->iParentId);
|
||||
}
|
||||
}
|
||||
|
||||
public function objectSetParent($iNewId, $sClass = '')
|
||||
{
|
||||
switch($sClass)
|
||||
{
|
||||
case 'version':
|
||||
$this->iVersionId = $iNewId;
|
||||
break;
|
||||
|
||||
case 'comment':
|
||||
$this->iParentId = $iNewId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function objectGetChildren($bIncludeDeleted = false)
|
||||
{
|
||||
$aObjects = array();
|
||||
$hResult = comment::grab_comments($this->iVersionId, $this->iCommentId);
|
||||
|
||||
if(!$hResult)
|
||||
return $aObjects;
|
||||
|
||||
while($oRow = mysql_fetch_object($hResult))
|
||||
{
|
||||
$oComment = new comment(null, $oRow);
|
||||
$aObjects += $oComment->objectGetChildren();
|
||||
$aObjects[] = $oComment;
|
||||
}
|
||||
|
||||
return $aObjects;
|
||||
}
|
||||
|
||||
function display_comments_threaded($versionId, $threadId = 0)
|
||||
{
|
||||
$hResult = Comment::grab_comments($versionId, $threadId);
|
||||
|
||||
Comment::do_display_comments_threaded($hResult, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* display flat comments
|
||||
*/
|
||||
function display_comments_flat($versionId)
|
||||
{
|
||||
$hResult = Comment::grab_comments($versionId);
|
||||
if ($hResult)
|
||||
{
|
||||
while($oRow = query_fetch_object($hResult))
|
||||
{
|
||||
Comment::view_app_comment($oRow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function view_app_comments($versionId, $threadId = 0)
|
||||
{
|
||||
global $aClean;
|
||||
|
||||
// count posts
|
||||
$hResult = query_parameters("SELECT commentId FROM appComments WHERE versionId = '?'", $versionId);
|
||||
$messageCount = query_num_rows($hResult);
|
||||
|
||||
//start comment format table
|
||||
echo html_frame_start("","98%",'',0);
|
||||
echo '<table width="100%" border="0" cellpadding="1" cellspacing="0">',"\n";
|
||||
|
||||
echo '<tr><td bgcolor="#C0C0C0" align="center"><table border="0" cellpadding="0" cellspacing="0"><tr bgcolor="#C0C0C0">',"\n";
|
||||
|
||||
$oVersion = new version($versionId);
|
||||
|
||||
// message display mode changer
|
||||
if ($_SESSION['current']->isLoggedIn())
|
||||
{
|
||||
// FIXME we need to change this so not logged in users can change current view as well
|
||||
if (!empty($aClean['sCmode']))
|
||||
$_SESSION['current']->setPref("comments:mode", $aClean['sCmode']);
|
||||
|
||||
$sel[$_SESSION['current']->getPref("comments:mode", "threaded")] = 'selected';
|
||||
echo '<td><form method="post" name="sMode" action="'.
|
||||
$oVersion->objectMakeUrl().'">',"\n";
|
||||
echo "<b>Application comments:</b> $messageCount total comments ";
|
||||
echo '<b>Mode:</b> <select name="sCmode" onchange="document.sMode.submit();">',"\n";
|
||||
echo ' <option value="flat" '.$sel['flat'].'>Flat</option>',"\n";
|
||||
echo ' <option value="threaded" '.$sel['threaded'].'>Threaded</option>',"\n";
|
||||
echo ' <option value="nested" '.$sel['nested'].'>Nested</option>',"\n";
|
||||
echo ' <option value="off" '.$sel['off'].'>No Comments</option>',"\n";
|
||||
echo '</select>',"\n";
|
||||
echo '</form></td>',"\n";
|
||||
}
|
||||
|
||||
// blank space
|
||||
echo '<td> </td>',"\n";
|
||||
|
||||
$oM = new objectManager("comment", "Add comment");
|
||||
$oM->setReturnTo($oVersion->objectMakeUrl());
|
||||
|
||||
// post new message button
|
||||
echo '<td><form method="post" name="sMessage" action="objectManager.php">';
|
||||
echo '<input type="hidden" name="sAction" value="add">';
|
||||
echo $oM->makeUrlFormData();
|
||||
echo '<input type="submit" value="Post new comment" class="button"> ',"\n";
|
||||
echo '<input type="hidden" name="iVersionId" value="'.$versionId.'"></form></td>',"\n";
|
||||
|
||||
//end comment format table
|
||||
echo '</tr></table></td></tr>',"\n";
|
||||
echo '</table>',"\n";
|
||||
echo html_frame_end();
|
||||
|
||||
if( $messageCount > 0 )
|
||||
{
|
||||
echo '<p align="center">The following comments are owned by whoever posted them. WineHQ is not responsible for what they say.</p>'."\n";
|
||||
}
|
||||
|
||||
//start comments
|
||||
echo '<table width="100%" border="0" cellpadding="2" cellspacing="1"><tr><td>',"\n";
|
||||
|
||||
//hide or display depending on pref
|
||||
if ($_SESSION['current']->isLoggedIn())
|
||||
$mode = $_SESSION['current']->getPref("comments:mode", "threaded");
|
||||
else
|
||||
$mode = "threaded"; /* default non-logged in users to threaded comment display mode */
|
||||
|
||||
if ( isset($aClean['sMode']) && $aClean['sMode']=="nested")
|
||||
$mode = "nested";
|
||||
|
||||
switch ($mode)
|
||||
{
|
||||
case "flat":
|
||||
Comment::display_comments_flat($versionId);
|
||||
break;
|
||||
case "nested":
|
||||
Comment::display_comments_nested($versionId, $threadId);
|
||||
break;
|
||||
case "threaded":
|
||||
Comment::display_comments_threaded($versionId, $threadId);
|
||||
break;
|
||||
}
|
||||
|
||||
echo '</td></tr></table>',"\n";
|
||||
}
|
||||
|
||||
function allowAnonymousSubmissions()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function objectGetCustomVars($sAction)
|
||||
{
|
||||
switch($sAction)
|
||||
{
|
||||
case "add":
|
||||
return array("iThread", "iVersionId");
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function checkOutputEditorInput($aClean)
|
||||
{
|
||||
$sErrors = "";
|
||||
|
||||
if(!$aClean['iVersionId'])
|
||||
$sErrors .= "<li>No version id defined; something may have gone wrong with the URL</li>\n";
|
||||
|
||||
if(!$aClean['sBody'])
|
||||
$sErrors .= "<li>You need to enter a message!</li>\n";
|
||||
|
||||
return $sErrors;
|
||||
}
|
||||
|
||||
function outputEditor($aClean)
|
||||
{
|
||||
$sMesTitle = "<b>Post New Comment</b>";
|
||||
|
||||
if($aClean['iThread'] > 0)
|
||||
{
|
||||
$hResult = query_parameters("SELECT * FROM appComments WHERE commentId = '?'",
|
||||
$aClean['iThread']);
|
||||
$oRow = query_fetch_object($hResult);
|
||||
if($oRow)
|
||||
{
|
||||
$sMesTitle = "<b>Replying To ...</b> $oRow->subject\n";
|
||||
echo html_frame_start($oRow->subject,500);
|
||||
echo htmlify_urls($oRow->body), "<br><br>\n";
|
||||
echo html_frame_end();
|
||||
|
||||
/* Set default reply subject */
|
||||
if(!$this->sSubject)
|
||||
{
|
||||
// Only add RE: once
|
||||
if(eregi("RE:", $oRow->subject))
|
||||
$this->sSubject = $oRow->subject;
|
||||
else
|
||||
$this->sSubject = "RE: ".$oRow->subject;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
echo "<p align=\"center\">Enter your comment in the box below.";
|
||||
echo "</br>Please do not paste large terminal or debug outputs here.</p>";
|
||||
|
||||
echo html_frame_start($sMesTitle,500,"",0);
|
||||
|
||||
echo '<table width="100%" border=0 cellpadding=0 cellspacing=1>',"\n";
|
||||
echo "<tr class=\"color0\"><td align=right><b>From:</b> </td>\n";
|
||||
echo " <td> ".$_SESSION['current']->sRealname."</td></tr>\n";
|
||||
echo "<tr class=\"color0\"><td align=right><b>Subject:</b> </td>\n";
|
||||
echo " <td> <input type=\"text\" size=\"35\" name=\"sSubject\" value=\"".$this->sSubject."\"> </td></tr>\n";
|
||||
echo "<tr class=\"color1\"><td colspan=2><textarea name=\"sBody\" cols=\"70\" rows=\"15\" wrap=\"virtual\">".$this->sBody."</textarea></td></tr>\n";
|
||||
|
||||
echo "</table>\n";
|
||||
|
||||
echo html_frame_end();
|
||||
|
||||
echo "<input type=\"hidden\" name=\"iThread\" value=\"".$aClean['iThread']."\">\n";
|
||||
echo "<input type=\"hidden\" name=\"iVersionId\" value=\"".$aClean['iVersionId']."\">\n";
|
||||
}
|
||||
|
||||
function objectShowPreview()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function objectMakeUrl()
|
||||
{
|
||||
$oVersion = new version($this->iVersionId);
|
||||
$sUrl = $oVersion->objectMakeUrl()."#Comment-".$this->iCommentId;
|
||||
return $sUrl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Comment functions that are not part of the class
|
||||
*/
|
||||
|
||||
function forum_lookup_user($iUserId)
|
||||
{
|
||||
if ($iUserId > 0)
|
||||
{
|
||||
$oUser = new User($iUserId);
|
||||
if($_SESSION['current']->isLoggedIn())
|
||||
$sMailto = '<a href="'.BASE.'contact.php?iRecipientId='.
|
||||
$oUser->iUserId.'">' .$oUser->sRealname . '</a>';
|
||||
else
|
||||
$sMailto = $oUser->sRealname;
|
||||
}
|
||||
if (!$iUserId || !$oUser->isLoggedIn())
|
||||
{
|
||||
$sMailto = 'Anonymous';
|
||||
}
|
||||
return $sMailto;
|
||||
}
|
||||
|
||||
?>
|
||||
57
include/config.php
Normal file
57
include/config.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/*************************/
|
||||
/* config file for AppDB */
|
||||
/*************************/
|
||||
|
||||
|
||||
/*
|
||||
* global params
|
||||
*/
|
||||
define("APPDB_DEBUG","1"); //turns debugging on/off
|
||||
define("APPDB_DONT_CLEAR_COOKIES_VAR","0"); // set to 1 if you have more than one Web application on the same virtual host
|
||||
define("APPDB_THUMBNAIL_WIDTH","128"); // width of the screenshot's thumbnails
|
||||
define("APPDB_THUMBNAIL_HEIGHT","128"); // height of the screenshot's thumbnails
|
||||
define("APPDB_SCREENSHOT_MAXWIDTH","1600"); // width of the screenshot's thumbnails
|
||||
define("APPDB_SCREENSHOT_MAXHEIGHT","1200"); // height of the screenshot's thumbnails
|
||||
define("APPDB_ROOT", "http://www.claunia.com/qemu3/appdb/"); // path to AppDB
|
||||
define("APPDB_OWNER","QEMU"); // with what product/company is this AppDB related ?
|
||||
define("APPDB_OWNER_URL","http://www.claunia.com/"); // website of this product/company
|
||||
define("APPDB_OWNER_EMAIL","natalia@claunia.com"); // e-mail of this product/company
|
||||
define("APPDB_SENDER_EMAIL","appdb-noreply@claunia.com"); // The e-mail address which appears as the sender in mails sent by the AppDB
|
||||
define("BUGZILLA_ROOT","http://bugs.claunia.com/"); // path to bugzilla
|
||||
|
||||
// AppDB developers: Use this define to disable email from being sent from the appdb during testing
|
||||
//if(!defined("DISABLE_EMAIL"))
|
||||
// define("DISABLE_EMAIL", true); // disable email, see mail_appdb() in include/mail.php
|
||||
|
||||
// AppDB developers: Use this define to print the contents of the e-mail instead
|
||||
// of sending it, useful for testing e-mail notifications. Has no effect if
|
||||
// DISABLE_EMAIL is set
|
||||
//if(!defined("PRINT_EMAIL"))
|
||||
// define("PRINT_EMAIL", true); // print email, see mail_appdb() in include/mail.php
|
||||
|
||||
// How old (days) a test report has to before it is judged to be aged
|
||||
define("TESTDATA_AGED_THRESHOLD", 175);
|
||||
|
||||
// Show versions from these branches even if they are not among the most recent ones
|
||||
// Separate by commas if there are more than one
|
||||
define("STABLE_BRANCHES", "0.8.0, 0.9.0, 0.10.0, 0.11.0");
|
||||
|
||||
/*
|
||||
* apps database info
|
||||
*/
|
||||
define("APPS_DBUSER","qemu");
|
||||
define("APPS_DBPASS","nsVxeFyvarqnQXfj");
|
||||
define("APPS_DBHOST","localhost");
|
||||
define("APPS_DB","apidb");
|
||||
|
||||
|
||||
/*
|
||||
* bugzilla database info
|
||||
*/
|
||||
define("BUGZILLA_DBUSER","qemu");
|
||||
define("BUGZILLA_DBPASS","nsVxeFyvarqnQXfj");
|
||||
define("BUGZILLA_DBHOST","localhost");
|
||||
define("BUGZILLA_DB","bugs");
|
||||
define("BUGZILLA_PRODUCT_ID","1");
|
||||
?>
|
||||
57
include/config.php.sample
Normal file
57
include/config.php.sample
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/*************************/
|
||||
/* config file for AppDB */
|
||||
/*************************/
|
||||
|
||||
|
||||
/*
|
||||
* global params
|
||||
*/
|
||||
define("APPDB_DEBUG","0"); //turns debugging on/off
|
||||
define("APPDB_DONT_CLEAR_COOKIES_VAR","0"); // set to 1 if you have more than one Web application on the same virtual host
|
||||
define("APPDB_THUMBNAIL_WIDTH","128"); // width of the screenshot's thumbnails
|
||||
define("APPDB_THUMBNAIL_HEIGHT","128"); // height of the screenshot's thumbnails
|
||||
define("APPDB_SCREENSHOT_MAXWIDTH","1024"); // width of the screenshot's thumbnails
|
||||
define("APPDB_SCREENSHOT_MAXHEIGHT","768"); // height of the screenshot's thumbnails
|
||||
define("APPDB_ROOT", "http://localhost/appdb/"); // path to AppDB
|
||||
define("APPDB_OWNER","WineHQ"); // with what product/company is this AppDB related ?
|
||||
define("APPDB_OWNER_URL","http://www.winehq.org/"); // website of this product/company
|
||||
define("APPDB_OWNER_EMAIL","appdb@winehq.org"); // e-mail of this product/company
|
||||
define("APPDB_SENDER_EMAIL","appdb-noreply@winehq.org"); // The e-mail address which appears as the sender in mails sent by the AppDB
|
||||
define("BUGZILLA_ROOT","http://bugs.winehq.org/"); // path to bugzilla
|
||||
|
||||
// AppDB developers: Use this define to disable email from being sent from the appdb during testing
|
||||
//if(!defined("DISABLE_EMAIL"))
|
||||
// define("DISABLE_EMAIL", true); // disable email, see mail_appdb() in include/mail.php
|
||||
|
||||
// AppDB developers: Use this define to print the contents of the e-mail instead
|
||||
// of sending it, useful for testing e-mail notifications. Has no effect if
|
||||
// DISABLE_EMAIL is set
|
||||
//if(!defined("PRINT_EMAIL"))
|
||||
// define("PRINT_EMAIL", true); // print email, see mail_appdb() in include/mail.php
|
||||
|
||||
// How old (days) a test report has to before it is judged to be aged
|
||||
define("TESTDATA_AGED_THRESHOLD", 175);
|
||||
|
||||
// Show versions from these branches even if they are not among the most recent ones
|
||||
// Separate by commas if there are more than one
|
||||
define("STABLE_BRANCHES", "1.0.");
|
||||
|
||||
/*
|
||||
* apps database info
|
||||
*/
|
||||
define("APPS_DBUSER","wineowner");
|
||||
define("APPS_DBPASS","lemonade");
|
||||
define("APPS_DBHOST","localhost");
|
||||
define("APPS_DB","apidb");
|
||||
|
||||
|
||||
/*
|
||||
* bugzilla database info
|
||||
*/
|
||||
define("BUGZILLA_DBUSER","root");
|
||||
define("BUGZILLA_DBPASS","");
|
||||
define("BUGZILLA_DBHOST","localhost");
|
||||
define("BUGZILLA_DB","bugs");
|
||||
define("BUGZILLA_PRODUCT_ID","1");
|
||||
?>
|
||||
233
include/db_filter.php
Normal file
233
include/db_filter.php
Normal file
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Classes for managing SQL filters (parts of SQL queries)
|
||||
*
|
||||
* Copyright 2008 BitSplash Software LLC
|
||||
* Copyright 2008 Alexander N. Sørnes <alex@thehandofagony.com>
|
||||
*
|
||||
*/
|
||||
|
||||
define('FILTER_LIKE', 1);
|
||||
define('FILTER_CONTAINS', 2); // Same as LIKE, but value is wrapped by wildcards
|
||||
define('FILTER_STARTS_WITH', 3); // Same as LIKE, but with a prepended wildcard
|
||||
define('FILTER_ENDS_WITH', 4); // Same as LIKE, but with an appended wildcard
|
||||
define('FILTER_EQUALS', 5);
|
||||
define('FILTER_GREATER_THAN', 6);
|
||||
define('FILTER_LESS_THAN', 7);
|
||||
define('FILTER_NOT_EQUALS', 8);
|
||||
define('FILTER_NOT_LIKE', 9);
|
||||
define('FILTER_OPTION_BOOL', 10);
|
||||
define('FILTER_OPTION_ENUM', 11);
|
||||
|
||||
/* A filter as part of an SQL query, such as something = 'somevalue' */
|
||||
class Filter
|
||||
{
|
||||
private $sColumn; // The table column the filter is for
|
||||
private $iType; // The type of filter, like EQUALS, LIKE
|
||||
private $sData; // What the column is to be compared to */
|
||||
|
||||
public function Filter($sColumn, $iType, $sData)
|
||||
{
|
||||
$this->sColumn = $sColumn;
|
||||
$this->iType = $iType;
|
||||
$this->sData = $sData;
|
||||
}
|
||||
|
||||
public function getColumn()
|
||||
{
|
||||
return $this->sColumn;
|
||||
}
|
||||
|
||||
public function setData($sData)
|
||||
{
|
||||
$this->sData = $sData;
|
||||
}
|
||||
|
||||
public function getOperatorId()
|
||||
{
|
||||
return $this->iType;
|
||||
}
|
||||
|
||||
public function getData()
|
||||
{
|
||||
return $this->sData;
|
||||
}
|
||||
|
||||
public function getOperator()
|
||||
{
|
||||
switch($this->iType)
|
||||
{
|
||||
case FILTER_LIKE:
|
||||
case FILTER_CONTAINS:
|
||||
case FILTER_STARTS_WITH:
|
||||
case FILTER_ENDS_WITH:
|
||||
return 'LIKE';
|
||||
case FILTER_EQUALS:
|
||||
return '=';
|
||||
case FILTER_LESS_THAN:
|
||||
return '<';
|
||||
case FILTER_GREATER_THAN:
|
||||
return '>';
|
||||
case FILTER_NOT_EQUALS:
|
||||
return '!=';
|
||||
case FILTER_NOT_LIKE:
|
||||
return 'NOT LIKE';
|
||||
|
||||
default:
|
||||
return 0; // error
|
||||
}
|
||||
}
|
||||
|
||||
/* Gets an SQL expression representing the current filter, for use in a WHERE clause */
|
||||
public function getExpression()
|
||||
{
|
||||
/* We let callers handle options themselves, so don't include them in the WHERE clause */
|
||||
if($this->isOption())
|
||||
return '';
|
||||
|
||||
$sData = $this->sData;
|
||||
|
||||
/* Add wildcards if required */
|
||||
switch($this->iType)
|
||||
{
|
||||
case FILTER_CONTAINS:
|
||||
$sData = "%$sData%";
|
||||
break;
|
||||
case FILTER_STARTS_WITH:
|
||||
$sData = "$sData%";
|
||||
break;
|
||||
case FILTER_ENDS_WITH:
|
||||
$sData = "%$sData";
|
||||
break;
|
||||
}
|
||||
|
||||
$sOp = $this->getOperator();
|
||||
|
||||
return "{$this->sColumn} $sOp '$sData'";
|
||||
}
|
||||
|
||||
public function IsOption()
|
||||
{
|
||||
switch($this->iType)
|
||||
{
|
||||
case FILTER_OPTION_BOOL:
|
||||
case FILTER_OPTION_ENUM:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Class handling tables where the user can filter contents */
|
||||
class FilterSet
|
||||
{
|
||||
private $aFilters; // Array of filters for this table
|
||||
|
||||
public function FilterSet($sTableName = '')
|
||||
{
|
||||
$this->aFilters = array();
|
||||
|
||||
if($sTableName)
|
||||
$this->loadTable($sTableName);
|
||||
}
|
||||
|
||||
public function loadTable($sTableName)
|
||||
{
|
||||
$sQuery = "SELECT * FROM $sTableName";
|
||||
$hResult = query_appdb($sQuery);
|
||||
|
||||
while($oRow = mysql_fetch_object($hResult))
|
||||
{
|
||||
$this->addFilterObject(new Filter($oRow->sColumn, $oRow->iType, $oRow->sData));
|
||||
}
|
||||
}
|
||||
|
||||
public function saveTable($sTableName)
|
||||
{
|
||||
$hResult = query_appdb("DROP TABLE IF EXISTS $sTableName");
|
||||
|
||||
$hResult = query_appdb("CREATE TABLE $sTableName (
|
||||
sColumn VARCHAR(255) NOT NULL,
|
||||
iType INT(3) NOT NULL,
|
||||
sData VARCHAR(255) NOT NULL DEFAULT ''
|
||||
)");
|
||||
|
||||
if(!$hResult)
|
||||
return false;
|
||||
|
||||
$bSuccess = true;
|
||||
foreach($this->aFilters as $oFilter)
|
||||
{
|
||||
$hResult = query_appdb("INSERT INTO $sTableName (sColumn,iType,sData)
|
||||
VALUES('{$oFilter->getColumn()}','{$oFilter->getOperatorId()}','{$oFilter->getData()}')");
|
||||
if(!$hResult)
|
||||
$bSuccess = false;
|
||||
}
|
||||
return $bSuccess;
|
||||
}
|
||||
|
||||
public function addFilterObject(Filter $oFilter)
|
||||
{
|
||||
$this->aFilters[] = $oFilter;
|
||||
}
|
||||
|
||||
public function AddFilter($sColumn, $iType, $sData)
|
||||
{
|
||||
$this->aFilters[] = new Filter($sColumn, $iType, $sData);
|
||||
}
|
||||
|
||||
public function getFilterCount()
|
||||
{
|
||||
return sizeof($this->aFilters);
|
||||
}
|
||||
|
||||
public function getFilters()
|
||||
{
|
||||
return $this->aFilters;
|
||||
}
|
||||
|
||||
public function getWhereClause()
|
||||
{
|
||||
$aFilters = array();
|
||||
for($i = 0; $i < sizeof($this->aFilters); $i++)
|
||||
{
|
||||
$oFilter = $this->aFilters[$i];
|
||||
|
||||
$sThisFilter = $oFilter->getExpression();
|
||||
|
||||
if($sThisFilter)
|
||||
$aFilters[] = $sThisFilter;
|
||||
}
|
||||
|
||||
return implode($aFilters, ' AND ');
|
||||
}
|
||||
|
||||
function getQuery($sTable, $iLimit = 0)
|
||||
{
|
||||
$sWhere = $this->getFilterCount() ? 'WHERE '.$this->getWhereClause() : '';
|
||||
$sQuery = "SELECT * FROM $sTable $sWhere";
|
||||
|
||||
$iLimit = mysql_real_escape_string($iLimit);
|
||||
|
||||
if($iLimit)
|
||||
$sQuery .= " LIMIT 0,$iLimit";
|
||||
|
||||
return $sQuery;
|
||||
}
|
||||
|
||||
function getMatchedItems($sTable, $iLimit = 0)
|
||||
{
|
||||
return query_appdb($this->getQuery($sTable, $iLimit));
|
||||
}
|
||||
|
||||
function getMatchedItemsCount($sTable)
|
||||
{
|
||||
return mysql_num_rows($this->getMatchedItems($sTable));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
567
include/db_filter_ui.php
Normal file
567
include/db_filter_ui.php
Normal file
@@ -0,0 +1,567 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* User interface for the SQL filter classes
|
||||
*
|
||||
* Copyright 2008 BitSplash Software LLC
|
||||
* Copyright 2008 Alexander N. Sørnes <alex@thehandofagony.com>
|
||||
*
|
||||
*/
|
||||
|
||||
require_once('db_filter.php');
|
||||
|
||||
define('FILTER_VALUES_NORMAL', 1);
|
||||
define('FILTER_VALUES_ENUM', 2);
|
||||
define('FILTER_VALUES_OPTION_BOOL', 3);
|
||||
define('FILTER_VALUES_OPTION_ENUM', 4);
|
||||
|
||||
define('MAX_FILTERS', 50);
|
||||
|
||||
/* Info describing an available filter: what column it applies to,
|
||||
and what comparison options are available */
|
||||
class FilterInfo
|
||||
{
|
||||
private $sColumn;
|
||||
private $sDisplayName;
|
||||
private $aTypes; // Available filters for this column
|
||||
private $iValueType; // Normal, enum ...
|
||||
private $aValueTypeData; // List of enums
|
||||
private $aValueTypeDataDisplay; // Optional display names for enums
|
||||
|
||||
public function FilterInfo($sColumn, $sDisplayName, $aTypes, $iValueType = FILTER_VALUES_NORMAL, $aValueTypeData = array(), $aValueTypeDisplay = array())
|
||||
{
|
||||
$this->sColumn = $sColumn;
|
||||
$this->sDisplayName = $sDisplayName;
|
||||
$this->aTypes = $aTypes;
|
||||
$this->iValueType = $iValueType;
|
||||
$this->aValueTypeData = $aValueTypeData;
|
||||
|
||||
if(sizeof($aValueTypeData) && !sizeof($aValueTypeDisplay))
|
||||
$this->aValueTypeDataDisplay = $aValueTypeData;
|
||||
else
|
||||
$this->aValueTypeDataDisplay = $aValueTypeDisplay;
|
||||
}
|
||||
|
||||
public function getColumn()
|
||||
{
|
||||
return $this->sColumn;
|
||||
}
|
||||
|
||||
public function getDisplayName()
|
||||
{
|
||||
return $this->sDisplayName;
|
||||
}
|
||||
|
||||
public function getValueType()
|
||||
{
|
||||
return $this->iValueType;
|
||||
}
|
||||
|
||||
public function getValueTypeData()
|
||||
{
|
||||
return $this->aValueTypeData;
|
||||
}
|
||||
|
||||
public function getValueTypeDataDisplay()
|
||||
{
|
||||
return $this->aValueTypeDataDisplay;
|
||||
}
|
||||
|
||||
public function getTypes()
|
||||
{
|
||||
return $this->aTypes;
|
||||
}
|
||||
|
||||
public function isOption()
|
||||
{
|
||||
switch($this->iValueType)
|
||||
{
|
||||
case FILTER_VALUES_OPTION_BOOL:
|
||||
case FILTER_VALUES_OPTION_ENUM:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getOpName($iOpId)
|
||||
{
|
||||
switch($iOpId)
|
||||
{
|
||||
case FILTER_EQUALS:
|
||||
return 'equal to';
|
||||
case FILTER_LIKE:
|
||||
return 'like';
|
||||
case FILTER_CONTAINS:
|
||||
return 'contains';
|
||||
case FILTER_STARTS_WITH:
|
||||
return 'starts with';
|
||||
case FILTER_ENDS_WITH:
|
||||
return 'ends with';
|
||||
case FILTER_NOT_LIKE:
|
||||
return 'not like';
|
||||
case FILTER_NOT_EQUALS:
|
||||
return 'not equal to';
|
||||
case FILTER_LESS_THAN:
|
||||
return 'less than';
|
||||
case FILTER_GREATER_THAN:
|
||||
return 'greater than';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Class handling tables where the user can filter contents */
|
||||
class FilterInterface
|
||||
{
|
||||
private $aFilterInfo;
|
||||
private $oFilterSet;
|
||||
private $aEscapeChars;
|
||||
private $aEscapeCharsWith;
|
||||
private $sErrors; // Used to inform the user about errors (and to give advice)
|
||||
|
||||
public function FilterInterface($sTableName = '')
|
||||
{
|
||||
$this->aFilterInfo = array();
|
||||
$this->oFilterSet = new FilterSet(query_escape_string($sTableName));
|
||||
$this->aEscapeChars = array('.');
|
||||
$this->aEscapeCharsWith = array('-');
|
||||
$this->sErrors = '';
|
||||
}
|
||||
|
||||
public function AddFilterObject(Filter $oFilter)
|
||||
{
|
||||
$this->oFilterSet->AddFilterObject($oFilter);
|
||||
}
|
||||
|
||||
public function setFilterSet(FilterSet $oSet)
|
||||
{
|
||||
$this->oFilterSet = $oSet;
|
||||
}
|
||||
|
||||
/* Convenience function to add a filter option */
|
||||
public function AddFilterInfo($sColumn, $sDisplayName, $aTypes, $iValueType = VALUE_TYPE_NORMAL, $aValueTypeData = array(), $aValueTypeDisplay = array())
|
||||
{
|
||||
$this->aFilterInfo[$sColumn] = new FilterInfo($sColumn, $sDisplayName, $aTypes, $iValueType, $aValueTypeData, $aValueTypeDisplay);
|
||||
}
|
||||
|
||||
/* We can't use some special chars in variable names, such as '.' */
|
||||
public function escapeChars($sIn)
|
||||
{
|
||||
return str_replace($this->aEscapeChars, $this->aEscapeCharsWith, $sIn);
|
||||
}
|
||||
|
||||
public function unescapeChars($sIn)
|
||||
{
|
||||
return str_replace($this->aEscapeWith, $this->aEscape, $sIn);
|
||||
}
|
||||
|
||||
public function getUrlElement($iId, Filter $oFilter)
|
||||
{
|
||||
$sColumn = $this->escapeChars($oFilter->getColumn());
|
||||
|
||||
$sId = $iId;
|
||||
|
||||
$shEditor = "&i{$sColumn}Op$sId={$oFilter->getOperatorId()}";
|
||||
$shEditor .= "&s{$sColumn}Data$sId={$oFilter->getData()}";
|
||||
|
||||
return $shEditor;
|
||||
}
|
||||
|
||||
public function getHiddenInputTag($iId, Filter $oFilter)
|
||||
{
|
||||
$sColumn = $this->escapeChars($oFilter->getColumn());
|
||||
$sId = $iId;
|
||||
|
||||
$shEditor = "<input type=\"hidden\" name=\"i{$sColumn}Op$sId\" value=\"{$oFilter->getOperatorId()}\">";
|
||||
$shEditor .= "<input type=\"hidden\" name=\"s{$sColumn}Data$sId\" value=\"{$oFilter->getData()}\" />";
|
||||
|
||||
return $shEditor;
|
||||
}
|
||||
|
||||
public function getOptionBoolEditor($iId, Filter $oFilter)
|
||||
{
|
||||
$sColumn = $this->escapeChars($oFilter->getColumn());
|
||||
$oColumn = $this->aFilterInfo[$oFilter->getColumn()];
|
||||
$sId = ($iId == -1) ? '' : $iId;
|
||||
|
||||
$aTypes = $oColumn->getTypes();
|
||||
$iOp = $aTypes[0];
|
||||
|
||||
if($iId == -1)
|
||||
{
|
||||
/* The first entry in the list of choices is the default */
|
||||
$aValues = $oColumn->getValueTypeData();
|
||||
$sData = $aValues[0];
|
||||
} else
|
||||
{
|
||||
$sData = $oFilter->getData();
|
||||
}
|
||||
|
||||
$shRet = "<input type=\"hidden\" name=\"i{$sColumn}Op$sId\" value=\"$iOp\" />";
|
||||
|
||||
if($sData == 'true')
|
||||
$sChecked = ' checked="checked"';
|
||||
else
|
||||
$sChecked = '';
|
||||
|
||||
$shRet .= "<input value=\"true\" $sChecked name=\"s{$sColumn}Data$sId\" type=\"checkbox\" />";
|
||||
$shRet .= ' '.$oColumn->getDisplayName();
|
||||
|
||||
return $shRet;
|
||||
}
|
||||
|
||||
public function getItemEditor($iId, Filter $oFilter)
|
||||
{
|
||||
$sColumn = $this->escapeChars($oFilter->getColumn());
|
||||
$oColumn = $this->aFilterInfo[$oFilter->getColumn()];
|
||||
|
||||
$sId = ($iId == -1) ? '' : $iId;
|
||||
$shEditor = $oColumn->getDisplayName().' ';
|
||||
|
||||
$aTypes = $oColumn->getTypes();
|
||||
|
||||
/* It doesn't make sense to show a dropdown menu of choices if there is only one
|
||||
If the filter is already active then there are more than one; one to remove */
|
||||
if($iId == -1 && sizeof($aTypes) == 1)
|
||||
{
|
||||
echo "<input type=\"hidden\" name=\"i{$sColumn}Op$sId\" value=\"{$aTypes[0]}\" />";
|
||||
|
||||
/* Printing 'equal to' sounds weird if it is the only choice */
|
||||
if($aTypes[0] != FILTER_EQUALS)
|
||||
$shEditor .= $oColumn->getOpName($aTypes[0]);
|
||||
} else if ($aTypes[0] != FILTER_OPTION_ENUM)
|
||||
{
|
||||
$shEditor .= "<select name='i{$sColumn}Op$sId'>";
|
||||
|
||||
if($iId != -1)
|
||||
{
|
||||
$sSel = '';
|
||||
$sText = 'remove';
|
||||
|
||||
$shEditor .= "<option value='0'$sSel>-- $sText --</option>";
|
||||
}
|
||||
|
||||
foreach($aTypes as $iType)
|
||||
{
|
||||
if($oFilter->getOperatorId() == $iType)
|
||||
$sSel = " selected='selected'";
|
||||
else
|
||||
$sSel = '';
|
||||
$shEditor .= "<option value='$iType'$sSel>".$oColumn->getOpName($iType).'</option><br />';
|
||||
}
|
||||
$shEditor .= '</select> ';
|
||||
} else
|
||||
{
|
||||
echo "<input type=\"hidden\" name=\"i{$sColumn}Op$sId\" value=\"{$aTypes[0]}\" />";
|
||||
}
|
||||
|
||||
switch($oColumn->getValueType())
|
||||
{
|
||||
case FILTER_VALUES_NORMAL:
|
||||
$shEditor .= "<input type='text' value=\"{$oFilter->getData()}\" name='s{$sColumn}Data$sId' size='30' />";
|
||||
break;
|
||||
case FILTER_VALUES_ENUM:
|
||||
case FILTER_VALUES_OPTION_ENUM:
|
||||
$shEditor .= $this->getEnumEditor($oColumn, $oFilter, $sId);
|
||||
break;
|
||||
}
|
||||
|
||||
return $shEditor;
|
||||
}
|
||||
|
||||
public function getEnumEditor($oColumn, $oFilter, $sId)
|
||||
{
|
||||
$sColumn = $this->escapeChars($oFilter->getColumn());
|
||||
$aOptions = $oColumn->getValueTypeData();
|
||||
$aOptionNames = $oColumn->getValueTypeDataDisplay();
|
||||
|
||||
$sData = $oFilter->getData();
|
||||
|
||||
$shEditor = "<select name=\"s{$sColumn}Data$sId\">";
|
||||
|
||||
if($sData)
|
||||
$shEditor .= "<option value=\"\">-- remove --</option>";
|
||||
else
|
||||
$shEditor .= "<option value=\"\">-- select --</option>";
|
||||
|
||||
for($i = 0; $i < sizeof($aOptions); $i++)
|
||||
{
|
||||
$sOption = $aOptions[$i];
|
||||
$sSelected = '';
|
||||
if($sData == $sOption)
|
||||
$sSelected = ' selected="selected"';
|
||||
$shEditor .= "<option value=\"$sOption\"$sSelected>{$aOptionNames[$i]}</option>";
|
||||
}
|
||||
|
||||
$shEditor .= "</select>";
|
||||
|
||||
return $shEditor;
|
||||
}
|
||||
|
||||
/* Get filter data formatted to fit in a URL */
|
||||
public function getUrlData()
|
||||
{
|
||||
$shEditor = '';
|
||||
$aCounts = array();
|
||||
|
||||
foreach($this->oFilterSet->getFilters() as $oFilter)
|
||||
{
|
||||
$sColumn = $oFilter->getColumn();
|
||||
|
||||
if(!array_key_exists($sColumn, $aCounts))
|
||||
$aCounts[$sColumn] = 0;
|
||||
|
||||
$shEditor .= $this->getUrlElement($aCounts[$sColumn], $oFilter);
|
||||
|
||||
$shEditor .= '<br />';
|
||||
|
||||
$aCounts[$sColumn]++;
|
||||
}
|
||||
|
||||
return $shEditor;
|
||||
}
|
||||
|
||||
/* Get a list of hidden input tags to preserve form data */
|
||||
public function getHiddenFormData()
|
||||
{
|
||||
$shEditor = '';
|
||||
$aCounts = array();
|
||||
|
||||
foreach($this->oFilterSet->getFilters() as $oFilter)
|
||||
{
|
||||
$sColumn = $oFilter->getColumn();
|
||||
|
||||
if(!array_key_exists($sColumn, $aCounts))
|
||||
$aCounts[$sColumn] = 0;
|
||||
|
||||
$shEditor .= $this->getHiddenInputTag($aCounts[$sColumn], $oFilter);
|
||||
|
||||
$shEditor .= '<br />';
|
||||
|
||||
$aCounts[$sColumn]++;
|
||||
}
|
||||
|
||||
return $shEditor;
|
||||
}
|
||||
|
||||
public function getEditor()
|
||||
{
|
||||
$shNewItemsEditor = '';
|
||||
$shCurrentItemsEditor = '';
|
||||
$aCounts = array();
|
||||
|
||||
if(sizeof($this->oFilterSet->getFilters()))
|
||||
$shCurrentItemsEditor .= '<br /><b>Active filters</b><br />';
|
||||
foreach($this->oFilterSet->getFilters() as $oFilter)
|
||||
{
|
||||
$sColumn = $oFilter->getColumn();
|
||||
|
||||
if(!array_key_exists($sColumn, $aCounts))
|
||||
$aCounts[$sColumn] = 0;
|
||||
|
||||
if($oFilter->getOperatorId() == FILTER_OPTION_BOOL)
|
||||
$shCurrentItemsEditor .= $this->getOptionBoolEditor($aCounts[$sColumn], $oFilter);
|
||||
else
|
||||
$shCurrentItemsEditor .= $this->getItemEditor($aCounts[$sColumn], $oFilter);
|
||||
$shCurrentItemsEditor .= '<br />';
|
||||
|
||||
$aCounts[$sColumn]++;
|
||||
}
|
||||
|
||||
$shNewItemsEditor .= '<b>Add new filter</b> <i>(You don’t have to fill out all rows.)</i><br />';
|
||||
|
||||
/* Show errors, if any */
|
||||
if($this->sErrors)
|
||||
$shNewItemsEditor .= "<font color=\"red\">{$this->sErrors}</font>";
|
||||
|
||||
foreach($this->aFilterInfo as $oOption)
|
||||
{
|
||||
$oDummyFilter = new Filter($oOption->getColumn(), 0, '');
|
||||
$aTypes = $oOption->getTypes();
|
||||
|
||||
if($oOption->getValueType() == FILTER_VALUES_OPTION_BOOL)
|
||||
{
|
||||
if(!array_key_exists($oOption->getColumn(), $aCounts))
|
||||
$shNewItemsEditor .= $this->getOptionBoolEditor(-1, $oDummyFilter);
|
||||
$shNewItemsEditor .= '<br />';
|
||||
} else
|
||||
{
|
||||
/* Make necessary checks for filters that are only supposed to be shown once */
|
||||
if($oOption->getValueType() != FILTER_VALUES_OPTION_ENUM || !array_key_exists($oOption->getColumn(), $aCounts))
|
||||
{
|
||||
$shNewItemsEditor .= $this->getItemEditor(-1, $oDummyFilter);
|
||||
$shNewItemsEditor .= '<br />';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $shNewItemsEditor.$shCurrentItemsEditor;
|
||||
}
|
||||
|
||||
public function getFilterInfo()
|
||||
{
|
||||
return $this->aFilterInfo;
|
||||
}
|
||||
|
||||
/* Reads all input related to filters for the given table column */
|
||||
public function readInputForColumn($aClean, FilterInfo $oOption)
|
||||
{
|
||||
$aReturn = array();
|
||||
$bChangedOption = false;
|
||||
|
||||
for($i = 0; array_key_exists('i'.$this->escapeChars($oOption->getColumn())."Op$i", $aClean); $i++)
|
||||
{
|
||||
$sColumn = $this->escapeChars($oOption->getColumn());
|
||||
$sData = query_escape_string(getInput("s{$sColumn}Data$i", $aClean));
|
||||
$iOp = $aClean["i{$sColumn}Op$i"];
|
||||
|
||||
if(!$iOp)
|
||||
continue;
|
||||
|
||||
$oFilter = new Filter($oOption->getColumn(), $iOp, $sData);
|
||||
|
||||
/* Only show an option as an active filter if it has been changed
|
||||
from the default */
|
||||
if($oOption->getValueType() == FILTER_VALUES_OPTION_BOOL || $oOption->getValueType() == FILTER_VALUES_OPTION_ENUM)
|
||||
{
|
||||
if($oOption->getValueType() == FILTER_VALUES_OPTION_BOOL)
|
||||
{
|
||||
/* The default option is the first entry in the list of choices */
|
||||
$aChoices = $oOption->getValueTypeData();
|
||||
$sDefault = $aChoices[0];
|
||||
if(!$sData)
|
||||
$sData = 'false';
|
||||
|
||||
if($sData == $sDefault)
|
||||
continue;
|
||||
}
|
||||
if($i > 0)
|
||||
continue;
|
||||
$bChangedOption = true;
|
||||
}
|
||||
|
||||
if(!$sData)
|
||||
continue;
|
||||
|
||||
$aReturn[] = $oFilter;
|
||||
}
|
||||
|
||||
if(array_key_exists('i'.$this->escapeChars($oOption->getColumn())."Op", $aClean))
|
||||
{
|
||||
$sColumn = $this->escapeChars($oOption->getColumn());
|
||||
$i = sizeof($aReturn);
|
||||
$sData = query_escape_string($aClean["s{$sColumn}Data"]);
|
||||
$iOp = $aClean["i{$sColumn}Op"];
|
||||
|
||||
|
||||
if($iOp && $sData && ($oOption->getValueType() != FILTER_VALUES_OPTION_BOOL || !$bChangedOoption))
|
||||
{
|
||||
$oFilter = new Filter($oOption->getColumn(), $iOp, $sData);
|
||||
$aReturn[] = $oFilter;
|
||||
} else if(!$iOp && $sData)
|
||||
{
|
||||
/* The user probably meant to add a filter, but forgot to seelect
|
||||
a filter criterion */
|
||||
$this->sErrors .= 'You need to select a filter criterion from the drop-down list<br />';
|
||||
}
|
||||
}
|
||||
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
/* Reads an input array get enabled filters from form data.
|
||||
The given TableFilterSet defines available options */
|
||||
public function readInput($aClean)
|
||||
{
|
||||
$iCount = 0; // We set a maximum for how many filters a user can add,
|
||||
// otherwise we may get a too long SQL query
|
||||
|
||||
foreach($this->getFilterInfo() as $oOption)
|
||||
{
|
||||
foreach($this->readInputForColumn($aClean, $oOption) as $oNewFilter)
|
||||
{
|
||||
$iCount ++;
|
||||
$this->AddFilterObject($oNewFilter);
|
||||
if($iCount > MAX_FILTERS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function loadTable($sTableName)
|
||||
{
|
||||
$this->oFilterSet->loadTable($sTableName);
|
||||
}
|
||||
|
||||
public function saveTable($sTableName)
|
||||
{
|
||||
$this->oFilterSet->saveTable($sTableName);
|
||||
}
|
||||
|
||||
public function getFilterCount()
|
||||
{
|
||||
return $this->oFilterSet->getFilterCount();
|
||||
}
|
||||
|
||||
/* Returns an array of options, where the keys are the columns and the members
|
||||
are the settings themselves */
|
||||
public function getOptions()
|
||||
{
|
||||
$aOptions = array();
|
||||
foreach($this->oFilterSet->getFilters() as $oFilter)
|
||||
{
|
||||
if($oFilter->isOption())
|
||||
$aOptions[$oFilter->getColumn()] = $oFilter->getData();
|
||||
}
|
||||
foreach($this->aFilterInfo as $oFilterInfo)
|
||||
{
|
||||
if($oFilterInfo->isOption() &&
|
||||
!array_key_exists($oFilterInfo->getColumn(), $aOptions))
|
||||
{
|
||||
$aTypes = $oFilterInfo->getTypes();
|
||||
|
||||
if($oFilterInfo->getValueType() == FILTER_VALUES_OPTION_BOOL)
|
||||
$sDefault = $aTypes[0];
|
||||
else
|
||||
$sDefault = '';
|
||||
|
||||
$aOptions[$oFilterInfo->getColumn()] = $sDefault;
|
||||
}
|
||||
}
|
||||
return $aOptions;
|
||||
}
|
||||
|
||||
public function getWhereClause()
|
||||
{
|
||||
return $this->oFilterSet->getWhereClause();
|
||||
}
|
||||
|
||||
public function getTable($sTable, $iLimit = 0)
|
||||
{
|
||||
$hResult = $this->oFilterSet->getMatchedItems($sTable, $iLimit);
|
||||
|
||||
if(!$hResult)
|
||||
return;
|
||||
|
||||
echo 'Selected '.$this->oFilterSet->getMatchedItemsCount($sTable).' rows<br><br>';
|
||||
|
||||
$oTable = new Table();
|
||||
|
||||
while($aRow = mysql_fetch_row($hResult))
|
||||
{
|
||||
$oRow = new TableRow();
|
||||
|
||||
foreach($aRow as $sCell)
|
||||
{
|
||||
$oRow->AddTextCell($sCell);
|
||||
}
|
||||
|
||||
$oTable->AddRow($oRow);
|
||||
}
|
||||
|
||||
return $oTable->getString();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
789
include/distribution.php
Normal file
789
include/distribution.php
Normal file
@@ -0,0 +1,789 @@
|
||||
<?php
|
||||
/***************************************/
|
||||
/* this class represents Distributions */
|
||||
/***************************************/
|
||||
require_once(BASE."include/mail.php");
|
||||
require_once(BASE."include/util.php");
|
||||
|
||||
// Test class for handling Distributions.
|
||||
|
||||
class distribution {
|
||||
var $iDistributionId;
|
||||
var $sName;
|
||||
var $sUrl;
|
||||
var $sSubmitTime;
|
||||
var $iSubmitterId;
|
||||
private $sState;
|
||||
var $aTestingIds;
|
||||
|
||||
// constructor, fetches the data.
|
||||
function distribution($iDistributionId = null, $oRow = null)
|
||||
{
|
||||
$this->aTestingIds = array();
|
||||
// we are working on an existing distribution.
|
||||
if(!$iDistributionId && !$oRow)
|
||||
return;
|
||||
|
||||
// We fetch the data related to this distribution.
|
||||
if(!$oRow)
|
||||
{
|
||||
$sQuery = "SELECT *
|
||||
FROM distributions
|
||||
WHERE distributionId = '?'";
|
||||
if($hResult = query_parameters($sQuery, $iDistributionId))
|
||||
$oRow = query_fetch_object($hResult);
|
||||
}
|
||||
|
||||
if($oRow)
|
||||
{
|
||||
$this->iDistributionId = $oRow->distributionId;
|
||||
$this->sName = $oRow->name;
|
||||
$this->sUrl = $oRow->url;
|
||||
$this->sSubmitTime = $oRow->submitTime;
|
||||
$this->iSubmitterId = $oRow->submitterId;
|
||||
$this->sState = $oRow->state;
|
||||
}
|
||||
|
||||
/*
|
||||
* We fetch Test Result Ids.
|
||||
*/
|
||||
|
||||
if($_SESSION['current']->hasPriv("admin"))
|
||||
{
|
||||
$sQuery = "SELECT testingId
|
||||
FROM testResults, ?.versions
|
||||
WHERE
|
||||
versions.value = testResults.testedRelease
|
||||
AND
|
||||
versions.product_id = '?'
|
||||
AND
|
||||
distributionId = '?'
|
||||
ORDER BY testedRating,bugs.versions.id DESC";
|
||||
} else /* only let users view test results that aren't queued and for apps that */
|
||||
/* aren't queued or versions that aren't queued */
|
||||
{
|
||||
$sQuery = "SELECT testingId
|
||||
FROM testResults, appFamily, appVersion, ?.versions
|
||||
WHERE testResults.state = 'accepted' AND
|
||||
versions.value = testResults.testedRelease
|
||||
AND
|
||||
versions.product_id = '?'
|
||||
AND
|
||||
testResults.versionId = appVersion.versionId AND
|
||||
appFamily.appId = appVersion.appId AND
|
||||
appFamily.state = 'accepted' AND
|
||||
appVersion.state = 'accepted' AND
|
||||
distributionId = '?'
|
||||
ORDER BY testedRating,bugs.versions.id DESC";
|
||||
}
|
||||
|
||||
if($hResult = query_parameters($sQuery, BUGZILLA_DB, BUGZILLA_PRODUCT_ID, $this->iDistributionId))
|
||||
{
|
||||
while($oRow = query_fetch_object($hResult))
|
||||
{
|
||||
$this->aTestingIds[] = $oRow->testingId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a new distribution.
|
||||
function create()
|
||||
{
|
||||
//Let's not create a duplicate
|
||||
$sQuery = "SELECT *
|
||||
FROM distributions
|
||||
WHERE name = '?'";
|
||||
$hResult = query_parameters($sQuery, $this->sName);
|
||||
|
||||
if($hResult && $oRow = query_fetch_object($hResult))
|
||||
{
|
||||
if(query_num_rows($hResult))
|
||||
{
|
||||
addmsg("There was an existing distribution called ".$this->sName.".", "red");
|
||||
$this->distribution($oRow->distributionId);
|
||||
|
||||
/* Even though we did not create a new distribution, the caller is provided
|
||||
with a valid distribution object. Thus no special handling is necessary,
|
||||
so we return TRUE */
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
$hResult = query_parameters("INSERT INTO distributions (name, url, submitTime, ".
|
||||
"submitterId, state) ".
|
||||
"VALUES ('?', '?', ?, '?', '?')",
|
||||
$this->sName, $this->sUrl,
|
||||
"NOW()",
|
||||
$_SESSION['current']->iUserId,
|
||||
$this->mustBeQueued() ? 'queued' : 'accepted');
|
||||
if($hResult)
|
||||
{
|
||||
$this->iDistributionId = query_appdb_insert_id();
|
||||
$this->distribution($this->iDistributionId);
|
||||
$this->SendNotificationMail();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
addmsg("Error while creating Distribution.", "red");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Update Distribution.
|
||||
function update()
|
||||
{
|
||||
// is the current user allowed to update this Distribution?
|
||||
if(!$_SESSION['current']->hasPriv("admin") &&
|
||||
!($_SESSION['current']->iUserId == $this->iSubmitterId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(query_parameters("UPDATE distributions SET name = '?', url = '?' WHERE distributionId = '?'",
|
||||
$this->sName, $this->sUrl, $this->iDistributionId))
|
||||
{
|
||||
$this->SendNotificationMail("edit");
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
addmsg("Error while updating Distribution", "red");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function purge()
|
||||
{
|
||||
/* Is the current user allowed to delete this distribution? We allow
|
||||
everyone to delete a queued, empty distribution, because it should be
|
||||
deleted along with the last testData associated with it */
|
||||
if(!($this->canEdit() || (!sizeof($this->aTestingIds) &&
|
||||
$this->sState != 'accepted')))
|
||||
return false;
|
||||
|
||||
// if the distribution has test results only enable an admin to delete
|
||||
// the distribution
|
||||
if(sizeof($this->aTestingIds) && !$_SESSION['current']->hasPriv("admin"))
|
||||
return FALSE;
|
||||
|
||||
$bSuccess = TRUE;
|
||||
|
||||
foreach($this->objectGetChildren(true) as $oChild)
|
||||
{
|
||||
if(!$oChild->purge())
|
||||
$bSuccess = FALSE;
|
||||
}
|
||||
|
||||
// now delete the Distribution
|
||||
$sQuery = "DELETE FROM distributions
|
||||
WHERE distributionId = '?'
|
||||
LIMIT 1";
|
||||
if(!($hResult = query_parameters($sQuery, $this->iDistributionId)))
|
||||
$bSuccess = FALSE;
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
|
||||
// Delete Distributution.
|
||||
function delete()
|
||||
{
|
||||
/* Is the current user allowed to delete this distribution? We allow
|
||||
everyone to delete a queued, empty distribution, because it should be
|
||||
deleted along with the last testData associated with it */
|
||||
if(!($this->canEdit() || (!sizeof($this->aTestingIds) &&
|
||||
$this->sState != 'accepted')))
|
||||
return false;
|
||||
|
||||
// if the distribution has test results only enable an admin to delete
|
||||
// the distribution
|
||||
if(sizeof($this->aTestingIds) && !$_SESSION['current']->hasPriv("admin"))
|
||||
return FALSE;
|
||||
|
||||
$bSuccess = TRUE;
|
||||
|
||||
foreach($this->objectGetChildren() as $oChild)
|
||||
{
|
||||
if(!$oChild->delete())
|
||||
$bSuccess = FALSE;
|
||||
}
|
||||
|
||||
// now delete the Distribution
|
||||
$sQuery = "UPDATE distributions SET state = 'deleted'
|
||||
WHERE distributionId = '?'
|
||||
LIMIT 1";
|
||||
if(!($hResult = query_parameters($sQuery, $this->iDistributionId)))
|
||||
$bSuccess = FALSE;
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
|
||||
// Move Distribution out of the queue.
|
||||
function unQueue()
|
||||
{
|
||||
/* Check permissions */
|
||||
if($this->mustBeQueued())
|
||||
return FALSE;
|
||||
|
||||
// If we are not in the queue, we can't move the Distribution out of the queue.
|
||||
if($this->sState != 'queued')
|
||||
return false;
|
||||
|
||||
if(query_parameters("UPDATE distributions SET state = '?' WHERE distributionId = '?'",
|
||||
'accepted', $this->iDistributionId))
|
||||
{
|
||||
$this->sState = 'accepted';
|
||||
// we send an e-mail to interested people
|
||||
$this->mailSubmitter("add");
|
||||
$this->SendNotificationMail();
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
addmsg("Error while unqueueing Distribution", "red");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function Reject($bSilent=false)
|
||||
{
|
||||
// is the current user allowed to reject this Distribution?
|
||||
if(!$_SESSION['current']->hasPriv("admin"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we are not in the queue, we can't move the Distribution out of the queue.
|
||||
if($this->sState != 'queued')
|
||||
return false;
|
||||
|
||||
return $this->delete();
|
||||
}
|
||||
|
||||
function getTestResults($bIncludeDeleted = false)
|
||||
{
|
||||
if($bIncludeDeleted)
|
||||
$sExcludeDeleted = "";
|
||||
else
|
||||
$sExcludeDeleted = " AND state != 'deleted'";
|
||||
|
||||
$aTests = array();
|
||||
$sQuery = "SELECT * FROM testResults WHERE distributionId = '?'$sExcludeDeleted";
|
||||
$hResult = query_parameters($sQuery, $this->iDistributionId);
|
||||
|
||||
while($oRow = mysql_fetch_object($hResult))
|
||||
$aTests[] = new testData(null, $oRow);
|
||||
|
||||
return $aTests;
|
||||
}
|
||||
|
||||
function objectGetChildren($bIncludeDeleted = false)
|
||||
{
|
||||
$aChildren = array();
|
||||
|
||||
foreach($this->getTestResults($bIncludeDeleted) as $oTest)
|
||||
{
|
||||
$aChildren += $oTest->objectGetChildren($bIncludeDeleted);
|
||||
$aChildren[] = $oTest;
|
||||
}
|
||||
|
||||
return $aChildren;
|
||||
}
|
||||
|
||||
function ReQueue()
|
||||
{
|
||||
// is the current user allowed to requeue this data
|
||||
if(!$_SESSION['current']->hasPriv("admin") &&
|
||||
!($_SESSION['current']->iUserId == $this->iSubmitterId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(query_parameters("UPDATE testResults SET state = '?' WHERE testingId = '?'",
|
||||
'queued', $this->iTestingId))
|
||||
{
|
||||
if(query_parameters("UPDATE distribution SET state = '?' WHERE distributionId = '?'",
|
||||
'queued', $this->iDistributionId))
|
||||
{
|
||||
$this->sState = 'queued';
|
||||
// we send an e-mail to interested people
|
||||
$this->SendNotificationMail();
|
||||
|
||||
// the test data has been resubmitted
|
||||
addmsg("The Distribution has been resubmitted", "green");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* something has failed if we fell through to this point without */
|
||||
/* returning */
|
||||
addmsg("Error requeueing Distribution", "red");
|
||||
return false;
|
||||
}
|
||||
|
||||
function objectGetSubmitterId()
|
||||
{
|
||||
return $this->iSubmitterId;
|
||||
}
|
||||
|
||||
function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return new mailOptions();
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
$oSubmitter = new user($this->iSubmitterId);
|
||||
|
||||
if($bMailSubmitter)
|
||||
{
|
||||
switch($sAction)
|
||||
{
|
||||
case "delete":
|
||||
$sSubject = "Submitted distribution deleted";
|
||||
$sMsg = "The distribution you submitted (".$this->sName.") has been ".
|
||||
"deleted.\n";
|
||||
break;
|
||||
}
|
||||
$aMailTo = null;
|
||||
} else
|
||||
{
|
||||
switch($sAction)
|
||||
{
|
||||
case "delete":
|
||||
$sSubject = "Distribution ".$this->sName." deleted";
|
||||
$sMsg = "";
|
||||
break;
|
||||
}
|
||||
$aMailTo = User::get_notify_email_address_list(null, null);
|
||||
}
|
||||
|
||||
return array($sSubject, $sMsg, $aMailTo);
|
||||
}
|
||||
|
||||
function mailSubmitter($sAction="add")
|
||||
{
|
||||
global $aClean;
|
||||
|
||||
if($this->iSubmitterId)
|
||||
{
|
||||
$oSubmitter = new User($this->iSubmitterId);
|
||||
switch($sAction)
|
||||
{
|
||||
case "add":
|
||||
{
|
||||
$sSubject = "Submitted Distribution accepted";
|
||||
$sMsg = "The Distribution you submitted (".$this->sName.") has been accepted.\n";
|
||||
}
|
||||
break;
|
||||
case "delete":
|
||||
{
|
||||
$sSubject = "Submitted Distribution deleted";
|
||||
$sMsg = "The Distribution you submitted (".$this->sName.") has been deleted.";
|
||||
$sMsg .= "Reason given:\n";
|
||||
$sMsg .= $aClean['sReplyText']."\n"; // append the reply text, if there is any
|
||||
}
|
||||
break;
|
||||
}
|
||||
$sMsg .= "We appreciate your help in making the Application Database better for all users.";
|
||||
|
||||
mail_appdb($oSubmitter->sEmail, $sSubject ,$sMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function SendNotificationMail($sAction="add",$sMsg=null)
|
||||
{
|
||||
global $aClean;
|
||||
|
||||
switch($sAction)
|
||||
{
|
||||
case "add":
|
||||
if($this->sState == 'accepted')
|
||||
{
|
||||
$sSubject = "Distribution ".$this->sName." added by ".
|
||||
$_SESSION['current']->sRealname;
|
||||
$sMsg = $this->objectMakeUrl()."\n";
|
||||
if($this->iSubmitterId)
|
||||
{
|
||||
$oSubmitter = new User($this->iSubmitterId);
|
||||
$sMsg .= "This Distribution has been submitted by ".$oSubmitter->sRealname.".";
|
||||
$sMsg .= "\n";
|
||||
$sMsg .= "Appdb admin reply text:\n";
|
||||
$sMsg .= $aClean['sReplyText']."\n"; // append the reply text, if there is any
|
||||
}
|
||||
addmsg("The Distribution was successfully added into the database.", "green");
|
||||
} else // test data queued.
|
||||
{
|
||||
$sSubject = "Distribution ".$this->sName." submitted by ".$_SESSION['current']->sRealname;
|
||||
$sMsg .= "This test data has been queued.";
|
||||
$sMsg .= "\n";
|
||||
addmsg("The Distribution you submitted will be added to the database after being reviewed.", "green");
|
||||
}
|
||||
break;
|
||||
case "edit":
|
||||
$sSubject = "Distribution ".$this->sName." has been modified by ".$_SESSION['current']->sRealname;
|
||||
$sMsg = $this->objectMakeUrl()."\n";
|
||||
addmsg("Distribution modified.", "green");
|
||||
break;
|
||||
case "delete":
|
||||
$sSubject = "Distribution ".$this->sName." has been deleted by ".$_SESSION['current']->sRealname;
|
||||
|
||||
// if sReplyText is set we should report the reason the data was deleted
|
||||
if($aClean['sReplyText'])
|
||||
{
|
||||
$sMsg .= "Reason given:\n";
|
||||
$sMsg .= $aClean['sReplyText']."\n"; // append the reply text, if there is any
|
||||
}
|
||||
|
||||
addmsg("Distribution deleted.", "green");
|
||||
break;
|
||||
case "reject":
|
||||
$sSubject = "Distribution '".$this->sName." has been rejected by ".
|
||||
$_SESSION['current']->sRealname;
|
||||
$sMsg = $this->objectMakeUrl()."\n";
|
||||
|
||||
// if sReplyText is set we should report the reason the data was rejected
|
||||
if($aClean['sReplyText'])
|
||||
{
|
||||
$sMsg .= "Reason given:\n";
|
||||
$sMsg .= $aClean['sReplyText']."\n"; // append the reply text, if there is any
|
||||
}
|
||||
|
||||
addmsg("Distribution rejected.", "green");
|
||||
break;
|
||||
}
|
||||
$sEmail = User::get_notify_email_address_list(null, null);
|
||||
if($sEmail)
|
||||
mail_appdb($sEmail, $sSubject ,$sMsg);
|
||||
}
|
||||
|
||||
function outputEditor()
|
||||
{
|
||||
echo "<table width='100%' border=0 cellpadding=2 cellspacing=0>\n";
|
||||
|
||||
$this->sName = str_replace('"', '"', $this->sName);
|
||||
// Name
|
||||
echo html_tr(array(
|
||||
array("<b>Distribution Name:</b>", 'align=right class="color0"'),
|
||||
array('<input type=text name="sDistribution" value="'.$this->sName.
|
||||
'" size="60" />', 'class="color0"')
|
||||
));
|
||||
|
||||
// URL
|
||||
echo html_tr(array(
|
||||
array("<b>Distribution URL:</b>", 'align=right class="color0"'),
|
||||
array('<input type=text name="sUrl" value="'.$this->sUrl.
|
||||
'" size="60" />', 'class="color0"')
|
||||
));
|
||||
|
||||
|
||||
echo "</table>\n";
|
||||
|
||||
if($this->iDistributionId)
|
||||
{
|
||||
echo '<input type="hidden" name="iDistributionId" '.
|
||||
'value="'.$this->iDistributionId.'">',"\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* retrieves values from $_REQUEST that were output by outputEditor() */
|
||||
/* $aValues can be $_REQUEST or any array with the values from outputEditor() */
|
||||
function GetOutputEditorValues($aValues)
|
||||
{
|
||||
if($aClean['iDistributionId'])
|
||||
$this->iDistributionId = $aValues['iDistributionId'];
|
||||
|
||||
$this->sName = $aValues['sDistribution'];
|
||||
$this->sUrl = $aValues['sUrl'];
|
||||
}
|
||||
|
||||
function objectGetFilterInfo()
|
||||
{
|
||||
$oFilter = new FilterInterface();
|
||||
|
||||
$oFilter->AddFilterInfo('name', 'Name', array(FILTER_CONTAINS, FILTER_STARTS_WITH, FILTER_ENDS_WITH), FILTER_VALUES_NORMAL);
|
||||
return $oFilter;
|
||||
}
|
||||
|
||||
/* Get the total number of Distributions in the database */
|
||||
function objectGetEntriesCount($sState, $oFilter = null)
|
||||
{
|
||||
/* Not implemented */
|
||||
if($sState == 'rejected')
|
||||
return FALSE;
|
||||
|
||||
$sWhereFilter = $oFilter ? $oFilter->getWhereClause() : '';
|
||||
|
||||
if($sWhereFilter)
|
||||
$sWhereFilter = " AND $sWhereFilter";
|
||||
|
||||
$hResult = query_parameters("SELECT count(distributionId) as num_dists FROM
|
||||
distributions WHERE state='?' $sWhereFilter",
|
||||
$sState);
|
||||
|
||||
if($hResult)
|
||||
{
|
||||
$oRow = query_fetch_object($hResult);
|
||||
return $oRow->num_dists;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Make a dropdown list of distributions */
|
||||
function make_distribution_list($varname, $cvalue)
|
||||
{
|
||||
$sQuery = "SELECT name, distributionId FROM distributions
|
||||
WHERE state = 'accepted'
|
||||
ORDER BY name";
|
||||
$hResult = query_parameters($sQuery);
|
||||
if(!$hResult) return;
|
||||
|
||||
echo "<select name='$varname'>\n";
|
||||
echo "<option value=\"\">Choose ...</option>\n";
|
||||
while(list($name, $value) = query_fetch_row($hResult))
|
||||
{
|
||||
if($value == $cvalue)
|
||||
echo "<option value=$value selected>$name\n";
|
||||
else
|
||||
echo "<option value=$value>$name\n";
|
||||
}
|
||||
echo "</select>\n";
|
||||
}
|
||||
|
||||
function objectGetHeader()
|
||||
{
|
||||
$oTableRow = new TableRowSortable();
|
||||
|
||||
$oTableRow->AddSortableTextCell("Distribution name", "name");
|
||||
|
||||
$oTableCell = new TableCell("Test reports");
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
$oTableRow->AddTextCell("Distribution url");
|
||||
|
||||
return $oTableRow;
|
||||
}
|
||||
|
||||
public static function objectGetSortableFields()
|
||||
{
|
||||
return array('name');
|
||||
}
|
||||
|
||||
public static function objectGetDefaultSort()
|
||||
{
|
||||
return 'name';
|
||||
}
|
||||
|
||||
function objectGetEntries($sState, $iRows = 0, $iStart = 0, $sOrderBy = "name", $bAscending = TRUE, $oFilter = null)
|
||||
{
|
||||
/* Not implemented */
|
||||
if($sState == 'rejected')
|
||||
return FALSE;
|
||||
|
||||
/* Only users with edit privileges are allowed to view queued
|
||||
items, so return NULL in that case */
|
||||
if($sState != 'accepted' && !distribution::canEdit())
|
||||
return NULL;
|
||||
|
||||
$sOrder = $bAscending ? "ASC" : "DESC";
|
||||
|
||||
/* If row limit is 0 we want to fetch all rows */
|
||||
if(!$iRows)
|
||||
$iRows = distribution::objectGetEntriesCount($sState, $oFilter);
|
||||
|
||||
$sWhereFilter = $oFilter ? $oFilter->getWhereClause() : '';
|
||||
|
||||
if($sWhereFilter)
|
||||
$sWhereFilter = " AND $sWhereFilter";
|
||||
|
||||
$sQuery = "SELECT * FROM distributions
|
||||
WHERE state = '?' $sWhereFilter ORDER BY $sOrderBy $sOrder LIMIT ?,?";
|
||||
|
||||
return query_parameters($sQuery, $sState,
|
||||
$iStart, $iRows);
|
||||
}
|
||||
|
||||
function objectGetTableRow()
|
||||
{
|
||||
$oTableRow = new TableRow();
|
||||
|
||||
$oTableRow->AddTextCell($this->objectMakeLink());
|
||||
|
||||
$oTableCell = new TableCell(sizeof($this->aTestingIds));
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
$oTableCell = new TableCell("$this->sUrl");
|
||||
$oTableCell->SetCellLink($this->sUrl);
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
|
||||
// enable the 'delete' action if this distribution has no test results
|
||||
$bDeleteLink = sizeof($this->aTestingIds) ? FALSE : TRUE;
|
||||
|
||||
$oOMTableRow = new OMTableRow($oTableRow);
|
||||
$oOMTableRow->SetHasDeleteLink($bDeleteLink);
|
||||
return $oOMTableRow;
|
||||
}
|
||||
|
||||
public function objectGetState()
|
||||
{
|
||||
return $this->sState;
|
||||
}
|
||||
|
||||
// Whether the user has permission to edit distributions
|
||||
function canEdit()
|
||||
{
|
||||
if($_SESSION['current']->hasPriv("admin"))
|
||||
return TRUE;
|
||||
|
||||
/* Maintainers are allowed to process queued test results and therefore also
|
||||
queued distributions */
|
||||
if(is_object($this) && $this->sState != 'accepted' &&
|
||||
maintainer::isUserMaintainer($_SESSION['current']))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function mustBeQueued()
|
||||
{
|
||||
if($_SESSION['current']->hasPriv("admin") ||
|
||||
maintainer::isUserMaintainer($_SESSION['current']))
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function objectHideDelete()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function display()
|
||||
{
|
||||
echo "Distribution Name:";
|
||||
|
||||
if($this->sUrl)
|
||||
echo "<a href='".$this->sUrl."'>";
|
||||
|
||||
echo $this->sName;
|
||||
|
||||
if ($this->sUrl)
|
||||
{
|
||||
echo " (".$this->sUrl.")";
|
||||
echo "</a> <br>\n";
|
||||
} else
|
||||
{
|
||||
echo "<br>\n";
|
||||
}
|
||||
|
||||
if($this->aTestingIds)
|
||||
{
|
||||
echo '<p><span class="title">Test Results for '.$this->sName.'</span><br>',"\n";
|
||||
echo '<table width="100%" border="1">',"\n";
|
||||
echo '<thead class="historyHeader">',"\n";
|
||||
echo '<tr>',"\n";
|
||||
echo '<td>Application Version</td>',"\n";
|
||||
echo '<td>Submitter</td>',"\n";
|
||||
echo '<td>Date Submitted</td>',"\n";
|
||||
echo '<td>Wine version</td>',"\n";
|
||||
echo '<td>Installs?</td>',"\n";
|
||||
echo '<td>Runs?</td>',"\n";
|
||||
echo '<td>Rating</td>',"\n";
|
||||
echo '</tr></thead>',"\n";
|
||||
foreach($this->aTestingIds as $iTestingId)
|
||||
{
|
||||
$oTest = new testData($iTestingId);
|
||||
|
||||
if($oTest->objectGetState() != $this->objectGetState())
|
||||
continue;
|
||||
|
||||
$oVersion = new Version($oTest->iVersionId);
|
||||
$oApp = new Application($oVersion->iAppId);
|
||||
$oSubmitter = new User($oTest->iSubmitterId);
|
||||
$bgcolor = $oTest->sTestedRating;
|
||||
|
||||
/* make sure the user can view the versions we list in the table */
|
||||
/* otherwise skip over displaying the entries in this table */
|
||||
if(!$_SESSION['current']->canViewApplication($oApp))
|
||||
continue;
|
||||
if(!$_SESSION['current']->canViewVersion($oVersion))
|
||||
continue;
|
||||
|
||||
echo '<tr class='.$bgcolor.'>',"\n";
|
||||
echo '<td><a href="'.$oVersion->objectMakeUrl().'&iTestingId='.$oTest->iTestingId.'">',"\n";
|
||||
echo version::fullName($oVersion->iVersionId).'</a></td>',"\n";
|
||||
echo '<td>',"\n";
|
||||
|
||||
echo $oSubmitter->objectMakeLink();
|
||||
|
||||
echo '</td>',"\n";
|
||||
echo '<td>'.date("M d Y", mysqldatetime_to_unixtimestamp($oTest->sSubmitTime)).'</td>',"\n";
|
||||
echo '<td>'.$oTest->sTestedRelease.' </td>',"\n";
|
||||
echo '<td>'.$oTest->sInstalls.' </td>',"\n";
|
||||
echo '<td>'.$oTest->sRuns.' </td>',"\n";
|
||||
echo '<td>'.$oTest->sTestedRating.' </td>',"\n";
|
||||
if ($_SESSION['current']->hasAppVersionModifyPermission($oVersion))
|
||||
{
|
||||
echo '<td><a href="'.$oTest->objectMakeUrl().'">',"\n";
|
||||
echo 'Edit</a></td>',"\n";
|
||||
}
|
||||
echo '</tr>',"\n";
|
||||
}
|
||||
echo '</table>',"\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* Make a URL for viewing the specified distribution */
|
||||
function objectMakeUrl()
|
||||
{
|
||||
$oObject = new objectManager("distribution", "View Distribution");
|
||||
return $oObject->makeUrl("view", $this->iDistributionId);
|
||||
}
|
||||
|
||||
/* Make an HTML link for viewing the specified distirbution */
|
||||
function objectMakeLink()
|
||||
{
|
||||
return "<a href=\"".$this->objectMakeUrl()."\">$this->sName</a>";
|
||||
}
|
||||
|
||||
function objectMoveChildren($iNewId)
|
||||
{
|
||||
/* Keep track of how many children we modified */
|
||||
$iCount = 0;
|
||||
|
||||
foreach($this->aTestingIds as $iTestId)
|
||||
{
|
||||
$oTest = new testData($iTestId);
|
||||
$oTest->iDistributionId = $iNewId;
|
||||
if($oTest->update(TRUE))
|
||||
$iCount++;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return $iCount;
|
||||
}
|
||||
|
||||
function objectGetItemsPerPage($sState = 'accepted')
|
||||
{
|
||||
$aItemsPerPage = array(25, 50, 100, 200);
|
||||
$iDefaultPerPage = 25;
|
||||
return array($aItemsPerPage, $iDefaultPerPage);
|
||||
}
|
||||
|
||||
function objectGetid()
|
||||
{
|
||||
return $this->iDistributionId;
|
||||
}
|
||||
|
||||
function allowAnonymousSubmissions()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function objectShowAddEntry()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
486
include/downloadurl.php
Normal file
486
include/downloadurl.php
Normal file
@@ -0,0 +1,486 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Functions related to download links
|
||||
*/
|
||||
|
||||
require_once(BASE."include/appData.php");
|
||||
|
||||
class downloadurl
|
||||
{
|
||||
var $iId;
|
||||
var $iVersionId;
|
||||
var $sDescription;
|
||||
var $sUrl;
|
||||
var $sSubmitTime;
|
||||
var $iSubmitterId;
|
||||
var $bQueued;
|
||||
|
||||
/* Fetch the data if id is given */
|
||||
function downloadurl($iId = NULL, $oRow = NULL)
|
||||
{
|
||||
if(!$iId && !$oRow)
|
||||
return;
|
||||
|
||||
if(!$oRow)
|
||||
{
|
||||
$hResult = query_parameters("SELECT id, versionId, description, url,
|
||||
submitTime, submitterId, state FROM appData WHERE id = '?'",
|
||||
$iId);
|
||||
|
||||
if($hResult && query_num_rows($hResult))
|
||||
$oRow = query_fetch_object($hResult);
|
||||
}
|
||||
|
||||
if($oRow)
|
||||
{
|
||||
$this->iId = $oRow->id;
|
||||
$this->iVersionId = $oRow->versionId;
|
||||
$this->sDescription = $oRow->description;
|
||||
$this->sUrl = $oRow->url;
|
||||
$this->sSubmitTime = $oRow->submitTime;
|
||||
$this->iSubmitterId = $oRow->submitterId;
|
||||
$this->bQueued = ($oRow->state == 'queued') ? TRUE : FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Display download links for a given version */
|
||||
function display($iVersionId)
|
||||
{
|
||||
if(!($hResult = appData::getData($iVersionId, "downloadurl")))
|
||||
return FALSE;
|
||||
|
||||
// we're appending, so initialize it
|
||||
$sReturn = '';
|
||||
for($i = 0; $oRow = query_fetch_object($hResult); $i++)
|
||||
{
|
||||
$sReturn .= html_tr(array(
|
||||
"<b>Free Download</b>",
|
||||
"<a href=\"$oRow->url\">$oRow->description</a>"),
|
||||
"color1");
|
||||
}
|
||||
|
||||
return $sReturn;
|
||||
}
|
||||
|
||||
public function objectGetParent($sClass = '')
|
||||
{
|
||||
$oAppData = new appData($this->iId, null, $this);
|
||||
return $oAppData->objectGetParent();
|
||||
}
|
||||
|
||||
public function objectSetParent($iNewId, $sClass = '')
|
||||
{
|
||||
if($this->iVersionId || !$this->iAppId)
|
||||
$this->iVersionId = $iNewId;
|
||||
else
|
||||
$this->iAppId = $iNewId;
|
||||
}
|
||||
|
||||
function objectGetChildren($bIncludeDeleted = false)
|
||||
{
|
||||
/* We have none */
|
||||
return array();
|
||||
}
|
||||
|
||||
/* Output an editor for Download URL fields */
|
||||
function outputEditor($oVersion = null, $sFormAction = null)
|
||||
{
|
||||
/* If we do not get any parameters we try to behave like a proper objectManager
|
||||
object, by only showing an editor for one entry instead of several. This
|
||||
code is sort of hacky, and should be fixed once the rest of the downloadurl
|
||||
code is fully adapted to the objectManager */
|
||||
if(!$oVersion && !$sFormAction)
|
||||
{
|
||||
global $aClean;
|
||||
echo downloadurl::outputEditorSingle($this->iVersionId);
|
||||
}
|
||||
|
||||
if(!$oVersion || !$sFormAction)
|
||||
return FALSE;
|
||||
|
||||
/* Check for correct permissions */
|
||||
if(!downloadurl::canEdit($oVersion->iVersionId))
|
||||
return FALSE;
|
||||
|
||||
$hResult = appData::getData($oVersion->iVersionId, "downloadurl");
|
||||
|
||||
$sReturn .= html_frame_start("Download URL", "90%", "", 0);
|
||||
$sReturn .= "<form method=\"post\" action=\"$sFormAction\">\n";
|
||||
$sReturn .= html_table_begin("border=0 cellpadding=5 cellspacing=0 width=100%");
|
||||
$sReturn .= html_tr(array(
|
||||
array("<b>Remove</b>", "width=\"90\""),
|
||||
"<b>Description</b>",
|
||||
"<b>URL</b>"
|
||||
),
|
||||
"color0");
|
||||
|
||||
$sReturn .= html_tr(array(
|
||||
" ",
|
||||
"<input type=\"text\" size=\"45\" name=\"".
|
||||
"sDescriptionNew\">",
|
||||
"<input type=\"text\" size=\"45\" name=\"sUrlNew\">"),
|
||||
"color4");
|
||||
|
||||
if($hResult)
|
||||
{
|
||||
for($i = 1; $oRow = query_fetch_object($hResult); $i++)
|
||||
{
|
||||
$sReturn .= html_tr(array(
|
||||
"<input type=\"checkbox\" name=\"bRemove$oRow->id\" ".
|
||||
"value=\"true\">",
|
||||
"<input type=\"text\" size=\"45\" name=\"".
|
||||
"sDescription$oRow->id\" value=\"$oRow->description\">",
|
||||
"<input type=\"text\" size=\"45\" name=\"sUrl$oRow->id\" ".
|
||||
"value=\"$oRow->url\">"),
|
||||
($i % 2) ? "color0" : "color4");
|
||||
}
|
||||
}
|
||||
|
||||
$sReturn .= html_table_end();
|
||||
$sReturn .= "<div align=\"center\"><input type=\"submit\" value=\"".
|
||||
"Update Download URLs\" name=\"sSubmit\"></div>\n";
|
||||
$sReturn .= "<input type=\"hidden\" name=\"iVersionId\" ".
|
||||
"value=\"$oVersion->iVersionId\">\n";
|
||||
$sReturn .= "<input type=\"hidden\" name=\"iAppId\" ".
|
||||
"value=\"$oVersion->iAppId\">\n";
|
||||
$sReturn .= "</form>\n";
|
||||
$sReturn .= html_frame_end(" ");
|
||||
|
||||
return $sReturn;
|
||||
}
|
||||
|
||||
function objectGetSubmitterId()
|
||||
{
|
||||
return $this->iSubmitterId;
|
||||
}
|
||||
|
||||
function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return new mailOptions();
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
/* We don't do this at the moment */
|
||||
return array(null, null, null);
|
||||
}
|
||||
|
||||
/* Process data from a Download URL form */
|
||||
function ProcessForm($aValues)
|
||||
{
|
||||
/* Check that we are processing a Download URL form */
|
||||
if($aValues["sSubmit"] != "Update Download URLs")
|
||||
return FALSE;
|
||||
|
||||
/* Check permissions */
|
||||
if(!downloadurl::canEdit($aValues["iVersionId"]))
|
||||
return FALSE;
|
||||
|
||||
if(!($hResult = query_parameters("SELECT COUNT(*) as num FROM appData
|
||||
WHERE TYPE = '?' AND versionId = '?' AND state = 'accepted'",
|
||||
"downloadurl", $aValues["iVersionId"])))
|
||||
return FALSE;
|
||||
|
||||
if(!($oRow = query_fetch_object($hResult)))
|
||||
return FALSE;
|
||||
|
||||
$num = $oRow->num;
|
||||
|
||||
/* Update URLs. Nothing to do if none are present in the database */
|
||||
if($num)
|
||||
{
|
||||
if(!$hResult = appData::getData($aValues["iVersionId"], "downloadurl"))
|
||||
return FALSE;
|
||||
|
||||
while($oRow = query_fetch_object($hResult))
|
||||
{
|
||||
$oDownloadurl = new downloadurl($oRow->id);
|
||||
|
||||
/* Remove URL */
|
||||
if($aValues["bRemove$oRow->id"])
|
||||
{
|
||||
if(!$oDownloadurl->delete())
|
||||
return FALSE;
|
||||
|
||||
$sWhatChangedRemove .= "Removed\nURL: $oRow->url\n".
|
||||
"Description: $oRow->description\n\n";
|
||||
}
|
||||
|
||||
/* Change description/URL */
|
||||
if(($aValues["sDescription$oRow->id"] != $oRow->description or
|
||||
$aValues["sUrl$oRow->id"] != $oRow->url) &&
|
||||
$aValues["sDescription$oRow->id"] && $aValues["sUrl$oRow->id"])
|
||||
{
|
||||
$oDownloadurl->sDescription =
|
||||
$aValues["sDescription$oRow->id"];
|
||||
$oDownloadurl->sUrl = $aValues["sUrl$oRow->id"];
|
||||
|
||||
if(!$oDownloadurl->update())
|
||||
return FALSE;
|
||||
|
||||
$sWhatChangedModify .= "Modified\nOld URL: $oRow->url\nOld ".
|
||||
"Description: $oRow->description\nNew URL: ".
|
||||
$aValues["sUrl$oRow->id"]."\nNew Description: ".
|
||||
$aValues["sDescription$oRow->id"]."\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert new URL */
|
||||
if($aValues["sDescriptionNew"] && $aValues["sUrlNew"])
|
||||
{
|
||||
$oDownloadurl = new downloadurl();
|
||||
$oDownloadurl->iVersionId = $aValues["iVersionId"];
|
||||
$oDownloadurl->sUrl = $aValues["sUrlNew"];
|
||||
$oDownloadurl->sDescription = $aValues["sDescriptionNew"];
|
||||
|
||||
if(!$oDownloadurl->create())
|
||||
return FALSE;
|
||||
|
||||
$sWhatChanged = "Added\nURL: ".$aValues["sUrlNew"]."\nDescription: ".
|
||||
$aValues["sDescriptionNew"]."\n\n";
|
||||
}
|
||||
|
||||
$sWhatChanged .= "$sWhatChangedRemove$sWhatChangedModify";
|
||||
|
||||
if($sWhatChanged && $sEmail =
|
||||
User::get_notify_email_address_list($aValues['iVersionId']))
|
||||
{
|
||||
$oVersion = new Version($aValues["iVersionId"]);
|
||||
|
||||
$sSubject = "Download URLs for ".version::fullName($oVersion->iVersionId).
|
||||
" updated by ".$_SESSION['current']->sRealname;
|
||||
|
||||
$sMsg = $oVersion->objectMakeUrl();
|
||||
$sMsg .= "\n\n";
|
||||
$sMsg .= "The following changed were made\n\n";
|
||||
$sMsg .= "$sWhatChanged\n\n";
|
||||
|
||||
mail_appdb($sEmail, $sSubject, $sMsg);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function objectGetState()
|
||||
{
|
||||
return ($this->bQueued) ? 'queued' : 'accepted';
|
||||
}
|
||||
|
||||
function canEdit($iVersionId = NULL)
|
||||
{
|
||||
if($_SESSION['current']->hasPriv("admin") ||
|
||||
($iVersionId &&
|
||||
maintainer::isUserMaintainer($_SESSION['current'], $iVersionId)))
|
||||
{
|
||||
return TRUE;
|
||||
} else
|
||||
{
|
||||
$oVersion = new version($this->iVersionId);
|
||||
|
||||
return $oVersion->canEdit();
|
||||
}
|
||||
}
|
||||
|
||||
/* Output an editor for a single new URL */
|
||||
function outputEditorSingle($iVersionId = NULL, $aValues = NULL)
|
||||
{
|
||||
if($aValues["sDownloadUrlUrl"] &&
|
||||
$aValues["sDownloadUrlDescription"])
|
||||
{
|
||||
$sDownloadUrlUrl = $aValues["sDownloadUrlUrl"];
|
||||
$sDownloadUrlDescription = $aValues["sDownloadUrlDescription"];
|
||||
} else if($iVersionId)
|
||||
{
|
||||
/* This illustrates the importance of converting downloadurl completely
|
||||
to the objectManager model. If we don't get a match searching for
|
||||
a queued entry, try finding a rejected one. */
|
||||
if(($hResult = appData::getData($iVersionId, "downloadurl",
|
||||
TRUE, TRUE, FALSE)) ||
|
||||
$hResult = appData::getData($iVersionId, "downloadurl",
|
||||
TRUE, TRUE, TRUE))
|
||||
{
|
||||
$oRow = query_fetch_object($hResult);
|
||||
$sDownloadUrlUrl = $oRow->url;
|
||||
$sDownloadUrlDescription = $oRow->description;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$sReturn .= html_frame_start("Download URL","90%");
|
||||
$sReturn .= html_table_begin("width='100%' border=0 cellpadding=2 cellspacing=0");
|
||||
|
||||
$sReturn .= "A place where this version can be downloaded for free".
|
||||
" (if applicable). You can add more links later.<br>";
|
||||
|
||||
$sReturn .= html_tr(array(
|
||||
array("<b>Download URL:</b>", "align=right"),
|
||||
array("<input type=\"text\" name=\"sDownloadUrlUrl\" ".
|
||||
"value=\"$sDownloadUrlUrl\" size=\"60\">",
|
||||
"class=\"color4\"")),
|
||||
"color0");
|
||||
|
||||
$sReturn .= html_tr(array(
|
||||
array("<b>Download URL Description:</b>", "align=right"),
|
||||
array("<input type=\"text\" name=\"sDownloadUrlDescription\" ".
|
||||
"value=\"$sDownloadUrlDescription\" size=\"60\">",
|
||||
"class=\"color4\"")),
|
||||
"color0");
|
||||
|
||||
$sReturn .= html_table_end();
|
||||
$sReturn .= html_frame_end("nbsp;");
|
||||
|
||||
return $sReturn;
|
||||
}
|
||||
|
||||
function create()
|
||||
{
|
||||
if(!$this->sUrl or !$this->sDescription or !$this->iVersionId)
|
||||
return FALSE;
|
||||
|
||||
$hResult = query_parameters("INSERT INTO appData (versionId, type,
|
||||
description, url, state, submitTime, submitterId)
|
||||
VALUES('?', '?', '?', '?', '?', ?, '?')",
|
||||
$this->iVersionId, "downloadurl", $this->sDescription,
|
||||
$this->sUrl,
|
||||
$this->mustBeQueued() ? 'queued' : 'accepted',
|
||||
"NOW()",
|
||||
$_SESSION['current']->iUserId);
|
||||
|
||||
$this->iId = query_appdb_insert_id();
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function update()
|
||||
{
|
||||
if(!$this->bQueued && !$this->canEdit($this->iVersionId))
|
||||
return FALSE;
|
||||
|
||||
if(!$this->sDescription && !$this->sUrl)
|
||||
{
|
||||
$this->delete();
|
||||
return true;
|
||||
}
|
||||
|
||||
$hResult = query_parameters("UPDATE appData SET
|
||||
description = '?', url = '?', versionId = '?' WHERE id = '?'",
|
||||
$this->sDescription, $this->sUrl, $this->iVersionId, $this->iId);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function unQueue()
|
||||
{
|
||||
if($this->mustBeQueued())
|
||||
return FALSE;
|
||||
|
||||
$hResult = query_parameters("UPDATE appData SET state = '?'
|
||||
WHERE id = '?'",
|
||||
'accepted', $this->iId);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function purge()
|
||||
{
|
||||
return $this->delete();
|
||||
}
|
||||
|
||||
function delete()
|
||||
{
|
||||
if(!downloadurl::canEdit($this->iVersionId))
|
||||
return FALSE;
|
||||
|
||||
if(!query_parameters("DELETE FROM appData WHERE id = '?'", $this->iId))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function reQueue()
|
||||
{
|
||||
$oAppData = new AppData($this->iId);
|
||||
|
||||
return $oAppData->reQueue();
|
||||
}
|
||||
|
||||
function reject()
|
||||
{
|
||||
$oAppData = new AppData($this->iId);
|
||||
|
||||
return $oAppData->reject();
|
||||
}
|
||||
|
||||
function objectGetEntries($sState, $iRows = 0, $iStart = 0, $sOrderBy = '', $bAscending = true)
|
||||
{
|
||||
return appData::objectGetEntries($sState, $iRows, $iStart, $sOrderBy, $bAscending, 'downloadurl');
|
||||
}
|
||||
|
||||
function objectGetEntriesCount($sState)
|
||||
{
|
||||
return appData::objectGetEntriesCount($sState, 'downloadurl');
|
||||
}
|
||||
|
||||
function objectGetHeader()
|
||||
{
|
||||
return appData::objectGetHeader("downloadurl");
|
||||
}
|
||||
|
||||
function objectGetTableRow()
|
||||
{
|
||||
$oAppData = new AppData();
|
||||
return $oAppData->objectGetTableRow();
|
||||
}
|
||||
|
||||
function getOutputEditorValues($aClean)
|
||||
{
|
||||
$this->sUrl = $aClean['sDownloadUrlUrl'];
|
||||
$this->sDescription = $aClean['sDownloadUrlDescription'];
|
||||
}
|
||||
|
||||
function mustBeQueued()
|
||||
{
|
||||
if($this)
|
||||
{
|
||||
$oAppData = new appData();
|
||||
$oAppData->iVersionId = $this->iVersionId;
|
||||
$oAppData->iAppId = NULL;
|
||||
return $oAppData->mustBeQueued();
|
||||
} else
|
||||
return appData::mustBeQueued();
|
||||
}
|
||||
|
||||
function allowAnonymousSubmissions()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function objectMakeLink()
|
||||
{
|
||||
/* FIXME: not implemented */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function objectMakeUrl()
|
||||
{
|
||||
/* FIXME: not implemented */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->iId;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
104
include/error_log.php
Normal file
104
include/error_log.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
define("ERROR_SQL", "sql_error");
|
||||
define("ERROR_GENERAL", "general_error");
|
||||
|
||||
class error_log
|
||||
{
|
||||
function log_error($sErrorType, $sLogText)
|
||||
{
|
||||
global $aClean;
|
||||
|
||||
/* dump the contents of $_REQUEST and $aClean to a variable */
|
||||
/* so we can output that to the log entry. it should make it much easier */
|
||||
/* to determine when and where the error took place */
|
||||
ob_start();
|
||||
echo "REQUEST:\n";
|
||||
var_dump($_REQUEST);
|
||||
echo "aClean:\n";
|
||||
var_dump($aClean);
|
||||
$sRequestText = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
$sQuery = 'INSERT INTO error_log (submitTime, userid, type, log_text, request_text, deleted) '.
|
||||
"VALUES(?, '?', '?', '?', '?', '?')";
|
||||
$iUser = (isset($_SESSION['current']) ? $_SESSION['current']->iUserId : 0);
|
||||
$hResult = query_parameters($sQuery,
|
||||
"NOW()",
|
||||
$iUser,
|
||||
$sErrorType,
|
||||
$sLogText,
|
||||
$sRequestText,
|
||||
'0');
|
||||
}
|
||||
|
||||
/* get a backtrace and log it to the database */
|
||||
function logBackTrace($sDescription)
|
||||
{
|
||||
ob_start();
|
||||
print_r(debug_backtrace());
|
||||
$sDebugOutput = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
error_log::log_error("general_error", $sDescription.' '.$sDebugOutput);
|
||||
}
|
||||
|
||||
function getEntryCount()
|
||||
{
|
||||
$sQuery = "SELECT count(*) as cnt FROM error_log WHERE deleted = '0'";
|
||||
$hResult = query_parameters($sQuery);
|
||||
$oRow = query_fetch_object($hResult);
|
||||
return $oRow->cnt;
|
||||
}
|
||||
|
||||
/* purge all of the current entries from the error log */
|
||||
function flush()
|
||||
{
|
||||
$sQuery = "UPDATE error_log SET deleted='1'";
|
||||
$hResult = query_parameters($sQuery);
|
||||
|
||||
if($hResult) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
function mail_admins_error_log($sSubject = "")
|
||||
{
|
||||
$sSubject .= "Database Error log\r\n";
|
||||
$sEmail = User::get_notify_email_address_list(null, null); /* get list admins */
|
||||
|
||||
$sQuery = "SELECT * from error_log WHERE deleted='0' ORDER BY submitTime";
|
||||
$hResult = query_parameters($sQuery);
|
||||
|
||||
$bEmpty = false;
|
||||
if(query_num_rows($hResult) == 0)
|
||||
$bEmpty = true;
|
||||
|
||||
$sMsg = "Log entries:\r\n";
|
||||
$sMsg.= "\r\n";
|
||||
|
||||
$sMsg.= "Submit time userid type\r\n";
|
||||
$sMsg.= "log_text\r\n";
|
||||
$sMsg.= "request_text\r\n";
|
||||
$sMsg.="----------------------------------\r\n\r\n";
|
||||
|
||||
/* append each log entry to $sMsg */
|
||||
while($oRow = query_fetch_object($hResult))
|
||||
{
|
||||
$sMsg.=$oRow->submitTime." ".$oRow->userid." ".$oRow->type."\r\n";
|
||||
$sMsg.= "---------------------\r\n";
|
||||
$sMsg.=$oRow->log_text."\r\n";
|
||||
$sMsg.= "---------------------\r\n";
|
||||
$sMsg.=$oRow->request_text."\r\n\r\n";
|
||||
}
|
||||
|
||||
/* if we had no entries we should indicate */
|
||||
/* that the error log is empty */
|
||||
if($bEmpty)
|
||||
$sMsg = "The error log is empty.\r\n";
|
||||
|
||||
if($sEmail)
|
||||
mail_appdb($sEmail, $sSubject, $sMsg);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
117
include/filter.php
Normal file
117
include/filter.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
$aClean = array();
|
||||
filter_perform_filtering();
|
||||
|
||||
/* perform input variable filtering */
|
||||
function filter_perform_filtering()
|
||||
{
|
||||
// if filtering failed post the error
|
||||
$sResult = filter_gpc();
|
||||
if($sResult)
|
||||
{
|
||||
util_show_error_page_and_exit($sResult);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Make all get/post/cookies variable clean based on their names.
|
||||
* Returns an error string if failure occurs, null if successful
|
||||
*/
|
||||
function filter_gpc()
|
||||
{
|
||||
global $aClean;
|
||||
$sErrorSuggestion = " Please try clearing out your cookies. If the problem continues ".
|
||||
" please email ".APPDB_OWNER_EMAIL." with the error text.";
|
||||
|
||||
$aKeys = array_keys($_REQUEST);
|
||||
for($i=0; $i < sizeof($aKeys); $i++)
|
||||
{
|
||||
// NOTE: useful for debugging
|
||||
//echo "'".$aKeys[$i]."' = '".$_REQUEST[$aKeys[$i]]."'\n";
|
||||
|
||||
// Special cases for variables that don't fit our filtering scheme
|
||||
// don't filter the AppDB session cookie and MAX_FILE_SIZE
|
||||
// and the DialogX values that xinha uses
|
||||
|
||||
// NOTE: we must use === when comparing the return value of strpos
|
||||
// against a value, otherwise if strpos() returns false indicating that
|
||||
// the value wasn't found strpos(something) == 0 will still be true
|
||||
if((strpos($aKeys[$i], "Dialog") === 0) ||
|
||||
(strpos($aKeys[$i], "XinhaColorPicker") === 0) || // Xinha variables
|
||||
($aKeys[$i] == "cx") || // google custom search variable
|
||||
($aKeys[$i] == "cof") || // google custom search variable
|
||||
($aKeys[$i] == "q")) // google custom search variable
|
||||
|
||||
{
|
||||
// copy the key over to the clean array
|
||||
// NOTE: we do not strip html tags or trim any Xinha variables
|
||||
// because Xinha is a html editor and removing html tags
|
||||
// would break the ability to use Xinha to create or edit html
|
||||
$aClean[$aKeys[$i]] = $_REQUEST[$aKeys[$i]];
|
||||
continue; // go to the next entry
|
||||
} else if($aKeys[$i] == "whq_appdb" || ($aKeys[$i] == "MAX_FILE_SIZE")
|
||||
|| ($aKeys[$i] == "PHPSESSID")
|
||||
|| (strpos($aKeys[$i], "pref_") === 0)) // other variables
|
||||
{
|
||||
// copy the key over to the clean array after stripping tags and trimming
|
||||
$aClean[$aKeys[$i]] = trim(strip_tags($_REQUEST[$aKeys[$i]]));
|
||||
continue; // go to the next entry
|
||||
}
|
||||
|
||||
switch($aKeys[$i][0])
|
||||
{
|
||||
case "i": // integer
|
||||
case "f": // float
|
||||
if(is_numeric($_REQUEST[$aKeys[$i]]))
|
||||
$aClean[$aKeys[$i]] = $_REQUEST[$aKeys[$i]];
|
||||
else if(empty($_REQUEST[$aKeys[$i]]))
|
||||
$aClean[$aKeys[$i]] = 0;
|
||||
else if(is_numeric(trim($_REQUEST[$aKeys[$i]]))) // try clearing whitespace
|
||||
$aClean[$aKeys[$i]] = trim($_REQUEST[$aKeys[$i]]);
|
||||
else
|
||||
return "Fatal error: ".$aKeys[$i]." should be a numeric value. ".
|
||||
$sErrorSuggestion;
|
||||
break;
|
||||
case "b": // boolean
|
||||
if($_REQUEST[$aKeys[$i]]=="true" || $_REQUEST[$aKeys[$i]]=="false")
|
||||
$aClean[$aKeys[$i]] = $_REQUEST[$aKeys[$i]];
|
||||
else
|
||||
return "Fatal error: ".$aKeys[$i]." should be a boolean value. ".
|
||||
$sErrorSuggestion;
|
||||
break;
|
||||
case "s": // string
|
||||
switch($aKeys[$i][1])
|
||||
{
|
||||
case "h": // HTML string
|
||||
$aClean[$aKeys[$i]] = trim($_REQUEST[$aKeys[$i]]);
|
||||
// if there is no content and no image, make the variable empty
|
||||
if(strip_tags($aClean[$aKeys[$i]],'<img>')=="")
|
||||
$aClean[$aKeys[$i]] = "";
|
||||
break;
|
||||
default: // normal string (no HTML)
|
||||
$aClean[$aKeys[$i]] = trim(strip_tags($_REQUEST[$aKeys[$i]]));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "a": // array
|
||||
// store the value if it is an array
|
||||
if(is_array($_REQUEST[$aKeys[$i]]))
|
||||
$aClean[$aKeys[$i]] = $_REQUEST[$aKeys[$i]];
|
||||
break;
|
||||
default:
|
||||
// type not recognized, skip it
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* null out all input data so we can be assured that */
|
||||
/* no unfiltered values are being used */
|
||||
$_REQUEST = array();
|
||||
$_POST = array();
|
||||
$_GET = array();
|
||||
if(APPDB_DONT_CLEAR_COOKIES_VAR != "1")
|
||||
$_COOKIES = array();
|
||||
|
||||
return null;
|
||||
}
|
||||
?>
|
||||
15
include/footer.php
Normal file
15
include/footer.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<!-- End Content -->
|
||||
</div>
|
||||
<b class="rbottom"><b class="r4"></b><b class="r3"></b><b class="r2"></b><b class="r1"></b></b>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
Hosted By
|
||||
<a href="http://www.codeweavers.com/"><img src="<?php echo BASE; ?>images/cw_logo_sm.png" alt="CodeWeavers"
|
||||
title="CodeWeavers - Run Windows applications and games on Mac and Linux"></a>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
42
include/form_edit.php
Normal file
42
include/form_edit.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
require_once(BASE."include/util.php");
|
||||
|
||||
/*********************/
|
||||
/* Edit Account Form */
|
||||
/*********************/
|
||||
|
||||
// returns an array of TableRow instances
|
||||
function GetEditAccountFormRows($sUserEmail, $sUserRealname)
|
||||
{
|
||||
$aTableRows = array();
|
||||
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->AddTextCell(" Email Address");
|
||||
$oTableRow->AddTextCell('<input type="text" name="sUserEmail" '.
|
||||
'value="'.$sUserEmail.'">');
|
||||
$aTableRows[] = $oTableRow;
|
||||
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->AddTextCell(" Password");
|
||||
$oTableRow->AddTextCell('<input type="password" name="sUserPassword">');
|
||||
$aTableRows[] = $oTableRow;
|
||||
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->AddTextCell(" Password (again)");
|
||||
$oTableRow->AddTextCell('<input type="password" name="sUserPassword2">');
|
||||
$aTableRows[] = $oTableRow;
|
||||
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->AddTextCell(" Real Name");
|
||||
$oTableRow->AddTextCell('<input type="text" name="sUserRealname" value="'.$sUserRealname.'">');
|
||||
$aTableRows[] = $oTableRow;
|
||||
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->AddTextCell(" ");
|
||||
$oTableRow->AddTextCell(" ");
|
||||
$aTableRows[] = $oTableRow;
|
||||
|
||||
return $aTableRows;
|
||||
}
|
||||
|
||||
?>
|
||||
63
include/form_login.php
Normal file
63
include/form_login.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
require_once(BASE."include/util.php");
|
||||
|
||||
/**************/
|
||||
/* Login Form */
|
||||
/**************/
|
||||
echo "<div class='default_container'>\n";
|
||||
echo '<form method="post" name="sFlogin" action="account.php">',"\n";
|
||||
echo html_frame_start("Login to Application DB","400","",0);
|
||||
/* Pass on the URL we should return to after log-in */
|
||||
global $aClean;
|
||||
echo '<input type="hidden" name="sReturnTo" value="' . (isset($aClean['sReturnTo']) ? $aClean['sReturnTo'] : '') . '">';
|
||||
?>
|
||||
|
||||
<!-- start of login form -->
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
function cmd_send_passwd() {
|
||||
document.sFlogin.sCmd.value = "send_passwd";
|
||||
document.sFlogin.submit();
|
||||
}
|
||||
//-->
|
||||
</script>
|
||||
|
||||
<table border="0" width="100%" cellspacing=0 cellpadding="10">
|
||||
<tr>
|
||||
<td class=color1> E-mail </td>
|
||||
<td class=color0> <input type="text" name="sUserEmail" value='<?php if(!empty($aClean['sUserEmail'])) echo $aClean['sUserEmail']?>'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=color1> Password </td>
|
||||
<td class=color0> <input type="password" name="sUserPassword"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan=2 align=center class=color3>
|
||||
<input type="submit" name="sLogin" value=" Login " class=button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- end of login form -->
|
||||
|
||||
<?php
|
||||
|
||||
echo html_frame_end(" ");
|
||||
echo '<input type="hidden" name="sCmd" value="do_login">',"\n";
|
||||
echo '<input type="hidden" name="sExtReferer" value="'.$_SERVER['HTTP_REFERER'].'">',"\n";
|
||||
echo '</form>',"\n";
|
||||
echo "</div>\n";
|
||||
|
||||
?>
|
||||
|
||||
<p align=center>Don't have an account yet?<br>
|
||||
[<a href="account.php?sCmd=new" onMouseOver="document.status='';return true;">Create a New Account</a>]</p>
|
||||
|
||||
<p align=center>Lost your password?<br>
|
||||
[<a href="javascript:cmd_send_passwd();" onMouseOver="document.status='';return true;">Email a New Password</a>]</p>
|
||||
|
||||
<?php
|
||||
|
||||
echo p(),p(),p();
|
||||
|
||||
?>
|
||||
49
include/form_new.php
Normal file
49
include/form_new.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
require_once(BASE."include/util.php");
|
||||
|
||||
/********************/
|
||||
/* New Account Form */
|
||||
/********************/
|
||||
|
||||
echo "<div class='default_container'>\n";
|
||||
echo '<form method="post" action="account.php">',"\n";
|
||||
echo html_frame_start("Create New Application DB Account","400","",0)
|
||||
?>
|
||||
|
||||
<!-- start of new account form -->
|
||||
The password will be sent to your e-mail
|
||||
<table border=0 width="100%" cellspacing=0 cellpadding=20>
|
||||
<tr>
|
||||
<td class=color1> E-mail </td>
|
||||
<td class=color0> <input type="text" name="sUserEmail" value='<?php if(!empty($aClean['sUserEmail'])) echo $aClean['sUserEmail']?>'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class=color1> Real Name </td>
|
||||
<td class=color0> <input type="text" name="sUserRealname" value='<?php if(!empty($aClean['sUserRealname'])) echo $aClean['sUserRealname']?>'> </td>
|
||||
</tr>
|
||||
<?php
|
||||
|
||||
echo "<tr><td class=color1> Wine version </td><td class=color0>";
|
||||
echo make_bugzilla_version_list("sWineRelease", isset($aClean['sWineRelease']) ? $aClean['sWineRelease'] : '');
|
||||
echo "</td></tr>";
|
||||
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td colspan=2 align=center class=color3>
|
||||
<input type="submit" name="sCreate" value=" Create Account " class=button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- end of new account form -->
|
||||
|
||||
<?php
|
||||
|
||||
echo html_frame_end(" ");
|
||||
echo '<input type="hidden" name="sCmd" value="do_new">',"\n";
|
||||
echo '</form>',"\n";
|
||||
echo "</div>\n";
|
||||
|
||||
echo p(),p(),p();
|
||||
|
||||
?>
|
||||
61
include/header.php
Normal file
61
include/header.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/*********************************/
|
||||
/* Application Database - Header */
|
||||
/*********************************/
|
||||
?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>WineHQ <?php echo $title; ?></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta HTTP-EQUIV="Expires" CONTENT="Mon, 06 Jan 1990 00:00:01 GMT">
|
||||
<meta HTTP-EQUIV="Pragma" CONTENT="no-cache">
|
||||
<meta name="description" content="Open Source Software for running Windows applications on other operating systems.">
|
||||
<meta name="keywords" content="windows, linux, macintosh, solaris, freebsd">
|
||||
<meta name="robots" content="index, follow">
|
||||
<meta name="copyright" content="Copyright WineHQ.org All Rights Reserved.">
|
||||
<meta name="language" content="English">
|
||||
<meta name="revisit-after" content="1">
|
||||
<link rel="stylesheet" href="<?php echo BASE; ?>styles.css" type="text/css" media="screen">
|
||||
<script language="JavaScript" src="<?php echo BASE; ?>jquery.js" type="text/javascript"></script>
|
||||
<script language="JavaScript" src="<?php echo BASE; ?>utils.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" href="<?php echo BASE; ?>apidb.css" type="text/css">
|
||||
<link rel="stylesheet" href="<?php echo BASE; ?>application.css" type="text/css">
|
||||
<script type="text/javascript"
|
||||
src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js"></script>
|
||||
<script src="<?php echo BASE; ?>scripts.js" type="text/javascript"></script>
|
||||
<link rel="icon" type="image/png" href="<?php echo BASE; ?>images/winehq_logo_16.png">
|
||||
<link rel="shortcut icon" type="image/png" href="<?php echo BASE; ?>images/winehq_logo_16.png">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="logo_glass"><a href="<?php echo BASE; ?>"><img src="<?php echo BASE; ?>images/winehq_logo_glass_sm.png" alt=""></a></div>
|
||||
<div id="logo_text"><a href="<?php echo BASE; ?>"><img src="<?php echo BASE; ?>images/winehq_logo_text.png" alt="WineHQ" title="WineHQ"></a></div>
|
||||
|
||||
<div id="logo_blurb"><?php echo preg_replace("/^ - /", "", $title); ?></div>
|
||||
|
||||
<div id="search_box">
|
||||
<form action="http://www.winehq.org/search" id="cse-search-box" style="margin: 0; padding: 0;">
|
||||
<input type="hidden" name="cx" value="partner-pub-0971840239976722:w9sqbcsxtyf">
|
||||
<input type="hidden" name="cof" value="FORID:10">
|
||||
<input type="hidden" name="ie" value="UTF-8">
|
||||
<span style="color: #ffffff;">Search:</span> <input type="text" name="q" size="20">
|
||||
</form>
|
||||
<script type="text/javascript" src="http://www.google.com/coop/cse/brand?form=cse-search-box&lang=en"></script>
|
||||
</div>
|
||||
|
||||
<div id="tabs">
|
||||
<ul>
|
||||
<li><a href="http://www.winehq.org/">WineHQ</a></li>
|
||||
<li><a href="http://wiki.winehq.org/">Wiki</a></li>
|
||||
<li class="s"><a href="http://appdb.winehq.org/">AppDB</a></li>
|
||||
<li><a href="http://bugs.winehq.org/">Bugzilla</a></li>
|
||||
<li><a href="http://forums.winehq.org/">Forums</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="main_content">
|
||||
|
||||
<div class="rbox">
|
||||
<b class="rtop"><b class="r1"></b><b class="r2"></b><b class="r3"></b><b class="r4"></b></b>
|
||||
<div class="content" style="padding: 20px 20px 10px 80px">
|
||||
<!-- Start Content -->
|
||||
340
include/html.php
Normal file
340
include/html.php
Normal file
@@ -0,0 +1,340 @@
|
||||
<?php
|
||||
|
||||
$_indent_level = 0;
|
||||
|
||||
function do_indent($str, $v = 0)
|
||||
{
|
||||
global $_indent_level;
|
||||
|
||||
if($v < 0)
|
||||
$_indent_level += $v;
|
||||
|
||||
if($_indent_level > 0)
|
||||
$str = str_repeat(" ", $_indent_level) . $str;
|
||||
|
||||
if($v > 0)
|
||||
$_indent_level += $v;
|
||||
|
||||
return $str . "\n";
|
||||
}
|
||||
|
||||
function do_html_tr($t, $arr, $class, $extra)
|
||||
{
|
||||
if(strlen($class))
|
||||
$class = " class=\"$class\"";
|
||||
|
||||
/* $extra contains parameters to <tr>, such as valign="top" */
|
||||
if(strlen($extra))
|
||||
$extra = " $extra";
|
||||
|
||||
$str = do_indent("<tr$class$extra>", 1);
|
||||
for($i = 0; $i < sizeof($arr); $i++)
|
||||
{
|
||||
/* If it is not an array, it contains the entire table cell. If it
|
||||
is an array, [0] holds the main content and [1] the options like
|
||||
valign="top" */
|
||||
if(is_array($arr[$i]))
|
||||
{
|
||||
$val = $arr[$i][0];
|
||||
$extra = " ".$arr[$i][1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$val = $arr[$i];
|
||||
$extra = "";
|
||||
}
|
||||
|
||||
if (! $val)
|
||||
{
|
||||
$val = " ";
|
||||
}
|
||||
|
||||
if(stristr($val, "<$t"))
|
||||
{
|
||||
$str .= do_indent($val);
|
||||
}
|
||||
else
|
||||
{
|
||||
$str .= do_indent("<$t$class$extra> ".trim($val)." </$t>", 0);
|
||||
}
|
||||
}
|
||||
$str .= do_indent("</tr>", -1);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
// HTML TR
|
||||
function html_tr($arr, $class = "", $extra = "")
|
||||
{
|
||||
return do_html_tr("td", $arr, $class, $extra);
|
||||
}
|
||||
|
||||
// HTML TABLE
|
||||
function html_table_begin($extra = "")
|
||||
{
|
||||
return do_indent("<table $extra>", 1);
|
||||
}
|
||||
|
||||
function html_table_end()
|
||||
{
|
||||
return do_indent("</table>", -1);
|
||||
}
|
||||
|
||||
|
||||
// HTML HTML
|
||||
function html_begin()
|
||||
{
|
||||
return do_indent("<html>", 1);
|
||||
}
|
||||
|
||||
function html_end()
|
||||
{
|
||||
return do_indent("</html>", -1);
|
||||
}
|
||||
|
||||
|
||||
// HTML HEAD
|
||||
function html_head($title, $stylesheet = 0)
|
||||
{
|
||||
$str = do_indent("<head>", 1);
|
||||
$str .= do_indent("<title> $title </title>", 0);
|
||||
if($stylesheet)
|
||||
$str .= do_indent("<link rel=\"stylesheet\" ".
|
||||
"href=\"$stylesheet\" type=\"text/css\">", 0);
|
||||
$str .= do_indent("</head>", -1);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
// HTML BODY
|
||||
function html_body_begin()
|
||||
{
|
||||
return do_indent("<body>", 1);
|
||||
}
|
||||
|
||||
function html_body_end()
|
||||
{
|
||||
return do_indent("</body>", -1);
|
||||
}
|
||||
|
||||
// HTML A HREF
|
||||
function html_ahref($label, $url, $extra = "")
|
||||
{
|
||||
$label = stripslashes($label);
|
||||
if (!$label and $url)
|
||||
{
|
||||
return do_indent(" <a href=\"$url\" $extra>$url</a> ");
|
||||
}
|
||||
else if (!$label)
|
||||
{
|
||||
return do_indent(" ");
|
||||
}
|
||||
else
|
||||
{
|
||||
return do_indent(" <a href=\"$url\" $extra>$label</a> ");
|
||||
}
|
||||
}
|
||||
|
||||
function html_imagebutton($text, $url, $extra = "")
|
||||
{
|
||||
static $i = 1;
|
||||
|
||||
$i++;
|
||||
$img1 = apidb_url("util/button.php?text=".urlencode($text)."&pressed=0");
|
||||
$img2 = apidb_url("util/button.php?text=".urlencode($text)."&pressed=1");
|
||||
|
||||
$java = "onMouseDown = 'document.img$i.src = \"$img2\"; return true;' ";
|
||||
$java .= "onMouseUp = 'document.img$i.src = \"$img1\"; return true;' ";
|
||||
|
||||
return "\n<a href=\"$url\" $extra $java>\n <img src=\"$img1\" name=\"img$i\" alt=\"$text\"> </a>\n";
|
||||
}
|
||||
|
||||
|
||||
function html_frame_start($title = "", $width = "", $extra = "", $innerPad = 0)
|
||||
{
|
||||
|
||||
if ($width) { $width = 'width="'.$width.'"'; }
|
||||
|
||||
$str = '<table '.$width.' border="0" class="mainTable" cellpadding="0" cellspacing="0" align="center">'."\n";
|
||||
|
||||
if ($title)
|
||||
{
|
||||
$str .= '
|
||||
<tr><td colspan=3><table width="100%" border=0 cellpadding=0 cellspacing=0>
|
||||
<tr><td>
|
||||
<table width="100%" border="0" cellpadding="0" cellspacing="0" class="topMenu">
|
||||
<tr>
|
||||
<td width="100%" rowspan="3" align="center"><span class="menuTitle">'.$title.'</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table></td></tr>
|
||||
';
|
||||
}
|
||||
|
||||
$str .= '
|
||||
<tr>
|
||||
<td><img src="'.BASE.'images/blank.gif" width="5" height="1" alt=""></td>
|
||||
<td width="100%"><table width="100%" border=0 cellpadding=0 cellspacing=0>
|
||||
<tr><td class=topMenu>
|
||||
<table width="100%" border=0 cellpadding="'.$innerPad.'" cellspacing="1" '.$extra.'><tr><td class=white>
|
||||
';
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
function html_frame_end($text = "")
|
||||
{
|
||||
|
||||
$str = '
|
||||
</td></tr></table></td></tr>
|
||||
</table>
|
||||
</td>
|
||||
<td><img src="'.BASE.'images/blank.gif" width="5" height="1" alt=""></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
';
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
|
||||
function html_select($name, $values, $default = null, $descs = null)
|
||||
{
|
||||
$str = "<select name='$name'>\n";
|
||||
while(list($idx, $value) = each($values))
|
||||
{
|
||||
$desc = $value;
|
||||
if($descs)
|
||||
$desc = $descs[$idx];
|
||||
|
||||
if($value == $default)
|
||||
$str .= " <option selected value='$value'>$desc\n";
|
||||
else
|
||||
$str .= " <option value='$value'>$desc\n";
|
||||
}
|
||||
$str .= "</select>\n";
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
function html_back_link($howmany = 1, $url = "")
|
||||
{
|
||||
if (!$url)
|
||||
{
|
||||
$url = 'javascript:history.back('.$howmany.');';
|
||||
}
|
||||
return '<p> <a href="'.htmlentities($url).'"><< Back</a></p>'."\n";
|
||||
}
|
||||
|
||||
|
||||
function p()
|
||||
{
|
||||
return "\n<p> </p>\n";
|
||||
}
|
||||
|
||||
function add_br($text = "")
|
||||
{
|
||||
$text = ereg_replace("\n","<br>\n",$text);
|
||||
return $text;
|
||||
}
|
||||
|
||||
function make_dll_option_list($varname, $dllid = -1)
|
||||
{
|
||||
$db = new ApiDB();
|
||||
|
||||
echo "<select name='$varname'>\n";
|
||||
//echo "<option value='ALL'>ALL\n";
|
||||
$list = $db->get_dll_names();
|
||||
while(list($name, $id) = each($list))
|
||||
{
|
||||
if($dllid == $id)
|
||||
echo "<option value=$id selected>$name ($id)\n";
|
||||
else
|
||||
echo "<option value=$id>$name ($id)\n";
|
||||
}
|
||||
echo "</select>\n";
|
||||
}
|
||||
|
||||
|
||||
function make_inx_option_list($varname, $inx = null)
|
||||
{
|
||||
$list = array("yes", "no", "stub", "unknown");
|
||||
echo "<select name='$varname'>\n";
|
||||
while(list($idx, $value) = each($list))
|
||||
{
|
||||
if($value == $inx)
|
||||
echo "<option value=$value selected>$value\n";
|
||||
else
|
||||
echo "<option value=$value>$value\n";
|
||||
}
|
||||
echo "</select>\n";
|
||||
|
||||
}
|
||||
|
||||
/* Displays a note box */
|
||||
function html_note($shTitle, $shBody)
|
||||
{
|
||||
$shRet = '<div class="note_container">';
|
||||
$shRet .= '<div class="note_title">';
|
||||
$shRet .= $shTitle;
|
||||
$shRet .= '</div>';
|
||||
$shRet .= '<div class="note_body">';
|
||||
$shRet .= $shBody;
|
||||
$shRet .= '</div></div>';
|
||||
|
||||
return $shRet;
|
||||
}
|
||||
|
||||
function html_radiobuttons($aIds, $aOptions, $sName, $sDefault = '')
|
||||
{
|
||||
$shRet = '';
|
||||
|
||||
for($i = 0; $i < sizeof($aIds); $i++)
|
||||
{
|
||||
if($aIds[$i] == $sDefault)
|
||||
$shChecked = ' checked="checked"';
|
||||
else
|
||||
$shChecked = '';
|
||||
|
||||
$shRet .= '<input type="radio" name="'.$sName.'" value="'.$aIds[$i]."\"$shChecked> " . $aOptions[$i].'<br />';
|
||||
}
|
||||
|
||||
return $shRet;
|
||||
}
|
||||
|
||||
function html_checkbox($sName, $sValue, $shText, $bChecked)
|
||||
{
|
||||
if($bChecked)
|
||||
$sSelected = ' checked="checked"';
|
||||
else
|
||||
$sSelected = '';
|
||||
|
||||
return "<input type=\"checkbox\" name=\"$sName\" value=\"$sValue\"$sSelected /> $shText\n";
|
||||
}
|
||||
|
||||
function html_checkboxes($sName, $aValues, $aTexts, $aSelected)
|
||||
{
|
||||
$shRet = '';
|
||||
|
||||
for($i = 0; $i < sizeof($aValues); $i++)
|
||||
$shRet .= html_checkbox($sName.$i, $aValues[$i], $aTexts[$i], $aSelected[$i]).'<br />';
|
||||
|
||||
return $shRet;
|
||||
}
|
||||
|
||||
function html_read_input_series($sName, $aInput, $iCount)
|
||||
{
|
||||
$aRet = array();
|
||||
|
||||
for($i = 0; $i < $iCount; $i++)
|
||||
{
|
||||
$aRet[] = getInput($sName.$i, $aInput);
|
||||
}
|
||||
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
?>
|
||||
439
include/image.php
Normal file
439
include/image.php
Normal file
@@ -0,0 +1,439 @@
|
||||
<?php
|
||||
/*************************************/
|
||||
/* image and image_resource classes */
|
||||
/*************************************/
|
||||
|
||||
/**
|
||||
* Image class for handling screenshot and thumbnail image files.
|
||||
*/
|
||||
class Image {
|
||||
var $sFile; // absolute path from the docroot
|
||||
var $aDebugLog;
|
||||
var $oImage;
|
||||
var $iWidth;
|
||||
var $iHeight;
|
||||
var $iType;
|
||||
|
||||
/**
|
||||
* Constructor:
|
||||
* $sFile is the full path to the image. $this->isLoaded()
|
||||
* should really be checked after making a new object.
|
||||
*/
|
||||
function Image($sPath, $bAbsolutePath=false)
|
||||
{
|
||||
/* if $bAbsolutePath is true we should use the $sPath without modification */
|
||||
/* otherwise use appdb_fullpath() to convert the relative $sPath into a absolute path */
|
||||
if($bAbsolutePath)
|
||||
$this->sFile = $sPath;
|
||||
else /* relative path */
|
||||
$this->sFile = appdb_fullpath($sPath);
|
||||
|
||||
$oInfo = @getimagesize($this->sFile);
|
||||
|
||||
if( empty($oInfo) )
|
||||
{
|
||||
$this->set_debuglog("Failed to load file ".$this->sFile);
|
||||
return;
|
||||
}
|
||||
|
||||
switch( $oInfo[2] )
|
||||
{
|
||||
case 2:
|
||||
$oImage = imagecreatefromjpeg($this->sFile);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
$oImage = imagecreatefrompng($this->sFile);
|
||||
break;
|
||||
|
||||
default;
|
||||
$this->set_debuglog("Image type ({$oInfo[2]}) unknown");
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->oImage = $oImage;
|
||||
$this->iWidth = $oInfo[0];
|
||||
$this->iHeight = $oInfo[1];
|
||||
$this->iType = $oInfo[2];
|
||||
|
||||
$this->set_debuglog("New image class created with as $this->sFile as"
|
||||
." file and {$oInfo[2]} as type. Dimensions"
|
||||
." {$oInfo[0]}x{$oInfo[1]}");
|
||||
}
|
||||
|
||||
/**
|
||||
* isLoaded()
|
||||
* This function should always be checked after loading a file
|
||||
* with the constructor. Returns true if the image has been
|
||||
* successfully loaded.
|
||||
*/
|
||||
function isLoaded()
|
||||
{
|
||||
if($this->iWidth > 0 AND $this->iHeight > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the latest debug log made for the last function. If $bFull is
|
||||
* set it will return the full log as array of the object.
|
||||
*/
|
||||
function get_debuglog($bFull = 0)
|
||||
{
|
||||
if($bFull)
|
||||
return $this->aDebugLog;
|
||||
else
|
||||
return end($this->aDebugLog);
|
||||
}
|
||||
|
||||
function get_width()
|
||||
{
|
||||
return $this->iWidth;
|
||||
}
|
||||
|
||||
function get_height()
|
||||
{
|
||||
return $this->iHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image resource identifier.
|
||||
*/
|
||||
function get_image_resource()
|
||||
{
|
||||
return $this->oImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* make_thumb()
|
||||
*
|
||||
* Calculates resize based on one parameter and calculates the other
|
||||
* with the right aspect ratio. If you want to use $iNewHeight set
|
||||
* $iNewWidth to 0.
|
||||
*
|
||||
* If none are set APPDB_THUMBNAIL_WIDTH is used. If both are set
|
||||
* $iNewWidth is used.
|
||||
*
|
||||
* If you want to make a border, look at resize_image_border() comment
|
||||
* and set $iBorderWidth and $sBorderColor as appropriate.
|
||||
*
|
||||
*/
|
||||
function make_thumb($iNewWidth, $iNewHeight, $iBorderWidth = 0, $sBorderColor = '')
|
||||
{
|
||||
|
||||
if($iNewWidth == 0 AND $iNewHeight == 0)
|
||||
{
|
||||
$iNewWidth = APPDB_THUMBNAIL_WIDTH;
|
||||
$iNewHeight = $this->calculate_proportions($this->iWidth, $this->iHeight,$iNewWidth);
|
||||
}
|
||||
else if($iNewWidth > 0)
|
||||
{
|
||||
$iNewHeight = $this->calculate_proportions($this->iWidth, $this->iHeight,$iNewWidth);
|
||||
}
|
||||
else if($iNewHeight > 0)
|
||||
{
|
||||
$iNewWidth = $this->calculate_proportions($this->iWidth, $this->iHeight, 0, $iNewHeight);
|
||||
}
|
||||
|
||||
$this->set_debuglog("Resizing image to $iNewWidth x $iNewHeight");
|
||||
|
||||
if(!empty($sBorderColor) and $iBorderWidth > 0)
|
||||
$this->resize_image_border($sBorderColor,$iBorderWidth,$iNewHeight,$iNewWidth);
|
||||
else
|
||||
$this->resize_image($iNewWidth,$iNewHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* make_full()
|
||||
*
|
||||
* Function will make sure your image is as big or smaller than the sizes
|
||||
* set here with $max_width and $max_height. Aspect ratio will be mantained.
|
||||
*
|
||||
* If none are set APPDB_SCREENSHOT_MAXWIDTH and APPDB_SCREENSHOT_MAXHEIGHT
|
||||
* are used.
|
||||
*/
|
||||
function make_full($iMaxWidth = 0, $iMaxHeight = 0)
|
||||
{
|
||||
if(!$iMaxWidth > 0)
|
||||
$iMaxWidth = APPDB_SCREENSHOT_MAXWIDTH;
|
||||
|
||||
if(!$iMaxHeight > 0)
|
||||
$iMaxHeight = APPDB_SCREENSHOT_MAXHEIGHT;
|
||||
|
||||
if($this->iWidth > $iMaxWidth)
|
||||
{
|
||||
/* The width is too much */
|
||||
$iNewWidth = $iMaxWidth;
|
||||
$iNewHeight = $this->calculate_proportions($this->iWidth,$this->iHeight,$iNewWidth);
|
||||
|
||||
/* Check if the height is also within the limits */
|
||||
if($iNewHeight > $iMaxHeight )
|
||||
{
|
||||
$iNewWidth = $this->calculate_proportions($iNewWidth,$iNewHeight,0,$iMaxHeight);
|
||||
$iNewHeight = $iMaxHeight;
|
||||
}
|
||||
}
|
||||
else if($this->iHeight > $iMaxHeight)
|
||||
{
|
||||
/* Width was ok, height not */
|
||||
$iNewWidth = $this->calculate_proportions($this->iWidth,$this->iHeight,0,$iMaxHeight);
|
||||
$iNewHeight = $iMaxHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* All ok */
|
||||
$iNewWidth = $this->iWidth;
|
||||
$iNewHeight = $this->iHeight;
|
||||
}
|
||||
|
||||
$this->set_debuglog("Resizing image to $iNewWidth x $iNewHeight");
|
||||
|
||||
$this->resize_image($iNewWidth, $iNewHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* resize_image()
|
||||
*
|
||||
* Resizes the image with the width and height specified with
|
||||
* $iNewHeight and $iNewWidth.
|
||||
*/
|
||||
function resize_image($iNewWidth, $iNewHeight)
|
||||
{
|
||||
// GD 2.x
|
||||
if(function_exists("imagecreatetruecolor"))
|
||||
{
|
||||
$oNewImage = imagecreatetruecolor($iNewWidth, $iNewHeight);
|
||||
imagecopyresampled($oNewImage,$this->oImage,0,0,0,0,
|
||||
$iNewWidth,$iNewHeight,$this->iWidth,$this->iHeight);
|
||||
} else // GD 1.x
|
||||
{
|
||||
$oNewImage = imagecreate($iNewWidth, $iNewHeight);
|
||||
imagecopyresized($oNewImage,$this->oImage,0,0,0,0,
|
||||
$iNewWidth,$iNewHeight,$this->iWidth,$this->iHeight);
|
||||
}
|
||||
|
||||
$this->set_debuglog("imagecopyresized($oNewImage,$this->oImage,0,0,0,0,$iNewWidth,"
|
||||
."$iNewHeight,$this->iWidth,$this->iHeight);");
|
||||
imagedestroy($this->oImage);
|
||||
$this->oImage = $oNewImage;
|
||||
$this->iWidth = $iNewWidth;
|
||||
$this->iHeight= $iNewHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* resize_image_border()
|
||||
*
|
||||
* Resizes the image. With the $iNewWidth + $iBorderWidth*2
|
||||
* and $iNewHeight + $iBorderWidth*2 as size. $sBorderColor is a
|
||||
* HTML hexadecimal color (like #0000FF)
|
||||
*/
|
||||
function resize_image_border($sBorderColor, $iBorderWidth, $iNewHeight, $iNewWidth)
|
||||
{
|
||||
$r = hexdec(substr($sBorderColor, 1, 2));
|
||||
$g = hexdec(substr($sBorderColor, 3, 2));
|
||||
$b = hexdec(substr($sBorderColor, 5, 2));
|
||||
|
||||
/* We multiply the border width by two because there are borders
|
||||
on both sides */
|
||||
// GD 2.x
|
||||
if(function_exists("imagecreatetruecolor"))
|
||||
{
|
||||
$new = imagecreatetruecolor($iNewWidth + ($iBorderWidth*2), $iNewHeight + ($iBorderWidth*2));
|
||||
} else // GD 1.x
|
||||
{
|
||||
$new = imagecreate($iNewWidth + ($iBorderWidth*2), $iNewHeight + ($iBorderWidth*2));
|
||||
}
|
||||
|
||||
/* Make the border by filling it completely,
|
||||
later on we will overwrite everything except the border */
|
||||
$color = ImageColorAllocate( $new, $r, $g, $b );
|
||||
imagefill($new,0,0,$color);
|
||||
|
||||
// GD 2.x
|
||||
if(function_exists("imagecopyresampled"))
|
||||
{
|
||||
imagecopyresampled($new,$this->oImage,$iBorderWidth,$iBorderWidth,
|
||||
0,0, $iNewWidth,$iNewHeight,
|
||||
$this->iWidth,$this->iHeight);
|
||||
} else // GD 1.x
|
||||
{
|
||||
imagecopyresized($new,$this->oImage,$iBorderWidth,$iBorderWidth,
|
||||
0,0,$iNewWidth,$iNewHeight,
|
||||
$this->iWidth,$this->iHeight);
|
||||
}
|
||||
|
||||
$this->set_debuglog("imagecopyresized($new,$this->oImage,$iBorderWidth,$iBorderWidth,0,0,"
|
||||
." $iNewWidth,$iNewHeight,$this->iWidth,$this->iHeight); with a $iBorderWidth px border"
|
||||
." in $sBorderColor");
|
||||
imagedestroy($this->oImage);
|
||||
$this->oImage = $new;
|
||||
$this->iWidth = $iNewWidth;
|
||||
$this->iHeight= $iNewHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* add_watermark()
|
||||
*
|
||||
* $watermark is an image resource identifier to any image resource.
|
||||
*
|
||||
* $min_mark_wwidth and $min_mark_height are the minimum sizes of the
|
||||
* destination image before the watermark is added. If none are set
|
||||
* both will be 0.
|
||||
*
|
||||
* A warning for transparency. If you resize an image down with make_thumb()
|
||||
* you loose the transparency on png images.
|
||||
*/
|
||||
function add_watermark($oWatermark, $iMinMarkWidth = 0, $iMinMarkHeight = 0)
|
||||
{
|
||||
$iWatermarkWidth = imagesx($oWatermark);
|
||||
$iWatermarkHeight = imagesy($oWatermark);
|
||||
|
||||
if($this->iWidth > $iMinMarkWidth AND
|
||||
$this->iHeight > $iMinMarkHeight)
|
||||
{
|
||||
$iWatermark_x = $this->iWidth - $iWatermarkWidth;
|
||||
$iWatermark_y = $this->iHeight - $iWatermarkHeight;
|
||||
|
||||
imagecopy($this->oImage, $oWatermark, $iWatermark_x, $iWatermark_y,
|
||||
0, 0, $iWatermarkWidth, $iWatermarkHeight);
|
||||
|
||||
$this->set_debuglog("imagecopy($this->oImage, $oWatermark,"
|
||||
."$iWatermark_x, $iWatermark_y, 0, 0,"
|
||||
."$iWatermarkWidth, $iWatermarkHeight);");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the image to a file set with $store.
|
||||
*
|
||||
* $iType is optional and is set like the second index of getimagesize().
|
||||
* If none (or 0) is set the original type of the file is used.
|
||||
* If $store is not give, the current file name will be used.
|
||||
* $quality is the jpeg output quality (100 best, 0 worst). Default is 75
|
||||
*/
|
||||
function output_to_file($sOutputFilename=null, $iType = 0, $iQuality = 75)
|
||||
{
|
||||
if(!$sOutputFilename)
|
||||
$sOutputFilename = $this->sFile;
|
||||
if($iType == 0)
|
||||
$iType = $this->iType;
|
||||
|
||||
switch($iType)
|
||||
{
|
||||
case 2:
|
||||
imagejpeg($this->oImage, $sOutputFilename, $iQuality);
|
||||
$this->set_debuglog("Saved file as jpeg to $sOutputFilename");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
imagepng($this->oImage, $sOutputFilename);
|
||||
$this->set_debuglog("Saved file as png to $sOutputFilename");
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->set_debuglog("Unknown output type");
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the files to the browser.
|
||||
*
|
||||
* If $bHeader is true a Content-type header with the correct type
|
||||
* is set.
|
||||
* $iType is optional and is set like the second index of getimagesize().
|
||||
* If none (or 0) is set the original type of the file is used.
|
||||
*
|
||||
* $iQuality is the jpeg output quality (100 best, 0 worst)
|
||||
*/
|
||||
function output_to_browser($bHeader, $iType = 0, $iQuality = 75)
|
||||
{
|
||||
if($iType == 0 )
|
||||
$iType = $this->iType;
|
||||
|
||||
switch($iType)
|
||||
{
|
||||
case 2:
|
||||
if($bHeader)
|
||||
header('Content-type: image/jpeg');
|
||||
imagejpeg($this->oImage,'',$iQuality);
|
||||
$this->set_debuglog("Outputed file as jpeg to browser");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if($bHeader)
|
||||
header('Content-type: image/png');
|
||||
imagepng($this->oImage);
|
||||
$this->set_debuglog("Outputed file as png to browser");
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->set_debuglog("Unknown output type");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the image resource. Be sure to do this at the end of your
|
||||
* actions with this object.
|
||||
*/
|
||||
function destroy()
|
||||
{
|
||||
if(is_resource($this->oImage))
|
||||
imagedestroy($this->oImage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the screenshot from the file system.
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
// if the file exists, delete it
|
||||
if(is_file($this->sFile))
|
||||
unlink($this->sFile);
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
* PRIVATE FUNCTIONS
|
||||
************************/
|
||||
|
||||
function set_debuglog( $sLog )
|
||||
{
|
||||
$this->aDebugLog[] = $sLog;
|
||||
}
|
||||
|
||||
function calculate_proportions($iWidth, $iHeight,
|
||||
$iNewWidth, $iNewHeight = '0')
|
||||
{
|
||||
if($iNewWidth > 0)
|
||||
// we want to calculate the new height
|
||||
return ($iHeight * $iNewWidth) / $iWidth;
|
||||
else if( $iNewHeight > 0 )
|
||||
return ($iWidth * $iNewHeight) / $iHeight;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class ImageResource extends Image {
|
||||
|
||||
function ImageResource($oImage,$iType)
|
||||
{
|
||||
|
||||
$this->oImage = $oImage;
|
||||
$this->iWidth = imagesx($oImage);
|
||||
$this->iHeight = imagesy($oImage);
|
||||
$this->iType = $iType;
|
||||
|
||||
$this->set_debuglog("New image class created with $oImage as"
|
||||
." image resource and $iType as type. Dimensions"
|
||||
." {$this->iWidth}x{$this->iHeight}");
|
||||
}
|
||||
}
|
||||
?>
|
||||
301
include/incl.php
Normal file
301
include/incl.php
Normal file
@@ -0,0 +1,301 @@
|
||||
<?php
|
||||
/*************************************************/
|
||||
/* Main Include Library for Application Database */
|
||||
/*************************************************/
|
||||
|
||||
// get modules
|
||||
ini_set("memory_limit","64M");
|
||||
require_once(BASE."include/config.php");
|
||||
require(BASE."include/util.php");
|
||||
require(BASE."include/user.php");
|
||||
require(BASE."include/session.php");
|
||||
require(BASE."include/menu.php");
|
||||
require(BASE."include/html.php");
|
||||
require(BASE."include/error_log.php");
|
||||
require(BASE."include/query.php");
|
||||
require(BASE."include/table.php");
|
||||
require_once(BASE."include/objectManager.php");
|
||||
|
||||
/* if magic quotes are enabled make sure the user disables them */
|
||||
/* otherwise they will see all kinds of odd effects that are difficult */
|
||||
/* to track down */
|
||||
if(get_magic_quotes_gpc())
|
||||
{
|
||||
echo "<b>Please disable the magic quotes GPC PHP setting. See <a href=\"http://us2.php.net/manual/en/ref.info.php#ini.magic-quotes-gpc\"> this page</a> for more information</b><br><br>";
|
||||
echo "AppDB php code assumes magic quotes are disabled.<br><br>";
|
||||
echo "Magic quotes are a bad idea for a few reasons.<br><br>";
|
||||
echo "First is that php calls <b>addslashes()</b> on all \$_POST, \$_REQUEST and cookie variables ";
|
||||
echo "if magic quotes is enabled. ";
|
||||
echo "Ooooooh you say.<br>";
|
||||
echo "<i>\"Aren't magic quotes a convienent way to protect my php code from sql injection attacks?\"</i><br><br>";
|
||||
echo "No! <b>addslashes()</b> isn't adequate. You should use <b>query_escape_string()</b> or some other function";
|
||||
echo " that will handle multi-byte characters. See <a href=\"http://shiflett.org/archive/184\">this article</a>";
|
||||
echo " for a way to exploit <b>addslash()</b>ed parameters.<br><br>";
|
||||
echo "A second reason is that with magic quotes enabled, due to the use of <b>query_escape_string()</b> to";
|
||||
echo " protect from sql injection attacks we'll end up with variables that have been addslash()ed and";
|
||||
echo " <b>query_escape_string()</b>ed. So you end up having to call stripslashes() on EVERY variable. ";
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* rename $_REQUEST variables to preserve backwards compatibility
|
||||
* with bugzilla links and urls in emails and on google from before our
|
||||
* mass rename of GPC variables to use our coding standard prefixing
|
||||
*
|
||||
* NOTE: we may be able to remove these backwareds compatibility changes
|
||||
* in a few years, check in mid 2007 to see how many old
|
||||
* links are still poping up in google then
|
||||
*/
|
||||
if(isset($_REQUEST['versionId']))
|
||||
{
|
||||
$_REQUEST['iVersionId'] = $_REQUEST['versionId'];
|
||||
unset($_REQUEST['versionId']);
|
||||
}
|
||||
if(isset($_REQUEST['appId']))
|
||||
{
|
||||
$_REQUEST['iAppId'] = $_REQUEST['appId'];
|
||||
unset($_REQUEST['appId']);
|
||||
}
|
||||
if(isset($_REQUEST['bug_id']))
|
||||
{
|
||||
$_REQUEST['iBugId'] = $_REQUEST['bug_id'];
|
||||
unset($_REQUEST['bug_id']);
|
||||
}
|
||||
if(isset($_REQUEST['catId']))
|
||||
{
|
||||
$_REQUEST['iCatId'] = $_REQUEST['catId'];
|
||||
unset($_REQUEST['catId']);
|
||||
}
|
||||
if(isset($_REQUEST['sub']))
|
||||
{
|
||||
$_REQUEST['sSub'] = $_REQUEST['sub'];
|
||||
unset($_REQUEST['sub']);
|
||||
}
|
||||
if(isset($_REQUEST['topic']))
|
||||
{
|
||||
$_REQUEST['sTopic'] = $_REQUEST['topic'];
|
||||
unset($_REQUEST['topic']);
|
||||
}
|
||||
if(isset($_REQUEST['mode']))
|
||||
{
|
||||
$_REQUEST['sMode'] = $_REQUEST['mode'];
|
||||
unset($_REQUEST['mode']);
|
||||
}
|
||||
/* End backwards compatibility code */
|
||||
|
||||
// create arrays
|
||||
$sidebar_func_list = array();
|
||||
$help_list = array();
|
||||
|
||||
function apidb_help_add($desc, $id)
|
||||
{
|
||||
global $help_list;
|
||||
$help_list[] = array($desc, $id);
|
||||
}
|
||||
|
||||
|
||||
// return url with docroot prepended
|
||||
function apidb_url($path)
|
||||
{
|
||||
return BASE.$path;
|
||||
}
|
||||
|
||||
// return FULL url with docroot prepended
|
||||
function apidb_fullurl($path = "")
|
||||
{
|
||||
return BASE.$path;
|
||||
}
|
||||
|
||||
function appdb_fullpath($path)
|
||||
{
|
||||
/* IE: we know this file is in /yyy/xxx/include, we want to get the /yyy/xxx
|
||||
/* so we call dirname on this file path twice */
|
||||
$fullpath = dirname(dirname(__FILE__))."//".$path;
|
||||
/* get rid of potential double slashes due to string concat */
|
||||
return str_replace("//", "/", $fullpath);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* output the common apidb header
|
||||
*/
|
||||
function apidb_header($title = 0)
|
||||
{
|
||||
$realname = $_SESSION['current']->sRealname;
|
||||
|
||||
// Set Page Title
|
||||
$page_title = $title;
|
||||
if ($title)
|
||||
$title = " - $title";
|
||||
|
||||
// grab the starting time
|
||||
global $sPageGeneratingStartTime;
|
||||
$sPageGeneratingStartTime = microtime();
|
||||
$aStartarray = explode(" ", $sPageGeneratingStartTime);
|
||||
$sPageGeneratingStartTime = $aStartarray[1] + $aStartarray[0];
|
||||
|
||||
// Display Header
|
||||
include(BASE."include/header.php");
|
||||
|
||||
// Display Sidebar
|
||||
apidb_sidebar();
|
||||
|
||||
// Display Status Messages
|
||||
dumpmsgbuffer();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* output the common apidb footer
|
||||
*/
|
||||
function apidb_footer()
|
||||
{
|
||||
// grab the end of the page generating time
|
||||
global $sPageGeneratingStartTime;
|
||||
$sPageGeneratingEndTime = microtime();
|
||||
$aEndarray = explode(" ", $sPageGeneratingEndTime);
|
||||
$sPageGeneratingEndTime = $aEndarray[1] + $aEndarray[0];
|
||||
$sTotaltime = $sPageGeneratingEndTime - $sPageGeneratingStartTime;
|
||||
$sTotaltime = round($sTotaltime,5);
|
||||
echo "<center>Page loaded in <b>$sTotaltime</b> seconds.</center>";
|
||||
|
||||
// Display Footer
|
||||
if(!isset($header_disabled))
|
||||
include(BASE."include/"."footer.php");
|
||||
}
|
||||
|
||||
/*
|
||||
* output the sidebar, calls all functions registered with apidb_sidebar_add
|
||||
*/
|
||||
function apidb_sidebar()
|
||||
{
|
||||
global $sidebar_func_list;
|
||||
|
||||
echo '
|
||||
<div id="sidebar">
|
||||
<ul>
|
||||
';
|
||||
|
||||
//TURN on GLOBAL ADMIN MENU
|
||||
if ($_SESSION['current']->hasPriv("admin"))
|
||||
{
|
||||
include(BASE."include/sidebar_admin.php");
|
||||
apidb_sidebar_add("global_admin_menu");
|
||||
} else if($_SESSION['current']->isMaintainer()) /* if the user maintains anything, add their menus */
|
||||
{
|
||||
include(BASE."include/sidebar_maintainer_admin.php");
|
||||
apidb_sidebar_add("global_maintainer_admin_menu");
|
||||
}
|
||||
|
||||
// Login Menu
|
||||
include(BASE."include/sidebar_login.php");
|
||||
apidb_sidebar_add("global_sidebar_login");
|
||||
|
||||
// Main Menu
|
||||
include(BASE."include/sidebar.php");
|
||||
apidb_sidebar_add("global_sidebar_menu");
|
||||
|
||||
//LOOP and display menus
|
||||
for($i = 0; $i < sizeof($sidebar_func_list); $i++)
|
||||
{
|
||||
$func = $sidebar_func_list[$i];
|
||||
$func();
|
||||
}
|
||||
|
||||
echo '
|
||||
</ul>
|
||||
</div>
|
||||
';
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* register a sidebar menu function
|
||||
* the supplied function is called when the sidebar is built
|
||||
*/
|
||||
function apidb_sidebar_add($funcname)
|
||||
{
|
||||
global $sidebar_func_list;
|
||||
array_unshift($sidebar_func_list, $funcname);
|
||||
}
|
||||
|
||||
|
||||
function apidb_image($name)
|
||||
{
|
||||
return BASE."images/$name";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* format a date as required for HTTP by RFC 2068 sec 3.3.1
|
||||
*/
|
||||
function fHttpDate($iDate) {
|
||||
return gmdate("D, d M Y H:i:s",$iDate)." GMT";
|
||||
}
|
||||
|
||||
/**
|
||||
* parse all the date formats required by HTTP 1.1 into PHP time values
|
||||
*/
|
||||
function pHttpDate($sDate) {
|
||||
$iDate = strtotime($sDate);
|
||||
if ($iDate != -1) return $iDate;
|
||||
/* the RFC also requires asctime() format... */
|
||||
$aTs = strptime($sDate,"%a %b %e %H:%M:%S %Y");
|
||||
$iDate = gmmktime($aTs[2],$aTs[1],$aTs[0],$aTs[4],$aTs[3],$aTs[5],0);
|
||||
return $iDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* msgs will be displayed on the Next page view of the same user
|
||||
*/
|
||||
function addmsg($shText, $color = "black")
|
||||
{
|
||||
$GLOBALS['session']->addmsg($shText, $color);
|
||||
}
|
||||
|
||||
|
||||
function purgeSessionMessages()
|
||||
{
|
||||
$GLOBALS['session']->purgemsg();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* output msg_buffer and clear it.
|
||||
*/
|
||||
function dumpmsgbuffer()
|
||||
{
|
||||
$GLOBALS['session']->dumpmsgbuffer();
|
||||
if (is_array($GLOBALS['session']->msg) and count($GLOBALS['session']->msg) > 0)
|
||||
{
|
||||
echo html_frame_start("","300","",5);
|
||||
foreach ($GLOBALS['session']->msg as $msg)
|
||||
{
|
||||
if ($msg['color'] == "red")
|
||||
$msg['color'] = "{$msg['color']}; text-decoration: blink;";
|
||||
echo "<div align=\"center\" class=\"session_note\" style=\"color: {$msg['color']};\"> {$msg['msg']} </div>";
|
||||
}
|
||||
echo html_frame_end(" ");
|
||||
echo "<br>\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Session (stores user info in session)
|
||||
*/
|
||||
$session = new session("whq_appdb");
|
||||
$session->register("current");
|
||||
|
||||
if(!isset($_SESSION['current']))
|
||||
{
|
||||
$_SESSION['current'] = new User();
|
||||
}
|
||||
|
||||
// if we are debugging we need to see all errors
|
||||
if($_SESSION['current']->showDebuggingInfos()) error_reporting(E_ALL ^ E_NOTICE);
|
||||
|
||||
// include filter.php to filter all REQUEST input
|
||||
require(BASE."include/filter.php");
|
||||
|
||||
?>
|
||||
48
include/mail.php
Normal file
48
include/mail.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
require_once(BASE."include/config.php");
|
||||
|
||||
function mail_appdb($sEmailList,$sSubject,$sMsg)
|
||||
{
|
||||
// NOTE: For AppDB developers: If email is disabled return from this function
|
||||
// immediately. See include/config.php.sample for information
|
||||
if(defined("DISABLE_EMAIL"))
|
||||
return;
|
||||
|
||||
$sEmailListComma = str_replace(" ",",",$sEmailList);
|
||||
|
||||
$sHeaders = "MIME-Version: 1.0\r\n";
|
||||
$sHeaders .= "From: AppDB <".APPDB_SENDER_EMAIL.">\r\n";
|
||||
$sHeaders .= "Reply-to: AppDB <".APPDB_SENDER_EMAIL.">\r\n";
|
||||
$sHeaders .= "Bcc: $sEmailListComma\r\n";
|
||||
$sHeaders .= "X-Priority: 3\r\n";
|
||||
$sHeaders .= "X-Mailer: ".APPDB_OWNER." mailer\r\n";
|
||||
$sMsg = trim(ereg_replace("\r\n","\n",$sMsg));
|
||||
$sMsg = $sSubject."\n-------------------------------------------------------\n".$sMsg."\n\n";
|
||||
$sMsg .= "Best regards.\n";
|
||||
$sMsg .= "The AppDB team\n";
|
||||
$sMsg .= APPDB_ROOT."\n";
|
||||
$sMsg .= "\n\nIf you don't want to receive any other e-mail, please change your preferences:\n";
|
||||
$sMsg .= APPDB_ROOT."preferences.php\n";
|
||||
|
||||
/* Print the message to the screen instead of sending it, if the PRINT_EMAIL
|
||||
option is set. Output in purple to distinguish it from other messages */
|
||||
if(defined("PRINT_EMAIL"))
|
||||
{
|
||||
$sMsg = str_replace("\n", "<br>", $sMsg);
|
||||
addmsg("This mail would have been sent<br><br>".
|
||||
"To: $sEmailList<br>".
|
||||
"Subject: $sSubject<br><br>".
|
||||
"Body:<br>$sMsg", "purple");
|
||||
return;
|
||||
}
|
||||
|
||||
$sMsg = html_entity_decode($sMsg);
|
||||
$bResult = mail(APPDB_SENDER_EMAIL, "[AppDB] ".$sSubject, $sMsg, $sHeaders,
|
||||
"-f".APPDB_SENDER_EMAIL);
|
||||
if($bResult)
|
||||
addmsg("E-mail sent", "green");
|
||||
else
|
||||
addmsg("Error while sending e-mail", "red");
|
||||
return $bResult;
|
||||
}
|
||||
?>
|
||||
1414
include/maintainer.php
Normal file
1414
include/maintainer.php
Normal file
File diff suppressed because it is too large
Load Diff
151
include/maintainerView.php
Normal file
151
include/maintainerView.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class to show an overview of a user's maintainership, including apps maintained
|
||||
* and their ratings
|
||||
*/
|
||||
class maintainerView
|
||||
{
|
||||
var $iUserId;
|
||||
var $bViewingSelf;
|
||||
|
||||
function maintainerView($iUserId = null)
|
||||
{
|
||||
if(!$iUserId)
|
||||
$this->iUserId = $_SESSION['current']->iUserId;
|
||||
else
|
||||
$this->iUserId = $iUserId;
|
||||
|
||||
if(!$iUserId || $this->iUserId == $_SESSION['current']->iUserId)
|
||||
$this->bViewingSelf = true;
|
||||
else
|
||||
$this->bViewingSelf = false;
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->iUserId;
|
||||
}
|
||||
|
||||
/* We don't queue this class or process it in any way */
|
||||
function objectGetState()
|
||||
{
|
||||
return 'accepted';
|
||||
}
|
||||
|
||||
function addVersionRatingInfo($oTableRow, $oVersion)
|
||||
{
|
||||
$oTableRow->AddTextCell($oVersion->objectMakeLink());
|
||||
|
||||
/* Rating info */
|
||||
$oTableCell = new TableCell($oVersion->sTestedRating);
|
||||
$oTableCell->SetClass($oVersion->sTestedRating);
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
$oTableCell = new TableCell($oVersion->sTestedRelease);
|
||||
$oTableCell->SetClass($oVersion->sTestedRating);
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
/* Get test reports submitted by the user */
|
||||
$aTestData = testData::getTestResultsForUser($this->iUserId,
|
||||
$oVersion->iVersionId);
|
||||
|
||||
if(sizeof($aTestData))
|
||||
{
|
||||
$oTest = $aTestData[0];
|
||||
$sUserRating = $oTest->sTestedRating;
|
||||
$sUserRelease = $oTest->sTestedRelease;
|
||||
} else
|
||||
{
|
||||
$sUserRating = '';
|
||||
$sUserRelease = '';
|
||||
}
|
||||
|
||||
$oTableCell = new TableCell($sUserRating);
|
||||
$oTableCell->SetClass($sUserRating);
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
$oTableCell = new TableCell($sUserRelease);
|
||||
$oTableCell->SetClass($sUserRating);
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
return $oTableRow;
|
||||
}
|
||||
|
||||
/* Shows a detailed vis of the user's maintained applications,
|
||||
including last tested release & rating */
|
||||
function display()
|
||||
{
|
||||
$oUser = new user($this->iUserId);
|
||||
|
||||
$aMaintainedApps = maintainer::getAppsMaintained($oUser);
|
||||
if(!$aMaintainedApps || !sizeof($aMaintainedApps))
|
||||
{
|
||||
if($this->bViewingSelf)
|
||||
echo '<p>You do not maintain any apps</p>';
|
||||
else
|
||||
echo "<p>{$oUser->sRealname} does not maintain any apps</p>";
|
||||
return;
|
||||
}
|
||||
|
||||
if($this->bViewingSelf)
|
||||
echo '<p>Viewing your maintained apps</p>';
|
||||
else
|
||||
echo "<p>Viewing {$oUser->sRealname}'s maintained apps</p>";
|
||||
|
||||
$oTable = new Table();
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->setClass('color4');
|
||||
$oTable->setCellSpacing(0);
|
||||
$oTable->setCellPadding(3);
|
||||
$oTableRow->AddTextCell('Application');
|
||||
$oTableRow->AddTextCell('Version');
|
||||
$oTableRow->AddTextCell('Current Rating');
|
||||
$oTableRow->AddTextCell('Current Version');
|
||||
$oTableRow->AddTextCell($this->bViewingSelf ? 'Your Rating' : "User's Rating");
|
||||
$oTableRow->AddTextCell($this->bViewingSelf ? 'Your Version' : "User's Version");
|
||||
$oTable->AddRow($oTableRow);
|
||||
|
||||
$i = 1;
|
||||
while(list($iIndex, list($iAppId, $iVersionId, $bSuperMaintainer)) = each($aMaintainedApps))
|
||||
{
|
||||
$oApp = new application($iAppId);
|
||||
$aVersions = array();
|
||||
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->AddTextCell($oApp->objectMakeLink());
|
||||
|
||||
$oTableRow->SetClass(($i % 2) ? 'color0' : 'color1');
|
||||
$i++;
|
||||
|
||||
if($iVersionId)
|
||||
{
|
||||
$oVersion = new version($iVersionId);
|
||||
$oTableRow = maintainerView::addVersionRatingInfo($oTableRow, $oVersion);
|
||||
$oTable->AddRow($oTableRow);
|
||||
} else
|
||||
{
|
||||
$aVersions = $oApp->getVersions(true);
|
||||
$oTableRow->AddTextCell('*');
|
||||
$oTableRow->AddTextCell('');
|
||||
$oTableRow->AddTextCell('');
|
||||
$oTableRow->AddTextCell('');
|
||||
$oTableRow->AddTextCell('');
|
||||
$oTable->AddRow($oTableRow);
|
||||
}
|
||||
|
||||
foreach($aVersions as $oVersion)
|
||||
{
|
||||
$oTableRow = new TableRow($oTableRow);
|
||||
$oTableRow->AddTextCell('');
|
||||
$oTableRow = maintainerView::addVersionRatingInfo($oTableRow, $oVersion);
|
||||
|
||||
$oTableRow->SetClass(($i % 2) ? 'color0' : 'color1');
|
||||
$i++;
|
||||
|
||||
$oTable->AddRow($oTableRow);
|
||||
}
|
||||
}
|
||||
echo $oTable->GetString();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
46
include/menu.php
Normal file
46
include/menu.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
class htmlmenu {
|
||||
|
||||
function htmlmenu($name, $form = null)
|
||||
{
|
||||
|
||||
if ($form)
|
||||
echo "<form action=\"$form\" method=\"post\">\n";
|
||||
|
||||
echo '
|
||||
<li class="top"><p>'.$name.'</p></li>
|
||||
';
|
||||
|
||||
}
|
||||
|
||||
/* add a table row */
|
||||
function add($sName, $shUrl = null, $sAlign = "left")
|
||||
{
|
||||
$oTableRow = new TableRow();
|
||||
|
||||
if($shUrl)
|
||||
{
|
||||
echo " <li><p><a href=\"{$shUrl}\">{$sName}</a></p></li>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo " <li><p>{$sName}</a></li>\n";
|
||||
}
|
||||
}
|
||||
|
||||
function addmisc($sStuff, $sAlign = "left")
|
||||
{
|
||||
echo "<li><p style=\"text-align: $sAlign\">$sStuff</p></li>\n";
|
||||
}
|
||||
|
||||
function done($form = null)
|
||||
{
|
||||
echo '
|
||||
<li class="bot"></li>
|
||||
';
|
||||
|
||||
if ($form)
|
||||
echo "</form>\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
387
include/monitor.php
Normal file
387
include/monitor.php
Normal file
@@ -0,0 +1,387 @@
|
||||
<?php
|
||||
/***************************************/
|
||||
/* Monitor class and related functions */
|
||||
/***************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Monitor class for handling Monitors
|
||||
*/
|
||||
class Monitor {
|
||||
var $iMonitorId;
|
||||
|
||||
// variables necessary for creating a monitor
|
||||
var $iAppId;
|
||||
var $iVersionId;
|
||||
var $iUserId;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* If $iMonitorId is provided, fetches Monitor.
|
||||
*/
|
||||
function Monitor($iMonitorId="", $oRow = null)
|
||||
{
|
||||
if(!$iMonitorId && !$oRow)
|
||||
return;
|
||||
|
||||
if(!$oRow)
|
||||
{
|
||||
$sQuery = "SELECT *
|
||||
FROM appMonitors
|
||||
WHERE monitorId = '".$iMonitorId."'";
|
||||
$hResult = query_appdb($sQuery);
|
||||
$oRow = query_fetch_object($hResult);
|
||||
}
|
||||
|
||||
if($oRow)
|
||||
{
|
||||
$this->iMonitorId = $oRow->monitorId;
|
||||
$this->iAppId = $oRow->appId;
|
||||
$this->iVersionId = $oRow->versionId;
|
||||
$this->iUserId = $oRow->userId;
|
||||
}
|
||||
}
|
||||
|
||||
function find($iUserId, $iVersionId=0)
|
||||
{
|
||||
if($iUserId && $iVersionId)
|
||||
{
|
||||
$sQuery = "SELECT *
|
||||
FROM appMonitors
|
||||
WHERE userId = '".$iUserId."'
|
||||
AND versionId = '".$iVersionId."'";
|
||||
$hResult = query_appdb($sQuery);
|
||||
if( $oRow = query_fetch_object($hResult) )
|
||||
{
|
||||
$this->iMonitorId = $oRow->monitorId;
|
||||
$this->iAppId = $oRow->appId;
|
||||
$this->iVersionId = $oRow->versionId;
|
||||
$this->iUserId = $oRow->userId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function objectGetParent($sClass = '')
|
||||
{
|
||||
if($this->iVersionId)
|
||||
return new version($this->iVersionId);
|
||||
else
|
||||
return new application($this->iAppId);
|
||||
}
|
||||
|
||||
public function objectSetParent($iNewId, $sClass = '')
|
||||
{
|
||||
if($this->iVersionId)
|
||||
$this->iVersionId = $iNewId;
|
||||
else
|
||||
$this->iAppId = $iNewId;
|
||||
}
|
||||
|
||||
function objectGetChildren($bIncludeDeleted = false)
|
||||
{
|
||||
/* We have none */
|
||||
return array();
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a new Monitor.
|
||||
* Informs interested people about the creation.
|
||||
* Returns true on success, false on failure
|
||||
*/
|
||||
function create()
|
||||
{
|
||||
/* Check for duplicate entries */
|
||||
$oMonitor = new monitor();
|
||||
$this->iUserId = $_SESSION['current']->iUserId;
|
||||
$oMonitor->find($this->iUserId, $this->iVersionId);
|
||||
if($oMonitor->iVersionId)
|
||||
return FALSE;
|
||||
|
||||
// create the new monitor entry
|
||||
$hResult = query_parameters("INSERT INTO appMonitors (versionId, appId,".
|
||||
"submitTime, userId) ".
|
||||
"VALUES ('?', '?', ?, '?')",
|
||||
$this->iVersionId, $this->iAppId,
|
||||
"NOW()", $this->iUserId);
|
||||
|
||||
if($hResult)
|
||||
{
|
||||
$this->Monitor(query_appdb_insert_id());
|
||||
$sWhatChanged = "New monitor\n\n";
|
||||
$this->SendNotificationMail("add", $sWhatChanged);
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
addmsg("Error while creating a new Monitor.", "red");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function update()
|
||||
{
|
||||
$oMonitor = new monitor($this->iMonitorId);
|
||||
|
||||
if($this->iVersionId && $oMonitor->iVersionId != $this->iVersionId)
|
||||
{
|
||||
$hResult = query_parameters("UPDATE appMonitors SET versionId = '?'
|
||||
WHERE monitorId = '?'",
|
||||
$this->iVersionId, $this->iMonitorId);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if($this->iAppId && $oMonitor->iAppId != $this->iAppId)
|
||||
{
|
||||
$hResult = query_parameters("UPDATE appMonitors SET appId = '?'
|
||||
WHERE monitorId = '?'",
|
||||
$this->iAppId, $this->iMonitorId);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function unQueue()
|
||||
{
|
||||
return true; // We don't queue monitors
|
||||
}
|
||||
|
||||
function objectGetSubmitterId()
|
||||
{
|
||||
return $this->iUserId;
|
||||
}
|
||||
|
||||
function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return new mailOptions();
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
$sSubject = null;
|
||||
$sMsg = null;
|
||||
|
||||
if($this->iVersionId)
|
||||
{
|
||||
$sWhat = "version";
|
||||
$sName = version::fullName($this->iVersionId);
|
||||
$oVersion = new version($this->iVersionId);
|
||||
$sUrl = $oVersion->objectMakeUrl();
|
||||
} else
|
||||
{
|
||||
$sWhat = "application";
|
||||
$oApp = new application($this->iAppId);
|
||||
$sName = $oApp->sName;
|
||||
$sUrl = $oApp->objectMakeUrl();
|
||||
}
|
||||
|
||||
if($bMailSubmitter)
|
||||
{
|
||||
switch($sAction)
|
||||
{
|
||||
case "delete":
|
||||
if($bParentActino)
|
||||
{
|
||||
$sSubject = "Monitored $sWhat deleted";
|
||||
$sMsg = "The $sWhat $sName which you monitored has been ".
|
||||
"deleted by ".$_SESSION['current']->iUserId.".";
|
||||
}
|
||||
break;
|
||||
}
|
||||
$aMailTo = null;
|
||||
} else
|
||||
{
|
||||
$oUser = new user($this->iUserId);
|
||||
$sUser = $oUser->sName;
|
||||
switch($sAction)
|
||||
{
|
||||
case "delete":
|
||||
if(!$bParentAction)
|
||||
{
|
||||
$sSubject = "Monitor for $sName removed: $sUser";
|
||||
$sMsg = $sUrl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
User::get_notify_email_address_list(null, $this->iVersionId);
|
||||
}
|
||||
return array($sSubject, $sMsg, $aMailTo);
|
||||
}
|
||||
|
||||
function purge()
|
||||
{
|
||||
return $this->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the current Monitor from the database.
|
||||
* Informs interested people about the deletion.
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
$hResult = query_parameters("DELETE FROM appMonitors WHERE monitorId = '?'", $this->iMonitorId);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function SendNotificationMail($sAction="add",$sMsg=null)
|
||||
{
|
||||
/* Set variables depending on whether it is an application or version monitor */
|
||||
if(isset($this->iVersionId))
|
||||
{
|
||||
$oVersion = new version($this->iVersionId);
|
||||
$sAppName = version::fullName($this->iVersionId);
|
||||
$sUrl = $oVersion->objectMakeUrl();
|
||||
$sVersion = " version";
|
||||
} else
|
||||
{
|
||||
$oApp = new application($this->iAppId);
|
||||
$sAppName = Application::lookup_name($this->iAppId);
|
||||
$sUrl = $oApp->objectMakeUrl();
|
||||
}
|
||||
|
||||
switch($sAction)
|
||||
{
|
||||
case "add":
|
||||
$sSubject = "Monitor for ".$sAppName;
|
||||
$sSubject .= " added: ".$_SESSION['current']->sRealname;
|
||||
$sMsg .= "$sUrl\n";
|
||||
addmsg("You will now receive an email whenever changes are made ".
|
||||
"to this application$sVersion.", "green");
|
||||
break;
|
||||
case "delete":
|
||||
$sSubject = "Monitor for ".$sAppName;
|
||||
$sSubject .= " removed: ".$_SESSION['current']->sRealname;
|
||||
$sMsg .= "$sUrl\n";
|
||||
addmsg("You will no longer receive an email whenever changes ".
|
||||
"are made to this application$sVersion.", "green");
|
||||
break;
|
||||
}
|
||||
$sEmail = User::get_notify_email_address_list(null, $this->iVersionId);
|
||||
if($sEmail)
|
||||
mail_appdb($sEmail, $sSubject ,$sMsg);
|
||||
}
|
||||
|
||||
function objectGetState()
|
||||
{
|
||||
// We don't queue monitors
|
||||
return 'accepted';
|
||||
}
|
||||
|
||||
function canEdit()
|
||||
{
|
||||
if($_SESSION['current']->hasPriv("admin") ||
|
||||
($this->iUserId == $_SESSION['current']->iUserId))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function mustBeQueued()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Stub */
|
||||
function display()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Stub */
|
||||
function getOutputEditorValues($aClean)
|
||||
{
|
||||
$this->iVersionId = $aClean['iVersionId'];
|
||||
$this->iAppId = $aClean['iAppId'];
|
||||
}
|
||||
|
||||
/* Stub */
|
||||
function objectGetHeader()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->iMonitorId;
|
||||
}
|
||||
|
||||
/* Stub */
|
||||
function objectGetTableRow()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Stub */
|
||||
function objectMakeLink()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Stub */
|
||||
function objectMakeUrl()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Stub */
|
||||
function outputEditor()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
function objectGetEntries($sState, $iRows = 0, $iStart = 0, $sOrderBy = '', $bAscending = true)
|
||||
{
|
||||
$hResult = query_parameters("SELECT * FROM appMonitors");
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
function objectGetEntriesCount($sState)
|
||||
{
|
||||
$hResult = query_parameters("SELECT COUNT(DISTINCT monitorId) as count
|
||||
FROM appMonitors");
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
$oRow = query_fetch_object($hResult);
|
||||
|
||||
if(!$oRow)
|
||||
return FALSE;
|
||||
|
||||
return $oRow->count;
|
||||
}
|
||||
|
||||
function allowAnonymousSubmissions()
|
||||
{
|
||||
/* That makes no sense */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Retrieve the user's monitored versions */
|
||||
function getVersionsMonitored($oUser)
|
||||
{
|
||||
$hResult = query_parameters("SELECT appId, versionId FROM appMonitors WHERE userId = '?'", $oUser->iUserId);
|
||||
|
||||
if(!$hResult || query_num_rows($hResult) == 0)
|
||||
return NULL;
|
||||
|
||||
$aVersionsMonitored = array();
|
||||
|
||||
for($i = 0; $oRow = query_fetch_object($hResult); $i++)
|
||||
$aVersionsMonitored[$i] = array($oRow->appId, $oRow->versionId);
|
||||
|
||||
return $aVersionsMonitored;
|
||||
}
|
||||
}
|
||||
?>
|
||||
877
include/note.php
Normal file
877
include/note.php
Normal file
@@ -0,0 +1,877 @@
|
||||
<?php
|
||||
require_once(BASE."include/util.php");
|
||||
require_once(BASE."include/version.php");
|
||||
|
||||
/************************************/
|
||||
/* note class and related functions */
|
||||
/************************************/
|
||||
|
||||
|
||||
define('APPNOTE_SHOW_FOR_ALL', -1);
|
||||
define('APPNOTE_SHOW_FOR_VERSIONS', -2);
|
||||
define('APPNOTE_SHOW_FOR_APP', -3);
|
||||
define('APPNOTE_SHOW_FOR_SPECIFIC_VERSIONS', -4);
|
||||
|
||||
/**
|
||||
* Note class for handling notes
|
||||
*/
|
||||
class Note {
|
||||
var $iNoteId;
|
||||
var $iVersionId;
|
||||
var $iAppId;
|
||||
var $sTitle;
|
||||
var $shDescription;
|
||||
var $iSubmitterId;
|
||||
var $sSubmitTime;
|
||||
var $iLinkedWith;
|
||||
var $aNoteLinks;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* If $iNoteId is provided, fetches note.
|
||||
*/
|
||||
function Note($iNoteId = null, $oRow = null)
|
||||
{
|
||||
$this->aNoteLinks = array();
|
||||
|
||||
if(!$iNoteId && !$oRow)
|
||||
return;
|
||||
|
||||
if(!$oRow)
|
||||
{
|
||||
$sQuery = "SELECT * FROM appNotes WHERE noteId = '?'";
|
||||
if($hResult = query_parameters($sQuery, $iNoteId))
|
||||
$oRow = query_fetch_object($hResult);
|
||||
}
|
||||
|
||||
if($oRow)
|
||||
{
|
||||
$this->iNoteId = $oRow->noteId;
|
||||
$this->iVersionId = $oRow->versionId;
|
||||
$this->iAppId = $oRow->appId;
|
||||
$this->sTitle = $oRow->noteTitle;
|
||||
$this->shDescription = $oRow->noteDesc;
|
||||
$this->sSubmitTime = $oRow->submitTime;
|
||||
$this->iSubmitterId = $oRow->submitterId;
|
||||
$this->iLinkedWith = $oRow->linkedWith;
|
||||
$this->aNoteLinks = $this->objectGetChildren();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Creates a new note.
|
||||
* Informs interested people about the creation.
|
||||
* Returns true on success, false on failure
|
||||
*/
|
||||
function create()
|
||||
{
|
||||
$hResult = query_parameters("INSERT INTO appNotes (versionId, ".
|
||||
"appId, noteTitle, noteDesc, submitterId, ".
|
||||
"submitTime) ".
|
||||
"VALUES('?', '?', '?', '?', '?', ?)",
|
||||
$this->iVersionId, $this->iAppId,
|
||||
$this->sTitle, $this->shDescription,
|
||||
$_SESSION['current']->iUserId,
|
||||
"NOW()");
|
||||
|
||||
if($hResult)
|
||||
{
|
||||
// We need to backup the noteLinks array
|
||||
$aNoteLinks = $this->aNoteLinks;
|
||||
$this->note(query_appdb_insert_id());
|
||||
|
||||
foreach($aNoteLinks as $oLink)
|
||||
{
|
||||
$oLink->objectSetParent($this->iNoteId, 'note');
|
||||
$this->aNoteLinks[] = $oLink;
|
||||
}
|
||||
|
||||
$this->saveNoteLinks(true);
|
||||
$sWhatChanged = "Description is:\n".$this->shDescription.".\n\n";
|
||||
$this->SendNotificationMail("add", $sWhatChanged);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
addmsg("Error while creating a new note.", "red");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function unQueue()
|
||||
{
|
||||
return true; // We don't queue notes
|
||||
}
|
||||
|
||||
/**
|
||||
* Update note.
|
||||
* Returns true on success and false on failure.
|
||||
*/
|
||||
function update()
|
||||
{
|
||||
$sWhatChanged = "";
|
||||
|
||||
/* create an instance of ourselves so we can see what has changed */
|
||||
$oNote = new Note($this->iNoteId);
|
||||
|
||||
if ($this->sTitle && $this->sTitle!=$oNote->sTitle)
|
||||
{
|
||||
if (!query_parameters("UPDATE appNotes SET noteTitle = '?' WHERE noteId = '?'",
|
||||
$this->sTitle, $this->iNoteId))
|
||||
return false;
|
||||
$sWhatChanged .= "Title was changed from ".$oNote->sTitle." to ".$this->sTitle.".\n\n";
|
||||
}
|
||||
|
||||
if ($this->shDescription && $this->shDescription!=$oNote->shDescription)
|
||||
{
|
||||
if (!query_parameters("UPDATE appNotes SET noteDesc = '?' WHERE noteId = '?'",
|
||||
$this->shDescription, $this->iNoteId))
|
||||
return false;
|
||||
$sWhatChanged .= "Description was changed from\n ".$oNote->shDescription."\n to \n".$this->shDescription.".\n\n";
|
||||
}
|
||||
|
||||
if($this->iVersionId == APPNOTE_SHOW_FOR_SPECIFIC_VERSIONS && (sizeof($this->aNoteLinks) == 1))
|
||||
{
|
||||
$oLink = $this->aNoteLinks[0];
|
||||
$this->iVersionId = $oLink->objectGetParent('version');
|
||||
$this->iAppId = 0;
|
||||
$oLink->delete();
|
||||
}
|
||||
|
||||
if (($this->iVersionId || $this->iAppId) && $this->iVersionId!=$oNote->iVersionId)
|
||||
{
|
||||
if (!query_parameters("UPDATE appNotes SET versionId = '?' WHERE noteId = '?'",
|
||||
$this->iVersionId, $this->iNoteId))
|
||||
return false;
|
||||
|
||||
if(!$this->iAppId && !$oNote->iAppId) // Changed version only
|
||||
{
|
||||
$sVersionBefore = Version::lookup_name($oNote->iVersionId);
|
||||
$sVersionAfter = Version::lookup_name($this->iVersionId);
|
||||
$sWhatChanged .= "Version was changed from ".$sVersionBefore." to ".$sVersionAfter.".\n\n";
|
||||
} else if(!$this->iAppId) // Moved from app to version
|
||||
{
|
||||
$sVersionAfter = Version::fullName($this->iVersionId);
|
||||
$oApp = new application($oNote->iAppId);
|
||||
$sOldApp = $oApp->sName;
|
||||
$sWhatChanged .= "Moved from application $sOldApp to version $sVersionAfter.\n\n";
|
||||
} else if($oNote->hasRealVersionId()) // Moved from version to app
|
||||
{
|
||||
$oApp = new application($this->iAppId);
|
||||
$sNewApp = $oApp->sName;
|
||||
$sVersionBefore = version::fullName($oNote->iVersionId);
|
||||
$sWhatChanged .= "Moved from version $sVersionBefore to application $sNewApp.\n\n";
|
||||
} else // Change display mode for app note
|
||||
{
|
||||
$sOldMode = $oNote->getDisplayModeName();
|
||||
$sNewMode = $this->getDisplayModeName();
|
||||
$sWhatChanged .= "Display mode was changed from '$sOldMode' to '$sNewMode'.\n\n";
|
||||
}
|
||||
}
|
||||
if (($this->iAppId || $this->iVersionId) && $this->iAppId!=$oNote->iAppId)
|
||||
{
|
||||
if(!query_parameters("UPDATE appNotes SET appId = '?' WHERE noteId = '?'",
|
||||
$this->iAppId, $this->iNoteId))
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->saveNoteLinks();
|
||||
|
||||
if($sWhatChanged)
|
||||
$this->SendNotificationMail("edit",$sWhatChanged);
|
||||
return true;
|
||||
}
|
||||
|
||||
function purge()
|
||||
{
|
||||
return $this->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the current note from the database.
|
||||
* Informs interested people about the deletion.
|
||||
*
|
||||
* Returns: true if successful, false if not
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
$hResult = query_parameters("DELETE FROM appNotes WHERE noteId = '?'", $this->iNoteId);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function objectShowPreview()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function SendNotificationMail($sAction="add",$sMsg=null)
|
||||
{
|
||||
if(!$this->iAppId)
|
||||
{
|
||||
$oVersion = new version($this->iVersionId);
|
||||
$sAppName = version::fullName($this->iVersionId);
|
||||
$sMsg .= $oVersion->objectMakeUrl()."\n";
|
||||
} else
|
||||
{
|
||||
$oApp = new application($this->iAppId);
|
||||
$sAppName = $oApp->sName;
|
||||
$sMsg .= $oApp->objectMakeUrl()."\n";
|
||||
}
|
||||
|
||||
switch($sAction)
|
||||
{
|
||||
case "add":
|
||||
$sSubject = "Note $this->sTitle for $sAppName added by ".
|
||||
$_SESSION['current']->sRealname;
|
||||
addmsg("The note was successfully added into the database.", "green");
|
||||
break;
|
||||
case "edit":
|
||||
$sSubject = "Note $this->sTitle for $sAppName has been modified by ".
|
||||
$_SESSION['current']->sRealname;
|
||||
addmsg("Note modified.", "green");
|
||||
break;
|
||||
case "delete":
|
||||
$oSubmitter = new User($this->iSubmitterId);
|
||||
$sSubject = "Note $this->sTitle for $sAppName has been deleted by ".
|
||||
$_SESSION['current']->sRealname;
|
||||
$sMsg .= "This note was made on ".print_date(mysqldatetime_to_unixtimestamp($this->sSubmitTime)).
|
||||
" by ".$oSubmitter->sRealname."\n";
|
||||
$sMsg .= "\n";
|
||||
$sMsg .= "Subject: ".$this->sTitle."\n";
|
||||
$sMsg .= "\n";
|
||||
$sMsg .= "Note contents:\n";
|
||||
$sMsg .= $this->shDescription."\n";
|
||||
$sMsg .= "\n";
|
||||
$sMsg .= "Because:\n";
|
||||
if(isset($aClean['sReplyText']) && $aClean['sReplyText'])
|
||||
$sMsg .= $aClean['sReplyText']."\n";
|
||||
else
|
||||
$sMsg .= "No reason given.\n";
|
||||
|
||||
addmsg("Note deleted.", "green");
|
||||
break;
|
||||
}
|
||||
$sEmail = User::get_notify_email_address_list(null, $this->iVersionId);
|
||||
if($sEmail)
|
||||
mail_appdb($sEmail, $sSubject ,$sMsg);
|
||||
}
|
||||
|
||||
/* Show note */
|
||||
/* $bDisplayOnly means we should not display any editing controls, even if */
|
||||
/* the user has the ability to edit this note */
|
||||
function display($aVars = null)
|
||||
{
|
||||
switch($this->sTitle)
|
||||
{
|
||||
case 'WARNING':
|
||||
$sClass = 'warning';
|
||||
$sTitle = 'Warning';
|
||||
break;
|
||||
|
||||
case 'HOWTO':
|
||||
$sClass = 'howto';
|
||||
$sTitle = 'HOWTO';
|
||||
break;
|
||||
|
||||
default:
|
||||
if(!empty($this->sTitle))
|
||||
$sTitle = $this->sTitle;
|
||||
else
|
||||
$sTitle = 'Note';
|
||||
|
||||
$sClass = 'defaultnote';
|
||||
}
|
||||
|
||||
if(!$aVars || !getInput('shReturnTo', $aVars))
|
||||
{
|
||||
$oVersion = new version($this->iVersionId);
|
||||
$shReturnTo = $oVersion->objectMakeUrl();
|
||||
} else
|
||||
{
|
||||
$shReturnTo = $aVars['shReturnTo'];
|
||||
}
|
||||
|
||||
$shOutput = html_frame_start("","98%",'',0);
|
||||
|
||||
$shOutput .= "<table width=\"100%\" border=\"0\" cellspacing=\"0\">\n";
|
||||
$shOutput .= "<tr class=\"".$sClass."\" align=\"center\" valign=\"top\"><td> </td></tr><tr class=\"notetitle\" valign=\"top\" align=\"center\"><td>".$sTitle."</td></tr>\n";
|
||||
$shOutput .= "<tr><td class=\"note\">\n";
|
||||
$shOutput .= $this->shDescription;
|
||||
$shOutput .= "</td></tr>\n";
|
||||
|
||||
if((!$aVars || $aVars['bEditing'] != "true") && $this->canEdit())
|
||||
{
|
||||
$shOutput .= "<tr class=\"color1\" align=\"center\" valign=\"top\"><td>";
|
||||
$shOutput .= "<form method=\"post\" name=\"message\" action=\"objectManager.php?sClass=note&sAction=edit&iId=".$this->iNoteId."&sReturnTo=".urlencode($shReturnTo)."\">";
|
||||
$shOutput .= '<input type="submit" value="Edit note" class="button">';
|
||||
$shOutput .= '</form></td></tr>';
|
||||
}
|
||||
|
||||
$shOutput .= "</table>\n";
|
||||
$shOutput .= html_frame_end();
|
||||
|
||||
echo $shOutput;
|
||||
}
|
||||
|
||||
function displayNotesForEntry($iVersionId, $iAppId = null)
|
||||
{
|
||||
if($iVersionId)
|
||||
{
|
||||
$oVersion = new version($iVersionId);
|
||||
$oApp = $oVersion->objectGetParent();
|
||||
$hResult = query_parameters("SELECT noteId FROM appNotes WHERE versionId = '?' OR (appId = '?' AND (versionId = '?' OR versionId = '?')) ORDER BY versionId,noteId", $iVersionId, $oApp->objectGetId(), APPNOTE_SHOW_FOR_ALL, APPNOTE_SHOW_FOR_VERSIONS);
|
||||
} else if($iAppId)
|
||||
{
|
||||
$hResult = query_parameters("SELECT noteId FROM appNotes WHERE appId = '?' AND (versionId = '?' OR versionId = '?')", $iAppId, APPNOTE_SHOW_FOR_ALL, APPNOTE_SHOW_FOR_APP);
|
||||
}
|
||||
|
||||
if(!$hResult)
|
||||
return;
|
||||
|
||||
if($iVersionId)
|
||||
$oVersion = new version($iVersionId);
|
||||
else
|
||||
$oApp = new application($iAppId);
|
||||
|
||||
while($oRow = mysql_fetch_object($hResult))
|
||||
{
|
||||
$oNote = new note($oRow->noteId);
|
||||
|
||||
$shReturnTo = $iVersionId ? $oVersion->objectMakeUrl() : $oApp->objectMakeUrl();
|
||||
|
||||
$aVars = array('shReturnTo' => $shReturnTo, 'bEditing' => 'false');
|
||||
|
||||
$oLink = $oNote->getLink();
|
||||
|
||||
if($oLink)
|
||||
$oLink->display($aVars);
|
||||
else
|
||||
$oNote->display($aVars);
|
||||
}
|
||||
}
|
||||
|
||||
function objectGetCustomVars($sAction)
|
||||
{
|
||||
switch($sAction)
|
||||
{
|
||||
case "preview":
|
||||
return array("bEditing");
|
||||
|
||||
case "add":
|
||||
return array('iVersionId','iAppId','sNoteTitle');
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static function isRealVersionId($iVersionId)
|
||||
{
|
||||
return $iVersionId > 0;
|
||||
}
|
||||
|
||||
public function hasRealVersionId()
|
||||
{
|
||||
return note::isRealVersionId($this->iVersionId);
|
||||
}
|
||||
|
||||
public static function getDisplayModeIds()
|
||||
{
|
||||
return array(APPNOTE_SHOW_FOR_ALL, APPNOTE_SHOW_FOR_VERSIONS, APPNOTE_SHOW_FOR_APP, APPNOTE_SHOW_FOR_SPECIFIC_VERSIONS);
|
||||
}
|
||||
|
||||
public static function getDisplayModeNames()
|
||||
{
|
||||
return array('Show on both application and version pages', 'Show on all version pages only', 'Show on application page only', 'Show on the following version pages only:');
|
||||
}
|
||||
|
||||
public function getDisplayModeName($iModeId = null)
|
||||
{
|
||||
if(!$iModeId)
|
||||
$iModeId = $this->iVersionId;
|
||||
|
||||
$aNames = note::getDisplayModeNames();
|
||||
$iIndex = 0;
|
||||
|
||||
foreach(note::getDisplayModeIds() as $iId)
|
||||
{
|
||||
if($iId == $iModeId)
|
||||
return $aNames[$iIndex];
|
||||
$iIndex++;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public function findLink($iVersionId, $bQueryDB = true)
|
||||
{
|
||||
if($bQueryDB)
|
||||
{
|
||||
// If we don't have a noteId we can't be linked to anything
|
||||
if(!$this->iNoteId)
|
||||
return null;
|
||||
|
||||
$hResult = query_parameters("SELECT * FROM appNotes WHERE linkedWith = '?' AND versionId = '?'", $this->iNoteId, $iVersionId);
|
||||
|
||||
if(!$hResult || !($oRow = mysql_fetch_object($hResult)))
|
||||
return null;
|
||||
|
||||
return new noteLink(null, $oRow);
|
||||
}
|
||||
|
||||
foreach($this->aNoteLinks as $oLink)
|
||||
{
|
||||
if($oLink->objectGetParent('version') == $iVersionId)
|
||||
return $oLink;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function isLinkedWith($iVersionId, $bQueryDB = true)
|
||||
{
|
||||
$oLink = $this->findLink($iVersionId, $bQueryDB);
|
||||
|
||||
return $oLink != null;
|
||||
}
|
||||
|
||||
public function getNoteLinksFromInput($aValues)
|
||||
{
|
||||
$iAppId = $this->iAppId;
|
||||
if(!$iAppId)
|
||||
$iAppId = getInput('iAppId', $aValues);
|
||||
$oApp = new application($iAppId);
|
||||
$iCount = sizeof($oApp->getVersions());
|
||||
$aLinkedVersions = html_read_input_series('iVersionId', $aValues, $iCount);
|
||||
$aLinks = array();
|
||||
|
||||
foreach($aLinkedVersions as $sLinkedVersionId)
|
||||
{
|
||||
|
||||
if(!$sLinkedVersionId)
|
||||
continue;
|
||||
|
||||
$iLinkedVersionId = (int)$sLinkedVersionId;
|
||||
// See if we already have a DB entry for this link
|
||||
$oExistingLink = $this->findLink($iLinkedVersionId);
|
||||
if($oExistingLink)
|
||||
{
|
||||
$aLinks[] = $oExistingLink;
|
||||
continue;
|
||||
}
|
||||
$oLink = new noteLink();
|
||||
|
||||
$oLink->objectSetParent($this->iNoteId, 'note');
|
||||
$oLink->objectSetParent($iLinkedVersionId, 'version');
|
||||
$aLinks[] = $oLink;
|
||||
}
|
||||
|
||||
return $aLinks;
|
||||
}
|
||||
|
||||
public function saveNoteLinks($bNewNote = false)
|
||||
{
|
||||
foreach($this->aNoteLinks as $oLink)
|
||||
{
|
||||
if($bNewNote || !$this->isLinkedWith($oLink->objectGetParent('version')))
|
||||
$oLink->create();
|
||||
}
|
||||
|
||||
// Check if we should delete any links
|
||||
$aDBLinks = $this->objectGetChildren();
|
||||
|
||||
if(sizeof($this->aNoteLinks) != sizeof($aDBLinks))
|
||||
{
|
||||
foreach($aDBLinks as $oDBLink)
|
||||
{
|
||||
$bFound = false;
|
||||
foreach($this->aNoteLinks as $oLink)
|
||||
{
|
||||
if($oDBLink->objectGetParent('version') == $oLink->objectGetParent('version'))
|
||||
$bFound = true;
|
||||
}
|
||||
if(!$bFound)
|
||||
$oDBLink->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getLink()
|
||||
{
|
||||
if($this->iLinkedWith)
|
||||
return new noteLink($this->iNoteId);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function outputEditor($aValues = null)
|
||||
{
|
||||
if($aValues)
|
||||
{
|
||||
if(!$this->iVersionId)
|
||||
$this->iVersionId = getInput('iVersionId', $aValues);
|
||||
|
||||
if(!$this->iAppId)
|
||||
$this->iAppId = getInput('iAppId', $aValues);
|
||||
|
||||
if(!$this->sTitle)
|
||||
$this->sTitle = getInput('sNoteTitle', $aValues);
|
||||
}
|
||||
|
||||
if($this->iAppId && !$this->iVersionId)
|
||||
$this->iVersionId = APPNOTE_SHOW_FOR_ALL;
|
||||
|
||||
if(!$this->iAppId)
|
||||
{
|
||||
$oVersion = new version($this->iVersionId);
|
||||
$this->iAppId = $oVersion->iAppId;
|
||||
}
|
||||
|
||||
HtmlAreaLoaderScript(array("editor"));
|
||||
|
||||
echo html_frame_start("Edit Application Note", "90%","",0);
|
||||
echo html_table_begin("width='100%' border=0 align=left cellpadding=6 cellspacing=0 class='box-body'");
|
||||
|
||||
echo '<input type="hidden" name="bEditing" value="true">';
|
||||
echo '<input type="hidden" name="iNoteId" value="'.$this->iNoteId.'">';
|
||||
|
||||
echo '<input type="hidden" name="iAppId" value="'.$this->iAppId.'">';
|
||||
|
||||
echo '<tr><td class=color1>Title</td>'."\n";
|
||||
echo ' <td class=color0><input size=80% type="text" name="sNoteTitle" type="text" value="'.$this->sTitle.'"></td></tr>',"\n";
|
||||
echo '<tr><td class=color4>Description</td><td class=color0>', "\n";
|
||||
echo '<p style="width:700px">', "\n";
|
||||
echo '<textarea cols="80" rows="20" id="editor" name="shNoteDesc">'.$this->shDescription.'</textarea>',"\n";
|
||||
echo '</p>';
|
||||
echo '</td></tr>'."\n";
|
||||
|
||||
if($this->iAppId || $oApp->canEdit())
|
||||
{
|
||||
if($this->hasRealVersionId())
|
||||
{
|
||||
$oLink = new noteLink();
|
||||
$oLink->objectSetParent($this->iNoteId, 'note');
|
||||
$oLink->objectSetParent($this->iVersionId, 'version');
|
||||
$this->aNoteLinks[] = $oLink;
|
||||
$oVersion = new version($this->iVersionId);
|
||||
$this->iAppId = $oVersion->iAppId;
|
||||
$this->iVersionId = APPNOTE_SHOW_FOR_SPECIFIC_VERSIONS;
|
||||
}
|
||||
|
||||
$oApp = new application($this->iAppId);
|
||||
$aIds = $this->getDisplayModeIds();
|
||||
$aOptions = $this->getDisplayModeNames();
|
||||
|
||||
echo '<tr><td class="color1">Display mode</td>'."\n";
|
||||
echo '<td class="color0">'.html_radiobuttons($aIds, $aOptions, 'iVersionId', $this->iVersionId);
|
||||
|
||||
/* Allow the note to be shown for certain versions only */
|
||||
$aIds = array();
|
||||
$aOptions = array();
|
||||
$aSelected = array();
|
||||
|
||||
foreach($oApp->getVersions(true) as $oAppVersion) // Only accepted versions
|
||||
{
|
||||
|
||||
$aIds[] = $oAppVersion->objectGetId();
|
||||
$aOptions[] = $oAppVersion->objectMakeLink();
|
||||
|
||||
$aSelected[] = $this->isLinkedWith($oAppVersion->objectGetId(), false);
|
||||
}
|
||||
echo html_checkboxes('iVersionId', $aIds, $aOptions, $aSelected);
|
||||
|
||||
echo '</td></tr>';
|
||||
} else if(!$this->iAppId)
|
||||
{
|
||||
echo '<input type="hidden" name="iVersionId" value="'.$this->iVersionId.'">';
|
||||
}
|
||||
|
||||
echo '<tr><td colspan="2" align="center" class="color3">',"\n";
|
||||
|
||||
echo html_table_end();
|
||||
echo html_frame_end();
|
||||
}
|
||||
|
||||
public function checkOutputEditorInput($aClean)
|
||||
{
|
||||
$shErrors = '';
|
||||
$iVersionId = getInput('iVersionId', $aClean);
|
||||
|
||||
if($iVersionId == APPNOTE_SHOW_FOR_SPECIFIC_VERSIONS)
|
||||
{
|
||||
$aNoteLinks = $this->getNoteLinksFromInput($aClean);
|
||||
if(!sizeof($aNoteLinks))
|
||||
$shErrors .= '<li>You need to show the note for at least one version, or choose another display mode</li>';
|
||||
}
|
||||
return $shErrors;
|
||||
}
|
||||
|
||||
/* retrieves values from $aValue that were output by outputEditor() */
|
||||
/* $aValues can be $_REQUEST or any array with the values from outputEditor() */
|
||||
function GetOutputEditorValues($aValues)
|
||||
{
|
||||
$this->iVersionId = getInput('iVersionId', $aValues);
|
||||
|
||||
if(!$this->isRealVersionId($this->iVersionId))
|
||||
$this->iAppId = getInput('iAppId', $aValues);
|
||||
else
|
||||
$this->iAppId = 0;
|
||||
|
||||
if($this->iVersionId == APPNOTE_SHOW_FOR_SPECIFIC_VERSIONS)
|
||||
{
|
||||
$this->aNoteLinks = $this->getNoteLinksFromInput($aValues);
|
||||
|
||||
// There's no need to use links if the note is only shown for one version
|
||||
if(sizeof($this->aNoteLinks) == 1)
|
||||
{
|
||||
$oLink = $this->aNoteLinks[0];
|
||||
$this->iVersionId = $oLink->objectGetParent('version');
|
||||
$this->iAppId = 0;
|
||||
$this->aNoteLinks = array();
|
||||
}
|
||||
}
|
||||
|
||||
$this->sTitle = $aValues['sNoteTitle'];
|
||||
$this->shDescription = $aValues['shNoteDesc'];
|
||||
}
|
||||
|
||||
function allowAnonymousSubmissions()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: notes cannot be queued at this point
|
||||
function mustBeQueued()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->iNoteId;
|
||||
}
|
||||
|
||||
// TODO: we ignore $bQueued and $bRejected as notes
|
||||
// do not support queuing at this point
|
||||
// TODO: we have no permissions scope on retrieving entries
|
||||
// as notes are typically only added to unqueued versions
|
||||
function objectGetEntries($sState, $iRows = 0, $iStart = 0, $sOrderBy = '', $bAscending = true)
|
||||
{
|
||||
$sQuery = "select * from appNotes";
|
||||
$hResult = query_parameters($sQuery);
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
function objectGetEntriesCount($sState)
|
||||
{
|
||||
$sQuery = "SELECT COUNT(DISTINCT noteId) as count FROM appNotes";
|
||||
$hResult = query_parameters($sQuery);
|
||||
|
||||
if(!$hResult)
|
||||
return false;
|
||||
|
||||
if(($oRow = mysql_fetch_object($hResult)))
|
||||
return $oRow->count;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//TODO: not sure how to best let users view a table of notes
|
||||
// since the note contents could be very long we would only
|
||||
// want to show a small amount of the text. Implement this
|
||||
// routine when we need it
|
||||
function objectGetHeader()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
//TODO: implement this when we implement objectGetHeader()
|
||||
function objectGetTableRow()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
function objectMakeUrl()
|
||||
{
|
||||
$oManager = new objectManager("note", "View Note");
|
||||
return $oManager->makeUrl("view", $this->objectGetId());
|
||||
}
|
||||
|
||||
function objectGetSubmitterId()
|
||||
{
|
||||
return $this->iSubmitterId;
|
||||
}
|
||||
|
||||
function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return new mailOptions();
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
/* We don't do this at the moment */
|
||||
return array(null, null, null);
|
||||
}
|
||||
|
||||
public function objectGetParent($sClass = '')
|
||||
{
|
||||
if($this->hasRealVersionId())
|
||||
return new version($this->iVersionId);
|
||||
else
|
||||
return new application($this->iAppId);
|
||||
}
|
||||
|
||||
public function objectSetParent($iNewId, $sClass = '')
|
||||
{
|
||||
if($this->hasRealVersionId())
|
||||
$this->iVersionId = $iNewId;
|
||||
else
|
||||
$this->iAppId = $iNewId;
|
||||
}
|
||||
|
||||
function objectGetChildren($bIncludeDeleted = false)
|
||||
{
|
||||
$aRet = array();
|
||||
|
||||
if(!$this->iAppId)
|
||||
return $aRet;
|
||||
|
||||
$hResult = query_parameters("SELECT * FROM appNotes WHERE linkedWith = '?'", $this->iNoteId);
|
||||
|
||||
if(!$hResult)
|
||||
return $aRet;
|
||||
|
||||
while($oRow = mysql_fetch_object($hResult))
|
||||
$aRet[] = new noteLink(null, $oRow);
|
||||
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
//TODO: not sure if we want to use sTitle here or what
|
||||
function objectMakeLink()
|
||||
{
|
||||
$sLink = "<a href=\"".$this->objectMakeUrl()."\">".
|
||||
$this->sTitle."</a>";
|
||||
return $sLink;
|
||||
}
|
||||
|
||||
function objectGetState()
|
||||
{
|
||||
return 'accepted'; // We don't queue notes
|
||||
}
|
||||
|
||||
// users can edit the note if they:
|
||||
// - have "admin" privileges
|
||||
// - maintain the version, or supermaintain the application that
|
||||
// this version is under
|
||||
function canEdit()
|
||||
{
|
||||
if($_SESSION['current']->hasPriv("admin"))
|
||||
return true;
|
||||
else if($this->iVersionId && !$this->iAppId)
|
||||
return maintainer::isUserMaintainer($_SESSION['current'], $this->iVersionId);
|
||||
else if($this->iAppId)
|
||||
return maintainer::isUserSuperMaintainer($_SESSION['current'], $this->iAppId);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class noteLink
|
||||
{
|
||||
private $iLinkId;
|
||||
private $iNoteId;
|
||||
private $iVersionId;
|
||||
|
||||
function noteLink($iLinkId = null, $oRow = null)
|
||||
{
|
||||
$this->iLinkId = $iLinkId;
|
||||
|
||||
if(!$oRow && $this->iLinkId)
|
||||
{
|
||||
$hResult = query_parameters("SELECT * FROM appNotes WHERE noteId = '?'", $this->iLinkId);
|
||||
|
||||
if(!$hResult)
|
||||
return;
|
||||
|
||||
$oRow = mysql_fetch_object($hResult);
|
||||
}
|
||||
|
||||
if($oRow)
|
||||
{
|
||||
$this->iLinkId = $oRow->noteId;
|
||||
$this->iNoteId = $oRow->linkedWith;
|
||||
$this->iVersionId = $oRow->versionId;
|
||||
}
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$hResult = query_parameters("INSERT INTO appNotes (linkedWith,versionId) VALUES('?','?')", $this->iNoteId, $this->iVersionId);
|
||||
|
||||
if(!$hResult)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isDuplicate()
|
||||
{
|
||||
$oNote = new note($this->iNoteId);
|
||||
return $oNote->isLinkedWith($this->iVersionId);
|
||||
}
|
||||
|
||||
public function update()
|
||||
{
|
||||
// Query the DB so we have something to compare against
|
||||
$oLink = new noteLink($this->iLinkId);
|
||||
|
||||
if($this->objectGetParent('version') != $oLink->objectGetParent('version') && !$this->isDuplicate())
|
||||
{
|
||||
$hResult = query_parameters("UPDATE appNotes SET versionId = '?' WHERE noteId = '?'", $this->iVersionId, $this->iNoteId);
|
||||
if(!$hResult)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$hResult = query_parameters("DELETE FROM appNotes WHERE noteId = '?'", $this->iLinkId);
|
||||
|
||||
if(!$hResult)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function objectSetParent($iNewId, $sClass = '')
|
||||
{
|
||||
if(!$sClass || $sClass == 'note')
|
||||
$this->iNoteId = $iNewId;
|
||||
else if($sClass == 'version')
|
||||
$this->iVersionId = $iNewId;
|
||||
}
|
||||
|
||||
public function objectGetParent($sClass = '')
|
||||
{
|
||||
if(!$sClass || $sClass == 'note')
|
||||
return $this->iNoteId;
|
||||
if($sClass == 'version')
|
||||
return $this->iVersionId;
|
||||
}
|
||||
|
||||
function display($aValues = null)
|
||||
{
|
||||
$oNote = new note($this->iNoteId);
|
||||
$oNote->display($aValues);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
1934
include/objectManager.php
Normal file
1934
include/objectManager.php
Normal file
File diff suppressed because it is too large
Load Diff
84
include/parsedate.php
Normal file
84
include/parsedate.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
function parsedate($datestr)
|
||||
{
|
||||
$daynames = array("monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday");
|
||||
$monthnames = array("jan" => 1, "feb" => 2, "mar" => 3, "apr" => 4, "may" => 5, "jun" => 6,
|
||||
"jul" => 7, "aug" => 8, "sep" => 9, "oct" => 10, "nov" => 11, "dec" => 12);
|
||||
$ampm = array("am" => 00, "pm" => 12);
|
||||
|
||||
if(!$datestr)
|
||||
return -1;
|
||||
|
||||
$datestr = strtolower($datestr);
|
||||
$datestr = ereg_replace("[,]", "", $datestr);
|
||||
$dp = explode(' ', $datestr);
|
||||
while(list($idx, $part) = each($dp))
|
||||
{
|
||||
//echo "PART($part)<br>";
|
||||
|
||||
/* 23:59:59 */
|
||||
if(ereg("^([0-9]+):([0-9]+):([0-9]+)$", $part, $arr))
|
||||
{
|
||||
$hour = $arr[1];
|
||||
$minute = $arr[2];
|
||||
$second = $arr[3];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 23:59 */
|
||||
if(ereg("^([0-9]+):([0-9]+)$", $part, $arr))
|
||||
{
|
||||
$hour = $arr[1];
|
||||
$minute = $arr[2];
|
||||
$second = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 2000-12-31 (mysql date format) */
|
||||
if(ereg("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$", $part, $arr))
|
||||
{
|
||||
$year = $arr[1];
|
||||
$month = $arr[2];
|
||||
$day = $arr[3];
|
||||
continue;
|
||||
}
|
||||
|
||||
if(defined($ampm[$part]))
|
||||
{
|
||||
$hour += $ampm[$part];
|
||||
continue;
|
||||
}
|
||||
|
||||
if($monthnames[substr($part, 0, 3)])
|
||||
{
|
||||
$month = $monthnames[substr($part, 0, 3)];
|
||||
continue;
|
||||
}
|
||||
|
||||
if($part > 1900)
|
||||
{
|
||||
$year = $part;
|
||||
continue;
|
||||
}
|
||||
|
||||
if($part > 31)
|
||||
{
|
||||
$year = 1900 + $part;
|
||||
continue;
|
||||
}
|
||||
|
||||
if($part >= 1 && $part <= 31)
|
||||
{
|
||||
$day = $part;
|
||||
continue;
|
||||
}
|
||||
|
||||
//echo "Unparsed: '$part'<br>\n";
|
||||
|
||||
}
|
||||
|
||||
return mktime($hour, $minute, $second, $month, $day, $year);
|
||||
}
|
||||
|
||||
?>
|
||||
232
include/query.php
Normal file
232
include/query.php
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
$hAppdbLink = null;
|
||||
$hBugzillaLink = null;
|
||||
|
||||
define("MYSQL_DEADLOCK_ERRNO", 1213);
|
||||
|
||||
function query_appdb($sQuery, $sComment="")
|
||||
{
|
||||
global $hAppdbLink;
|
||||
|
||||
if(!is_resource($hAppdbLink))
|
||||
{
|
||||
// The last argument makes sure we are really opening a new connection
|
||||
$hAppdbLink = mysql_connect(APPS_DBHOST, APPS_DBUSER, APPS_DBPASS, true);
|
||||
if(!$hAppdbLink)
|
||||
die("Database error, please try again soon.");
|
||||
mysql_select_db(APPS_DB, $hAppdbLink);
|
||||
}
|
||||
|
||||
$iRetries = 2;
|
||||
|
||||
/* we need to retry queries that hit transaction deadlocks */
|
||||
/* as a deadlock isn't really a failure */
|
||||
while($iRetries)
|
||||
{
|
||||
$hResult = mysql_query($sQuery, $hAppdbLink);
|
||||
if(!$hResult)
|
||||
{
|
||||
/* if this error isn't a deadlock OR if it is a deadlock and we've */
|
||||
/* run out of retries, report the error */
|
||||
$iErrno = mysql_errno($hAppdbLink);
|
||||
if(($iErrno != MYSQL_DEADLOCK_ERRNO) || (($iErrno == MYSQL_DEADLOCK_ERRNO) && ($iRetries <= 0)))
|
||||
{
|
||||
query_error($sQuery, $sComment, $hAppdbLink);
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
$iRetries--;
|
||||
} else
|
||||
{
|
||||
return $hResult;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wildcard Rules
|
||||
* SCALAR (?) => 'original string quoted'
|
||||
* OPAQUE (&) => 'string from file quoted'
|
||||
* MISC (~) => original string (left 'as-is')
|
||||
*
|
||||
* NOTE: These rules convienently match those for Pear DB
|
||||
*
|
||||
* MySQL Prepare Function
|
||||
* By: Kage (Alex)
|
||||
* KageKonjou@GMail.com
|
||||
* http://us3.php.net/manual/en/function.mysql-query.php#53400
|
||||
*
|
||||
* Modified by CMM 20060622
|
||||
*
|
||||
* Values are mysql_real_escape_string()'d to prevent against injection attacks
|
||||
* See http://php.net/mysql_real_escape_string for more information about why this is the case
|
||||
*
|
||||
* Usage:
|
||||
* $hResult = query_parameters("Select * from mytable where userid = '?'",
|
||||
* $iUserId);
|
||||
*
|
||||
* Note:
|
||||
* Ensure that all variables are passed as parameters to query_parameters()
|
||||
* to ensure that sql injection attacks are prevented against
|
||||
*
|
||||
*/
|
||||
function query_parameters()
|
||||
{
|
||||
global $hAppdbLink;
|
||||
|
||||
if(!is_resource($hAppdbLink))
|
||||
{
|
||||
// The last argument makes sure we are really opening a new connection
|
||||
$hAppdbLink = mysql_connect(APPS_DBHOST, APPS_DBUSER, APPS_DBPASS, true) or die('Database error, please try again soon: '.mysql_error());
|
||||
mysql_select_db(APPS_DB, $hAppdbLink);
|
||||
}
|
||||
|
||||
$aData = func_get_args();
|
||||
$sQuery = $aData[0];
|
||||
$aTokens = split("[&?~]", $sQuery); /* NOTE: no need to escape characters inside of [] in regex */
|
||||
$sPreparedquery = $aTokens[0];
|
||||
$iCount = strlen($aTokens[0]);
|
||||
|
||||
/* do we have the correct number of tokens to the number of parameters provided? */
|
||||
if(count($aTokens) != count($aData))
|
||||
return NULL; /* count mismatch, return NULL */
|
||||
|
||||
for ($i=1; $i < count($aTokens); $i++)
|
||||
{
|
||||
$char = substr($sQuery, $iCount, 1);
|
||||
$iCount += (strlen($aTokens[$i])+1);
|
||||
if ($char == "&")
|
||||
{
|
||||
$fp = @fopen($aData[$i], 'r');
|
||||
$pdata = "";
|
||||
if ($fp)
|
||||
{
|
||||
while (($sBuf = fread($fp, 4096)) != false)
|
||||
{
|
||||
$pdata .= $sBuf;
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
} else
|
||||
{
|
||||
$pdata = &$aData[$i];
|
||||
}
|
||||
$sPreparedquery .= ($char != "~" ? mysql_real_escape_string($pdata) : $pdata);
|
||||
$sPreparedquery .= $aTokens[$i];
|
||||
}
|
||||
|
||||
return query_appdb($sPreparedquery);
|
||||
}
|
||||
|
||||
function query_bugzilladb($sQuery,$sComment="")
|
||||
{
|
||||
global $hBugzillaLink;
|
||||
|
||||
if(!is_resource($hBugzillaLink))
|
||||
{
|
||||
// The last argument makes sure we are really opening a new connection
|
||||
$hBugzillaLink = mysql_connect(BUGZILLA_DBHOST, BUGZILLA_DBUSER, BUGZILLA_DBPASS, true);
|
||||
if(!$hBugzillaLink) return;
|
||||
mysql_select_db(BUGZILLA_DB, $hBugzillaLink);
|
||||
}
|
||||
|
||||
$hResult = mysql_query($sQuery, $hBugzillaLink);
|
||||
if(!$hResult) query_error($sQuery, $sComment, $hBugzillaLink);
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
|
||||
function query_error($sQuery, $sComment, $hLink)
|
||||
{
|
||||
static $bInQueryError = false;
|
||||
|
||||
// if we are already reporting an error we can't report it again
|
||||
// as that indicates that error reporting itself produced an error
|
||||
if($bInQueryError)
|
||||
return;
|
||||
|
||||
// record that we are inside of this function, we don't want to recurse
|
||||
$bInQueryError = true;
|
||||
|
||||
error_log::log_error(ERROR_SQL, "Query: '".$sQuery."' ".
|
||||
"mysql_errno(): '".mysql_errno($hLink)."' ".
|
||||
"mysql_error(): '".mysql_error($hLink)."' ".
|
||||
"comment: '".$sComment."'");
|
||||
|
||||
$sStatusMessage = "<p><b>An internal error has occurred and has been logged and reported to appdb admins</b></p>";
|
||||
addmsg($sStatusMessage);
|
||||
|
||||
$bInQueryError = false; // clear variable upon exit
|
||||
}
|
||||
|
||||
function query_fetch_row($hResult)
|
||||
{
|
||||
return mysql_fetch_row($hResult);
|
||||
}
|
||||
|
||||
function query_fetch_object($hResult)
|
||||
{
|
||||
return mysql_fetch_object($hResult);
|
||||
}
|
||||
|
||||
function query_appdb_insert_id()
|
||||
{
|
||||
global $hAppdbLink;
|
||||
return mysql_insert_id($hAppdbLink);
|
||||
}
|
||||
|
||||
function query_bugzilla_insert_id()
|
||||
{
|
||||
global $hBugzillaLink;
|
||||
return mysql_insert_id($hBugzillaLink);
|
||||
}
|
||||
|
||||
function query_num_rows($hResult)
|
||||
{
|
||||
return mysql_num_rows($hResult);
|
||||
}
|
||||
|
||||
function query_escape_string($sString)
|
||||
{
|
||||
global $hAppdbLink;
|
||||
|
||||
if(!is_resource($hAppdbLink))
|
||||
{
|
||||
// The last argument makes sure we are really opening a new connection
|
||||
$hAppdbLink = mysql_connect(APPS_DBHOST, APPS_DBUSER, APPS_DBPASS, true);
|
||||
if(!$hAppdbLink)
|
||||
die("Database error, please try again soon.");
|
||||
mysql_select_db(APPS_DB, $hAppdbLink);
|
||||
}
|
||||
|
||||
return mysql_real_escape_string($sString, $hAppdbLink);
|
||||
}
|
||||
|
||||
function query_field_type($hResult, $iFieldOffset)
|
||||
{
|
||||
return mysql_field_type($hResult, $iFieldOffset);
|
||||
}
|
||||
|
||||
function query_field_name($hResult, $iFieldOffset)
|
||||
{
|
||||
return mysql_field_name($hResult, $iFieldOffset);
|
||||
}
|
||||
|
||||
function query_field_len($hResult, $ifieldOffset)
|
||||
{
|
||||
return mysql_field_len($hResult, $iFieldOffset);
|
||||
}
|
||||
|
||||
function query_field_flags($hResult, $iFieldOffset)
|
||||
{
|
||||
return mysql_field_flags($hResult, $iFieldOffset);
|
||||
}
|
||||
|
||||
function query_fetch_field($hResult, $iFieldOffset)
|
||||
{
|
||||
return mysql_fetch_field($hResult, $iFieldOffset);
|
||||
}
|
||||
|
||||
?>
|
||||
832
include/screenshot.php
Normal file
832
include/screenshot.php
Normal file
@@ -0,0 +1,832 @@
|
||||
<?php
|
||||
/******************************************/
|
||||
/* screenshot class and related functions */
|
||||
/******************************************/
|
||||
|
||||
require_once(BASE."include/util.php");
|
||||
require_once(BASE."include/image.php");
|
||||
|
||||
// load the watermark
|
||||
$watermark = new Image("/images/watermark.png");
|
||||
|
||||
/**
|
||||
* Screenshot class for handling screenshots and thumbnails
|
||||
*/
|
||||
class screenshot
|
||||
{
|
||||
var $iScreenshotId;
|
||||
|
||||
// parameters necessary for creating a new screenshot with
|
||||
// Screenshot::create()
|
||||
var $iVersionId;
|
||||
var $hFile;
|
||||
var $sDescription;
|
||||
|
||||
var $oScreenshotImage;
|
||||
var $oThumbnailImage;
|
||||
var $bQueued;
|
||||
var $iAppId;
|
||||
var $sUrl;
|
||||
var $sSubmitTime;
|
||||
var $iSubmitterId;
|
||||
|
||||
/**
|
||||
* Constructor, fetches the data and image objects if $iScreenshotId is given.
|
||||
*/
|
||||
function Screenshot($iScreenshotId = null, $oRow = null)
|
||||
{
|
||||
// we are working on an existing screenshot
|
||||
if(!$iScreenshotId && !$oRow)
|
||||
return;
|
||||
|
||||
if(!$oRow)
|
||||
{
|
||||
$hResult = query_parameters("SELECT appData.*, appVersion.appId AS appId
|
||||
FROM appData, appVersion
|
||||
WHERE appData.versionId = appVersion.versionId
|
||||
AND id = '?'
|
||||
AND type = 'screenshot'", $iScreenshotId);
|
||||
if($hResult)
|
||||
$oRow = query_fetch_object($hResult);
|
||||
}
|
||||
|
||||
if($oRow)
|
||||
{
|
||||
$this->iScreenshotId = $oRow->id;
|
||||
$this->sDescription = $oRow->description;
|
||||
$this->iAppId = $oRow->appId;
|
||||
$this->iVersionId = $oRow->versionId;
|
||||
$this->sUrl = $oRow->url;
|
||||
$this->bQueued = ($oRow->state=='queued')?true:false;
|
||||
$this->sSubmitTime = $oRow->submitTime;
|
||||
$this->iSubmitterId = $oRow->submitterId;
|
||||
$this->hFile = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new screenshot.
|
||||
*/
|
||||
function create()
|
||||
{
|
||||
$hResult = query_parameters("INSERT INTO appData
|
||||
(versionId, type, description, state, submitTime, submitterId)
|
||||
VALUES('?', '?', '?', '?', ?, '?')",
|
||||
$this->iVersionId, "screenshot",
|
||||
$this->sDescription,
|
||||
$this->mustBeQueued() ? 'queued' : 'accepted',
|
||||
"NOW()",
|
||||
$_SESSION['current']->iUserId);
|
||||
if($hResult)
|
||||
{
|
||||
$this->iScreenshotId = query_appdb_insert_id();
|
||||
|
||||
/* make sure we supply the full path to move_uploaded_file() */
|
||||
$moveToPath = appdb_fullpath("data/screenshots/originals/").$this->iScreenshotId;
|
||||
if(!move_uploaded_file($this->hFile['tmp_name'], $moveToPath))
|
||||
{
|
||||
// whoops, moving failed, do something
|
||||
addmsg("Unable to move screenshot from '".$this->hFile['tmp_name']."' to '".$moveToPath."'", "red");
|
||||
$sQuery = "DELETE
|
||||
FROM appData
|
||||
WHERE id = '?'";
|
||||
query_parameters($sQuery, $this->iScreenshotId);
|
||||
return false;
|
||||
} else // we managed to copy the file, now we have to process the image
|
||||
{
|
||||
$this->sUrl = $this->iScreenshotId;
|
||||
if($this->generate())
|
||||
{
|
||||
// we have to update the entry now that we know its name
|
||||
$sQuery = "UPDATE appData
|
||||
SET url = '?'
|
||||
WHERE id = '?'";
|
||||
if (!query_parameters($sQuery, $this->iScreenshotId, $this->iScreenshotId)) return false;
|
||||
} else
|
||||
{
|
||||
addmsg("Unable to generate image or thumbnail. The file format might not be recognized. Please use PNG or JPEG only.","red");
|
||||
$sQuery = "DELETE
|
||||
FROM appData
|
||||
WHERE id = '?'";
|
||||
query_parameters($sQuery, $this->iScreenshotId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->screenshot($this->iScreenshotId,$this->bQueued);
|
||||
$this->mailMaintainers();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
addmsg("Error while creating a new screenshot.", "red");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function purge()
|
||||
{
|
||||
return $this->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the screenshot from the database.
|
||||
* and request its deletion from the filesystem (including the thumbnail).
|
||||
*
|
||||
* Returns: true if deletion was success, false if otherwise
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
/* appData has a universal function for removing database entries */
|
||||
$oAppData = new appData($this->iScreenshotId, null, $this);
|
||||
if($oAppData->delete())
|
||||
{
|
||||
/* make sure the screenshot and thumbnail is loaded */
|
||||
/* up before we try to delete them */
|
||||
$this->load_image(true);
|
||||
$this->load_image(false);
|
||||
|
||||
$this->oScreenshotImage->delete();
|
||||
$this->oThumbnailImage->delete();
|
||||
|
||||
// if the original file exists, delete it
|
||||
$sOriginalFilename = appdb_fullpath("/data/screenshots/originals/".$this->iScreenshotId);
|
||||
if(is_file($sOriginalFilename))
|
||||
unlink($sOriginalFilename);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function reject()
|
||||
{
|
||||
$this->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move screenshot out of the queue.
|
||||
*/
|
||||
function unQueue()
|
||||
{
|
||||
// If we are not in the queue, we can't move the screenshot out of the queue.
|
||||
if(!$this->bQueued)
|
||||
return false;
|
||||
|
||||
if(query_parameters("UPDATE appData SET state = '?' WHERE id='?'",
|
||||
'accepted', $this->iScreenshotId))
|
||||
{
|
||||
$this->bQueued = false;
|
||||
// we send an e-mail to interested people
|
||||
$this->mailSubmitter();
|
||||
$this->mailMaintainers();
|
||||
// the screenshot has been unqueued
|
||||
addmsg("The screenshot has been unqueued.", "green");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cleans up the memory.
|
||||
*/
|
||||
function free()
|
||||
{
|
||||
if($this->oScreenshotImage)
|
||||
$this->oScreenshotImage->destroy();
|
||||
if($this->oThumbnailImage)
|
||||
$this->oThumbnailImage->destroy();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the screenshot description.
|
||||
*/
|
||||
function setDescription($sDescription)
|
||||
{
|
||||
if($hResult = query_parameters("UPDATE id SET description = '?' WHERE id = '?' AND type = 'screenshot'",
|
||||
$sDescription, $this->iScreenshotId))
|
||||
$this->sDescription = $sDescription;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method generates a watermarked screenshot and thumbnail from the original file.
|
||||
* Useful when changing thumbnail, upgrading GD, adding an image, etc.
|
||||
* Return false if an image could not be loaded.
|
||||
*/
|
||||
function generate()
|
||||
{
|
||||
global $watermark;
|
||||
// first we will create the thumbnail
|
||||
// load the screenshot
|
||||
$this->oThumbnailImage = new Image("/data/screenshots/originals/".$this->sUrl);
|
||||
if(!$this->oThumbnailImage->isLoaded())
|
||||
{
|
||||
$this->oThumbnailImage->delete(); // if we cannot load the original file we delete it from the filesystem
|
||||
return false;
|
||||
}
|
||||
$this->oThumbnailImage->make_thumb(0,0,1,'#000000');
|
||||
// store the image
|
||||
$this->oThumbnailImage->output_to_file(appdb_fullpath("/data/screenshots/thumbnails/".$this->sUrl));
|
||||
|
||||
// now we'll process the screenshot image for watermarking
|
||||
// load the screenshot
|
||||
$this->oScreenshotImage = new Image("/data/screenshots/originals/".$this->sUrl);
|
||||
if(!$this->oScreenshotImage->isLoaded()) return false;
|
||||
// resize the image
|
||||
$this->oScreenshotImage->make_full();
|
||||
// store the resized image
|
||||
$this->oScreenshotImage->output_to_file(appdb_fullpath("/data/screenshots/".$this->sUrl));
|
||||
// reload the resized screenshot
|
||||
$this->oScreenshotImage = new Image("/data/screenshots/".$this->sUrl);
|
||||
if(!$this->oScreenshotImage->isLoaded()) return false;
|
||||
|
||||
// add the watermark to the screenshot
|
||||
$this->oScreenshotImage->add_watermark($watermark->get_image_resource());
|
||||
// store the watermarked image
|
||||
$this->oScreenshotImage->output_to_file(appdb_fullpath("/data/screenshots/".$this->sUrl));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ensure that either the thumbnail or screenshot */
|
||||
/* has been loaded into memory */
|
||||
function load_image($bThumbnail)
|
||||
{
|
||||
if($bThumbnail)
|
||||
{
|
||||
/* if we haven't loaded the thumbnail up yet, do so */
|
||||
if(!$this->oThumbnailImage)
|
||||
$this->oThumbnailImage = new Image("/data/screenshots/thumbnails/".$this->sUrl);
|
||||
} else
|
||||
{
|
||||
/* if we haven't loaded the screenshot up yet, do so */
|
||||
if(!$this->oScreenshotImage)
|
||||
$this->oScreenshotImage = new Image("/data/screenshots/".$this->sUrl);
|
||||
}
|
||||
}
|
||||
|
||||
/* output the thumbnail if $bThumbnail or the full screenshot if !$bThumbnail */
|
||||
/* NOTE: use this instead of calling through to this classes oScreenshot or */
|
||||
/* oThumbnail objects directly to their output_*() functions */
|
||||
function output_screenshot($bThumbnail)
|
||||
{
|
||||
$this->load_image($bThumbnail);
|
||||
|
||||
if($bThumbnail)
|
||||
{
|
||||
if($this->oThumbnailImage)
|
||||
$this->oThumbnailImage->output_to_browser(1);
|
||||
} else
|
||||
{
|
||||
if($this->oScreenshotImage)
|
||||
$this->oScreenshotImage->output_to_browser(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Accessor functions for the screenshot and thumbnail images that this */
|
||||
/* screenshot object encapsulates */
|
||||
/* NOTE: DO NOT call like $oScreenshot->oScreenshotImage->get_width(), there is NO */
|
||||
/* guarantee that oScreenshotImage will be valid */
|
||||
function get_screenshot_width()
|
||||
{
|
||||
$this->load_image(false);
|
||||
return $this->oScreenshotImage->get_width();
|
||||
}
|
||||
|
||||
public function objectGetParent($sClass = '')
|
||||
{
|
||||
$oAppData = new appData($this->iScreenshotId, null, $this);
|
||||
return $oAppData->objectGetParent();
|
||||
}
|
||||
|
||||
public function objectSetParent($iNewId, $sClass = '')
|
||||
{
|
||||
if($this->iVersionId)
|
||||
$this->iVersionId = $iNewId;
|
||||
else
|
||||
$this->iAppId = $iNewId;
|
||||
}
|
||||
|
||||
function objectGetChildren($bIncludeDeleted = false)
|
||||
{
|
||||
/* We have none */
|
||||
return array();
|
||||
}
|
||||
|
||||
function get_screenshot_height()
|
||||
{
|
||||
$this->load_image(false);
|
||||
return $this->oScreenshotImage->get_height();
|
||||
}
|
||||
|
||||
function get_thumbnail_width()
|
||||
{
|
||||
$this->load_image(true);
|
||||
return $this->oThumbnailImage->get_width();
|
||||
}
|
||||
|
||||
function get_thumbnail_height()
|
||||
{
|
||||
$this->load_image(true);
|
||||
return $this->oThumbnailImage->get_height();
|
||||
}
|
||||
|
||||
function objectGetSubmitterId()
|
||||
{
|
||||
return $this->iSubmitterId;
|
||||
}
|
||||
|
||||
function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
$oOptions = new mailOptions();
|
||||
|
||||
if($sAction == "delete" && $bParentAction)
|
||||
$oOptions->bMailOnce = TRUE;
|
||||
|
||||
return $oOptions;
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
$sFor = version::fullName($this->iVersionId);
|
||||
|
||||
$sMsg = null;
|
||||
$sSubject = null;
|
||||
|
||||
if($bMailSubmitter)
|
||||
{
|
||||
switch($sAction)
|
||||
{
|
||||
case "delete":
|
||||
if($bParentAction)
|
||||
{
|
||||
$sSubject = "Submitter screenshots deleted";
|
||||
$sMsg = "The screenshots you submitted for $sFor have been ".
|
||||
"deleted because $sFor was deleted.";
|
||||
} else
|
||||
{
|
||||
$sSubject = "Submitted screenshot deleted";
|
||||
$sMsg = "The screenshot with description '".$this->sDescription.
|
||||
"' that you submitted for $sFor has been deleted.";
|
||||
}
|
||||
break;
|
||||
}
|
||||
$aMailTo = null;
|
||||
} else
|
||||
{
|
||||
switch($sAction)
|
||||
{
|
||||
case "delete":
|
||||
if(!$bParentAction)
|
||||
{
|
||||
$sSubject = "Screenshot for $sFor deleted";
|
||||
$sMsg = "The screenshot with description '".$this->sDescription.
|
||||
"' for $sFor has been deleted.";
|
||||
}
|
||||
break;
|
||||
}
|
||||
$aMailTo = User::get_notify_email_address_list(null, $this->iVersionId);
|
||||
}
|
||||
return array($sSubject, $sMsg, $aMailTo);
|
||||
}
|
||||
|
||||
function mailSubmitter($bRejected=false)
|
||||
{
|
||||
global $aClean;
|
||||
|
||||
if($this->iSubmitterId)
|
||||
{
|
||||
$sAppName = Application::lookup_name($this->iAppId)." ".Version::lookup_name($this->iVersionId);
|
||||
$oSubmitter = new User($this->iSubmitterId);
|
||||
if(!$bRejected)
|
||||
{
|
||||
$sSubject = "Submitted screenshot accepted";
|
||||
$sMsg = "The screenshot you submitted for ".$sAppName." has been accepted.";
|
||||
} else
|
||||
{
|
||||
$sSubject = "Submitted screenshot rejected";
|
||||
$sMsg = "The screenshot you submitted for ".$sAppName." has been rejected.";
|
||||
}
|
||||
$sMsg .= $aClean['sReplyText']."\n";
|
||||
$sMsg .= "We appreciate your help in making the Application Database better for all users.";
|
||||
|
||||
mail_appdb($oSubmitter->sEmail, $sSubject ,$sMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function mailMaintainers($bDeleted=false)
|
||||
{
|
||||
$oVersion = new version($this->iVersionId);
|
||||
$sAppName = version::fullName($this->iVersionId);
|
||||
|
||||
if(!$bDeleted)
|
||||
$sMsg = $this->objectMakeUrl()."\n";
|
||||
else
|
||||
$sMsg = $oVersion->objectMakeUrl()."\n";
|
||||
|
||||
if(!$bDeleted)
|
||||
{
|
||||
if(!$this->bQueued)
|
||||
{
|
||||
$sSubject = "Screenshot for $sAppName added by ".
|
||||
$_SESSION['current']->sRealname;
|
||||
if($this->iSubmitterId)
|
||||
{
|
||||
$oSubmitter = new User($this->iSubmitterId);
|
||||
$sMsg .= "This screenshot has been submitted by ".
|
||||
$oSubmitter->sRealname.".";
|
||||
$sMsg .= "\n";
|
||||
}
|
||||
addmsg("The screenshot was successfully added into the database.",
|
||||
"green");
|
||||
} else // Screenshot queued.
|
||||
{
|
||||
$sSubject = "Screenshot for $sAppName submitted by ".
|
||||
$_SESSION['current']->sRealname;
|
||||
$sMsg .= "This screenshot has been queued.";
|
||||
$sMsg .= "\n";
|
||||
addmsg("The screenshot you submitted will be added to the ".
|
||||
"database after being reviewed.", "green");
|
||||
}
|
||||
} else // Screenshot deleted.
|
||||
{
|
||||
$sSubject = "Screenshot for $sAppName deleted by ".
|
||||
$_SESSION['current']->sRealname;
|
||||
addmsg("Screenshot deleted.", "green");
|
||||
}
|
||||
|
||||
$sEmail = User::get_notify_email_address_list(null, $this->iVersionId);
|
||||
if($sEmail)
|
||||
mail_appdb($sEmail, $sSubject ,$sMsg);
|
||||
}
|
||||
|
||||
function get_zoomicon_overlay()
|
||||
{
|
||||
/* if the user is using mozilla or firefox show the zoom icon over images */
|
||||
/* otherwise because IE doesn't support transparent PNGs or proper css we have to */
|
||||
/* skip it for IE */
|
||||
if(strpos($_SERVER['HTTP_USER_AGENT'], "MSIE") === false)
|
||||
{
|
||||
$sZoomIcon = '<img class="zoom_overlay" src="'.BASE.'images/xmag_32.png" alt="">';
|
||||
}
|
||||
else
|
||||
$sZoomIcon = "";
|
||||
|
||||
return $sZoomIcon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random image for a particular version of an app.
|
||||
* If the version is not set, get a random app image
|
||||
*
|
||||
* $bFormatting == false turns off all extranious formatting applied to the returned image html
|
||||
*/
|
||||
function get_random_screenshot_img($iAppId = null, $iVersionId = null,
|
||||
$bFormatting = true)
|
||||
{
|
||||
// initialize variables to avoid notices when appending to them
|
||||
$hResult = null;
|
||||
$sImgFile = '';
|
||||
$sImg = '';
|
||||
// we want a random screenshots for this app
|
||||
if($iAppId && !$iVersionId)
|
||||
{
|
||||
$hResult = query_parameters("SELECT appData.id, appData.description, RAND() AS rand
|
||||
FROM appData, appVersion
|
||||
WHERE appData.versionId = appVersion.versionId
|
||||
AND appVersion.appId = '?'
|
||||
AND type = 'screenshot'
|
||||
AND appData.state = 'accepted'
|
||||
ORDER BY rand", $iAppId);
|
||||
} else if ($iVersionId) // we want a random screenshot for this version
|
||||
{
|
||||
$hResult = query_parameters("SELECT id, description, RAND() AS rand
|
||||
FROM appData
|
||||
WHERE versionId = '?'
|
||||
AND type = 'screenshot'
|
||||
AND state = 'accepted'
|
||||
ORDER BY rand", $iVersionId);
|
||||
}
|
||||
|
||||
if($bFormatting)
|
||||
$sImgFile .= '<center>';
|
||||
|
||||
if(!$hResult || !query_num_rows($hResult))
|
||||
{
|
||||
$sImgFile.= '<img src="images/no_screenshot.png" alt="No Screenshot">';
|
||||
} else
|
||||
{
|
||||
$oRow = query_fetch_object($hResult);
|
||||
$sImgFile.= '<img src="appimage.php?bThumbnail=true&iId='.$oRow->id.'" alt="'.$oRow->description.'">';
|
||||
}
|
||||
|
||||
if($bFormatting)
|
||||
$sImgFile .= '</center>';
|
||||
|
||||
if($bFormatting)
|
||||
$sImg = html_frame_start("",'128','',2);
|
||||
|
||||
/* retrieve the url for the zoom icon overlay */
|
||||
$sZoomIcon = Screenshot::get_zoomicon_overlay();
|
||||
|
||||
/* we have screenshots */
|
||||
if($hResult && query_num_rows($hResult))
|
||||
{
|
||||
if($iVersionId)
|
||||
$sImg .= "<div class=\"imgarea\"><a href='screenshots.php?iAppId=$iAppId&iVersionId=$iVersionId'>".$sImgFile.$sZoomIcon."<br>View/Submit Screenshot</a></div>";
|
||||
else
|
||||
$sImg .= "<div class=\"imgarea\"><a href='screenshots.php?iAppId=$iAppId&iVersionId=$iVersionId'>".$sImgFile.$sZoomIcon."<br>View Screenshot</a></div>";
|
||||
} else if($iVersionId) /* we are asking for a specific app version but it has no screenshots */
|
||||
{
|
||||
$sImg .= "<div class=\"imgarea\"><a href='screenshots.php?iAppId=$iAppId&iVersionId=$iVersionId'>".$sImgFile.$sZoomIcon."<br>Submit Screenshot</a></div>";
|
||||
} else /* we have no screenshots and we aren't a specific version, we don't allow adding screenshots for an app */
|
||||
{
|
||||
$sImg .= $sImgFile.$sZoomIcon;
|
||||
}
|
||||
|
||||
if($bFormatting)
|
||||
$sImg .= html_frame_end()."<br>";
|
||||
|
||||
return $sImg;
|
||||
}
|
||||
|
||||
function get_screenshots($iAppId = null, $iVersionId = null, $bQueued = "false")
|
||||
{
|
||||
/*
|
||||
* We want all screenshots for this app.
|
||||
*/
|
||||
if($iAppId && !$iVersionId)
|
||||
{
|
||||
$hResult = query_parameters("SELECT appData.*, appVersion.appId as appId
|
||||
FROM appData, appVersion
|
||||
WHERE appVersion.versionId = appData.versionId
|
||||
AND type = 'screenshot'
|
||||
AND appVersion.appId = '?'
|
||||
AND appData.state = '?'", $iAppId, ($bQueued == 'false') ? 'accepted' : 'queued');
|
||||
}
|
||||
/*
|
||||
* We want all screenshots for this version.
|
||||
*/
|
||||
else if ($iVersionId)
|
||||
{
|
||||
$hResult = query_parameters("SELECT appData.*, appVersion.appId as appId
|
||||
FROM appData, appVersion
|
||||
WHERE appVersion.versionId = appData.versionId
|
||||
AND type = 'screenshot'
|
||||
AND appData.versionId = '?'
|
||||
AND appData.state = '?'", $iVersionId, ($bQueued == 'false') ? 'accepted' : 'queued');
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
function get_thumbnail_img()
|
||||
{
|
||||
// generate random tag for popup window
|
||||
$sRandName = User::generate_passwd(5);
|
||||
// set img tag
|
||||
$shImgSRC = '<img src="'.apidb_fullurl("appimage.php").
|
||||
'?bThumbnail=true&iId='.$this->iScreenshotId.'" alt="'.$this->sDescription.
|
||||
'" width="'.$this->get_thumbnail_width().
|
||||
'" height="'.$this->get_thumbnail_height().'">';
|
||||
$shImg = '<a href="'.apidb_fullurl("appimage.php").
|
||||
'?iId='.$this->iScreenshotId.
|
||||
'" onclick="javascript:openWin(\''.apidb_fullurl("appimage.php").
|
||||
'?iId='.$this->iScreenshotId.'\',\''.$sRandName.'\','.
|
||||
($this->get_screenshot_width() + 20).','.
|
||||
($this->get_screenshot_height() + 6).
|
||||
');return false;">'.$shImgSRC.Screenshot::get_zoomicon_overlay().'</a>';
|
||||
|
||||
// set image link based on user pref
|
||||
if ($_SESSION['current']->isLoggedIn())
|
||||
{
|
||||
if ($_SESSION['current']->getpref("window:screenshot") == "no")
|
||||
{
|
||||
$shImg = '<a href="'.apidb_fullurl("appimage.php").
|
||||
'?iImageId='.$this->iScreenshotId.'">'.$shImgSRC.'</a>';
|
||||
}
|
||||
}
|
||||
return $shImg;
|
||||
}
|
||||
|
||||
public static function objectGetItemsPerPage($sState = 'accepted')
|
||||
{
|
||||
if($sState != 'accepted')
|
||||
{
|
||||
$aItemsPerPage = array(25, 50, 100, 200);
|
||||
$iDefaultPerPage = 25;
|
||||
} else
|
||||
{
|
||||
$aItemsPerPage = array(6, 9, 12, 15, 18, 21, 24);
|
||||
$iDefaultPerPage = 6;
|
||||
}
|
||||
return array($aItemsPerPage, $iDefaultPerPage);
|
||||
}
|
||||
|
||||
function objectWantCustomDraw($sWhat, $sQueued)
|
||||
{
|
||||
switch($sWhat)
|
||||
{
|
||||
case 'table':
|
||||
if($sQueued == 'false')
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function objectDrawCustomTable($hResult, $sQueued)
|
||||
{
|
||||
echo "<div align=center><table><tr>\n";
|
||||
for($i = 1; $oRow = query_fetch_object($hResult); $i++)
|
||||
{
|
||||
// display thumbnail
|
||||
$oVersion = new version($oRow->versionId);
|
||||
$oApp = new Application($oVersion->iAppId);
|
||||
$oScreenshot = new Screenshot($oRow->id);
|
||||
$shImg = $oScreenshot->get_thumbnail_img();
|
||||
echo "<td align=center>\n";
|
||||
echo $shImg;
|
||||
echo "<div align=center>". substr($oRow->description,0,20). "\n";
|
||||
|
||||
echo "<br>[".$oApp->objectMakeLink()."]";
|
||||
|
||||
echo "<br>[".$oVersion->objectMakeLink()."]";
|
||||
|
||||
if($oScreenshot->canEdit())
|
||||
{
|
||||
$oM = new objectManager('screenshot');
|
||||
echo '<br />[<a href="'.$oM->makeUrl('delete', $oScreenshot->objectGetId(), 'Delete Screenshot').'">Delete</a>]';
|
||||
}
|
||||
|
||||
echo "</div></td>\n";
|
||||
// end row if counter of 3
|
||||
if($i % 3 == 0)
|
||||
echo "</tr><tr>\n";
|
||||
}
|
||||
|
||||
echo "</tr></table></div><br>\n";
|
||||
}
|
||||
|
||||
public function objectGetFilterInfo()
|
||||
{
|
||||
$oFilter = new filterInterface();
|
||||
|
||||
$aCatNames = array();
|
||||
$aCatIds = array();
|
||||
|
||||
$aCategories = category::getOrderedList();
|
||||
foreach($aCategories as $oCategory)
|
||||
{
|
||||
$aCatNames[] = $oCategory->sName;
|
||||
$aCatIds[] = $oCategory->objectGetId();
|
||||
}
|
||||
|
||||
$oFilter->addFilterInfo('appCategory', 'App category', array(FILTER_OPTION_ENUM), FILTER_VALUES_OPTION_ENUM, $aCatIds, $aCatNames);
|
||||
|
||||
return $oFilter;
|
||||
}
|
||||
|
||||
function objectGetEntries($sState, $iRows = 0, $iStart = 0, $sOrderBy = '', $bAscending = true, $oFilters = null)
|
||||
{
|
||||
return appData::objectGetEntries($sState, $iRows, $iStart, $sOrderBy, $bAscending,
|
||||
'screenshot', $oFilters);
|
||||
}
|
||||
|
||||
function objectGetEntriesCount($sState, $oFilters = null)
|
||||
{
|
||||
return appData::objectGetEntriesCount($sState, 'screenshot', $oFilters);
|
||||
}
|
||||
|
||||
function objectGetHeader()
|
||||
{
|
||||
return appData::objectGetHeader("screenshot");
|
||||
}
|
||||
|
||||
function objectGetState()
|
||||
{
|
||||
return ($this->bQueued) ? 'queued' : 'accepted';
|
||||
}
|
||||
|
||||
function canEdit()
|
||||
{
|
||||
if($this)
|
||||
{
|
||||
$oAppData = new appData($this->objectGetId(), null, $this);
|
||||
return $oAppData->canEdit();
|
||||
} else
|
||||
return appData::canEdit();
|
||||
}
|
||||
|
||||
function mustBeQueued()
|
||||
{
|
||||
if($this)
|
||||
{
|
||||
$oAppData = new appData();
|
||||
$oAppData->iVersionId = $this->iVersionId;
|
||||
$oAppData->iAppId = NULL;
|
||||
return $oAppData->mustBeQueued();
|
||||
} else
|
||||
return appData::mustBeQueued();
|
||||
}
|
||||
|
||||
function objectGetTableRow()
|
||||
{
|
||||
$oAppData = new AppData($this->iScreenshotId, null, $this);
|
||||
return $oAppData->objectGetTableRow();
|
||||
}
|
||||
|
||||
function objectDisplayQueueProcessingHelp()
|
||||
{
|
||||
$shRet = "<p>This is the list of screenshots waiting to be processed</p>";
|
||||
$shRet .= "<p>To view and process an entry, use the links under ‘Action’</p>";
|
||||
return $shRet;
|
||||
}
|
||||
|
||||
function outputEditor()
|
||||
{
|
||||
$oAppData = new appData($this->iScreenshotId, null, $this);
|
||||
$oAppData->outputEditorGeneric();
|
||||
|
||||
echo '<tr valign=top><td class=color0><b>Submitted screenshot</b></td>',"\n";
|
||||
echo '<td>';
|
||||
$imgSRC = '<img width="'.$this->get_thumbnail_width().'" height="'.
|
||||
$this->get_thumbnail_height().'" src="'.BASE.
|
||||
'appimage.php?bQueued=true&iId='.$this->iScreenshotId.'" />';
|
||||
// generate random tag for popup window
|
||||
$randName = User::generate_passwd(5);
|
||||
// set image link based on user pref
|
||||
$img = '<a href="javascript:openWin(\''.BASE.'appimage.php?bQueued=true&iId='.
|
||||
$this->iScreenshotId.'\',\''.$randName.'\','.$this->get_screenshot_width()
|
||||
.','.($this->get_screenshot_height()+4).');">'.$imgSRC.'</a>';
|
||||
if ($_SESSION['current']->isLoggedIn())
|
||||
{
|
||||
if ($_SESSION['current']->getpref("window:screenshot") == "no")
|
||||
{
|
||||
$img = '<a href="'.BASE.'appimage.php?bQueued=true&iId='.
|
||||
$this->iScreenshotId.'">'.$imgSRC.'</a>';
|
||||
}
|
||||
}
|
||||
echo $img;
|
||||
echo '</td></tr>',"\n";
|
||||
echo '<input type="hidden" name="iScreenshotId" value="'.
|
||||
$this->iScreenshotId.'" />';
|
||||
echo html_frame_end();
|
||||
}
|
||||
|
||||
function getOutputEditorValues($aClean)
|
||||
{
|
||||
$this->sDescription = $aClean['sDescription'];
|
||||
}
|
||||
|
||||
function update()
|
||||
{
|
||||
$oAppData = new appData($this->iScreenshotId, null, $this);
|
||||
return $oAppData->update();
|
||||
}
|
||||
|
||||
function objectHideDelete()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function getDefaultReply()
|
||||
{
|
||||
return appData::getDefaultReply();
|
||||
}
|
||||
|
||||
function display()
|
||||
{
|
||||
/* STUB */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function objectMakeLink()
|
||||
{
|
||||
/* STUB */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function objectMakeUrl()
|
||||
{
|
||||
return APPDB_ROOT."appimage.php?iId={$this->iScreenshotId}";
|
||||
}
|
||||
|
||||
function allowAnonymousSubmissions()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->iScreenshotId;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
168
include/session.php
Normal file
168
include/session.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* session.php - session handler functions
|
||||
* sessions are stored in memcached
|
||||
* http://www.danga.com/memcached/
|
||||
*/
|
||||
|
||||
class session
|
||||
{
|
||||
// defines
|
||||
var $_server;
|
||||
var $_expire;
|
||||
var $_db;
|
||||
var $name;
|
||||
var $msg;
|
||||
|
||||
// create session object
|
||||
function session ($name, $server = "127.0.0.1", $expire = 2)
|
||||
{
|
||||
// set the connection server
|
||||
$this->_server = $server;
|
||||
|
||||
// set the session and cookie expiration time in days (default 30 days)
|
||||
$this->_expire = (60 * 60 * 24 * $expire);
|
||||
|
||||
// set name for this session
|
||||
$this->name = $name;
|
||||
|
||||
// define options for sessions
|
||||
ini_set('session.name', $this->name);
|
||||
ini_set('session.use_cookies', true);
|
||||
ini_set('session.use_only_cookies', true);
|
||||
|
||||
// setup session object
|
||||
session_set_save_handler(
|
||||
array(&$this, "_open"),
|
||||
array(&$this, "_close"),
|
||||
array(&$this, "_read"),
|
||||
array(&$this, "_write"),
|
||||
array(&$this, "_destroy"),
|
||||
array(&$this, "_gc")
|
||||
);
|
||||
|
||||
// default lifetime on session cookie
|
||||
session_set_cookie_params(
|
||||
$this->_expire,
|
||||
'/'
|
||||
);
|
||||
|
||||
// start the loaded session
|
||||
session_start();
|
||||
|
||||
// make sure we have a valid memcache server connection
|
||||
if (!$this->_db->getVersion())
|
||||
{
|
||||
trigger_error("Unable to Connect to Session Server", E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
// register variables into session (dynamic load and save of vars)
|
||||
function register ($var)
|
||||
{
|
||||
global $$var;
|
||||
|
||||
// load $var into memory
|
||||
if (isset($_SESSION[$var]))
|
||||
$$var = $_SESSION[$var];
|
||||
|
||||
// store var into session
|
||||
$_SESSION[$var] =& $$var;
|
||||
}
|
||||
|
||||
// destroy session
|
||||
function destroy ()
|
||||
{
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
// add alert message to buffer that will be displayed on the Next page view of the same user in html class
|
||||
function addmsg ($text, $color = "black")
|
||||
{
|
||||
if (!isset($_SESSION['_msg']))
|
||||
$_SESSION['_msg'] = array();
|
||||
$_SESSION['_msg'][] = array(
|
||||
'msg' => $text,
|
||||
'color' => $color
|
||||
);
|
||||
}
|
||||
|
||||
// add alert message that will be displayed on the current page output in html class
|
||||
function alert ($text, $color = "black")
|
||||
{
|
||||
$this->msg[] = array(
|
||||
'msg' => $text,
|
||||
'color' => $color
|
||||
);
|
||||
}
|
||||
|
||||
// clear session messages
|
||||
function purgemsg ()
|
||||
{
|
||||
$this->msg[] = array();
|
||||
$_SESSION['_msg'][] = array();
|
||||
}
|
||||
|
||||
// output msg_buffer and clear it.
|
||||
function dumpmsgbuffer ()
|
||||
{
|
||||
if (isset($_SESSION['_msg']) and is_array($_SESSION['_msg']))
|
||||
{
|
||||
foreach ($_SESSION['_msg'] as $alert)
|
||||
{
|
||||
$this->msg[] = $alert;
|
||||
}
|
||||
}
|
||||
$_SESSION['_msg'] = array();
|
||||
}
|
||||
|
||||
// connect to session
|
||||
function _open ($save_path, $session_name)
|
||||
{
|
||||
$this->_db = new Memcache;
|
||||
return $this->_db->connect($this->_server, "11211");
|
||||
}
|
||||
|
||||
// close the session
|
||||
function _close ()
|
||||
{
|
||||
return $this->_db->close();
|
||||
}
|
||||
|
||||
// restore a session from memory
|
||||
function _read ($id)
|
||||
{
|
||||
return $this->_db->get($id);
|
||||
}
|
||||
|
||||
// write the session
|
||||
function _write ($id, $data)
|
||||
{
|
||||
if ($this->_db->get($id))
|
||||
{
|
||||
$this->_db->replace($id, $data, null, $this->_expire);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_db->set($id, $data, null, $this->_expire);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Delete the Session
|
||||
function _destroy ($id)
|
||||
{
|
||||
return $this->_db->delete($id);
|
||||
}
|
||||
|
||||
// Garbage Collector (Not Needed for MemCache)
|
||||
function _gc ($maxlifetime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
// end session
|
||||
|
||||
?>
|
||||
30
include/sidebar.php
Normal file
30
include/sidebar.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/***********/
|
||||
/* SideBar */
|
||||
/***********/
|
||||
require_once(BASE."include/distribution.php");
|
||||
require_once(BASE."include/vendor.php");
|
||||
require_once(BASE."include/util.php");
|
||||
|
||||
function global_sidebar_menu()
|
||||
{
|
||||
global $aClean;
|
||||
|
||||
$g = new htmlmenu("AppDB");
|
||||
$g->add('Home', BASE.'index.php');
|
||||
$g->add("Screenshots", BASE."objectManager.php?sClass=screenshot&sTitle=View+Screenshots");
|
||||
$g->add("Browse Apps", BASE."objectManager.php?sClass=application&".
|
||||
'sTitle=Browse%20Applications&sOrderBy=appName&bAscending=true');
|
||||
$g->add('Browse by Developer', BASE.'objectManager.php?sClass=vendor&sTitle=Browse%20by%20Developer');
|
||||
$g->add("Top 25", BASE."votestats.php");
|
||||
$g->add("Submit App", BASE."objectManager.php?sClass=application_queue&".
|
||||
"sTitle=Submit+Application&sAction=add");
|
||||
$g->add("Help", BASE."help/");
|
||||
$g->add("Statistics", BASE."appdbStats.php");
|
||||
$g->add('Distributions ('.distribution::objectGetEntriesCount('accepted').')', BASE.'objectManager.php?sClass=distribution&sTitle=View%20Distributions');
|
||||
$g->add("Email Us", "mailto:appdb@winehq.org");
|
||||
$g->done();
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
66
include/sidebar_admin.php
Normal file
66
include/sidebar_admin.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/*****************/
|
||||
/* sidebar_admin */
|
||||
/*****************/
|
||||
require_once(BASE."include/testData.php");
|
||||
require_once(BASE."include/distribution.php");
|
||||
|
||||
function global_admin_menu() {
|
||||
|
||||
$g = new htmlmenu("Global Admin");
|
||||
|
||||
$g->add("App Queue (".application::objectGetEntriesCount('queued').")",
|
||||
BASE.'objectManager.php?sClass=application_queue&sState=queued&sTitle='.
|
||||
'Application%20Queue');
|
||||
$g->add("Version Queue (".version::objectGetEntriesCount('queued').")",
|
||||
BASE.'objectManager.php?sClass=version_queue&sState=queued&sTitle='.
|
||||
'Version%20Queue');
|
||||
$g->add("Screenshot Queue (".appData::objectGetEntriesCount('queued', "screenshot").")",
|
||||
BASE.'objectManager.php?sClass=screenshot&sState=queued&sTitle='.
|
||||
'Screenshot%20Queue');
|
||||
$g->add("Maintainer Queue (".Maintainer::objectGetEntriesCount('queued').")",
|
||||
BASE.'objectManager.php?sClass=maintainer&sState=queued&sTitle='.
|
||||
'Maintainer%20Queue');
|
||||
$g->add("Test Results Queue (".testData::objectGetEntriesCount('queued').")",
|
||||
BASE.'objectManager.php?sClass=testData_queue&sState=queued&sTitle='.
|
||||
'Test%20Results%20Queue');
|
||||
$g->add("Bug Link Queue (".bug::objectGetEntriesCount('queued').")",
|
||||
BASE.'objectManager.php?sClass=bug&sState=queued&sTitle='.
|
||||
'Bug%20Link%20Queue');
|
||||
|
||||
$g->addmisc(" ");
|
||||
|
||||
$g->add("Maintainer Entries (".Maintainer::objectGetEntriesCount('accepted').")",
|
||||
BASE."admin/adminMaintainers.php");
|
||||
$g->add("Bug Links (".bug::objectGetEntriesCount('accepted').")",
|
||||
BASE."objectManager.php?sClass=bug&sTitle=".
|
||||
"Bug%20Links");
|
||||
$g->add("Test Results (".testData::objectGetEntriesCount('accepted').")",
|
||||
BASE."objectManager.php?sClass=testData&sTitle=".
|
||||
"View%20Test%20Results");
|
||||
$g->add("Users Management", BASE."admin/adminUsers.php");
|
||||
$g->add("Comments Management", BASE."admin/adminCommentView.php");
|
||||
$g->add("Screenshots Management", BASE."admin/adminScreenshots.php");
|
||||
|
||||
$g->addmisc(" ");
|
||||
|
||||
$g->add("Rejected Applications (".application::objectGetEntriesCount('rejected').")",
|
||||
BASE.'objectManager.php?sClass=application_queue&sState=rejected&'.
|
||||
'sTitle=Rejected%20Applications');
|
||||
$g->add("Rejected Versions (".version::objectGetEntriesCount('rejected').")",
|
||||
BASE.'objectManager.php?sClass=version_queue&sState=rejected&'.
|
||||
'sTitle=Rejected%20Versions');
|
||||
$g->add("Rejected Test Results (".testData::objectGetEntriesCount('rejected').")",
|
||||
BASE.'objectManager.php?sClass=testData_queue&sState=rejected&'.
|
||||
'sTitle=Rejected%20Test%20Results');
|
||||
|
||||
$g->addmisc(" ");
|
||||
|
||||
$g->add("Add Category", BASE."objectManager.php?sClass=category&sAction=add&sTitle=Add+Category");
|
||||
$g->add("Add Vendor", BASE."objectManager.php?sClass=vendor&bQueue=".
|
||||
"false&sAction=add&sTitle=Add%20Vendor");
|
||||
|
||||
$g->done();
|
||||
}
|
||||
|
||||
?>
|
||||
102
include/sidebar_login.php
Normal file
102
include/sidebar_login.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/*****************/
|
||||
/* Login SideBar */
|
||||
/*****************/
|
||||
|
||||
require_once(BASE."include/maintainer.php");
|
||||
require_once(BASE."include/application.php");
|
||||
require_once(BASE."include/user.php");
|
||||
require_once(BASE."include/monitor.php");
|
||||
|
||||
function global_sidebar_login() {
|
||||
|
||||
$g = new htmlmenu("User Menu");
|
||||
|
||||
if($_SESSION['current']->isLoggedIn())
|
||||
{
|
||||
|
||||
$g->add("Logout", BASE."account.php?sCmd=logout");
|
||||
$g->add("Preferences", BASE."preferences.php");
|
||||
|
||||
/* if this user maintains any applications list them */
|
||||
/* in their sidebar */
|
||||
$apps_user_maintains = Maintainer::getAppsMaintained($_SESSION['current']);
|
||||
if($apps_user_maintains)
|
||||
{
|
||||
$g->add('Maintainership Overview', BASE.'objectManager.php?sClass=maintainerView&iId='.
|
||||
$_SESSION['current']->iUserId.'&sTitle=Your+Maintained+Apps');
|
||||
|
||||
$g->addmisc("");
|
||||
$g->addmisc("You maintain:\n");
|
||||
|
||||
while(list($index, list($appId, $versionId, $superMaintainer)) = each($apps_user_maintains))
|
||||
{
|
||||
$oApp = new application($appId);
|
||||
if($superMaintainer)
|
||||
$g->add($oApp->sName."*", $oApp->objectMakeUrl(),"center");
|
||||
else
|
||||
{
|
||||
$oVersion = new version($versionId);
|
||||
$g->add(version::fullName($versionId),
|
||||
$oVersion->objectMakeUrl(), "center");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Display the user's rejected applications */
|
||||
$iAppsRejected = application::objectGetEntriesCount('rejected');
|
||||
if($iAppsRejected && !$_SESSION['current']->hasPriv("admin"))
|
||||
{
|
||||
$g->add("Review Rejected Apps ($iAppsRejected)", BASE."objectManager.php?".
|
||||
"sClass=application_queue&bIsQueue=true&bIsRejected=true&sTitle=".
|
||||
"Rejected+Applications", "center");
|
||||
}
|
||||
|
||||
/* Display the user's rejected versions */
|
||||
$iVersionsRejected = version::objectGetEntriesCount('rejected');
|
||||
if($iVersionsRejected && !$_SESSION['current']->hasPriv("admin"))
|
||||
{
|
||||
$g->add("Review Rejected Versions ($iVersionsRejected)",
|
||||
BASE."objectManager.php?sClass=version_queue&bIsRejected=true".
|
||||
"&bIsQueue=true&sTitle=Rejected+Versions", "center");
|
||||
}
|
||||
|
||||
/* Display the user's rejected test results */
|
||||
$iTestDataRejected = testData::objectGetEntriesCount('rejected');
|
||||
if($iTestDataRejected && !$_SESSION['current']->hasPriv("admin"))
|
||||
$g->add("Review Rejected Test Results ($iTestDataRejected)",
|
||||
BASE."objectManager.php?sClass=testData_queue&".
|
||||
"sAction=view&bIsQueue=true&bIsRejected=true&sTitle=".
|
||||
"Rejected+Test+Results", "center");
|
||||
|
||||
$aMonitored = Monitor::getVersionsMonitored($_SESSION['current']);
|
||||
if($aMonitored)
|
||||
{
|
||||
$g->addmisc("");
|
||||
$g->addmisc("You monitor:\n");
|
||||
|
||||
while(list($i, list($iAppId, $iVersionId)) = each($aMonitored))
|
||||
{
|
||||
$oVersion = new version($iVersionId);
|
||||
$g->add(version::fullName($iVersionId), $oVersion->objectMakeUrl(), "center");
|
||||
}
|
||||
}
|
||||
|
||||
/* Display a link to the user's queued items,
|
||||
but not for admins, as theirs are auto-accepted */
|
||||
if(!$_SESSION['current']->hasPriv("admin"))
|
||||
{
|
||||
$g->addmisc("");
|
||||
$g->add("Your queued items", BASE."queueditems.php");
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
$g->add("Log in", login_url());
|
||||
$g->add("Register", BASE."account.php?sCmd=new");
|
||||
}
|
||||
|
||||
$g->done();
|
||||
|
||||
}
|
||||
?>
|
||||
22
include/sidebar_maintainer_admin.php
Normal file
22
include/sidebar_maintainer_admin.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/*****************/
|
||||
/* sidebar_admin */
|
||||
/*****************/
|
||||
|
||||
function global_maintainer_admin_menu() {
|
||||
|
||||
$g = new htmlmenu("Maintainer Admin");
|
||||
|
||||
$g->add('View Version Queue ('.version::objectGetEntriesCount('queued').')',
|
||||
BASE.'objectManager.php?sClass=version_queue&sState=queued&sTitle='.
|
||||
'Version%20Queue');
|
||||
$g->add('View Screenshot Queue ('.screenshot::objectGetEntriesCount('queued').')',
|
||||
BASE.'objectManager.php?sClass=screenshot&sState=queued&sTitle='.
|
||||
'Screenshot%20Queue');
|
||||
$g->add('View Test Results Queue ('.testData::objectGetEntriesCount('queued').')',
|
||||
BASE.'objectManager.php?sClass=testData_queue&sState=queued&sTitle='.
|
||||
'Test%20Results%20Queue');
|
||||
$g->done();
|
||||
}
|
||||
|
||||
?>
|
||||
580
include/table.php
Normal file
580
include/table.php
Normal file
@@ -0,0 +1,580 @@
|
||||
<?php
|
||||
|
||||
// classes for managing tables and data related to tables
|
||||
|
||||
// class for managing the highlighting/inactive state of a row
|
||||
class TableRowHighlight
|
||||
{
|
||||
private $oHighlightColor;
|
||||
private $oInactiveColor;
|
||||
|
||||
// properties to apply to text when highlighted or inactive
|
||||
private $sTextDecorationHighlight;
|
||||
private $sTextDecorationInactive;
|
||||
|
||||
function TableRowHighlight(color $oHighlightColor, color $oInactiveColor,
|
||||
$sTextDecorationHighlight = "",
|
||||
$sTextDecorationInactive = "")
|
||||
{
|
||||
$this->oHighlightColor = $oHighlightColor;
|
||||
$this->oInactiveColor = $oInactiveColor;
|
||||
|
||||
$this->sTextDecorationHighlight = $sTextDecorationHighlight;
|
||||
$this->sTextDecorationInactive = $sTextDecorationInactive;
|
||||
}
|
||||
|
||||
function GetHighlightColor()
|
||||
{
|
||||
return $this->oHighlightColor;
|
||||
}
|
||||
|
||||
function GetInactiveColor()
|
||||
{
|
||||
return $this->oInactiveColor;
|
||||
}
|
||||
|
||||
function GetTextDecorationHighlight()
|
||||
{
|
||||
return $this->sTextDecorationHighlight;
|
||||
}
|
||||
|
||||
function GetTextDecorationInactive()
|
||||
{
|
||||
return $this->sTextDecorationInactive;
|
||||
}
|
||||
}
|
||||
|
||||
class TableRowClick
|
||||
{
|
||||
var $oTableRowHighlight;
|
||||
var $bHasHighlight;
|
||||
var $shUrl;
|
||||
|
||||
function TableRowClick($shUrl)
|
||||
{
|
||||
$this->shUrl = $shUrl;
|
||||
$this->bHasHighlight = false;
|
||||
$this->oTableRowHighlight = null;
|
||||
}
|
||||
|
||||
function SetHighlight(TableRowHighlight $oTableRowHighlight)
|
||||
{
|
||||
$this->oTableRowHighlight = $oTableRowHighlight;
|
||||
}
|
||||
|
||||
function GetString()
|
||||
{
|
||||
$sStr = "";
|
||||
|
||||
// if we have highlighting output the attributes necessary to enable the javascript tht we use
|
||||
// to perform the highlighting actions
|
||||
if($this->oTableRowHighlight)
|
||||
{
|
||||
$sStr.= 'onmouseover="ChangeTr(this, true,'.
|
||||
'\''.$this->oTableRowHighlight->getHighlightColor()->GetHexString().'\','.
|
||||
'\''.$this->oTableRowHighlight->getInactiveColor()->GetHexString().'\','.
|
||||
'\''.$this->oTableRowHighlight->getTextDecorationHighlight().'\','.
|
||||
'\''.$this->oTableRowHighlight->getTextDecorationInactive().'\');"';
|
||||
$sStr.= ' onmouseout="ChangeTr(this, false,'.
|
||||
'\''.$this->oTableRowHighlight->getHighlightColor()->GetHexString().'\','.
|
||||
'\''.$this->oTableRowHighlight->getInactiveColor()->GetHexString().'\','.
|
||||
'\''.$this->oTableRowHighlight->getTextDecorationHighlight().'\','.
|
||||
'\''.$this->oTableRowHighlight->getTextDecorationInactive().'\');"';
|
||||
}
|
||||
|
||||
$sStr.= ' onclick="DoNav(\''.$this->shUrl.'\');"';
|
||||
|
||||
return $sStr;
|
||||
}
|
||||
}
|
||||
|
||||
class TableCell
|
||||
{
|
||||
private $sCell;
|
||||
private $sStyle;
|
||||
private $sClass;
|
||||
private $sAlign; // align="$sAlign" will be output if this is not null
|
||||
private $sValign; // valign="$sValign" will be output if this is not null
|
||||
private $sWidth; // width="$sWidth"
|
||||
private $sUrl; // wraps the cell contents in an anchor tag if $sUrl is not null
|
||||
private $bBold; // if true will output the cell contents as bold
|
||||
|
||||
// NOTE: We specifically have limited the parameters to the constructor
|
||||
// to only the contents of the cell. Additional parameters, while
|
||||
// appearing convienent, make the parameters confusing
|
||||
// Use accessors to set additional parameters.
|
||||
function TableCell($sCellContents)
|
||||
{
|
||||
$this->sCellContents = $sCellContents;
|
||||
$this->sStyle = null;
|
||||
$this->sClass = null;
|
||||
$this->sAlign = null;
|
||||
$this->sValign = null;
|
||||
$this->sWidth = null;
|
||||
$this->bBold = false;
|
||||
}
|
||||
|
||||
function SetCellContents($sCellContents)
|
||||
{
|
||||
$this->sCellContents = $sCellContents;
|
||||
}
|
||||
|
||||
function SetStyle($sStyle)
|
||||
{
|
||||
$this->sStyle = $sStyle;
|
||||
}
|
||||
|
||||
function SetClass($sClass)
|
||||
{
|
||||
$this->sClass = $sClass;
|
||||
}
|
||||
|
||||
function SetAlign($sAlign)
|
||||
{
|
||||
$this->sAlign = $sAlign;
|
||||
}
|
||||
|
||||
function SetValign($sValign)
|
||||
{
|
||||
$this->sValign = $sValign;
|
||||
}
|
||||
|
||||
function SetWidth($sWidth)
|
||||
{
|
||||
$this->sWidth = $sWidth;
|
||||
}
|
||||
|
||||
function SetCellLink($sUrl)
|
||||
{
|
||||
$this->sUrl = $sUrl;
|
||||
}
|
||||
|
||||
function SetBold($bBold)
|
||||
{
|
||||
$this->bBold = $bBold;
|
||||
}
|
||||
|
||||
function GetString()
|
||||
{
|
||||
$sStr = "<td";
|
||||
|
||||
if($this->sClass)
|
||||
$sStr.=" class=\"".$this->sClass."\"";
|
||||
|
||||
if($this->sStyle)
|
||||
$sStr.=" style=\"".$this->sStyle."\"";
|
||||
|
||||
if($this->sAlign)
|
||||
$sStr.=" align=\"".$this->sAlign."\"";
|
||||
|
||||
if($this->sValign)
|
||||
$sStr.=" valign=\"".$this->sValign."\"";
|
||||
|
||||
if($this->sWidth)
|
||||
$sStr.=" width=\"".$this->sWidth."\"";
|
||||
|
||||
$sStr.=">";
|
||||
|
||||
// if we have a url, output the start of the anchor tag
|
||||
if($this->sUrl)
|
||||
$sStr.='<a href="'.$this->sUrl.'">';
|
||||
|
||||
if($this->bBold)
|
||||
$sStr.='<b>';
|
||||
|
||||
// output the contents of the cell
|
||||
$sStr.=$this->sCellContents;
|
||||
|
||||
if($this->bBold)
|
||||
$sStr.='</b>';
|
||||
|
||||
// if we have a url, close the anchor tag
|
||||
if($this->sUrl)
|
||||
$sStr.='</a>';
|
||||
|
||||
$sStr.="</td>";
|
||||
|
||||
return $sStr;
|
||||
}
|
||||
}
|
||||
|
||||
class TableRow
|
||||
{
|
||||
protected $aTableCells; // array that contains the cells for the table row
|
||||
private $sStyle; // CSS style to be used
|
||||
private $sClass; // CSS class to be used
|
||||
private $sValign; // valign="$sValign" - if this variable is set
|
||||
|
||||
private $oTableRowClick; // information about whether the table row is clickable etc
|
||||
|
||||
function TableRow()
|
||||
{
|
||||
$this->aTableCells = array();
|
||||
$this->sStyle = null;
|
||||
$this->sClass = null;
|
||||
$this->sValign = null;
|
||||
$this->oTableRowClick = null;
|
||||
}
|
||||
|
||||
function AddCell(TableCell $oTableCell)
|
||||
{
|
||||
$this->aTableCells[] = $oTableCell;
|
||||
}
|
||||
|
||||
function AddCells($aTableCells)
|
||||
{
|
||||
foreach($aTableCells as $oTableCell)
|
||||
{
|
||||
$this->AddCell($oTableCell);
|
||||
}
|
||||
}
|
||||
|
||||
function AddTextCell($sCellText)
|
||||
{
|
||||
$this->AddCell(new TableCell($sCellText));
|
||||
}
|
||||
|
||||
function SetStyle($sStyle)
|
||||
{
|
||||
$this->sStyle = $sStyle;
|
||||
}
|
||||
|
||||
function SetClass($sClass)
|
||||
{
|
||||
$this->sClass = $sClass;
|
||||
}
|
||||
|
||||
function SetValign($sValign)
|
||||
{
|
||||
$this->sValign = $sValign;
|
||||
}
|
||||
|
||||
function SetRowClick($oTableRowClick)
|
||||
{
|
||||
$this->oTableRowClick = $oTableRowClick;
|
||||
}
|
||||
|
||||
// get a string that contains the html representation
|
||||
// of this table row
|
||||
function GetString()
|
||||
{
|
||||
// generate the opening of the tr element
|
||||
$sStr = "<tr";
|
||||
|
||||
if($this->sClass)
|
||||
$sStr.= " class=\"$this->sClass\"";
|
||||
|
||||
if($this->sStyle)
|
||||
$sStr.= " style=\"$this->sStyle\"";
|
||||
|
||||
if($this->sValign)
|
||||
$sStr.= " valign=\"$this->sValign\"";
|
||||
|
||||
if($this->oTableRowClick)
|
||||
$sStr.= " ".$this->oTableRowClick->GetString();
|
||||
|
||||
$sStr.= ">"; // close the opening tr
|
||||
|
||||
// process the td elements
|
||||
foreach($this->aTableCells as $oTableCell)
|
||||
{
|
||||
$sStr.=$oTableCell->GetString();
|
||||
}
|
||||
|
||||
// close the table row
|
||||
$sStr.= "</tr>";
|
||||
|
||||
return $sStr;
|
||||
}
|
||||
|
||||
function GetClass()
|
||||
{
|
||||
return $this->sClass;
|
||||
}
|
||||
|
||||
function GetTableRowClick()
|
||||
{
|
||||
return $this->oTableRowClick;
|
||||
}
|
||||
}
|
||||
|
||||
/* Class for a sortable table row. The user can click on the header for a sortable field, and it
|
||||
will alternate between sorting that by ascending/descending order and the default sorting */
|
||||
class TableRowSortable extends TableRow
|
||||
{
|
||||
private $aSortVars; /* Array of sort variables. Not all fields have to be sortable.
|
||||
This is paired with the aTableCells array from TableRow */
|
||||
|
||||
function TableRowSortable()
|
||||
{
|
||||
$this->aSortVars = array();
|
||||
|
||||
$this->TableRow();
|
||||
}
|
||||
|
||||
/* Adds a table cell without sorting */
|
||||
function AddTableCell(TableCell $oCell)
|
||||
{
|
||||
$this->aTableCells[] = $oCell;
|
||||
$this->aSortVars[] = '';
|
||||
}
|
||||
|
||||
/* Adds a text cell without sorting */
|
||||
function AddTextCell($shText)
|
||||
{
|
||||
$this->AddTableCell(new TableCell($shText));
|
||||
}
|
||||
|
||||
/* Adds a text cell with a sorting var */
|
||||
function AddSortableTextCell($shText, $sSortVar)
|
||||
{
|
||||
$this->aTableCells[] = new TableCell($shText);
|
||||
$this->aSortVars[] = $sSortVar;
|
||||
}
|
||||
|
||||
/* Sets sorting info on all cells that are sortable */
|
||||
function SetSortInfo(TableSortInfo $oSortInfo)
|
||||
{
|
||||
for($i = 0; $i < sizeof($this->aTableCells); $i++)
|
||||
{
|
||||
$sSortVar = $this->aSortVars[$i];
|
||||
|
||||
if($sSortVar)
|
||||
{
|
||||
$bAscending = TRUE;
|
||||
|
||||
if($this->aSortVars[$i] == $oSortInfo->sCurrentSort)
|
||||
{
|
||||
if($oSortInfo->bAscending)
|
||||
$bAscending = FALSE;
|
||||
else
|
||||
$sSortVar = '';
|
||||
|
||||
$this->aTableCells[$i]->sCellContents .= $oSortInfo->bAscending ?
|
||||
' ▲' : ' ▼';
|
||||
}
|
||||
|
||||
$sAscending = $bAscending == TRUE ? 'true': 'false';
|
||||
$this->aTableCells[$i]->SetCellLink($oSortInfo->shUrl."sOrderBy=$sSortVar&bAscending=$sAscending");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Container for table sorting info, used to hold the current sort order */
|
||||
class TableSortInfo
|
||||
{
|
||||
var $sCurrentSort;
|
||||
var $bAscending;
|
||||
var $shUrl;
|
||||
|
||||
function TableSortInfo($shUrl, $sCurrentSort = '', $bAscending = TRUE)
|
||||
{
|
||||
$this->sCurrentSort = $sCurrentSort;
|
||||
$this->shUrl = $shUrl;
|
||||
$this->bAscending = $bAscending;
|
||||
}
|
||||
|
||||
/* Parses an array of HTTP vars to determine current sort settings.
|
||||
Optionally checks the sort var against an array of legal values */
|
||||
function ParseArray($aClean, $aLegalValues = null)
|
||||
{
|
||||
$sCurrentSort = key_exists('sOrderBy', $aClean) ? $aClean['sOrderBy'] : '';
|
||||
|
||||
if($aLegalValues && array_search($sCurrentSort, $aLegalValues) === FALSE)
|
||||
return;
|
||||
|
||||
$this->sCurrentSort = $sCurrentSort;
|
||||
$this->bAscending = key_exists('bAscending', $aClean) ?
|
||||
($aClean['bAscending'] == 'false') ? false : true : true;
|
||||
}
|
||||
}
|
||||
|
||||
// object manager table row, has additional parameters used by the object manager
|
||||
// when outputting a table row
|
||||
//TODO: php5 consider inheriting from HtmlTableRow since this class is really an
|
||||
// extension of that class
|
||||
class OMTableRow
|
||||
{
|
||||
private $oTableRow;
|
||||
private $bHasDeleteLink;
|
||||
private $bCanEdit;
|
||||
|
||||
function OMTableRow($oTableRow)
|
||||
{
|
||||
$this->oTableRow = $oTableRow;
|
||||
$this->bHasDeleteLink = false;
|
||||
$this->bCanEdit = false;
|
||||
}
|
||||
|
||||
function SetHasDeleteLink($bHasDeleteLink)
|
||||
{
|
||||
$this->bHasDeleteLink = $bHasDeleteLink;
|
||||
}
|
||||
|
||||
function GetHasDeleteLink()
|
||||
{
|
||||
return $this->bHasDeleteLink;
|
||||
}
|
||||
|
||||
function SetRowClickable(TableRowClick $oTableRowClick)
|
||||
{
|
||||
$this->oTableRowClick = $oTableRowClick;
|
||||
}
|
||||
|
||||
function SetStyle($sStyle)
|
||||
{
|
||||
$this->oTableRow->SetStyle($sStyle);
|
||||
}
|
||||
|
||||
// add a TableCell to an existing row
|
||||
function AddCell($oTableCell)
|
||||
{
|
||||
$this->oTableRow->AddCell($oTableCell);
|
||||
}
|
||||
|
||||
function GetString()
|
||||
{
|
||||
return $this->oTableRow->GetString();
|
||||
}
|
||||
|
||||
function GetTableRow()
|
||||
{
|
||||
return $this->oTableRow;
|
||||
}
|
||||
}
|
||||
|
||||
class Table
|
||||
{
|
||||
private $oTableRowHeader;
|
||||
private $aTableRows;
|
||||
private $sClass;
|
||||
private $sWidth;
|
||||
private $iBorder;
|
||||
private $sAlign; // align="$sAlign" - deprecated in html standards
|
||||
private $iCellSpacing; // cellspacing="$iCellSpacing"
|
||||
private $iCellPadding; // cellpadding="$iCellPadding"
|
||||
|
||||
function Table()
|
||||
{
|
||||
$this->oTableRowHeader = null;
|
||||
$this->aTableRows = array();
|
||||
$this->sClass = null;
|
||||
$this->sWidth = null;
|
||||
$this->iBorder = null;
|
||||
$this->sAlign = null;
|
||||
$this->iCellSpacing = null;
|
||||
$this->iCellPadding = null;
|
||||
}
|
||||
|
||||
function AddRow($oTableRow)
|
||||
{
|
||||
$this->aTableRows[] = $oTableRow;
|
||||
}
|
||||
|
||||
function SetHeader(TableRow $oTableRowHeader)
|
||||
{
|
||||
$this->oTableRowHeader = $oTableRowHeader;
|
||||
}
|
||||
|
||||
function SetClass($sClass)
|
||||
{
|
||||
$this->sClass = $sClass;
|
||||
}
|
||||
|
||||
function SetWidth($sWidth)
|
||||
{
|
||||
$this->sWidth = $sWidth;
|
||||
}
|
||||
|
||||
function SetBorder($iBorder)
|
||||
{
|
||||
$this->iBorder = $iBorder;
|
||||
}
|
||||
|
||||
function SetAlign($sAlign)
|
||||
{
|
||||
$this->sAlign = $sAlign;
|
||||
}
|
||||
|
||||
function SetCellSpacing($iCellSpacing)
|
||||
{
|
||||
$this->iCellSpacing = $iCellSpacing;
|
||||
}
|
||||
|
||||
function SetCellPadding($iCellPadding)
|
||||
{
|
||||
$this->iCellPadding = $iCellPadding;
|
||||
}
|
||||
|
||||
function GetString()
|
||||
{
|
||||
$sStr = "<table";
|
||||
|
||||
if($this->sClass)
|
||||
$sStr.= ' class="'.$this->sClass.'"';
|
||||
|
||||
if($this->sWidth)
|
||||
$sStr.= ' width="'.$this->sWidth.'"';
|
||||
|
||||
if($this->iBorder !== null)
|
||||
$sStr.= ' border="'.$this->iBorder.'"';
|
||||
|
||||
if($this->sAlign)
|
||||
$sStr.= ' align="'.$this->sAlign.'"';
|
||||
|
||||
if($this->iCellSpacing !== null)
|
||||
$sStr.= ' cellspacing="'.$this->iCellSpacing.'"';
|
||||
|
||||
if($this->iCellPadding !== null)
|
||||
$sStr.= ' cellpadding="'.$this->iCellPadding.'"';
|
||||
|
||||
$sStr.= ">"; // close the open table element
|
||||
|
||||
if($this->oTableRowHeader)
|
||||
{
|
||||
$sStr.="<thead>";
|
||||
$sStr.= $this->oTableRowHeader->GetString();
|
||||
$sStr.="</thead>";
|
||||
}
|
||||
|
||||
foreach($this->aTableRows as $oTableRow)
|
||||
{
|
||||
$sStr.= $oTableRow->GetString();
|
||||
}
|
||||
|
||||
$sStr.= "</table>";
|
||||
|
||||
return $sStr;
|
||||
}
|
||||
}
|
||||
|
||||
// input is the row index, we alternate colors based on odd or even index rows
|
||||
// returns a TableRowHighlight instance
|
||||
function GetStandardRowHighlight($iRowIndex)
|
||||
{
|
||||
//set row color
|
||||
$sColor = ($iRowIndex % 2) ? "color0" : "color1";
|
||||
|
||||
$oInactiveColor = new color();
|
||||
$oInactiveColor->SetColorByName($sColor);
|
||||
|
||||
$oHighlightColor = GetHighlightColorFromInactiveColor($oInactiveColor);
|
||||
|
||||
$oTableRowHighlight = new TableRowHighlight($oHighlightColor, $oInactiveColor);
|
||||
|
||||
return $oTableRowHighlight;
|
||||
}
|
||||
|
||||
// returns a color class instance
|
||||
function GetHighlightColorFromInactiveColor(color $oInactiveColor)
|
||||
{
|
||||
$oHighlightColor = new color($oInactiveColor->iRed,
|
||||
$oInactiveColor->iGreen,
|
||||
$oInactiveColor->iBlue);
|
||||
$oHighlightColor->Add(50);
|
||||
|
||||
return $oHighlightColor;
|
||||
}
|
||||
|
||||
?>
|
||||
480
include/tableve.php
Normal file
480
include/tableve.php
Normal file
@@ -0,0 +1,480 @@
|
||||
<?php
|
||||
class TableVE {
|
||||
|
||||
var $mode;
|
||||
var $titleField;
|
||||
var $titleText;
|
||||
var $numberedTitles;
|
||||
|
||||
/*
|
||||
* mode can be: view, edit, create
|
||||
*/
|
||||
function TableVE($mode)
|
||||
{
|
||||
$this->mode = $mode;
|
||||
$this->titleField = "";
|
||||
$this->titleText = "";
|
||||
$this->numberedTitles = 0;
|
||||
}
|
||||
|
||||
function test($query)
|
||||
{
|
||||
$hResult = query_appdb($query);
|
||||
$nfields = query_num_fields($hResult);
|
||||
$nrows = query_num_rows($hResult);
|
||||
$table = query_field_table($hResult, 0);
|
||||
|
||||
echo "Table: $table <br> Fields: $nfields <br> Rows: $nrows <br> <br>\n";
|
||||
|
||||
$i = 0;
|
||||
while($i < $nfields)
|
||||
{
|
||||
$type = query_field_type($hResult, $i);
|
||||
$name = query_field_name($hResult, $i);
|
||||
$len = query_field_len($hResult, $i);
|
||||
$flags = query_field_flags($hResult, $i);
|
||||
|
||||
echo "$type | $name | $len | $flags <br>\n";
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* this is a bit of a hack,
|
||||
* we first create an empty entry, and then simply use the
|
||||
* edit() function to do the rest of the work for us.
|
||||
*/
|
||||
function create($query, $table, $idcolumn)
|
||||
{
|
||||
$hResult = query_appdb($query);
|
||||
$id = query_appdb_insert_id();
|
||||
|
||||
$new_query = "SELECT * FROM $table WHERE $idcolumn = $id";
|
||||
$this->edit($new_query);
|
||||
}
|
||||
|
||||
|
||||
function view($query)
|
||||
{
|
||||
//$this->test($query);
|
||||
|
||||
$nrows = 0;
|
||||
|
||||
$hResult = query_appdb($query);
|
||||
$nrows = query_num_rows($hResult);
|
||||
|
||||
if(debugging())
|
||||
{
|
||||
echo "Query returns $nrows rows.";
|
||||
}
|
||||
|
||||
for($i = 0; $i < $nrows; $i++)
|
||||
{
|
||||
$this->view_entry($hResult, $i);
|
||||
echo "<br>\n";
|
||||
}
|
||||
}
|
||||
|
||||
function view_entry($hResult, $num)
|
||||
{
|
||||
$nfields = query_num_fields($hResult);
|
||||
$fields = query_fetch_array($hResult, MYSQL_BOTH);
|
||||
|
||||
$titleValue = $fields[$this->titleField];
|
||||
$titleText = $this->titleText;
|
||||
if($this->numberedTitles)
|
||||
{
|
||||
// don't want zero-based.
|
||||
$num++;
|
||||
$titleText .= " # $num";
|
||||
}
|
||||
|
||||
//echo "<table border=1 bordercolor=black width='80%' cellpadding=0 cellspacing=0>\n";
|
||||
//echo "<th class='box-title' colspan='2'></th></tr>\n";
|
||||
|
||||
//echo "<tr><td>\n";
|
||||
|
||||
echo html_frame_start("Viewing $titleValue $titleText","80%","",0);
|
||||
echo "<table border=0 width='100%' cellspacing=0 cellpadding=2>\n";
|
||||
|
||||
for($i = 0; $i < $nfields; $i++)
|
||||
{
|
||||
$field = query_fetch_field($hResult, $i);
|
||||
|
||||
if(ereg("^impl_(.+)$", $field->table, $arr))
|
||||
{
|
||||
if($cur_impl != $arr[1])
|
||||
echo "<tr><th class='box-label' colspan=2> ".ucfirst($arr[1])." Implementation </th></tr>\n";
|
||||
$cur_impl = $arr[1];
|
||||
}
|
||||
|
||||
echo "<tr><td width='15%' class='box-label'><b> $field->name </b></td>";
|
||||
echo "<td class='box-body'>";
|
||||
$this->view_entry_output_field($field, $fields[$i], 0);
|
||||
echo "</td></tr>\n";
|
||||
}
|
||||
|
||||
echo "</table>\n";
|
||||
echo html_frame_end();
|
||||
}
|
||||
|
||||
|
||||
function edit($query)
|
||||
{
|
||||
$hResult = query_appdb($query);
|
||||
$nrows = query_num_rows($hResult);
|
||||
|
||||
echo "<form method=post action='".$_SERVER['PHP_SELF']."'>\n";
|
||||
|
||||
for($i = 0; $i < $nrows; $i++)
|
||||
{
|
||||
$this->edit_entry($hResult);
|
||||
echo "<br>\n";
|
||||
}
|
||||
|
||||
echo html_frame_start("Update Database",100);
|
||||
echo "<input type=submit value='Update Database'>\n";
|
||||
echo html_frame_end();
|
||||
|
||||
echo "</form>\n";
|
||||
}
|
||||
|
||||
|
||||
function edit_entry($hResult)
|
||||
{
|
||||
$nfields = query_num_fields($hResult);
|
||||
$fields = query_fetch_array($hResult);
|
||||
|
||||
echo html_frame_start(ucfirst($this->mode),"80%","",0);
|
||||
echo "<table border=0 width='100%' cellspacing=0 cellpadding=2>\n";
|
||||
|
||||
$cur_impl = null;
|
||||
for($i = 0; $i < $nfields; $i++)
|
||||
{
|
||||
global $testvar;
|
||||
$field = query_fetch_field($hResult, $i);
|
||||
$len = query_field_len($hResult, $i);
|
||||
|
||||
if(ereg("^impl_(.+)$", $field->table, $arr))
|
||||
{
|
||||
if($cur_impl != $arr[1])
|
||||
echo "<tr><th class='box-label' colspan=2> ".ucfirst($arr[1])." Implementation </th></tr>\n";
|
||||
$cur_impl = $arr[1];
|
||||
}
|
||||
|
||||
echo "<tr><td width='15%' class='box-label'><b> $field->name </b></td>";
|
||||
echo "<td class='box-body'> ";
|
||||
$this->edit_entry_output_field($field, $fields[$i], $len);
|
||||
echo "</td></tr>\n";
|
||||
}
|
||||
|
||||
echo "</table>\n";
|
||||
echo html_frame_end();
|
||||
}
|
||||
|
||||
// returns a string that contains the option list
|
||||
function make_option_list($sVarname, $sCvalue, $sTable, $sIdField, $sNameField, $aWhere = null)
|
||||
{
|
||||
$sStr = "";
|
||||
|
||||
/* We do not allow direct insertion into of SQL code, so the WHERE clause is
|
||||
is accepted in an array form, where the first element is the variable
|
||||
and the second is the value it must be equal to */
|
||||
if($aWhere)
|
||||
$sWhere = "WHERE ".$aWhere[0]." ='".$aWhere[1]."'";
|
||||
|
||||
$hResult = query_parameters("SELECT ?, ? FROM ? $sWhere ORDER BY ?",
|
||||
$sIdField, $sNameField, $sTable, $sNameField);
|
||||
if(!$hResult)
|
||||
return $sStr; // Oops
|
||||
|
||||
$sStr.= "<select name='$sVarname'>\n";
|
||||
$sStr.= "<option value=0>Choose ...</option>\n";
|
||||
while(list($iId, $sName) = query_fetch_row($hResult))
|
||||
{
|
||||
if ($sName == "NONAME")
|
||||
continue;
|
||||
if($iId == $sCvalue)
|
||||
$sStr.= "<option value=$iId selected>$sName\n";
|
||||
else
|
||||
$sStr.= "<option value=$iId>$sName\n";
|
||||
}
|
||||
$sStr.= "</select>\n";
|
||||
|
||||
return $sStr;
|
||||
}
|
||||
|
||||
|
||||
function edit_entry_output_field($field, $value, $len)
|
||||
{
|
||||
static $idx = 0;
|
||||
|
||||
$idx++;
|
||||
if($len > 50)
|
||||
$len = 50;
|
||||
|
||||
$varname = "FIELD_".$field->table."___".$field->name."[]";
|
||||
echo "<input type=hidden name='TYPE_$varname' value='$field->type'>\n";
|
||||
|
||||
if($field->name == "appId" && $field->table != "appFamily")
|
||||
{
|
||||
echo $this->make_option_list($varname, $value, "appFamily", "appId", "appName");
|
||||
return;
|
||||
}
|
||||
|
||||
if($field->name == "vendorId" && $field->table != "vendor")
|
||||
{
|
||||
echo $this->make_option_list($varname, $value, "vendor", "vendorId", "vendorName");
|
||||
return;
|
||||
}
|
||||
|
||||
if($field->name == "catId" && $field->table != "appCategory")
|
||||
{
|
||||
echo $this->make_option_list($varname, $value, "appCategory", "catId", "catName");
|
||||
return;
|
||||
}
|
||||
|
||||
if($field->name == "catParent")
|
||||
{
|
||||
echo $this->make_option_list($varname, $value, "appCategory", "catId", "catName");
|
||||
return;
|
||||
}
|
||||
|
||||
if($field->name == "keywords")
|
||||
{
|
||||
echo "<textarea cols=$len rows=3 name='$varname'>".stripslashes($value)."</textarea>\n";
|
||||
return;
|
||||
}
|
||||
|
||||
switch($field->type)
|
||||
{
|
||||
case "string":
|
||||
case "enum":
|
||||
case "int":
|
||||
case "text":
|
||||
echo "<input type=text size=$len name='$varname' value='".stripslashes($value)."'>\n";
|
||||
break;
|
||||
case "blob":
|
||||
echo "<textarea cols=$len rows=10 name='$varname'>".stripslashes($value)."</textarea>\n";
|
||||
break;
|
||||
case "timestamp":
|
||||
$time = mysqltimestamp_to_unixtimestamp($value);
|
||||
echo print_date($time);
|
||||
break;
|
||||
case "datetime":
|
||||
$time = mysqldatetime_to_unixtimestamp($value);
|
||||
echo print_date($time);
|
||||
break;
|
||||
default:
|
||||
echo "$value \n";
|
||||
break;
|
||||
}
|
||||
|
||||
$this->entry_add_extra($field, $value);
|
||||
}
|
||||
|
||||
function view_entry_output_field($field, $value, $len)
|
||||
{
|
||||
if($len > 50)
|
||||
$len = 50;
|
||||
|
||||
//FIXME: need a better way for special cases
|
||||
if(!$value && $field->name == "comments")
|
||||
{
|
||||
echo "none";
|
||||
return;
|
||||
}
|
||||
if(!$value && ($field->name == "location" || $field->name == "quality"))
|
||||
{
|
||||
echo "unknown";
|
||||
return;
|
||||
}
|
||||
|
||||
if($field->name == "lastmodby")
|
||||
{
|
||||
$user = new User();
|
||||
$name = $user->lookup_realname($value);
|
||||
if(!$name)
|
||||
$name = "system";
|
||||
echo "$name ($value)";
|
||||
return;
|
||||
}
|
||||
|
||||
switch($field->type)
|
||||
{
|
||||
case "string":
|
||||
case "enum":
|
||||
case "int":
|
||||
case "blob":
|
||||
echo "$value \n";
|
||||
break;
|
||||
case "timestamp":
|
||||
$time = mysqltimestamp_to_unixtimestamp($value);
|
||||
echo print_date($time);
|
||||
break;
|
||||
case "datetime":
|
||||
$time = mysqldatetime_to_unixtimestamp($value);
|
||||
echo print_date($time);
|
||||
break;
|
||||
default:
|
||||
echo "$value \n";
|
||||
break;
|
||||
}
|
||||
|
||||
$this->entry_add_extra($field, $value);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* add extra stuff to certain fields
|
||||
*/
|
||||
function entry_add_extra($field, $value)
|
||||
{
|
||||
/*
|
||||
* add extra stuff to certain fields
|
||||
*/
|
||||
|
||||
if($field->name == "mslink" && $value)
|
||||
{
|
||||
echo html_imagebutton("Go!", $value);
|
||||
}
|
||||
|
||||
if($field->name == "apiname")
|
||||
{
|
||||
echo html_imagebutton("Wine LXR", "http://twine.codeweavers.com/lxr/ident?i=$value");
|
||||
echo html_imagebutton("Wine API", "http://www.winehq.com/WineAPI/$value.html");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* required field for each table.
|
||||
* When editing a query this field needs to be present in the query
|
||||
* in order to identify the correct row to update.
|
||||
*/
|
||||
var $table_ids = array(
|
||||
"user_list" => "userid",
|
||||
"appFamily" => "appId",
|
||||
"appVersion" => "versionId",
|
||||
"userExperience" => "uExpId",
|
||||
"appCategory" => "catId",
|
||||
"vendor" => "vendorId",
|
||||
"appNotes" => "noteId"
|
||||
);
|
||||
|
||||
function get_id($name)
|
||||
{
|
||||
reset($this->table_ids);
|
||||
while(list($table, $id) = each($this->table_ids))
|
||||
{
|
||||
$r = "^$table$";
|
||||
//echo "Checking $r against $name <br>\n";
|
||||
if(ereg($r, $name))
|
||||
{
|
||||
//echo "ID for $name -> $id <br>\n";
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* update() expects $_POST as argument
|
||||
* this is where things are getting kinda complex, here we update "
|
||||
* multiple entries with multiple fields in multiple tables (get it?)
|
||||
*/
|
||||
function update($vars)
|
||||
{
|
||||
$tables = array();
|
||||
$fieldnames = array();
|
||||
$num_entries = 0;
|
||||
|
||||
while(list($varname, $arr) = each($vars))
|
||||
{
|
||||
if(!ereg("^FIELD_([a-zA-Z_]+)___(.+)$", $varname, $regs))
|
||||
continue;
|
||||
|
||||
$tables[$regs[1]][] = $regs[2];
|
||||
$fieldnames[$regs[2]] = $arr;
|
||||
$num_entries = sizeof($arr);
|
||||
}
|
||||
|
||||
while(list($table, $fields) = each($tables))
|
||||
{
|
||||
echo "<b> $table (".$this->get_id($table).") </b>";
|
||||
|
||||
if($fieldnames[$this->get_id($table)])
|
||||
echo "OK!";
|
||||
|
||||
echo "<br>\n";
|
||||
|
||||
for($i = 0; $i < sizeof($fields); $i++)
|
||||
echo "- $fields[$i] <br>\n";
|
||||
|
||||
echo "<br>\n";
|
||||
}
|
||||
|
||||
for($i = 0; $i < $num_entries; $i++)
|
||||
{
|
||||
reset($tables);
|
||||
while(list($table, $fields) = each($tables))
|
||||
{
|
||||
$update = "UPDATE $table SET ";
|
||||
|
||||
$count = sizeof($fields);
|
||||
reset($fields);
|
||||
while(list($idx, $field) = each($fields))
|
||||
{
|
||||
$count--;
|
||||
|
||||
if($this->table_ids[$table] == $field)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$key = "FIELD_".$table."___".$field;
|
||||
$type = $vars["TYPE_$key"][$i];
|
||||
|
||||
if($type == "int")
|
||||
$update .= "$field = ".$vars[$key][$i];
|
||||
else
|
||||
$update .= "$field = '".addslashes($vars[$key][$i])."'";
|
||||
|
||||
if($count)
|
||||
$update .= ", ";
|
||||
}
|
||||
|
||||
$value = $fieldnames[$this->get_id($table)][$i];
|
||||
|
||||
$update .= " WHERE ".$this->get_id($table)." = $value";
|
||||
|
||||
if(query_appdb($update))
|
||||
{
|
||||
addmsg("Database Operation Complete!","green");
|
||||
}
|
||||
|
||||
if(ereg("^impl_.+$", $table))
|
||||
{
|
||||
$value = $fieldnames["apiid"][$i];
|
||||
query_parameters("UPDATE ? SET lastmodby = '?' WHERE apiid = '?'",
|
||||
$table, $_SESSION['current']->iUserId, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function set_title_field($newTitleField)
|
||||
{
|
||||
$this->titleField = $newTitleField;
|
||||
}
|
||||
|
||||
function set_title_text($newTitleText)
|
||||
{
|
||||
$this->titleText = $newTitleText;
|
||||
}
|
||||
|
||||
function set_numbered_titles()
|
||||
{
|
||||
$this->numberedTitles = 1;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
1517
include/testData.php
Normal file
1517
include/testData.php
Normal file
File diff suppressed because it is too large
Load Diff
242
include/testData_queue.php
Normal file
242
include/testData_queue.php
Normal file
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
|
||||
class testData_queue
|
||||
{
|
||||
var $oTestData;
|
||||
var $oDistribution;
|
||||
|
||||
function testData_queue($iTestId = null, $oRow = null)
|
||||
{
|
||||
$this->oTestData = new testData($iTestId, $oRow);
|
||||
$this->oDistribution = new distribution($this->oTestData->iDistributionId);
|
||||
}
|
||||
|
||||
function create()
|
||||
{
|
||||
if(!$this->oTestData->iDistributionId)
|
||||
{
|
||||
$this->oDistribution->create();
|
||||
$this->oTestData->iDistributionId = $this->oDistribution->iDistributionId;
|
||||
}
|
||||
|
||||
return $this->oTestData->create();
|
||||
}
|
||||
|
||||
function purge()
|
||||
{
|
||||
$bSuccess = $this->oTestData->purge();
|
||||
|
||||
/* We delete the distribution if it has not been approved and is not associated
|
||||
with any other testData. Otherwise we would have to have a distribution
|
||||
queue for admins to clean up unused, queued entries */
|
||||
$this->oDistribution = new distribution($this->oDistribution->iDistributionId);
|
||||
if(!sizeof($this->oDistribution->aTestingIds) &&
|
||||
$this->oDistribution->canEdit())
|
||||
$this->oDistribution->purge();
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
|
||||
function delete()
|
||||
{
|
||||
$bSuccess = $this->oTestData->delete();
|
||||
|
||||
/* We delete the distribution if it has not been approved and is not associated
|
||||
with any other testData. Otherwise we would have to have a distribution
|
||||
queue for admins to clean up unused, queued entries */
|
||||
$this->oDistribution = new distribution($this->oDistribution->iDistributionId);
|
||||
if(!sizeof($this->oDistribution->aTestingIds) &&
|
||||
$this->oDistribution->canEdit())
|
||||
$this->oDistribution->delete();
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
|
||||
function reQueue()
|
||||
{
|
||||
$this->oTestData->reQueue();
|
||||
|
||||
$this->oDistribution->reQueue();
|
||||
}
|
||||
|
||||
function unQueue()
|
||||
{
|
||||
$this->oTestData->unQueue();
|
||||
|
||||
/* Avoid a misguiding message about the distribution being unqueued */
|
||||
if($this->oDistribution->objectGetState() != 'accepted')
|
||||
$this->oDistribution->unQueue();
|
||||
}
|
||||
|
||||
function reject()
|
||||
{
|
||||
$this->oTestData->reject();
|
||||
}
|
||||
|
||||
function update()
|
||||
{
|
||||
$this->oTestData->update();
|
||||
|
||||
/* If the distribution was already un-queued the form for editing it would
|
||||
not have been displayed and getOutputEditorValues() wouldn't have
|
||||
retrieved a valid sName for the distribution. If sName isn't valid
|
||||
we shouldn't update the distribution */
|
||||
if($this->oDistribution->sName)
|
||||
$this->oDistribution->update();
|
||||
}
|
||||
|
||||
function outputEditor()
|
||||
{
|
||||
$this->oTestData->outputEditor();
|
||||
|
||||
/* If we are processing queued test results with a queued distribution,
|
||||
we display some additional help here */
|
||||
if($this->oDistribution->iDistributionId &&
|
||||
$this->oDistribution->objectGetState() != 'accepted' && $this->canEdit())
|
||||
{
|
||||
echo "The user submitted a new distribution, which will be un-queued ".
|
||||
"together with the test data unless you select an existing one ".
|
||||
"from the list above.";
|
||||
}
|
||||
|
||||
/* If the testData is already associated with a distribution and the
|
||||
distribution is un-queued, there is no need to display the
|
||||
distribution form here */
|
||||
if(!$this->oTestData->iDistributionId or
|
||||
$this->oDistribution->objectGetState() != 'accepted')
|
||||
{
|
||||
echo html_frame_start("New Distribution", "90%");
|
||||
$this->oDistribution->outputEditor();
|
||||
echo html_frame_end();
|
||||
}
|
||||
}
|
||||
|
||||
function getOutputEditorValues($aClean)
|
||||
{
|
||||
$this->oTestData->getOutputEditorValues($aClean);
|
||||
$this->oDistribution->getOutputEditorValues($aClean);
|
||||
}
|
||||
|
||||
function checkOutputEditorInput($aClean)
|
||||
{
|
||||
return $this->oTestData->checkOutputEditorInput($aClean);
|
||||
}
|
||||
|
||||
function objectGetState()
|
||||
{
|
||||
return $this->oTestData->objectGetState();
|
||||
}
|
||||
|
||||
function canEdit()
|
||||
{
|
||||
return $this->oTestData->canEdit();
|
||||
}
|
||||
|
||||
function mustBeQueued()
|
||||
{
|
||||
return $this->oTestData->mustBeQueued();
|
||||
}
|
||||
|
||||
function objectDisplayAddItemHelp()
|
||||
{
|
||||
$this->oTestData->objectDisplayAddItemHelp();
|
||||
}
|
||||
|
||||
public static function objectGetDefaultSort()
|
||||
{
|
||||
return testData::objectGetDefaultSort();
|
||||
}
|
||||
|
||||
function objectGetEntries($sState, $iRows = 0, $iStart = 0, $sOrderBy = "testingId", $bAscending = true)
|
||||
{
|
||||
return $this->oTestData->objectGetEntries($sState, $iRows, $iStart, $sOrderBy, $bAscending);
|
||||
}
|
||||
|
||||
function objectGetEntriesCount($sState)
|
||||
{
|
||||
return testData::objectGetEntriesCount($sState);
|
||||
}
|
||||
|
||||
function objectGetHeader()
|
||||
{
|
||||
return $this->oTestData->objectGetHeader();
|
||||
}
|
||||
|
||||
function objectGetTableRow()
|
||||
{
|
||||
return $this->oTestData->objectGetTableRow();
|
||||
}
|
||||
|
||||
function objectDisplayQueueProcessingHelp()
|
||||
{
|
||||
$oTest = new testData();
|
||||
$oTest->objectDisplayQueueProcessingHelp();
|
||||
}
|
||||
|
||||
function objectShowPreview()
|
||||
{
|
||||
return $this->oTestData->objectShowPreview();
|
||||
}
|
||||
|
||||
function display()
|
||||
{
|
||||
return $this->oTestData->display();
|
||||
}
|
||||
|
||||
function objectMakeUrl()
|
||||
{
|
||||
return $this->oTestData->objectMakeUrl();
|
||||
}
|
||||
|
||||
function objectMakeLink()
|
||||
{
|
||||
return $this->oTestData->objectMakeLink();
|
||||
}
|
||||
|
||||
function allowAnonymousSubmissions()
|
||||
{
|
||||
return testData::allowAnonymousSubmissions();
|
||||
}
|
||||
|
||||
function objectAllowPurgingRejected()
|
||||
{
|
||||
return $this->oTestData->objectAllowPurgingRejected();
|
||||
}
|
||||
|
||||
public function objectGetSubmitTime()
|
||||
{
|
||||
return $this->oTestData->objectGetSubmitTime();
|
||||
}
|
||||
|
||||
function objectGetItemsPerPage($sState = 'accepted')
|
||||
{
|
||||
return testData::objectGetItemsPerPage($sState);
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->oTestData->objectGetId();
|
||||
}
|
||||
|
||||
function objectGetSubmitterId()
|
||||
{
|
||||
return $this->oTestData->objectGetSubmitterId();
|
||||
}
|
||||
|
||||
function objectGetChildren($bIncludeDeleted = false)
|
||||
{
|
||||
return $this->oTestData->objectGetChildren($bIncludeDeleted);
|
||||
}
|
||||
|
||||
function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return $this->oTestData->objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction);
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return $this->oTestData->objectGetMail($sAction, $bMailSubmitter, $bParentAction);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
558
include/url.php
Normal file
558
include/url.php
Normal file
@@ -0,0 +1,558 @@
|
||||
<?php
|
||||
/***************************************/
|
||||
/* url class and related functions */
|
||||
/***************************************/
|
||||
require_once(BASE."include/util.php");
|
||||
|
||||
/**
|
||||
* Url class for handling urls
|
||||
*/
|
||||
class Url {
|
||||
var $iUrlId;
|
||||
var $iAppId;
|
||||
var $iVersionId;
|
||||
var $sDescription;
|
||||
var $sUrl;
|
||||
var $sSubmitTime;
|
||||
var $sSubmitterId;
|
||||
var $bQueued;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor, fetches the url $iUrlId is given.
|
||||
*/
|
||||
function Url($iUrlId = null, $oRow = null)
|
||||
{
|
||||
if(!$iUrlId && !$oRow)
|
||||
return;
|
||||
|
||||
if(!$oRow)
|
||||
{
|
||||
$sQuery = "SELECT appData.*
|
||||
FROM appData
|
||||
WHERE type = 'url'
|
||||
AND id = '?'";
|
||||
$hResult = query_parameters($sQuery, $iUrlId);
|
||||
$oRow = query_fetch_object($hResult);
|
||||
}
|
||||
|
||||
// we are working on an existing url
|
||||
if($oRow)
|
||||
{
|
||||
$this->iUrlId = $oRow->id;
|
||||
$this->sDescription = $oRow->description;
|
||||
$this->iAppId = $oRow->appId;
|
||||
$this->iVersionId = $oRow->versionId;
|
||||
$this->sUrl = Url::normalize($oRow->url);
|
||||
$this->bQueued = ($oRow->state == 'accepted') ? false : true;
|
||||
$this->sSubmitTime = $oRow->submitTime;
|
||||
$this->iSubmitterId = $oRow->submitterId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new url.
|
||||
*/
|
||||
function create($sDescription = null, $sUrl = null, $iVersionId = null,
|
||||
$iAppId = null, $bSilent = false)
|
||||
{
|
||||
global $aClean;
|
||||
|
||||
// Security, if we are not an administrator or a maintainer, the url must be queued.
|
||||
if(($iAppId && !url::canEdit(NULL, $iAppId)) ||
|
||||
($iVersionId && !url::canEdit($iVersionId)))
|
||||
$this->bQueued = true;
|
||||
|
||||
$hResult = query_parameters("INSERT INTO appData (appId, versionId, type,
|
||||
description, state, submitTime, submitterId, url)
|
||||
VALUES ('?', '?', '?', '?', '?', ?, '?', '?')",
|
||||
$iAppId, $iVersionId, "url", $sDescription,
|
||||
$this->bQueued ? 'queued' : 'accepted',
|
||||
"NOW()", $_SESSION['current']->iUserId, $sUrl);
|
||||
|
||||
if(!$hResult)
|
||||
{
|
||||
addmsg("Error while creating a new url.", "red");
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->iUrlId = query_appdb_insert_id();
|
||||
$this->url($this->iUrlId,$this->bQueued);
|
||||
|
||||
if(!$bSilent)
|
||||
$this->SendNotificationMail();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function purge()
|
||||
{
|
||||
return $this->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the url from the database.
|
||||
* and request its deletion from the filesystem (including the thumbnail).
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
$sQuery = "DELETE FROM appData
|
||||
WHERE id = '?'
|
||||
AND type = 'url'
|
||||
LIMIT 1";
|
||||
if(!$hResult = query_parameters($sQuery, $this->iUrlId))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Move url out of the queue.
|
||||
*/
|
||||
function unQueue()
|
||||
{
|
||||
// If we are not in the queue, we can't move the url out of the queue.
|
||||
if(!$this->bQueued)
|
||||
return false;
|
||||
|
||||
if(query_parameters("UPDATE appData SET state '?' WHERE id='?'",
|
||||
'accepted', $this->iUrlId))
|
||||
{
|
||||
// we send an e-mail to interested people
|
||||
$this->mailSubmitter();
|
||||
$this->SendNotificationMail();
|
||||
// the url has been unqueued
|
||||
addmsg("The url has been unqueued.", "green");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update url.
|
||||
* Returns true on success and false on failure.
|
||||
*/
|
||||
function update($sDescription = null, $sUrl = null, $iVersionId = null, $iAppId = null, $bSilent = false)
|
||||
{
|
||||
if(!$this->iUrlId)
|
||||
return FALSE;
|
||||
|
||||
$oUrl = new url($this->iUrlId);
|
||||
|
||||
if($this->iVersionId && !$iVersionId)
|
||||
$iVersionId = $this->iVersionId;
|
||||
|
||||
$sWhatChanged = "";
|
||||
|
||||
if ($sDescription && $sDescription!=$this->sDescription)
|
||||
{
|
||||
if (!query_parameters("UPDATE appData SET description = '?' WHERE id = '?'",
|
||||
$sDescription, $this->iUrlId))
|
||||
return false;
|
||||
$sWhatChanged .= "Description was changed from\n ".$this->sDescription."\n to \n".$sDescription.".\n\n";
|
||||
$this->sDescription = $sDescription;
|
||||
}
|
||||
|
||||
if ($sUrl && $sUrl!=$this->sUrl)
|
||||
{
|
||||
if (!query_parameters("UPDATE appData SET url = '?' WHERE id = '?'",
|
||||
$sUrl, $this->iUrlId))
|
||||
return false;
|
||||
$sWhatChanged .= "Url was changed from ".$this->sUrl." to ".$sUrl.".\n\n";
|
||||
$this->sUrl = $sUrl;
|
||||
}
|
||||
|
||||
if ($iVersionId && $iVersionId!=$oUrl->iVersionId)
|
||||
{
|
||||
if (!query_parameters("UPDATE appData SET versionId = '?' WHERE id = '?'",
|
||||
$iVersionId, $this->iUrlId))
|
||||
return false;
|
||||
$oVersionBefore = new Version($this->iVersionId);
|
||||
$oVersionAfter = new Version($iVersionId);
|
||||
$sWhatChanged .= "Version was changed from ".$oVersionBefore->sName." to ".$oVersionAfter->sName.".\n\n";
|
||||
$this->iVersionId = $iVersionId;
|
||||
$this->iAppId = $oVersionAfter->iAppId;
|
||||
}
|
||||
|
||||
if ($iAppId && $iAppId!=$this->iAppId)
|
||||
{
|
||||
if (!query_parameters("UPDATE appData SET appId = '?' WHERE id = '?'",
|
||||
$iAppId, $this->iUrlId))
|
||||
return false;
|
||||
$oAppBefore = new Application($this->iAppId);
|
||||
$oAppAfter = new Application($iAppId);
|
||||
$sWhatChanged .= "Application was changed from ".$oAppBefore->sName." to ".$oAppAfter->sName.".\n\n";
|
||||
$this->iAppId = $iAppId;
|
||||
}
|
||||
if($sWhatChanged && !$bSilent)
|
||||
$this->SendNotificationMail("edit",$sWhatChanged);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function mailSubmitter($bRejected=false)
|
||||
{
|
||||
global $aClean;
|
||||
|
||||
if($this->iSubmitterId)
|
||||
{
|
||||
$sAppName = Application::lookup_name($this->iAppId)." ".Version::lookup_name($this->iVersionId);
|
||||
$oSubmitter = new User($this->iSubmitterId);
|
||||
if(!$bRejected)
|
||||
{
|
||||
$sSubject = "Submitted url accepted";
|
||||
$sMsg = "The url you submitted for ".$sAppName." has been accepted.";
|
||||
} else
|
||||
{
|
||||
$sSubject = "Submitted url rejected";
|
||||
$sMsg = "The url you submitted for ".$sAppName." has been rejected.";
|
||||
}
|
||||
$sMsg .= $aClean['sReplyText']."\n";
|
||||
$sMsg .= "We appreciate your help in making the Application Database better for all users.";
|
||||
|
||||
mail_appdb($oSubmitter->sEmail, $sSubject ,$sMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function SendNotificationMail($bDeleted=false)
|
||||
{
|
||||
/* Set variables depending on whether the url is for an app or version */
|
||||
if($this->iVersionId)
|
||||
{
|
||||
$oVersion = new version($this->iVersionId);
|
||||
$sAppName = version::fullName($this->iVersionId);
|
||||
$sUrl = $oVersion->objectMakeUrl();
|
||||
} else
|
||||
{
|
||||
$oApp = new application($this->iAppId);
|
||||
$sAppName = $oApp->sName;
|
||||
$sUrl = $oApp->objectMakeUrl();
|
||||
}
|
||||
|
||||
if(!$bDeleted)
|
||||
{
|
||||
if(!$this->bQueued)
|
||||
{
|
||||
$sSubject = "Url for $sAppName added by ".$_SESSION['current']->sRealname;
|
||||
$sMsg = "$sUrl\n";
|
||||
if($this->iSubmitterId)
|
||||
{
|
||||
$oSubmitter = new User($this->iSubmitterId);
|
||||
$sMsg .= "This url has been submitted by ".$oSubmitter->sRealname.".";
|
||||
$sMsg .= "\n";
|
||||
}
|
||||
addmsg("The url was successfully added into the database.", "green");
|
||||
} else // Url queued.
|
||||
{
|
||||
$sSubject = "Url for $sAppName submitted by ".
|
||||
$_SESSION['current']->sRealname;
|
||||
$sMsg = "$sUrl\n";
|
||||
$sMsg .= "This url has been queued.";
|
||||
$sMsg .= "\n";
|
||||
addmsg("The url you submitted will be added to the database ".
|
||||
"database after being reviewed.", "green");
|
||||
}
|
||||
}
|
||||
|
||||
$sEmail = User::get_notify_email_address_list(null, $this->iVersionId);
|
||||
if($sEmail)
|
||||
mail_appdb($sEmail, $sSubject ,$sMsg);
|
||||
}
|
||||
|
||||
/* Output an editor for URL fields */
|
||||
function outputEditor($sFormAction, $oVersion, $oApp = NULL)
|
||||
{
|
||||
/* Check for correct permissions */
|
||||
if(($oVersion && !url::canEdit($oVersion->iVersionId)) ||
|
||||
($oApp && !url::canEdit(NULL, $oApp->iAppId)))
|
||||
return FALSE;
|
||||
|
||||
if($oVersion)
|
||||
$hResult = appData::getData($oVersion->iVersionId, "url");
|
||||
else
|
||||
$hResult = appData::getData($oApp->iAppId, "url", FALSE);
|
||||
|
||||
$sReturn .= html_frame_start("URLs", "90%", "", 0);
|
||||
$sReturn .= "<form method=\"post\" action=\"$sFormAction\">\n";
|
||||
$sReturn .= html_table_begin("border=0 cellpadding=5 cellspacing=0 width=100%");
|
||||
$sReturn .= html_tr(array(
|
||||
array("<b>Remove</b>", "width=\"90\""),
|
||||
"<b>Description</b>",
|
||||
"<b>URL</b>"
|
||||
),
|
||||
"color0");
|
||||
|
||||
$sReturn .= html_tr(array(
|
||||
" ",
|
||||
"<input type=\"text\" size=\"45\" name=\"".
|
||||
"sDescriptionNew\">",
|
||||
"<input type=\"text\" size=\"45\" name=\"sUrlNew\">"),
|
||||
"color4");
|
||||
|
||||
if($hResult)
|
||||
{
|
||||
for($i = 1; $oRow = query_fetch_object($hResult); $i++)
|
||||
{
|
||||
$sReturn .= html_tr(array(
|
||||
"<input type=\"checkbox\" name=\"bRemove$oRow->id\" ".
|
||||
"value=\"true\">",
|
||||
"<input type=\"text\" size=\"45\" name=\"".
|
||||
"sDescription$oRow->id\" value=\"$oRow->description\">",
|
||||
"<input type=\"text\" size=\"45\" name=\"sUrl$oRow->id\" ".
|
||||
"value=\"$oRow->url\">"),
|
||||
($i % 2) ? "color0" : "color4");
|
||||
}
|
||||
}
|
||||
|
||||
if($oVersion)
|
||||
$iAppId = $oVersion->iAppId;
|
||||
else
|
||||
$iAppId = $oApp->iAppId;
|
||||
|
||||
$sReturn .= html_table_end();
|
||||
$sReturn .= "<div align=\"center\"><input type=\"submit\" value=\"".
|
||||
"Update URLs\" name=\"sSubmit\"></div>\n";
|
||||
|
||||
if($oVersion)
|
||||
$sReturn .=" <input type=\"hidden\" name=\"iVersionId\" ".
|
||||
"value=\"$oVersion->iVersionId\">\n";
|
||||
|
||||
$sReturn .= "<input type=\"hidden\" name=\"iAppId\" ".
|
||||
"value=\"$iAppId\">\n";
|
||||
$sReturn .= "</form>\n";
|
||||
$sReturn .= html_frame_end(" ");
|
||||
|
||||
return $sReturn;
|
||||
}
|
||||
|
||||
/* Process data from a URL form */
|
||||
function ProcessForm($aValues)
|
||||
{
|
||||
|
||||
/* Check that we are processing a Download URL form */
|
||||
if($aValues["sSubmit"] != "Update URLs")
|
||||
return FALSE;
|
||||
|
||||
/* Check permissions */
|
||||
if(($aValues['iVersionId'] && !url::canEdit($aValues["iVersionId"])) ||
|
||||
(!$aValues['iVersionId'] && !url::canEdit(NULL, $aValues['iAppId'])))
|
||||
return FALSE;
|
||||
|
||||
if($aValues["iVersionId"])
|
||||
{
|
||||
if(!($hResult = query_parameters("SELECT COUNT(*) as num FROM appData
|
||||
WHERE TYPE = '?' AND versionId = '?'",
|
||||
"url", $aValues["iVersionId"])))
|
||||
return FALSE;
|
||||
} else
|
||||
{
|
||||
if(!($hResult = query_parameters("SELECT COUNT(*) as num FROM appData
|
||||
WHERE TYPE = '?' AND appId = '?'",
|
||||
"url", $aValues["iAppId"])))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(!($oRow = query_fetch_object($hResult)))
|
||||
return FALSE;
|
||||
|
||||
$num = $oRow->num;
|
||||
|
||||
/* Update URLs. Nothing to do if none are present in the database */
|
||||
if($num)
|
||||
{
|
||||
if($aValues['iVersionId'])
|
||||
{
|
||||
if(!$hResult = appData::getData($aValues["iVersionId"], "url"))
|
||||
return FALSE;
|
||||
} else
|
||||
{
|
||||
if(!$hResult = appData::getData($aValues['iAppId'], "url", FALSE))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while($oRow = query_fetch_object($hResult))
|
||||
{
|
||||
$url = new url($oRow->id);
|
||||
|
||||
/* Remove URL */
|
||||
if($aValues["bRemove$oRow->id"])
|
||||
{
|
||||
if(!$url->delete(TRUE))
|
||||
return FALSE;
|
||||
|
||||
$sWhatChangedRemove .= "Removed\nURL: $oRow->url\n".
|
||||
"Description: $oRow->description\n\n";
|
||||
}
|
||||
|
||||
/* Change description/URL */
|
||||
if(($aValues["sDescription$oRow->id"] != $oRow->description or
|
||||
$aValues["sUrl$oRow->id"] != $oRow->url) &&
|
||||
$aValues["sDescription$oRow->id"] && $aValues["sUrl$oRow->id"])
|
||||
{
|
||||
if(!$url->update($aValues["sDescription$oRow->id"],
|
||||
$aValues["sUrl$oRow->id"], $aValues["iVersionId"],
|
||||
$aValues["iVersionId"] ? 0 : $aValues["iAppId"], TRUE))
|
||||
return FALSE;
|
||||
|
||||
$sWhatChangedModify .= "Modified\nOld URL: $oRow->url\nOld ".
|
||||
"Description: $oRow->description\nNew URL: ".
|
||||
$aValues["sUrl$oRow->id"]."\nNew Description: ".
|
||||
$aValues["sDescription$oRow->id"]."\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert new URL */
|
||||
if($aValues["sDescriptionNew"] && $aValues["sUrlNew"])
|
||||
{
|
||||
$url = new Url();
|
||||
|
||||
if(!$url->create($aValues["sDescriptionNew"], $aValues["sUrlNew"],
|
||||
$aValues["iVersionId"] ? $aValues["iVersionId"] : "0",
|
||||
$aValues["iVersionId"] ? "0" : $aValues["iAppId"], TRUE))
|
||||
return FALSE;
|
||||
|
||||
$sWhatChanged = "Added\nURL: ".$aValues["sUrlNew"]."\nDescription: ".
|
||||
$aValues["sDescriptionNew"]."\n\n";
|
||||
}
|
||||
|
||||
$sWhatChanged .= "$sWhatChangedRemove$sWhatChangedModify";
|
||||
|
||||
if($aValues["iVersionId"])
|
||||
$sEmail = User::get_notify_email_address_list($aValues['iVersionId']);
|
||||
else
|
||||
$sEmail = User::get_notify_email_address_list($aValues['iAppId']);
|
||||
if($sWhatChanged && $sEmail)
|
||||
{
|
||||
$oApp = new Application($aValues["iAppId"]);
|
||||
|
||||
if($aValues["iVersionId"])
|
||||
{
|
||||
$oVersion = new Version($aValues["iVersionId"]);
|
||||
$sVersionName = " $oVersion->sName";
|
||||
}
|
||||
|
||||
$sSubject = "Links for $oApp->sName$sVersionName updated by ".
|
||||
$_SESSION['current']->sRealname;
|
||||
|
||||
$sMsg = $aValues["iVersionId"] ?
|
||||
$oVersion->objectMakeUrl() :
|
||||
$oApp->objectMakeUrl();
|
||||
$sMsg .= "\n\n";
|
||||
$sMsg .= "The following changed were made\n\n";
|
||||
$sMsg .= "$sWhatChanged\n\n";
|
||||
|
||||
mail_appdb($sEmail, $sSubject, $sMsg);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function canEdit($iVersionId = NULL, $iAppId = NULL)
|
||||
{
|
||||
if($_SESSION['current']->hasPriv("admin"))
|
||||
return TRUE;
|
||||
else if($iVersionId)
|
||||
{
|
||||
$oVersion = new version($iVersionId);
|
||||
return $oVersion->canEdit();
|
||||
} else if($iAppId)
|
||||
{
|
||||
$oApp = new application($iAppId);
|
||||
return $oApp->canEdit();
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Display links for a given version/application */
|
||||
function display($iVersionId, $iAppId = NULL)
|
||||
{
|
||||
if($iVersionId)
|
||||
{
|
||||
if(!($hResult = appData::getData($iVersionId, "url")))
|
||||
return FALSE;
|
||||
} else
|
||||
{
|
||||
if(!($hResult = appData::getData($iAppId, "url", FALSE)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$sReturn = '';
|
||||
for($i = 0; $oRow = query_fetch_object($hResult); $i++)
|
||||
{
|
||||
// create a url object
|
||||
$oUrl = new Url(null, $oRow);
|
||||
|
||||
$sReturn .= html_tr(array(
|
||||
"<b>Link</b>",
|
||||
"<a href=\"$oUrl->sUrl\">$oUrl->sDescription</a>"),
|
||||
"color1");
|
||||
}
|
||||
|
||||
return $sReturn;
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->iUrlId;
|
||||
}
|
||||
|
||||
function objectGetSubmitterId()
|
||||
{
|
||||
return $this->iSubmitterId;
|
||||
}
|
||||
|
||||
function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return new mailOptions();
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
/* We don't do this at the moment */
|
||||
return array(null, null, null);
|
||||
}
|
||||
|
||||
public function objectGetParent($sClass = '')
|
||||
{
|
||||
$oAppData = new appData($this->iUrlId, null, $this);
|
||||
return $oAppData->objectGetParent();
|
||||
}
|
||||
|
||||
public function objectSetParent($iNewId, $sClass = '')
|
||||
{
|
||||
if($this->iVersionId)
|
||||
$this->iVersionId = $iNewId;
|
||||
else
|
||||
$this->iAppId = $iNewId;
|
||||
}
|
||||
|
||||
function objectGetChildren($bIncludeDeleted = false)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
// if a url lacks "://" assume the url is an http one
|
||||
// and prepend "http://"
|
||||
function normalize($sTheUrl)
|
||||
{
|
||||
// return if we have an empty string
|
||||
if($sTheUrl == "")
|
||||
return $sTheUrl;
|
||||
|
||||
// if we already have "://" in the url
|
||||
// we can leave the url alone
|
||||
if(strpos($sTheUrl, "://") === false)
|
||||
{
|
||||
// assume this is a website and prepend "http://"
|
||||
return "http://".$sTheUrl;
|
||||
} else
|
||||
{
|
||||
// leave the url alone
|
||||
return $sTheUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
866
include/user.php
Normal file
866
include/user.php
Normal file
@@ -0,0 +1,866 @@
|
||||
<?php
|
||||
/************************************/
|
||||
/* user class and related functions */
|
||||
/************************************/
|
||||
|
||||
require_once(BASE."include/version.php");
|
||||
require_once(BASE."include/maintainer.php");
|
||||
require_once(BASE."include/util.php");
|
||||
|
||||
define("SUCCESS", 0);
|
||||
define("USER_CREATE_EXISTS", 1);
|
||||
define("USER_CREATE_FAILED", 2);
|
||||
define("USER_LOGIN_FAILED", 3);
|
||||
define("USER_UPDATE_FAILED", 4);
|
||||
define("USER_UPDATE_FAILED_EMAIL_EXISTS", 5); /* user updating to an email address that is already in use */
|
||||
define("USER_UPDATE_FAILED_NOT_LOGGED_IN", 6); /* user::update() called but user not logged in */
|
||||
|
||||
/**
|
||||
* User class for handling users
|
||||
*/
|
||||
class User {
|
||||
var $iUserId;
|
||||
var $sEmail;
|
||||
var $sRealname;
|
||||
var $sStamp;
|
||||
var $sDateCreated;
|
||||
var $sWineRelease;
|
||||
var $bInactivityWarned;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* If $iUserId is provided, logs in user.
|
||||
*/
|
||||
function User($iUserId="")
|
||||
{
|
||||
$this->sRealname = "an anonymous user";
|
||||
if(is_numeric($iUserId))
|
||||
{
|
||||
$sQuery = "SELECT *
|
||||
FROM user_list
|
||||
WHERE userId = '?'";
|
||||
$hResult = query_parameters($sQuery, $iUserId);
|
||||
$oRow = query_fetch_object($hResult);
|
||||
if($oRow)
|
||||
{
|
||||
$this->iUserId = $oRow->userid;
|
||||
$this->sEmail = $oRow->email;
|
||||
$this->sRealname = $oRow->realname;
|
||||
$this->sStamp = $oRow->stamp;
|
||||
$this->sDateCreated = $oRow->created;
|
||||
$this->sWineRelease = $oRow->CVSrelease;
|
||||
$this->bInactivityWarned = $oRow->inactivity_warned;
|
||||
}
|
||||
}
|
||||
return $this->isLoggedIn();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Logs in an user using e-mail and password.
|
||||
*/
|
||||
function login($sEmail, $sPassword)
|
||||
{
|
||||
$sQuery = "SELECT *
|
||||
FROM user_list
|
||||
WHERE email = '?' AND password = ";
|
||||
|
||||
$sMysqlSHAPasswordPart = "SHA1('?');";
|
||||
$sMysqlPasswordPart = "password('?');";
|
||||
$sMysql40xPasswordPart = "old_password('?');";
|
||||
|
||||
// if true we used an old style password and we need to
|
||||
// update the users password to the new style
|
||||
$bUsedOldStylePassword = false;
|
||||
|
||||
$oRow = null; // null out the row object
|
||||
|
||||
// if we aren't logged in yet
|
||||
// try to login with the mysql sha1() value of the password
|
||||
if(!$oRow)
|
||||
{
|
||||
$hResult = query_parameters($sQuery.$sMysqlSHAPasswordPart,
|
||||
$sEmail, $sPassword);
|
||||
$oRow = query_fetch_object($hResult);
|
||||
}
|
||||
|
||||
// if we aren't logged in yet
|
||||
// try to login with the mysql password() value of the password
|
||||
if(!$oRow)
|
||||
{
|
||||
$hResult = query_parameters($sQuery.$sMysqlPasswordPart,
|
||||
$sEmail, $sPassword);
|
||||
$oRow = query_fetch_object($hResult);
|
||||
if($oRow) $bUsedOldStylePassword = true;
|
||||
}
|
||||
|
||||
// if we aren't logged in yet
|
||||
// try to login with the mysql old_password() value of the password
|
||||
if(!$oRow)
|
||||
{
|
||||
// make sure we have a newer version, older versions may not
|
||||
$sResult = mysql_get_server_info();
|
||||
$fVersion = substr($sResult, 0, 3);
|
||||
|
||||
// if we have a newer version of mysql, try with the 'old_password()' function
|
||||
if($fVersion >= 4.1)
|
||||
{
|
||||
$hResult = query_parameters($sQuery.$sMysql40xPasswordPart,
|
||||
$sEmail, $sPassword);
|
||||
$oRow = query_fetch_object($hResult);
|
||||
if($oRow) $bUsedOldStylePassword = true;
|
||||
}
|
||||
}
|
||||
|
||||
if($oRow)
|
||||
{
|
||||
$this->iUserId = $oRow->userid;
|
||||
$this->sEmail = $oRow->email;
|
||||
$this->sRealname = $oRow->realname;
|
||||
$this->sStamp = $oRow->stamp;
|
||||
$this->sDateCreated = $oRow->created;
|
||||
$this->sWineRelease = $oRow->CVSrelease;
|
||||
|
||||
// if we used an old style password, update the users password
|
||||
if($bUsedOldStylePassword)
|
||||
{
|
||||
$this->update_password($sPassword);
|
||||
}
|
||||
}
|
||||
|
||||
if($this->isLoggedIn())
|
||||
{
|
||||
// Update timestamp and clear the inactivity flag if it was set
|
||||
query_parameters("UPDATE user_list SET stamp = ?, inactivity_warned = '?' WHERE userid='?'",
|
||||
"NOW()", "false", $this->iUserId);
|
||||
|
||||
/* set the session variable for the current user to this user object */
|
||||
$_SESSION['current'] = $this;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* destroy all session variables since we failed to login */
|
||||
$GLOBALS['session']->destroy();
|
||||
|
||||
return USER_LOGIN_FAILED;
|
||||
}
|
||||
|
||||
function logout()
|
||||
{
|
||||
/* destroy all session variables since we are logging out */
|
||||
$GLOBALS['session']->destroy();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Creates a new user.
|
||||
* returns SUCCESS on success, USER_CREATE_EXISTS if the user already exists
|
||||
*/
|
||||
function create($sEmail, $sPassword, $sRealname, $sWineRelease)
|
||||
{
|
||||
if(User::exists($sEmail))
|
||||
{
|
||||
return USER_CREATE_EXISTS;
|
||||
} else
|
||||
{
|
||||
$hResult = query_parameters("INSERT INTO user_list (realname, email, CVSrelease, password, stamp,".
|
||||
"created) VALUES ('?', '?', '?', SHA1('?'), ?, ?)",
|
||||
$sRealname, $sEmail, $sWineRelease, $sPassword, "NOW()", "NOW()");
|
||||
|
||||
if(!$hResult) return USER_CREATE_FAILED;
|
||||
|
||||
$retval = $this->login($sEmail, $sPassword);
|
||||
if($retval == SUCCESS)
|
||||
$this->setPref("comments:mode", "threaded"); /* set the users default comments:mode to threaded */
|
||||
$this->logout();
|
||||
|
||||
return $retval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update User Account;
|
||||
*/
|
||||
function update()
|
||||
{
|
||||
if(!$this->isLoggedIn()) return USER_UPDATE_FAILED_NOT_LOGGED_IN;
|
||||
|
||||
/* create an instance of ourselves so we can see what has changed */
|
||||
$oUser = new User($this->iUserId);
|
||||
|
||||
if($this->sEmail && ($this->sEmail != $oUser->sEmail))
|
||||
{
|
||||
/* make sure this email isn't already in use */
|
||||
if(User::exists($this->sEmail))
|
||||
{
|
||||
addMsg("An account with this e-mail exists already.","red");
|
||||
return USER_UPDATE_FAILED_EMAIL_EXISTS;
|
||||
}
|
||||
if (!query_parameters("UPDATE user_list SET email = '?' WHERE userid = '?'",
|
||||
$this->sEmail, $this->iUserId))
|
||||
return USER_UPDATE_FAILED;
|
||||
}
|
||||
|
||||
if ($this->sRealname && ($this->sRealname != $oUser->sRealname))
|
||||
{
|
||||
if (!query_parameters("UPDATE user_list SET realname = '?' WHERE userid = '?'",
|
||||
$this->sRealname, $this->iUserId))
|
||||
return USER_UPDATE_FAILED;
|
||||
}
|
||||
|
||||
if ($this->sWineRelease && ($this->sWineRelease != $oUser->sWineRelease))
|
||||
{
|
||||
if (!query_parameters("UPDATE user_list SET CVSrelease = '?' WHERE userid = '?'",
|
||||
$this->sWineRelease, $this->iUserId))
|
||||
return USER_UPDATE_FAILED;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: we can't update the users password like we can update other
|
||||
* fields such as their email or username because the password is hashed
|
||||
* in the database so we can't keep the users password in a class member variable
|
||||
* and use update() because we can't check if the password changed without hashing
|
||||
* the newly supplied one
|
||||
*/
|
||||
function update_password($sPassword)
|
||||
{
|
||||
if($sPassword)
|
||||
{
|
||||
if (query_parameters("UPDATE user_list SET password = SHA1('?') ".
|
||||
"WHERE userid = '?'",
|
||||
$sPassword, $this->iUserId))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes the current, or specified user and preferences from the database.
|
||||
* returns true on success and false on failure.
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
$hResult2 = query_parameters("DELETE FROM user_privs WHERE userid = '?'", $this->iUserId);
|
||||
$hResult3 = query_parameters("DELETE FROM user_prefs WHERE userid = '?'", $this->iUserId);
|
||||
$hResult4 = query_parameters("DELETE FROM appVotes WHERE userid = '?'", $this->iUserId);
|
||||
$hResult5 = Maintainer::deleteMaintainer($this);
|
||||
$hResult6 = query_parameters("DELETE FROM appComments WHERE userId = '?'", $this->iUserId);
|
||||
return($hResult = query_parameters("DELETE FROM user_list WHERE userid = '?'", $this->iUserId));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a preference for the current user.
|
||||
*/
|
||||
function getPref($sKey, $sDef = null)
|
||||
{
|
||||
if(!$this->isLoggedIn() || !$sKey)
|
||||
return $sDef;
|
||||
|
||||
$hResult = query_parameters("SELECT * FROM user_prefs WHERE userid = '?' AND name = '?'",
|
||||
$this->iUserId, $sKey);
|
||||
if(!$hResult || query_num_rows($hResult) == 0)
|
||||
return $sDef;
|
||||
$oRow = query_fetch_object($hResult);
|
||||
return $oRow->value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a preference for the current user.
|
||||
*/
|
||||
function setPref($sKey, $sValue)
|
||||
{
|
||||
if(!$this->isLoggedIn() || !$sKey || !$sValue)
|
||||
return false;
|
||||
|
||||
$hResult = query_parameters("DELETE FROM user_prefs WHERE userid = '?' AND name = '?'",
|
||||
$this->iUserId, $sKey);
|
||||
$hResult = query_parameters("INSERT INTO user_prefs (userid, name, value) VALUES".
|
||||
"('?', '?', '?')", $this->iUserId, $sKey, $sValue);
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if this user has $priv.
|
||||
*/
|
||||
function hasPriv($sPriv)
|
||||
{
|
||||
if(!$this->isLoggedIn() || !$sPriv)
|
||||
return false;
|
||||
|
||||
$hResult = query_parameters("SELECT * FROM user_privs WHERE userid = '?' AND priv = '?'",
|
||||
$this->iUserId, $sPriv);
|
||||
if(!$hResult)
|
||||
return false;
|
||||
return query_num_rows($hResult);
|
||||
}
|
||||
|
||||
|
||||
/* Check if this user is a maintainer of a given appId/versionId */
|
||||
function isMaintainer($iVersionId=null)
|
||||
{
|
||||
return Maintainer::isUserMaintainer($this, $iVersionId);
|
||||
}
|
||||
|
||||
/* Check if this user is a maintainer of a given appId/versionId */
|
||||
function isSuperMaintainer($iAppId=null)
|
||||
{
|
||||
return Maintainer::isUserSuperMaintainer($this, $iAppId);
|
||||
}
|
||||
|
||||
function addPriv($sPriv)
|
||||
{
|
||||
if(!$this->isLoggedIn() || !$sPriv)
|
||||
return false;
|
||||
|
||||
if($this->hasPriv($sPriv))
|
||||
return true;
|
||||
|
||||
$hResult = query_parameters("INSERT INTO user_privs (userid, priv) VALUES".
|
||||
" ('?', '?')", $this->iUserId, $sPriv);
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
|
||||
function delPriv($sPriv)
|
||||
{
|
||||
if(!$this->isLoggedIn() || !$sPriv)
|
||||
return false;
|
||||
|
||||
$hResult = query_parameters("DELETE FROM user_privs WHERE userid = '?' AND priv = '?'",
|
||||
$this->iUserId, $sPriv);
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the current user is valid.
|
||||
*/
|
||||
function isLoggedIn()
|
||||
{
|
||||
return $this->iUserId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if user should see debugging infos.
|
||||
*/
|
||||
function showDebuggingInfos()
|
||||
{
|
||||
return (($this->isLoggedIn() && $this->getPref("debug") == "yes") || APPDB_DEBUG == 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if user wants to get e-mails.
|
||||
*/
|
||||
function wantsEmail()
|
||||
{
|
||||
return ($this->isLoggedIn() && $this->getPref("send_email","yes")=="yes");
|
||||
}
|
||||
|
||||
function isAppSubmitter($iAppId)
|
||||
{
|
||||
$hResult = query_parameters("SELECT appId FROM appFamily
|
||||
WHERE submitterId = '?'
|
||||
AND appId = '?'",
|
||||
$this->iUserId, $iAppId);
|
||||
if(query_num_rows($hResult))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function isVersionSubmitter($iVersionId)
|
||||
{
|
||||
$hResult = query_parameters("SELECT appVersion.versionId FROM appVersion, appFamily
|
||||
WHERE appFamily.appId = appVersion.appId
|
||||
AND appVersion.submitterId = '?'
|
||||
AND appVersion.versionId = '?'",
|
||||
$this->iUserId, $iVersionId);
|
||||
if(query_num_rows($hResult))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/* if this user has data associated with them we will return true */
|
||||
/* otherwise we return false */
|
||||
function hasDataAssociated()
|
||||
{
|
||||
$hResult = query_parameters("SELECT count(userId) as c FROM appComments WHERE userId = '?'",
|
||||
$this->iUserId);
|
||||
$oRow = query_fetch_object($hResult);
|
||||
if($oRow->c != 0) return true;
|
||||
|
||||
if($this->isMaintainer() || $this->isSuperMaintainer())
|
||||
return true;
|
||||
|
||||
$hResult = query_parameters("SELECT count(userId) as c FROM appVotes WHERE userId = '?'",
|
||||
$this->iUserId);
|
||||
$oRow = query_fetch_object($hResult);
|
||||
if($oRow->c != 0) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* warn the user that their account has been marked as inactive */
|
||||
function warnForInactivity()
|
||||
{
|
||||
/* we don't want to warn users that have data associated with them */
|
||||
if($this->hasDataAssociated())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->isMaintainer())
|
||||
{
|
||||
$sSubject = "Warning: inactivity detected";
|
||||
$sMsg = "You didn't log in in the past six months to the AppDB.\r\n";
|
||||
$sMsg .= "As a maintainer we would be pleased to see you once in a while.\r\n";
|
||||
$sMsg .= "Please log in or you will lose your maintainer's abilities in one month.\r\n";
|
||||
} else
|
||||
{
|
||||
$sSubject = "Warning: inactivity detected";
|
||||
$sMsg = "You didn't log in in the past six months to the AppDB.\r\n";
|
||||
$sMsg .= "Please log in or your account will automatically be deleted in one month.\r\n";
|
||||
}
|
||||
$sMsg .= APPDB_ROOT."account.php?sCmd=login\r\n";
|
||||
|
||||
mail_appdb($this->sEmail, $sSubject, $sMsg);
|
||||
|
||||
/* mark this user as being inactive and set the appropriate timestamp */
|
||||
$sQuery = "update user_list set inactivity_warned='true', inactivity_warn_stamp=NOW() where userid='?'";
|
||||
query_parameters($sQuery, $this->iUserId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new random password.
|
||||
*/
|
||||
function generate_passwd($pass_len = 10)
|
||||
{
|
||||
$nps = "";
|
||||
mt_srand ((double) microtime() * 1000000);
|
||||
while (strlen($nps)<$pass_len)
|
||||
{
|
||||
$c = chr(mt_rand (0,255));
|
||||
if (eregi("^[a-z0-9]$", $c)) $nps = $nps.$c;
|
||||
}
|
||||
return ($nps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a user exists.
|
||||
* returns the userid if the user exists
|
||||
*/
|
||||
function exists($sEmail)
|
||||
{
|
||||
$hResult = query_parameters("SELECT userid FROM user_list WHERE email = '?'",
|
||||
$sEmail);
|
||||
if(!$hResult || query_num_rows($hResult) != 1)
|
||||
{
|
||||
return 0;
|
||||
} else
|
||||
{
|
||||
$oRow = query_fetch_object($hResult);
|
||||
return $oRow->userid;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of users in the database
|
||||
* The parameters are only included for compatibility; we don't queue users
|
||||
*/
|
||||
function objectGetEntriesCount($bQueued = null, $bRejected = null)
|
||||
{
|
||||
$hResult = query_parameters("SELECT count(*) as num_users FROM user_list;");
|
||||
$oRow = query_fetch_object($hResult);
|
||||
return $oRow->num_users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of active users within $days of the current day
|
||||
*/
|
||||
function active_users_within_days($days)
|
||||
{
|
||||
$hResult = query_parameters("SELECT count(*) as num_users FROM user_list WHERE stamp >= DATE_SUB(CURDATE(), interval '?' day);",
|
||||
$days);
|
||||
$oRow = query_fetch_object($hResult);
|
||||
return $oRow->num_users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the count of users who have been warned for inactivity and are
|
||||
* pending deletion after the X month grace period
|
||||
*/
|
||||
function get_inactive_users_pending_deletion()
|
||||
{
|
||||
/* retrieve the number of users that have been warned and are pending deletion */
|
||||
$hResult = query_parameters("select count(*) as count from user_list where inactivity_warned = 'true'");
|
||||
$oRow = query_fetch_object($hResult);
|
||||
return $oRow->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the email address of people to notify for this appId and versionId.
|
||||
*/
|
||||
function get_notify_email_address_list($iAppId = null, $iVersionId = null)
|
||||
{
|
||||
$aUserId = array();
|
||||
$sRetval = "";
|
||||
|
||||
/*
|
||||
* Retrieve version maintainers.
|
||||
*/
|
||||
$hResult = Maintainer::getMaintainersForAppIdVersionId($iAppId, $iVersionId);
|
||||
|
||||
if($hResult)
|
||||
{
|
||||
if(query_num_rows($hResult) > 0)
|
||||
{
|
||||
while($oRow = query_fetch_object($hResult))
|
||||
$aUserId[] = $oRow->userId;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve version Monitors.
|
||||
*/
|
||||
/*
|
||||
* If versionId was supplied we fetch superMonitors of application and Monitors of version.
|
||||
*/
|
||||
if($iVersionId)
|
||||
{
|
||||
$hResult = query_parameters("SELECT appMonitors.userId
|
||||
FROM appMonitors, appVersion
|
||||
WHERE appVersion.appId = appMonitors.appId
|
||||
AND appVersion.versionId = '?'",
|
||||
$iVersionId);
|
||||
}
|
||||
/*
|
||||
* If versionId was not supplied we fetch superMonitors of application and Monitors of all versions.
|
||||
*/
|
||||
elseif($iAppId)
|
||||
{
|
||||
$hResult = query_parameters("SELECT userId
|
||||
FROM appMonitors
|
||||
WHERE appId = '?'",
|
||||
$iAppId);
|
||||
}
|
||||
if($hResult)
|
||||
{
|
||||
if(query_num_rows($hResult) > 0)
|
||||
{
|
||||
while($oRow = query_fetch_object($hResult))
|
||||
$aUserId[] = $oRow->userId;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve administrators.
|
||||
*/
|
||||
$hResult = query_parameters("SELECT * FROM user_privs WHERE priv = 'admin'");
|
||||
if(query_num_rows($hResult) > 0)
|
||||
{
|
||||
while($oRow = query_fetch_object($hResult))
|
||||
{
|
||||
$i = array_search($oRow->userid, $aUserId);
|
||||
|
||||
// if we didn't find this entry in the $aUserId
|
||||
// array then we should add it
|
||||
if($i === false)
|
||||
$aUserId[] = $oRow->userid;
|
||||
}
|
||||
}
|
||||
|
||||
// go through the email entries and only add the emails for the users
|
||||
// that want to receive it
|
||||
if (sizeof($aUserId) > 0)
|
||||
{
|
||||
foreach($aUserId as $iUserId)
|
||||
{
|
||||
$oUser = new User($iUserId);
|
||||
if ($oUser->wantsEmail())
|
||||
$sRetval .= $oUser->sEmail." ";
|
||||
}
|
||||
}
|
||||
|
||||
return $sRetval;
|
||||
}
|
||||
|
||||
|
||||
/************************/
|
||||
/* Permission functions */
|
||||
/************************/
|
||||
|
||||
/**
|
||||
* Returns true or false depending on whether the user can view the image
|
||||
*/
|
||||
function canViewImage($iImageId)
|
||||
{
|
||||
$oScreenshot = new Screenshot($iImageId);
|
||||
|
||||
if(!$oScreenshot->bQueued ||
|
||||
($oScreenshot->bQueued && ($this->hasPriv("admin") ||
|
||||
$this->isMaintainer($oScreenshot->iVersionId) ||
|
||||
$this->isSuperMaintainer($oScreenshot->iAppId))))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/***************************/
|
||||
/* application permissions */
|
||||
function canViewApplication($oApp)
|
||||
{
|
||||
/* If there is no id the app is not in the database, which means the current user must have created the object */
|
||||
if(!$oApp->iAppId)
|
||||
return true;
|
||||
|
||||
/* if the application isn't queued */
|
||||
if($oApp->objectGetState() == 'accepted')
|
||||
return true;
|
||||
|
||||
if($this->hasPriv("admin"))
|
||||
return true;
|
||||
|
||||
/* if this user is the submitter and the application is queued */
|
||||
if(($this->iUserId == $oApp->iSubmitterId) &&
|
||||
($oApp->objectGetState() != 'accepted'))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the user have permission to modify this application?
|
||||
*/
|
||||
function canModifyApplication($oApp)
|
||||
{
|
||||
if($this->hasPriv("admin"))
|
||||
return true;
|
||||
|
||||
/* is this user a super maintainer of this app? */
|
||||
if($this->isSuperMaintainer($oApp->iAppId))
|
||||
return true;
|
||||
|
||||
/* if the user is the submitter of the application */
|
||||
/* and the application is still queued */
|
||||
/* the user can modify the app */
|
||||
if(($this->iUserId == $oApp->iSubmitterId) &&
|
||||
($oApp->objectGetState() != 'accepted'))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can this user create applications?
|
||||
*/
|
||||
function canCreateApplication()
|
||||
{
|
||||
return $this->isLoggedIn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 'true' if the current user has the permission to delete
|
||||
* this application, 'false' otherwise
|
||||
*/
|
||||
function canDeleteApplication($oApp)
|
||||
{
|
||||
if($this->hasPriv("admin"))
|
||||
return true;
|
||||
|
||||
/* is this the user that submitted the application and is still queued */
|
||||
if(($oApp->objectGetState() != 'accepted') && ($oApp->iSubmitterId == $this->iUserId))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Can this user unQueue applications? */
|
||||
function canUnQueueApplication()
|
||||
{
|
||||
return $this->hasPriv("admin");
|
||||
}
|
||||
|
||||
/* Can this user Requeue an application? */
|
||||
function canRequeueApplication($oApp)
|
||||
{
|
||||
if($oApp->objectGetState() == 'accepted')
|
||||
return false;
|
||||
|
||||
if($this->hasPriv("admin"))
|
||||
return true;
|
||||
|
||||
if(($oApp->objectGetState() != 'accepted') && ($oApp->iSubmitterId == $this->iUserId))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Can the user reject application? */
|
||||
function canRejectApplication()
|
||||
{
|
||||
return $this->hasPriv("admin");
|
||||
}
|
||||
|
||||
/***********************/
|
||||
/* version permissions */
|
||||
|
||||
function canViewVersion($oVersion)
|
||||
{
|
||||
/* If there is no id that means data must have been generated by the user */
|
||||
if(!$oVersion->iVersionId)
|
||||
return true;
|
||||
|
||||
/* if the version isn't queued */
|
||||
if($oVersion->objectGetState() == 'accepted')
|
||||
return true;
|
||||
|
||||
if($this->hasPriv("admin"))
|
||||
return true;
|
||||
|
||||
/* if the user is the submitter and the version is still queued */
|
||||
if(($this->iUserId == $oVersion->iSubmitterId) &&
|
||||
($oVersion->objectGetState() != 'accepted'))
|
||||
return true;
|
||||
|
||||
/* if this user supermaintains the application this version belongs to */
|
||||
if($this->isSupermaintainer($oVersion->iAppId))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the user have permission to modify on this version?
|
||||
*/
|
||||
function hasAppVersionModifyPermission($oVersion)
|
||||
{
|
||||
if(!$this->isLoggedIn())
|
||||
return false;
|
||||
|
||||
if($this->hasPriv("admin"))
|
||||
return true;
|
||||
|
||||
if($this->isSuperMaintainer($oVersion->iAppId))
|
||||
return true;
|
||||
|
||||
if($this->isMaintainer($oVersion->iVersionId))
|
||||
return true;
|
||||
|
||||
/* the version is queued and the user is the submitter */
|
||||
if(($oVersion->objectGetState() != 'accepted') && ($this->iUserId == $oVersion->iSubmitterId))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can this user create a version?
|
||||
*/
|
||||
function canCreateVersion()
|
||||
{
|
||||
return $this->isLoggedIn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 'true' if the current user has the permission to delete
|
||||
* this version, 'false' otherwise
|
||||
*/
|
||||
function canDeleteVersion($oVersion)
|
||||
{
|
||||
if($this->hasPriv("admin"))
|
||||
return true;
|
||||
|
||||
/* if the app is anything other than not queued and if the user is the submitter */
|
||||
/* then allow the user to delete the app */
|
||||
if(($oVersion->objectGetState() != 'accepted') && ($oVersion->iSubmitterId == $this->iUserId))
|
||||
return true;
|
||||
|
||||
/* is this user a supermaintainer of the application this version is under? */
|
||||
if($this->isSuperMaintainer($oVersion->iAppId))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the user unqueue this version?
|
||||
*/
|
||||
function canUnQueueVersion($oVersion)
|
||||
{
|
||||
if($this->hasPriv("admin"))
|
||||
return true;
|
||||
|
||||
if($this->hasAppVersionModifyPermission($oVersion))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the user reject this version?
|
||||
*/
|
||||
function canRejectVersion($oVersion)
|
||||
{
|
||||
if($this->hasPriv("admin"))
|
||||
return true;
|
||||
|
||||
if($this->hasAppVersionModifyPermission($oVersion))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the user reject this version?
|
||||
*/
|
||||
function canRequeueVersion($oVersion)
|
||||
{
|
||||
if($this->hasPriv("admin"))
|
||||
return true;
|
||||
|
||||
if($this->hasAppVersionModifyPermission($oVersion))
|
||||
return true;
|
||||
|
||||
if(($this->iUserId == $oVersion->iSubmitterId) &&
|
||||
($oVersion->objectGetState() != 'accepted'))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function objectMakeUrl()
|
||||
{
|
||||
if(!$this->iUserId)
|
||||
return;
|
||||
|
||||
$sUrl = BASE."contact.php?iRecipientId=$this->iUserId";
|
||||
return $sUrl;
|
||||
}
|
||||
|
||||
function objectMakeLink()
|
||||
{
|
||||
if(!$this->iUserId)
|
||||
return $this->sRealname;
|
||||
|
||||
$sLink = "<a href=\"".$this->objectMakeUrl()."\">$this->sRealname</a>";
|
||||
return $sLink;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
1073
include/util.php
Normal file
1073
include/util.php
Normal file
File diff suppressed because it is too large
Load Diff
485
include/vendor.php
Normal file
485
include/vendor.php
Normal file
@@ -0,0 +1,485 @@
|
||||
<?php
|
||||
/**********************************/
|
||||
/* this class represents a vendor */
|
||||
/**********************************/
|
||||
|
||||
/**
|
||||
* Vendor class for handling developers.
|
||||
*/
|
||||
class Vendor {
|
||||
var $iVendorId;
|
||||
var $sName;
|
||||
var $sWebpage;
|
||||
private $sState;
|
||||
var $aApplicationsIds; // an array that contains the appId of every application linked to this vendor
|
||||
|
||||
/**
|
||||
* constructor, fetches the data.
|
||||
*/
|
||||
function Vendor($iVendorId = null, $oRow = null)
|
||||
{
|
||||
// we are working on an existing vendor
|
||||
if(!$iVendorId && !$oRow)
|
||||
return;
|
||||
|
||||
if(!$oRow)
|
||||
{
|
||||
/*
|
||||
* We fetch the data related to this vendor.
|
||||
*/
|
||||
$sQuery = "SELECT *
|
||||
FROM vendor
|
||||
WHERE vendorId = '?'";
|
||||
if($hResult = query_parameters($sQuery, $iVendorId))
|
||||
$oRow = query_fetch_object($hResult);
|
||||
}
|
||||
|
||||
if($oRow)
|
||||
{
|
||||
$this->iVendorId = $oRow->vendorId;
|
||||
$this->sName = $oRow->vendorName;
|
||||
$this->sWebpage = $oRow->vendorURL;
|
||||
$this->sState = $oRow->state;
|
||||
}
|
||||
|
||||
/*
|
||||
* We fetch applicationsIds.
|
||||
*/
|
||||
$sQuery = "SELECT appId
|
||||
FROM appFamily
|
||||
WHERE vendorId = '?' ORDER by appName";
|
||||
if($hResult = query_parameters($sQuery, $this->iVendorId))
|
||||
{
|
||||
while($oRow = query_fetch_object($hResult))
|
||||
{
|
||||
$this->aApplicationsIds[] = $oRow->appId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new vendor.
|
||||
*
|
||||
* NOTE: If creating a vendor with the same name as an existing vendor
|
||||
* we retrieve the existing vendors information and return true,
|
||||
* even though we didn't create the vendor, this makes it easier
|
||||
* for the user of the vendor class.
|
||||
*/
|
||||
function create()
|
||||
{
|
||||
/* Check for duplicates */
|
||||
$hResult = query_parameters("SELECT * FROM vendor WHERE vendorName = '?'",
|
||||
$this->sName);
|
||||
if($hResult && $oRow = query_fetch_object($hResult))
|
||||
{
|
||||
if(query_num_rows($hResult))
|
||||
{
|
||||
$this->vendor($oRow->vendorId);
|
||||
|
||||
/* Even though we did not create a new vendor, the caller is provided
|
||||
with an id and can proceed as normal, so we return TRUE */
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
$hResult = query_parameters("INSERT INTO vendor (vendorName, vendorURL, state) ".
|
||||
"VALUES ('?', '?', '?')",
|
||||
$this->sName, $this->sWebpage,
|
||||
$this->mustBeQueued() ? 'queued' : 'accepted');
|
||||
if($hResult)
|
||||
{
|
||||
$this->iVendorId = query_appdb_insert_id();
|
||||
$this->vendor($this->iVendorId);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
addmsg("Error while creating a new developer.", "red");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-queue vendor
|
||||
* Returns TRUE or FALSE
|
||||
*/
|
||||
function unQueue()
|
||||
{
|
||||
$hResult = query_parameters("UPDATE vendor SET state = '?' WHERE vendorId = '?'",
|
||||
'accepted', $this->iVendorId);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
$this->sState = 'accepted';
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update vendor.
|
||||
* Returns true on success and false on failure.
|
||||
*/
|
||||
function update()
|
||||
{
|
||||
if(!$this->iVendorId)
|
||||
return $this->create();
|
||||
|
||||
if($this->sName)
|
||||
{
|
||||
if (!query_parameters("UPDATE vendor SET vendorName = '?' WHERE vendorId = '?'",
|
||||
$this->sName, $this->iVendorId))
|
||||
return false;
|
||||
$this->sName = $sName;
|
||||
}
|
||||
|
||||
if($this->sWebpage)
|
||||
{
|
||||
if (!query_parameters("UPDATE vendor SET vendorURL = '?' WHERE vendorId = '?'",
|
||||
$this->sWebpage, $this->iVendorId))
|
||||
return false;
|
||||
$this->sWebpage = $sWebpage;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the vendor from the database.
|
||||
*/
|
||||
function purge()
|
||||
{
|
||||
if(sizeof($this->aApplicationsIds)>0)
|
||||
{
|
||||
return FALSE;
|
||||
} else
|
||||
{
|
||||
$sQuery = "DELETE FROM vendor
|
||||
WHERE vendorId = '?'
|
||||
LIMIT 1";
|
||||
if(query_parameters($sQuery, $this->iVendorId))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag the vendor as deleted
|
||||
*/
|
||||
function delete()
|
||||
{
|
||||
if(sizeof($this->aApplicationsIds)>0)
|
||||
{
|
||||
return FALSE;
|
||||
} else
|
||||
{
|
||||
$sQuery = "UPDATE vendor SET state = 'deleted'
|
||||
WHERE vendorId = '?'
|
||||
LIMIT 1";
|
||||
if(query_parameters($sQuery, $this->iVendorId))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkOutputEditorInput($aClean)
|
||||
{
|
||||
if(!getInput('sVendorName', $aClean))
|
||||
return '<li>You need to enter the developer\'s name</li>';
|
||||
}
|
||||
|
||||
function outputEditor()
|
||||
{
|
||||
$oTable = new Table();
|
||||
$oTable->SetWidth("100%");
|
||||
$oTable->SetBorder(0);
|
||||
$oTable->SetCellPadding(2);
|
||||
$oTable->SetCellSpacing(0);
|
||||
|
||||
// name
|
||||
$oTableRow = new TableRow();
|
||||
|
||||
$oTableCell = new TableCell("Developer name:");
|
||||
$oTableCell->SetAlign("right");
|
||||
$oTableCell->SetClass("color0");
|
||||
$oTableCell->SetBold(true);
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
$oTableCell = new TableCell('<input type=text name="sVendorName" value="'.$this->sName.'" size="60">');
|
||||
$oTableCell->SetClass("color0");
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
$oTable->AddRow($oTableRow);
|
||||
|
||||
// Url
|
||||
$oTableRow = new TableRow();
|
||||
|
||||
$oTableCell = new TableCell("Developer URL:");
|
||||
$oTableCell->SetAlign("right");
|
||||
$oTableCell->SetClass("color0");
|
||||
$oTableCell->SetBold(true);
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
$oTableCell = new TableCell('<input type=text name="sVendorWebpage" value="'.$this->sWebpage.'" size="60">');
|
||||
$oTableCell->SetClass("color0");
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
$oTable->AddRow($oTableRow);
|
||||
|
||||
echo $oTable->GetString();
|
||||
|
||||
echo '<input type="hidden" name="iVendorId" value="'.$this->iVendorId.'">',"\n";
|
||||
}
|
||||
|
||||
public static function objectGetSortableFields()
|
||||
{
|
||||
return array('vendorName');
|
||||
}
|
||||
|
||||
public static function objectGetDefaultSort()
|
||||
{
|
||||
return 'vendorName';
|
||||
}
|
||||
|
||||
function objectGetFilterInfo()
|
||||
{
|
||||
$oFilter = new FilterInterface();
|
||||
|
||||
$oFilter->AddFilterInfo('vendorName', 'Name', array(FILTER_CONTAINS, FILTER_STARTS_WITH, FILTER_ENDS_WITH), FILTER_VALUES_NORMAL);
|
||||
return $oFilter;
|
||||
}
|
||||
|
||||
function objectGetEntries($sState, $iRows = 0, $iStart = 0, $sOrderBy = 'vendorName', $bAscending = TRUE, $oFilter = null)
|
||||
{
|
||||
/* Not implemented */
|
||||
if($sState == 'rejected')
|
||||
return FALSE;
|
||||
|
||||
$sWhereFilter = $oFilter ? $oFilter->getWhereClause() : '';
|
||||
$sOrder = $bAscending ? 'ASC' : 'DESC';
|
||||
|
||||
if($sWhereFilter)
|
||||
$sWhereFilter = " AND $sWhereFilter";
|
||||
|
||||
if(!$iRows)
|
||||
$iRows = Vendor::objectGetEntriesCount($sState, $oFilter);
|
||||
|
||||
$hResult = query_parameters("SELECT * FROM vendor WHERE state = '?' $sWhereFilter
|
||||
ORDER BY $sOrderBy $sOrder LIMIT ?,?",
|
||||
$sState, $iStart, $iRows);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
return $hResult;
|
||||
}
|
||||
|
||||
function objectGetHeader()
|
||||
{
|
||||
$oTableRow = new TableRowSortable();
|
||||
|
||||
$oTableRow->AddSortableTextCell('Name', 'vendorName');
|
||||
|
||||
$oTableCell = new TableCell('Applications');
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
$oTableRow->AddTextCell("Website");
|
||||
|
||||
return $oTableRow;
|
||||
}
|
||||
|
||||
// returns an OMTableRow instance
|
||||
function objectGetTableRow()
|
||||
{
|
||||
$bDeleteLink = sizeof($this->aApplicationsIds) ? FALSE : TRUE;
|
||||
|
||||
// create the html table row
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->AddTextCell($this->objectMakeLink());
|
||||
|
||||
$oTableCell = new TableCell(sizeof($this->aApplicationsIds));
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
$oTableCell = new TableCell($this->sWebpage);
|
||||
$oTableCell->SetCellLink($this->sWebpage);
|
||||
$oTableRow->AddCell($oTableCell);
|
||||
|
||||
// create the object manager specific row
|
||||
$oOMTableRow = new OMTableRow($oTableRow);
|
||||
$oOMTableRow->SetHasDeleteLink($bDeleteLink);
|
||||
|
||||
return $oOMTableRow;
|
||||
}
|
||||
|
||||
public function objectGetState()
|
||||
{
|
||||
return $this->sState;
|
||||
}
|
||||
|
||||
function canEdit()
|
||||
{
|
||||
if($_SESSION['current']->hasPriv("admin"))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function mustBeQueued()
|
||||
{
|
||||
if($_SESSION['current']->hasPriv("admin"))
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return new mailOptions();
|
||||
}
|
||||
|
||||
function objectGetChildren($bIncludeDeleted = false)
|
||||
{
|
||||
/* We don't have any */
|
||||
return array();
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
/* We don't send notification mails */
|
||||
return array(null, null, null);
|
||||
}
|
||||
|
||||
function objectGetSubmitterId()
|
||||
{
|
||||
/* We don't record the submitter id */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
function getOutputEditorValues($aClean)
|
||||
{
|
||||
$this->sName = $aClean['sVendorName'];
|
||||
$this->sWebpage = $aClean['sVendorWebpage'];
|
||||
}
|
||||
|
||||
function display()
|
||||
{
|
||||
echo 'Developer name: '.$this->sName,"\n";
|
||||
if($this->canEdit())
|
||||
{
|
||||
echo "[<a href=\"".$_SERVER['PHP_SELF']."?sClass=vendor&sAction=edit&".
|
||||
"iId=$this->iVendorId&sTitle=Edit%20Developer\">edit</a>]";
|
||||
}
|
||||
|
||||
echo '<br>',"\n";
|
||||
if ($this->sWebpage)
|
||||
{
|
||||
echo 'Developer URL: <a href="'.$this->sWebpage.'">'.
|
||||
$this->sWebpage.'</a> <br>',"\n";
|
||||
}
|
||||
|
||||
|
||||
if($this->aApplicationsIds)
|
||||
{
|
||||
echo '<br>Applications by '.$this->sName.'<br><ol>',"\n";
|
||||
foreach($this->aApplicationsIds as $iAppId)
|
||||
{
|
||||
$oApp = new Application($iAppId);
|
||||
|
||||
if($oApp->objectGetState() == 'accepted')
|
||||
echo '<li>'.$oApp->objectMakeLink().'</li>',"\n";
|
||||
}
|
||||
echo '</ol>',"\n";
|
||||
}
|
||||
}
|
||||
|
||||
public function objectGetClassDisplayName()
|
||||
{
|
||||
return 'developer';
|
||||
}
|
||||
|
||||
/* Make a URL for viewing the specified vendor */
|
||||
function objectMakeUrl()
|
||||
{
|
||||
$oManager = new objectManager("vendor", "View Developer");
|
||||
return $oManager->makeUrl("view", $this->iVendorId);
|
||||
}
|
||||
|
||||
/* Make a HTML link for viewing the specified vendor */
|
||||
function objectMakeLink()
|
||||
{
|
||||
return "<a href=\"".$this->objectMakeUrl()."\">$this->sName</a>";
|
||||
}
|
||||
|
||||
function objectGetEntriesCount($sState, $oFilter = null)
|
||||
{
|
||||
/* Not implemented */
|
||||
if($sState == 'rejected')
|
||||
return FALSE;
|
||||
|
||||
$sWhereClause = $oFilter ? $oFilter->getWhereClause() : '';
|
||||
if($sWhereClause)
|
||||
$sWhereClause = " AND $sWhereClause";
|
||||
|
||||
$hResult = query_parameters("SELECT COUNT(vendorId) as count FROM vendor WHERE state = '?' $sWhereClause",
|
||||
$sState);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
if(!$oRow = query_fetch_object($hResult))
|
||||
return FALSE;
|
||||
|
||||
return $oRow->count;
|
||||
}
|
||||
|
||||
function allowAnonymousSubmissions()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function objectMoveChildren($iNewId)
|
||||
{
|
||||
/* Keep track of how many children we have modified */
|
||||
$iCount = 0;
|
||||
|
||||
foreach($this->aApplicationsIds as $iAppId)
|
||||
{
|
||||
$oApp = new application($iAppId);
|
||||
$oApp->iVendorId = $iNewId;
|
||||
if($oApp->update(TRUE))
|
||||
$iCount++;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return $iCount;
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->iVendorId;
|
||||
}
|
||||
|
||||
function objectGetItemsPerPage($sState = 'accepted')
|
||||
{
|
||||
$aItemsPerPage = array(25, 50, 100, 200);
|
||||
$iDefaultPerPage = 25;
|
||||
return array($aItemsPerPage, $iDefaultPerPage);
|
||||
}
|
||||
|
||||
function objectShowAddEntry()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
1903
include/version.php
Normal file
1903
include/version.php
Normal file
File diff suppressed because it is too large
Load Diff
369
include/version_queue.php
Normal file
369
include/version_queue.php
Normal file
@@ -0,0 +1,369 @@
|
||||
<?php
|
||||
|
||||
class version_queue
|
||||
{
|
||||
var $oTestDataQueue;
|
||||
var $oVersion;
|
||||
var $oDownloadUrl;
|
||||
|
||||
function version_queue($iVersionId = null, $oRow = null)
|
||||
{
|
||||
$this->oVersion = new version($iVersionId, $oRow);
|
||||
$iTestingId = null;
|
||||
$iDownloadUrlId = null;
|
||||
|
||||
if(!$iVersionId)
|
||||
$iVersionId = $this->oVersion->iVersionId;
|
||||
|
||||
if($iVersionId)
|
||||
{
|
||||
$iTestingId = testData::getNewestTestIdFromVersionId($iVersionId, "pending");
|
||||
/* This illustrates the importance of converting downloadurl completely
|
||||
to the objectManager model. If we don't get a match searching for
|
||||
a queued entry, try finding a rejected one. */
|
||||
if(($hResult = appData::getData($iVersionId, "downloadurl",
|
||||
TRUE, TRUE, FALSE)) ||
|
||||
$hResult = appData::getData($iVersionId, "downloadurl",
|
||||
TRUE, TRUE, TRUE))
|
||||
{
|
||||
if($oRow = query_fetch_object($hResult))
|
||||
$iDownloadUrlId = $oRow->id;
|
||||
}
|
||||
}
|
||||
|
||||
$this->oTestDataQueue = new testData_queue($iTestingId);
|
||||
$this->oDownloadUrl = new downloadurl($iDownloadUrlId);
|
||||
|
||||
if(!$this->oDownloadUrl->objectGetId() && $iVersionId)
|
||||
$this->oDownloadUrl->objectSetParent($iVersionId);
|
||||
}
|
||||
|
||||
function create()
|
||||
{
|
||||
global $aClean;
|
||||
if(!$this->oVersion->create())
|
||||
return FALSE;
|
||||
|
||||
$this->oTestDataQueue->oTestData->iVersionId = $this->oVersion->iVersionId;
|
||||
$this->oTestDataQueue->create();
|
||||
$this->oDownloadUrl->objectSetParent($this->oVersion->objectGetId());
|
||||
$this->oDownloadUrl->create();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function reQueue()
|
||||
{
|
||||
$this->oDownloadUrl->reQueue();
|
||||
}
|
||||
|
||||
function reject()
|
||||
{
|
||||
$oApp = new application($this->oVersion->iAppId);
|
||||
|
||||
if($oApp->objectGetState() == 'accepted')
|
||||
$this->oVersion->reject();
|
||||
|
||||
if($this->oDownloadUrl->iId)
|
||||
$this->oDownloadUrl->reject();
|
||||
}
|
||||
|
||||
function update()
|
||||
{
|
||||
$this->oVersion->update();
|
||||
|
||||
/* A downloadurl is optional and can thus be added later */
|
||||
if($this->oDownloadUrl->objectGetId())
|
||||
$this->oDownloadUrl->update();
|
||||
else
|
||||
$this->oDownloadUrl->create();
|
||||
|
||||
$this->oTestDataQueue->update();
|
||||
}
|
||||
|
||||
function purge()
|
||||
{
|
||||
$bSuccess = TRUE;
|
||||
|
||||
if(!$this->oVersion->purge())
|
||||
$bSuccess = FALSE;
|
||||
|
||||
if(!$this->oTestDataQueue->purge())
|
||||
$bSuccess = FALSE;
|
||||
|
||||
if($this->oDownloadUrl->iId && !$this->oDownloadUrl->purge())
|
||||
$bSuccess = FALSE;
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
|
||||
function delete()
|
||||
{
|
||||
$bSuccess = TRUE;
|
||||
|
||||
if(!$this->oVersion->delete())
|
||||
$bSuccess = FALSE;
|
||||
|
||||
if(!$this->oTestDataQueue->delete())
|
||||
$bSuccess = FALSE;
|
||||
|
||||
if($this->oDownloadUrl->iId && !$this->oDownloadUrl->delete())
|
||||
$bSuccess = FALSE;
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
|
||||
function unQueue()
|
||||
{
|
||||
$this->oVersion->unQueue();
|
||||
$this->oTestDataQueue->unQueue();
|
||||
$this->oDownloadUrl->unQueue();
|
||||
}
|
||||
|
||||
function objectGetSubmitterId()
|
||||
{
|
||||
return $this->oVersion->objectGetSubmitterId();
|
||||
}
|
||||
|
||||
function objectGetChildren($bIncludeDeleted = false)
|
||||
{
|
||||
return $this->oVersion->objectGetChildren($bIncludeDeleted);
|
||||
}
|
||||
|
||||
function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return $this->oVersion->objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction);
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return $this->oVersion->objectGetMail($sAction, $bMailSubmitter, $bParentAction);
|
||||
}
|
||||
|
||||
function outputEditor()
|
||||
{
|
||||
global $aClean;
|
||||
|
||||
echo "<div class='default_container'>\n";
|
||||
|
||||
/* Display duplicate list if this is a an existing version */
|
||||
if($this->oVersion->iVersionId)
|
||||
$this->displayMoveTestTable();
|
||||
|
||||
$this->oVersion->outputEditor();
|
||||
|
||||
/* Allow the user to apply as maintainer if this is a new version.
|
||||
If it is a new application as well, radio boxes will be displayed
|
||||
by the application class instead. */
|
||||
if(!$this->oVersion->iVersionId && $this->oVersion->iAppId &&
|
||||
!$_SESSION['current']->isSuperMaintainer($this->oVersion->iAppId))
|
||||
{
|
||||
echo html_frame_start("Become a Maintainer or Monitor Changes", "90%");
|
||||
echo "<div style='padding:5px;' class='color0'>\n";
|
||||
$oTable = new Table();
|
||||
if($this->oVersion->iMaintainerRequest == MAINTAINER_REQUEST)
|
||||
$sRequestMaintainerChecked = 'checked="checked" ';
|
||||
else
|
||||
$sRequestMaintainerChecked = '';
|
||||
if($this->oVersion->iMaintainerRequest == MONITOR_REQUEST)
|
||||
$sRequestMonitorChecked = 'checked="checked"' ;
|
||||
else
|
||||
$sRequestMonitorChecked = '';
|
||||
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->AddTextCell(' ');
|
||||
$oTableRow->AddTextCell("<input type=\"radio\" $sRequestMaintainerChecked".
|
||||
"name=\"iMaintainerRequest\" value=\"".MAINTAINER_REQUEST."\"> ".
|
||||
"Request being a maintainer for this version, allowing you to edit it later");
|
||||
$oTable->AddRow($oTableRow);
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->AddTextCell(' ');
|
||||
$oTableRow->AddTextCell("<input type=\"radio\" $sRequestMonitorChecked".
|
||||
"name=\"iMaintainerRequest\" value=\"".MONITOR_REQUEST."\"> ".
|
||||
"Monitor changes to this version, also after it has been accepted");
|
||||
$oTable->AddRow($oTableRow);
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->AddTextCell(' ');
|
||||
$oTableRow->AddTextCell('<input type="radio" name="iMaintainerRequest" value="0"> '.
|
||||
'None of the above');
|
||||
$oTable->AddRow($oTableRow);
|
||||
|
||||
echo $oTable->GetString();
|
||||
echo "</div\n";
|
||||
echo html_frame_end();
|
||||
}
|
||||
|
||||
echo $this->oDownloadUrl->outputEditorSingle($this->oVersion->iVersionId,
|
||||
$aClean);
|
||||
$this->oTestDataQueue->outputEditor();
|
||||
|
||||
echo "</div>\n";
|
||||
}
|
||||
|
||||
function getOutputEditorValues($aClean)
|
||||
{
|
||||
$this->oVersion->iAppId = $aClean['iAppId'];
|
||||
$this->oVersion->getOutputEditorValues($aClean);
|
||||
$this->oDownloadUrl->getOutputEditorValues($aClean);
|
||||
$this->oTestDataQueue->getOutputEditorValues($aClean);
|
||||
}
|
||||
|
||||
function checkOutputEditorInput($aClean)
|
||||
{
|
||||
$sErrors = $this->oVersion->checkOutputEditorInput($aClean);
|
||||
$sErrors .= $this->oTestDataQueue->checkOutputEditorInput($aClean);
|
||||
return $sErrors;
|
||||
}
|
||||
|
||||
function objectGetState()
|
||||
{
|
||||
return $this->oVersion->objectGetState();
|
||||
}
|
||||
|
||||
function canEdit()
|
||||
{
|
||||
return $this->oVersion->canEdit();
|
||||
}
|
||||
|
||||
function mustBeQueued()
|
||||
{
|
||||
return $this->oVersion->mustBeQueued();
|
||||
}
|
||||
|
||||
function objectDisplayAddItemHelp()
|
||||
{
|
||||
/* $this->oVersion->displayAddItemHelp(); */
|
||||
}
|
||||
|
||||
function objectGetItemsPerPage($sState = 'accepted')
|
||||
{
|
||||
return $this->oVersion->objectGetItemsPerPage($sState);
|
||||
}
|
||||
|
||||
function objectGetEntriesCount($sState)
|
||||
{
|
||||
return $this->oVersion->objectGetEntriesCount($sState);
|
||||
}
|
||||
|
||||
public static function objectGetDefaultSort()
|
||||
{
|
||||
return version::objectGetDefaultSort();
|
||||
}
|
||||
|
||||
function objectGetEntries($sState, $iRows = 0, $iStart = 0, $sOrderBy = "versionId", $bAscending = true)
|
||||
{
|
||||
return $this->oVersion->objectGetEntries($sState, $iRows, $iStart,
|
||||
$sOrderBy, $bAscending);
|
||||
}
|
||||
|
||||
function objectGetHeader()
|
||||
{
|
||||
return $this->oVersion->objectGetHeader();
|
||||
}
|
||||
|
||||
function objectGetTableRow()
|
||||
{
|
||||
return $this->oVersion->objectGetTableRow();
|
||||
}
|
||||
|
||||
public function objectShowPreview()
|
||||
{
|
||||
return $this->oVersion->objectShowPreview();
|
||||
}
|
||||
|
||||
function display()
|
||||
{
|
||||
/* Cache the test result object as it's not in the DB */
|
||||
$this->oVersion->aTestResults[] = $this->oTestDataQueue->oTestData;
|
||||
$this->oVersion->display();
|
||||
}
|
||||
|
||||
function objectMakeUrl()
|
||||
{
|
||||
return $this->oVersion->objectMakeUrl();
|
||||
}
|
||||
|
||||
function objectMakeLink()
|
||||
{
|
||||
return $this->oVersion->objectMakeLink();
|
||||
}
|
||||
|
||||
function displayMoveTestTable()
|
||||
{
|
||||
$oApp = new application($this->oVersion->iAppId);
|
||||
|
||||
echo html_frame_start("Move test to version","90%","",0);
|
||||
echo "<table width=\"100%\" border=\"0\" cellpadding=\"3\" ".
|
||||
"cellspacing=\"1\">\n\n";
|
||||
|
||||
echo html_tr(array(
|
||||
array("Version", 'width="80"'),
|
||||
"Description",
|
||||
array("Rating", 'width="80"'),
|
||||
array("Wine version", 'width="80"'),
|
||||
array("Comments", 'width="40"'),
|
||||
array("Move test results", 'width="80"')
|
||||
),
|
||||
"color4");
|
||||
|
||||
$i = 0;
|
||||
foreach($oApp->aVersionsIds as $iVersionId)
|
||||
{
|
||||
$oVersion = new Version($iVersionId);
|
||||
if ($oVersion->objectGetState() == 'accepted')
|
||||
{
|
||||
//display row
|
||||
echo html_tr(array(
|
||||
$oVersion->objectMakeLink(),
|
||||
util_trim_description($oVersion->sDescription),
|
||||
array($oVersion->sTestedRating, 'align="center"'),
|
||||
array($oVersion->sTestedRelease, 'align="center"'),
|
||||
array(Comment::get_comment_count_for_versionid(
|
||||
$oVersion->iVersionId), 'align="center"'),
|
||||
html_ahref("Move here",
|
||||
"objectManager.php?sClass=version_queue&bIsQueue=true&".
|
||||
"sAction=moveChildren&iId=".
|
||||
$this->oVersion->iVersionId."&iNewId=".
|
||||
$oVersion->iVersionId."&sTitle=Version+Queue"),
|
||||
),
|
||||
($i % 2) ? "color0" : "color1");
|
||||
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
echo "</table>\n";
|
||||
echo html_frame_end(" ");
|
||||
}
|
||||
|
||||
function objectDisplayQueueProcessingHelp()
|
||||
{
|
||||
version::objectDisplayQueueProcessingHelp();
|
||||
}
|
||||
|
||||
function objectMoveChildren($iNewId)
|
||||
{
|
||||
return $this->oVersion->objectMoveChildren($iNewId);
|
||||
}
|
||||
|
||||
function allowAnonymousSubmissions()
|
||||
{
|
||||
return version::allowAnonymousSubmissions();
|
||||
}
|
||||
|
||||
function objectAllowPurgingRejected()
|
||||
{
|
||||
return $this->oVersion->objectAllowPurgingRejected();
|
||||
}
|
||||
|
||||
public function objectGetSubmitTime()
|
||||
{
|
||||
return $this->oVersion->objectGetSubmitTime();
|
||||
}
|
||||
|
||||
function objectGetId()
|
||||
{
|
||||
return $this->oVersion->objectGetId();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
505
include/vote.php
Normal file
505
include/vote.php
Normal file
@@ -0,0 +1,505 @@
|
||||
<?php
|
||||
require_once(BASE."include/util.php");
|
||||
/* max votes per user */
|
||||
define('MAX_VOTES',3);
|
||||
|
||||
class vote
|
||||
{
|
||||
public $iUserId;
|
||||
public $iVoteId;
|
||||
public $iSlotIndex;
|
||||
public $iVersionId;
|
||||
|
||||
public function vote($iVoteId = null, $oRow = null)
|
||||
{
|
||||
if(!$iVoteId && !$oRow) /* Nothing to do */
|
||||
return;
|
||||
|
||||
if(!$oRow)
|
||||
{
|
||||
$hResult = query_parameters("SELECT * FROM appVotes WHERE id = '?'", $iVoteId);
|
||||
|
||||
$oRow = mysql_fetch_object($hResult);
|
||||
}
|
||||
|
||||
if($oRow)
|
||||
{
|
||||
$this->iUserId = $oRow->userId;
|
||||
$this->iVoteId = $oRow->id;
|
||||
$this->iSlotIndex = $oRow->slot;
|
||||
$this->iVersionId = $oRow->versionId;
|
||||
}
|
||||
}
|
||||
|
||||
public function update()
|
||||
{
|
||||
/* Check for valid vote slot index */
|
||||
if($this->iSlotIndex < 1 || $this->iSlotIndex > MAX_VOTES)
|
||||
return;
|
||||
|
||||
/* Avoid pointless votes */
|
||||
if(!$this->iVersionId)
|
||||
return;
|
||||
|
||||
if(!$this->iVoteId)
|
||||
{
|
||||
$hResult = query_parameters("INSERT INTO appVotes (versionId,userId,slot) VALUES('?','?','?')",
|
||||
$this->iVersionId, $_SESSION['current']->iUserId, $this->iSlotIndex);
|
||||
} else
|
||||
{
|
||||
$hResult = query_parameters("UPDATE appVotes SET versionId = '?' WHERE id = '?'", $this->iVersionId, $this->iVoteId);
|
||||
}
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
/* A vote needs to have a versionId, so if it doesn't that means it is not in the
|
||||
database or it was not selected in the vote editor */
|
||||
if(!$this->iVersionId)
|
||||
return TRUE;
|
||||
|
||||
$hResult = query_parameters("DELETE FROM appVotes WHERE id = '?'", $this->iVoteId);
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function getVotesForVersion($iVersionId)
|
||||
{
|
||||
$aRet = array();
|
||||
$hResult = query_parameters("SELECT * FROM appVotes WHERE versionId = '?'",
|
||||
$iVersionId);
|
||||
|
||||
if(!$hResult)
|
||||
return $aRet;
|
||||
|
||||
while($oRow = mysql_fetch_object($hResult))
|
||||
$aRet[] = new vote(null, $oRow);
|
||||
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
public function objectGetId()
|
||||
{
|
||||
return $this->iVoteId;
|
||||
}
|
||||
|
||||
public function objectGetSubmitterId()
|
||||
{
|
||||
return $this->iUserId;
|
||||
}
|
||||
|
||||
public function objectGetParent($sClass = '')
|
||||
{
|
||||
return new version($this->iVersionId);
|
||||
}
|
||||
|
||||
public function objectSetParent($iNewId, $sClass = '')
|
||||
{
|
||||
$this->iVersionId = $iNewId;
|
||||
}
|
||||
|
||||
public function canEdit()
|
||||
{
|
||||
if($_SESSION['current']->iUserId == $this->iUserId)
|
||||
return true;
|
||||
|
||||
$oVersion = new version($this->iVersionId);
|
||||
|
||||
return $oVersion->canEdit();
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return array(null, null, null); /* No mail */
|
||||
}
|
||||
|
||||
public static function objectGetMailOptions($sAction, $bMailSubmitter,
|
||||
$bParentAction)
|
||||
{
|
||||
return new mailOptions();
|
||||
}
|
||||
}
|
||||
|
||||
class voteManager
|
||||
{
|
||||
private $iUserId;
|
||||
private $aVotes;
|
||||
|
||||
public function voteManager($iUserId = null, $oRow = null)
|
||||
{
|
||||
$this->iUserId = $iUserId;
|
||||
}
|
||||
|
||||
public function objectGetCustomVars($sAction)
|
||||
{
|
||||
switch($sAction)
|
||||
{
|
||||
case "edit":
|
||||
return array("iVersionId");
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function outputEditor($aClean = null)
|
||||
{
|
||||
echo "The following shows your current votes. Check the boxes next to the apps you wish to replace with a vote for ".version::fullNameLink($aClean['iVersionId'])." or delete.";
|
||||
|
||||
$oTable = new table();
|
||||
$this->aVotes = $this->getVotes();
|
||||
|
||||
for($i = 0; $i < MAX_VOTES; $i++)
|
||||
{
|
||||
$sVersionText = $this->aVotes[$i]->iVersionId ? version::fullNameLink($this->aVotes[$i]->iVersionId) : "No app selected";
|
||||
$oTableRow = new tableRow();
|
||||
$oTableRow->addTextCell('<input type="checkbox" name="iSlot'.$i.'" value="'.$aClean['iVersionId'].'">');
|
||||
$oTableRow->addTextCell($sVersionText);
|
||||
$oTable->addRow($oTableRow);
|
||||
}
|
||||
|
||||
echo $oTable->getString();
|
||||
}
|
||||
|
||||
public function canEdit()
|
||||
{
|
||||
if($_SESSION['current']->iUserId == $this->iUserId)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
return array(null, null, null); /* No mail */
|
||||
}
|
||||
|
||||
public function mustBeQueued()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function objectGetEntries($bQueued, $bRejected)
|
||||
{
|
||||
return query_parameters("SELECT * FROM appVotes");
|
||||
}
|
||||
|
||||
public function objectGetId()
|
||||
{
|
||||
return $this->iUserId;
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function purge()
|
||||
{
|
||||
return $this->delete();
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$bSuccess = TRUE;
|
||||
|
||||
if(!is_array($this->aVotes))
|
||||
$this->aVotes = $this->getVotes();
|
||||
|
||||
foreach($this->aVotes as $oVote)
|
||||
{
|
||||
if(!$oVote->delete())
|
||||
$bSuccess = FALSE;
|
||||
}
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
|
||||
public function update()
|
||||
{
|
||||
foreach($this->aVotes as $oVote)
|
||||
$oVote->update();
|
||||
}
|
||||
|
||||
public function getOutputEditorValues($aClean)
|
||||
{
|
||||
$this->aVotes = $this->getVotes();
|
||||
|
||||
for($i = 0; $i < MAX_VOTES; $i++)
|
||||
$this->aVotes[$i]->iVersionId = $aClean["iSlot$i"];
|
||||
}
|
||||
|
||||
public function objectGetEntriesCount()
|
||||
{
|
||||
$hResult = query_parameters("SELECT COUNT(id) as count FROM appVotes");
|
||||
|
||||
if(!$hResult)
|
||||
return FALSE;
|
||||
|
||||
if(!($oRow = mysql_fetch_object($hResult)))
|
||||
return FALSE;
|
||||
|
||||
return $oRow->count;
|
||||
}
|
||||
|
||||
public function objectGetSubmitterId()
|
||||
{
|
||||
return $this->iUserId;
|
||||
}
|
||||
|
||||
public function getVotes()
|
||||
{
|
||||
$aVotes = array();
|
||||
$hResult = query_parameters("SELECT * FROM appVotes WHERE userId = '?' ORDER BY slot", $this->iUserId);
|
||||
|
||||
if(!$hResult)
|
||||
return $aVotes;
|
||||
|
||||
for($i = 0; $i < MAX_VOTES; $i++)
|
||||
$aVotes[$i] = null;
|
||||
|
||||
while($oRow = mysql_fetch_object($hResult))
|
||||
$aVotes[$oRow->slot-1] = new vote(null, $oRow);
|
||||
|
||||
for($i = 0; $i < MAX_VOTES; $i++)
|
||||
{
|
||||
if(!$aVotes[$i])
|
||||
{
|
||||
$aVotes[$i] = new vote();
|
||||
$aVotes[$i]->iSlotIndex = $i+1;
|
||||
}
|
||||
}
|
||||
|
||||
return $aVotes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* used by admins to check whether votes for a version are legit
|
||||
*/
|
||||
class voteInspector
|
||||
{
|
||||
private $iVersionId;
|
||||
private $aDeleteVoters;
|
||||
|
||||
function voteInspector($iVersionId = null)
|
||||
{
|
||||
if(is_numeric($iVersionId))
|
||||
$this->iVersionId = $iVersionId;
|
||||
|
||||
$this->aDeleteVoters = array();
|
||||
}
|
||||
|
||||
public function objectGetId()
|
||||
{
|
||||
return $this->iVersionId;
|
||||
}
|
||||
|
||||
public function objectGetState()
|
||||
{
|
||||
return 'accepted';
|
||||
}
|
||||
|
||||
public function canEdit()
|
||||
{
|
||||
return $_SESSION['current']->hasPriv('admin');
|
||||
}
|
||||
|
||||
public function objectGetSubmitterId()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getVotes()
|
||||
{
|
||||
return query_parameters("SELECT userId, COUNT(userId) as count FROM appVotes WHERE
|
||||
versionId = '?'
|
||||
GROUP BY userId", $this->iVersionId);
|
||||
}
|
||||
|
||||
public function getVoteCount()
|
||||
{
|
||||
return vote_count_version_total($this->iVersionId);
|
||||
}
|
||||
|
||||
public function getVoterCount()
|
||||
{
|
||||
return mysql_num_rows($this->getVotes());
|
||||
}
|
||||
|
||||
public function outputEditor()
|
||||
{
|
||||
$oVersion = new version($this->iVersionId);
|
||||
|
||||
echo 'Inspecting votes for ' . version::fullNameLink($this->iVersionId).'<br />';
|
||||
echo 'Total votes: '.$this->getVoteCount().'<br />';
|
||||
echo 'To delete bogus user accounts, select them and press the Delete button below.<br /><br />';
|
||||
|
||||
$hResult = $this->getVotes();
|
||||
|
||||
if(!$hResult)
|
||||
{
|
||||
echo 'Failed to get list of votes';
|
||||
return;
|
||||
}
|
||||
|
||||
if(mysql_num_rows($hResult) == 0)
|
||||
{
|
||||
echo 'There are no votes for this version';
|
||||
return;
|
||||
}
|
||||
|
||||
$oTable = new Table();
|
||||
$oTable->setCellPadding(3);
|
||||
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->setClass('color4');
|
||||
$oTableRow->AddTextCell('Delete account');
|
||||
$oTableRow->AddTextCell('User');
|
||||
$oTableRow->AddTextCell('ID');
|
||||
$oTableRow->AddTextCell('E-mail');
|
||||
$oTableRow->AddTextCell('Created');
|
||||
$oTableRow->AddTextCell('Votes');
|
||||
$oTableRow->AddTextCell('Privileges');
|
||||
$oTableRow->AddTextCell('Test data');
|
||||
$oTableRow->AddTextcell('Comments');
|
||||
$oTable->AddRow($oTableRow);
|
||||
|
||||
for($i = 0; $oRow = mysql_fetch_object($hResult); $i++)
|
||||
{
|
||||
$oVoter = new user($oRow->userId);
|
||||
$oTableRow = new TableRow();
|
||||
$oTableRow->setClass(($i % 2) ? 'color0' : 'color1');
|
||||
|
||||
if($oVoter->hasPriv('admin'))
|
||||
$shDelete = '';
|
||||
else
|
||||
$shDelete = "<input type=\"checkbox\" name=\"iDelSlot$i\" value=\"{$oVoter->iUserId}\" />";
|
||||
|
||||
$oTableRow->AddTextCell($shDelete);
|
||||
$oTableRow->AddTextCell($oVoter->objectMakeLink());
|
||||
$oTableRow->AddTextCell($oVoter->iUserId);
|
||||
$oTableRow->AddTextCell($oVoter->sEmail);
|
||||
$oTableRow->AddTextCell($oVoter->sDateCreated);
|
||||
$oTableRow->AddTextCell($oRow->count);
|
||||
|
||||
$sPrivs = '';
|
||||
if($oVoter->hasPriv('admin'))
|
||||
$sPrivs .= 'Admin<br />';
|
||||
|
||||
if($oVoter->isMaintainer($this->iVersionId))
|
||||
$sPrivs .= 'Maintainer of this version<br />';
|
||||
|
||||
if($oVoter->isMaintainer())
|
||||
{
|
||||
$oM = new objectManager('maintainerView', 'View maintainership info');
|
||||
$sPrivs .= '<a href="'.$oM->makeUrl('view',$oVoter->iUserId).'">Maintainer (other entries)</a><br />';
|
||||
}
|
||||
|
||||
$oTableRow->AddTextCell($sPrivs);
|
||||
|
||||
$hSubResult = query_parameters("SELECT COUNT(testingId) AS count FROM testResults WHERE submitterId = '?' AND state != 'deleted'", $oVoter->iUserId);
|
||||
|
||||
if($hSubResult && ($oSubRow = mysql_fetch_object($hSubResult)))
|
||||
$sSubmitted = $oSubRow->count;
|
||||
else
|
||||
$sSubmitted = 'DB failure';
|
||||
|
||||
$oTableRow->AddTextCell($sSubmitted);
|
||||
|
||||
$hSubResult = query_parameters("SELECT COUNT(commentId) as count FROM appComments WHERE userId = '?'", $oVoter->iUserId);
|
||||
|
||||
if($hSubResult && ($oSubRow = mysql_fetch_object($hSubResult)))
|
||||
$sSubmitted = $oSubRow->count;
|
||||
else
|
||||
$sSubmitted = 'DB failure';
|
||||
|
||||
$oTableRow->AddTextCell($sSubmitted);
|
||||
$oTable->AddRow($oTableRow);
|
||||
}
|
||||
|
||||
echo $oTable->getString();
|
||||
}
|
||||
|
||||
public function getOutputEditorValues($aValues)
|
||||
{
|
||||
$iVoters = $this->getVoterCount();
|
||||
$this->aDeleteVoters = array();
|
||||
|
||||
for($i = 0; $i < $iVoters; $i++)
|
||||
{
|
||||
if(($iVoterId = getInput("iDelSlot$i", $aValues)))
|
||||
$this->aDeleteVoters[] = new user($iVoterId);
|
||||
}
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function update()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function objectGetMail($sAction, $bMailSubmitter, $bParentAction)
|
||||
{
|
||||
$sSubject = '';
|
||||
$sMsg = '';
|
||||
$aMailTo = null;
|
||||
|
||||
return array($sSubject, $sMsg, $aMailTo);
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$bSuccess = true;
|
||||
|
||||
foreach($this->aDeleteVoters as $oVoter)
|
||||
{
|
||||
if(!$oVoter->delete())
|
||||
$bSuccess = false;
|
||||
}
|
||||
|
||||
return $bSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* count the number of votes for appId by userId
|
||||
*/
|
||||
function vote_count($iVersionId, $iUserId = null)
|
||||
{
|
||||
if(!$iUserId)
|
||||
{
|
||||
if($_SESSION['current']->isLoggedIn())
|
||||
$iUserId = $_SESSION['current']->iUserId;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
$hResult = query_parameters("SELECT * FROM appVotes WHERE versionId = '?' AND userId = '?'",
|
||||
$iVersionId, $iUserId);
|
||||
return query_num_rows($hResult);
|
||||
}
|
||||
|
||||
/*
|
||||
* total votes for versionId
|
||||
*/
|
||||
function vote_count_version_total($iVersionId)
|
||||
{
|
||||
$hResult = query_parameters("SELECT * FROM appVotes WHERE versionId = '?'",
|
||||
$iVersionId);
|
||||
return query_num_rows($hResult);
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user