Symfony4: Validate DateIntervalType - symfony

I am currently stuck on a probably very simple question.
How do I validate my DateIntervalType to be != 0 - meaning atleast something has been selected.
And how do I set a minimum/maximum: for example minimum interval of 1 day.
Background: I want to send an email every X years/months/days depending on the user select - an interval of 0 would mean permanent email sending, which I do not want.
Sadly I did not find anything helpful yet. Also tried integer assertations like #Assert\GratherThan etc. but that does not work.
Thanks in advance

Solution: Thanks to #Arleigh Hix for putting me on the right direction.
I solved my problem with following solution:
/**
* #Assert\Expression("this.checkInterval()")
*/
private $interval;
public function checkInterval() {
return $this->getTimestamp()->add($this->getInterval()) > $this->getTimestamp(); //getTimestamp() returns a DateTime
}
So basically just add the interval to any date and compare the new date to the initial date. With this way you can also get the difference in seconds and compare for min max values.
Better practise is probably to create a custom validator which will be my next step.

It looks you should be able to use an Expression constraint Maybe like this (I'm not sure about syntax for constructing the \DateInterval in the annotation)
/**
* #Assert\Expression(
* "value >= minimum",
* values = { "minimum": new \DateInterval('P1D') }
* )
*/
$dateIntervalField;
Alternatively, you should be able to set your minimum interval to an entity property and then compare value to that.
public function __construct()
{
$this->minInterval = new \DateInterval('P1D');
}
/**
* #Assert\GreaterThanOrEqual(
* value = this.minInterval
* )
*/
$dateIntervalField;

Related

Karate - locateAll filter and input field

Using Karate, according to Karate - is it possible to find element according to part of its parameter I have tried to do that using:
* def filter = function(x){ return x.attribute('placeholder').startsWith('Very') }
* def list = locateAll('input[placeholder]', filter)
But I have no idea how to use it for inserting the value. I have tried this:
* retry().input(list[0], '12312312311111')
and this:
* retry().input('list[0]', '12312312311111')
but neither worked.
Have you any idea what is wrong in syntax?
Thank you.
Whatever locate returns is an Element object. So you can call methods on it. Please read the documentation: https://github.com/intuit/karate/tree/master/karate-core#locate
So this should work:
* list[0].input('12312312311111')
* list[0].retry().input('12312312311111')

How to get Corda transaction time?

I am using the following to get the transaction timestamp:
val outputStateRef = StateRef(ledgerTx.id, 0)
val queryCriteria = QueryCriteria.VaultQueryCriteria(stateRefs = listOf(outputStateRef))
val results = serviceHub.vaultService.queryBy<ContractState>(queryCriteria)
val recordedTime = results.statesMetadata.singleOrNull()?.recordedTime
The problem is the transaction time is not always returned, sometimes null is returned for the timestamp.
Why is this happening and how can I ensure the timestamp is always returned?
results is Vault.Page<ContractState> which contains the following variables:
/**
* Returned in queries [VaultService.queryBy] and [VaultService.trackBy].
* A Page contains:
* 1) a [List] of actual [StateAndRef] requested by the specified [QueryCriteria] to a maximum of [MAX_PAGE_SIZE].
* 2) a [List] of associated [Vault.StateMetadata], one per [StateAndRef] result.
* 3) a total number of states that met the given [QueryCriteria] if a [PageSpecification] was provided,
* otherwise it defaults to -1.
* 4) Status types used in this query: [StateStatus.UNCONSUMED], [StateStatus.CONSUMED], [StateStatus.ALL].
* 5) Other results as a [List] of any type (eg. aggregate function results with/without group by).
*
* Note: currently otherResults are used only for Aggregate Functions (in which case, the states and statesMetadata
* results will be empty).
*/
As it looks from your code, if result page contains multiple StateAndRef, the method code singleOrNull()? will actually return null.
This is my guess based on available codes, please share more information if this wasnt the cause of the issue.
I would add your own timestamp to the state and record it in the flow.
Or, you can add a Time-Window to the transaction (https://docs.corda.net/api-transactions.html#time-windows). I believe this also ensures that the statesMetadata.recordedTime will not be null.

How to save a decimal number with Symfony2

I'm working on a Symfony2.3 project and I need an input number that lets me save the value with decimals and samples the arrows. With the following code I can show the decimals but then only the whole part is saved.
Entity
/**
*
* #ORM\Column(name="horas", type="decimal", scale=1)
* #Assert\NotBlank()
*/
private $hours;
FormType
->add('hours','integer', array('required' => true,'attr' => array('min' => 15,'max' => 40,'step' => 0.5)))
I appreciate your help.
To store a floating point value in a decimal field, you must first decide how many digits you need before the point, and how many after. For example, your field could look like this:
/**
* #ORM\Column(type="decimal", precision=3, scale=1)
* #Assert\Range(min=15, max=40)
*/
private $hours;
In a decimal field, the precision is always the total number of digits, while scale denotes the length of the fraction part. In the example above, the decimal field could store values between 0 and 99, while one digit after the point would be stored.
Note that Doctrine will represent the field as string, so if you retrieve the entity, the value of the field would be "20.5" (i.e. a string). You must manually convert the value to a float again. This can be done in the getter for the field:
public function getHours()
{
return (float) $this->hours;
}

Using VFreebusy iCalendar component

I making a scheduling application and I am using iCalendar format. I am aware that I can use this code to get the free time slots from current calendar:
DateTime start = new DateTime();
DateTime end = new DateTime(start.getTime() + 1000 * 60 * 60 * 24 * 7);
VFreeBusy request = new VFreeBusy(start, end, new Dur(0, 2, 0, 0));
VFreeBusy response = new VFreeBusy(request, myCalendar.getComponents());
And I get the following output from using this code on a couple of events in the calendar.
DTSTAMP:20140323T204423Z
DTSTART:20020202T040023Z
DTEND:20020203T040023Z
DURATION:PT45M
FREEBUSY;FBTYPE=FREE:20020202T040023Z/PT2H,20020202T070023Z/PT4H,20020202T120023Z/PT16H
END:VFREEBUSY
What I don't know is how to use that VFreeBusy object with those free time slots and actually get them out, so I can compare them and use them as dates and times.
I used response.getProperties().getProperty(Property.FREEBUSY) to get the part that I need, but I don't know how to parse all that String. If you have any other ways for me to get those time slots please advise.
Assuming that you are using ical4j. Once you get the property, you can cast it to a FreeBusy property which has a getPeriods() method.

ArrayCollection reverses order of my objects

I'll show you the function first.
private var areaCollection:ArrayCollection;
private function generateAreaCollection():void
{
areaCollection = new ArrayCollection();
areaCollection.addItem({Areal: "Totalareal:", Verdi: int(totalArea * 100) / 100 + " kvm"});
areaCollection.addItem({Areal: "Hovedtakets areal:", Verdi: int(result.area* 100) / 100 + " kvm"});
//Lots of other stuff omitted (just more addItems).
}
As you see, the order i put the items in the ArrayCollection is Areal, then Verdi (area, value)
When i loop through the collection later, the order changes. Now it is Verdi then Areal (value, area).
Does anyone have an idea of what might be the problem?
It really ruins things when I pass it over to a PHP-script for table-making in html later.
(I have several different dynamic DataGrids that differs in size and "values", so I can't really point directly to f.ex "Areal" in my PHP-script)
And by the way, does anyone know how i can remove that pesky mx_internal_uid?
Raw objects in AS3 (Object class, or things defined by {} ), have no sorting. That is, the order is unpredictable. You're confusing two ideas here I think. The Areal and Verdi strings are keys within an object map. The array collection is a list composed of two such objects. So any sorting applied to the array collection will sort those objects, but not within the object.
So you need to refer to areaCollection.source[0].Areal to get "Totalareal". And areaCollection.source[1].Verdi to get int(result.area* 100) / 100 + " kvm"
If you do for(var s:String in areaCollection.source[0]) { } you will iterate twice, with the value of "s" being "Areal" and "Verdi" or vice-versa (e.g, order not guaranteed).
Make sense? If you need order, you can make the object an array instead ["Totalareal", (int(totalArea * 100) / 100 + " kvm")], and then access "Verdi" using [1].
P.s. not sure how to remove the mx_internal_id.

Resources