I want to extend the DataObject (EditableDateField) of a module that I use (UserDefinedForms). There I want to overwrite a certain method (getFormField). I was trying to extend with DataExtension. But it does not work.
Here the code...
config.php:
EditableDateField::add_extension("CustomEditableDateField");
CustomEditableDateField:
class CustomEditableDateField extends DataExtension {
public function getFormField() {
//test is function called
echo 'test';
exit();
}
}
Also I tried to use Object::useCustomClass in the config to replace the whole EditableDateField with my CustomClass, but also no success.
What is the best way to do that?
Many thanx,
Florian
To do what you are wanting to achieve, you don't need to extend EditableDateField.
What you are looking for is EditableDateField_FormField which extends DateField. DateField does the heavy lifting for generating the HTML and doing the validation etc. One thing that DateField does have is a static variable called default_config which looks like this:
static $default_config = array(
'showcalendar' => false,
'jslocale' => null,
'dmyfields' => false,
'dmyseparator' => ' <span class="separator">/</span> ',
'dmyplaceholders' => true,
'dateformat' => null,
'datavalueformat' => 'yyyy-MM-dd',
'min' => null,
'max' => null,
);
Using the configuration system in Silverstripe, you can change the default dateformat to your dd.MM.yyyy format by using:
EditableDateField_FormField:
default_config:
'dateformat': 'dd.MM.yyyy'
You will want to use EditableDateField_FormField like my example above rather than change the default_config of DateField itself otherwise you may encounter issues in the CMS.
Technical Description
This works due to the constructor of DateField setting the instance config to the value of the default_config.
Because the value of dateformat is normally NULL in default_config, an if-statement passes which causes dateformat to be set the result from i18n::get_date_format().
Related
We are working on a project using Silverstripe with the Fluent module to enable multiple translations.
Here's an example Data Object with Fluent enabled. First we create the Data Object & explicitly set the CMS fields:
namespace Yard;
use SilverStripe\ORM\DataObject;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;
class Milkshake extends DataObject {
private static $table_name = 'Milkshake';
private static $db = [
'Title' => 'Varchar(255)'
]
public function getCMSFields() {
$fields = new FieldList(
new TextField('Title', 'Milkshake Title', null, 255)
);
$this->extend('updateCMSFields', $fields);
return $fields;
}
}
Then we set Title as translatable in a YML file:
Yard\Milkshake:
extensions:
- 'TractorCow\Fluent\Extension\FluentExtension'
translate:
- 'Title'
This gives us an object with a translatable Title field that can have different values in different locales. It creates the following database table:
Milkshake_Localised
ID | RecordID | Locale | Title
So far so good, except using:
$milkshake = Milkshake::get()->first() doesn't return the localised data & pulls from the Milkshake table.
I think it could be possible to use:
$locale= FluentState::singleton()->getLocale();
$milkshake = Milkshake_Localised::get()->filter(['Locale' => $locale])->first();
But this feels clumsy & has no fallback if the locale data doesn't exist for that field (at which point it should fall back to the default locale, or failing that the original Milkshake field).
What is the correct way to access Locale data in Fluent so there is a fallback if required?
I got the desired behaviour by wrapping the get command in "withState"
use TractorCow\Fluent\State\FluentState;
$milkshake = FluentState::singleton()->withState(function (FluentState $state) {
return Milkshake::get()->first();
});
I am trying to export a CSV of my data which is currently displayed in a section of my Silverstripe CMS as filtered by a particular date range . It works fine at the moment when exporting the entire contents but I would like to be able to filter the results that are exported so that it returns all results within a particular date range.
My Database has a column thats records the date created - in the format 'D-M-Y; H-M-S' which I think could be used to do the filtering but I cant figure out how to set up the search filter. I understand that if you use the searchable fields and then export, you only export the filtered search results so would assume thats the best way of doing it but can't figure out how to implement it.
Any suggestions would be greatly appreciated.
-- disclaimer - I would have liked to put this on the silverstripe forum but I am completely unable to sign up for some reason - I never receive the email confirmations. ---
<?php
namespace AffiliateProgram;
use SilverStripe\Forms\GridField\GridField;
use UndefinedOffset\SortableGridField\Forms\GridFieldSortableRows;
use SilverStripe\Security\Permission;
use SilverStripe\ORM\DataObject;
class MemberBonus extends DataObject
{
private static $db = [
'Amount' => 'Currency',
'Confirmed' => 'Boolean',
'Level' => 'Int',
'Percentage' => 'Int'
];
private static $has_one = [
'Member' => 'AffiliateProgram\Member',
'MemberPayment' => 'AffiliateProgram\MemberPayment',
'PaymentType' => 'AffiliateProgram\PaymentType',
'ProgramType' => 'AffiliateProgram\ProgramType'
];
private static $summary_fields = [
'Amount' => 'Amount (USD)',
'Member.Email' => 'Email',
'Level',
'MemberPayment.PaymentType.Symbol' => 'Recieved As',
'Percentage' => 'Percentage Bonus Applied',
'ProgramType.Name' => 'Program Type',
'MemberPayment.Created' => 'Payment Date',
'Confirmed' => 'Confirmed?',
'MemberPayment.ID' => 'Payment ID'
];
}
There is also a DateCreated column on the table.
You can add custom search fields to a ModelAdmin via getSearchContext(), and customise the query based on them with getList(). See this section of the SilverStripe documentation.
Here's an example of excluding results that have a CreatedAt value below the date provided in a search field (assuming your ModelAdmin only manages MemberBonus):
<?php
use SilverStripe\Admin\ModelAdmin;
use SilverStripe\Forms\DatetimeField;
class MemberBonusAdmin extends ModelAdmin
{
...
public function getSearchContext()
{
$context = parent::getSearchContext();
$context->getFields()->push(new DatetimeField('q[CreatedAfter]', 'Created After'));
return $context;
}
public function getList()
{
$list = parent::getList();
$params = $this->getRequest()->requestVar('q');
if (!empty($params['CreatedAfter'])) {
$list = $list->exclude('CreatedAt:LessThan', $params['CreatedAfter']);
}
return $list;
}
}
To get a range working, you'd just need to add a CreatedBefore field and filter.
So i have a GUI for a simple database made with Symfony2 + Sonata Admin Bundle + Doctrine 2. That database will hold billions of rows so the dates are stored as timestamps (to save space) but in the GUI displayed as dates (ex: 2013/10/17 10:05:06). Everything works in the GUI except the filtering by dates. I tried all sorts of configurations in the class that extends the Admin, method configureDatagridFilters(). I cannot make it to work... can you help me?
I found a work around that i think it can be useful in many other situations as well:
So in the class that extends Admin.php we have the method configureDatagridFilters(). There one can add an input like
->add('startDateFrom', 'doctrine_orm_callback', array(
'label' => 'Start Date from',
'callback' => function($queryBuilder, $alias, $field, $value) {
if (!$value['value']) {
return;
}
$inputValue = $this->dateStringToTimestamp($value['value']);
$queryBuilder->andWhere("{$alias}.startDate >= :startDateFrom");
$queryBuilder->setParameter('startDateFrom', $inputValue);
return true;
},
'field_type' => 'text'
), null, array('attr' => array('class' => 'calendar',
)))
As you can see, in this way we can manipulate the field value as we wish. I hope it will help others too :)
I have an array which can have various keys. However, always exists two keys which are required. I use the OptionsResolver component now. It is works fine until there is no any extra keys. I also considered the Validator component and as I understood there is the same behaviour. So I need always set the full list of keys but as I wrote above I need validate only some of them. Is there a way to solve this problem?
Thanks!
Hello you can define required, optional and defaults values in OptionResolver.
Maybe I will give you some example so it will be easier than describing it:
$resolver = new Symfony\Component\OptionsResolver\OptionsResolver;
$resolver
->setRequired(['required1', 'required2'])
->setOptional(['optional1', 'optional2'])
->setDefaults(['defaultValue' => '123'])
;
$options = $resolver->resolve(
[
'required1' => 'test',
'required2' => 'test123',
'optional1' => 'opt'
]
);
then options will be looks like that
[
'defaultValue' => '123',
'required1' => 'test',
'required2' => 'test123',
'optional1' => 'opt',
]
if we do not set required1 or required2 in resolved array then we gotSymfony\Component\OptionsResolver\Exception\MissingOptionsException exception.
If we give not know option (not defined in setRequired, setOptional or setDefaults) then we got Symfony\Component\OptionsResolver\Exception\InvalidOptionsException exception.
I also considered the Validator component and as I understood there is the same behaviour
You can decide which values should be "required"... but not sure if I got what you mean exactly
I'm trying to create a very simple performance class that extends dataobject and has a date for one of the fields but for some reason if I fill it out when I press 'Add' it just hangs. I've checked in the Chrome inspector and it fires off the Ajax request but the request never returns anything, I've even tried leaving it for a few minutes and still nothing returns and nothing gets puts in the error log either.
If I leave the date blank and just fill out the text field it works fine, here is the code I'm using.
class Performance extends DataObject {
static $db = array(
'Title' => 'Varchar(255)',
'StartDate' => 'Date',
);
static $summary_fields = array(
'Title' => 'Title',
'Starts' => 'StartDate',
);
static $has_one = array(
'Production' => 'ProductionPage'
);
}
What's really weird is if I grab the ArticlePage class from the extending Silverstripe tutorial it works fine, it's just if I try and do it with a DataObject rather than a page that I run into this.
Would really appreciate any help with this, I've been struggling with it for hours now.
Try the Legacydatetimefields module: http://www.silverstripe.org/legacydatetimefields-module/
There was a change of how Silverstripe handles date and time in the latest version (2.4) which means some older code dealing with date and time doesn't work.
Hope this helps.