Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
calendar-3296709
Manage
Activity
Members
Labels
Plan
Custom issue tracker
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Model registry
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Issue forks
calendar-3296709
Commits
78651228
Commit
78651228
authored
16 years ago
by
Karen Stevenson
Browse files
Options
Downloads
Patches
Plain Diff
#268669
Improve logic for splitting multi-day nodes across calendar dates, patch by emok.
parent
95a426c3
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
CHANGELOG.txt
+1
-0
1 addition, 0 deletions
CHANGELOG.txt
calendar.inc
+130
-45
130 additions, 45 deletions
calendar.inc
calendar_admin.inc
+17
-1
17 additions, 1 deletion
calendar_admin.inc
with
148 additions
and
46 deletions
CHANGELOG.txt
+
1
−
0
View file @
78651228
...
...
@@ -4,6 +4,7 @@ Views Calendar 5.x
Version 2.0 dev
===============
- #268669 Improve logic for splitting multi-day nodes across calendar dates, patch by emok.
- Add new DATE_FORMAT_DATE for date-only format that is used throughout the calendar.
- Make sure you can have arguments with summary views preceding the calendar.
- #258176 Make sure mini calendar links includes all other arguments.
...
...
This diff is collapsed.
Click to expand it.
calendar.inc
+
130
−
45
View file @
78651228
...
...
@@ -502,7 +502,22 @@ function calendar_build_field_query(&$query, $field) {
* and date field.
*/
function
calendar_build_nodes
(
&
$view
,
&
$items
)
{
global
$user
;
if
(
empty
(
$view
->
min_date
)
||
empty
(
$view
->
max_date
))
{
return
$items
;
}
// Midnights are determined based on the same timezone as the View uses
$display_timezone
=
date_timezone_get
(
$view
->
min_date
);
$display_timezone_name
=
timezone_name_get
(
$display_timezone
);
// Translate the view min and max dates to UTC values
// so we can compare UTC dates to the view range.
$min_utc
=
drupal_clone
(
$view
->
min_date
);
date_timezone_set
(
$min_utc
,
timezone_open
(
'UTC'
));
$max_utc
=
drupal_clone
(
$view
->
max_date
);
date_timezone_set
(
$max_utc
,
timezone_open
(
'UTC'
));
$min_zone_string
=
array
();
// Will cache $min_utc-strings in various timezones
$max_zone_string
=
array
();
$view
->
nodes_per_page
=
0
;
$type_names
=
node_get_types
(
'names'
);
...
...
@@ -516,28 +531,29 @@ function calendar_build_nodes(&$view, &$items) {
$nodes
=
array
();
$i
=
0
;
// Translate the view min and max dates to UTC values
// so we can compare UTC dates to the view range.
$min_utc
=
drupal_clone
(
$view
->
min_date
);
date_timezone_set
(
$min_utc
,
timezone_open
(
'UTC'
));
$max_utc
=
drupal_clone
(
$view
->
max_date
);
date_timezone_set
(
$max_utc
,
timezone_open
(
'UTC'
));
// explode out field and format info from the view
foreach
(
$view
->
field
as
$delta
=>
$data
)
{
if
(
$fields
[
$data
[
'id'
]][
'visible'
]
!==
FALSE
&&
array_key_exists
(
$data
[
'field'
],
$fields
))
{
if
(
in_array
(
$data
[
'field'
],
$field_names
))
{
$option
=
$fields
[
$data
[
'field'
]];
$field_type
=
strstr
(
$option
[
'type'
],
'string'
)
?
'string'
:
'timestamp'
;
$field_field
=
$option
[
'query_name'
];
$field_field_name
=
$option
[
'field_name'
];
$fromto
=
$option
[
'fromto'
];
$tz_handling
=
$option
[
'tz_handling'
];
$label
=
$data
[
'label'
];
$fromto_alias
=
array
(
str_replace
(
'.'
,
'_'
,
$fromto
[
0
]),
str_replace
(
'.'
,
'_'
,
$fromto
[
1
]));
if
(
strstr
(
$option
[
'type'
],
'cck'
))
{
$format
=
date_formatter_format
(
$data
[
'options'
],
$field_field_name
);
$field
=
$fields
[
$data
[
'field'
]];
$field_type
=
strstr
(
$field
[
'type'
],
'string'
)
?
'string'
:
'timestamp'
;
$tz_handling
=
$field
[
'tz_handling'
];
$label
=
$field
[
'label'
];
$fromto
=
$field
[
'fromto'
];
$fromto_alias
=
array
(
str_replace
(
'.'
,
'_'
,
$fromto
[
0
]),
str_replace
(
'.'
,
'_'
,
$fromto
[
1
]));
$tz_alias
=
str_replace
(
'.'
,
'_'
,
$field
[
'timezone_field'
]);
$db_tz
=
'UTC'
;
$local_tz
=
date_default_timezone_name
();
switch
(
$field
[
'tz_handling'
])
{
case
'none'
:
$db_tz
=
date_default_timezone_name
();
break
;
case
'date'
:
$local_tz
=
'date'
;
break
;
}
if
(
strstr
(
$field
[
'type'
],
'cck'
))
{
$format
=
date_formatter_format
(
$data
[
'options'
],
$field
[
'field_name'
]);
}
else
{
switch
(
$data
[
'handler'
])
{
...
...
@@ -559,33 +575,92 @@ function calendar_build_nodes(&$view, &$items) {
}
foreach
(
$items
as
$pos
=>
$item
)
{
// The query created from/to dates like 2007-12-31T01:30:00|2007-12-31T02:30:00,
// explode those values and separate them into from and to dates on the node.
if
(
$item
->
$field_field
)
{
if
(
isset
(
$item
->
{
$field
[
'query_name'
]}))
{
// Create from and to date values for each item, adjusted to
// the correct timezone.
$values
=
array
(
$item
->
$fromto_alias
[
0
],
$item
->
$fromto_alias
[
1
]);
if
(
$field_type
!=
'string'
)
{
$date
=
date_make_date
(
$values
[
0
],
'UTC'
,
DATE_UNIX
);
$values
[
0
]
=
date_format
(
$date
,
DATE_FORMAT_DATETIME
);
$date
=
date_make_date
(
$values
[
1
],
'UTC'
,
DATE_UNIX
);
$values
[
1
]
=
date_format
(
$date
,
DATE_FORMAT_DATETIME
);
$to_zone
=
$local_tz
;
if
(
$tz_handling
==
'date'
&&
!
empty
(
$item
->
$tz_alias
))
{
$to_zone
=
$item
->
$tz_alias
;
}
// NOTE: Now $display_timezone determines how $item is split
// into one entry per day, while $to_zone determines how date is displayed.
// Maybe someone wants to the date fields's timezone for the day splitting,
// then use: $display_timezone_name = $to_zone;
$values_display
=
array
();
// Start date
$date
=
date_make_date
(
$values
[
0
],
$db_tz
,
$field
[
'sql_type'
]);
if
(
$db_tz
!=
$to_zone
)
{
date_timezone_set
(
$date
,
timezone_open
(
$to_zone
));
}
$values
[
0
]
=
date_format
(
$date
,
DATE_FORMAT_DATETIME
);
if
(
$display_timezone_name
!=
$to_zone
)
{
date_timezone_set
(
$date
,
$display_timezone
);
$values_display
[
0
]
=
date_format
(
$date
,
DATE_FORMAT_DATETIME
);
}
else
{
$values
[
0
]
=
str_replace
(
'T'
,
' '
,
$values
[
0
]);
$values
[
1
]
=
str_replace
(
'T'
,
' '
,
$values
[
1
]);
$values_display
[
0
]
=
$values
[
0
];
}
// End date
$date
=
date_make_date
(
$values
[
1
],
$db_tz
,
$field
[
'sql_type'
]);
if
(
$db_tz
!=
$to_zone
)
{
date_timezone_set
(
$date
,
timezone_open
(
$to_zone
));
}
$values
[
1
]
=
date_format
(
$date
,
DATE_FORMAT_DATETIME
);
if
(
$display_timezone_name
!=
$to_zone
)
{
date_timezone_set
(
$date
,
$display_timezone
);
$values_display
[
1
]
=
date_format
(
$date
,
DATE_FORMAT_DATETIME
);
}
else
{
$values_display
[
1
]
=
$values
[
1
];
}
// Now $values contain start and end date of a node,
// expressed as strings in the display (local) timezone.
// $values_utc does the same in UTC timezone.
// Get calendar min and max day (not time) as strings in the
// $display_timezone. Cache in $min_zone_string and $max_zone_string,
// since many items or fields typically use the samee timezone.
if
(
!
isset
(
$min_zone_string
[
$display_timezone_name
]))
{
$date
=
drupal_clone
(
$view
->
min_date
);
date_timezone_set
(
$date
,
$display_timezone
);
$min_zone_string
[
$display_timezone_name
]
=
date_format
(
$date
,
'Y-m-d'
);
$date
=
drupal_clone
(
$view
->
max_date
);
date_timezone_set
(
$date
,
$display_timezone
);
$max_zone_string
[
$display_timezone_name
]
=
date_format
(
$date
,
'Y-m-d'
);
}
// Create a node for each date within the field's date range,
// limited to the view's date range.
$now
=
max
(
date_format
(
$min_utc
,
DATE_FORMAT_DATETIME
),
$values
[
0
]);
$to
=
min
(
date_format
(
$max_utc
,
DATE_FORMAT_DATETIME
),
$values
[
1
]);
$next
=
date_make_date
(
$now
,
'UTC'
);
// limited to the view's date range (regarding only day, not time).
$now
=
max
(
$min_zone_string
[
$display_timezone_name
],
substr
(
$values_display
[
0
],
0
,
10
));
$to
=
min
(
$max_zone_string
[
$display_timezone_name
],
substr
(
$values_display
[
1
],
0
,
10
));
$next
=
date_make_date
(
$now
,
$display_timezone
);
if
(
$display_timezone_name
!=
$to_zone
)
{
// Make $start and $end (derived from $node) use the timezone $to_zone, just as $values[..] do
date_timezone_set
(
$next
,
timezone_open
(
$to_zone
));
}
if
(
empty
(
$to
))
{
$to
=
$now
;
}
// $now and $next are midnight (in display timezone) on the first day where node will occur.
// $to is midnight on the last day where node will occur.
// All three were limited by the min-max date range of the view.
while
(
$now
<=
$to
)
{
$node
=
drupal_clone
(
$item
);
$node
->
title
=
$node
->
node_title
;
// Make sure the pseudo node has the same properties a
// regular node would have.
if
(
isset
(
$node
->
node_title
)
&&
!
isset
(
$node
->
title
))
{
$node
->
title
=
$node
->
node_title
;
}
if
(
isset
(
$node
->
node_type
)
&&
!
isset
(
$node
->
type
))
{
$node
->
type
=
$node
->
node_type
;
}
$node
->
label
=
$label
;
$node
->
format
=
$format
;
$node
->
format_time
=
variable_get
(
'calendar_time_format_'
.
$view
->
name
,
'H:i'
);
...
...
@@ -598,34 +673,44 @@ function calendar_build_nodes(&$view, &$items) {
// Flag which datefield this node is using, in case
// there are multiple date fields in the view.
$node
->
datefield
=
$field
_field
;
$node
->
datefield
=
$field
[
'query_name'
]
;
// If there are other datefields in the View, get rid
// of them in this pseudo node. There should only be one
// date in each calendar node.
foreach
(
$node
as
$key
=>
$val
)
{
if
(
$key
!=
$field
_field
&&
in_array
(
$key
,
$datefields
))
{
if
(
$key
!=
$field
[
'query_name'
]
&&
in_array
(
$key
,
$datefields
))
{
unset
(
$node
->
$key
);
}
}
// Get start and end of current day
$start
=
date_format
(
$next
,
DATE_FORMAT_DATETIME
);
date_modify
(
$next
,
'+1 day'
);
date_modify
(
$next
,
'-1 second'
);
$end
=
date_format
(
$next
,
DATE_FORMAT_DATETIME
);
// Get intersection of current day and the node value's duration (as strings in $to_zone timezone)
$node
->
calendar_start
=
$values
[
0
]
<
$start
?
$start
:
$values
[
0
];
$node
->
calendar_end
=
!
empty
(
$values
[
1
])
?
(
$values
[
1
]
>
$end
?
$end
:
$values
[
1
])
:
$node
->
calendar_start
;
$node
->
calendar_start_date
=
date_create
(
$node
->
calendar_start
,
timezone_open
(
'UTC'
));
$node
->
calendar_end_date
=
date_create
(
$node
->
calendar_end
,
timezone_open
(
'UTC'
));
// Make date objects
$node
->
calendar_start_date
=
date_create
(
$node
->
calendar_start
,
timezone_open
(
$to_zone
));
$node
->
calendar_end_date
=
date_create
(
$node
->
calendar_end
,
timezone_open
(
$to_zone
));
if
(
$tz_handling
!=
'utc'
&&
$tz_handling
!=
'none'
)
{
date_timezone_set
(
$node
->
calendar_start_date
,
date_default_timezone
());
date_timezone_set
(
$node
->
calendar_end_date
,
date_default_timezone
());
}
else
{
date_timezone_set
(
$node
->
calendar_start_date
,
timezone_open
(
'UTC'
));
date_timezone_set
(
$node
->
calendar_end_date
,
timezone_open
(
'UTC'
));
}
// Change string timezones into
// calendar_start and calendar_end are UTC dates as formatted strings
$node
->
calendar_start
=
date_format
(
$node
->
calendar_start_date
,
DATE_FORMAT_DATETIME
);
$node
->
calendar_end
=
date_format
(
$node
->
calendar_end_date
,
DATE_FORMAT_DATETIME
);
unset
(
$node
->
calendar_fields
);
if
(
isset
(
$node
)
&&
(
empty
(
$node
->
calendar_start
)))
{
// if no date for the node and no date in the item
// there is no way to display it on the calendar
...
...
@@ -633,20 +718,20 @@ function calendar_build_nodes(&$view, &$items) {
}
else
{
$delta
=
!
empty
(
$field
[
'delta_field'
])
&&
!
empty
(
$item
->
{
$field
[
'delta_field'
]})
?
$item
->
{
$field
[
'delta_field'
]}
:
0
;
$real_field
=
$field
_
field_name
;
$real_field
=
$field
[
'
field_name
'
]
;
if
(
substr
(
$field
[
'type'
],
0
,
3
)
==
'cck'
)
{
$real_field
=
str_replace
(
array
(
'_value2'
,
'_value'
),
''
,
$field
_
field_name
);
$real_field
=
str_replace
(
array
(
'_value2'
,
'_value'
),
''
,
$field
[
'
field_name
'
]
);
}
$id
=
'calendar:'
.
$item
->
nid
.
':'
.
$real_field
.
':'
.
$delta
.
':'
.
$pos
;
$node
->
date_id
=
$id
;
if
(
$view
->
build_type
==
'page'
&&
$view
->
calendar_type
!=
'year'
)
{
calendar_node_stripe
(
$view
,
$node
,
$field
_field
,
$field_field
);
calendar_node_stripe
(
$view
,
$node
,
$field
[
'query_name'
],
$field
[
'query_name'
]
);
}
$nodes
[]
=
$node
;
unset
(
$node
);
}
date_modify
(
$next
,
'+1 second'
);
$now
=
date_format
(
$next
,
DATE_FORMAT_DATETIME
);
$now
=
date_format
(
$next
,
'Y-m-d'
);
}
}
}
...
...
This diff is collapsed.
Click to expand it.
calendar_admin.inc
+
17
−
1
View file @
78651228
...
...
@@ -191,12 +191,28 @@ function _calendar_fields() {
$event_fields_processed
[]
=
$processed_name
;
}
// skip this step on second occurrence of fromto date fields, if more than one exists in view
// cck fields append a column name to the field, others do not
// need a real field_name with no column name appended for cck date formatters
switch
(
$type
)
{
case
'cck_string'
:
$sql_type
=
DATE_ISO
;
break
;
case
'cck_datetime'
:
$sql_type
=
DATE_DATETIME
;
break
;
default
:
$sql_type
=
DATE_UNIX
;
break
;
}
// skip this step on second occurrence of fromto date fields, if more than one exists in view
if
(
!
in_array
(
$processed_name
,
$event_fields_processed
)
||
$fromto
)
{
// cck fields append a column name to the field, others do not
// need a real field_name with no column name appended for cck date formatters
$fields
[
$tmp
[
1
]]
=
array
(
'type'
=>
$type
,
'sql_type'
=>
$sql_type
,
'delta'
=>
$delta
,
'label'
=>
$val
[
'name'
],
'fullname'
=>
$name
,
...
...
@@ -214,7 +230,7 @@ function _calendar_fields() {
}
}
}
cache_set
(
$cid
,
'cache_views'
,
serialize
(
$fields
));
//
cache_set($cid, 'cache_views', serialize($fields));
return
$fields
;
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment