From 8a4c5fef72ddd58d52334d61d1807610b2f59f38 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Sat, 9 Aug 2008 05:00:42 +0000 Subject: [PATCH] (merged from branches/roa. use "svn log -c -g " for detailed commit message) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@60212 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/ModelAdmin.php | 88 ++++++++++++++++++++++++++- css/ModelAdmin.css | 4 ++ javascript/ModelAdmin.js | 15 ++++- templates/Includes/ModelAdmin_left.ss | 11 +++- 4 files changed, 112 insertions(+), 6 deletions(-) diff --git a/code/ModelAdmin.php b/code/ModelAdmin.php index 650f33e0..2be815d3 100644 --- a/code/ModelAdmin.php +++ b/code/ModelAdmin.php @@ -40,6 +40,8 @@ abstract class ModelAdmin extends LeftAndMain { 'add', 'edit', 'delete', + 'import', + 'renderimportform', 'handleList', 'handleItem' ); @@ -59,6 +61,23 @@ abstract class ModelAdmin extends LeftAndMain { */ private $currentModel = false; + /** + * List of all {@link DataObject}s which can be imported through + * a subclass of {@link BulkLoader} (mostly CSV data). + * By default {@link CsvBulkLoader} is used, assuming a standard mapping + * of column names to {@link DataObject} properties/relations. + * + * @var array + */ + protected static $model_importers = null; + + /** + * Amount of results showing on a single page. + * + * @var int + */ + protected static $page_length = 30; + /** * Initialize the model admin interface. Sets up embedded jquery libraries and requisite plugins. * @@ -69,7 +88,7 @@ abstract class ModelAdmin extends LeftAndMain { // security check for valid models if(isset($this->urlParams['Action']) && !in_array($this->urlParams['Action'], $this->getManagedModels())) { - user_error('ModelAdmin::init(): Invalid Model class', E_USER_ERROR); + //user_error('ModelAdmin::init(): Invalid Model class', E_USER_ERROR); } Requirements::css('cms/css/ModelAdmin.css'); // standard layout formatting for management UI @@ -137,11 +156,56 @@ abstract class ModelAdmin extends LeftAndMain { return $form; } + /** + * Generate a CSV import form with an option to select + * one of the "importable" models specified through {@link self::$model_importers}. + * + * @return Form + */ + public function ImportForm() { + $models = $this->getManagedModels(); + $modelMap = array(); + foreach($this->getModelImporters() as $modelName => $spec) $modelMap[$modelName] = singleton($modelName)->singular_name(); + + $form = new Form( + $this, + "ImportForm", + new FieldSet( + new DropdownField('ClassName', 'Type', $modelMap), + new FileField('_CsvFile', false) + ), + new FieldSet( + new FormAction('import', _t('ModelAdmin.IMPORT', 'Import from CSV')) + ) + ); + return $form; + } + function add($data, $form, $request) { $className = $request->requestVar("ClassName"); return $this->$className()->add($request); } + /** + * Imports the submitted CSV file based on specifications given in + * {@link self::model_importers}. + * Redirects back with a success/failure message. + * + * @todo Figure out ajax submission of files via jQuery.form plugin + * + * @param unknown_type $data + * @param unknown_type $form + * @param unknown_type $request + */ + function import($data, $form, $request) { + $loader = new DemandPointBulkLoader($data['ClassName']); + $results = $loader->load($_FILES['_CsvFile']['tmp_name']); + $resultsCount = ($results) ? $results->Count() : 0; + + Session::setFormMessage('Form_ImportForm', "Loaded {$resultsCount} items", 'good'); + Director::redirect($_SERVER['HTTP_REFERER'] . '#Form_ImportForm_holder'); + } + /** * * @uses {@link SearchContext} @@ -175,6 +239,26 @@ abstract class ModelAdmin extends LeftAndMain { return $models; } + + /** + * Returns all importers defined in {@link self::$model_importers}. + * If none are defined, we fall back to {@link self::managed_models} + * with a default {@link CsvBulkLoader} class. In this case the column names of the first row + * in the CSV file are assumed to have direct mappings to properties on the object. + * + * @return array + */ + protected function getModelImporters() { + $importers = $this->stat('model_importers'); + + // fallback to all defined models if not explicitly defined + if(!$importers) { + $models = $this->getManagedModels(); + foreach($models as $modelName) $importers[$modelName] = 'CsvBulkLoader'; + } + + return $importers; + } } /** @@ -270,7 +354,7 @@ class ModelAdmin_CollectionController extends Controller { $model = singleton($this->modelClass); $searchKeys = array_intersect_key($request->getVars(), $model->searchable_fields()); $context = $model->getDefaultSearchContext(); - $results = $context->getResults($searchKeys); + $results = $context->getResults($searchKeys, 0, $this->parentController->stat('page_length')); $output = ""; if ($results) { $output .= ""; diff --git a/css/ModelAdmin.css b/css/ModelAdmin.css index 205d3c90..cd23b3e3 100644 --- a/css/ModelAdmin.css +++ b/css/ModelAdmin.css @@ -52,4 +52,8 @@ body.ModelAdmin #ResultTable_holder table td.over { body.ModelAdmin #ResultTable_holder table td.active { background-color:#555; color:#fff; +} + +body.ModelAdmin #right .tab { + height: 450px; /* @todo add dynamic resizing */ } \ No newline at end of file diff --git a/javascript/ModelAdmin.js b/javascript/ModelAdmin.js index 16a12ce1..bc343fd8 100644 --- a/javascript/ModelAdmin.js +++ b/javascript/ModelAdmin.js @@ -56,7 +56,7 @@ jQuery(document).ready(function() { /** * Find the selected data object and load its create form */ - jQuery('#AddForm_holder form').submit(function(){ + jQuery('#Form_ManagedModelsSelect').submit(function(){ className = jQuery('select option:selected', this).val(); requestPath = jQuery(this).attr('action').replace('ManagedModelsSelect', className + '/add'); showRecord(requestPath); @@ -83,7 +83,7 @@ jQuery(document).ready(function() { * * @todo use livequery to manage ResultTable click handlers */ - jQuery('.tab form').submit(function(){ + jQuery('#SearchForm_holder .tab form').submit(function(){ form = jQuery(this); data = formData(form); jQuery.get(form.attr('action'), data, function(result){ @@ -103,4 +103,13 @@ jQuery(document).ready(function() { return false; }); -}); \ No newline at end of file +}); + +/** + * @todo Terrible HACK, but thats the cms UI... + */ +function fixHeight_left() { + fitToParent('LeftPane'); + fitToParent('Search_holder',12); + fitToParent('ResultTable_holder',12); +} \ No newline at end of file diff --git a/templates/Includes/ModelAdmin_left.ss b/templates/Includes/ModelAdmin_left.ss index 6f2ab70b..3ff1a3e0 100755 --- a/templates/Includes/ModelAdmin_left.ss +++ b/templates/Includes/ModelAdmin_left.ss @@ -1,7 +1,16 @@

<% _t('ADDLISTING','Add Listing') %>

- $ManagedModelsSelect + +
+ $ManagedModelsSelect +
+
+ $ImportForm +

<% _t('SEARCHLISTINGS','Search Listings') %>