diff --git a/application/helpers/remotecontrol/remotecontrol_handle.php b/application/helpers/remotecontrol/remotecontrol_handle.php index 5ffaaf54cfa..67c05bcbd44 100644 --- a/application/helpers/remotecontrol/remotecontrol_handle.php +++ b/application/helpers/remotecontrol/remotecontrol_handle.php @@ -2353,6 +2353,246 @@ public function list_questions($sSessionKey, $iSurveyID, $iGroupID = null, $sLan } } + /* Quota specific functions */ + + /** + * Add a new quota with minimum details + * + * This just tries to create an empty quota with the minimal settings. + * + * Failure status: Invalid session key, No permission, Faulty parameters, Creation Failed result + * + * @access public + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID ID the Quota will belong to + * @param string $sQuotaName The name of the new Quota + * @param int $iLimit Quota limit + * @param bool $bActive Whether quota is active + * @param string $sAction ('terminate', 'confirm_terminate') + * @param bool $bAutoloadURL Whether URL is automatically redirected if quota is triggered + * @param string $sMessage Message to be presented to the user + * @param string $sURL URL to be redirected to after finishing the quota + * @param string $sURLDescription Description of the URL + * @return array|int The id of the new quota - Or status + */ + public function add_quota($sSessionKey, $iSurveyID, $sQuotaName, $iLimit, $bActive = true, $sAction = 'terminate', $bAutoloadURL = false, $sMessage = '', $sURL = '', $sURLDescription = '') + { + if ($this->_checkSessionKey($sSessionKey)) { + $iSurveyID = (int) $iSurveyID; + $iLimit = (int) $iLimit; + $bActive = (bool) $bActive; + $sAction = (string) $sAction; + $bAutoloadURL = (int) $bAutoloadURL; + $sMessage = (string) $sMessage; + $sURL = (string) $sURL; + $sURLDescription = (string) $sURLDescription; + + if (Permission::model()->hasSurveyPermission($iSurveyID, 'quotas', 'create')) { + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) { + return array('status' => 'Error: Invalid survey ID'); + } + + if ($iLimit < 0) { + return array('status' => 'Error: Invalid limit'); + } + + switch ($sAction) { + case 'terminate': + $iAction = Quota::ACTION_TERMINATE; + break; + case 'confirm_terminate': + $iAction = Quota::ACTION_CONFIRM_TERMINATE; + break; + default: + return array('status' => 'Error: Invalid quota action'); + } + + if ($sMessage == '' && ($sURL != '' || $sURLDescription != '')) { + return array('status' => 'Language-specific URL/description is set but no message is given'); + } + + $oDB = Yii::app()->db; + $oTransaction = $oDB->beginTransaction(); + + $oQuota = new Quota(); + $oQuota->sid = $iSurveyID; + $oQuota->name = $sQuotaName; + $oQuota->qlimit = $iLimit; + $oQuota->action = $iAction; + $oQuota->active = (int) $bActive; + $oQuota->autoload_url = (int) $bAutoloadURL; + + if (!$oQuota->save()) { + return array('status' => 'Creation Failed'); + } + + if (!$sMessage == '') { + $oQuotaLanguageSetting = new QuotaLanguageSetting(); + $oQuotaLanguageSetting->quotals_quota_id = $oQuota->id; + $oQuotaLanguageSetting->quotals_language = $oSurvey->language; + $oQuotaLanguageSetting->quotals_name = $sQuotaName; + $oQuotaLanguageSetting->quotals_message = $sMessage; + $oQuotaLanguageSetting->quotals_url = $sURL; + $oQuotaLanguageSetting->quotals_urldescrip = $sURLDescription; + + if (!$oQuotaLanguageSetting->save()) { + $oTransaction->rollback(); + return array('status' => 'Creation Failed'); + } + } + + $oTransaction->commit(); + return (int) $oQuota->id; + + } else { + return array('status' => 'No permission'); + } + } else { + return array('status' => 'Invalid session key'); + } + } + + /** + * List the quotas in a survey + * + * @access public + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID ID of the Survey containing the quotas + * @return array The list of quotas + */ + public function list_quotas($sSessionKey, $iSurveyID) + { + if ($this->_checkSessionKey($sSessionKey)) { + $iSurveyID = (int) $iSurveyID; + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) { + return array('status' => 'Error: Invalid survey ID'); + } + + if (Permission::model()->hasSurveyPermission($iSurveyID, 'quotas', 'read')) { + $aQuotas = Quota::model()->findAllByAttributes(array('sid' => $iSurveyID)); + if (count($aQuotas) == 0) { + return array('status' => 'No quotas found'); + } + + $aData = array(); + foreach ($aQuotas as $oRow) { + $aData[] = array( + 'id' => $oRow->id, + 'name' => $oRow->name, + 'action' => $oRow->action, + 'limit' => $oRow->qlimit, + 'active' => $oRow->active, + 'autoload_url' => $oRow->autoload_url, + ); + } + return $aData; + } else { + return array('status' => 'No permission'); + } + } else { + return array('status' => 'Invalid session key'); + } + } + + /** + * Delete a quota + * + * @access public + * @param string $sSessionKey Auth credentials + * @param int $iQuotaID The ID of the quota to be deleted + * @return array|int The ID of the deleted quota or status + */ + public function delete_quota($sSessionKey, $iQuotaID) + { + if ($this->_checkSessionKey($sSessionKey)) { + $iQuotaID = (int) $iQuotaID; + $oQuota = Quota::model()->findByPk($iQuotaID); + if (!isset($oQuota)) { + return array('status' => 'Error: Invalid quota ID'); + } + + if (Permission::model()->hasSurveyPermission($oQuota->sid, 'quotas', 'delete')) { + $oQuota->deleteQuota(array('id' => $iQuotaID)); + return array('status' => 'OK'); + } else { + return array('status' => 'No permission'); + } + } else { + return array('status' => 'Invalid session key'); + } + } + + /** + * Get quota attributes (RPC function) + * + * Get properties of a quota + * All internal properties of a quota are available. + * @see \Quota for the list of available properties + * + * Failure status : Invalid quota ID, Invalid session key, No permission, No valid Data + * + * @access public + * @param string $sSessionKey Auth credentials + * @param integer $iQuotaId Quota ID + * @param array|null $aQuotaSettings (optional) The properties to get + * @param string $sLanguage Optional parameter language for multilingual quotas + * @return array + */ + public function get_quota_properties($sSessionKey, $iQuotaId, $aQuotaSettings = null, $sLanguage = null) + { + if ($this->_checkSessionKey($sSessionKey)) { + $iQuotaId = (int) $iQuotaId; + $oQuota = Quota::model()->findByPk($iQuotaId); + + if (!isset($oQuota)) { + return array('status' => 'Error: Invalid quota ID'); + } + + if (Permission::model()->hasSurveyPermission($oQuota->sid, 'quotas', 'read')) { + $iSurveyID = $oQuota->sid; + if (is_null($sLanguage)) { + $sLanguage = Survey::model()->findByPk($iSurveyID)->language; + } + + $aBasicDestinationFields = Quota::model()->tableSchema->columnNames; + + # Quota Language settings + array_push($aBasicDestinationFields, 'quotals_message'); + array_push($aBasicDestinationFields, 'quotals_url'); + array_push($aBasicDestinationFields, 'quotals_urldescrip'); + + if (!empty($aQuotaSettings)) { + $aQuotaSettings = array_intersect($aQuotaSettings, $aBasicDestinationFields); + } else { + $aQuotaSettings = $aBasicDestinationFields; + } + + if (empty($aQuotaSettings)) { + return array('status' => 'No valid Data'); + } + + $aResult = array(); + foreach ($aQuotaSettings as $sPropertyName) { + if (isset($oQuota->$sPropertyName)) { + $aResult[$sPropertyName] = $oQuota->$sPropertyName; + } elseif ( + isset($oQuota->languagesettings[$sLanguage]) + && isset($oQuota->languagesettings[$sLanguage]->$sPropertyName) + ) { + $aResult[$sPropertyName] = $oQuota->languagesettings[$sLanguage]->$sPropertyName; + } + } + return $aResult; + } else { + return array('status' => 'No permission'); + } + } else { + return array('status' => self::INVALID_SESSION_KEY); + } + } + /** * Set quota attributes (RPC function) * diff --git a/tests/unit/helpers/RemoteControlQuotaTest.php b/tests/unit/helpers/RemoteControlQuotaTest.php new file mode 100644 index 00000000000..fdb092d75ec --- /dev/null +++ b/tests/unit/helpers/RemoteControlQuotaTest.php @@ -0,0 +1,133 @@ +getDb(); + + // Make sure the Authdb is in database (might not be the case if no browser login attempt has been made). + $plugin = \Plugin::model()->findByAttributes(array('name'=>'Authdb')); + if (!$plugin) { + $plugin = new \Plugin(); + $plugin->name = 'Authdb'; + $plugin->active = 1; + $plugin->save(); + } else { + $plugin->active = 1; + $plugin->save(); + } + App()->getPluginManager()->loadPlugin('Authdb', $plugin->id); + // Clear login attempts. + $query = sprintf('DELETE FROM {{failed_login_attempts}}'); + $dbo->createCommand($query)->execute(); + + + $filename = self::$surveysFolder . '/limesurvey_survey_remote_api_group_language.lss'; + self::importSurvey($filename); + + // Create handler. + $admin = new \AdminController('dummyid'); + $handler = new \remotecontrol_handle($admin); + + // Get session key. + $sessionKey = $handler->get_session_key( + self::$username, + self::$password + ); + $this->assertNotEquals(['status' => 'Invalid user name or password'], $sessionKey); + + // Add quota + $quota_id = $handler->add_quota( + $sessionKey, + self::$surveyId, + 'Test quota name', + 150, + true, + 'confirm_terminate', + true, + 'Quota reached', + 'https://example.com', + 'This is the Quota URL' + ); + $this->assertIsNumeric($quota_id, '$quota_id = ' . json_encode($quota_id)); + + $oQuota = \Quota::model()->findByPk($quota_id); + $this->assertNotEmpty($oQuota, 'Added quota not found'); + + $this->assertEquals(self::$surveyId, $oQuota->sid); + $this->assertEquals('Test quota name', $oQuota->name); + $this->assertEquals(150, $oQuota->qlimit); + $this->assertEquals(1, $oQuota->active); + $this->assertEquals(2, $oQuota->action); + $this->assertEquals(1, $oQuota->autoload_url); + $this->assertEquals('Quota reached', $oQuota->mainLanguagesetting->quotals_message); + $this->assertEquals('https://example.com', $oQuota->mainLanguagesetting->quotals_url); + $this->assertEquals('This is the Quota URL', $oQuota->mainLanguagesetting->quotals_urldescrip); + + // List quotas + $quotas = $handler->list_quotas($sessionKey, self::$surveyId); + $this->assertIsArray($quotas); + $this->assertEquals(1, count($quotas)); + $this->assertEquals($quota_id, $quotas[0]['id']); + + // Update quota properties + $set_result = $handler->set_quota_properties( + $sessionKey, + $quota_id, + array('qlimit' => 200) + ); + $this->assertTrue($set_result['success']); + $this->assertEquals(200, $set_result['message']['qlimit']); + + // Get quota properties + $properties = $handler->get_quota_properties($sessionKey, $quota_id); + $this->assertEquals(200, $properties['qlimit']); + + // Delete quota + $delete_result = $handler->delete_quota($sessionKey, $quota_id); + $this->assertEquals('OK', $delete_result['status']); + + // No quotas + $no_quotas_result = $handler->list_quotas($sessionKey, self::$surveyId); + $this->assertEquals('No quotas found', $no_quotas_result['status']); + + // Cleanup + self::$testSurvey->delete(); + self::$testSurvey = null; + } +}