aVersions = array(); // Should always be an array // we are working on an existing application if(!$iAppId && !$oRow) return; if(!$oRow) { /* fetch this applications information */ $sQuery = "SELECT * FROM appFamily WHERE appId = '?'"; if($hResult = query_parameters($sQuery, $iAppId)) $oRow = query_fetch_object($hResult); } if($oRow) { $this->iAppId = $oRow->appId; $this->iVendorId = $oRow->vendorId; $this->iCatId = $oRow->catId; $this->iSubmitterId = $oRow->submitterId; $this->sSubmitTime = $oRow->submitTime; $this->sName = $oRow->appName; $this->sKeywords = $oRow->keywords; $this->sDescription = $oRow->description; //TODO: we should move the url to the appData table // and return an id into the appData table here $this->sWebpage = Url::normalize($oRow->webPage); $this->sState = $oRow->state; $this->bHasMaintainer = $oRow->hasMaintainer == 'true' ? true : false; } /* fetch versions of this application, if there are any */ $this->aVersionsIds = array(); /* only admins can view all versions */ //FIXME: it would be nice to move this permission into the user class as well as keep it generic if($_SESSION['current']->hasPriv("admin")) { $hResult = $this->_internal_retrieve_all_versions(); } else { $hResult = $this->_internal_retrieve_unqueued_versions(); } if($hResult) { while($oRow = query_fetch_object($hResult)) { $this->aVersionsIds[] = $oRow->versionId; } } } private function _internal_retrieve_all_versions($bOnlyAccepted = false, $bIncludeObsolete = TRUE, $bIncludeDeleted = false) { $sExtraTerms = ''; if(!$bIncludeObsolete) $sExtraTerms .= " AND obsoleteBy = '0'"; if($bOnlyAccepted) $sExtraTerms .= " AND state = 'accepted'"; else if(!$bIncludeDeleted) $sExtraTerms .= " AND state != 'deleted'"; $sQuery = "SELECT versionId FROM appVersion WHERE appId = '?'$sExtraTerms ORDER by versionName"; $hResult = query_parameters($sQuery, $this->iAppId); return $hResult; } private function _internal_retrieve_unqueued_versions() { $sQuery = "SELECT versionId FROM appVersion WHERE state = 'accepted' AND appId = '?'"; $hResult = query_parameters($sQuery, $this->iAppId); return $hResult; } /** * Creates a new application. */ public function create() { if(!$_SESSION['current']->canCreateApplication()) return false; $hResult = query_parameters("INSERT INTO appFamily (appName, description, ". "keywords, webPage, vendorId, catId, ". "submitTime, submitterId, ". "state) VALUES (". "'?', '?', '?', '?', '?', '?', ?, '?', '?')", $this->sName, $this->sDescription, $this->sKeywords, $this->sWebpage, $this->iVendorId, $this->iCatId, "NOW()", $_SESSION['current']->iUserId, $this->mustBeQueued() ? 'queued' : 'accepted'); if($hResult) { $this->iAppId = query_appdb_insert_id(); $this->application($this->iAppId); $this->SendNotificationMail(); // Only administrators will be mailed as no supermaintainers exist for this app. /* Submit super maintainer request if asked to */ if($this->iMaintainerRequest == SUPERMAINTAINER_REQUEST) { $oMaintainer = new Maintainer(); $oMaintainer->iAppId = $this->iAppId; $oMaintainer->iUserId = $_SESSION['current']->iUserId; $oMaintainer->sMaintainReason = "This user submitted the application; auto-queued."; $oMaintainer->bSuperMaintainer = 1; $oMaintainer->create(); } return true; } else { addmsg("Error while creating a new application.", "red"); return false; } } /** * Update application. * Returns true on success and false on failure. */ public function update($bSilent=false) { $sWhatChanged = ""; /* if the user doesn't have permission to modify this application, don't let them */ if(!$_SESSION['current']->canModifyApplication($this)) return; /* create an instance of ourselves so we can see what has changed */ $oApp = new Application($this->iAppId); if ($this->sName && ($this->sName!=$oApp->sName)) { if (!query_parameters("UPDATE appFamily SET appName = '?' WHERE appId = '?'", $this->sName, $this->iAppId)) return false; $sWhatChanged .= "Name was changed from ".$oApp->sName." to ".$this->sName.".\n\n"; } if ($this->sDescription && ($this->sDescription!=$oApp->sDescription)) { if (!query_parameters("UPDATE appFamily SET description = '?' WHERE appId = '?'", $this->sDescription, $this->iAppId)) return false; $sWhatChanged .= "Description was changed from\n ".$oApp->sDescription."\n to \n".$this->sDescription.".\n\n"; } if ($this->sKeywords && ($this->sKeywords!=$oApp->sKeywords)) { if (!query_parameters("UPDATE appFamily SET keywords = '?' WHERE appId = '?'", $this->sKeywords, $this->iAppId)) return false; $sWhatChanged .= "Keywords were changed from\n ".$oApp->sKeywords."\n to \n".$this->sKeywords.".\n\n"; } if ($this->sWebpage!=$oApp->sWebpage) { if (!query_parameters("UPDATE appFamily SET webPage = '?' WHERE appId = '?'", $this->sWebpage, $this->iAppId)) return false; $sWhatChanged .= "Web page was changed from ".$oApp->sWebpage." to ".$this->sWebpage.".\n\n"; } if ($this->iVendorId && ($this->iVendorId!=$oApp->iVendorId)) { if (!query_parameters("UPDATE appFamily SET vendorId = '?' WHERE appId = '?'", $this->iVendorId, $this->iAppId)) return false; $oVendorBefore = new Vendor($oApp->iVendorId); $oVendorAfter = new Vendor($this->iVendorId); $sWhatChanged .= "Developer was changed from ".$oVendorBefore->sName." to ".$oVendorAfter->sName.".\n\n"; } if ($this->iCatId && ($this->iCatId!=$oApp->iCatId)) { if (!query_parameters("UPDATE appFamily SET catId = '?' WHERE appId = '?'", $this->iCatId, $this->iAppId)) return false; $oCatBefore = new Category($oApp->iCatId); $oCatAfter = new Category($this->iCatId); $sWhatChanged .= "Category was changed from ".$oCatBefore->sName." to ".$oCatAfter->sName.".\n\n"; } if($sWhatChanged and !$bSilent) $this->SendNotificationMail("edit",$sWhatChanged); return true; } public function hasMaintainer() { return $this->bHasMaintainer; } public function updateMaintainerState() { $this->bHasMaintainer = maintainer::appHasMaintainer($this->iAppId); $hResult = query_parameters("UPDATE appFamily SET hasMaintainer = '?' WHERE appId = '?'", $this->bHasMaintainer ? 'true' : 'false', $this->iAppId); } /** * Deletes the application from the database. * and request the deletion of linked elements. */ public function purge() { $bSuccess = true; /* make sure the current user has the appropriate permission to delete this application */ if(!$_SESSION['current']->canDeleteApplication($this)) return false; foreach($this->objectGetChildren(true) as $oChild) { if(!$oChild->purge()) $bSuccess = FALSE; } /* Flag the entry as deleted */ $sQuery = "DELETE FROM appFamily WHERE appId = '?' LIMIT 1"; if(!($hResult = query_parameters($sQuery, $this->iAppId))) $bSuccess = false; return $bSuccess; } /** * Falgs the application as deleted * and request the deletion of linked elements. */ public function delete() { $bSuccess = true; /* make sure the current user has the appropriate permission to delete this application */ if(!$_SESSION['current']->canDeleteApplication($this)) return false; foreach($this->objectGetChildren() as $oChild) { if(!$oChild->delete()) $bSuccess = FALSE; } /* Flag the entry as deleted */ $sQuery = "UPDATE appFamily SET state = 'deleted' WHERE appId = '?' LIMIT 1"; if(!($hResult = query_parameters($sQuery, $this->iAppId))) $bSuccess = false; return $bSuccess; } /** * Move application out of the queue. */ public function unQueue() { if(!$_SESSION['current']->canUnQueueApplication()) return; if(query_parameters("UPDATE appFamily SET state = '?', keywords = '?' WHERE appId = '?'", 'accepted', str_replace(" *** ","",$this->sKeywords), $this->iAppId)) { $this->sState = 'accepted'; // we send an e-mail to interested people $this->mailSubmitter(); $this->SendNotificationMail(); /* Unqueue matching super maintainer request */ $hResultMaint = query_parameters("SELECT maintainerId FROM appMaintainers WHERE userId = '?' AND appId = '?'", $this->iSubmitterId, $this->iAppId); if($hResultMaint && query_num_rows($hResultMaint)) { $oMaintainerRow = query_fetch_object($hResultMaint); $oMaintainer = new Maintainer($oMaintainerRow->maintainerId); $oMaintainer->unQueue("OK"); } } } public function Reject() { if(!$_SESSION['current']->canRejectApplication($this)) return; // If we are not in the queue, we can't move the application out of the queue. if($this->sState != 'queued') return false; if(query_parameters("UPDATE appFamily SET state = '?' WHERE appId = '?'", 'rejected', $this->iAppId)) { $this->sState = 'rejected'; // we send an e-mail to interested people $this->mailSubmitter("reject"); $this->SendNotificationMail("reject"); // the application has been rejected addmsg("The application has been rejected.", "green"); } } public static function objectGetItemsPerPage($sState = 'accepted') { $aItemsPerPage = array(25, 50, 100, 200); $iDefaultPerPage = 25; return array($aItemsPerPage, $iDefaultPerPage); } public function ReQueue() { if(!$_SESSION['current']->canRequeueApplication($this)) return false; if(query_parameters("UPDATE appFamily SET state = '?' WHERE appId = '?'", 'queued', $this->iAppId)) { $this->sState = 'queued'; // we send an e-mail to interested people $this->SendNotificationMail(); // the application has been re-queued addmsg("The application has been re-queued.", "green"); } } public function objectGetSubmitterId() { return $this->iSubmitterId; } public function objectGetMailOptions($sAction, $bMailSubmitter, $bParentAction) { return new mailOptions(); } public function objectGetMail($sAction, $bMailSubmitter, $bParentAction) { if($bMailSubmitter) { switch($sAction) { case "delete": $sSubject = "Submitted application deleted"; $sMsg = "The application you submitted (".$this->sName. ") has been deleted."; break; } $aMailTo = null; } else { switch($sAction) { case "delete": $sSubject = $this->sName." deleted"; $sMsg = "The application '".$this->sName."' has been deleted."; break; } $aMailTo = User::get_notify_email_address_list($this->iAppId); } return array($sSubject, $sMsg, $aMailTo); } private function mailSubmitter($sAction="add") { global $aClean; if(!isset($aClean['sReplyText'])) $aClean['sReplyText'] = ""; if($this->iSubmitterId) { $oSubmitter = new User($this->iSubmitterId); switch($sAction) { case "add": $sSubject = "Submitted application accepted"; $sMsg = "The application you submitted (".$this->sName.") has been accepted by ".$_SESSION['current']->sRealname.".\n"; $sMsg .= "Administrator's Response:\n"; break; case "reject": $sSubject = "Submitted application rejected"; $sMsg = "The application you submitted (".$this->sName.") has been rejected by ".$_SESSION['current']->sRealname."."; $sMsg .= "Clicking on the link in this email will allow you to modify and resubmit the application. "; $sMsg .= "A link to your queue of applications and versions will also show up on the left hand side of the Appdb site once you have logged in. "; $sMsg .= APPDB_ROOT."objectManager.php?sClass=application_queue". "&bIsQueue=true&bIsRejected=true&iId=".$this->iAppId."&sTitle=". "Edit+Application\n"; $sMsg .= "Reason given:\n"; break; } $sMsg .= $aClean['sReplyText']."\n"; $sMsg .= "We appreciate your help in making the Application Database better for all users."; mail_appdb($oSubmitter->sEmail, $sSubject ,$sMsg); } } public static function countWithRating($sRating) { $sQuery = "SELECT DISTINCT count(appId) as total FROM appVersion WHERE rating = '?' AND state = 'accepted'"; if($hResult = query_parameters($sQuery, $sRating)) { $oRow = query_fetch_object($hResult); } return $oRow->total; } public static function getWithRating($sRating, $iOffset, $iItemsPerPage) { $aApps = array(); $sQuery = "SELECT DISTINCT appVersion.appId, appName FROM appVersion, appFamily WHERE appVersion.appId = appFamily.appId AND rating = '?' AND appVersion.state = 'accepted' ORDER BY appName ASC LIMIT ?, ?"; if($hResult = query_parameters($sQuery, $sRating, $iOffset, $iItemsPerPage)) { while($aRow = query_fetch_row($hResult)) { array_push($aApps, $aRow[0]); } } return $aApps; } private function SendNotificationMail($sAction="add",$sMsg=null) { global $aClean; if(!isset($aClean['sReplyText'])) $aClean['sReplyText'] = ""; switch($sAction) { case "add": if($this->sState == 'accepted') // Has been accepted. { $sSubject = $this->sName." has been added by ".$_SESSION['current']->sRealname; $sMsg = $this->objectMakeUrl()."\n"; if($this->iSubmitterId) { $oSubmitter = new User($this->iSubmitterId); $sMsg .= "This application has been submitted by ".$oSubmitter->sRealname."."; $sMsg .= "\n"; } if($aClean['sReplyText']) { $sMsg .= "Appdb admin reply text:\n"; $sMsg .= $aClean['sReplyText']."\n"; // append the reply text, if there is any } addmsg("The application was successfully added into the database.", "green"); } else { $sSubject = $this->sName." has been submitted by ".$_SESSION['current']->sRealname; $sMsg .= "This application has been queued."; $sMsg .= "\n"; addmsg("The application you submitted will be added to the database after being reviewed.", "green"); } break; case "edit": $sSubject = $this->sName." has been modified by ".$_SESSION['current']->sRealname; $sMsg .= $this->objectMakeUrl()."\n"; addmsg("Application modified.", "green"); break; case "reject": $sSubject = $this->sName." has been rejected by ".$_SESSION['current']->sRealname; $sMsg .= APPDB_ROOT."objectManager.php?sClass=application_queue". "&bIsQueue=true&bIsRejected=true&iId=".$this->iAppId."&sTitle=". "Edit+Application\n"; // if sReplyText is set we should report the reason the application was rejected if($aClean['sReplyText']) { $sMsg .= "Reason given:\n"; $sMsg .= $aClean['sReplyText']."\n"; // append the reply text, if there is any } addmsg("Application rejected.", "green"); break; } $sEmail = User::get_notify_email_address_list($this->iAppId); if($sEmail) mail_appdb($sEmail, $sSubject ,$sMsg); } public function objectShowPreview() { return TRUE; } /* output a html table and this applications values to the fields for editing */ public function outputEditor($sVendorName = "") { HtmlAreaLoaderScript(array("app_editor")); echo ''; /* Used to distinguish between the first step of entering an application name and the full editor displayed here */ echo ''."\n"; echo html_frame_start("Application Form", "90%", "", 0); echo "\n"; echo '',"\n"; echo '',"\n"; // app Category echo '',"\n"; $oVendor = new vendor($this->iVendorId); $sVendorHelp = "The developer of the application. "; if(!$this->iAppId || $oVendor->objectGetState() != 'accepted') { if(!$this->iAppId) { $sVendorHelp .= "If it is not on the list please add it ". "using the form below."; } else { if($this->iSubmitterId != $_SESSION['current']->iUserId) { $sVendorHelp .= "The user added a new one; review ". "it in the Developer form below or ". "replace it with an existing one."; } else { $sVendorHelp .= 'You added a new one; it can be edited '. 'using the form below, or replaced with '. 'one from this list.'; } } } // vendor name echo '',"\n"; echo "\n"; // alt vendor $x = new TableVE("view"); echo '',"\n"; // url echo '',"\n"; echo '',"\n"; echo '',"\n"; echo '',"\n"; echo '',"\n"; echo '',"\n"; // Allow user to apply as super maintainer if this is a new app if(!$this->iAppId) { $sMaintainerOptions = "". "I would not like to become a maintainer
\n". "". "I would like to be a maintainer of the new version only
\n". "". "I would like to be a maintainer of the entire application
\n"; $sMaintainerOptionsSelected = str_replace( "value=\"$this->iMaintainerRequest\"", "value=\"$this->iMaintainerRequest\" checked=\"checked\"", $sMaintainerOptions); echo html_tr(array( array("Maintainer options", "class=\"color0\""), $sMaintainerOptionsSelected), "", "valign=\"top\""); } echo "
Application name
Category',"\n"; $aCategories = category::getOrderedList(true); $aCatNames = array(); $aCatIds = array(); foreach($aCategories as $oCategory) { $aCatNames[] = $oCategory->sName; $aCatIds[] = $oCategory->objectGetId(); } echo html_select("iAppCatId",$aCatIds,$this->iCatId, $aCatNames); echo '
Developer$sVendorHelp
 ',"\n"; echo $x->make_option_list("iAppVendorId", $this->iVendorId,"vendor","vendorId","vendorName", array('vendor.state', 'accepted')); echo '
URL
Keywords
Application description (In your own words)

\n"; echo html_frame_end(); } public function CheckOutputEditorInput($aValues) { $errors = ""; if (empty($aValues['iAppCatId'])) $errors .= "
  • Please enter a category for your application.
  • \n"; if (strlen($aValues['sAppName']) > 200 ) $errors .= "
  • Your application name is too long.
  • \n"; if (empty($aValues['sAppName'])) $errors .= "
  • Please enter an application name.
  • \n"; // No vendor entered, and nothing in the list is selected if (empty($aValues['sVendorName']) && !$aValues['iAppVendorId']) $errors .= "
  • Please enter a developer.
  • \n"; if (empty($aValues['shAppDescription'])) $errors .= "
  • Please enter a description of your application.
  • \n"; return $errors; } /* retrieves values from $aValues that were output by outputEditor() */ /* $aValues can be $_REQUEST or any array with the values from outputEditor() */ public function GetOutputEditorValues($aValues) { if($aValues['iAppId']) $this->iAppId = $aValues['iAppId']; $this->sName = $aValues['sAppName']; $this->sDescription = $aValues['shAppDescription']; $this->iCatId = $aValues['iAppCatId']; $this->iVendorId = $aValues['iAppVendorId']; $this->sWebpage = $aValues['sAppWebpage']; $this->sKeywords = $aValues['sAppKeywords']; $this->iMaintainerRequest = $aValues['iMaintainerRequest']; } /** * Displays the SUB apps that belong to this application. */ public function displayBundle() { $hResult = query_parameters("SELECT appFamily.appId, appName, description FROM appBundle, appFamily ". "WHERE appFamily.state = 'accepted' AND bundleId = '?' AND appBundle.appId = appFamily.appId", $this->iAppId); if(!$hResult || query_num_rows($hResult) == 0) { return; // do nothing } echo html_frame_start("","98%","",0); echo "\n\n"; echo "\n"; echo " \n"; echo " \n"; echo "\n\n"; for($c = 0; $ob = query_fetch_object($hResult); $c++) { $oApp = new application($ob->appId); //set row color $bgcolor = ($c % 2 == 0) ? "color0" : "color1"; //display row echo "\n"; echo " \n"; echo " \n"; echo "\n\n"; } echo "
    Application NameDescription
    ".$oApp->objectMakeLink()."".util_trim_description($oApp->sDescription)."
    \n\n"; echo html_frame_end(); } public function objectGetCustomTitle($sAction) { switch($sAction) { case 'delete': return 'Delete '.$this->sName; case "view": return $this->sName; default: return null; } } /* display this application */ public function display() { /* is this user supposed to view this version? */ if(!$_SESSION['current']->canViewApplication($this)) { $sError = 'You do not have permission to view this entry'; objectManager::error_exit($sError); } // cat display $oCategory = new Category($this->iCatId); $oCategory->displayPath($this->iAppId); // set developer $oVendor = new Vendor($this->iVendorId); // set URL $appLinkURL = ($this->sWebpage) ? trimmed_link($this->sWebpage,30) : " "; // start display application echo html_frame_start("","98%","",0); echo "\n"; echo " \n"; echo " \n"; echo " \n"; echo "
    \n"; echo ' ',"\n"; echo " \n"; echo " \n"; // main URL echo " \n"; // optional links if($sUrls = url::display(NULL, $this->iAppId)) echo $sUrls; // image $img = Screenshot::get_random_screenshot_img($this->iAppId, null, false); echo "\n"; echo "
    Name ".$this->sName."
    Developer ". $oVendor->objectMakeLink()." \n"; echo "
    URL".$appLinkURL."
    $img
    \n"; /* close of name/developer/bugs/url table */ echo "
    \n"; // Display all supermaintainers maintainers of this application echo " \n"; echo " \n"; $other_maintainers = Maintainer::getSuperMaintainersUserIdsFromAppId($this->iAppId); if($other_maintainers) { echo " \n"; } else { echo " \n"; } // Display the app maintainer button echo ' \n"; echo "
    Super maintainers:
      \n"; while(list($index, $userIdValue) = each($other_maintainers)) { $oUser = new User($userIdValue); echo "
    • ".$oUser->objectMakeLink()."
    • \n"; } echo "
    No maintainers.Volunteer today!
    '; if($_SESSION['current']->isLoggedIn()) { /* are we already a maintainer? */ if($_SESSION['current']->isSuperMaintainer($this->iAppId)) /* yep */ { echo '
    '; } else /* nope */ { echo ' sName).'&sReturnTo='.urlencode($this->objectMakeUrl()).'">'; } echo " iAppId."\">"; echo " "; /* set superMaintainer to 1 because we are at the appFamily level */ echo "
    "; if($_SESSION['current']->isSuperMaintainer($this->iAppId) || $_SESSION['current']->hasPriv("admin")) { echo '
    '; echo '
    '; echo ''; echo '
    '; } if($_SESSION['current']->isLoggedIn()) { echo '
    '; echo ''; echo '
    '; } if($_SESSION['current']->hasPriv("admin")) { $url = BASE."objectManager.php?sClass=application&bIsQueue=false&sAction=delete&iId=".$this->iAppId; echo "
    "; echo '
    '; } } else { echo '
    '; } echo "
    \n"; /* close of super maintainers table */ echo "
    \n"; /* close the table that contains the whole left hand side of the upper table */ // description echo " \n"; echo "
    \n"; echo "\t
    \n"; echo "\t\tDescription\n"; echo "\t
    \n"; // close the 'title_class' div echo "\t
    \n"; echo "\t\t".$this->sDescription."\n"; echo "\t
    \n"; // close the 'info_contents' div echo "
    \n"; // close the 'info_container' div echo html_frame_end("For more details and user comments, view the versions of this application."); // display versions Version::displayList($this->getVersions()); // display bundle $this->displayBundle(); note::displayNotesForEntry(null, $this->iAppId); } public static function lookup_name($appId) { if(!$appId) return null; $result = query_parameters("SELECT appName FROM appFamily WHERE appId = '?'", $appId); if(!$result || query_num_rows($result) != 1) return null; $ob = query_fetch_object($result); return $ob->appName; } /* List applications submitted by a given user */ public static function listSubmittedBy($iUserId, $bQueued = true) { $hResult = query_parameters("SELECT appId, appName, vendorId, description, submitTime FROM appFamily WHERE submitterId = '?' AND state = '?' ORDER BY appId", $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("Application"); $oTableRow->AddTextCell("Description"); $oTableRow->AddTextCell("Developer"); $oTableRow->AddTextCell("Submission Date"); $oTableRow->SetClass("color4"); $oTable->SetHeader($oTableRow); if($bQueued) $oTableRow->addTextCell("Action"); for($i = 1; $oRow = query_fetch_object($hResult); $i++) { $oVendor = new vendor($oRow->vendorId); $oApp = new application($oRow->appId); $oTableRow = new TableRow(); $oTableRow->AddTextCell($oApp->objectMakeLink()); $oTableRow->AddTextCell($oRow->description); $oTableRow->AddTextCell($oVendor->objectMakeLink()); $oTableRow->AddTextCell(print_date(mysqldatetime_to_unixtimestamp($oRow->submitTime))); $oTableRow->SetClass(($i % 2) ? "color0" : "color1"); if($bQueued) { $oM = new objectManager('application_queue'); $oM->setReturnTo(array_key_exists('REQUEST_URI', $_SERVER) ? $_SERVER['REQUEST_URI'] : ""); $shDeleteLink = 'iAppId, "Delete entry").'">delete'; $shEditLink = 'iAppId, "Edit entry").'">edit'; $oTableRow->addTextCell("[ $shEditLink ]   [ $shDeleteLink ]"); } $oTable->AddRow($oTableRow); } return $oTable->GetString(); } public function objectGetClassDisplayName() { return 'application'; } public function objectMakeUrl() { $sUrl = APPDB_ROOT."objectManager.php?sClass=application&iId=$this->iAppId"; return $sUrl; } public function objectMakeLink() { $sLink = "objectMakeUrl()."\">". $this->sName.""; return $sLink; } public static function objectGetDefaultSort() { return 'appId'; } public static function objectGetEntries($sState, $iRows = 0, $iStart = 0, $sOrderBy = 'default', $bAscending = TRUE, $oFilters = null) { $sLimit = ""; $sOrdering = $bAscending ? "ASC" : "DESC"; if($sOrderBy == 'default') { if($sState == 'queued') $sOrderBy = 'appId'; else $sOrderBy = 'appName'; } $sExtraTables = ''; $sWhereFilter = $oFilters ? $oFilters->getWhereClause() : ''; $aOptions = $oFilters ? $oFilters->getOptions() : array('onlyDownloadable' => 'false', 'appCategory' => null); if($sWhereFilter || $aOptions['onlyDownloadable'] == 'true') { $sExtraTables = ",appVersion"; $sBugzillaQuery = ''; /* We only query the bugzilla table when necessary; these queries will hide apps without test results */ if(strstr($sWhereFilter, 'versions.id')) { $sExtraTables .= ','.BUGZILLA_DB.'.versions'; $sBugzillaQuery = ' AND versions.value = appVersion.ratingRelease AND versions.product_id = '.BUGZILLA_PRODUCT_ID.' '; } if($sWhereFilter) $sWhereFilter = " AND $sWhereFilter"; $sWhereFilter = " AND appVersion.state = 'accepted' AND appVersion.appId = appFamily.appId $sBugzillaQuery $sWhereFilter"; } if($aOptions['onlyDownloadable'] == 'true') { $sExtraTables .= ',appData'; $sWhereFilter .= " AND appData.type = 'downloadurl' AND appData.versionId = appVersion.versionId AND appData.state = 'accepted'"; } if($aOptions['appCategory']) { $oCategory = new Category($aOptions['appCategory']); $sWhereFilter .= ' AND ' . $oCategory->getSqlQueryPart(); } /* Should we add a limit clause to the query? */ if($iRows || $iStart) { $sLimit = " LIMIT ?,?"; /* 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 = application::objectGetEntriesCount($sState); } $sQuery = "SELECT DISTINCT(appFamily.appId), appFamily.*, vendor.vendorName AS vendorName FROM appFamily, vendor$sExtraTables WHERE appFamily.vendorId = vendor.vendorId AND appFamily.state = '?'$sWhereFilter"; if($sState != 'accepted' && !application::canEdit()) { /* Without global edit rights a user can only view his rejected apps */ if($sState != 'rejected') return FALSE; $sQuery .= " AND appFamily.submitterId = '?' ORDER BY ? ?$sLimit"; if($sLimit) { $hResult = query_parameters($sQuery, $sState, $_SESSION['current']->iUserId, $sOrderBy, $sOrdering, $iStart, $iRows); } else { $hResult = query_parameters($sQuery, $sState, $_SESSION['current']->iUserId, $sOrderBy, $sOrdering); } } else { $sQuery .= " ORDER BY ? ?$sLimit"; if($sLimit) { $hResult = query_parameters($sQuery, $sState, $sOrderBy, $sOrdering, $iStart, $iRows); } else { $hResult = query_parameters($sQuery, $sState, $sOrderBy, $sOrdering); } } if(!$hResult) return FALSE; return $hResult; } public static function objectGetFilterInfo() { $oFilter = new FilterInterface(); $aCategories = category::getOrderedList(); $aCatNames = array(); $aCatIds = array(); foreach($aCategories as $oCategory) { $aCatNames[] = $oCategory->sName; $aCatIds[] = $oCategory->objectGetId(); } $aLicenses = version::getLicenses(); $aDXGLVersions = get_bugzilla_versions(); $aDXGLVersionIds = get_bugzilla_version_ids(); $oFilter->AddFilterInfo('appVersion.rating', 'Rating', array(FILTER_EQUALS), FILTER_VALUES_ENUM, array('Platinum', 'Gold', 'Silver', 'Bronze', 'Garbage')); $oFilter->AddFilterInfo('versions.id', 'DXGL version', array(FILTER_EQUALS,FILTER_LESS_THAN,FILTER_GREATER_THAN), FILTER_VALUES_ENUM, $aDXGLVersionIds, $aDXGLVersions); $oFilter->AddFilterInfo('appCategory', 'Category', array(FILTER_OPTION_ENUM), FILTER_VALUES_OPTION_ENUM, $aCatIds, $aCatNames); $oFilter->AddFilterInfo('appVersion.license', 'License', array(FILTER_EQUALS), FILTER_VALUES_ENUM, $aLicenses); $oFilter->AddFilterInfo('appFamily.appName', 'Name', array(FILTER_CONTAINS, FILTER_STARTS_WITH, FILTER_ENDS_WITH), FILTER_VALUES_NORMAL); $oFilter->AddFilterInfo('onlyDownloadable', 'Only show downloadable apps', array(FILTER_OPTION_BOOL), FILTER_VALUES_OPTION_BOOL, array('false','true')); return $oFilter; } public static function objectGetSortableFields() { return array('submitTime', 'appName', 'appId', 'userName', 'vendorName'); } public static function objectGetHeader($sState) { $oTableRow = new TableRowSortable(); if($sState == 'accepted') { $oTableRow->AddSortableTextCell('Application', 'appName'); $oTableRow->AddSortableTextCelL('Entry#', 'appId'); $oTableRow->AddTextCell('Description'); } else { $oTableRow->AddSortableTextCell('Submission Date', 'submitTime'); /* Only show submitter when processing queued entries */ $oTableRow->AddTextCell('Submitter'); $oTableRow->AddSortableTextCell('Developer', 'vendorName'); $oTableRow->AddSortableTextCell('Application', 'appName'); } return $oTableRow; } public function objectGetTableRow() { $oUser = new user($this->iSubmitterId); $oVendor = new vendor($this->iVendorId); $sVendor = $oVendor->objectMakeLink(); $oTableRow = new TableRow(); if($this->sState == 'accepted') { $oTableRow->AddTextCell($this->objectMakeLink()); $oTableRow->AddTextCell($this->iAppId); $oTableRow->AddTextCell(util_trim_description($this->sDescription)); } else { $oTableRow->AddTextCell(print_date(mysqldatetime_to_unixtimestamp($this->sSubmitTime))); $oTableRow->AddTextCell($oUser->objectMakeLink()); $oTableRow->AddTextCell($sVendor); $oTableRow->AddTextCell( $this->sName); } $oOMTableRow = new OMTableRow($oTableRow); return $oOMTableRow; } public function objectGetState() { return $this->sState; } public function canEdit() { if($_SESSION['current']->hasPriv("admin")) return TRUE; if(isset($this) && is_object($this) && $this->iAppId) { if(maintainer::isUserSuperMaintainer($_SESSION['current'], $this->iAppId)) return TRUE; if($this->sState != 'accepted' && $this->iSubmitterId == $_SESSION['current']->iUserId) { return TRUE; } return FALSE; } else { return FALSE; } } public function mustBeQueued() { if($_SESSION['current']->hasPriv("admin")) return FALSE; else return TRUE; } public function objectDisplayQueueProcessingHelp() { echo "

    This is the list of application entries waiting to be processed.

    \n"; echo "

    To view and process an entry, use the links under ‘Action’

    "; } public function objectDisplayAddItemHelp() { /* We don't display the full help on the page where you only input the app name */ if(!$this->sName) { echo "

    First, please enter the name of the application you wish to add. "; echo "This will allow you to determine whether there is already "; echo "an entry for it in the database.

    \n"; } else { echo "

    This page is for submitting new applications to be added to the\n"; echo "database. The application will be reviewed by an AppDB Administrator,\n"; echo "and you will be notified via e-mail if it is added to the database or rejected.

    \n"; echo "

    Before continuing, please ensure that you have

    \n"; echo "

    "; echo "

    Having app descriptions just sponsoring the app\n"; echo "(yes, some vendors want to use the appdb for this) or saying ‘I haven't tried this app with DXGL’ "; echo "will not help DXGL development or DXGL users. Application descriptions should be exactly that and only that, \n"; echo "they should not contain any information about how well the app works, just what the app is. The same applies to the \n"; echo "version information, it should be only information on what is unique or different about that version of the application, \n"; echo "not how well that version works or how great you think a new feature is.

    \n"; echo "

    When you reach the \"Test Form\" part (What works, What doesn't work, etc) please be detailed \n"; echo "about how well it worked and if any workarounds were needed but do NOT paste chunks of terminal output.

    \n"; echo "

    Please write information in proper English with correct grammar and punctuation!

    \n"; echo "Please only submit applications/versions that you have tested.\n"; echo "Submissions without test information or not using the provided template will be rejected.\n"; echo "If you are unable to see the in-browser editors below, please try Firefox, Mozilla or Opera browsers.\n"; echo "

    After your application has been added, you will be able to submit screenshots for it, post"; echo " messages in its forums or become a maintainer to help others trying to run the application.

    "; } } public static function objectGetEntriesCount($sState, $oFilters = null) { $sExtraTables = ''; $sWhereFilter = $oFilters ? $oFilters->getWhereClause() : ''; $aOptions = $oFilters ? $oFilters->getOptions() : array('onlyDownloadable' => 'false', 'appCategory' => null); if($sWhereFilter || $aOptions['onlyDownloadable'] == 'true') { $sExtraTables = ',appVersion'; $sBugzillaQuery = ''; /* We only query the bugzilla table when necessary; these queries will hide apps without test results */ if(strstr($sWhereFilter, 'versions.id')) { $sExtraTables .= ','.BUGZILLA_DB.'.versions'; $sBugzillaQuery = ' AND versions.value = appVersion.ratingRelease AND versions.product_id = '.BUGZILLA_PRODUCT_ID.' '; } if($sWhereFilter) $sWhereFilter = " AND $sWhereFilter"; $sWhereFilter = " AND appVersion.appId = appFamily.appId $sBugzillaQuery $sWhereFilter"; } if($aOptions['onlyDownloadable'] == 'true') { $sExtraTables .= ',appData'; $sWhereFilter .= " AND appData.type = 'downloadurl' AND appData.versionId = appVersion.versionId"; } if($aOptions['appCategory']) { $oCategory = new Category($aOptions['appCategory']); $sWhereFilter .= ' AND ' . $oCategory->getSqlQueryPart(); } if($sState != 'accepted' && !application::canEdit()) { /* Without edit rights users can only resubmit their rejected entries */ if($sState != 'rejected') return FALSE; $sQuery = "SELECT COUNT(DISTINCT(appFamily.appId)) as count FROM appFamily$sExtraTables WHERE submitterId = '?' AND appFamily.state = '?'$sWhereFilter"; $hResult = query_parameters($sQuery, $_SESSION['current']->iUserId, $sState); } else { $sQuery = "SELECT COUNT(DISTINCT(appFamily.appId)) as count FROM appFamily$sExtraTables WHERE appFamily.state = '?'$sWhereFilter"; $hResult = query_parameters($sQuery, $sState); } if(!$hResult) return FALSE; if(!$oRow = query_fetch_object($hResult)) return FALSE; return $oRow->count; } public function getVersions($bOnlyAccepted = false, $bIncludeObsolete = TRUE, $bIncludeDeleted = false) { /* If no id is set we cannot query for the versions, but perhaps objects are already cached? */ if(!$this->iAppId) return $this->aVersions; $aVersions = array(); $hResult = $this->_internal_retrieve_all_versions($bOnlyAccepted, $bIncludeObsolete, $bIncludeDeleted); while($oRow = mysql_fetch_object($hResult)) $aVersions[] = new version($oRow->versionId); return $aVersions; } /* Make a drop-down list of this application's versions. Optionally set the default versionId, a version to exclude and whether to not show obsolete versions */ public function makeVersionDropDownList($sVarName, $iCurrentId = null, $iExclude = null, $bIncludeObsolete = TRUE) { $sMsg = "\n"; return $sMsg; } public function objectAllowCreatingParents() { return true; } public function objectSetParent($iNewId, $sClass = '') { $this->iVendorId = $iNewId; } public function objectGetParent($sClass = '') { return new vendor($this->iVendorId); } public function objectGetChildren($bIncludeDeleted = false) { return $this->objectGetChildrenClassSpecific('', $IncludeDeleted); } public function objectGetChildrenClassSpecific($sClass = '', $bIncludeDeleted = false) { $aChildren = array(); /* Get versions */ foreach($this->getVersions(false, true, $bIncludeDeleted) as $oVersion) { if($sClass != 'version') $aChildren += $oVersion->objectGetChildren($bIncludeDeleted); $aChildren[] = $oVersion; } if($sClass == 'version') return $aChildren; /* Get urls */ $sQuery = "SELECT * FROM appData WHERE type = '?' AND appId = '?'"; $hResult = query_parameters($sQuery, "url", $this->iAppId); if(!$hResult) return FALSE; while($oRow = mysql_fetch_object($hResult)) { $oUrl = new url(0, $oRow); $aChildren += $oUrl->objectGetChildren($bIncludeDeleted); $aChildren[] = $oUrl; } /* Get maintainers */ $sQuery = "SELECT * FROM appMaintainers WHERE appId = '?' AND superMaintainer = '?'"; $hResult = query_parameters($sQuery, $this->iAppId, '1'); if(!$hResult) return FALSE; while($oRow = mysql_fetch_object($hResult)) { $oMaintainer = new maintainer(0, $oRow); $aChildren += $oMaintainer->objectGetChildren($bIncludeDeleted); $aChildren[] = $oMaintainer; } return $aChildren; } public function objectMoveChildren($iNewId) { /* Keep track of how many children we have moved */ $iCount = 0; foreach($this->aVersionsIds as $iVersionId) { $oVersion = new version($iVersionId); $oVersion->iAppId = $iNewId; if($oVersion->update()) $iCount++; else return FALSE; } /* If no errors occurred we return the number of moved children */ return $iCount; } public static function objectAllowMovingToNewParent() { return TRUE; } public static function allowAnonymousSubmissions() { return FALSE; } function objectAllowPurgingRejected() { return TRUE; } public function objectGetSubmitTime() { return mysqltimestamp_to_unixtimestamp($this->sSubmitTime); } public function objectGetId() { return $this->iAppId; } public function objectShowAddEntry() { return TRUE; } } ?>