Silverstripe 3.2: How to export db fields of only one Dataobject in a CSV file? - field

I know there is a GridFieldExportButton which exports all the data of a GridField. But what I want is a custom Button which exports all the $db fields (ore just a few of them) of only ONE DataObject in a CSV file and download it. So I want this button in the edit area of this one DataObject and not for the GridField which shows all data objects.
I have already the button, now I need the right function. Can somebody help me?

You can change the fields exported for any DataObject in ModelAdmin with the following:
ModelAdmin:
class MyModelAdmin extends ModelAdmin {
...
static $managed_models = array(
'MyDataObject'
);
...
public function getExportFields() {
$modelClass = singleton($this->modelClass);
return $modelClass->hasMethod('getExportFields')
? $modelClass->getExportFields()
: $modelClass->summaryFields();
}
...
}
MyDataObject:
class MyDataObject extends DataObject {
...
public function getExportFields() {
$exportFields = array(
//Add all "db" fields here
);
return $exportFields;
}
...
}
If you wish for the export to be attached to a button else where I would suggest that you change the button to link to the ModelAdmin export CSV link

Related

frida modify static param as ArrayList

public class OBDSportsModelManager {
public static ArrayList<DataArray> mDiagnosisCommand;
public boolean getData() {
mDiagnosisCommand = new ArrayList<>();
for (String dataArray : this.commandIDs) {
mDiagnosisCommand.add(new DataArray(dataArray));
}
return true;
}
}
I want to add some more item to the 'mDiagnosisCommand',
by using this code:
sports.getData.implementation = function(){
Log.v("hook-sports", "try to add obd commands!");
var ret = this.getData();
var DataArray = Java.use("com.obd2.comm.DataArray");
var items = DataArray.$new("0x00,0x00,0x00,0x00,0x00,0x42");
this.mDiagnosisCommand.add(items); // not working!!!
Log.v("hook-sports", "hook done!");
return ret;
}
but doesn't works well.
I googled frida ArrayList add items without any help.
You have two problems:
You are using this.mDiagnosisCommand but the field is a static field, therefore it belongs to the class OBDSportsModelManager and not to the class instance this.
By calling this.mDiagnosisCommand you only get the Frida object representing this field, not the field value itself. If you want the ArrayList referenced by a field you have to add .value.
Considering both problems the following lines should work (after correcting the class name):
// correct the class name in the next line
var cls = Java.use("<full.name.to>.OBDSportsModelManager");
cls.mDiagnosisCommand.value.add(items);

SYMFONY FORM ChoiceType, multiple=>true. How to by pass the need to implement Data Transformers

In a SYMFONY FORM (ORM is not use (PDO is used for DB query instead)).
I have a class MyEntityType in which the buildForm function has:
$builder->add('my_attribute',ChoiceType::class,array(
'choices'=>$listForMyAttribute,
'multiple'=>'true',
'attr'=>array('data-native-menu'=>'false'),
'label'=>'Multiple Select on my attribute'
));
My attribute is an array of an entity named MyEntity which has:
/**
* #Assert\NotBlank()
*/
private $myAttribute;
With a getter and a setter for that variable $myAttribute.
When I submit the form in the Controller, it doesn't pass the validation check and logs this error:
Unable to reverse value for property path "myAttribute" : Could not find all matching choices for the given values.
When I start to look for solution around this error message, it leads to something named "How to Use Data Transformers" in SYMFONY Cookbook; And it seems a solution would involve to create new Class and write a lot of code for something that one should be able to by-pass in a much straight forward way.
Does anyone have an idea?
My problem was that my array $listForMyAttribute was defined in the buildForm() function and its definition was relying on some conditional.
The conditional to make the array were met when this one was displayed for the first time.
After pushing the submit button, the buildForm was regenerated in the Controller, this second time, the condition were not met to make the array $listForMyAttribute as it was on the first display. Hence the program was throwing a "contraint not met error" because the value submited for that field could not be find.
Today I face exactly the same problem. Solution is simple as 1-2-3.
1) Create utility dummy class DoNotTransformChoices
<?php
namespace AppBundle\DataTransformer;
use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface;
class DoNotTransformChoices implements ChoiceListInterface
{
public function getChoices() { return []; }
public function getValues() { return []; }
public function getPreferredViews() { return []; }
public function getRemainingViews() { return []; }
public function getChoicesForValues(array $values) { return $values; }
public function getValuesForChoices(array $choices) { return $choices; }
public function getIndicesForChoices(array $choices) { return $choices; }
public function getIndicesForValues(array $values) { return $values; }
}
2) Add to your field the following additional option:
...
'choice_list' => new DoNotTransformChoices,
...
3) Congratulations!

How to access other filter values inside of a custom addXXXColumnCriteria?

I have a request to create a form filter that has two fields, one a freeform text
and the other a select. The value in the select will determine how to handle the value of the text is turned into a criteria.
I can create a custom addXXXColumnCriteria for either field, but how can I access the other field from within this function?
I suggest you not to use de addXXXColumnCriteria, but overwrite the FormFilter doBuildCriteria (Propel) or doBuildQuery(Doctrine) methods.
I have never used Propel, but I guess that works as good as for Doctrine.
For example:
class yourPropelFormFilter extends anyKindOfSfFormFilterPropel {
public function doBuildCriteria(array $values) {
$criteria = parent::doBuildCriteria($values);
// ... change the criteria behaviour with the $values array (do some print_r to $values to see how the data array is formatted)
return $criteria;
}
}
For Doctrine (remember to use the getRootAlias query method):
class yourDoctrineFormFilter extends anyKindOfSfFormFilterDoctrine {
public function doBuildQuery(array $values) {
$q = parent::doBuildQuery($values);
$rootAlias = $q->getRootAlias();
if(...) {
$q->innerJoin($rootAlias.'.RelationX rx')
->addWhere('rx.value = ?',$values['...']);
}
return $q;
}
}
Please, remember to return the criteria/query modified object!

Problem with GRAILS select - trying to insert a number for a field that appears as text in dropdown list

Here is the domain class I have defined:
package mypackage
public enum UFModeType {
I(0),
O(1),
R(3)
Integer mode
public UserFileModeType(Integer mode) {
this.mode = mode;
}
static list() {
[I, O, R]
}
}
This is a property of another domain Parent where it is as follows:
package mypackage
class Parent {
String name
... ... ...
UFModeType uFMode
static mapping = {
table 'parent_table_with_ufMode_col_as_number'
version false
tablePerHierarchy false
id generator:'sequence', params:[sequence:'myseq']
columns {
id column:'parentid'
uFMode column: 'UFMODE'
}
}
static constraints = {
userFileMode(nullable: true)
}
}
The gsp call for this looks like this:
g:select name="uFMode" from="${mypackage.UFModeType?.list()}" value="${parentInstance?.uFMode?.name()}" /
I have tried a lot of variants of the above in the gsp call but I am getting error that the db insert fails saying the entry of ufmode is invalid number, thus this is not being passed as a number. I printed the params in the controllers save and it shows this:
Params in save=[uFMode:I ...
I am sure I may be missing some minor thing in syntax, but I have tried a lot of things without much success, so any inputs will be greatly appreciated.
Thanks!
Try changing
value="${parentInstance?.uFMode?.name()}
to
value="${parentInstance?.uFMode?.mode()}
From the definition of UFModeType you give you do not have a name attribute.

Symfony forms: how to change default widget for form generation

I'm using a custom Widget for date fields, and I want to use it in all my forms. The problem is that symfony uses the default sfWidgetFormDate. What I want is to change this default widget in order to generate forms with my custom Widget. I don't want to change by hand all the forms generated.
The only approach I have found is the trik of modify BaseFormDoctrine.php:
public function setup()
{
foreach($this->getWidgetSchema()->getFields() as $name=>$widget)
{
if($widget instanceof sfWidgetFormDate)
{
$this->widgetSchema[$name] = new sfWidgetFormJQueryDate(array(
'config' => '{}',
'image'=>'/images/calendar.png',
));
}
}
}
What you could do is create your own form generator class.
class myFormGenerator extends sfDoctrineGenerator
{
public function getWidgetClassForColumn($column)
{
switch ($column->getDoctrineType())
{
case 'date':
return 'sfWidgetFormJQueryDate';
break;
default:
return parent::getWidgetClassForColumn($column);
}
}
}
Save that somewhere sensible in your lib folder, clearing the cache etc..
Then rerun your for generator like so...
php doctrine:build-forms --generator-class='myFormGenerator'
I haven't tried any of the above, but the theory is sound I think...
Have a look at the following files to see where I figured this out from:
lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/task/sfDoctrineBuildFormsTask.class.php
lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/generator/sfDoctrineFormGenerator.class.php
Following johnwards answer, as I want to define default options for the widget, I also override the function to do that:
class myFormGenerator extents sfDoctrineFormGenerator
{
public function getWidgetClassForColumn($column)
{
...
}
public function getWidgetOptionsForColumn($column)
{
switch ($column->getDoctrineType())
{
case 'date':
return "array('config' => '{}', 'image'=>'/images/calendar.png')";
break;
default:
return parent::getWidgetOptionsForColumn($column);
}
}
}

Resources