Install Recurr via Composer
masterInstall the Recurr library using Composer to manage dependencies in your PHP project.
composer require simshaun/recurrrepository·master·Indexed 23 days ago
https://github.com/simshaun/recurrA PHP library for parsing and working with RFC 5545 recurrence rules (RRULEs). It allows developers to convert these rules into collections of DateTime objects or human-readable text. Key features include the Rule class for managing RRULE configurations, the ArrayTransformer for expanding rules into RecurrenceCollections, and the TextTransformer for generating human-readable strings.
Install the Recurr library using Composer to manage dependencies in your PHP project.
composer require simshaun/recurrTo expand an RRULE into actual occurrences, use the \Recurr\Transformer\ArrayTransformer.
transform($rule) on the transformer. It returns a RecurrenceCollection containing Recurrence objects.Recurrence object provides getStart() and getEnd() methods, which return \DateTime objects.getEnd() returns a \DateTime object equal to the start date.Note on Limits: The transformer has a default virtual limit of 732 objects to prevent infinite loops from infinite rules. You can adjust this limit by passing an ArrayTransformerConfig object to the ArrayTransformer via setConfig().
$transformer = new \Recurr\Transformer\ArrayTransformer();
print_r($transformer->transform($rule));By default, if a monthly rule starts on the 29th, 30th, or 31st, Recurr skips months that do not contain that day (e.g., Jan 31st + 1 month = March).
To fix this so that it uses the last available day of the month (e.g., Jan 31st + 1 month = Feb 28th), use ArrayTransformerConfig::enableLastDayOfMonthFix() and pass it to the transformer.
$timezone = 'America/New_York';
$startDate = new \DateTime('2013-01-31 20:00:00', new \DateTimeZone($timezone));
$rule = new \Recurr\Rule('FREQ=MONTHLY;COUNT=5', $startDate, null, $timezone);
$transformer = new \Recurr\Transformer\ArrayTransformer();
$transformerConfig = new \Recurr\Transformer\ArrayTransformerConfig();
$transformerConfig->enableLastDayOfMonthFix();
$transformer->setConfig($transformerConfig);
print_r($transformer->transform($rule));
// 2013-01-31, 2013-02-28, 2013-03-31, 2013-04-30, 2013-05-31The setByDay() method supports positional values (e.g., +1MO for the first Monday of the month, or -1FR for the last Friday).
Constraints:
BYDAY values only work with MONTHLY or YEARLY frequencies.-1MO) and non-positional (e.g., MO) values in the same BYDAY array.Recurr v6.0.0 introduces strict type declarations for all method parameters and return types.
Impact: If your code relied on loose type coercion when interacting with Recurr, it may now throw exceptions.
Action Required: Review any code that extends Recurr classes or heavily utilizes them to ensure your data types are compatible with the new strict signatures.
The TextTransformer (currently in beta) converts RRULEs into human-readable strings. It currently supports YEARLY, MONTHLY, WEEKLY, and DAILY frequencies.
You can localize the output by passing a \Recurr\Transformer\Translator with a specific locale to the TextTransformer constructor.
// English (default)
$rule = new Rule('FREQ=YEARLY;INTERVAL=2;COUNT=3;', new \DateTime());
$textTransformer = new TextTransformer();
echo $textTransformer->transform($rule);
// German
$textTransformer = new TextTransformer(
new \Recurr\Transformer\Translator('de')
);
echo $textTransformer->transform($rule);If you have implemented a custom TranslatorInterface, you must update the trans method signature to match the new requirements in v6.0.0. The method now requires strict type hints for the string parameter, an optional params array, and an explicit return type of string|array.
interface TranslatorInterface
{
public function trans(string $string, array $params = []): string|array;
}Constraints allow you to limit the dates generated by the ArrayTransformer during the transformation process. This is more efficient than filtering after the fact because dates that don't meet the constraint do not count toward the transformer's virtual limit.
Supported constraints:
AfterConstraint(\DateTime $after, $inc = false)BeforeConstraint(\DateTime $before, $inc = false)BetweenConstraint(\DateTime $after, \DateTime $before, $inc = false)The $inc parameter determines if the boundary date itself is included in the collection.
$startDate = new \DateTime('2014-06-17 04:00:00');
$rule = new \Recurr\Rule('FREQ=MONTHLY;COUNT=5', $startDate);
$transformer = new \Recurr\Transformer\ArrayTransformer();
$constraint = new \Recurr\Transformer\Constraint\BeforeConstraint(new \DateTime('2014-08-01 00:00:00'));
print_r($transformer->transform($rule, $constraint));A RecurrenceCollection (which extends Doctrine's ArrayCollection) provides chainable helper methods to filter occurrences after they have been transformed. Use these to narrow down results based on start or end times.
Available filters:
startsBetween(\DateTime $after, \DateTime $before, $inc = false)startsBefore(\DateTime $before, $inc = false)startsAfter(\DateTime $after, $inc = false)endsBetween(\DateTime $after, \DateTime $before, $inc = false)endsBefore(\DateTime $before, $inc = false)endsAfter(\DateTime $after, $inc = false)The $inc parameter determines if the boundary date is included.
You can instantiate a \Recurr\Rule object in two ways:
Use getString() to retrieve the resulting RRULE string.
$timezone = 'America/New_York';
$startDate = new \DateTime('2013-06-12 20:00:00', new \DateTimeZone($timezone));
$endDate = new \DateTime('2013-06-14 20:00:00', new \DateTimeZone($timezone)); // Optional
$rule = new \Recurr\Rule('FREQ=MONTHLY;COUNT=5', $startDate, $endDate, $timezone);
// Or using chained methods
$rule = (new \Recurr\Rule)
->setStartDate($startDate)
->setTimezone($timezone)
->setFreq('DAILY')
->setByDay(['MO', 'TU'])
->setUntil(new \DateTime('2017-12-31'));
echo $rule->getString(); //FREQ=DAILY;UNTIL=20171231T000000;BYDAY=MO,TU