Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions FieldtypeRecurringDatesRule.info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"title": "Recurring Dates Rule",
"version": "0.0.2",
"summary": "Field that stores recurring events from RRule input.",
"icon": "calendar-o",
"installs": "InputfieldRecurringDatesRule",
"requires": "ProcessWire>=3.0.184, AlpineJS"
}
255 changes: 255 additions & 0 deletions FieldtypeRecurringDatesRule.module
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
<?php namespace ProcessWire;

use DateTime;
use RRule\RRule;
use ProcessWire\Field;
use ProcessWire\Page;
use ProcessWire\DatabaseQuerySelect;
use ProcessWire\FieldtypeTextarea;


class FieldtypeRecurringDatesRule extends FieldtypeTextarea
{

/**
* Construct the Fieldtype, make sure all dependencies are in place
*
*/

public function __construct()
{

require_once(__DIR__ . '/RecurringDateRule.php');
require_once(__DIR__ . '/RecurringDateRuleSettings.php');
parent::__construct();
}

public function init(){
$urls = $this->config->versionUrls([
$this->config->urls->siteModules . 'FieldtypeRecurringDates/InputfieldRecurringDatesRule.js?v=123',
$this->config->urls->siteModules . 'FieldtypeRecurringDates/InputfieldRecurringDatesRule.css'
]);
$this->config->scripts->add($urls[0]);
$this->config->styles->add($urls[1]);
$this->addHook('/fieldtype-recurring-dates-rule/get-dates/', $this, 'hookGetDates');

}

public function ready(){
}


public function getRruleOcurrences($value)
{
$rrule = new RRule($value);
return $rrule;
}

public function hookGetDates($event)
{
$input = $event->input;
$page = $input->get->int('id');
$field = $input->get->int('field_id');
return [];
}

/**
* Return the database schema that defines an Occurrence
*
* @param Field $field
* @return array
*
*/
public function getDatabaseSchema(Field $field)
{
$schema = parent::getDatabaseSchema($field);
$schema['data'] = 'JSON NULL';
return $schema;
}

/**
* Return the Inputfield used to collect input for a field of this type
*
* @param Page $page
* @param Field $field
* @return Inputfield|InputfieldRecurringDates
*
*/
public function getInputfield(Page $page, Field $field)
{
$inputfield = $this->modules->get('InputfieldRecurringDatesRule');
/** @var InputfieldRecurringDates $inputfield */
return $inputfield;
}

/**
* Return a blank ready-to-populate value
*
* @param Page $page
* @param Field $field
* @return RecurringDate
*
*/
public function getBlankValue(Page $page, Field $field)
{
return new RecurringDateRule();
}

/**
* Given a value, make it clean and of the correct type for storage within a Page
*
* @param Page $page
* @param Field $field
* @param EventArray $value
* @return mixed
*
*/
public function sanitizeValue(Page $page, Field $field, $value)
{
// if given an invalid value, return a valid blank value
return $value;
}

protected function isSettingsValue($value)
{
$count = 0;
$keys = self::EXTRAS_TABLE_COLS;
foreach ($keys as $key) {
if (isset($value[$key]) || array_key_exists($key, $value)) {
$count++;
}
}

if ($count == 3) {
return true;
} else {
return false;
}
//if(array_key_exists(''))
}




/**
* Prepare a value for storage in the database
*
* @param Page $page
* @param Field $field
* @param mixed $value
* @return string
*
*/
public function ___sleepValue(Page $page, Field $field, $value)
{

if (!$value instanceof RecurringDateRule) {
return json_encode(null);
}
//bd((string) $value);
$rrule = $value->get('rrule');

$rruleData = null;
if ($rrule instanceof RRule) {
$rruleData = $rrule->getRule();
}

$data = array(
'rrule' => $rruleData,
'settings' => $value->settings
);
//bd($data);

return json_encode($data);
}

public function ___wakeupValue(Page $page, Field $field, $value)
{


$value = json_decode($value, true);

$recurring_date = $this->getBlankValue($page, $field);

if (empty($value)) {
return $recurring_date;
}

$recurring_date->settings = $value['settings'];
//bd($recurring_date);
if (!empty($value['rrule'])) {
$rrule = new RRule($value['rrule']);
$recurring_date->set('rrule', $rrule);
}
//return null;
//bd($recurring_date);
return $recurring_date;
}

/**
*
* @param Page $page
* @param Field $field
* @param array $value
* @return array
*
*/


/**
* Render a markup string of the value (optional for Fieldtypes to implement)
*
* @param Page $page
* @param Field $field
* @param EventArray $value
* @param string $property Property to render or omit for all
* @return string|MarkupFieldtype
*
*/

public function ___markupValue(Page $page, Field $field, $value = null, $property = '')
{
return $value;
}

public function getMonths()
{
$months = [];
for ($m = 1; $m <= 12; $m++) {
$months[] = date('F', mktime(0, 0, 0, $m, 1, date('Y')));
}
return $months;
}

public function getLoadQuery(Field $field, DatabaseQuerySelect $query)
{

return parent::getLoadQuery($field, $query);
}

/*
* TODO Implement properly.
* Known issue is blank value on selector throws an error. Normal date
* fields don't do this, so predictable behaviour like existing fields is desired
*/
public function isEmptyValue(Field $field, $value) {
return true;
}



/**
* Get selector info
*
* @param Field $field
* @param array $data
* @return array
*
*/
public function ___getSelectorInfo(Field $field, array $data = array()) {
$a = parent::___getSelectorInfo($field, $data);
$a['operators'] = array('=', '!=', '>', '>=', '<', '<=', '%=', '^=', '=""', '!=""');
return $a;
}

}
10 changes: 7 additions & 3 deletions InputfieldRecurringDates.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,13 @@ document.addEventListener('alpine:init', (e) => {
this.saveString();
});

var json_rrule = this.$refs['main-input'].dataset.rrule;
var widget_settings = this.$refs['main-input'].dataset.settings;
var mainInput = this.$refs['main-input'];
if (!mainInput) {
mainInput = this.$el.querySelector('[x-ref="main-input"]');
}

var json_rrule = mainInput ? mainInput.dataset.rrule : null;
var widget_settings = mainInput ? mainInput.dataset.settings : null;

if (widget_settings) {
this.settings = JSON.parse(widget_settings);
Expand Down Expand Up @@ -200,7 +205,6 @@ document.addEventListener('alpine:init', (e) => {
delete rrule_copy.UNTIL
rrule_copy.COUNT = this.hard_limit;
}
console.log(rrule_copy);
var json_string = JSON.stringify(rrule_copy);
if (this.$refs['pre-debug'] !== undefined) {
this.$refs['pre-debug'].innerText = JSON.stringify(rrule_copy, null, 2);
Expand Down
59 changes: 59 additions & 0 deletions InputfieldRecurringDatesRule.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
.InputfieldRecurringDatesRule [x-cloak] { display: none !important; }

.InputfieldRecurringDatesRule .bymonthday-filter-wrapper{
max-width: 280px;
}

.InputfieldRecurringDatesRule .bymonthday-grid-item{
width: calc(100% / 7);
}

.InputfieldRecurringDatesRule .bymonthday-grid-item:nth-child(7n + 1) .bymonthday-wrapper{
border-left:1px solid #efefef;
}
.InputfieldRecurringDatesRule .bymonthday-grid-item:nth-child(-n + 7) .bymonthday-wrapper{
border-top:1px solid #efefef;
}

.InputfieldRecurringDatesRule .bymonthday-wrapper{
border-right:1px solid #efefef;
border-bottom:1px solid #efefef;
width:40px;
height:40px;
display:block;
position:relative;
font-size:14px;
}

.InputfieldRecurringDatesRule .bymonthday-wrapper label{
line-height:40px;
text-align: center;
display:block;
position:relative;
}
.InputfieldRecurringDatesRule .bymonthday-wrapper .bymonth-checkbox-background{
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
}

.InputfieldRecurringDatesRule .bymonthday-wrapper input[type=checkbox]:checked + .bymonth-checkbox-background{
background-color:rgb(88,88,88);
color:white;
}

.InputfieldRecurringDatesRule .bymonthday-wrapper input[type=checkbox]{
width:30px;
height:30px;
display:block;
position:absolute;
top:0;
bottom:0;
left:0;
border:0;
opacity:0;
z-index:1;
}

Loading