예제 #1
0
 public function testSecurityExceptionThrownDuringExport()
 {
     $super = User::getByUsername('super');
     Yii::app()->user->userModel = $super;
     SecurityTestHelper::createAccounts();
     $billy = User::getByUsername('billy');
     Yii::app()->user->userModel = $billy;
     AllPermissionsOptimizationUtil::rebuild();
     $numberOfUserNotifications = Notification::getCountByTypeAndUser('ExportProcessCompleted', $billy);
     $account = new Account(false);
     $searchForm = new AccountsSearchForm($account);
     $dataProvider = ExportTestHelper::makeRedBeanDataProvider($searchForm, 'Account', 0, $billy->id);
     $totalItems = $dataProvider->getTotalItemCount();
     $this->assertEquals(3, $totalItems);
     $exportItem = new ExportItem();
     $exportItem->isCompleted = 0;
     $exportItem->exportFileType = 'csv';
     $exportItem->exportFileName = 'test7';
     $exportItem->modelClassName = 'Account';
     $exportItem->serializedData = serialize($dataProvider);
     $exportItem->owner = $billy;
     $this->assertTrue($exportItem->save());
     $id = $exportItem->id;
     $exportItem->forget();
     unset($exportItem);
     //Delete queued jobs from test exportItems created above
     Yii::app()->jobQueue->deleteAll();
     $accounts = Account::getByName('Microsoft');
     $account = $accounts[0];
     $account->owner = $super;
     $this->assertTrue($account->save());
     $job = new ExportJob();
     //ReadPermissionSubscriptionUpdate should get added to jobQueue
     $this->assertEquals(0, count(Yii::app()->jobQueue->getAll()));
     $this->assertTrue($job->run());
     $this->assertEquals(0, count(Yii::app()->jobQueue->getAll()));
     $exportItem = ExportItem::getById($id);
     $fileModel = $exportItem->exportFileModel;
     $this->assertEquals(1, $exportItem->isCompleted);
     $this->assertEquals('csv', $exportItem->exportFileType);
     $this->assertEquals('test7', $exportItem->exportFileName);
     $this->assertTrue($fileModel instanceof ExportFileModel);
     $data = array();
     $rows = $dataProvider->getData();
     $modelToExportAdapter = new ModelToExportAdapter($rows[0]);
     $headerData = $modelToExportAdapter->getHeaderData();
     foreach ($rows as $model) {
         //billy lost access to Microsoft account
         if ($model->id != $account->id) {
             $modelToExportAdapter = new ModelToExportAdapter($model);
             $data[] = $modelToExportAdapter->getData();
         }
     }
     $output = ExportItemToCsvFileUtil::export($data, $headerData, 'test7.csv', false);
     $this->assertEquals($output, $fileModel->fileContent->content);
 }
예제 #2
0
 /**
  * Test if background export job generated csv file,
  * check if content of this csv file is correct, and
  * finally check if user got notification message that
  * his downloads are completed.
  */
 public function testRun()
 {
     $super = User::getByUsername('super');
     Yii::app()->user->userModel = $super;
     $numberOfUserNotifications = Notification::getCountByTypeAndUser('ExportProcessCompleted', Yii::app()->user->userModel);
     $account = new Account();
     $account->owner = $super;
     $account->name = 'Test Account';
     $account->officePhone = '1234567890';
     $this->assertTrue($account->save());
     $account = new Account();
     $account->owner = $super;
     $account->name = 'Test Account 2';
     $account->officePhone = '1234567899';
     $this->assertTrue($account->save());
     $account = new Account(false);
     $searchForm = new AccountsSearchForm($account);
     $dataProvider = ExportTestHelper::makeRedBeanDataProvider($searchForm, 'Account', 0, Yii::app()->user->userModel->id);
     $totalItems = $dataProvider->getTotalItemCount();
     $this->assertEquals(2, $totalItems);
     $exportItem = new ExportItem();
     $exportItem->isCompleted = 0;
     $exportItem->exportFileType = 'csv';
     $exportItem->exportFileName = 'test';
     $exportItem->modelClassName = 'Account';
     $exportItem->serializedData = serialize($dataProvider);
     $this->assertTrue($exportItem->save());
     $id = $exportItem->id;
     $exportItem->forget();
     unset($exportItem);
     $job = new ExportJob();
     $this->assertTrue($job->run());
     $exportItem = ExportItem::getById($id);
     $fileModel = $exportItem->exportFileModel;
     $this->assertEquals(1, $exportItem->isCompleted);
     $this->assertEquals('csv', $exportItem->exportFileType);
     $this->assertEquals('test', $exportItem->exportFileName);
     $this->assertTrue($fileModel instanceof ExportFileModel);
     // Get csv string via regular csv export process(directly, not in background)
     // We suppose that csv generated thisway is corrected, this function itself
     // is tested in another test.
     $data = array();
     $rows = $dataProvider->getData();
     $modelToExportAdapter = new ModelToExportAdapter($rows[0]);
     $headerData = $modelToExportAdapter->getHeaderData();
     foreach ($rows as $model) {
         $modelToExportAdapter = new ModelToExportAdapter($model);
         $data[] = $modelToExportAdapter->getData();
     }
     $output = ExportItemToCsvFileUtil::export($data, $headerData, 'test.csv', false);
     $this->assertEquals($output, $fileModel->fileContent->content);
     // Check if user got notification message, and if its type is ExportProcessCompleted
     $this->assertEquals($numberOfUserNotifications + 1, Notification::getCountByTypeAndUser('ExportProcessCompleted', Yii::app()->user->userModel));
 }
 protected function export($stickySearchKey = null, $modelClassName = null, $exportFileName = null)
 {
     assert('$stickySearchKey == null || is_string($stickySearchKey)');
     assert('$modelClassName == null || is_string($modelClassName)');
     assert('$exportFileName == null || is_string($exportFileName)');
     if ($modelClassName == null) {
         $modelClassName = $this->getModelName();
     }
     $searchFormClassName = static::getSearchFormClassName();
     $pageSize = null;
     $model = new $modelClassName(false);
     if ($searchFormClassName != null) {
         $searchForm = new $searchFormClassName($model);
     } else {
         throw new NotSupportedException();
     }
     $stateMetadataAdapterClassName = $this->resolveStateMetadataAdapterClassNameForExport();
     $dataProvider = $this->getDataProviderByResolvingSelectAllFromGet($searchForm, $pageSize, Yii::app()->user->userModel->id, $stateMetadataAdapterClassName, $stickySearchKey);
     if (!$dataProvider) {
         $idsToExport = array_filter(explode(",", trim($_GET['selectedIds'], " ,")));
         // Not Coding Standard
     }
     $totalItems = static::getSelectedRecordCountByResolvingSelectAllFromGet($dataProvider, false);
     $data = array();
     if ($totalItems > 0) {
         if ($totalItems <= ExportModule::$asynchronousThreshold) {
             // Output csv file directly to user browser
             if ($dataProvider) {
                 $modelsToExport = ExportUtil::getDataForExport($dataProvider);
                 if (count($modelsToExport) > 0) {
                     $modelToExportAdapter = new ModelToExportAdapter($modelsToExport[0]);
                     $headerData = $modelToExportAdapter->getHeaderData();
                 }
                 foreach ($modelsToExport as $model) {
                     if (ControllerSecurityUtil::doesCurrentUserHavePermissionOnSecurableItem($model, Permission::READ)) {
                         $modelToExportAdapter = new ModelToExportAdapter($model);
                         $data[] = $modelToExportAdapter->getData();
                     }
                 }
             } else {
                 $headerData = array();
                 foreach ($idsToExport as $idToExport) {
                     $model = $modelClassName::getById(intval($idToExport));
                     if (ControllerSecurityUtil::doesCurrentUserHavePermissionOnSecurableItem($model, Permission::READ)) {
                         $modelToExportAdapter = new ModelToExportAdapter($model);
                         $data[] = $modelToExportAdapter->getData();
                         if (count($headerData) == 0) {
                             $headerData = $modelToExportAdapter->getHeaderData();
                         }
                     }
                 }
             }
             // Output data
             if (count($data)) {
                 if ($exportFileName == null) {
                     $fileName = $this->getModule()->getName() . ".csv";
                 } else {
                     $fileName = $exportFileName . ".csv";
                 }
                 $output = ExportItemToCsvFileUtil::export($data, $headerData, $fileName, true);
             } else {
                 Yii::app()->user->setFlash('notification', Zurmo::t('ZurmoModule', 'There is no data to export.'));
             }
         } else {
             if ($dataProvider) {
                 $serializedData = ExportUtil::getSerializedDataForExport($dataProvider);
             } else {
                 $serializedData = serialize($idsToExport);
             }
             // Create background job
             $exportItem = new ExportItem();
             $exportItem->isCompleted = false;
             $exportItem->exportFileType = 'csv';
             $exportItem->exportFileName = $this->getModule()->getName();
             $exportItem->modelClassName = $modelClassName;
             $exportItem->serializedData = $serializedData;
             $exportItem->isJobRunning = false;
             $exportItem->cancelExport = false;
             $exportItem->save();
             $exportItem->forget();
             Yii::app()->user->setFlash('notification', Zurmo::t('ZurmoModule', 'A large amount of data has been requested for export.  You will receive ' . 'a notification with the download link when the export is complete.'));
         }
     } else {
         Yii::app()->user->setFlash('notification', Zurmo::t('ZurmoModule', 'There is no data to export.'));
     }
     $this->redirect(array($this->getId() . '/index'));
 }
예제 #4
0
 /**
  * @depends testGetDataWithAllHasOneOrOwnedRelationsSet
  */
 public function testGetDataWithHasOneRelatedModel()
 {
     $super = User::getByUsername('super');
     Yii::app()->user->userModel = $super;
     $currencies = Currency::getAll();
     $currencyValue = new CurrencyValue();
     $currencyValue->value = 100;
     $currencyValue->currency = $currencies[0];
     $this->assertEquals('USD', $currencyValue->currency->code);
     $testItem2 = new ExportTestModelItem2();
     $testItem2->name = 'John';
     $this->assertTrue($testItem2->save());
     $testItem4 = new ExportTestModelItem4();
     $testItem4->name = 'John';
     $this->assertTrue($testItem4->save());
     //HAS_MANY and MANY_MANY relationships should be ignored.
     $testItem3_1 = new ExportTestModelItem3();
     $testItem3_1->name = 'Kevin';
     $this->assertTrue($testItem3_1->save());
     $testItem3_2 = new ExportTestModelItem3();
     $testItem3_2->name = 'Jim';
     $this->assertTrue($testItem3_2->save());
     $testItem = new ExportTestModelItem();
     $testItem->firstName = 'Bob3';
     $testItem->lastName = 'Bob3';
     $testItem->boolean = true;
     $testItem->date = '2002-04-03';
     $testItem->dateTime = '2002-04-03 02:00:43';
     $testItem->float = 54.22;
     $testItem->integer = 10;
     $testItem->phone = '21313213';
     $testItem->string = 'aString';
     $testItem->textArea = 'Some Text Area';
     $testItem->url = 'http://www.asite.com';
     $testItem->email = '*****@*****.**';
     $testItem->owner = $super;
     $testItem->currencyValue = $currencyValue;
     $testItem->hasOne = $testItem2;
     $testItem->hasMany->add($testItem3_1);
     $testItem->hasMany->add($testItem3_2);
     $testItem->hasOneAlso = $testItem4;
     $createStamp = strtotime(DateTimeUtil::convertTimestampToDbFormatDateTime(time()));
     $this->assertTrue($testItem->save());
     $id = $testItem->id;
     $testItem->forget();
     unset($testItem);
     $testItem = ExportTestModelItem::getById($id);
     $adapter = new ModelToExportAdapter($testItem);
     $data = $adapter->getData();
     $headerData = $adapter->getHeaderData();
     $compareData = array($id, 'stubDateTime', 'stubDateTime', 'super', 'super', 'super', 'Bob3', 'Bob3', '1', '2002-04-03', '2002-04-03 02:00:43', 54.22, 10, '21313213', 'aString', 'Some Text Area', 'http://www.asite.com', '*****@*****.**', null, 100, 'USD', null, null, null, null, '(None)', '(None)', null, null, null, null, null, null, null, null, null, null, null, null, null);
     $compareHeaderData = array($testItem->getAttributeLabel('id'), $testItem->getAttributeLabel('createdDateTime'), $testItem->getAttributeLabel('modifiedDateTime'), $testItem->getAttributeLabel('createdByUser'), $testItem->getAttributeLabel('modifiedByUser'), $testItem->getAttributeLabel('owner'), $testItem->getAttributeLabel('firstName'), $testItem->getAttributeLabel('lastName'), $testItem->getAttributeLabel('boolean'), $testItem->getAttributeLabel('date'), $testItem->getAttributeLabel('dateTime'), $testItem->getAttributeLabel('float'), $testItem->getAttributeLabel('integer'), $testItem->getAttributeLabel('phone'), $testItem->getAttributeLabel('string'), $testItem->getAttributeLabel('textArea'), $testItem->getAttributeLabel('url'), $testItem->getAttributeLabel('email'), $testItem->getAttributeLabel('currency'), $testItem->getAttributeLabel('currencyValue'), $testItem->getAttributeLabel('currencyValue') . ' ' . 'Currency', $testItem->getAttributeLabel('dropDown'), $testItem->getAttributeLabel('radioDropDown'), $testItem->getAttributeLabel('multiDropDown'), $testItem->getAttributeLabel('tagCloud'), $testItem->getAttributeLabel('hasOne') . ' - ' . 'Name', $testItem->getAttributeLabel('hasOneAlso') . ' - ' . 'Name', 'Primary Email - Email Address', 'Primary Email - Is Invalid', 'Primary Email - Opt Out', 'Primary Address - City', 'Primary Address - Country', 'Primary Address - Postal Code', 'Primary Address - Street 1', 'Primary Address - Street 2', 'Primary Address - State', 'Secondary Email - Email Address', 'Secondary Email - Is Invalid', 'Secondary Email - Opt Out', $testItem->getAttributeLabel('user'));
     // Because small delay in IO operation, allow tresholds
     $createdDateTimeKey = array_search($testItem->getAttributeLabel('createdDateTime'), $headerData);
     $modifiedDateTimeKey = array_search($testItem->getAttributeLabel('modifiedDateTime'), $headerData);
     $this->assertEquals($createStamp, strtotime($data[$createdDateTimeKey]), '', 2);
     $this->assertEquals($createStamp, strtotime($data[$modifiedDateTimeKey]), '', 2);
     $data[$createdDateTimeKey] = 'stubDateTime';
     $data[$modifiedDateTimeKey] = 'stubDateTime';
     $this->assertEquals($compareData, $data);
     $this->assertEquals($compareHeaderData, $headerData);
 }
예제 #5
0
 /**
  * Get the header row data which includes a label for each column
  * @return array $data
  */
 public function getHeaderData()
 {
     $data = array();
     $data[] = $this->resolveIdLabelToTitleCaseForExport($this->model->getAttributeLabel('id'));
     $retrievableAttributes = static::resolveExportableAttributesByModel($this->model);
     foreach ($this->model->getAttributes($retrievableAttributes) as $attributeName => $notUsed) {
         if (null !== ($adapterClassName = $this->getRedBeanModelAttributeValueToExportValueAdapterClassName($attributeName)) && !($this->model->isRelation($attributeName) && $this->model->getRelationType($attributeName) != RedBeanModel::HAS_ONE)) {
             //Non-relation attribute
             $adapter = new $adapterClassName($this->model, $attributeName);
             $adapter->resolveHeaderData($data);
         } elseif ($this->isHasOneVariationOwnedRelation($attributeName)) {
             //Owned relation attribute
             if ($this->model->{$attributeName}->id > 0) {
                 $util = new ModelToExportAdapter($this->model->{$attributeName});
                 $relatedData = $util->getData();
                 foreach ($relatedData as $relatedDataAttribute => $notUsed) {
                     if (strtolower($relatedDataAttribute) != 'id') {
                         $exportAttributeName = static::getLabelFromTwoAttributeStrings($this->model->getAttributeLabel($attributeName), $relatedDataAttribute);
                         $data[] = $exportAttributeName;
                     }
                 }
             } else {
                 $data = array_merge($data, $this->getAllAtttributesDataAsLabels($attributeName));
             }
         } elseif ($this->model->isRelation($attributeName) && $this->model->getRelationType($attributeName) == RedBeanModel::HAS_ONE) {
             //Non-owned relation
             if ($this->model->{$attributeName}->id > 0) {
                 $label = static::getLabelFromTwoAttributeStrings($this->model->getAttributeLabel($attributeName), Zurmo::t('ExportModule', 'Name'));
                 $data[] = $label;
             } else {
                 $data[] = $this->model->getAttributeLabel($attributeName);
             }
         }
     }
     return $data;
 }
 protected function isValidCsvConversion($textAreaContent)
 {
     $super = User::getByUsername('super');
     Yii::app()->user->userModel = $super;
     $testItem = new ExportTestModelItem();
     $testItem->firstName = 'Bob3';
     $testItem->lastName = 'Bob3';
     $testItem->boolean = true;
     $testItem->date = '2002-04-03';
     $testItem->dateTime = '2002-04-03 02:00:43';
     $testItem->float = 54.22;
     $testItem->integer = 10;
     $testItem->phone = '21313213';
     $testItem->string = 'aString';
     $testItem->textArea = $textAreaContent;
     $testItem->url = 'http://www.asite.com';
     $testItem->email = '*****@*****.**';
     $testItem->save();
     $id = $testItem->id;
     $testItem->forget();
     unset($testItem);
     $data = array();
     $testItem = ExportTestModelItem::getById($id);
     $adapter = new ModelToExportAdapter($testItem);
     $data[] = $adapter->getData();
     $headerData = $adapter->getHeaderData();
     // Export data to csv, and then revert csv back to array, so we compare data
     $csvData = ExportItemToCsvFileUtil::export($data, $headerData, 'exports.csv', false);
     $revertedData = CsvParser::parseFromString($csvData);
     // We are testing ModelToExportAdapter in details in another test
     // so in this test we suppose that ModelToExportAdapter::getData
     // return correct results
     $adapter = new ModelToExportAdapter($testItem);
     $compareData = $adapter->getData();
     $compareHeaderData = $adapter->getHeaderData();
     // Using === here would fail as we are not setting all keys part of getData()'s return array
     if ($compareData == array_values($revertedData[0]) && $compareHeaderData == array_keys($revertedData[0])) {
         return true;
     }
     return false;
 }
예제 #7
0
 /**
  * @param array $models
  * @param array $headerData
  * @param array $data
  * @param bool $resolveForHeader
  */
 protected function processExportModels(array $models, &$headerData, &$data, $resolveForHeader = true)
 {
     foreach ($models as $model) {
         $canRead = ControllerSecurityUtil::doesCurrentUserHavePermissionOnSecurableItem($model, Permission::READ);
         if ($canRead) {
             $modelToExportAdapter = new ModelToExportAdapter($model);
             if (count($headerData) == 0 && $resolveForHeader) {
                 $headerData = $modelToExportAdapter->getHeaderData();
             }
             $data[] = $modelToExportAdapter->getData();
             unset($modelToExportAdapter);
         }
         $this->runGarbageCollection($model);
     }
     unset($models);
 }
예제 #8
0
 public function run()
 {
     $exportItems = ExportItem::getUncompletedItems();
     if (count($exportItems) > 0) {
         foreach ($exportItems as $exportItem) {
             if (isset($exportItem->exportFileModel)) {
                 //continue;
             }
             $unserializedData = unserialize($exportItem->serializedData);
             if ($unserializedData instanceof RedBeanModelDataProvider) {
                 $formattedData = $unserializedData->getData();
             } else {
                 $formattedData = array();
                 foreach ($unserializedData as $idToExport) {
                     $model = call_user_func(array($exportItem->modelClassName, 'getById'), intval($idToExport));
                     $formattedData[] = $model;
                 }
             }
             if ($exportItem->exportFileType == 'csv') {
                 $headerData = array();
                 foreach ($formattedData as $model) {
                     if (ControllerSecurityUtil::doesCurrentUserHavePermissionOnSecurableItem($model, Permission::READ)) {
                         $modelToExportAdapter = new ModelToExportAdapter($model);
                         if (count($headerData) == 0) {
                             $headerData = $modelToExportAdapter->getHeaderData();
                         }
                         $data[] = $modelToExportAdapter->getData();
                     }
                 }
                 $output = ExportItemToCsvFileUtil::export($data, $headerData);
                 $fileContent = new FileContent();
                 $fileContent->content = $output;
                 $exportFileModel = new ExportFileModel();
                 $exportFileModel->fileContent = $fileContent;
                 $exportFileModel->name = $exportItem->exportFileName . ".csv";
                 $exportFileModel->type = 'application/octet-stream';
                 $exportFileModel->size = strlen($output);
                 $saved = $exportFileModel->save();
                 if ($saved) {
                     $exportItem->isCompleted = 1;
                     $exportItem->exportFileModel = $exportFileModel;
                     $exportItem->save();
                     $message = new NotificationMessage();
                     $message->htmlContent = Zurmo::t('ExportModule', 'Export of {fileName} requested on {dateTime} is completed. <a href="{url}">Click here</a> to download file!', array('{fileName}' => $exportItem->exportFileName, '{url}' => Yii::app()->createUrl('export/default/download', array('id' => $exportItem->id)), '{dateTime}' => DateTimeUtil::convertDbFormattedDateTimeToLocaleFormattedDisplay($exportItem->createdDateTime, 'long')));
                     $rules = new ExportProcessCompletedNotificationRules();
                     NotificationsUtil::submit($message, $rules);
                 }
             }
         }
     } else {
         return true;
     }
     return true;
 }
 public function testHasOneAndNotOwnedVariants()
 {
     $super = User::getByUsername('super');
     Yii::app()->user->userModel = $super;
     $adapter = new ModelToExportAdapter($super);
     $data = $adapter->getData();
     $headerData = $adapter->getHeaderData();
     $this->assertTrue(in_array($super->getAttributeLabel('language'), $headerData));
     $this->assertTrue(in_array($super->getAttributeLabel('locale'), $headerData));
     $this->assertTrue(in_array($super->getAttributeLabel('timeZone'), $headerData));
     $this->assertTrue(in_array($super->getAttributeLabel('role'), $headerData));
     $this->assertEquals(count($headerData), count($data));
 }