From: Tim Otten Date: Fri, 30 May 2014 23:04:03 +0000 (-0700) Subject: CRM-14765 - FullText - Implement "File" search UI with mocked result data X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=2f5c26f8ad4002936196bbdd4bcbb17661781172;p=civicrm-core.git CRM-14765 - FullText - Implement "File" search UI with mocked result data --- diff --git a/CRM/Contact/Form/Search/Custom/FullText.php b/CRM/Contact/Form/Search/Custom/FullText.php index 9135b82831..719124ffde 100644 --- a/CRM/Contact/Form/Search/Custom/FullText.php +++ b/CRM/Contact/Form/Search/Custom/FullText.php @@ -86,6 +86,7 @@ class CRM_Contact_Form_Search_Custom_FullText implements CRM_Contact_Form_Search new CRM_Contact_Form_Search_Custom_FullText_Contribution(), new CRM_Contact_Form_Search_Custom_FullText_Participant(), new CRM_Contact_Form_Search_Custom_FullText_Membership(), + new CRM_Contact_Form_Search_Custom_FullText_File(), ); $formValues['table'] = $this->getFieldValue($formValues, 'table', 'String'); @@ -194,6 +195,12 @@ class CRM_Contact_Form_Search_Custom_FullText implements CRM_Contact_Form_Search 'membership_end_date' => 'datetime', 'membership_source' => 'varchar(255)', 'membership_status' => 'varchar(255)', + 'file_id' => 'int unsigned', + 'file_name' => 'varchar(255)', + 'file_url' => 'varchar(255)', + 'file_mime_type' => 'varchar(255)', + 'file_entity_table' => 'varchar(255)', + 'file_entity_id' => 'int unsigned', ); $sql = " diff --git a/CRM/Contact/Form/Search/Custom/FullText/File.php b/CRM/Contact/Form/Search/Custom/FullText/File.php new file mode 100644 index 0000000000..4607ea380b --- /dev/null +++ b/CRM/Contact/Form/Search/Custom/FullText/File.php @@ -0,0 +1,199 @@ +solrResponse = $this->doSearch($queryText, $queryLimit); + $fileIds = $this->findFileIds($this->solrResponse, $detailLimit); + $matches = $this->formatFileMatches($fileIds); + $this->insertMatches($toTable, $matches); + + return count($this->solrResponse['docs']); + } + + public function doSearch($queryText, $limit) { + // TODO use $queryText, $limit + $json = '{ + "response": { + "numFound": 14, + "start": 0, + "docs": [ + { + "id": "pqlj2a/civiFile/2", + "site": "http://localhost:8009/", + "hash": "pqlj2a", + "entity_id": 2, + "entity_type": "civiFile", + "bundle": "civiFile", + "bundle_name": "civiFile", + "ss_language": "und", + "label": "CiviCRM_Scalability_DataSet_QA.doc", + "spell": [ + "CiviCRM_Scalability_DataSet_QA.doc", + "CiviCRM Scalability Initiative: Reproducing Large Data Sets Background The CiviCRM community provides contact and payment processing software for a wide-range of organizations – organizations whose datasets range from a few thousand records to [WM\'s actual size]. For small and mid-sized organizations running CiviCRM on modern hardware, scalability-testing is a low-priority issue; for large organizations, scalability is critical. Unfortunately, the CiviCRM development community currently tests scalability in an ad-hoc fashion – system implementors may run ad-hoc performance tests in their staging environments when evaluating a new CiviCRM upgrade, but code contributors and core developers do not have suitable resources to test performance during development. Goals Enable the community to assess CiviCRM performance with large data-sets on an on-going basis. Assess performance of listed use-cases (see below). Non-Goals This project only addresses testing of read-access to large datasets. High-performance transaction processing (OLTP) is left as a separate issue. Related Projects Continuous integration – [Comment on funding/progress and how it ties in] Developer VM/puppet scripts – [Comment on funding/progress and how it ties in] Long upgrade support – [Comment on funding/progress and how it ties in] Deliverables Dataset An analysis of selected contact, contribution, group, and mailing data-patterns in the Wikimedia dataset A redistributable “clean-room” data-generation script which parallels the Wikimedia dataset (without explicitly copying it) Three redistributable, “rendered” MySQL data-sets which can be (re)loaded into developer VM\'s. The three data-sets will be designated “0.25x”, “1x”, and “4x” (based on the size of the data-set relative to the example Wikimedia) Systems (Cross-Support for CI/VM Projects) [some kind of plan for getting hardware to run tests periodically – eg a system-image for EC2 or a new box at OSUOSL] Performance Tests A repository of scripts for testing listed use-cases A report on performance of listed use-cases [Non-commital] Patches and/or analyses of slow use-cases Performance Test-Cases Advanced search by contact email address Advanced search by contribution amount Advanced search by contribution date Advanced search by contribution amount and date Database upgrades and schema changes Budget Dataset: X hr Systems (Cross-Support for CI/VM): $X hardware + X hour Performance Tests: X hour Total: $X h/w + X hr" + ], + "url": "/civicrm/file?reset=1&id=2&eid=22", + "ss_filemime": "application/msword", + "content": "CiviCRM Scalability Initiative: Reproducing Large Data Sets Background The CiviCRM community provides contact and payment processing software for a wide-range of organizations – organizations whose datasets range from a few thousand records to [WM\'s actual size]. For small and mid-sized organizations running CiviCRM on modern hardware, scalability-testing is a low-priority issue; for large organizations, scalability is critical. Unfortunately, the CiviCRM development community currently tests scalability in an ad-hoc fashion – system implementors may run ad-hoc performance tests in their staging environments when evaluating a new CiviCRM upgrade, but code contributors and core developers do not have suitable resources to test performance during development. Goals Enable the community to assess CiviCRM performance with large data-sets on an on-going basis. Assess performance of listed use-cases (see below). Non-Goals This project only addresses testing of read-access to large datasets. High-performance transaction processing (OLTP) is left as a separate issue. Related Projects Continuous integration – [Comment on funding/progress and how it ties in] Developer VM/puppet scripts – [Comment on funding/progress and how it ties in] Long upgrade support – [Comment on funding/progress and how it ties in] Deliverables Dataset An analysis of selected contact, contribution, group, and mailing data-patterns in the Wikimedia dataset A redistributable “clean-room” data-generation script which parallels the Wikimedia dataset (without explicitly copying it) Three redistributable, “rendered” MySQL data-sets which can be (re)loaded into developer VM\'s. The three data-sets will be designated “0.25x”, “1x”, and “4x” (based on the size of the data-set relative to the example Wikimedia) Systems (Cross-Support for CI/VM Projects) [some kind of plan for getting hardware to run tests periodically – eg a system-image for EC2 or a new box at OSUOSL] Performance Tests A repository of scripts for testing listed use-cases A report on performance of listed use-cases [Non-commital] Patches and/or analyses of slow use-cases Performance Test-Cases Advanced search by contact email address Advanced search by contribution amount Advanced search by contribution date Advanced search by contribution amount and date Database upgrades and schema changes Budget Dataset: X hr Systems (Cross-Support for CI/VM): $X hardware + X hour Performance Tests: X hour Total: $X h/w + X hr", + "teaser": "CiviCRM Scalability Initiative: Reproducing Large Data Sets Background The CiviCRM community provides contact and payment processing software for a wide-range of organizations – organizations whose datasets range from a few thousand records to [WM\'s actual size]. For small and mid-sized", + "timestamp": "2014-05-29T22:28:29.852Z" + } + ] + } +}'; + $matches = json_decode($json, TRUE); + return $matches['response']; + } + + /** + * @param array $solrResponse + * @param array|NULL $limit + * @return array + * @throws CRM_Core_Exception + */ + public function findFileIds($solrResponse, $limit) { + $fileIds = array(); + if (!empty($solrResponse['docs'])) { + if ($limit) { + list($rowCount, $offset) = $limit; + $docs = array_slice($solrResponse['docs'], $offset ? $offset : 0, $rowCount); + } + else { + $docs = $solrResponse['docs']; + } + + foreach ($docs as $doc) { + if ($doc['entity_type'] == 'civiFile') { + if (isset($doc['entity_id'])) { + $fileIds[] = $doc['entity_id']; + } + else { + } + } + } + } + return $fileIds; + } + + /** + * @param array $fileIds + * @return array + */ + public function formatFileMatches($fileIds) { + $fileIdsCsv = implode(',', array_filter($fileIds, 'is_numeric')); + if (empty($fileIdsCsv)) { + return array(); + } + + $selectFilesSql = " + SELECT f.*, ef.*, ef.id as entity_file_id + FROM civicrm_file f + INNER JOIN civicrm_entity_file ef ON f.id = ef.file_id + WHERE f.id IN ({$fileIdsCsv}) + "; + $selectFilesDao = CRM_Core_DAO::executeQuery($selectFilesSql); + + $matches = array(); + while ($selectFilesDao->fetch()) { + $match = array( + 'table_name' => $this->getName(), + 'file_id' => $selectFilesDao->file_id, + 'file_name' => CRM_Utils_File::cleanFileName($selectFilesDao->uri), + 'file_url' => CRM_Utils_System::url('civicrm/file', "reset=1&id={$selectFilesDao->file_id}&eid={$selectFilesDao->entity_id}"), + 'file_mime_type' => $selectFilesDao->mime_type, + ); + + if ($selectFilesDao->entity_table == 'civicrm_note') { + // For notes, we go up an extra level to the note's parent + $note = new CRM_Core_DAO_Note(); + $note->id = $selectFilesDao->entity_id; + $note->find(); + if ($note->fetch()) { + $match['file_entity_table'] = $note->entity_table; + $match['file_entity_id'] = $note->entity_id; + } + else { + continue; // skip; perhaps an orphan? + } + } + else { + $match['file_entity_table'] = $selectFilesDao->entity_table; + $match['file_entity_id'] = $selectFilesDao->entity_id; + } + $matches[] = $match; + } + + // When possible, add 'contact_id' to matches + foreach (array_keys($matches) as $matchKey) { + switch ($matches[$matchKey]['file_entity_table']) { + case'civicrm_contact': + $matches[$matchKey]['contact_id'] = $matches[$matchKey]['file_entity_id']; + //$matches[$matchKey]['sort_name'] = NULL; + //$matches[$matchKey]['display_name'] = NULL; + break; + default: + $matches[$matchKey]['contact_id'] = NULL; + //$matches[$matchKey]['sort_name'] = NULL; + //$matches[$matchKey]['display_name'] = NULL; + } + } + + return $matches; + } + + public function insertMatches($toTable, $matches) { + if (empty($matches)) { + return; + } + $insertContactSql = CRM_Utils_SQL_Insert::into($toTable)->rows($matches)->toSQL(); + CRM_Core_DAO::executeQuery($insertContactSql); + } +} diff --git a/templates/CRM/Contact/Form/Search/Custom/FullText.tpl b/templates/CRM/Contact/Form/Search/Custom/FullText.tpl index 95dd712cfc..55cd24dea1 100644 --- a/templates/CRM/Contact/Form/Search/Custom/FullText.tpl +++ b/templates/CRM/Contact/Form/Search/Custom/FullText.tpl @@ -360,5 +360,51 @@ {* END Actions/Results section *} {/if} + +{if !empty($summary.File) } +
+{* Search request has returned 1 or more matching rows. *} + +

{ts}Files{/ts}: + {if !$table} + {if $summary.Count.File <= $limit}{$summary.Count.File}{else}{ts 1=$limit}%1 or more{/ts}{/if} + {else} + {$summary.Count.File} + {/if}

+ {if $table}{include file="CRM/common/pager.tpl" location="top"}{/if} + + {* This section displays the rows along and includes the paging controls *} + + + + + + + + + + + {foreach from=$summary.File item=row} + + + + + + + {/foreach} + +
{ts}File Name{/ts}{ts}Type{/ts}{ts}Attached To{/ts}
{$row.file_name}{$row.file_mime_type}{crmCrudLink action=VIEW table=$row.file_entity_table id=$row.file_entity_id} + {ts}View{/ts} +
+ {if !$table and $summary.addShowAllLink.File} + {/if} + {if $table}{include file="CRM/common/pager.tpl" location="below"}{/if} +{* END Actions/Results section *} +
+{/if} + {if !$table}{include file="CRM/common/pager.tpl" location="bottom"}{/if}