Simple Calendar – Google Calendar Plugin - Version 0.6

Version Description

  • Drastically reduced memory usage
  • Improved feed data caching system
  • Improved error reporting
  • General performance and efficiency improvements
  • Added a few more shortcodes to the event display builder
  • Other miscellaneous changes / additions and bug fixes
Download this release

Release Info

Developer rosshanney
Plugin Icon 128x128 Simple Calendar – Google Calendar Plugin
Version 0.6
Comparing to
See all releases

Code changes from version 0.5 to 0.6

admin/add.php CHANGED
@@ -70,7 +70,9 @@ function gce_add_title_field(){
70
  //URL
71
  function gce_add_url_field(){
72
  ?>
73
- <span class="description"><?php _e('This will probably be something like: <code>http://www.google.com/calendar/feeds/your-email@gmail.com/public/full</code>.', GCE_TEXT_DOMAIN); ?></span>
 
 
74
  <br />
75
  <input type="text" name="gce_options[url]" size="100" class="required" />
76
  <?php
@@ -82,13 +84,13 @@ function gce_add_retrieve_from_field(){
82
  <span class="description"><?php _e('The point in time at which to start retrieving events. Use the text-box to specify an additional offset from you chosen start point. The offset should be provided in seconds (3600 = 1 hour, 86400 = 1 day) and can be negative. If you have selected the \'Specific date / time\' option, enter a <a href="http://www.timestampgenerator.com" target="_blank">UNIX timestamp</a> in the text-box.', GCE_TEXT_DOMAIN); ?></span>
83
  <br />
84
  <select name="gce_options[retrieve_from]">
85
- <option value="now">Now</option>
86
- <option value="today" selected="selected">00:00 today</option>
87
- <option value="week">Start of current week</option>
88
- <option value="month-start">Start of current month</option>
89
- <option value="month-end">End of current month</option>
90
- <option value="any">The beginning of time</option>
91
- <option value="date">Specific date / time</option>
92
  </select>
93
  <input type="text" name="gce_options[retrieve_from_value]" value="0" />
94
  <?php
@@ -100,13 +102,13 @@ function gce_add_retrieve_until_field(){
100
  <span class="description"><?php _e('The point in time at which to stop retrieving events. The instructions for the above option also apply here.', GCE_TEXT_DOMAIN); ?></span>
101
  <br />
102
  <select name="gce_options[retrieve_until]">
103
- <option value="now">Now</option>
104
- <option value="today">00:00 today</option>
105
- <option value="week">Start of current week</option>
106
- <option value="month-start">Start of current month</option>
107
- <option value="month-end">End of current month</option>
108
- <option value="any" selected="selected">The end of time</option>
109
- <option value="date">Specific date / time</option>
110
 
111
  </select>
112
  <input type="text" name="gce_options[retrieve_until_value]" value="0" />
@@ -185,8 +187,8 @@ function gce_add_use_builder_field(){
185
  <span class="description"><?php _e('It is recommended that you use the event display builder option, as it provides much more flexibility than the simple display options. The event display builder can do everything the simple display options can, plus lots more!', GCE_TEXT_DOMAIN); ?></span>
186
  <br />
187
  <select name="gce_options[use_builder]">
188
- <option value="true" selected="selected">Event display builder</option>
189
- <option value="false">Simple display options</option>
190
  </select>
191
  <?php
192
  }
@@ -194,7 +196,7 @@ function gce_add_use_builder_field(){
194
  //Event display builder
195
  function gce_add_builder_main_text(){
196
  ?>
197
- <p class="gce-event-builder">Use the event display builder to customize how event information will be displayed in the grid tooltips and in lists. Use HTML and the shortcodes (explained below) to display the information you require. A basic example display format is provided as a starting point. For more information, take a look at the <a href="http://www.rhanney.co.uk/plugins/google-calendar-events/event-display-builder" target="_blank">event display builder guide</a>.</p>
198
  <?php
199
  }
200
 
@@ -209,56 +211,60 @@ function gce_add_builder_field(){
209
  &lt;p&gt;[link newwindow="true"]More details...[/link]&lt;/p&gt;
210
  </textarea>
211
  <br />
212
- <p style="margin-top:20px;">(More information on all of the below shortcodes and attributes, and working examples, can be found in the <a href="http://www.rhanney.co.uk/plugins/google-calendar-events/event-display-builder" target="_blank">event display builder guide</a>)</p>
213
- <h4>Event information shortcodes:</h4>
214
  <ul>
215
- <li><code>[event-title]</code><span class="description"> - The event title (possible attributes: <code>html</code>, <code>markdown</code>)</span></li>
216
- <li><code>[start-time]</code><span class="description"> - The event start time. Will use the time format specified in the above settings</span></li>
217
- <li><code>[start-date]</code><span class="description"> - The event start date. Will use the date format specified in the above settings</span></li>
218
- <li><code>[start-custom]</code><span class="description"> - The event start date / time. Will use the format specified in the <code>format</code> attribute (possible attributes: <code>format</code>)</span></li>
219
- <li><code>[start-human]</code><span class="description"> - The difference between the start time of the event and the time now, in human-readable format, such as '1 hour', '4 days', '15 mins'</span></li>
220
- <li><code>[end-time]</code><span class="description"> - The event end time. Will use the time format specified in the above settings</span></li>
221
- <li><code>[end-date]</code><span class="description"> - The event end date. Will use the date format specified in the above settings</span></li>
222
- <li><code>[end-custom]</code><span class="description"> - The event end date / time. Will use the format specified in the <code>format</code> attribute (possible attributes: <code>format</code>)</span></li>
223
- <li><code>[end-human]</code><span class="description"> - The difference between the end time of the event and the time now, in human-readable format, such as '1 hour', '4 days', '15 mins'</span></li>
224
- <li><code>[location]</code><span class="description"> - The event location (possible attributes: <code>html</code>, <code>markdown</code>)</span></li>
225
- <li><code>[maps-link]&hellip;[/maps-link]</code><span class="description"> - Anything between the opening and closing shortcode tags (inlcuding further shortcodes) will be linked to Google Maps, using the event location as a search parameter (possible attributes: <code>newwindow</code>)</span></li>
226
- <li><code>[description]</code><span class="description"> - The event description (possible attributes: <code>html</code>, <code>markdown</code>, <code>limit</code>)</span></li>
227
- <li><code>[link]&hellip;[/link]</code><span class="description"> - Anything between the opening and closing shortcode tags (inlcuding further shortcodes) will be linked to the Google Calendar page for the event (possible attributes: <code>newwindow</code>)</span></li>
228
- <li><code>[link-path]</code><span class="description"> - The raw URL to the Google Calendar page for the event</span></li>
 
229
  </ul>
230
- <h4>Feed information shortcodes:</h4>
231
  <ul>
232
- <li><code>[feed-title]</code><span class="description"> - The title of the feed from which the event comes</span></li>
233
- <li><code>[feed-id]</code><span class="description"> - The ID of the feed from which the event comes</span></li>
234
  </ul>
235
- <h4>Conditional shortcodes:</h4>
236
- <p class="description" style="margin-bottom:18px;">Anything entered between the opening and closing tags of each of the following shortcodes will only be displayed if its condition (below) is met.</p>
237
  <ul>
238
- <li><code>[if-all-day]&hellip;[/if-all-day]</code><span class="description"> - The event is an all-day event</span></li>
239
- <li><code>[if-not-all-day]&hellip;[/if-not-all-day]</code><span class="description"> - The event is not an all-day event</span></li>
240
- <li><code>[if-title]&hellip;[/if-title]</code><span class="description"> - The event has a title</span></li>
241
- <li><code>[if-description]&hellip;[/if-description]</code><span class="description"> - The event has a description</span></li>
242
- <li><code>[if-location]&hellip;[/if-location]</code><span class="description"> - The event has a location</span></li>
243
- <li><code>[if-tooltip]&hellip;[/if-tooltip]</code><span class="description"> - The event is to be displayed in a tooltip (not a list)</span></li>
244
- <li><code>[if-list]&hellip;[/if-list]</code><span class="description"> - The event is to be displayed in a list (not a tooltip)</span></li>
245
- <li><code>[if-now]&hellip;[/if-now]</code><span class="description"> - The event is taking place now (after the start time, but before the end time)</span></li>
246
- <li><code>[if-not-now]&hellip;[/if-not-now]</code><span class="description"> - The event is not taking place now (may have ended or not yet started)</span></li>
247
- <li><code>[if-started]&hellip;[/if-started]</code><span class="description"> - The event has started (even if it has also ended)</span></li>
248
- <li><code>[if-not-started]&hellip;[/if-not-started]</code><span class="description"> - The event has not started</span></li>
249
- <li><code>[if-ended]&hellip;[/if-ended]</code><span class="description"> - The event has ended</span></li>
250
- <li><code>[if-not-ended]&hellip;[/if-not-ended]</code><span class="description"> - The event has not ended (even if it hasn't started)</span></li>
251
- <li><code>[if-first]&hellip;[/if-first]</code><span class="description"> - The event is the first of the day</span></li>
252
- <li><code>[if-not-first]&hellip;[/if-not-first]</code><span class="description"> - The event is not the first of the day</span></li>
 
 
253
  </ul>
254
- <h4>Attributes:</h4>
255
- <p class="description" style="margin-bottom:18px;">The possible attributes mentioned above are explained here:</p>
256
  <ul>
257
- <li><code>html</code><span class="description"> - Whether or not to parse HTML that has been entered in the relevant field. Can be <code>true</code> or <code>false</code></span></li>
258
- <li><code>markdown</code><span class="description"> - Whether or not parse <a href="http://daringfireball.net/projects/markdown" target="_blank">Markdown</a> that has been entered in the relevant field. <a href="http://michelf.com/projects/php-markdown" target="_blank">PHP Markdown</a> must be installed for this to work. Can be <code>true</code> or <code>false</code></span></li>
259
- <li><code>limit</code><span class="description"> - The word limit for the field. Should be specified as a positive integer</span></li>
260
- <li><code>format</code><span class="description"> - The date / time format to use. Should specified as a <a href="http://php.net/manual/en/function.date.php" target="_blank">PHP date format</a> string</span></li>
261
- <li><code>newwindow</code><span class="description"> - Whether or not the link should open in a new window / tab. Can be <code>true</code> or <code>false</code></span></li>
 
262
  </ul>
263
  <?php
264
  }
70
  //URL
71
  function gce_add_url_field(){
72
  ?>
73
+ <span class="description"><?php _e('This will probably be something like: <code>http://www.google.com/calendar/feeds/your-email@gmail.com/public/basic</code>.', GCE_TEXT_DOMAIN); ?></span>
74
+ <br />
75
+ <span class="description"><?php _e('or: <code>http://www.google.com/calendar/feeds/your-email@gmail.com/private-d65741b037h695ff274247f90746b2ty/basic</code>.', GCE_TEXT_DOMAIN); ?></span>
76
  <br />
77
  <input type="text" name="gce_options[url]" size="100" class="required" />
78
  <?php
84
  <span class="description"><?php _e('The point in time at which to start retrieving events. Use the text-box to specify an additional offset from you chosen start point. The offset should be provided in seconds (3600 = 1 hour, 86400 = 1 day) and can be negative. If you have selected the \'Specific date / time\' option, enter a <a href="http://www.timestampgenerator.com" target="_blank">UNIX timestamp</a> in the text-box.', GCE_TEXT_DOMAIN); ?></span>
85
  <br />
86
  <select name="gce_options[retrieve_from]">
87
+ <option value="now"><?php _e('Now', GCE_TEXT_DOMAIN); ?></option>
88
+ <option value="today" selected="selected"><?php _e('00:00 today', GCE_TEXT_DOMAIN); ?></option>
89
+ <option value="week"><?php _e('Start of current week', GCE_TEXT_DOMAIN); ?></option>
90
+ <option value="month-start"><?php _e('Start of current month', GCE_TEXT_DOMAIN); ?></option>
91
+ <option value="month-end"><?php _e('End of current month', GCE_TEXT_DOMAIN); ?></option>
92
+ <option value="any"><?php _e('The beginning of time', GCE_TEXT_DOMAIN); ?></option>
93
+ <option value="date"><?php _e('Specific date / time', GCE_TEXT_DOMAIN); ?></option>
94
  </select>
95
  <input type="text" name="gce_options[retrieve_from_value]" value="0" />
96
  <?php
102
  <span class="description"><?php _e('The point in time at which to stop retrieving events. The instructions for the above option also apply here.', GCE_TEXT_DOMAIN); ?></span>
103
  <br />
104
  <select name="gce_options[retrieve_until]">
105
+ <option value="now"><?php _e('Now', GCE_TEXT_DOMAIN); ?></option>
106
+ <option value="today"><?php _e('00:00 today', GCE_TEXT_DOMAIN); ?></option>
107
+ <option value="week"><?php _e('Start of current week', GCE_TEXT_DOMAIN); ?></option>
108
+ <option value="month-start"><?php _e('Start of current month', GCE_TEXT_DOMAIN); ?></option>
109
+ <option value="month-end"><?php _e('End of current month', GCE_TEXT_DOMAIN); ?></option>
110
+ <option value="any" selected="selected"><?php _e('The end of time', GCE_TEXT_DOMAIN); ?></option>
111
+ <option value="date"><?php _e('Specific date / time', GCE_TEXT_DOMAIN); ?></option>
112
 
113
  </select>
114
  <input type="text" name="gce_options[retrieve_until_value]" value="0" />
187
  <span class="description"><?php _e('It is recommended that you use the event display builder option, as it provides much more flexibility than the simple display options. The event display builder can do everything the simple display options can, plus lots more!', GCE_TEXT_DOMAIN); ?></span>
188
  <br />
189
  <select name="gce_options[use_builder]">
190
+ <option value="true" selected="selected"><?php _e('Event display builder', GCE_TEXT_DOMAIN); ?></option>
191
+ <option value="false"><?php _e('Simple display options', GCE_TEXT_DOMAIN); ?></option>
192
  </select>
193
  <?php
194
  }
196
  //Event display builder
197
  function gce_add_builder_main_text(){
198
  ?>
199
+ <p class="gce-event-builder"><?php _e('Use the event display builder to customize how event information will be displayed in the grid tooltips and in lists. Use HTML and the shortcodes (explained below) to display the information you require. A basic example display format is provided as a starting point. For more information, take a look at the <a href="http://www.rhanney.co.uk/plugins/google-calendar-events/event-display-builder" target="_blank">event display builder guide</a>.', GCE_TEXT_DOMAIN); ?></p>
200
  <?php
201
  }
202
 
211
  &lt;p&gt;[link newwindow="true"]More details...[/link]&lt;/p&gt;
212
  </textarea>
213
  <br />
214
+ <p style="margin-top:20px;"><?php _e('(More information on all of the below shortcodes and attributes, and working examples, can be found in the <a href="http://www.rhanney.co.uk/plugins/google-calendar-events/event-display-builder" target="_blank">event display builder guide</a>)', GCE_TEXT_DOMAIN); ?></p>
215
+ <h4><?php _e('Event information shortcodes:', GCE_TEXT_DOMAIN); ?></h4>
216
  <ul>
217
+ <li><code>[event-title]</code><span class="description"> - <?php _e('The event title (possible attributes: <code>html</code>, <code>markdown</code>)', GCE_TEXT_DOMAIN); ?></span></li>
218
+ <li><code>[start-time]</code><span class="description"> - <?php _e('The event start time. Will use the time format specified in the above settings', GCE_TEXT_DOMAIN); ?></span></li>
219
+ <li><code>[start-date]</code><span class="description"> - <?php _e('The event start date. Will use the date format specified in the above settings', GCE_TEXT_DOMAIN); ?></span></li>
220
+ <li><code>[start-custom]</code><span class="description"> - <?php _e('The event start date / time. Will use the format specified in the <code>format</code> attribute (possible attributes: <code>format</code>)', GCE_TEXT_DOMAIN); ?></span></li>
221
+ <li><code>[start-human]</code><span class="description"> - <?php _e('The difference between the start time of the event and the time now, in human-readable format, such as \'1 hour\', \'4 days\', \'15 mins\' (possible attributes: <code>precision</code>)', GCE_TEXT_DOMAIN); ?></span></li>
222
+ <li><code>[end-time]</code><span class="description"> - <?php _e('The event end time. Will use the time format specified in the above settings', GCE_TEXT_DOMAIN); ?></span></li>
223
+ <li><code>[end-date]</code><span class="description"> - <?php _e('The event end date. Will use the date format specified in the above settings', GCE_TEXT_DOMAIN); ?></span></li>
224
+ <li><code>[end-custom]</code><span class="description"> - <?php _e('The event end date / time. Will use the format specified in the <code>format</code> attribute (possible attributes: <code>format</code>)', GCE_TEXT_DOMAIN); ?></span></li>
225
+ <li><code>[end-human]</code><span class="description"> - <?php _e('The difference between the end time of the event and the time now, in human-readable format (possible attributes: <code>precision</code>)', GCE_TEXT_DOMAIN); ?></span></li>
226
+ <li><code>[location]</code><span class="description"> - <?php _e('The event location (possible attributes: <code>html</code>, <code>markdown</code>)', GCE_TEXT_DOMAIN); ?></span></li>
227
+ <li><code>[maps-link]&hellip;[/maps-link]</code><span class="description"> - <?php _e('Anything between the opening and closing shortcode tags (inlcuding further shortcodes) will be linked to Google Maps, using the event location as a search parameter (possible attributes: <code>newwindow</code>)', GCE_TEXT_DOMAIN); ?></span></li>
228
+ <li><code>[description]</code><span class="description"> - <?php _e('The event description (possible attributes: <code>html</code>, <code>markdown</code>, <code>limit</code>)', GCE_TEXT_DOMAIN); ?></span></li>
229
+ <li><code>[link]&hellip;[/link]</code><span class="description"> - <?php _e('Anything between the opening and closing shortcode tags (inlcuding further shortcodes) will be linked to the Google Calendar page for the event (possible attributes: <code>newwindow</code>)', GCE_TEXT_DOMAIN); ?></span></li>
230
+ <li><code>[link-path]</code><span class="description"> - <?php _e('The raw URL to the Google Calendar page for the event', GCE_TEXT_DOMAIN); ?></span></li>
231
+ <li><code>[length]</code><span class="description"> - <?php _e('The length of the event, in human-readable format (possible attributes: <code>precision</code>)', GCE_TEXT_DOMAIN); ?></span></li>
232
  </ul>
233
+ <h4><?php _e('Feed information shortcodes:', GCE_TEXT_DOMAIN); ?></h4>
234
  <ul>
235
+ <li><code>[feed-title]</code><span class="description"> - <?php _e('The title of the feed from which the event comes', GCE_TEXT_DOMAIN); ?></span></li>
236
+ <li><code>[feed-id]</code><span class="description"> - <?php _e('The ID of the feed from which the event comes', GCE_TEXT_DOMAIN); ?></span></li>
237
  </ul>
238
+ <h4><?php _e('Conditional shortcodes:', GCE_TEXT_DOMAIN); ?></h4>
239
+ <p class="description" style="margin-bottom:18px;"><?php _e('Anything entered between the opening and closing tags of each of the following shortcodes will only be displayed if its condition (below) is met.', GCE_TEXT_DOMAIN); ?></p>
240
  <ul>
241
+ <li><code>[if-all-day]&hellip;[/if-all-day]</code><span class="description"> - <?php _e('The event is an all-day event', GCE_TEXT_DOMAIN); ?></span></li>
242
+ <li><code>[if-not-all-day]&hellip;[/if-not-all-day]</code><span class="description"> - <?php _e('The event is not an all-day event', GCE_TEXT_DOMAIN); ?></span></li>
243
+ <li><code>[if-title]&hellip;[/if-title]</code><span class="description"> - <?php _e('The event has a title', GCE_TEXT_DOMAIN); ?></span></li>
244
+ <li><code>[if-description]&hellip;[/if-description]</code><span class="description"> - <?php _e('The event has a description', GCE_TEXT_DOMAIN); ?></span></li>
245
+ <li><code>[if-location]&hellip;[/if-location]</code><span class="description"> - <?php _e('The event has a location', GCE_TEXT_DOMAIN); ?></span></li>
246
+ <li><code>[if-tooltip]&hellip;[/if-tooltip]</code><span class="description"> - <?php _e('The event is to be displayed in a tooltip (not a list)', GCE_TEXT_DOMAIN); ?></span></li>
247
+ <li><code>[if-list]&hellip;[/if-list]</code><span class="description"> - <?php _e('The event is to be displayed in a list (not a tooltip)', GCE_TEXT_DOMAIN); ?></span></li>
248
+ <li><code>[if-now]&hellip;[/if-now]</code><span class="description"> - <?php _e('The event is taking place now (after the start time, but before the end time)', GCE_TEXT_DOMAIN); ?></span></li>
249
+ <li><code>[if-not-now]&hellip;[/if-not-now]</code><span class="description"> - <?php _e('The event is not taking place now (may have ended or not yet started)', GCE_TEXT_DOMAIN); ?></span></li>
250
+ <li><code>[if-started]&hellip;[/if-started]</code><span class="description"> - <?php _e('The event has started (even if it has also ended)', GCE_TEXT_DOMAIN); ?></span></li>
251
+ <li><code>[if-not-started]&hellip;[/if-not-started]</code><span class="description"> - <?php _e('The event has not started', GCE_TEXT_DOMAIN); ?></span></li>
252
+ <li><code>[if-ended]&hellip;[/if-ended]</code><span class="description"> - <?php _e('The event has ended', GCE_TEXT_DOMAIN); ?></span></li>
253
+ <li><code>[if-not-ended]&hellip;[/if-not-ended]</code><span class="description"> - <?php _e('The event has not ended (even if it hasn\'t started)', GCE_TEXT_DOMAIN); ?></span></li>
254
+ <li><code>[if-first]&hellip;[/if-first]</code><span class="description"> - <?php _e('The event is the first of the day', GCE_TEXT_DOMAIN); ?></span></li>
255
+ <li><code>[if-not-first]&hellip;[/if-not-first]</code><span class="description"> - <?php _e('The event is not the first of the day', GCE_TEXT_DOMAIN); ?></span></li>
256
+ <li><code>[if-multi-day]&hellip;[/if-multi-day]</code><span class="description"> - <?php _e('The event spans multiple days', GCE_TEXT_DOMAIN); ?></span></li>
257
+ <li><code>[if-single-day]&hellip;[/if-single-day]</code><span class="description"> - <?php _e('The event does not span multiple days', GCE_TEXT_DOMAIN); ?></span></li>
258
  </ul>
259
+ <h4><?php _e('Attributes:', GCE_TEXT_DOMAIN); ?></h4>
260
+ <p class="description" style="margin-bottom:18px;"><?php _e('The possible attributes mentioned above are explained here:', GCE_TEXT_DOMAIN); ?></p>
261
  <ul>
262
+ <li><code>html</code><span class="description"> - <?php _e('Whether or not to parse HTML that has been entered in the relevant field. Can be <code>true</code> or <code>false</code>', GCE_TEXT_DOMAIN); ?></span></li>
263
+ <li><code>markdown</code><span class="description"> - <?php _e('Whether or not to parse <a href="http://daringfireball.net/projects/markdown" target="_blank">Markdown</a> that has been entered in the relevant field. <a href="http://michelf.com/projects/php-markdown" target="_blank">PHP Markdown</a> must be installed for this to work. Can be <code>true</code> or <code>false</code>', GCE_TEXT_DOMAIN); ?></span></li>
264
+ <li><code>limit</code><span class="description"> - <?php _e('The word limit for the field. Should be specified as a positive integer', GCE_TEXT_DOMAIN); ?></span></li>
265
+ <li><code>format</code><span class="description"> - <?php _e('The date / time format to use. Should specified as a <a href="http://php.net/manual/en/function.date.php" target="_blank">PHP date format</a> string', GCE_TEXT_DOMAIN); ?></span></li>
266
+ <li><code>newwindow</code><span class="description"> - <?php _e('Whether or not the link should open in a new window / tab. Can be <code>true</code> or <code>false</code>', GCE_TEXT_DOMAIN); ?></span></li>
267
+ <li><code>precision</code><span class="description"> - <?php _e('How precise to be when displaying a time difference in human-readable format. Should be specified as a positive integer', GCE_TEXT_DOMAIN); ?></span></li>
268
  </ul>
269
  <?php
270
  }
admin/edit.php CHANGED
@@ -69,6 +69,8 @@ function gce_edit_url_field(){
69
  ?>
70
  <span class="description"><?php _e('This will probably be something like: <code>http://www.google.com/calendar/feeds/your-email@gmail.com/public/full</code>.', GCE_TEXT_DOMAIN); ?></span>
71
  <br />
 
 
72
  <input type="text" name="gce_options[url]" value="<?php echo $options['url']; ?>" size="100" />
73
  <?php
74
  }
@@ -200,8 +202,8 @@ function gce_edit_use_builder_field(){
200
  <span class="description"><?php _e('It is recommended that you use the event display builder option, as it provides much more flexibility than the simple display options. The event display builder can do everything the simple display options can, plus lots more!', GCE_TEXT_DOMAIN); ?></span>
201
  <br />
202
  <select name="gce_options[use_builder]">
203
- <option value="true"<?php selected($options['use_builder'], 'true'); ?>>Event display builder</option>
204
- <option value="false"<?php selected($options['use_builder'], 'false'); ?>>Simple display options</option>
205
  </select>
206
  <?php
207
  }
@@ -209,7 +211,7 @@ function gce_edit_use_builder_field(){
209
  //Event display builder
210
  function gce_edit_builder_main_text(){
211
  ?>
212
- <p class="gce-event-builder">Use the event display builder to customize how event information will be displayed in the grid tooltips and in lists. Use HTML and the shortcodes (explained below) to display the information you require. A basic example display format is provided as a starting point. For more information, take a look at the <a href="http://www.rhanney.co.uk/plugins/google-calendar-events/event-display-builder" target="_blank">event display builder guide</a>.</p>
213
  <?php
214
  }
215
 
@@ -219,56 +221,60 @@ function gce_edit_builder_field(){
219
  ?>
220
  <textarea name="gce_options[builder]" rows="10" cols="80"><?php echo $options['builder']; ?></textarea>
221
  <br />
222
- <p style="margin-top:20px;">(More information on all of the below shortcodes and attributes, and working examples, can be found in the <a href="http://www.rhanney.co.uk/plugins/google-calendar-events/event-display-builder" target="_blank">event display builder guide</a>)</p>
223
- <h4>Event information shortcodes:</h4>
224
  <ul>
225
- <li><code>[event-title]</code><span class="description"> - The event title (possible attributes: <code>html</code>, <code>markdown</code>)</span></li>
226
- <li><code>[start-time]</code><span class="description"> - The event start time. Will use the time format specified in the above settings</span></li>
227
- <li><code>[start-date]</code><span class="description"> - The event start date. Will use the date format specified in the above settings</span></li>
228
- <li><code>[start-custom]</code><span class="description"> - The event start date / time. Will use the format specified in the <code>format</code> attribute (possible attributes: <code>format</code>)</span></li>
229
- <li><code>[start-human]</code><span class="description"> - The difference between the start time of the event and the time now, in human-readable format, such as '1 hour', '4 days', '15 mins'</span></li>
230
- <li><code>[end-time]</code><span class="description"> - The event end time. Will use the time format specified in the above settings</span></li>
231
- <li><code>[end-date]</code><span class="description"> - The event end date. Will use the date format specified in the above settings</span></li>
232
- <li><code>[end-custom]</code><span class="description"> - The event end date / time. Will use the format specified in the <code>format</code> attribute (possible attributes: <code>format</code>)</span></li>
233
- <li><code>[end-human]</code><span class="description"> - The difference between the end time of the event and the time now, in human-readable format, such as '1 hour', '4 days', '15 mins'</span></li>
234
- <li><code>[location]</code><span class="description"> - The event location (possible attributes: <code>html</code>, <code>markdown</code>)</span></li>
235
- <li><code>[maps-link]&hellip;[/maps-link]</code><span class="description"> - Anything between the opening and closing shortcode tags (inlcuding further shortcodes) will be linked to Google Maps, using the event location as a search parameter (possible attributes: <code>newwindow</code>)</span></li>
236
- <li><code>[description]</code><span class="description"> - The event description (possible attributes: <code>html</code>, <code>markdown</code>, <code>limit</code>)</span></li>
237
- <li><code>[link]&hellip;[/link]</code><span class="description"> - Anything between the opening and closing shortcode tags (inlcuding further shortcodes) will be linked to the Google Calendar page for the event (possible attributes: <code>newwindow</code>)</span></li>
238
- <li><code>[link-path]</code><span class="description"> - The raw URL to the Google Calendar page for the event</span></li>
 
239
  </ul>
240
- <h4>Feed information shortcodes:</h4>
241
  <ul>
242
- <li><code>[feed-title]</code><span class="description"> - The title of the feed from which the event comes</span></li>
243
- <li><code>[feed-id]</code><span class="description"> - The ID of the feed from which the event comes</span></li>
244
  </ul>
245
- <h4>Conditional shortcodes:</h4>
246
- <p class="description" style="margin-bottom:18px;">Anything entered between the opening and closing tags of each of the following shortcodes will only be displayed if its condition (below) is met.</p>
247
  <ul>
248
- <li><code>[if-all-day]&hellip;[/if-all-day]</code><span class="description"> - The event is an all-day event</span></li>
249
- <li><code>[if-not-all-day]&hellip;[/if-not-all-day]</code><span class="description"> - The event is not an all-day event</span></li>
250
- <li><code>[if-title]&hellip;[/if-title]</code><span class="description"> - The event has a title</span></li>
251
- <li><code>[if-description]&hellip;[/if-description]</code><span class="description"> - The event has a description</span></li>
252
- <li><code>[if-location]&hellip;[/if-location]</code><span class="description"> - The event has a location</span></li>
253
- <li><code>[if-tooltip]&hellip;[/if-tooltip]</code><span class="description"> - The event is to be displayed in a tooltip (not a list)</span></li>
254
- <li><code>[if-list]&hellip;[/if-list]</code><span class="description"> - The event is to be displayed in a list (not a tooltip)</span></li>
255
- <li><code>[if-now]&hellip;[/if-now]</code><span class="description"> - The event is taking place now (after the start time, but before the end time)</span></li>
256
- <li><code>[if-not-now]&hellip;[/if-not-now]</code><span class="description"> - The event is not taking place now (may have ended or not yet started)</span></li>
257
- <li><code>[if-started]&hellip;[/if-started]</code><span class="description"> - The event has started (even if it has also ended)</span></li>
258
- <li><code>[if-not-started]&hellip;[/if-not-started]</code><span class="description"> - The event has not started</span></li>
259
- <li><code>[if-ended]&hellip;[/if-ended]</code><span class="description"> - The event has ended</span></li>
260
- <li><code>[if-not-ended]&hellip;[/if-not-ended]</code><span class="description"> - The event has not ended (even if it hasn't started)</span></li>
261
- <li><code>[if-first]&hellip;[/if-first]</code><span class="description"> - The event is the first of the day</span></li>
262
- <li><code>[if-not-first]&hellip;[/if-not-first]</code><span class="description"> - The event is not the first of the day</span></li>
 
 
263
  </ul>
264
- <h4>Attributes:</h4>
265
- <p class="description" style="margin-bottom:18px;">The possible attributes mentioned above are explained here:</p>
266
  <ul>
267
- <li><code>html</code><span class="description"> - Whether or not to parse HTML that has been entered in the relevant field. Can be <code>true</code> or <code>false</code></span></li>
268
- <li><code>markdown</code><span class="description"> - Whether or not parse <a href="http://daringfireball.net/projects/markdown" target="_blank">Markdown</a> that has been entered in the relevant field. <a href="http://michelf.com/projects/php-markdown" target="_blank">PHP Markdown</a> must be installed for this to work. Can be <code>true</code> or <code>false</code></span></li>
269
- <li><code>limit</code><span class="description"> - The word limit for the field. Should be specified as a positive integer</span></li>
270
- <li><code>format</code><span class="description"> - The date / time format to use. Should specified as a <a href="http://php.net/manual/en/function.date.php" target="_blank">PHP date format</a> string</span></li>
271
- <li><code>newwindow</code><span class="description"> - Whether or not the link should open in a new window / tab. Can be <code>true</code> or <code>false</code></span></li>
 
272
  </ul>
273
  <?php
274
  }
69
  ?>
70
  <span class="description"><?php _e('This will probably be something like: <code>http://www.google.com/calendar/feeds/your-email@gmail.com/public/full</code>.', GCE_TEXT_DOMAIN); ?></span>
71
  <br />
72
+ <span class="description"><?php _e('or: <code>http://www.google.com/calendar/feeds/your-email@gmail.com/private-d65741b037h695ff274247f90746b2ty/basic</code>.', GCE_TEXT_DOMAIN); ?></span>
73
+ <br />
74
  <input type="text" name="gce_options[url]" value="<?php echo $options['url']; ?>" size="100" />
75
  <?php
76
  }
202
  <span class="description"><?php _e('It is recommended that you use the event display builder option, as it provides much more flexibility than the simple display options. The event display builder can do everything the simple display options can, plus lots more!', GCE_TEXT_DOMAIN); ?></span>
203
  <br />
204
  <select name="gce_options[use_builder]">
205
+ <option value="true"<?php selected($options['use_builder'], 'true'); ?>><?php _e('Event display builder', GCE_TEXT_DOMAIN); ?></option>
206
+ <option value="false"<?php selected($options['use_builder'], 'false'); ?>><?php _e('Simple display options', GCE_TEXT_DOMAIN); ?></option>
207
  </select>
208
  <?php
209
  }
211
  //Event display builder
212
  function gce_edit_builder_main_text(){
213
  ?>
214
+ <p class="gce-event-builder"><?php _e('Use the event display builder to customize how event information will be displayed in the grid tooltips and in lists. Use HTML and the shortcodes (explained below) to display the information you require. A basic example display format is provided as a starting point. For more information, take a look at the <a href="http://www.rhanney.co.uk/plugins/google-calendar-events/event-display-builder" target="_blank">event display builder guide</a>.', GCE_TEXT_DOMAIN); ?></p>
215
  <?php
216
  }
217
 
221
  ?>
222
  <textarea name="gce_options[builder]" rows="10" cols="80"><?php echo $options['builder']; ?></textarea>
223
  <br />
224
+ <p style="margin-top:20px;"><?php _e('(More information on all of the below shortcodes and attributes, and working examples, can be found in the <a href="http://www.rhanney.co.uk/plugins/google-calendar-events/event-display-builder" target="_blank">event display builder guide</a>)', GCE_TEXT_DOMAIN); ?></p>
225
+ <h4><?php _e('Event information shortcodes:', GCE_TEXT_DOMAIN); ?></h4>
226
  <ul>
227
+ <li><code>[event-title]</code><span class="description"> - <?php _e('The event title (possible attributes: <code>html</code>, <code>markdown</code>)', GCE_TEXT_DOMAIN); ?></span></li>
228
+ <li><code>[start-time]</code><span class="description"> - <?php _e('The event start time. Will use the time format specified in the above settings', GCE_TEXT_DOMAIN); ?></span></li>
229
+ <li><code>[start-date]</code><span class="description"> - <?php _e('The event start date. Will use the date format specified in the above settings', GCE_TEXT_DOMAIN); ?></span></li>
230
+ <li><code>[start-custom]</code><span class="description"> - <?php _e('The event start date / time. Will use the format specified in the <code>format</code> attribute (possible attributes: <code>format</code>)', GCE_TEXT_DOMAIN); ?></span></li>
231
+ <li><code>[start-human]</code><span class="description"> - <?php _e('The difference between the start time of the event and the time now, in human-readable format, such as \'1 hour\', \'4 days\', \'15 mins\' (possible attributes: <code>precision</code>)', GCE_TEXT_DOMAIN); ?></span></li>
232
+ <li><code>[end-time]</code><span class="description"> - <?php _e('The event end time. Will use the time format specified in the above settings', GCE_TEXT_DOMAIN); ?></span></li>
233
+ <li><code>[end-date]</code><span class="description"> - <?php _e('The event end date. Will use the date format specified in the above settings', GCE_TEXT_DOMAIN); ?></span></li>
234
+ <li><code>[end-custom]</code><span class="description"> - <?php _e('The event end date / time. Will use the format specified in the <code>format</code> attribute (possible attributes: <code>format</code>)', GCE_TEXT_DOMAIN); ?></span></li>
235
+ <li><code>[end-human]</code><span class="description"> - <?php _e('The difference between the end time of the event and the time now, in human-readable format (possible attributes: <code>precision</code>)', GCE_TEXT_DOMAIN); ?></span></li>
236
+ <li><code>[location]</code><span class="description"> - <?php _e('The event location (possible attributes: <code>html</code>, <code>markdown</code>)', GCE_TEXT_DOMAIN); ?></span></li>
237
+ <li><code>[maps-link]&hellip;[/maps-link]</code><span class="description"> - <?php _e('Anything between the opening and closing shortcode tags (inlcuding further shortcodes) will be linked to Google Maps, using the event location as a search parameter (possible attributes: <code>newwindow</code>)', GCE_TEXT_DOMAIN); ?></span></li>
238
+ <li><code>[description]</code><span class="description"> - <?php _e('The event description (possible attributes: <code>html</code>, <code>markdown</code>, <code>limit</code>)', GCE_TEXT_DOMAIN); ?></span></li>
239
+ <li><code>[link]&hellip;[/link]</code><span class="description"> - <?php _e('Anything between the opening and closing shortcode tags (inlcuding further shortcodes) will be linked to the Google Calendar page for the event (possible attributes: <code>newwindow</code>)', GCE_TEXT_DOMAIN); ?></span></li>
240
+ <li><code>[link-path]</code><span class="description"> - <?php _e('The raw URL to the Google Calendar page for the event', GCE_TEXT_DOMAIN); ?></span></li>
241
+ <li><code>[length]</code><span class="description"> - <?php _e('The length of the event, in human-readable format (possible attributes: <code>precision</code>)', GCE_TEXT_DOMAIN); ?></span></li>
242
  </ul>
243
+ <h4><?php _e('Feed information shortcodes:', GCE_TEXT_DOMAIN); ?></h4>
244
  <ul>
245
+ <li><code>[feed-title]</code><span class="description"> - <?php _e('The title of the feed from which the event comes', GCE_TEXT_DOMAIN); ?></span></li>
246
+ <li><code>[feed-id]</code><span class="description"> - <?php _e('The ID of the feed from which the event comes', GCE_TEXT_DOMAIN); ?></span></li>
247
  </ul>
248
+ <h4><?php _e('Conditional shortcodes:', GCE_TEXT_DOMAIN); ?></h4>
249
+ <p class="description" style="margin-bottom:18px;"><?php _e('Anything entered between the opening and closing tags of each of the following shortcodes will only be displayed if its condition (below) is met.', GCE_TEXT_DOMAIN); ?></p>
250
  <ul>
251
+ <li><code>[if-all-day]&hellip;[/if-all-day]</code><span class="description"> - <?php _e('The event is an all-day event', GCE_TEXT_DOMAIN); ?></span></li>
252
+ <li><code>[if-not-all-day]&hellip;[/if-not-all-day]</code><span class="description"> - <?php _e('The event is not an all-day event', GCE_TEXT_DOMAIN); ?></span></li>
253
+ <li><code>[if-title]&hellip;[/if-title]</code><span class="description"> - <?php _e('The event has a title', GCE_TEXT_DOMAIN); ?></span></li>
254
+ <li><code>[if-description]&hellip;[/if-description]</code><span class="description"> - <?php _e('The event has a description', GCE_TEXT_DOMAIN); ?></span></li>
255
+ <li><code>[if-location]&hellip;[/if-location]</code><span class="description"> - <?php _e('The event has a location', GCE_TEXT_DOMAIN); ?></span></li>
256
+ <li><code>[if-tooltip]&hellip;[/if-tooltip]</code><span class="description"> - <?php _e('The event is to be displayed in a tooltip (not a list)', GCE_TEXT_DOMAIN); ?></span></li>
257
+ <li><code>[if-list]&hellip;[/if-list]</code><span class="description"> - <?php _e('The event is to be displayed in a list (not a tooltip)', GCE_TEXT_DOMAIN); ?></span></li>
258
+ <li><code>[if-now]&hellip;[/if-now]</code><span class="description"> - <?php _e('The event is taking place now (after the start time, but before the end time)', GCE_TEXT_DOMAIN); ?></span></li>
259
+ <li><code>[if-not-now]&hellip;[/if-not-now]</code><span class="description"> - <?php _e('The event is not taking place now (may have ended or not yet started)', GCE_TEXT_DOMAIN); ?></span></li>
260
+ <li><code>[if-started]&hellip;[/if-started]</code><span class="description"> - <?php _e('The event has started (even if it has also ended)', GCE_TEXT_DOMAIN); ?></span></li>
261
+ <li><code>[if-not-started]&hellip;[/if-not-started]</code><span class="description"> - <?php _e('The event has not started', GCE_TEXT_DOMAIN); ?></span></li>
262
+ <li><code>[if-ended]&hellip;[/if-ended]</code><span class="description"> - <?php _e('The event has ended', GCE_TEXT_DOMAIN); ?></span></li>
263
+ <li><code>[if-not-ended]&hellip;[/if-not-ended]</code><span class="description"> - <?php _e('The event has not ended (even if it hasn\'t started)', GCE_TEXT_DOMAIN); ?></span></li>
264
+ <li><code>[if-first]&hellip;[/if-first]</code><span class="description"> - <?php _e('The event is the first of the day', GCE_TEXT_DOMAIN); ?></span></li>
265
+ <li><code>[if-not-first]&hellip;[/if-not-first]</code><span class="description"> - <?php _e('The event is not the first of the day', GCE_TEXT_DOMAIN); ?></span></li>
266
+ <li><code>[if-multi-day]&hellip;[/if-multi-day]</code><span class="description"> - <?php _e('The event spans multiple days', GCE_TEXT_DOMAIN); ?></span></li>
267
+ <li><code>[if-single-day]&hellip;[/if-single-day]</code><span class="description"> - <?php _e('The event does not span multiple days', GCE_TEXT_DOMAIN); ?></span></li>
268
  </ul>
269
+ <h4><?php _e('Attributes:', GCE_TEXT_DOMAIN); ?></h4>
270
+ <p class="description" style="margin-bottom:18px;"><?php _e('The possible attributes mentioned above are explained here:', GCE_TEXT_DOMAIN); ?></p>
271
  <ul>
272
+ <li><code>html</code><span class="description"> - <?php _e('Whether or not to parse HTML that has been entered in the relevant field. Can be <code>true</code> or <code>false</code>', GCE_TEXT_DOMAIN); ?></span></li>
273
+ <li><code>markdown</code><span class="description"> - <?php _e('Whether or not to parse <a href="http://daringfireball.net/projects/markdown" target="_blank">Markdown</a> that has been entered in the relevant field. <a href="http://michelf.com/projects/php-markdown" target="_blank">PHP Markdown</a> must be installed for this to work. Can be <code>true</code> or <code>false</code>', GCE_TEXT_DOMAIN); ?></span></li>
274
+ <li><code>limit</code><span class="description"> - <?php _e('The word limit for the field. Should be specified as a positive integer', GCE_TEXT_DOMAIN); ?></span></li>
275
+ <li><code>format</code><span class="description"> - <?php _e('The date / time format to use. Should specified as a <a href="http://php.net/manual/en/function.date.php" target="_blank">PHP date format</a> string', GCE_TEXT_DOMAIN); ?></span></li>
276
+ <li><code>newwindow</code><span class="description"> - <?php _e('Whether or not the link should open in a new window / tab. Can be <code>true</code> or <code>false</code>', GCE_TEXT_DOMAIN); ?></span></li>
277
+ <li><code>precision</code><span class="description"> - <?php _e('How precise to be when displaying a time difference in human-readable format. Should be specified as a positive integer', GCE_TEXT_DOMAIN); ?></span></li>
278
  </ul>
279
  <?php
280
  }
admin/main.php CHANGED
@@ -44,7 +44,7 @@
44
  <td><?php echo $event['title']; ?></td>
45
  <td><?php echo $event['url']; ?></td>
46
  <td align="right">
47
- <a href="<?php echo admin_url('options-general.php?page=' . GCE_PLUGIN_NAME . '.php&action=edit&id=' . $key); ?>"><?php _e('Edit', GCE_TEXT_DOMAIN); ?></a>&nbsp;|&nbsp;<a href="<?php echo admin_url('options-general.php?page=' . GCE_PLUGIN_NAME . '.php&action=delete&id=' . $key); ?>"><?php _e('Delete', GCE_TEXT_DOMAIN); ?></a>
48
  </td>
49
  </tr>
50
  <?php } ?>
@@ -59,13 +59,12 @@
59
 
60
  <br />
61
  <h3><?php _e('General Options', GCE_TEXT_DOMAIN); ?></h3>
62
-
63
  <table class="form-table">
64
  <tr>
65
  <th scope="row"><?php _e('Custom stylesheet URL', GCE_TEXT_DOMAIN); ?></th>
66
  <td>
67
- <span class="description"><?php _e('If you want to make changes to the default CSS, make a copy of <code>google-calendar-events/css/gce-style.css</code> on your server. Make any
68
- changes to the copy. Enter the URL to the copied file below.', GCE_TEXT_DOMAIN); ?></span>
69
  <br />
70
  <input type="text" name="gce_general[stylesheet]" value="<?php echo $options['stylesheet']; ?>" size="100" />
71
  </td>
@@ -90,6 +89,13 @@
90
  <br />
91
  <input type="text" name="gce_general[error]" value="<?php echo $options['error']; ?>" size="100" />
92
  </td>
 
 
 
 
 
 
 
93
  </tr>
94
  </table>
95
 
44
  <td><?php echo $event['title']; ?></td>
45
  <td><?php echo $event['url']; ?></td>
46
  <td align="right">
47
+ <a href="<?php echo admin_url('options-general.php?page=' . GCE_PLUGIN_NAME . '.php&action=refresh&id=' . $key); ?>"><?php _e('Refresh', GCE_TEXT_DOMAIN); ?></a>&nbsp;|&nbsp;<a href="<?php echo admin_url('options-general.php?page=' . GCE_PLUGIN_NAME . '.php&action=edit&id=' . $key); ?>"><?php _e('Edit', GCE_TEXT_DOMAIN); ?></a>&nbsp;|&nbsp;<a href="<?php echo admin_url('options-general.php?page=' . GCE_PLUGIN_NAME . '.php&action=delete&id=' . $key); ?>"><?php _e('Delete', GCE_TEXT_DOMAIN); ?></a>
48
  </td>
49
  </tr>
50
  <?php } ?>
59
 
60
  <br />
61
  <h3><?php _e('General Options', GCE_TEXT_DOMAIN); ?></h3>
62
+
63
  <table class="form-table">
64
  <tr>
65
  <th scope="row"><?php _e('Custom stylesheet URL', GCE_TEXT_DOMAIN); ?></th>
66
  <td>
67
+ <span class="description"><?php _e('If you want to alter the default plugin styling, create a new stylesheet on your server (not in the <code>google-calendar-events</code> directory) and then enter its URL below.', GCE_TEXT_DOMAIN); ?></span>
 
68
  <br />
69
  <input type="text" name="gce_general[stylesheet]" value="<?php echo $options['stylesheet']; ?>" size="100" />
70
  </td>
89
  <br />
90
  <input type="text" name="gce_general[error]" value="<?php echo $options['error']; ?>" size="100" />
91
  </td>
92
+ </tr><tr>
93
+ <th scope="row"><?php _e('Optimise event retrieval?', GCE_TEXT_DOMAIN); ?></th>
94
+ <td>
95
+ <span class="description"><?php _e('If this option is enabled, the plugin will use an experimental feature of the Google Data API, which can improve performance significantly, especially with large numbers of events. Google could potentially remove / change this feature at any time.', GCE_TEXT_DOMAIN); ?></span>
96
+ <br />
97
+ <input type="checkbox" name="gce_general[fields]"<?php checked($options['fields'], true); ?> value="on" />
98
+ </td>
99
  </tr>
100
  </table>
101
 
admin/refresh.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //Redirect to the main plugin options page if form has been submitted
3
+ if(isset($_GET['action'])){
4
+ if($_GET['action'] == 'refresh' && isset($_GET['updated'])){
5
+ wp_redirect(admin_url('options-general.php?page=' . GCE_PLUGIN_NAME . '.php&updated=refreshed'));
6
+ }
7
+ }
8
+
9
+ add_settings_section('gce_refresh', __('Refresh Feed Cache', GCE_TEXT_DOMAIN), 'gce_refresh_main_text', 'refresh_feed');
10
+ //Unique ID //Title //Function //Page //Section ID
11
+ add_settings_field('gce_refresh_id_field', __('Feed ID', GCE_TEXT_DOMAIN), 'gce_refresh_id_field', 'refresh_feed', 'gce_refresh');
12
+ add_settings_field('gce_refresh_title_field', __('Feed Title', GCE_TEXT_DOMAIN), 'gce_refresh_title_field', 'refresh_feed', 'gce_refresh');
13
+
14
+ //Main text
15
+ function gce_refresh_main_text(){
16
+ ?>
17
+ <p><?php _e('The plugin will automatically refresh the cache when it expires, but you can manually clear the cache now by clicking the button below.', GCE_TEXT_DOMAIN); ?></p>
18
+ <p><?php _e('Are you want you want to clear the cache data for this feed?', GCE_TEXT_DOMAIN); ?></p>
19
+ <?php
20
+ }
21
+
22
+ //ID
23
+ function gce_refresh_id_field(){
24
+ $options = get_option(GCE_OPTIONS_NAME);
25
+ $options = $options[$_GET['id']];
26
+ ?>
27
+ <input type="text" disabled="disabled" value="<?php echo $options['id']; ?>" size="3" />
28
+ <input type="hidden" name="gce_options[id]" value="<?php echo $options['id']; ?>" />
29
+ <?php
30
+ }
31
+
32
+ //Title
33
+ function gce_refresh_title_field(){
34
+ $options = get_option(GCE_OPTIONS_NAME);
35
+ $options = $options[$_GET['id']];
36
+ ?>
37
+ <input type="text" name="gce_options[title]" disabled="disabled" value="<?php echo $options['title']; ?>" size="50" />
38
+ <?php
39
+ }
40
+ ?>
google-calendar-events.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Google Calendar Events
4
  Plugin URI: http://www.rhanney.co.uk/plugins/google-calendar-events
5
  Description: Parses Google Calendar feeds and displays the events as a calendar grid or list on a page, post or widget.
6
- Version: 0.5
7
  Author: Ross Hanney
8
  Author URI: http://www.rhanney.co.uk
9
  License: GPL2
@@ -13,9 +13,8 @@ License: GPL2
13
  Copyright 2010 Ross Hanney (email: rosshanney@gmail.com)
14
 
15
  This program is free software; you can redistribute it and/or modify
16
- it under the terms of the GNU General Public License as published by
17
- the Free Software Foundation; either version 2 of the License, or
18
- (at your option) any later version.
19
 
20
  This program is distributed in the hope that it will be useful,
21
  but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -24,37 +23,53 @@ GNU General Public License for more details.
24
 
25
  You should have received a copy of the GNU General Public License
26
  along with this program; if not, write to the Free Software
27
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
  */
29
 
30
  define('GCE_PLUGIN_NAME', str_replace('.php', '', basename(__FILE__)));
31
  define('GCE_TEXT_DOMAIN', 'google-calendar-events');
32
  define('GCE_OPTIONS_NAME', 'gce_options');
33
  define('GCE_GENERAL_OPTIONS_NAME', 'gce_general');
34
-
35
- require_once 'widget/gce-widget.php';
36
- require_once 'inc/gce-parser.php';
37
 
38
  if(!class_exists('Google_Calendar_Events')){
39
  class Google_Calendar_Events{
40
  function __construct(){
41
  add_action('activate_google-calendar-events/google-calendar-events.php', array($this, 'activate_plugin'));
42
  add_action('init', array($this, 'init_plugin'));
43
- add_action('admin_menu', array($this, 'setup_admin'));
44
- add_action('admin_init', array($this, 'init_admin'));
45
- add_action('wp_print_styles', array($this, 'add_styles'));
46
- add_action('wp_print_scripts', array($this, 'add_scripts'));
47
- add_action('widgets_init', create_function('', 'return register_widget("GCE_Widget");'));
48
  add_action('wp_ajax_gce_ajax', array($this, 'gce_ajax'));
49
  add_action('wp_ajax_nopriv_gce_ajax', array($this, 'gce_ajax'));
50
- add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this, 'add_settings_link'));
51
- add_shortcode('google-calendar-events', array($this, 'shortcode_handler'));
52
- add_shortcode('gce-start', array($this, 'boom'));
 
 
 
 
 
 
 
 
53
  }
54
 
55
- //If any new options have been added between versions, this will update any saved feeds with defaults for new options (shouldn't overwrite anything saved)
56
- //Will do the same for general options
57
  function activate_plugin(){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  add_option(GCE_OPTIONS_NAME);
59
  add_option(GCE_GENERAL_OPTIONS_NAME);
60
 
@@ -95,7 +110,14 @@ if(!class_exists('Google_Calendar_Events')){
95
  );
96
 
97
  //If necessary, copy saved behaviour of old show_past_events and day_limit options into the new from / until options
98
- if(isset($saved_feed_options['show_past_events']) && $saved_feed_options['show_past_events'] == 'true') $saved_feed_options['retrieve_from'] = 'month-start';
 
 
 
 
 
 
 
99
  if(isset($saved_feed_options['day_limit']) && $saved_feed_options['day_limit'] != ''){
100
  $saved_feed_options['retrieve_until'] = 'today';
101
  $saved_feed_options['retrieve_until_value'] = (int)$saved_feed_options['day_limit'] * 86400;
@@ -131,7 +153,8 @@ if(!class_exists('Google_Calendar_Events')){
131
  'stylesheet' => '',
132
  'javascript' => false,
133
  'loading' => 'Loading...',
134
- 'error' => 'Events cannot currently be displayed, sorry! Please check back later.'
 
135
  );
136
 
137
  $old_stylesheet_option = get_option('gce_stylesheet');
@@ -147,6 +170,7 @@ if(!class_exists('Google_Calendar_Events')){
147
  if(isset($options['javascript'])) $defaults['javascript'] = $options['javascript'];
148
  if(isset($options['loading'])) $defaults['loading'] = $options['loading'];
149
  if(isset($options['error'])) $defaults['error'] = $options['error'];
 
150
 
151
  //Save general options
152
  update_option(GCE_GENERAL_OPTIONS_NAME, $defaults);
@@ -176,6 +200,16 @@ if(!class_exists('Google_Calendar_Events')){
176
  <div id="icon-options-general" class="icon32"><br /></div>
177
 
178
  <h2><?php _e('Google Calendar Events', GCE_TEXT_DOMAIN); ?></h2>
 
 
 
 
 
 
 
 
 
 
179
  <form method="post" action="options.php" id="test-form">
180
  <?php
181
  if(isset($_GET['action']) && !isset($_GET['settings-updated'])){
@@ -187,7 +221,13 @@ if(!class_exists('Google_Calendar_Events')){
187
  do_settings_sections('add_display');
188
  do_settings_sections('add_builder');
189
  do_settings_sections('add_simple_display');
190
- ?><p class="submit"><input type="submit" class="button-primary submit" value="<?php _e('Add Feed', GCE_TEXT_DOMAIN); ?>" /></p>
 
 
 
 
 
 
191
  <p><a href="<?php echo admin_url('options-general.php?page=' . GCE_PLUGIN_NAME . '.php'); ?>" class="button-secondary"><?php _e('Cancel', GCE_TEXT_DOMAIN); ?></a></p><?php
192
  break;
193
  //Edit feed section
@@ -197,7 +237,7 @@ if(!class_exists('Google_Calendar_Events')){
197
  do_settings_sections('edit_display');
198
  do_settings_sections('edit_builder');
199
  do_settings_sections('edit_simple_display');
200
- ?><p class="submit"><input type="submit" class="button-primary submit" value="<?php _e('Save Changes', GCE_TEXT_DOMAIN); ?>" /></p>
201
  <p><a href="<?php echo admin_url('options-general.php?page=' . GCE_PLUGIN_NAME . '.php'); ?>" class="button-secondary"><?php _e('Cancel', GCE_TEXT_DOMAIN); ?></a></p><?php
202
  break;
203
  //Delete feed section
@@ -220,12 +260,55 @@ if(!class_exists('Google_Calendar_Events')){
220
 
221
  //Initialize admin stuff
222
  function init_admin(){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  register_setting('gce_options', 'gce_options', array($this, 'validate_feed_options'));
224
  register_setting('gce_general', 'gce_general', array($this, 'validate_general_options'));
225
 
226
  require_once 'admin/add.php';
227
  require_once 'admin/edit.php';
228
  require_once 'admin/delete.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  }
230
 
231
  //Check / validate submitted feed options data before being stored
@@ -234,8 +317,14 @@ if(!class_exists('Google_Calendar_Events')){
234
  $options = get_option(GCE_OPTIONS_NAME);
235
 
236
  if(isset($input['submit_delete'])){
237
- //If delete button was clicked, delete feed from options array
238
  unset($options[$input['id']]);
 
 
 
 
 
 
239
  }else{
240
  //Otherwise, validate options and add / update them
241
 
@@ -243,8 +332,8 @@ if(!class_exists('Google_Calendar_Events')){
243
  $id = absint($input['id']);
244
  //Escape title text
245
  $title = esc_html($input['title']);
246
- //Escape feed url. Replace https:// with http:// as SimplePie doesn't seem to support https:// Google Calendar feed URLs at present
247
- $url = str_replace('https://', 'http://', esc_url($input['url']));
248
 
249
  //Array of valid options for retrieve_from and retrieve_until settings
250
  $valid_retrieve_options = array('now', 'today', 'week', 'month-start', 'month-end', 'any', 'date');
@@ -336,6 +425,12 @@ if(!class_exists('Google_Calendar_Events')){
336
  'use_builder' => $use_builder,
337
  'builder' => $builder
338
  );
 
 
 
 
 
 
339
  }
340
 
341
  return $options;
@@ -349,10 +444,19 @@ if(!class_exists('Google_Calendar_Events')){
349
  $options['javascript'] = (isset($input['javascript']) ? true : false);
350
  $options['loading'] = esc_html($input['loading']);
351
  $options['error'] = wp_filter_kses($input['error']);
 
 
 
352
 
353
  return $options;
354
  }
355
 
 
 
 
 
 
 
356
  //Handles the shortcode stuff
357
  function shortcode_handler($atts){
358
  $options = get_option(GCE_OPTIONS_NAME);
@@ -410,13 +514,11 @@ if(!class_exists('Google_Calendar_Events')){
410
  function add_styles(){
411
  //Don't add styles if on admin screens
412
  if(!is_admin()){
413
- //If user has entered a URL to a custom stylesheet, use it. Otherwise use the default
 
 
414
  $options = get_option(GCE_GENERAL_OPTIONS_NAME);
415
- if(isset($options['stylesheet']) && ($options['stylesheet'] != '')){
416
- wp_enqueue_style('gce_styles', $options['stylesheet']);
417
- }else{
418
- wp_enqueue_style('gce_styles', WP_PLUGIN_URL . '/' . GCE_PLUGIN_NAME . '/css/gce-style.css');
419
- }
420
  }
421
  }
422
 
@@ -449,23 +551,35 @@ if(!class_exists('Google_Calendar_Events')){
449
  //The widget grid markup to be returned via AJAX
450
  gce_widget_content_grid($_GET['gce_feed_ids'], $_GET['gce_title_text'], $_GET['gce_max_events'], $_GET['gce_widget_id'], true, $_GET['gce_month'], $_GET['gce_year']);
451
  }
452
- die();
453
  }
 
454
  }
455
  }
456
  }
457
 
458
  function gce_print_list($feed_ids, $title_text, $max_events, $grouped = false){
 
 
 
 
459
  //Create new GCE_Parser object, passing array of feed id(s)
460
- $list = new GCE_Parser(explode('-', $feed_ids), $title_text, $max_events);
 
 
 
 
 
 
 
 
 
461
 
462
- //If the feed(s) parsed ok, return the list markup, otherwise return an error message
463
- if(count($list->get_errors()) == 0){
464
- return '<div class="gce-page-list">' . $list->get_list($grouped) . '</div>';
465
  }else{
466
- //If current user is an admin, display an error message explaining problem. Otherwise, display a 'nice' error messsage
467
  if(current_user_can('manage_options')){
468
- return sprintf(__('The following feeds were not parsed successfully: %s. Please check that the feed URLs are correct and that the feeds have public sharing enabled.'), implode(', ', $list->get_errors()));
469
  }else{
470
  $options = get_option(GCE_GENERAL_OPTIONS_NAME);
471
  return $options['error'];
@@ -474,21 +588,33 @@ function gce_print_list($feed_ids, $title_text, $max_events, $grouped = false){
474
  }
475
 
476
  function gce_print_grid($feed_ids, $title_text, $max_events, $ajaxified = false, $month = null, $year = null){
 
 
 
 
477
  //Create new GCE_Parser object, passing array of feed id(s) returned from gce_get_feed_ids()
478
- $grid = new GCE_Parser(explode('-', $feed_ids), $title_text, $max_events);
479
 
480
- //If the feed(s) parsed ok, return the grid markup, otherwise return an error message
481
- if(count($grid->get_errors()) == 0){
 
 
482
  $markup = '<div class="gce-page-grid" id="gce-page-grid-' . $feed_ids .'">';
483
 
484
  //Add AJAX script if required
485
  if($ajaxified) $markup .= '<script type="text/javascript">jQuery(document).ready(function($){gce_ajaxify("gce-page-grid-' . $feed_ids . '", "' . $feed_ids . '", "' . $max_events . '", "' . $title_text . '", "page");});</script>';
486
 
487
- return $markup . $grid->get_grid($year, $month, $ajaxified) . '</div>';
 
 
 
 
 
 
488
  }else{
489
  //If current user is an admin, display an error message explaining problem. Otherwise, display a 'nice' error messsage
490
  if(current_user_can('manage_options')){
491
- return sprintf(__('The following feeds were not parsed successfully: %s. Please check that the feed URLs are correct and that the feeds have public sharing enabled.'), implode(', ', $grid->get_errors()));
492
  }else{
493
  $options = get_option(GCE_GENERAL_OPTIONS_NAME);
494
  return $options['error'];
3
  Plugin Name: Google Calendar Events
4
  Plugin URI: http://www.rhanney.co.uk/plugins/google-calendar-events
5
  Description: Parses Google Calendar feeds and displays the events as a calendar grid or list on a page, post or widget.
6
+ Version: 0.6
7
  Author: Ross Hanney
8
  Author URI: http://www.rhanney.co.uk
9
  License: GPL2
13
  Copyright 2010 Ross Hanney (email: rosshanney@gmail.com)
14
 
15
  This program is free software; you can redistribute it and/or modify
16
+ it under the terms of the GNU General Public License, version 2, as
17
+ published by the Free Software Foundation.
 
18
 
19
  This program is distributed in the hope that it will be useful,
20
  but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 
24
  You should have received a copy of the GNU General Public License
25
  along with this program; if not, write to the Free Software
26
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
  */
28
 
29
  define('GCE_PLUGIN_NAME', str_replace('.php', '', basename(__FILE__)));
30
  define('GCE_TEXT_DOMAIN', 'google-calendar-events');
31
  define('GCE_OPTIONS_NAME', 'gce_options');
32
  define('GCE_GENERAL_OPTIONS_NAME', 'gce_general');
33
+ define('GCE_VERSION', 0.6);
 
 
34
 
35
  if(!class_exists('Google_Calendar_Events')){
36
  class Google_Calendar_Events{
37
  function __construct(){
38
  add_action('activate_google-calendar-events/google-calendar-events.php', array($this, 'activate_plugin'));
39
  add_action('init', array($this, 'init_plugin'));
 
 
 
 
 
40
  add_action('wp_ajax_gce_ajax', array($this, 'gce_ajax'));
41
  add_action('wp_ajax_nopriv_gce_ajax', array($this, 'gce_ajax'));
42
+ add_action('widgets_init', array($this, 'add_widget'));
43
+
44
+ //No point doing any of this if currently processing an AJAX request
45
+ if(!defined('DOING_AJAX') || !DOING_AJAX){
46
+ add_action('admin_menu', array($this, 'setup_admin'));
47
+ add_action('admin_init', array($this, 'init_admin'));
48
+ add_action('wp_print_styles', array($this, 'add_styles'));
49
+ add_action('wp_print_scripts', array($this, 'add_scripts'));
50
+ add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this, 'add_settings_link'));
51
+ add_shortcode('google-calendar-events', array($this, 'shortcode_handler'));
52
+ }
53
  }
54
 
55
+ //PHP 5.2 is required (json_decode), so if PHP version is lower then 5.2, display an error message and deactivate the plugin
 
56
  function activate_plugin(){
57
+ if(version_compare(PHP_VERSION, '5.2', '<')){
58
+ if(is_admin() && (!defined('DOING_AJAX') || !DOING_AJAX)){
59
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
60
+ deactivate_plugins(basename(__FILE__));
61
+ wp_die('Google Calendar Events requires the server on which your site resides to be running PHP 5.2 or higher. As of version 3.2, WordPress itself will also <a href="http://wordpress.org/news/2010/07/eol-for-php4-and-mysql4">have this requirement</a>. You should get in touch with your web hosting provider and ask them to update PHP.<br /><br /><a href="' . admin_url('plugins.php') . '">Back to Plugins</a>');
62
+ }
63
+ }
64
+ }
65
+
66
+ //If any new options have been added between versions, this will update any saved feeds with defaults for new options (shouldn't overwrite anything saved)
67
+ function update_settings(){
68
+ //If there are some plugin options in the database, but no version info, then this must be an upgrade from version 0.5 or below, so add flag that will provide user with option to clear old transients
69
+ if(get_option(GCE_OPTIONS_NAME) && !get_option('gce_version')) add_option('gce_clear_old_transients', true);
70
+
71
+ add_option('gce_version', GCE_VERSION);
72
+
73
  add_option(GCE_OPTIONS_NAME);
74
  add_option(GCE_GENERAL_OPTIONS_NAME);
75
 
110
  );
111
 
112
  //If necessary, copy saved behaviour of old show_past_events and day_limit options into the new from / until options
113
+ if(isset($saved_feed_options['show_past_events'])){
114
+ if($saved_feed_options['show_past_events'] == 'true'){
115
+ $saved_feed_options['retrieve_from'] = 'month-start';
116
+ }else{
117
+ $saved_feed_options['retrieve_from'] = 'today';
118
+ }
119
+ }
120
+
121
  if(isset($saved_feed_options['day_limit']) && $saved_feed_options['day_limit'] != ''){
122
  $saved_feed_options['retrieve_until'] = 'today';
123
  $saved_feed_options['retrieve_until_value'] = (int)$saved_feed_options['day_limit'] * 86400;
153
  'stylesheet' => '',
154
  'javascript' => false,
155
  'loading' => 'Loading...',
156
+ 'error' => 'Events cannot currently be displayed, sorry! Please check back later.',
157
+ 'fields' => true
158
  );
159
 
160
  $old_stylesheet_option = get_option('gce_stylesheet');
170
  if(isset($options['javascript'])) $defaults['javascript'] = $options['javascript'];
171
  if(isset($options['loading'])) $defaults['loading'] = $options['loading'];
172
  if(isset($options['error'])) $defaults['error'] = $options['error'];
173
+ if(isset($options['fields'])) $defaults['fields'] = $options['fields'];
174
 
175
  //Save general options
176
  update_option(GCE_GENERAL_OPTIONS_NAME, $defaults);
200
  <div id="icon-options-general" class="icon32"><br /></div>
201
 
202
  <h2><?php _e('Google Calendar Events', GCE_TEXT_DOMAIN); ?></h2>
203
+
204
+ <?php if(get_option('gce_clear_old_transients')): ?>
205
+ <div class="error">
206
+ <p><?php _e('<strong>Notice:</strong> The way in which Google Calendar Events stores cached data has been much improved in version 0.6. As you have upgraded from a previous version of the plugin, there is likely to be some data from the old caching system hanging around in your database that is now useless. Click below to clear expired cached data from your database.', GCE_TEXT_DOMAIN); ?></p>
207
+ <p><a href="<?php echo wp_nonce_url(add_query_arg(array('gce_action' => 'clear_old_transients')), 'gce_action_clear_old_transients'); ?>"><?php _e('Clear expired cached data', GCE_TEXT_DOMAIN); ?></a></p>
208
+ <p><?php _e('or', GCE_TEXT_DOMAIN); ?></p>
209
+ <p><a href="<?php echo wp_nonce_url(add_query_arg(array('gce_action' => 'ignore_old_transients')), 'gce_action_ignore_old_transients'); ?>"><?php _e('Ignore this notice', GCE_TEXT_DOMAIN); ?></a></p>
210
+ </div>
211
+ <?php endif; ?>
212
+
213
  <form method="post" action="options.php" id="test-form">
214
  <?php
215
  if(isset($_GET['action']) && !isset($_GET['settings-updated'])){
221
  do_settings_sections('add_display');
222
  do_settings_sections('add_builder');
223
  do_settings_sections('add_simple_display');
224
+ ?><p class="submit"><input type="submit" class="button-primary submit" name="gce_options[submit_add]" value="<?php _e('Add Feed', GCE_TEXT_DOMAIN); ?>" /></p>
225
+ <p><a href="<?php echo admin_url('options-general.php?page=' . GCE_PLUGIN_NAME . '.php'); ?>" class="button-secondary"><?php _e('Cancel', GCE_TEXT_DOMAIN); ?></a></p><?php
226
+ break;
227
+ case 'refresh':
228
+ settings_fields('gce_options');
229
+ do_settings_sections('refresh_feed');
230
+ ?><p class="submit"><input type="submit" class="button-primary submit" name="gce_options[submit_refresh]" value="<?php _e('Refresh Feed', GCE_TEXT_DOMAIN); ?>" /></p>
231
  <p><a href="<?php echo admin_url('options-general.php?page=' . GCE_PLUGIN_NAME . '.php'); ?>" class="button-secondary"><?php _e('Cancel', GCE_TEXT_DOMAIN); ?></a></p><?php
232
  break;
233
  //Edit feed section
237
  do_settings_sections('edit_display');
238
  do_settings_sections('edit_builder');
239
  do_settings_sections('edit_simple_display');
240
+ ?><p class="submit"><input type="submit" class="button-primary submit" name="gce_options[submit_edit]" value="<?php _e('Save Changes', GCE_TEXT_DOMAIN); ?>" /></p>
241
  <p><a href="<?php echo admin_url('options-general.php?page=' . GCE_PLUGIN_NAME . '.php'); ?>" class="button-secondary"><?php _e('Cancel', GCE_TEXT_DOMAIN); ?></a></p><?php
242
  break;
243
  //Delete feed section
260
 
261
  //Initialize admin stuff
262
  function init_admin(){
263
+ //If updating from a previous version, update the settings
264
+ $version = get_option('gce_version');
265
+ if(false === $version || $version < GCE_VERSION) $this->update_settings();
266
+
267
+ //If the message about old transients was displayed, check authority and intention, and then either clear transients or clear flag
268
+ if(isset($_GET['gce_action']) && current_user_can('manage_options')){
269
+ switch($_GET['gce_action']){
270
+ case 'clear_old_transients':
271
+ check_admin_referer('gce_action_clear_old_transients');
272
+ $this->clear_old_transients();
273
+ add_settings_error('gce_options', 'gce_cleared_old_transients', __('Old cached data cleared.', GCE_TEXT_DOMAIN), 'updated');
274
+ break;
275
+ case 'ignore_old_transients':
276
+ check_admin_referer('gce_action_ignore_old_transients');
277
+ delete_option('gce_clear_old_transients');
278
+ }
279
+ }
280
+
281
  register_setting('gce_options', 'gce_options', array($this, 'validate_feed_options'));
282
  register_setting('gce_general', 'gce_general', array($this, 'validate_general_options'));
283
 
284
  require_once 'admin/add.php';
285
  require_once 'admin/edit.php';
286
  require_once 'admin/delete.php';
287
+ require_once 'admin/refresh.php';
288
+ }
289
+
290
+ //Clears any expired transients from the database
291
+ function clear_old_transients(){
292
+ global $wpdb;
293
+
294
+ //Retrieve names of all transients
295
+ $transients = $wpdb->get_results("SELECT option_name FROM $wpdb->options WHERE option_name LIKE '%transient%' AND option_name NOT LIKE '%transient_timeout%'");
296
+
297
+ if(!empty($transients)){
298
+ foreach($transients as $transient){
299
+ //Attempt to retrieve the transient. If it has expired, it will be deleted
300
+ get_transient(str_replace('_transient_', '', $transient->option_name));
301
+ }
302
+ }
303
+
304
+ //Remove the flag
305
+ delete_option('gce_clear_old_transients');
306
+ }
307
+
308
+ //Register the widget
309
+ function add_widget(){
310
+ require_once 'widget/gce-widget.php';
311
+ return register_widget('GCE_Widget');
312
  }
313
 
314
  //Check / validate submitted feed options data before being stored
317
  $options = get_option(GCE_OPTIONS_NAME);
318
 
319
  if(isset($input['submit_delete'])){
320
+ //If delete button was clicked, delete feed from options array and remove associated transients
321
  unset($options[$input['id']]);
322
+ $this->delete_feed_transients((int)$input['id']);
323
+ add_settings_error('gce_options', 'gce_deleted', __(sprintf('Feed %s deleted.', absint($input['id'])), GCE_TEXT_DOMAIN), 'updated');
324
+ }else if(isset($input['submit_refresh'])){
325
+ //If refresh button was clicked, delete transients associated with feed
326
+ $this->delete_feed_transients((int)$input['id']);
327
+ add_settings_error('gce_options', 'gce_refreshed', __(sprintf('Cached data for feed %s cleared.', absint($input['id'])), GCE_TEXT_DOMAIN), 'updated');
328
  }else{
329
  //Otherwise, validate options and add / update them
330
 
332
  $id = absint($input['id']);
333
  //Escape title text
334
  $title = esc_html($input['title']);
335
+ //Escape feed url
336
+ $url = esc_url($input['url']);
337
 
338
  //Array of valid options for retrieve_from and retrieve_until settings
339
  $valid_retrieve_options = array('now', 'today', 'week', 'month-start', 'month-end', 'any', 'date');
425
  'use_builder' => $use_builder,
426
  'builder' => $builder
427
  );
428
+
429
+ if(isset($input['submit_add'])){
430
+ add_settings_error('gce_options', 'gce_added', __(sprintf('Feed %s added.', absint($input['id'])), GCE_TEXT_DOMAIN), 'updated');
431
+ }else{
432
+ add_settings_error('gce_options', 'gce_edited', __(sprintf('Settings for feed %s updated.', absint($input['id'])), GCE_TEXT_DOMAIN), 'updated');
433
+ }
434
  }
435
 
436
  return $options;
444
  $options['javascript'] = (isset($input['javascript']) ? true : false);
445
  $options['loading'] = esc_html($input['loading']);
446
  $options['error'] = wp_filter_kses($input['error']);
447
+ $options['fields'] = (isset($input['fields']) ? true : false);
448
+
449
+ add_settings_error('gce_general', 'gce_general_updated', __('General options updated.', GCE_TEXT_DOMAIN), 'updated');
450
 
451
  return $options;
452
  }
453
 
454
+ //Delete all transients (cached feed data) associated with feeds specified
455
+ function delete_feed_transients($id){
456
+ delete_transient('gce_feed_' . $id);
457
+ delete_transient('gce_feed_' . $id . '_url');
458
+ }
459
+
460
  //Handles the shortcode stuff
461
  function shortcode_handler($atts){
462
  $options = get_option(GCE_OPTIONS_NAME);
514
  function add_styles(){
515
  //Don't add styles if on admin screens
516
  if(!is_admin()){
517
+ wp_enqueue_style('gce_styles', WP_PLUGIN_URL . '/' . GCE_PLUGIN_NAME . '/css/gce-style.css');
518
+
519
+ //If user has entered a URL to a custom stylesheet, enqueue it too
520
  $options = get_option(GCE_GENERAL_OPTIONS_NAME);
521
+ if(isset($options['stylesheet']) && $options['stylesheet'] != '') wp_enqueue_style('gce_custom_styles', $options['stylesheet']);
 
 
 
 
522
  }
523
  }
524
 
551
  //The widget grid markup to be returned via AJAX
552
  gce_widget_content_grid($_GET['gce_feed_ids'], $_GET['gce_title_text'], $_GET['gce_max_events'], $_GET['gce_widget_id'], true, $_GET['gce_month'], $_GET['gce_year']);
553
  }
 
554
  }
555
+ die();
556
  }
557
  }
558
  }
559
 
560
  function gce_print_list($feed_ids, $title_text, $max_events, $grouped = false){
561
+ require_once 'inc/gce-parser.php';
562
+
563
+ $ids = explode('-', $feed_ids);
564
+
565
  //Create new GCE_Parser object, passing array of feed id(s)
566
+ $list = new GCE_Parser($ids, $title_text, $max_events);
567
+
568
+ $num_errors = $list->get_num_errors();
569
+
570
+ //If there are less errors than feeds parsed, at least one feed must have parsed successfully so continue to display the list
571
+ if($num_errors < count($ids)){
572
+ $markup = '<div class="gce-page-list">' . $list->get_list($grouped) . '</div>';
573
+
574
+ //If there was at least one error, return the list markup with error messages (for admins only)
575
+ if($num_errors > 0 && current_user_can('manage_options')) return $list->error_messages() . $markup;
576
 
577
+ //Otherwise just return the list markup
578
+ return $markup;
 
579
  }else{
580
+ //If current user is an admin, display an error message explaining problem(s). Otherwise, display a 'nice' error messsage
581
  if(current_user_can('manage_options')){
582
+ return $list->error_messages();
583
  }else{
584
  $options = get_option(GCE_GENERAL_OPTIONS_NAME);
585
  return $options['error'];
588
  }
589
 
590
  function gce_print_grid($feed_ids, $title_text, $max_events, $ajaxified = false, $month = null, $year = null){
591
+ require_once 'inc/gce-parser.php';
592
+
593
+ $ids = explode('-', $feed_ids);
594
+
595
  //Create new GCE_Parser object, passing array of feed id(s) returned from gce_get_feed_ids()
596
+ $grid = new GCE_Parser($ids, $title_text, $max_events);
597
 
598
+ $num_errors = $grid->get_num_errors();
599
+
600
+ //If there are less errors than feeds parsed, at least one feed must have parsed successfully so continue to display the grid
601
+ if($num_errors < count($ids)){
602
  $markup = '<div class="gce-page-grid" id="gce-page-grid-' . $feed_ids .'">';
603
 
604
  //Add AJAX script if required
605
  if($ajaxified) $markup .= '<script type="text/javascript">jQuery(document).ready(function($){gce_ajaxify("gce-page-grid-' . $feed_ids . '", "' . $feed_ids . '", "' . $max_events . '", "' . $title_text . '", "page");});</script>';
606
 
607
+ $markup .= $grid->get_grid($year, $month, $ajaxified) . '</div>';
608
+
609
+ //If there was at least one error, return the grid markup with an error message (for admins only)
610
+ if($num_errors > 0 && current_user_can('manage_options')) return $grid->error_messages() . $markup;
611
+
612
+ //Otherwise just return the grid markup
613
+ return $markup;
614
  }else{
615
  //If current user is an admin, display an error message explaining problem. Otherwise, display a 'nice' error messsage
616
  if(current_user_can('manage_options')){
617
+ return $grid->error_messages();
618
  }else{
619
  $options = get_option(GCE_GENERAL_OPTIONS_NAME);
620
  return $options['error'];
inc/gce-event.php ADDED
@@ -0,0 +1,407 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class GCE_Event{
3
+ private $title;
4
+ private $description;
5
+ private $location;
6
+ private $start_time;
7
+ private $end_time;
8
+ private $link;
9
+ private $type;
10
+ private $num_in_day;
11
+ private $feed;
12
+ private $day_type;
13
+
14
+ function __construct($title, $description, $location, $start_time, $end_time, $link){
15
+ $this->title = $title;
16
+ $this->description = $description;
17
+ $this->location = $location;
18
+ $this->start_time = $start_time;
19
+ $this->end_time = $end_time;
20
+ $this->link = $link;
21
+
22
+ //Calculate which day type this event is (SWD = single whole day, SPD = single part day, MWD = multiple whole day, MPD = multiple part day)
23
+ if(($start_time + 86400) <= $end_time){
24
+ if(($start_time + 86400) == $end_time){
25
+ $this->day_type = 'SWD';
26
+ }else{
27
+ if((date('g:i a', $start_time) == '12:00 am') && (date('g:i a', $end_time) == '12:00 am')){
28
+ $this->day_type = 'MWD';
29
+ }else{
30
+ $this->day_type = 'MPD';
31
+ }
32
+ }
33
+ }else{
34
+ $this->day_type = 'SPD';
35
+ }
36
+ }
37
+
38
+ function set_feed($feed){
39
+ $this->feed = $feed;
40
+ }
41
+
42
+ function get_feed(){
43
+ return $this->feed;
44
+ }
45
+
46
+ function get_start_time(){
47
+ return $this->start_time;
48
+ }
49
+
50
+ function get_end_time(){
51
+ return $this->end_time;
52
+ }
53
+
54
+ function get_day_type(){
55
+ return $this->day_type;
56
+ }
57
+
58
+ //Returns an array of days (as UNIX timestamps) that this events spans
59
+ function get_days(){
60
+ //Round start date to nearest day
61
+ $start_time = mktime(0, 0, 0, date('m', $this->start_time), date('d', $this->start_time) , date('Y', $this->start_time));
62
+
63
+ $days = array();
64
+
65
+ //If multiple day events should be handled, and this event is a multi-day event, add multiple day event to required days
66
+ if($this->feed->get_multi_day() && ($this->day_type == 'MPD' || $this->day_type == 'MWD')){
67
+ $on_next_day = true;
68
+ $next_day = $start_time;
69
+
70
+ while($on_next_day){
71
+ //If the end time of the event is after 00:00 on the next day (therefore, not doesn't end on this day)
72
+ if($this->end_time > $next_day){
73
+ //
74
+ if($next_day >= $this->feed->get_feed_start() && $next_day < $this->feed->get_feed_end()){
75
+ $days[] = $next_day;
76
+ }
77
+ }else{
78
+ $on_next_day = false;
79
+ }
80
+ $next_day += 86400;
81
+ }
82
+ }else{
83
+ //Add event into array of events for that day
84
+ $days[] = $start_time;
85
+ }
86
+
87
+ return $days;
88
+ }
89
+
90
+ //Returns the markup for this event, so that it can be used in the construction of a grid / list
91
+ function get_event_markup($display_type, $event_num){
92
+ //Set the display type (either tooltip or list)
93
+ $this->type = $display_type;
94
+
95
+ //Set which number event this is in day (first in day etc)
96
+ $this->num_in_day = $event_num;
97
+
98
+ //Use the builder or the old display options to create the markup, depending on user choice
99
+ if($this->feed->get_use_builder()) return $this->use_builder();
100
+ return $this->use_old_display_options();
101
+ }
102
+
103
+ //Return the event markup using the builder
104
+ function use_builder(){
105
+ //Array of valid shortcodes
106
+ $shortcodes =
107
+ 'event-title|' . //The event title
108
+ 'start-time|' . //The start time of the event (uses the time format from the feed options, if it is set. Otherwise uses the default WordPress time format)
109
+ 'start-date|' . //The start date of the event (uses the date format from the feed options, if it is set. Otherwise uses the default WordPress date format)
110
+ 'start-custom|' . //The start time / date of the event (uses a custom PHP date format, specified in the 'format' attribute)
111
+ 'start-human|' . //The difference between the start time of the event and the time now, in human-readable format, such as '1 hour', '4 days', '15 mins'
112
+ 'end-time|' . //The end time of the event (uses the time format from the feed options, if it is set. Otherwise uses the default WordPress time format)
113
+ 'end-date|' . //The end date of the event (uses the date format from the feed options, if it is set. Otherwise uses the default WordPress date format)
114
+ 'end-custom|' . //The end time / date of the event (uses a custom PHP date format, specified in the 'format' attribute)
115
+ 'end-human|' . //The difference between the end time of the event and the time now, in human-readable format, such as '1 hour', '4 days', '15 mins'
116
+ 'location|' . //The event location
117
+ 'description|' . //The event deescription (number of words can be limited by the 'limit' attribute)
118
+ 'link|' . //Anything within this shortcode (including further shortcodes) will be linked to the Google Calendar page for this event
119
+ 'link-path|' . //The raw link URL to the Google Calendar page for this event (can be used to construct more customized links)
120
+ 'feed-id|' . //The ID of this feed (Can be useful for constructing feed specific CSS classes)
121
+ 'feed-title|' . //The feed title
122
+ 'maps-link|' . //Anything within this shortcode (including further shortcodes) will be linked to a Google Maps page based on whatever is specified for the event location
123
+ 'length|' . //How long the events lasts, in human-readable format
124
+
125
+ //Anything between the opening and closing tags of the following logical shortcodes (including further shortcodes) will only be displayed if:
126
+
127
+ 'if-all-day|' . //This is an all-day event
128
+ 'if-not-all-day|' . //This is not an all-day event
129
+ 'if-title|' . //The event has a title
130
+ 'if-description|' . //The event has a description
131
+ 'if-location|' . //The event has a location
132
+ 'if-tooltip|' . //The current display type is 'tooltip'
133
+ 'if-list|' . //The current display type is 'list'
134
+ 'if-now|' . //The event is taking place now (after the start time, but before the end time)
135
+ 'if-not-now|' . //The event is not taking place now (may have ended or not yet started)
136
+ 'if-started|' . //The event has started (and even if it has ended)
137
+ 'if-not-started|' . //The event has not yet started
138
+ 'if-ended|' . //The event has ended
139
+ 'if-not-ended|' . //The event has not ended (and even if it hasn't started)
140
+ 'if-first|' . //The event is the first in the day
141
+ 'if-not-first|' . //The event is not the first in the day
142
+ 'if-multi-day|' . //The event spans multiple days
143
+ 'if-single-day'; //The event does not span multiple days
144
+
145
+ $markup = $this->feed->get_builder();
146
+
147
+ $count = 0;
148
+
149
+ //Go through the builder text looking for valid shortcodes. If one is found, send it to parse_shortcodes(). Once $count reaches 0, there are no un-parsed shortcodes
150
+ //left, so return the markup (which now contains all the appropriate event information)
151
+ do{
152
+ $markup = preg_replace_callback('/(.?)\[(' . $shortcodes . ')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)/s', array($this, 'parse_shortcode'), $markup, -1, $count);
153
+ }while($count > 0);
154
+
155
+ return $markup;
156
+ }
157
+
158
+ //Parse a shortcode, returning the appropriate event information
159
+ //Much of this code is 'borrowed' from WordPress' own shortcode handling stuff!
160
+ function parse_shortcode($m){
161
+ if($m[1] == '[' && $m[6] == ']' ) return substr($m[0], 1, -1);
162
+
163
+ //Extract any attributes contained in the shortcode
164
+ extract(shortcode_atts(array(
165
+ 'newwindow' => 'false',
166
+ 'format' => '',
167
+ 'limit' => '0',
168
+ 'html' => 'false',
169
+ 'markdown' => 'false',
170
+ 'precision' => '1'
171
+ ), shortcode_parse_atts($m[3])));
172
+
173
+ //Sanitize the attributes
174
+ $format = esc_attr($format);
175
+ $limit = absint($limit);
176
+ $precision = absint($precision);
177
+
178
+ //Do the appropriate stuff depending on which shortcode we're looking at. See valid shortcode list (above) for explanation of each shortcode
179
+ switch($m[2]){
180
+ case 'event-title':
181
+ $title = esc_html(trim($this->title));
182
+
183
+ //Handle markdown / HTML if required
184
+ if($markdown == 'true' && function_exists('Markdown')) $title = Markdown($title);
185
+ if($html == 'true') $title = wp_kses_post(html_entity_decode($title));
186
+
187
+ return $m[1] . $title . $m[6];
188
+ case 'start-time':
189
+ return $m[1] . date_i18n($this->feed->get_time_format(), $this->start_time) . $m[6];
190
+ case 'start-date':
191
+ return $m[1] . date_i18n($this->feed->get_date_format(), $this->start_time) . $m[6];
192
+ case 'start-custom':
193
+ return $m[1] . date_i18n($format, $this->start_time) . $m[6];
194
+ case 'start-human':
195
+ return $m[1] . $this->gce_human_time_diff($this->start_time, time(), $precision) . $m[6];
196
+ case 'end-time':
197
+ return $m[1] . date_i18n($this->feed->get_time_format(), $this->end_time) . $m[6];
198
+ case 'end-date':
199
+ return $m[1] . date_i18n($this->feed->get_date_format(), $this->end_time) . $m[6];
200
+ case 'end-custom':
201
+ return $m[1] . date_i18n($format, $this->end_time) . $m[6];
202
+ case 'end-human':
203
+ return $m[1] . $this->gce_human_time_diff($this->end_time, time(), $precision) . $m[6];
204
+ case 'location':
205
+ $location = esc_html(trim($this->location));
206
+
207
+ //Handle markdown / HTML if required
208
+ if($markdown == 'true' && function_exists('Markdown')) $location = Markdown($location);
209
+ if($html == 'true') $location = wp_kses_post(html_entity_decode($location));
210
+
211
+ return $m[1] . $location . $m[6];
212
+ case 'description':
213
+ $description = esc_html(trim($this->description));
214
+
215
+ //If a word limit has been set, trim the description to the required length
216
+ if($limit != 0){
217
+ preg_match('/([\S]+\s*){0,' . $limit . '}/', esc_html($this->description), $description);
218
+ $description = trim($description[0]);
219
+ }
220
+
221
+ if($markdown == 'true' || $html == 'true'){
222
+ //Handle markdown / HTML if required
223
+ if($markdown == 'true' && function_exists('Markdown')) $description = Markdown($description);
224
+ if($html == 'true') $description = wp_kses_post(html_entity_decode($description));
225
+ }else{
226
+ //Otherwise, preserve line breaks and make URLs into links
227
+ $description = make_clickable(nl2br($description));
228
+ }
229
+
230
+ return $m[1] . $description . $m[6];
231
+ case 'link':
232
+ $new_window = ($newwindow == 'true') ? ' target="_blank"' : '';
233
+ return $m[1] . '<a href="' . $this->link . '&ctz=' . $this->feed->get_timezone() . '"' . $new_window . '>' . $m[5] . '</a>' . $m[6];
234
+ case 'link-path':
235
+ return $m[1] . $this->link . '&ctz=' . $this->feed->get_timezone() . $m[6];
236
+ case 'feed-id':
237
+ return $m[1] . $this->feed->get_feed_id() . $m[6];
238
+ case 'feed-title':
239
+ return $m[1] . $this->feed->get_feed_title() . $m[6];
240
+ case 'maps-link':
241
+ $new_window = ($newwindow == 'true') ? ' target="_blank"' : '';
242
+ return $m[1] . '<a href="http://maps.google.com?q=' . urlencode($this->location) . '"' . $new_window . '>' . $m[5] . '</a>' . $m[6];
243
+ case 'length':
244
+ return $m[1] . $this->gce_human_time_diff($this->start_time, $this->end_time, $precision) . $m[6];
245
+ case 'if-all-day':
246
+ if($this->day_type == 'SWD' || $this->day_type == 'MWD') return $m[1] . $m[5] . $m[6];
247
+ return '';
248
+ case 'if-not-all-day':
249
+ if($this->day_type == 'SPD' || $this->day_type == 'MPD') return $m[1] . $m[5] . $m[6];
250
+ return '';
251
+ case 'if-title':
252
+ if($this->title != '') return $m[1] . $m[5] . $m[6];
253
+ return '';
254
+ case 'if-description':
255
+ if($this->description != '') return $m[1] . $m[5] . $m[6];
256
+ return '';
257
+ case 'if-location':
258
+ if($this->location != '') return $m[1] . $m[5] . $m[6];
259
+ return '';
260
+ case 'if-tooltip':
261
+ if($this->type == 'tooltip') return $m[1] . $m[5] . $m[6];
262
+ return '';
263
+ case 'if-list':
264
+ if($this->type == 'list') return $m[1] . $m[5] . $m[6];
265
+ return '';
266
+ case 'if-now':
267
+ if(time() >= $this->start_time && time() < $this->end_time) return $m[1] . $m[5] . $m[6];
268
+ return '';
269
+ case 'if-not-now':
270
+ if($this->end_time < time() || $this->start_time > time()) return $m[1] . $m[5] . $m[6];
271
+ return '';
272
+ case 'if-started':
273
+ if($this->start_time < time()) return $m[1] . $m[5] . $m[6];
274
+ return '';
275
+ case 'if-not-started':
276
+ if($this->start_time > time()) return $m[1] . $m[5] . $m[6];
277
+ return '';
278
+ case 'if-ended':
279
+ if($this->end_time < time()) return $m[1] . $m[5] . $m[6];
280
+ return '';
281
+ case 'if-not-ended':
282
+ if($this->end_time > time()) return $m[1] . $m[5] . $m[6];
283
+ return '';
284
+ case 'if-first':
285
+ if($this->num_in_day == 0) return $m[1] . $m[5] . $m[6];
286
+ return '';
287
+ case 'if-not-first':
288
+ if($this->num_in_day != 0) return $m[1] . $m[5] . $m[6];
289
+ return '';
290
+ case 'if-multi-day':
291
+ if($this->day_type == 'MPD' || $this->day_type == 'MWD') return $m[1] . $m[5] . $m[6];
292
+ return '';
293
+ case 'if-single-day':
294
+ if($this->day_type == 'SPD' || $this->day_type == 'SWD') return $m[1] . $m[5] . $m[6];
295
+ return '';
296
+ }
297
+ }
298
+
299
+ //Return the event markup using the old display options
300
+ function use_old_display_options(){
301
+ $display_options = $this->feed->get_display_options();
302
+
303
+ $markup = '<p class="gce-' . $this->type . '-event">' . esc_html($this->title) . '</p>';
304
+
305
+ $start_end = array();
306
+
307
+ //If start date / time should be displayed, set up array of start date and time
308
+ if($display_options['display_start'] != 'none'){
309
+ $sd = $this->start_time;
310
+ $start_end['start'] = array('time' => date_i18n($this->feed->get_time_format(), $sd), 'date' => date_i18n($this->feed->get_date_format(), $sd));
311
+ }
312
+
313
+ //If end date / time should be displayed, set up array of end date and time
314
+ if($display_options['display_end'] != 'none'){
315
+ $ed = $this->end_time;
316
+ $start_end['end'] = array('time' => date_i18n($this->feed->get_time_format(), $ed), 'date' => date_i18n($this->feed->get_date_format(), $ed));
317
+ }
318
+
319
+ //Add the correct start / end, date / time information to $markup
320
+ foreach($start_end as $start_or_end => $info){
321
+ $markup .= '<p class="gce-' . $this->type . '-' . $start_or_end . '"><span>' . $display_options['display_' . $start_or_end . '_text'] . '</span> ';
322
+
323
+ switch($display_options['display_' . $start_or_end]){
324
+ case 'time': $markup .= $info['time'];
325
+ break;
326
+ case 'date': $markup .= $info['date'];
327
+ break;
328
+ case 'time-date': $markup .= $info['time'] . $display_options['display_separator'] . $info['date'];
329
+ break;
330
+ case 'date-time': $markup .= $info['date'] . $display_options['display_separator'] . $info['time'];
331
+ }
332
+
333
+ $markup .= '</p>';
334
+ }
335
+
336
+ //If location should be displayed (and is not empty) add to $markup
337
+ if(isset($display_options['display_location'])){
338
+ $event_location = $this->location;
339
+ if($event_location != '') $markup .= '<p class="gce-' . $this->type . '-loc"><span>' . $display_options['display_location_text'] . '</span> ' . esc_html($event_location) . '</p>';
340
+ }
341
+
342
+ //If description should be displayed (and is not empty) add to $markup
343
+ if(isset($display_options['display_desc'])){
344
+ $event_desc = $this->description;
345
+
346
+ if($event_desc != ''){
347
+ //Limit number of words of description to display, if required
348
+ if($display_options['display_desc_limit'] != ''){
349
+ preg_match('/([\S]+\s*){0,' . $display_options['display_desc_limit'] . '}/', $this->description, $event_desc);
350
+ $event_desc = trim($event_desc[0]);
351
+ }
352
+
353
+ $markup .= '<p class="gce-' . $this->type . '-desc"><span>' . $display_options['display_desc_text'] . '</span> ' . make_clickable(nl2br(esc_html($event_desc))) . '</p>';
354
+ }
355
+ }
356
+
357
+ //If link should be displayed add to $markup
358
+ if(isset($display_options['display_link'])){ //Below: add target="_blank" if required
359
+ $markup .= '<p class="gce-' . $this->type . '-link"><a href="' . $this->link . '&amp;ctz=' . $this->feed->get_timezone() . '"' . (isset($display_options['display_link_target']) ? ' target="_blank"' : '') . '>' . $display_options['display_link_text'] . '</a></p>';
360
+ }
361
+
362
+ return $markup;
363
+ }
364
+
365
+ //Returns the difference between two times in human-readable format. Based on a patch for human_time_diff posted in the WordPress trac (http://core.trac.wordpress.org/ticket/9272) by Viper007Bond
366
+ function gce_human_time_diff($from, $to = '', $limit = 1){
367
+ $units = array(
368
+ 31556926 => array(__('%s year'), __('%s years')),
369
+ 2629744 => array(__('%s month'), __('%s months')),
370
+ 604800 => array(__('%s week'), __('%s weeks')),
371
+ 86400 => array(__('%s day'), __('%s days')),
372
+ 3600 => array(__('%s hour'), __('%s hours')),
373
+ 60 => array(__('%s min'), __('%s mins')),
374
+ );
375
+
376
+ if(empty($to)) $to = time();
377
+
378
+ $from = (int) $from;
379
+ $to = (int) $to;
380
+ $diff = (int) abs($to - $from);
381
+
382
+ $items = 0;
383
+ $output = array();
384
+
385
+ foreach($units as $unitsec => $unitnames){
386
+ if($items >= $limit) break;
387
+
388
+ if($diff < $unitsec) continue;
389
+
390
+ $numthisunits = floor($diff / $unitsec);
391
+ $diff = $diff - ($numthisunits * $unitsec);
392
+ $items++;
393
+
394
+ if($numthisunits > 0) $output[] = sprintf(_n($unitnames[0], $unitnames[1], $numthisunits), $numthisunits);
395
+ }
396
+
397
+ $seperator = _x(', ', 'human_time_diff');
398
+
399
+ if(!empty($output)){
400
+ return implode($seperator, $output);
401
+ }else{
402
+ $smallest = array_pop($units);
403
+ return sprintf($smallest[0], 1);
404
+ }
405
+ }
406
+ }
407
+ ?>
inc/gce-feed.php CHANGED
@@ -1,70 +1,188 @@
1
  <?php
2
- require_once(ABSPATH . WPINC . '/class-feed.php');
3
- if(!class_exists('SimplePie_GCalendar')) require_once('simplepie-gcalendar.php');
4
-
5
- class GCE_Feed extends SimplePie_GCalendar{
6
- private $feed_id;
7
- private $feed_title;
8
- private $d_format;
9
- private $t_format;
10
- private $display_opts;
11
- private $multi_day;
12
- private $feed_start;
13
- private $use_builder;
14
- private $builder;
15
-
16
- function __construct(){
17
- parent::__construct();
18
- $this->set_cache_class('WP_Feed_Cache');
19
- $this->set_file_class('WP_SimplePie_File');
20
- }
21
 
22
  function init(){
23
- parent::init();
24
- $this->set_item_class('GCE_Event');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  }
26
 
27
  //Setters
28
 
29
- function set_feed_id($id){
30
- $this->feed_id = $id;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  }
32
 
33
- function set_feed_title($title){
34
- $this->feed_title = $title;
35
  }
36
 
37
- function set_date_format($format_string){
38
- $this->d_format = $format_string;
39
  }
40
 
41
- function set_time_format($format_string){
42
- $this->t_format = $format_string;
43
  }
44
 
45
- function set_display_options($display_options){
46
- $this->display_opts = $display_options;
47
  }
48
 
49
- function set_multi_day($multiple_day){
50
- $this->multi_day = $multiple_day;
51
  }
52
 
53
- function set_start_date($start_date){
54
- $this->feed_start = $start_date;
55
- parent::set_start_date($start_date);
56
  }
57
 
58
- function set_use_builder($b){
59
- $this->use_builder = $b;
60
  }
61
 
62
- function set_builder($b){
63
- $this->builder = $b;
64
  }
65
 
66
  //Getters
67
 
 
 
 
 
68
  function get_feed_id(){
69
  return $this->feed_id;
70
  }
@@ -74,11 +192,11 @@ class GCE_Feed extends SimplePie_GCalendar{
74
  }
75
 
76
  function get_date_format(){
77
- return $this->d_format;
78
  }
79
 
80
  function get_time_format(){
81
- return $this->t_format;
82
  }
83
 
84
  function get_display_options(){
@@ -89,10 +207,14 @@ class GCE_Feed extends SimplePie_GCalendar{
89
  return $this->multi_day;
90
  }
91
 
92
- function get_start_date(){
93
  return $this->feed_start;
94
  }
95
 
 
 
 
 
96
  function get_timezone(){
97
  return $this->timezone;
98
  }
@@ -105,278 +227,4 @@ class GCE_Feed extends SimplePie_GCalendar{
105
  return $this->builder;
106
  }
107
  }
108
-
109
- class GCE_Event extends SimplePie_Item_GCalendar{
110
- private $type;
111
- private $num_in_day;
112
-
113
- //Returns the markup for this event, so that it can be used in the construction of a grid / list
114
- function get_event_markup($display_type, $event_num){
115
- //Set the display type (either tooltip or list)
116
- $this->type = $display_type;
117
-
118
- //Set which number event this is in day (first in day etc)
119
- $this->num_in_day = $event_num;
120
-
121
- //Use the builder or the old display options to create the markup, depending on user choice
122
- if($this->get_feed()->get_use_builder()) return $this->use_builder();
123
- return $this->use_old_display_options();
124
- }
125
-
126
- //Return the event markup using the builder
127
- function use_builder(){
128
- //Array of valid shortcodes
129
- $shortcodes =
130
- 'event-title|' . //The event title
131
- 'start-time|' . //The start time of the event (uses the time format from the feed options, if it is set. Otherwise uses the default WordPress time format)
132
- 'start-date|' . //The start date of the event (uses the date format from the feed options, if it is set. Otherwise uses the default WordPress date format)
133
- 'start-custom|' . //The start time / date of the event (uses a custom PHP date format, specified in the 'format' attribute)
134
- 'start-human|' . //The difference between the start time of the event and the time now, in human-readable format, such as '1 hour', '4 days', '15 mins'
135
- 'end-time|' . //The end time of the event (uses the time format from the feed options, if it is set. Otherwise uses the default WordPress time format)
136
- 'end-date|' . //The end date of the event (uses the date format from the feed options, if it is set. Otherwise uses the default WordPress date format)
137
- 'end-custom|' . //The end time / date of the event (uses a custom PHP date format, specified in the 'format' attribute)
138
- 'end-human|' . //The difference between the end time of the event and the time now, in human-readable format, such as '1 hour', '4 days', '15 mins'
139
- 'location|' . //The event location
140
- 'description|' . //The event deescription (number of words can be limited by the 'limit' attribute)
141
- 'link|' . //Anything within this shortcode (including further shortcodes) will be linked to the Google Calendar page for this event
142
- 'link-path|' . //The raw link URL to the Google Calendar page for this event (can be used to construct more customized links)
143
- 'feed-id|' . //The ID of this feed (Can be useful for constructing feed specific CSS classes)
144
- 'feed-title|' . //The feed title
145
- 'maps-link|' . //Anything within this shortcode (including further shortcodes) will be linked to a Google Maps page based on whatever is specified for the event location
146
-
147
- //Anything between the opening and closing tags of the following logical shortcodes (including further shortcodes) will only be displayed if:
148
-
149
- 'if-all-day|' . //This is an all-day event
150
- 'if-not-all-day|' . //This is not an all-day event
151
- 'if-title|' . //The event has a title
152
- 'if-description|' . //The event has a description
153
- 'if-location|' . //The event has a location
154
- 'if-tooltip|' . //The current display type is 'tooltip'
155
- 'if-list|' . //The current display type is 'list'
156
- 'if-now|' . //The event is taking place now (after the start time, but before the end time)
157
- 'if-not-now|' . //The event is not taking place now (may have ended or not yet started)
158
- 'if-started|' . //The event has started (and even if it has ended)
159
- 'if-not-started|' . //The event has not yet started
160
- 'if-ended|' . //The event has ended
161
- 'if-not-ended|' . //The event has not ended (and even if it hasn't started)
162
- 'if-first|' . //This event is the first in the day
163
- 'if-not-first'; //This event is not the first in the day
164
-
165
- $markup = $this->get_feed()->get_builder();
166
-
167
- $count = 0;
168
-
169
- //Go through the builder text looking for valid shortcodes. If one is found, send it to parse_shortcodes(). Once $count reaches 0, there are no un-parsed shortcodes
170
- //left, so return the markup (which now contains all the appropriate event information)
171
- do{
172
- $markup = preg_replace_callback('/(.?)\[(' . $shortcodes . ')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)/s', array($this, 'parse_shortcode'), $markup, -1, $count);
173
- }while($count > 0);
174
-
175
- return $markup;
176
- }
177
-
178
- //Parse a shortcode, returning the appropriate event information
179
- //Much of this code is 'borrowed' from WordPress' own shortcode handling stuff!
180
- function parse_shortcode($m){
181
- if($m[1] == '[' && $m[6] == ']' ) return substr($m[0], 1, -1);
182
-
183
- //Extract any attributes contained in the shortcode
184
- extract(shortcode_atts(array(
185
- 'newwindow' => 'false',
186
- 'format' => '',
187
- 'limit' => '0',
188
- 'html' => 'false',
189
- 'markdown' => 'false'
190
- ), shortcode_parse_atts($m[3])));
191
-
192
- //Sanitize the attributes
193
- $format = esc_attr($format);
194
- $limit = absint($limit);
195
-
196
- //If this is an all-day event
197
- $is_all_day = ($this->get_day_type() == $this->SINGLE_WHOLE_DAY || $this->get_day_type() == $this->MULTIPLE_WHOLE_DAY);
198
-
199
- //Do the appropriate stuff depending on which shortcode we're looking at. See valid shortcode list (above) for explanation of each shortcode
200
- switch($m[2]){
201
- case 'event-title':
202
- $title = esc_html($this->get_title());
203
-
204
- //Handle markdown / HTML if required
205
- if($markdown == 'true' && function_exists('Markdown')) $title = Markdown($title);
206
- if($html == 'true') $title = wp_kses_post(html_entity_decode($title));
207
-
208
- return $m[1] . $title . $m[6];
209
- case 'start-time':
210
- return $m[1] . date_i18n($this->get_feed()->get_time_format(), $this->get_start_date()) . $m[6];
211
- case 'start-date':
212
- return $m[1] . date_i18n($this->get_feed()->get_date_format(), $this->get_start_date()) . $m[6];
213
- case 'start-custom':
214
- return $m[1] . date_i18n($format, $this->get_start_date()) . $m[6];
215
- case 'start-human':
216
- return $m[1] . human_time_diff($this->get_start_date()) . $m[6];
217
- case 'end-time':
218
- return $m[1] . date_i18n($this->get_feed()->get_time_format(), $this->get_end_date()) . $m[6];
219
- case 'end-date':
220
- return $m[1] . date_i18n($this->get_feed()->get_date_format(), $this->get_end_date()) . $m[6];
221
- case 'end-custom':
222
- return $m[1] . date_i18n($format, $this->get_end_date()) . $m[6];
223
- case 'end-human':
224
- return $m[1] . human_time_diff($this->get_end_date()) . $m[6];
225
- case 'location':
226
- $location = esc_html($this->get_location());
227
-
228
- //Handle markdown / HTML if required
229
- if($markdown == 'true' && function_exists('Markdown')) $location = Markdown($location);
230
- if($html == 'true') $location = wp_kses_post(html_entity_decode($location));
231
-
232
- return $m[1] . $location . $m[6];
233
- case 'description':
234
- $description = esc_html($this->get_description());
235
-
236
- //If a word limit has been set, trim the description to the required length
237
- if($limit != 0){
238
- preg_match('/([\S]+\s*){0,' . $limit . '}/', esc_html($this->get_description()), $description);
239
- $description = trim($description[0]);
240
- }
241
-
242
- //Handle markdown / HTML if required
243
- if($markdown == 'true' && function_exists('Markdown')) $description = Markdown($description);
244
- if($html == 'true') $description = wp_kses_post(html_entity_decode($description));
245
-
246
- return $m[1] . $description . $m[6];
247
- case 'link':
248
- $new_window = ($newwindow == 'true') ? ' target="_blank"' : '';
249
- return $m[1] . '<a href="' . $this->get_link() . '"' . $new_window . '>' . $m[5] . '</a>' . $m[6];
250
- case 'link-path':
251
- return $m[1] . $this->get_link() . $m[6];
252
- case 'feed-id':
253
- return $m[1] . $this->get_feed()->get_feed_id() . $m[6];
254
- case 'feed-title':
255
- return $m[1] . $this->get_feed()->get_feed_title() . $m[6];
256
- case 'maps-link':
257
- $new_window = ($newwindow == 'true') ? ' target="_blank"' : '';
258
- return $m[1] . '<a href="http://maps.google.com?q=' . urlencode($this->get_location()) . '"' . $new_window . '>' . $m[5] . '</a>' . $m[6];
259
- case 'if-all-day':
260
- if($is_all_day) return $m[1] . $m[5] . $m[6];
261
- return '';
262
- case 'if-not-all-day':
263
- if(!$is_all_day) return $m[1] . $m[5] . $m[6];
264
- return '';
265
- case 'if-title':
266
- if($this->get_title() != '') return $m[1] . $m[5] . $m[6];
267
- return '';
268
- case 'if-description':
269
- if($this->get_description() != '') return $m[1] . $m[5] . $m[6];
270
- return '';
271
- case 'if-location':
272
- if($this->get_location() != '') return $m[1] . $m[5] . $m[6];
273
- return '';
274
- case 'if-tooltip':
275
- if($this->type == 'tooltip') return $m[1] . $m[5] . $m[6];
276
- return '';
277
- case 'if-list':
278
- if($this->type == 'list') return $m[1] . $m[5] . $m[6];
279
- return '';
280
- case 'if-now':
281
- $s = $this->get_start_date();
282
- $e = $this->get_end_date();
283
-
284
- if(time() >= $s && time() < $e) return $m[1] . $m[5] . $m[6];
285
- return '';
286
- case 'if-not-now':
287
- $s = $this->get_start_date();
288
- $e = $this->get_end_date();
289
-
290
- if($e < time() || $s > time()) return $m[1] . $m[5] . $m[6];
291
- return '';
292
- case 'if-started':
293
- if($this->get_start_date() < time()) return $m[1] . $m[5] . $m[6];
294
- return '';
295
- case 'if-not-started':
296
- if($this->get_start_date() > time()) return $m[1] . $m[5] . $m[6];
297
- return '';
298
- case 'if-ended':
299
- if($this->get_end_date() < time()) return $m[1] . $m[5] . $m[6];
300
- return '';
301
- case 'if-not-ended':
302
- if($this->get_end_date() > time()) return $m[1] . $m[5] . $m[6];
303
- return '';
304
- case 'if-first':
305
- if($this->num_in_day == 0) return $m[1] . $m[5] . $m[6];
306
- return '';
307
- case 'if-not-first':
308
- if($this->num_in_day != 0) return $m[1] . $m[5] . $m[6];
309
- return '';
310
- }
311
- }
312
-
313
- //Return the event markup using the old display options
314
- function use_old_display_options(){
315
- //Get the feed from which this event comes
316
- $feed = $this->get_feed();
317
-
318
- $display_options = $feed->get_display_options();
319
-
320
- $markup = '<p class="gce-' . $this->type . '-event">' . esc_html($this->get_title()) . '</p>';
321
-
322
- $start_end = array();
323
-
324
- //If start date / time should be displayed, set up array of start date and time
325
- if($display_options['display_start'] != 'none'){
326
- $sd = $this->get_start_date();
327
- $start_end['start'] = array('time' => date_i18n($feed->get_time_format(), $sd), 'date' => date_i18n($feed->get_date_format(), $sd));
328
- }
329
-
330
- //If end date / time should be displayed, set up array of end date and time
331
- if($display_options['display_end'] != 'none'){
332
- $ed = $this->get_end_date();
333
- $start_end['end'] = array('time' => date_i18n($feed->get_time_format(), $ed), 'date' => date_i18n($feed->get_date_format(), $ed));
334
- }
335
-
336
- //Add the correct start / end, date / time information to $markup
337
- foreach($start_end as $start_or_end => $info){
338
- $markup .= '<p class="gce-' . $this->type . '-' . $start_or_end . '"><span>' . $display_options['display_' . $start_or_end . '_text'] . '</span> ';
339
-
340
- switch($display_options['display_' . $start_or_end]){
341
- case 'time': $markup .= $info['time'];
342
- break;
343
- case 'date': $markup .= $info['date'];
344
- break;
345
- case 'time-date': $markup .= $info['time'] . $display_options['display_separator'] . $info['date'];
346
- break;
347
- case 'date-time': $markup .= $info['date'] . $display_options['display_separator'] . $info['time'];
348
- }
349
-
350
- $markup .= '</p>';
351
- }
352
-
353
- //If location should be displayed (and is not empty) add to $markup
354
- if(isset($display_options['display_location'])){
355
- $event_location = $this->get_location();
356
- if($event_location != '') $markup .= '<p class="gce-' . $this->type . '-loc"><span>' . $display_options['display_location_text'] . '</span> ' . esc_html($event_location) . '</p>';
357
- }
358
-
359
- //If description should be displayed (and is not empty) add to $markup
360
- if(isset($display_options['display_desc'])){
361
- $event_desc = $this->get_description();
362
-
363
- if($event_desc != ''){
364
- //Limit number of words of description to display, if required
365
- if($display_options['display_desc_limit'] != ''){
366
- preg_match('/([\S]+\s*){0,' . $display_options['display_desc_limit'] . '}/', $this->get_description(), $event_desc);
367
- $event_desc = trim($event_desc[0]);
368
- }
369
-
370
- $markup .= '<p class="gce-' . $this->type . '-desc"><span>' . $display_options['display_desc_text'] . '</span> ' . make_clickable(nl2br(esc_html($event_desc))) . '</p>';
371
- }
372
- }
373
-
374
- //If link should be displayed add to $markup
375
- if(isset($display_options['display_link'])){ //Below: add target="_blank" if required
376
- $markup .= '<p class="gce-' . $this->type . '-link"><a href="' . $this->get_link() . '&amp;ctz=' . $feed->get_timezone() . '"' . (isset($display_options['display_link_target']) ? ' target="_blank"' : '') . '>' . $display_options['display_link_text'] . '</a></p>';
377
- }
378
-
379
- return $markup;
380
- }
381
- }
382
  ?>
1
  <?php
2
+ class GCE_Feed{
3
+ private $feed_id = 1;
4
+ private $feed_title = '';
5
+ private $feed_url = '';
6
+ private $max_events = 25;
7
+ private $cache_duration = 43200;
8
+ private $date_format = '';
9
+ private $time_format = '';
10
+ private $timezone = '';
11
+ private $display_opts = array();
12
+ private $multi_day = false;
13
+ private $feed_start = 0;
14
+ private $feed_end = 2145916800;
15
+ private $use_builder = true;
16
+ private $builder = '';
17
+ private $events = array();
18
+ private $error = false;
 
 
19
 
20
  function init(){
21
+ require_once 'gce-event.php';
22
+
23
+ //Break the feed URL up into its parts (scheme, host, path, query)
24
+ $url_parts = parse_url($this->feed_url);
25
+
26
+ $scheme_and_host = $url_parts['scheme'] . '://' . $url_parts['host'];
27
+
28
+ //Remove the exisitng projection from the path, and replace it with '/full-noattendees'
29
+ $path = substr($url_parts['path'], 0, strrpos($url_parts['path'], '/')) . '/full-noattendees';
30
+
31
+ //Add the default parameters to the querystring (retrieving JSON, not XML)
32
+ $query = '?alt=json&sortorder=ascending&orderby=starttime&singleevents=true';
33
+
34
+ //Append the feed specific parameters to the querystring
35
+ $query .= '&start-min=' . date('Y-m-d\TH:i:s', $this->feed_start);
36
+ $query .= '&start-max=' . date('Y-m-d\TH:i:s', $this->feed_end);
37
+ $query .= '&max-results=' . $this->max_events;
38
+ if($this->timezone != '') $query .= '&ctz=' . $this->timezone;
39
+
40
+ //If enabled, use experimental 'fields' parameter of Google Data API, so that only necessary data is retrieved. This *significantly* reduces amount of data to retrieve and process
41
+ $general_options = get_option(GCE_GENERAL_OPTIONS_NAME);
42
+ if($general_options['fields'] == true) $query .= '&fields=entry(title,link[@rel="alternate"],content,gd:where,gd:when)';
43
+
44
+ //Put the URL back together
45
+ $url = $scheme_and_host . $path . $query;
46
+
47
+ //Attempt to retrieve the cached feed data
48
+ $this->events = get_transient('gce_feed_' . $this->feed_id);
49
+
50
+ //If the cached feed data isn't valid any more (has expired), or the URL has changed (settings have changed), then the feed data needs to be retrieved and decoded again
51
+ if($this->events === false || get_transient('gce_feed_' . $this->feed_id . '_url') != $url){
52
+ $this->events = array();
53
+
54
+ //Retrieve the feed data
55
+ $raw_data = wp_remote_get($url, array(
56
+ 'sslverify' => false, //sslverify is set to false to ensure https URLs work reliably. Data source is Google's servers, so is trustworthy
57
+ 'timeout' => 10 //Increase timeout from the default 5 seconds to ensure even large feeds are retrieved successfully
58
+ ));
59
+
60
+ //If $raw_data is a WP_Error, something went wrong
61
+ if(!is_wp_error($raw_data)){
62
+ //If response code isn't 200, something went wrong
63
+ if($raw_data['response']['code'] == 200){
64
+ //Attempt to convert the returned JSON into an array
65
+ $raw_data = json_decode($raw_data['body'], true);
66
+
67
+ //If decoding was successful
68
+ if(!empty($raw_data)){
69
+ //If there are some entries (events) to process
70
+ if(isset($raw_data['feed']['entry'])){
71
+ //Loop through each event, extracting the relevant information
72
+ foreach($raw_data['feed']['entry'] as $event){
73
+ $title = (string)$event['title']['$t'];
74
+ $description = (string)$event['content']['$t'];
75
+ $link = (string)$event['link'][0]['href'];
76
+ $location = (string)$event['gd$where'][0]['valueString'];
77
+ $start_time = strtotime($event['gd$when'][0]['startTime']);
78
+ $end_time = strtotime($event['gd$when'][0]['endTime']);
79
+
80
+ //Create a GCE_Event using the above data. Add it to the array of events
81
+ $this->events[] = new GCE_Event($title, $description, $location, $start_time, $end_time, $link);
82
+ }
83
+
84
+ //Cache the feed data
85
+ set_transient('gce_feed_' . $this->feed_id, $this->events, $this->cache_duration);
86
+ set_transient('gce_feed_' . $this->feed_id . '_url', $url, $this->cache_duration);
87
+ }
88
+ }else{
89
+ //json_decode failed
90
+ $this->error = __('Some data was retrieved, but could not be parsed successfully. Please ensure your feed URL is correct.', GCE_TEXT_DOMAIN);
91
+ }
92
+ }else{
93
+ //The response code wasn't 200, so generate a helpful(ish) error message depending on error code
94
+ switch($raw_data['response']['code']){
95
+ case 404:
96
+ $this->error = __('The feed could not be found (404). Please ensure your feed URL is correct.', GCE_TEXT_DOMAIN);
97
+ break;
98
+ case 403:
99
+ $this->error = __('Access to this feed was denied (403). Please ensure you have public sharing enabled for your calendar.', GCE_TEXT_DOMAIN);
100
+ break;
101
+ default:
102
+ $this->error = sprintf(__('The feed data could not be retrieved. Error code: %s. Please ensure your feed URL is correct.', GCE_TEXT_DOMAIN), $raw_data['response']['code']);
103
+ }
104
+ }
105
+ }else{
106
+ //Generate an error message from the returned WP_Error
107
+ $this->error = $raw_data->get_error_message() . ' Please ensure your feed URL is correct.';
108
+ }
109
+ }
110
+
111
+ //Makes sure each event knows it came from this feed
112
+ foreach($this->events as $event){
113
+ $event->set_feed($this);
114
+ }
115
+ }
116
+
117
+ //Return error message, or false if no error occurred
118
+ function error(){
119
+ return $this->error;
120
  }
121
 
122
  //Setters
123
 
124
+ function set_feed_id($v){
125
+ $this->feed_id = $v;
126
+ }
127
+
128
+ function set_feed_title($v){
129
+ $this->feed_title = $v;
130
+ }
131
+
132
+ function set_feed_url($v){
133
+ $this->feed_url = $v;
134
+ }
135
+
136
+ function set_max_events($v){
137
+ $this->max_events = $v;
138
+ }
139
+
140
+ function set_cache_duration($v){
141
+ $this->cache_duration = $v;
142
+ }
143
+
144
+ function set_date_format($v){
145
+ $this->date_format = $v;
146
  }
147
 
148
+ function set_time_format($v){
149
+ $this->time_format = $v;
150
  }
151
 
152
+ function set_timezone($v){
153
+ $this->timezone = $v;
154
  }
155
 
156
+ function set_display_options($v){
157
+ $this->display_opts = $v;
158
  }
159
 
160
+ function set_multi_day($v){
161
+ $this->multi_day = $v;
162
  }
163
 
164
+ function set_feed_start($v){
165
+ $this->feed_start = $v;
166
  }
167
 
168
+ function set_feed_end($v){
169
+ $this->feed_end = $v;
 
170
  }
171
 
172
+ function set_use_builder($v){
173
+ $this->use_builder = $v;
174
  }
175
 
176
+ function set_builder($v){
177
+ $this->builder = $v;
178
  }
179
 
180
  //Getters
181
 
182
+ function get_events(){
183
+ return $this->events;
184
+ }
185
+
186
  function get_feed_id(){
187
  return $this->feed_id;
188
  }
192
  }
193
 
194
  function get_date_format(){
195
+ return $this->date_format;
196
  }
197
 
198
  function get_time_format(){
199
+ return $this->time_format;
200
  }
201
 
202
  function get_display_options(){
207
  return $this->multi_day;
208
  }
209
 
210
+ function get_feed_start(){
211
  return $this->feed_start;
212
  }
213
 
214
+ function get_feed_end(){
215
+ return $this->feed_end;
216
+ }
217
+
218
  function get_timezone(){
219
  return $this->timezone;
220
  }
227
  return $this->builder;
228
  }
229
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  ?>
inc/gce-parser.php CHANGED
@@ -1,12 +1,14 @@
1
  <?php
2
  class GCE_Parser{
3
- var $feeds = array();
4
- var $merged_feed_data = array();
5
- var $title = null;
6
- var $max_events_display = 0;
 
 
7
 
8
  function __construct($feed_ids, $title_text = null, $max_events = 0){
9
- require_once('gce-feed.php');
10
 
11
  $this->title = $title_text;
12
  $this->max_events_display = $max_events;
@@ -14,6 +16,8 @@ class GCE_Parser{
14
  //Get the feed options
15
  $options = get_option(GCE_OPTIONS_NAME);
16
 
 
 
17
  foreach($feed_ids as $single_feed){
18
  //Get the options for this particular feed
19
  if(isset($options[$single_feed])){
@@ -32,50 +36,51 @@ class GCE_Parser{
32
 
33
  //Set the start date to the appropriate value based on the retrieve_from option
34
  switch($feed_options['retrieve_from']){
 
35
  case 'now':
36
- $feed->set_start_date(time() + $feed_options['retrieve_from_value'] - date('Z'));
37
  break;
38
  case 'today':
39
- $feed->set_start_date(mktime(0, 0, 0, date('m'), date('j'), date('Y')) + $feed_options['retrieve_from_value'] - date('Z'));
40
  break;
41
  case 'week':
42
- $feed->set_start_date(mktime(0, 0, 0, date('m'), (date('j') - date('w') + get_option('start_of_week')), date('Y')) + $feed_options['retrieve_from_value'] - date('Z'));
43
  break;
44
  case 'month-start':
45
- $feed->set_start_date(mktime(0, 0, 0, date('m'), 1, date('Y')) + $feed_options['retrieve_from_value'] - date('Z'));
46
  break;
47
  case 'month-end':
48
- $feed->set_start_date(mktime(0, 0, 0, date('m') + 1, 1, date('Y')) + $feed_options['retrieve_from_value'] - date('Z'));
49
  break;
50
  case 'date':
51
- $feed->set_start_date($feed_options['retrieve_from_value']);
52
  break;
53
  case 'any':
54
- $feed->set_show_past_events(true);
55
  }
56
 
57
  //Set the end date to the appropriate value based on the retrieve_until option
58
  switch($feed_options['retrieve_until']){
59
  case 'now':
60
- $feed->set_end_date(time() + $feed_options['retrieve_until_value'] - date('Z'));
61
  break;
62
  case 'today':
63
- $feed->set_end_date(mktime(0, 0, 0, date('m'), date('j'), date('Y')) + $feed_options['retrieve_until_value'] - date('Z'));
64
  break;
65
  case 'week':
66
- $feed->set_end_date(mktime(0, 0, 0, date('m'), (date('j') - date('w') + get_option('start_of_week')), date('Y')) + $feed_options['retrieve_until_value'] - date('Z'));
67
  break;
68
  case 'month-start':
69
- $feed->set_end_date(mktime(0, 0, 0, date('m'), 1, date('Y')) + $feed_options['retrieve_until_value'] - date('Z'));
70
  break;
71
  case 'month-end':
72
- $feed->set_end_date(mktime(0, 0, 0, date('m') + 1, 1, date('Y')) + $feed_options['retrieve_until_value'] - date('Z'));
73
  break;
74
  case 'date':
75
- $feed->set_end_date($feed_options['retrieve_until_value']);
76
  break;
77
  case 'any':
78
- $feed->set_show_past_events(true);
79
  }
80
 
81
  //Set date and time formats. If they have not been set by user, set to global WordPress formats
@@ -104,7 +109,7 @@ class GCE_Parser{
104
  $feed->set_use_builder($feed_options['use_builder'] == 'true' ? true : false);
105
  $feed->set_builder($feed_options['builder']);
106
 
107
- //SimplePie does the hard work
108
  $feed->init();
109
 
110
  //Add feed object to array of feeds
@@ -112,24 +117,42 @@ class GCE_Parser{
112
  }
113
  }
114
 
115
- //More SimplePie magic to merge items from all feeds together
116
- $this->merged_feed_data = SimplePie::merge_items($this->feeds);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
- //Sort the items by into date order
119
- usort($this->merged_feed_data, array('SimplePie_Item_GCalendar', 'compare'));
 
120
  }
121
 
122
- //Returns an array of feed ids that have encountered errors
123
- function get_errors(){
124
- $errors = array();
125
 
126
- foreach($this->feeds as $feed){
127
- //Remove '//' on line below to see more error information
128
- //echo $feed->error();
129
- if($feed->error()) $errors[] = $feed->get_feed_id();
130
  }
131
 
132
- return $errors;
133
  }
134
 
135
  //Returns array of days with events, with sub-arrays of events for that day
@@ -144,33 +167,14 @@ class GCE_Parser{
144
 
145
  //Loop through entire array of events, or until maximum number of events to be displayed has been reached
146
  for($i = 0; $i < $count && $max > 0; $i++){
147
- $item = $this->merged_feed_data[$i];
148
 
149
  //Check that event end time isn't before start time of feed (ignores events from before start time that may have been inadvertently retrieved)
150
- if($item->get_end_date() > ($item->get_feed()->get_start_date() + date('Z'))){
151
-
152
- $start_date = $item->get_start_date();
153
-
154
- //Round start date to nearest day
155
- $start_date = mktime(0, 0, 0, date('m', $start_date), date('d', $start_date) , date('Y', $start_date));
156
-
157
- //If multiple day events should be handled, add multiple day event to required days
158
- if($item->get_feed()->get_multi_day()){
159
- $on_next_day = true;
160
- $next_day = $start_date + 86400;
161
- while($on_next_day){
162
- if($item->get_end_date() > $next_day){
163
- $event_days[$next_day][] = $item;
164
- }else{
165
- $on_next_day = false;
166
- }
167
- $next_day += 86400;
168
- }
169
  }
170
 
171
- //Add item into array of events for that day
172
- $event_days[$start_date][] = $item;
173
-
174
  //If maximum events to display isn't 0 (unlimited) decrement $max counter
175
  if($this->max_events_display != 0) $max--;
176
  }
@@ -187,8 +191,19 @@ class GCE_Parser{
187
  if($year == null) $year = date('Y');
188
  if($month == null) $month = date('m');
189
 
190
- //Month and year to be displayed, in format mY (e.g. 052010)
191
- $m_y = date('mY', mktime(0, 0, 0, $month, 1, $year));
 
 
 
 
 
 
 
 
 
 
 
192
 
193
  //Get events data
194
  $event_days = $this->get_event_days();
@@ -196,23 +211,11 @@ class GCE_Parser{
196
  //If event_days is empty, then there are no events in the feed(s), so set ajaxified to false (Prevents AJAX calendar from allowing to endlessly click through months with no events)
197
  if(count((array)$event_days) == 0) $ajaxified = false;
198
 
199
- $at_last_event = false;
200
- $at_first_event = false;
201
-
202
- $last_event = end($event_days);
203
- $first_event = reset($event_days);
204
-
205
  $today = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
206
 
207
  foreach($event_days as $key => $event_day){
208
  //If event day is in the month and year specified (by $month and $year)
209
- if(date('mY', $key) == $m_y){
210
- //If this event day is the last in $event_days, there are no more events in the future so set $at_last_event to true
211
- if($event_day === $last_event) $at_last_event = true;
212
-
213
- //If this event day is the first in $event_days, there are no more events in the past so set $at_first_event to true
214
- if($event_day === $first_event) $at_first_event = true;
215
-
216
  //Create array of CSS classes. Add gce-has-events
217
  $css_classes = array('gce-has-events');
218
 
@@ -225,10 +228,11 @@ class GCE_Parser{
225
  $markup .= '<ul>';
226
 
227
  foreach($event_day as $event_num => $event){
228
- $markup .= '<li class="gce-tooltip-feed-' . $event->get_feed()->get_feed_id() . '">' . $event->get_event_markup('tooltip', $event_num) . '</li>';
 
229
 
230
  //Add CSS class for the feed from which this event comes. If there are multiple events from the same feed on the same day, the CSS class will only be added once.
231
- $css_classes['feed-' . $event->get_feed()->get_feed_id()] = 'gce-feed-' . $event->get_feed()->get_feed_id();
232
  }
233
 
234
  $markup .= '</ul></div>';
@@ -240,8 +244,13 @@ class GCE_Parser{
240
 
241
  //Change array entry to array of link href, CSS classes, and markup for use in gce_generate_calendar (below)
242
  $event_days[$key] = array(null, implode(' ', $css_classes), $markup);
 
 
 
 
243
  }else{
244
- //Else if event day isn't in month and year specified, remove event day (and all associated events) from the array
 
245
  unset($event_days[$key]);
246
  }
247
  }
@@ -253,27 +262,27 @@ class GCE_Parser{
253
 
254
  //Only add previous / next functionality if AJAX grid is enabled
255
  if($ajaxified){
256
- //If $at_first_event don't add previous month link. Otherwise, do add previous month link
257
- $prev_key = ($at_first_event ? '&nbsp;' : '&laquo;');
258
- $prev = ($at_first_event ? null : date('m-Y', mktime(0, 0, 0, $month - 1, 1, $year)));
259
 
260
- //If $at_last_event don't add next month link. Otherwise, do add next month link
261
- $next_key = ($at_last_event ? '&nbsp;' : '&raquo;');
262
- $next = ($at_last_event ? null : date('m-Y', mktime(0, 0, 0, $month + 1, 1, $year)));
263
 
264
  //Array of previous and next link stuff for use in gce_generate_calendar (below)
265
  $pn = array($prev_key => $prev, $next_key => $next);
266
  }
267
 
268
  //Generate the calendar markup and return it
269
- return gce_generate_calendar($year, $month, $event_days, 1, null, get_option('start_of_week'), $pn);
270
  }
271
 
272
  function get_list($grouped = false){
273
  $event_days = $this->get_event_days();
274
 
275
  //If event_days is empty, there are no events in the feed(s), so return a message indicating this
276
- if(count((array)$event_days) == 0) return '<p>' . __('There are currently no upcoming events.', GCE_TEXT_DOMAIN) . '</p>';
277
 
278
  $today = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
279
 
1
  <?php
2
  class GCE_Parser{
3
+ private $feeds = array();
4
+ private $merged_feed_data = array();
5
+ private $errors = array();
6
+ private $title = null;
7
+ private $max_events_display = 0;
8
+ private $start_of_week = 0;
9
 
10
  function __construct($feed_ids, $title_text = null, $max_events = 0){
11
+ require_once 'gce-feed.php';
12
 
13
  $this->title = $title_text;
14
  $this->max_events_display = $max_events;
16
  //Get the feed options
17
  $options = get_option(GCE_OPTIONS_NAME);
18
 
19
+ $this->start_of_week = get_option('start_of_week');
20
+
21
  foreach($feed_ids as $single_feed){
22
  //Get the options for this particular feed
23
  if(isset($options[$single_feed])){
36
 
37
  //Set the start date to the appropriate value based on the retrieve_from option
38
  switch($feed_options['retrieve_from']){
39
+ //Don't just use time() for 'now', as this will effectively make cache duration 1 second. Instead set to previous minute. Events in Google Calendar cannot be set to precision of seconds anyway
40
  case 'now':
41
+ $feed->set_feed_start(mktime(date('H'), date('i'), 0, date('m'), date('j'), date('Y')) + $feed_options['retrieve_from_value'] - date('Z'));
42
  break;
43
  case 'today':
44
+ $feed->set_feed_start(mktime(0, 0, 0, date('m'), date('j'), date('Y')) + $feed_options['retrieve_from_value'] - date('Z'));
45
  break;
46
  case 'week':
47
+ $feed->set_feed_start(mktime(0, 0, 0, date('m'), (date('j') - date('w') + $this->start_of_week), date('Y')) + $feed_options['retrieve_from_value'] - date('Z'));
48
  break;
49
  case 'month-start':
50
+ $feed->set_feed_start(mktime(0, 0, 0, date('m'), 1, date('Y')) + $feed_options['retrieve_from_value'] - date('Z'));
51
  break;
52
  case 'month-end':
53
+ $feed->set_feed_start(mktime(0, 0, 0, date('m') + 1, 1, date('Y')) + $feed_options['retrieve_from_value'] - date('Z'));
54
  break;
55
  case 'date':
56
+ $feed->set_feed_start($feed_options['retrieve_from_value']);
57
  break;
58
  case 'any':
59
+ $feed->set_feed_start(0); //1970-01-01 00:00
60
  }
61
 
62
  //Set the end date to the appropriate value based on the retrieve_until option
63
  switch($feed_options['retrieve_until']){
64
  case 'now':
65
+ $feed->set_feed_end(mktime(date('H'), date('i'), 0, date('m'), date('j'), date('Y')) + $feed_options['retrieve_until_value'] - date('Z'));
66
  break;
67
  case 'today':
68
+ $feed->set_feed_end(mktime(0, 0, 0, date('m'), date('j'), date('Y')) + $feed_options['retrieve_until_value'] - date('Z'));
69
  break;
70
  case 'week':
71
+ $feed->set_feed_end(mktime(0, 0, 0, date('m'), (date('j') - date('w') + $this->start_of_week), date('Y')) + $feed_options['retrieve_until_value'] - date('Z'));
72
  break;
73
  case 'month-start':
74
+ $feed->set_feed_end(mktime(0, 0, 0, date('m'), 1, date('Y')) + $feed_options['retrieve_until_value'] - date('Z'));
75
  break;
76
  case 'month-end':
77
+ $feed->set_feed_end(mktime(0, 0, 0, date('m') + 1, 1, date('Y')) + $feed_options['retrieve_until_value'] - date('Z'));
78
  break;
79
  case 'date':
80
+ $feed->set_feed_end($feed_options['retrieve_until_value']);
81
  break;
82
  case 'any':
83
+ $feed->set_feed_end(2145916800); //2038-01-01 00:00
84
  }
85
 
86
  //Set date and time formats. If they have not been set by user, set to global WordPress formats
109
  $feed->set_use_builder($feed_options['use_builder'] == 'true' ? true : false);
110
  $feed->set_builder($feed_options['builder']);
111
 
112
+ //Parse the feed
113
  $feed->init();
114
 
115
  //Add feed object to array of feeds
117
  }
118
  }
119
 
120
+ $this->merged_feed_data = array();
121
+
122
+ //Merge the feeds together into one array of events
123
+ foreach($this->feeds as $feed_id => $feed){
124
+ $errors_occurred = $feed->error();
125
+
126
+ if($errors_occurred === false){
127
+ $this->merged_feed_data = array_merge($this->merged_feed_data, $feed->get_events());
128
+ }else{
129
+ $this->errors[$feed_id] = $errors_occurred;
130
+ }
131
+ }
132
+
133
+ //Sort the items into date order
134
+ if(!empty($this->merged_feed_data)) usort($this->merged_feed_data, array($this, 'compare'));
135
+ }
136
+
137
+ //Comparison function for use when sorting merged feed data (with usort)
138
+ function compare($event1, $event2){
139
+ return $event1->get_start_time() - $event2->get_start_time();
140
+ }
141
 
142
+ //Returns number of errors that have occurred
143
+ function get_num_errors(){
144
+ return count($this->errors);
145
  }
146
 
147
+ //Outputs a message describing each error that has occurred
148
+ function error_messages(){
149
+ $message = '<p>' . __('1 or more of your feeds could not be displayed. The following errors occurred:', GCE_TEXT_DOMAIN) . '</p><ul>';
150
 
151
+ foreach($this->errors as $feed_id => $error){
152
+ $message .= '<li><strong>' . sprintf(__('Feed %s:', GCE_TEXT_DOMAIN), $feed_id) . '</strong> ' . $error . '</li>';
 
 
153
  }
154
 
155
+ return $message . '</ul>';
156
  }
157
 
158
  //Returns array of days with events, with sub-arrays of events for that day
167
 
168
  //Loop through entire array of events, or until maximum number of events to be displayed has been reached
169
  for($i = 0; $i < $count && $max > 0; $i++){
170
+ $event = $this->merged_feed_data[$i];
171
 
172
  //Check that event end time isn't before start time of feed (ignores events from before start time that may have been inadvertently retrieved)
173
+ if($event->get_end_time() > ($event->get_feed()->get_feed_start() + date('Z'))){
174
+ foreach($event->get_days() as $day){
175
+ $event_days[$day][] = $event;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  }
177
 
 
 
 
178
  //If maximum events to display isn't 0 (unlimited) decrement $max counter
179
  if($this->max_events_display != 0) $max--;
180
  }
191
  if($year == null) $year = date('Y');
192
  if($month == null) $month = date('m');
193
 
194
+ //Get timestamps for the start and end of current month
195
+ $current_month_start = mktime(0, 0, 0, date('m'), 1, date('Y'));
196
+ $current_month_end = mktime(0, 0, 0, date('m') + 1, 1, date('Y'));
197
+
198
+ //Get timestamps for the start and end of the month to be displayed in the grid
199
+ $display_month_start = mktime(0, 0, 0, $month, 1, $year);
200
+ $display_month_end = mktime(0, 0, 0, $month + 1, 1, $year);
201
+
202
+ //It should always be possible to navigate to the current month, even if it doesn't have any events
203
+ //So, if the display month is before the current month, set $nav_next to true, otherwise false
204
+ //If the display month is after the current month, set $nav_prev to true, otherwise false
205
+ $nav_next = $display_month_start < $current_month_start;
206
+ $nav_prev = $display_month_start >= $current_month_end;
207
 
208
  //Get events data
209
  $event_days = $this->get_event_days();
211
  //If event_days is empty, then there are no events in the feed(s), so set ajaxified to false (Prevents AJAX calendar from allowing to endlessly click through months with no events)
212
  if(count((array)$event_days) == 0) $ajaxified = false;
213
 
 
 
 
 
 
 
214
  $today = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
215
 
216
  foreach($event_days as $key => $event_day){
217
  //If event day is in the month and year specified (by $month and $year)
218
+ if($key >= $display_month_start && $key < $display_month_end){
 
 
 
 
 
 
219
  //Create array of CSS classes. Add gce-has-events
220
  $css_classes = array('gce-has-events');
221
 
228
  $markup .= '<ul>';
229
 
230
  foreach($event_day as $event_num => $event){
231
+ $feed_id = $event->get_feed()->get_feed_id();
232
+ $markup .= '<li class="gce-tooltip-feed-' . $feed_id . '">' . $event->get_event_markup('tooltip', $event_num) . '</li>';
233
 
234
  //Add CSS class for the feed from which this event comes. If there are multiple events from the same feed on the same day, the CSS class will only be added once.
235
+ $css_classes['feed-' . $feed_id] = 'gce-feed-' . $feed_id;
236
  }
237
 
238
  $markup .= '</ul></div>';
244
 
245
  //Change array entry to array of link href, CSS classes, and markup for use in gce_generate_calendar (below)
246
  $event_days[$key] = array(null, implode(' ', $css_classes), $markup);
247
+ }elseif($key < $display_month_start){
248
+ //This day is before the display month, so set $nav_prev to true. Remove the day from $event_days, as it's no use for displaying this month
249
+ $nav_prev = true;
250
+ unset($event_days[$key]);
251
  }else{
252
+ //This day is after the display month, so set $nav_next to true. Remove the day from $event_days, as it's no use for displaying this month
253
+ $nav_next = true;
254
  unset($event_days[$key]);
255
  }
256
  }
262
 
263
  //Only add previous / next functionality if AJAX grid is enabled
264
  if($ajaxified){
265
+ //If there are events to display in a previous month, add previous month link
266
+ $prev_key = ($nav_prev ? '&laquo;' : '&nbsp;');
267
+ $prev = ($nav_prev ? date('m-Y', mktime(0, 0, 0, $month - 1, 1, $year)) : null);
268
 
269
+ //If there are events to display in a future month, add next month link
270
+ $next_key = ($nav_next ? '&raquo;' : '&nbsp;');
271
+ $next = ($nav_next ? date('m-Y', mktime(0, 0, 0, $month + 1, 1, $year)) : null);
272
 
273
  //Array of previous and next link stuff for use in gce_generate_calendar (below)
274
  $pn = array($prev_key => $prev, $next_key => $next);
275
  }
276
 
277
  //Generate the calendar markup and return it
278
+ return gce_generate_calendar($year, $month, $event_days, 1, null, $this->start_of_week, $pn);
279
  }
280
 
281
  function get_list($grouped = false){
282
  $event_days = $this->get_event_days();
283
 
284
  //If event_days is empty, there are no events in the feed(s), so return a message indicating this
285
+ if(count((array)$event_days) == 0) return '<p>' . __('There are currently no events to display.', GCE_TEXT_DOMAIN) . '</p>';
286
 
287
  $today = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
288
 
inc/simplepie-gcalendar.php DELETED
@@ -1,468 +0,0 @@
1
- <?php
2
- /**
3
- * GCalendar is free software: you can redistribute it and/or modify
4
- * it under the terms of the GNU General Public License as published by
5
- * the Free Software Foundation, either version 3 of the License, or
6
- * (at your option) any later version.
7
- *
8
- * GCalendar is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
12
- *
13
- * You should have received a copy of the GNU General Public License
14
- * along with GCalendar. If not, see <http://www.gnu.org/licenses/>.
15
- *
16
- * @author Allon Moritz
17
- * @copyright 2007-2009 Allon Moritz
18
- * @version $Revision: 0.4.0 $
19
- */
20
-
21
- if (!defined('SIMPLEPIE_NAMESPACE_GOOGLE_CALENDAR_ITEM')) {
22
- define('SIMPLEPIE_NAMESPACE_GOOGLE_CALENDAR_ITEM', 'http://schemas.google.com/g/2005');
23
- }
24
-
25
- if (!defined('SIMPLEPIE_NAMESPACE_GOOGLE_CALENDAR_FEED')) {
26
- define('SIMPLEPIE_NAMESPACE_GOOGLE_CALENDAR_FEED', 'http://schemas.google.com/gCal/2005');
27
- }
28
-
29
- /**
30
- * SimplePie_GCalendar is the SimplePie extension which provides some
31
- * helper methods.
32
- *
33
- * @see http://code.google.com/apis/calendar/docs/2.0/reference.html
34
- */
35
- class SimplePie_GCalendar extends SimplePie {
36
-
37
- var $show_past_events = FALSE;
38
- var $sort_ascending = TRUE;
39
- var $orderby_by_start_date = TRUE;
40
- var $expand_single_events = TRUE;
41
- var $cal_language = "";
42
- var $cal_query = "";
43
- var $meta_data = array();
44
- var $start_date = null;
45
- var $end_date = null;
46
- var $max_events = 25;
47
- var $projection = "full";
48
- var $timezone = "";
49
-
50
- /**
51
- * If the method $this->get_items() should include past events.
52
- */
53
- function set_show_past_events($value = FALSE){
54
- $this->show_past_events = $value;
55
- }
56
-
57
- /**
58
- * If is set to true the closest event is the first in the returning items.
59
- * So it makes sense to call enable_order_by_date(false) before fetching
60
- * the data to prevent from sorting twice.
61
- */
62
- function set_sort_ascending($value = TRUE){
63
- $this->sort_ascending = $value;
64
- }
65
-
66
- /**
67
- * The method $this->get_items() will return the events ordered by
68
- * the start date if set to true otherwise by the publish date.
69
- *
70
- */
71
- function set_orderby_by_start_date($value = TRUE){
72
- $this->orderby_by_start_date = $value;
73
- }
74
-
75
- /**
76
- * If the method $this->get_items() should treat reccuring events
77
- * as one item.
78
- */
79
- function set_expand_single_events($value = TRUE){
80
- $this->expand_single_events = $value;
81
- }
82
-
83
- /**
84
- * Sets the language of the feed. Something like
85
- * en or en_GB or de.
86
- */
87
- function set_cal_language($value = ""){
88
- $this->cal_language = $value;
89
- }
90
-
91
- /**
92
- * If this parameter is set the feed will just contain events
93
- * which contain the given parameter in the titel or the description.
94
- *
95
- * @param $value
96
- */
97
- function set_cal_query($value = ""){
98
- $this->cal_query = $value;
99
- }
100
-
101
- /**
102
- * Sets the start date of the events in the feed, set_end_date(...)
103
- * must also be feeded with a value.
104
- * If this value is set the set_show_past_events(...)
105
- * will be ignored.
106
- *
107
- * @param $value must php timestamp
108
- */
109
- function set_start_date($value = 0){
110
- $this->start_date = strftime('%Y-%m-%dT%H:%M:%S',$value);
111
- }
112
-
113
- /**
114
- * Sets the end date of the events in the feed, set_start_date(...)
115
- * must also be feeded with a value.
116
- * If this value is set the set_show_past_events(...)
117
- * will be ignored.
118
- *
119
- * @param $value must be php timestamp
120
- */
121
- function set_end_date($value = 0){
122
- $this->end_date = strftime('%Y-%m-%dT%H:%M:%S',$value);
123
- }
124
-
125
- /**
126
- * Sets the max events this feed should fetch
127
- *
128
- * @param $value the max events
129
- */
130
- function set_max_events($value = 25){
131
- $this->max_events = $value;
132
- }
133
-
134
- /**
135
- * Sets the projection of this feed. The given value must one of the
136
- * following strings:
137
- * - full
138
- * - full-noattendees
139
- * - composite
140
- * - attendees-only
141
- * - free-busy
142
- * - basic
143
- * Note if the feed projection is not full, some methodes in the returned
144
- * items are empty. For example if the feed projection is basic the method
145
- * SimplePie_Item_GCalendar->get_start_date() returns an empty string,
146
- * because this information is only included in the full projection.
147
- * @param $value
148
- */
149
- function set_projection($value = "full"){
150
- if(!empty($value))
151
- $this->projection = $value;
152
- }
153
-
154
- /**
155
- * Sets the timezone of this feed.
156
- *
157
- * @param $value
158
- */
159
- function set_timezone($value = "") {
160
- if(!empty($value))
161
- $this->timezone = $value;
162
- }
163
-
164
- /**
165
- * Overrides the default ini method and sets automatically
166
- * SimplePie_Item_GCalendar as item class.
167
- * It also sets the variables specified in this feed as query
168
- * parameters.
169
- */
170
- function init(){
171
- $this->set_item_class('SimplePie_Item_GCalendar');
172
-
173
- $new_url;
174
- if (!empty($this->multifeed_url)){
175
- $tmp = array();
176
- foreach ($this->multifeed_url as $value)
177
- $tmp[] = $this->check_url($value);
178
- $new_url = $tmp;
179
- }else{
180
- $new_url = $this->check_url($this->feed_url);
181
- }
182
- $this->set_feed_url($new_url);
183
-
184
- parent::init();
185
- }
186
-
187
- /**
188
- * Creates an url depending on the variables $show_past_events, etc.
189
- * and returns a valid google calendar feed url.
190
- */
191
- function check_url($url_to_check){
192
- $new_url = parse_url($url_to_check);
193
- $path = $new_url['path'];
194
- $path = substr($path, 0, strrpos($path, '/')+1).$this->projection;
195
- $query = '';
196
- if(isset($new_url['query'])){
197
- $query = $new_url['query'];
198
- }
199
- $tmp = $new_url['scheme'].'://'.$new_url['host'].$path.'?'.$query;
200
- if(!empty($new_url['query']))
201
- $tmp = $this->append($tmp,'&');
202
- if($this->start_date==null && $this->end_date==null){
203
- if($this->show_past_events )
204
- $tmp = $this->append($tmp,'futureevents=false&');
205
- else
206
- $tmp = $this->append($tmp,'futureevents=true&');
207
- }
208
- if($this->start_date!=null){
209
- $tmp = $this->append($tmp,'start-min='.$this->start_date.'&');
210
- }
211
- if( $this->end_date!=null){
212
- $tmp = $this->append($tmp,'start-max='.$this->end_date.'&');
213
- }
214
- if($this->sort_ascending)
215
- $tmp = $this->append($tmp,'sortorder=ascending&');
216
- else
217
- $tmp = $this->append($tmp,'sortorder=descending&');
218
- if($this->orderby_by_start_date)
219
- $tmp = $this->append($tmp,'orderby=starttime&');
220
- else
221
- $tmp = $this->append($tmp,'orderby=lastmodified&');
222
- if($this->expand_single_events)
223
- $tmp = $this->append($tmp,'singleevents=true&');
224
- else
225
- $tmp = $this->append($tmp,'singleevents=false&');
226
- if(!empty($this->cal_language))
227
- $tmp = $this->append($tmp,'hl='.$this->cal_language.'&');
228
- if(!empty($this->cal_query))
229
- $tmp = $this->append($tmp,'q='.urlencode($this->cal_query).'&');
230
- if(!empty($this->timezone))
231
- $tmp = $this->append($tmp,'ctz='.$this->timezone.'&');
232
- $tmp = $this->append($tmp,'max-results='.$this->max_events);
233
-
234
- return $tmp;
235
- }
236
-
237
- /**
238
- * Internal helper method to append a string to an other one.
239
- */
240
- function append($value, $appendix){
241
- $pos = strpos($value,$appendix);
242
- if($pos === FALSE)
243
- $value .= $appendix;
244
- return $value;
245
- }
246
-
247
- /**
248
- * Returns the timezone of the feed.
249
- */
250
- function get_timezone(){
251
- $tzvalue = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_GOOGLE_CALENDAR_FEED, 'timezone');
252
- return $tzvalue[0]['attribs']['']['value'];
253
- }
254
-
255
- /**
256
- * Sets the given value for the given key which is accessible in the get(...) method.
257
- * @param $key
258
- * @param $value
259
- */
260
- function put($key, $value){
261
- $this->meta_data[$key] = $value;
262
- }
263
-
264
- /**
265
- * Returns the value for the given key which is set in the set(...) method.
266
- * @param $key
267
- * @return the value
268
- */
269
- function get($key){
270
- return $this->meta_data[$key];
271
- }
272
-
273
- /**
274
- * Creates a valid feed url for the given email address.
275
- * If the magic cookie parameter is set it will return the private feed url.
276
- */
277
- function create_feed_url($email_address, $magic_cookie = null){
278
- $type = 'public';
279
- if($magic_cookie != null)
280
- $type = 'private-'.$magic_cookie;
281
-
282
- return 'http://www.google.com/calendar/feeds/'.$email_address.'/'.$type.'/full';
283
- }
284
- }
285
-
286
- /**
287
- * The GCalendar Item which provides more google calendar specific
288
- * functions like the location of the event, etc.
289
- */
290
- class SimplePie_Item_GCalendar extends SimplePie_Item {
291
-
292
- // static variables used as return value for get_day_type()
293
- var $SINGLE_WHOLE_DAY = 1;
294
- var $SINGLE_PART_DAY = 2;
295
- var $MULTIPLE_WHOLE_DAY = 3;
296
- var $MULTIPLE_PART_DAY = 4;
297
-
298
- //internal cache variables
299
- var $gc_id;
300
- var $gc_pub_date;
301
- var $gc_location;
302
- var $gc_status;
303
- var $gc_start_date;
304
- var $gc_end_date;
305
- var $gc_day_type;
306
-
307
- /**
308
- * Returns the id of the event.
309
- *
310
- * @return the id of the event
311
- */
312
- function get_id(){
313
- if(!$this->gc_id){
314
- $this->gc_id = substr($this->get_link(),strpos(strtolower($this->get_link()),'eid=')+4);
315
- }
316
- return $this->gc_id;
317
- }
318
-
319
- /**
320
- * Returns the publish date as unix timestamp of the event.
321
- *
322
- * @return the publish date of the event
323
- */
324
- function get_publish_date(){
325
- if(!$this->gc_pub_date){
326
- $pubdate = $this->get_date('Y-m-d\TH:i:s\Z');
327
- $this->gc_pub_date = SimplePie_Item_GCalendar::tstamptotime($pubdate);
328
- }
329
- return $this->gc_pub_date;
330
- }
331
-
332
- /**
333
- * Returns the location of the event.
334
- *
335
- * @return the location of the event
336
- */
337
- function get_location(){
338
- if(!$this->gc_location){
339
- $gd_where = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GOOGLE_CALENDAR_ITEM, 'where');
340
- if(isset($gd_where[0]) &&
341
- isset($gd_where[0]['attribs']) &&
342
- isset($gd_where[0]['attribs']['']) &&
343
- isset($gd_where[0]['attribs']['']['valueString']))
344
- $this->gc_location = $gd_where[0]['attribs']['']['valueString'];
345
- }
346
- return $this->gc_location;
347
- }
348
-
349
- /**
350
- * Returns the status of the event.
351
- *
352
- * @return the status of the event
353
- */
354
- function get_status(){
355
- if(!$this->gc_status){
356
- $gd_status = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GOOGLE_CALENDAR_ITEM, 'eventStatus');
357
- $this->gc_status = substr( $gd_status[0]['attribs']['']['value'], -9);
358
- }
359
- return $this->gc_status;
360
- }
361
-
362
- /**
363
- * If the given format (must match the criterias of strftime)
364
- * is not null a string is returned otherwise a unix timestamp.
365
- *
366
- * @see http://www.php.net/mktime
367
- * @see http://www.php.net/strftime
368
- * @param $format
369
- * @return the start date of the event
370
- */
371
- function get_start_date($format = null){
372
- if(!$this->gc_start_date){
373
- $when = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GOOGLE_CALENDAR_ITEM, 'when');
374
- $startdate = $when[0]['attribs']['']['startTime'];
375
- $this->gc_start_date = SimplePie_Item_GCalendar::tstamptotime($startdate);
376
- }
377
- if($format != null)
378
- return strftime($format, $this->gc_start_date);
379
- return $this->gc_start_date;
380
- }
381
-
382
- /**
383
- * If the given format (must match the criterias of strftime)
384
- * is not null a string is returned otherwise a unix timestamp.
385
- *
386
- * @see http://www.php.net/mktime
387
- * @see http://www.php.net/strftime
388
- * @param $format
389
- * @return the end date of the event
390
- */
391
- function get_end_date($format = null){
392
- if(!$this->gc_end_date){
393
- $when = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GOOGLE_CALENDAR_ITEM, 'when');
394
- $enddate = $when[0]['attribs']['']['endTime'];
395
- $this->gc_end_date = SimplePie_Item_GCalendar::tstamptotime($enddate);
396
- }
397
- if($format != null)
398
- return strftime($format, $this->gc_end_date);
399
- return $this->gc_end_date;
400
- }
401
-
402
- /**
403
- * Returns the event type. One of the following constants:
404
- * - SINGLE_WHOLE_DAY
405
- * - SINGLE_PART_DAY
406
- * - MULTIPLE_WHOLE_DAY
407
- * - MULTIPLE_PART_DAY
408
- *
409
- * @return the event type
410
- */
411
- function get_day_type(){
412
- if(!$this->gc_day_type){
413
- $SECSINDAY=86400;
414
-
415
- if (($this->get_start_date()+ $SECSINDAY) <= $this->get_end_date()) {
416
- if (($this->get_start_date()+ $SECSINDAY) == $this->get_end_date()) {
417
- $this->gc_day_type = $this->SINGLE_WHOLE_DAY;
418
- } else {
419
- if ((date('g:i a',$this->get_start_date())=='12:00 am')&&(date('g:i a',$this->get_end_date())=='12:00 am')){
420
- $this->gc_day_type = $this->MULTIPLE_WHOLE_DAY;
421
- }else{
422
- $this->gc_day_type = $this->MULTIPLE_PART_DAY;
423
- }
424
- }
425
- }else
426
- $this->gc_day_type = $this->SINGLE_PART_DAY;
427
- }
428
- return $this->gc_day_type;
429
- }
430
-
431
- /**
432
- * Returns a unix timestamp of the given iso date.
433
- *
434
- * @param $iso_date
435
- * @return unix timestamp
436
- */
437
- function tstamptotime($iso_date) {
438
- // converts ISODATE to unix date
439
- // 1984-09-01T14:21:31Z
440
- sscanf($iso_date,"%u-%u-%uT%u:%u:%uZ",$year,$month,$day,$hour,$min,$sec);
441
- $newtstamp = mktime($hour,$min,$sec,$month,$day,$year);
442
- return $newtstamp;
443
- }
444
-
445
- /**
446
- * Returns an integer less than, equal to, or greater than zero if
447
- * the first argument is considered to be respectively less than,
448
- * equal to, or greater than the second.
449
- * This function can be used to sort an array of SimplePie_Item_GCalendar
450
- * items with usort.
451
- *
452
- * @see http://www.php.net/usort
453
- * @param $gc_sp_item1
454
- * @param $gc_sp_item2
455
- * @return the comparison integer
456
- */
457
- function compare($gc_sp_item1, $gc_sp_item2){
458
- $time1 = $gc_sp_item1->get_start_date();
459
- $time2 = $gc_sp_item2->get_start_date();
460
- $feed = $gc_sp_item1->get_feed();
461
- if(!$feed->orderby_by_start_date){
462
- $time1 = $gc_sp_item1->get_publish_date();
463
- $time2 = $gc_sp_item2->get_publish_date();
464
- }
465
- return $time1-$time2;
466
- }
467
- }
468
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/google-calendar-events.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the Google Calendar Events package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Google Calendar Events 0.5\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/google-calendar-events\n"
7
- "POT-Creation-Date: 2011-04-18 14:26:48+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -12,149 +12,224 @@ msgstr ""
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
- #: inc/gce-parser.php:276
16
- msgid "There are currently no upcoming events."
 
 
17
  msgstr ""
18
 
19
- #: google-calendar-events.php:163
20
- msgid "Settings"
 
21
  msgstr ""
22
 
23
- #. #-#-#-#-# plugin.pot (Google Calendar Events 0.5) #-#-#-#-#
24
- #. Plugin Name of the plugin/theme
25
- #: google-calendar-events.php:178 widget/gce-widget.php:6
26
- msgid "Google Calendar Events"
27
  msgstr ""
28
 
29
- #: google-calendar-events.php:190 admin/main.php:4
30
- msgid "Add Feed"
 
 
31
  msgstr ""
32
 
33
- #: google-calendar-events.php:191 google-calendar-events.php:201
34
- #: google-calendar-events.php:208
35
- msgid "Cancel"
 
36
  msgstr ""
37
 
38
- #: google-calendar-events.php:200
39
- msgid "Save Changes"
40
  msgstr ""
41
 
42
- #: google-calendar-events.php:207 admin/delete.php:9
43
- msgid "Delete Feed"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  msgstr ""
45
 
46
- #: google-calendar-events.php:389
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  msgid ""
48
- "No valid Feed IDs have been entered for this shortcode. Please check that "
49
- "you have entered the IDs correctly and that the Feeds have not been deleted."
 
 
 
 
 
 
 
50
  msgstr ""
51
 
52
- #: google-calendar-events.php:405 widget/gce-widget.php:85
53
  msgid ""
54
  "No feeds have been added yet. You can add a feed in the Google Calendar "
55
  "Events settings."
56
  msgstr ""
57
 
58
- #: google-calendar-events.php:468 google-calendar-events.php:491
59
- #: widget/gce-widget.php:166 widget/gce-widget.php:184
60
  msgid ""
61
- "The following feeds were not parsed successfully: %s. Please check that the "
62
- "feed URLs are correct and that the feeds have public sharing enabled."
63
  msgstr ""
64
 
65
- #: admin/main.php:2
66
- msgid "Add a New Feed"
67
  msgstr ""
68
 
69
- #: admin/main.php:4
70
- msgid "Click here to add a new feed"
71
  msgstr ""
72
 
73
- #: admin/main.php:7
74
- msgid "Current Feeds"
75
  msgstr ""
76
 
77
- #: admin/main.php:16
78
- msgid "You haven't added any Google Calendar feeds yet."
79
  msgstr ""
80
 
81
- #: admin/main.php:24 admin/main.php:32
82
- msgid "ID"
83
  msgstr ""
84
 
85
- #: admin/main.php:25 admin/main.php:33
86
- msgid "Title"
87
  msgstr ""
88
 
89
- #: admin/main.php:26 admin/main.php:34
90
- msgid "URL"
91
  msgstr ""
92
 
93
- #: admin/main.php:47
94
- msgid "Edit"
95
  msgstr ""
96
 
97
- #: admin/main.php:47
98
- msgid "Delete"
 
 
 
 
 
99
  msgstr ""
100
 
101
- #: admin/main.php:61
102
- msgid "General Options"
103
  msgstr ""
104
 
105
- #: admin/main.php:65
106
- msgid "Custom stylesheet URL"
107
  msgstr ""
108
 
109
- #: admin/main.php:67
110
- msgid ""
111
- "If you want to make changes to the default CSS, make a copy of <code>google-"
112
- "calendar-events/css/gce-style.css</code> on your server. Make any \r\n"
113
- "\t\t\t\tchanges to the copy. Enter the URL to the copied file below."
114
  msgstr ""
115
 
116
- #: admin/main.php:73
117
- msgid "Add JavaScript to footer?"
118
  msgstr ""
119
 
120
- #: admin/main.php:75
121
- msgid ""
122
- "If you are having issues with tooltips not appearing or the AJAX "
123
- "functionality not working, try ticking the checkbox below."
124
  msgstr ""
125
 
126
- #: admin/main.php:80
127
- msgid "Loading text"
128
  msgstr ""
129
 
130
- #: admin/main.php:82
131
- msgid "Text to display while calendar data is loading (on AJAX requests)."
132
  msgstr ""
133
 
134
- #: admin/main.php:87
135
- msgid "Error message"
136
  msgstr ""
137
 
138
- #: admin/main.php:89
139
- msgid ""
140
- "An error message to display to non-admin users if events cannot be displayed "
141
- "for any reason (admins will see a message indicating the cause of the "
142
- "problem)."
143
  msgstr ""
144
 
145
- #: admin/main.php:98
146
- msgid "Save"
 
 
 
 
 
 
147
  msgstr ""
148
 
149
  #: admin/add.php:9
150
  msgid "Add a Feed"
151
  msgstr ""
152
 
153
- #: admin/add.php:11 admin/delete.php:11 admin/edit.php:11
154
  msgid "Feed ID"
155
  msgstr ""
156
 
157
- #: admin/add.php:12 admin/delete.php:12 admin/edit.php:12
158
  msgid "Feed Title"
159
  msgstr ""
160
 
@@ -246,13 +321,19 @@ msgstr ""
246
  msgid "Anything you like. 'Upcoming Club Events', for example."
247
  msgstr ""
248
 
249
- #: admin/add.php:73 admin/edit.php:70
250
  msgid ""
251
  "This will probably be something like: <code>http://www.google.com/calendar/"
252
- "feeds/your-email@gmail.com/public/full</code>."
 
 
 
 
 
 
253
  msgstr ""
254
 
255
- #: admin/add.php:82 admin/edit.php:81
256
  msgid ""
257
  "The point in time at which to start retrieving events. Use the text-box to "
258
  "specify an additional offset from you chosen start point. The offset should "
@@ -262,45 +343,77 @@ msgid ""
262
  "in the text-box."
263
  msgstr ""
264
 
265
- #: admin/add.php:100 admin/edit.php:101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
  msgid ""
267
  "The point in time at which to stop retrieving events. The instructions for "
268
  "the above option also apply here."
269
  msgstr ""
270
 
271
- #: admin/add.php:119 admin/edit.php:122
 
 
 
 
272
  msgid ""
273
  "Set this to a few more than you actually want to display (due to caching and "
274
  "timezone issues). The exact number to display can be configured per "
275
  "shortcode / widget."
276
  msgstr ""
277
 
278
- #: admin/add.php:128 admin/edit.php:133
279
  msgid ""
280
  "In <a href=\"http://php.net/manual/en/function.date.php\" target=\"_blank"
281
  "\">PHP date format</a>. Leave this blank if you'd rather stick with the "
282
  "default format for your blog."
283
  msgstr ""
284
 
285
- #: admin/add.php:137 admin/edit.php:144
286
  msgid ""
287
  "In <a href=\"http://php.net/manual/en/function.date.php\" target=\"_blank"
288
  "\">PHP date format</a>. Again, leave this blank to stick with the default."
289
  msgstr ""
290
 
291
- #: admin/add.php:150 admin/edit.php:159
292
  msgid ""
293
  "If you are having problems with dates and times displaying in the wrong "
294
  "timezone, select a city in your required timezone here."
295
  msgstr ""
296
 
297
- #: admin/add.php:159 admin/edit.php:170
298
  msgid ""
299
  "The length of time, in seconds, to cache the feed (43200 = 12 hours). If "
300
  "this feed changes regularly, you may want to reduce the cache duration."
301
  msgstr ""
302
 
303
- #: admin/add.php:168 admin/edit.php:181
304
  msgid ""
305
  "Show events that span multiple days on each day that they span (There are "
306
  "some <a href=\"http://www.rhanney.co.uk/2010/08/19/google-calendar-events-0-"
@@ -308,13 +421,13 @@ msgid ""
308
  "of)."
309
  msgstr ""
310
 
311
- #: admin/add.php:179 admin/edit.php:192
312
  msgid ""
313
  "These settings control what information will be displayed for this feed in "
314
  "the tooltip (for grids), or in a list."
315
  msgstr ""
316
 
317
- #: admin/add.php:185 admin/edit.php:200
318
  msgid ""
319
  "It is recommended that you use the event display builder option, as it "
320
  "provides much more flexibility than the simple display options. The event "
@@ -322,106 +435,363 @@ msgid ""
322
  "more!"
323
  msgstr ""
324
 
325
- #: admin/add.php:269 admin/edit.php:279
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
  msgid ""
327
  "You can use some HTML in the text fields, but ensure it is valid or things "
328
  "might go wonky. Text fields can be empty too."
329
  msgstr ""
330
 
331
- #: admin/add.php:275 admin/edit.php:287
332
  msgid "Select how to display the start date / time."
333
  msgstr ""
334
 
335
- #: admin/add.php:278 admin/edit.php:290
336
  msgid "Don't display start time or date"
337
  msgstr ""
338
 
339
- #: admin/add.php:279 admin/edit.php:291
340
  msgid "Display start time"
341
  msgstr ""
342
 
343
- #: admin/add.php:280 admin/edit.php:292
344
  msgid "Display start date"
345
  msgstr ""
346
 
347
- #: admin/add.php:281 admin/edit.php:293
348
  msgid "Display start time and date (in that order)"
349
  msgstr ""
350
 
351
- #: admin/add.php:282 admin/edit.php:294
352
  msgid "Display start date and time (in that order)"
353
  msgstr ""
354
 
355
- #: admin/add.php:285 admin/edit.php:297
356
  msgid "Text to display before the start time."
357
  msgstr ""
358
 
359
- #: admin/add.php:293 admin/edit.php:307
360
  msgid "Select how to display the end date / time."
361
  msgstr ""
362
 
363
- #: admin/add.php:296 admin/edit.php:310
364
  msgid "Don't display end time or date"
365
  msgstr ""
366
 
367
- #: admin/add.php:297 admin/edit.php:311
368
  msgid "Display end time"
369
  msgstr ""
370
 
371
- #: admin/add.php:298 admin/edit.php:312
372
  msgid "Display end date"
373
  msgstr ""
374
 
375
- #: admin/add.php:299 admin/edit.php:313
376
  msgid "Display end time and date (in that order)"
377
  msgstr ""
378
 
379
- #: admin/add.php:300 admin/edit.php:314
380
  msgid "Display end date and time (in that order)"
381
  msgstr ""
382
 
383
- #: admin/add.php:303 admin/edit.php:317
384
  msgid "Text to display before the end time."
385
  msgstr ""
386
 
387
- #: admin/add.php:311 admin/edit.php:327
388
  msgid ""
389
  "If you have chosen to display both the time and date above, enter the text / "
390
  "characters to display between the time and date here (including any spaces)."
391
  msgstr ""
392
 
393
- #: admin/add.php:320 admin/edit.php:338
394
  msgid "Show the location of events?"
395
  msgstr ""
396
 
397
- #: admin/add.php:322 admin/edit.php:340
398
  msgid "Text to display before the location."
399
  msgstr ""
400
 
401
- #: admin/add.php:331
402
  msgid ""
403
  "Show the description of events? (URLs in the description will be made into "
404
  "links)."
405
  msgstr ""
406
 
407
- #: admin/add.php:333 admin/edit.php:353
408
  msgid "Text to display before the description."
409
  msgstr ""
410
 
411
- #: admin/add.php:337 admin/edit.php:357
412
  msgid ""
413
  "Maximum number of words to show from description. Leave blank for no limit."
414
  msgstr ""
415
 
416
- #: admin/add.php:346 admin/edit.php:368
417
  msgid "Show a link to the Google Calendar page for an event?"
418
  msgstr ""
419
 
420
- #: admin/add.php:349 admin/edit.php:371
421
  msgid "Links open in a new window / tab?"
422
  msgstr ""
423
 
424
- #: admin/add.php:351 admin/edit.php:373
425
  msgid "The link text to be displayed."
426
  msgstr ""
427
 
@@ -431,6 +801,20 @@ msgid ""
431
  "widgets or shortcodes associated with this feed)."
432
  msgstr ""
433
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
  #: admin/edit.php:9
435
  msgid "Edit Feed"
436
  msgstr ""
@@ -441,56 +825,116 @@ msgid ""
441
  "Changes button."
442
  msgstr ""
443
 
444
- #: admin/edit.php:351
 
 
 
 
 
 
445
  msgid ""
446
  "Show the description of events? (URLs in the description will be made into "
447
  "links)."
448
  msgstr ""
449
 
450
- #: widget/gce-widget.php:6
451
- msgid ""
452
- "Display a list or calendar grid of events from one or more Google Calendar "
453
- "feeds you have added"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
  msgstr ""
455
 
456
- #: widget/gce-widget.php:42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
457
  msgid ""
458
- "No valid Feed IDs have been entered for this widget. Please check that you "
459
- "have entered the IDs correctly and that the Feeds have not been deleted."
 
460
  msgstr ""
461
 
462
- #: widget/gce-widget.php:113
 
 
 
 
463
  msgid ""
464
- "No feeds have been added yet. You can add feeds in the Google Calendar "
465
- "Events settings."
466
  msgstr ""
467
 
468
- #: widget/gce-widget.php:128
469
- msgid "Feed IDs to display in this widget, separated by commas (e.g. 1, 2, 4):"
470
  msgstr ""
471
 
472
- #: widget/gce-widget.php:132
473
- msgid "Display as:"
474
  msgstr ""
475
 
476
- #: widget/gce-widget.php:134
477
- msgid "Calendar Grid"
478
  msgstr ""
479
 
480
- #: widget/gce-widget.php:135
481
- msgid "Calendar Grid - with AJAX"
 
 
 
482
  msgstr ""
483
 
484
- #: widget/gce-widget.php:136
485
- msgid "List"
486
  msgstr ""
487
 
488
- #: widget/gce-widget.php:137
489
- msgid "List - grouped by date"
 
 
 
 
490
  msgstr ""
491
 
492
- #: widget/gce-widget.php:140
493
- msgid "Maximum no. events to display. Enter 0 to show all retrieved."
494
  msgstr ""
495
 
496
  #. Plugin URI of the plugin/theme
2
  # This file is distributed under the same license as the Google Calendar Events package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Google Calendar Events 0.6\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/google-calendar-events\n"
7
+ "POT-Creation-Date: 2011-04-29 08:54:59+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
+ #: inc/gce-feed.php:90
16
+ msgid ""
17
+ "Some data was retrieved, but could not be parsed successfully. Please ensure "
18
+ "your feed URL is correct."
19
  msgstr ""
20
 
21
+ #: inc/gce-feed.php:96
22
+ msgid ""
23
+ "The feed could not be found (404). Please ensure your feed URL is correct."
24
  msgstr ""
25
 
26
+ #: inc/gce-feed.php:99
27
+ msgid ""
28
+ "Access to this feed was denied (403). Please ensure you have public sharing "
29
+ "enabled for your calendar."
30
  msgstr ""
31
 
32
+ #: inc/gce-feed.php:102
33
+ msgid ""
34
+ "The feed data could not be retrieved. Error code: %s. Please ensure your "
35
+ "feed URL is correct."
36
  msgstr ""
37
 
38
+ #: inc/gce-parser.php:149
39
+ msgid ""
40
+ "1 or more of your feeds could not be displayed. The following errors "
41
+ "occurred:"
42
  msgstr ""
43
 
44
+ #: inc/gce-parser.php:152
45
+ msgid "Feed %s:"
46
  msgstr ""
47
 
48
+ #: inc/gce-parser.php:285
49
+ msgid "There are currently no events to display."
50
+ msgstr ""
51
+
52
+ #: inc/gce-event.php:368
53
+ msgid "%s year"
54
+ msgstr ""
55
+
56
+ #: inc/gce-event.php:368
57
+ msgid "%s years"
58
+ msgstr ""
59
+
60
+ #: inc/gce-event.php:369
61
+ msgid "%s month"
62
+ msgstr ""
63
+
64
+ #: inc/gce-event.php:369
65
+ msgid "%s months"
66
+ msgstr ""
67
+
68
+ #: inc/gce-event.php:370
69
+ msgid "%s week"
70
  msgstr ""
71
 
72
+ #: inc/gce-event.php:370
73
+ msgid "%s weeks"
74
+ msgstr ""
75
+
76
+ #: inc/gce-event.php:371
77
+ msgid "%s day"
78
+ msgstr ""
79
+
80
+ #: inc/gce-event.php:371
81
+ msgid "%s days"
82
+ msgstr ""
83
+
84
+ #: inc/gce-event.php:372
85
+ msgid "%s hour"
86
+ msgstr ""
87
+
88
+ #: inc/gce-event.php:372
89
+ msgid "%s hours"
90
+ msgstr ""
91
+
92
+ #: inc/gce-event.php:373
93
+ msgid "%s min"
94
+ msgstr ""
95
+
96
+ #: inc/gce-event.php:373
97
+ msgid "%s mins"
98
+ msgstr ""
99
+
100
+ #: inc/gce-event.php:397
101
+ msgctxt "human_time_diff"
102
+ msgid ", "
103
+ msgstr ""
104
+
105
+ #. #-#-#-#-# plugin.pot (Google Calendar Events 0.6) #-#-#-#-#
106
+ #. Plugin Name of the plugin/theme
107
+ #: widget/gce-widget.php:6 google-calendar-events.php:199
108
+ msgid "Google Calendar Events"
109
+ msgstr ""
110
+
111
+ #: widget/gce-widget.php:7
112
  msgid ""
113
+ "Display a list or calendar grid of events from one or more Google Calendar "
114
+ "feeds you have added"
115
+ msgstr ""
116
+
117
+ #: widget/gce-widget.php:44
118
+ msgid ""
119
+ "No valid Feed IDs have been entered for this widget. Please check that you "
120
+ "have entered the IDs correctly in the widget settings (Appearance > "
121
+ "Widgets), and that the Feeds have not been deleted."
122
  msgstr ""
123
 
124
+ #: widget/gce-widget.php:87 google-calendar-events.php:502
125
  msgid ""
126
  "No feeds have been added yet. You can add a feed in the Google Calendar "
127
  "Events settings."
128
  msgstr ""
129
 
130
+ #: widget/gce-widget.php:115
 
131
  msgid ""
132
+ "No feeds have been added yet. You can add feeds in the Google Calendar "
133
+ "Events settings."
134
  msgstr ""
135
 
136
+ #: widget/gce-widget.php:130
137
+ msgid "Feed IDs to display in this widget, separated by commas (e.g. 1, 2, 4):"
138
  msgstr ""
139
 
140
+ #: widget/gce-widget.php:134
141
+ msgid "Display as:"
142
  msgstr ""
143
 
144
+ #: widget/gce-widget.php:136
145
+ msgid "Calendar Grid"
146
  msgstr ""
147
 
148
+ #: widget/gce-widget.php:137
149
+ msgid "Calendar Grid - with AJAX"
150
  msgstr ""
151
 
152
+ #: widget/gce-widget.php:138
153
+ msgid "List"
154
  msgstr ""
155
 
156
+ #: widget/gce-widget.php:139
157
+ msgid "List - grouped by date"
158
  msgstr ""
159
 
160
+ #: widget/gce-widget.php:142
161
+ msgid "Maximum no. events to display. Enter 0 to show all retrieved."
162
  msgstr ""
163
 
164
+ #: google-calendar-events.php:184
165
+ msgid "Settings"
166
  msgstr ""
167
 
168
+ #: google-calendar-events.php:203
169
+ msgid ""
170
+ "<strong>Notice:</strong> The way in which Google Calendar Events stores "
171
+ "cached data has been much improved in version 0.6. As you have upgraded from "
172
+ "a previous version of the plugin, there is likely to be some data from the "
173
+ "old caching system hanging around in your database that is now useless. "
174
+ "Click below to clear expired cached data from your database."
175
  msgstr ""
176
 
177
+ #: google-calendar-events.php:204
178
+ msgid "Clear expired cached data"
179
  msgstr ""
180
 
181
+ #: google-calendar-events.php:205
182
+ msgid "or"
183
  msgstr ""
184
 
185
+ #: google-calendar-events.php:206
186
+ msgid "Ignore this notice"
 
 
 
187
  msgstr ""
188
 
189
+ #: google-calendar-events.php:221 admin/main.php:4
190
+ msgid "Add Feed"
191
  msgstr ""
192
 
193
+ #: google-calendar-events.php:222 google-calendar-events.php:228
194
+ #: google-calendar-events.php:238 google-calendar-events.php:245
195
+ msgid "Cancel"
 
196
  msgstr ""
197
 
198
+ #: google-calendar-events.php:227
199
+ msgid "Refresh Feed"
200
  msgstr ""
201
 
202
+ #: google-calendar-events.php:237
203
+ msgid "Save Changes"
204
  msgstr ""
205
 
206
+ #: google-calendar-events.php:244 admin/delete.php:9
207
+ msgid "Delete Feed"
208
  msgstr ""
209
 
210
+ #: google-calendar-events.php:266
211
+ msgid "Old cached data cleared."
 
 
 
212
  msgstr ""
213
 
214
+ #: google-calendar-events.php:442
215
+ msgid "General options updated."
216
+ msgstr ""
217
+
218
+ #: google-calendar-events.php:486
219
+ msgid ""
220
+ "No valid Feed IDs have been entered for this shortcode. Please check that "
221
+ "you have entered the IDs correctly and that the Feeds have not been deleted."
222
  msgstr ""
223
 
224
  #: admin/add.php:9
225
  msgid "Add a Feed"
226
  msgstr ""
227
 
228
+ #: admin/add.php:11 admin/delete.php:11 admin/refresh.php:11 admin/edit.php:11
229
  msgid "Feed ID"
230
  msgstr ""
231
 
232
+ #: admin/add.php:12 admin/delete.php:12 admin/refresh.php:12 admin/edit.php:12
233
  msgid "Feed Title"
234
  msgstr ""
235
 
321
  msgid "Anything you like. 'Upcoming Club Events', for example."
322
  msgstr ""
323
 
324
+ #: admin/add.php:73
325
  msgid ""
326
  "This will probably be something like: <code>http://www.google.com/calendar/"
327
+ "feeds/your-email@gmail.com/public/basic</code>."
328
+ msgstr ""
329
+
330
+ #: admin/add.php:75 admin/edit.php:72
331
+ msgid ""
332
+ "or: <code>http://www.google.com/calendar/feeds/your-email@gmail.com/private-"
333
+ "d65741b037h695ff274247f90746b2ty/basic</code>."
334
  msgstr ""
335
 
336
+ #: admin/add.php:84 admin/edit.php:83
337
  msgid ""
338
  "The point in time at which to start retrieving events. Use the text-box to "
339
  "specify an additional offset from you chosen start point. The offset should "
343
  "in the text-box."
344
  msgstr ""
345
 
346
+ #: admin/add.php:87 admin/add.php:105
347
+ msgid "Now"
348
+ msgstr ""
349
+
350
+ #: admin/add.php:88 admin/add.php:106
351
+ msgid "00:00 today"
352
+ msgstr ""
353
+
354
+ #: admin/add.php:89 admin/add.php:107
355
+ msgid "Start of current week"
356
+ msgstr ""
357
+
358
+ #: admin/add.php:90 admin/add.php:108
359
+ msgid "Start of current month"
360
+ msgstr ""
361
+
362
+ #: admin/add.php:91 admin/add.php:109
363
+ msgid "End of current month"
364
+ msgstr ""
365
+
366
+ #: admin/add.php:92
367
+ msgid "The beginning of time"
368
+ msgstr ""
369
+
370
+ #: admin/add.php:93 admin/add.php:111
371
+ msgid "Specific date / time"
372
+ msgstr ""
373
+
374
+ #: admin/add.php:102 admin/edit.php:103
375
  msgid ""
376
  "The point in time at which to stop retrieving events. The instructions for "
377
  "the above option also apply here."
378
  msgstr ""
379
 
380
+ #: admin/add.php:110
381
+ msgid "The end of time"
382
+ msgstr ""
383
+
384
+ #: admin/add.php:121 admin/edit.php:124
385
  msgid ""
386
  "Set this to a few more than you actually want to display (due to caching and "
387
  "timezone issues). The exact number to display can be configured per "
388
  "shortcode / widget."
389
  msgstr ""
390
 
391
+ #: admin/add.php:130 admin/edit.php:135
392
  msgid ""
393
  "In <a href=\"http://php.net/manual/en/function.date.php\" target=\"_blank"
394
  "\">PHP date format</a>. Leave this blank if you'd rather stick with the "
395
  "default format for your blog."
396
  msgstr ""
397
 
398
+ #: admin/add.php:139 admin/edit.php:146
399
  msgid ""
400
  "In <a href=\"http://php.net/manual/en/function.date.php\" target=\"_blank"
401
  "\">PHP date format</a>. Again, leave this blank to stick with the default."
402
  msgstr ""
403
 
404
+ #: admin/add.php:152 admin/edit.php:161
405
  msgid ""
406
  "If you are having problems with dates and times displaying in the wrong "
407
  "timezone, select a city in your required timezone here."
408
  msgstr ""
409
 
410
+ #: admin/add.php:161 admin/edit.php:172
411
  msgid ""
412
  "The length of time, in seconds, to cache the feed (43200 = 12 hours). If "
413
  "this feed changes regularly, you may want to reduce the cache duration."
414
  msgstr ""
415
 
416
+ #: admin/add.php:170 admin/edit.php:183
417
  msgid ""
418
  "Show events that span multiple days on each day that they span (There are "
419
  "some <a href=\"http://www.rhanney.co.uk/2010/08/19/google-calendar-events-0-"
421
  "of)."
422
  msgstr ""
423
 
424
+ #: admin/add.php:181 admin/edit.php:194
425
  msgid ""
426
  "These settings control what information will be displayed for this feed in "
427
  "the tooltip (for grids), or in a list."
428
  msgstr ""
429
 
430
+ #: admin/add.php:187 admin/edit.php:202
431
  msgid ""
432
  "It is recommended that you use the event display builder option, as it "
433
  "provides much more flexibility than the simple display options. The event "
435
  "more!"
436
  msgstr ""
437
 
438
+ #: admin/add.php:190 admin/edit.php:205
439
+ msgid "Event display builder"
440
+ msgstr ""
441
+
442
+ #: admin/add.php:191 admin/edit.php:206
443
+ msgid "Simple display options"
444
+ msgstr ""
445
+
446
+ #: admin/add.php:199 admin/edit.php:214
447
+ msgid ""
448
+ "Use the event display builder to customize how event information will be "
449
+ "displayed in the grid tooltips and in lists. Use HTML and the shortcodes "
450
+ "(explained below) to display the information you require. A basic example "
451
+ "display format is provided as a starting point. For more information, take a "
452
+ "look at the <a href=\"http://www.rhanney.co.uk/plugins/google-calendar-"
453
+ "events/event-display-builder\" target=\"_blank\">event display builder "
454
+ "guide</a>."
455
+ msgstr ""
456
+
457
+ #: admin/add.php:214 admin/edit.php:224
458
+ msgid ""
459
+ "(More information on all of the below shortcodes and attributes, and working "
460
+ "examples, can be found in the <a href=\"http://www.rhanney.co.uk/plugins/"
461
+ "google-calendar-events/event-display-builder\" target=\"_blank\">event "
462
+ "display builder guide</a>)"
463
+ msgstr ""
464
+
465
+ #: admin/add.php:215 admin/edit.php:225
466
+ msgid "Event information shortcodes:"
467
+ msgstr ""
468
+
469
+ #: admin/add.php:217 admin/edit.php:227
470
+ msgid ""
471
+ "The event title (possible attributes: <code>html</code>, <code>markdown</"
472
+ "code>)"
473
+ msgstr ""
474
+
475
+ #: admin/add.php:218 admin/edit.php:228
476
+ msgid ""
477
+ "The event start time. Will use the time format specified in the above "
478
+ "settings"
479
+ msgstr ""
480
+
481
+ #: admin/add.php:219 admin/edit.php:229
482
+ msgid ""
483
+ "The event start date. Will use the date format specified in the above "
484
+ "settings"
485
+ msgstr ""
486
+
487
+ #: admin/add.php:220 admin/edit.php:230
488
+ msgid ""
489
+ "The event start date / time. Will use the format specified in the "
490
+ "<code>format</code> attribute (possible attributes: <code>format</code>)"
491
+ msgstr ""
492
+
493
+ #: admin/add.php:221 admin/edit.php:231
494
+ msgid ""
495
+ "The difference between the start time of the event and the time now, in "
496
+ "human-readable format, such as '1 hour', '4 days', '15 mins' (possible "
497
+ "attributes: <code>precision</code>)"
498
+ msgstr ""
499
+
500
+ #: admin/add.php:222 admin/edit.php:232
501
+ msgid ""
502
+ "The event end time. Will use the time format specified in the above settings"
503
+ msgstr ""
504
+
505
+ #: admin/add.php:223 admin/edit.php:233
506
+ msgid ""
507
+ "The event end date. Will use the date format specified in the above settings"
508
+ msgstr ""
509
+
510
+ #: admin/add.php:224 admin/edit.php:234
511
+ msgid ""
512
+ "The event end date / time. Will use the format specified in the "
513
+ "<code>format</code> attribute (possible attributes: <code>format</code>)"
514
+ msgstr ""
515
+
516
+ #: admin/add.php:225 admin/edit.php:235
517
+ msgid ""
518
+ "The difference between the end time of the event and the time now, in human-"
519
+ "readable format (possible attributes: <code>precision</code>)"
520
+ msgstr ""
521
+
522
+ #: admin/add.php:226 admin/edit.php:236
523
+ msgid ""
524
+ "The event location (possible attributes: <code>html</code>, <code>markdown</"
525
+ "code>)"
526
+ msgstr ""
527
+
528
+ #: admin/add.php:227 admin/edit.php:237
529
+ msgid ""
530
+ "Anything between the opening and closing shortcode tags (inlcuding further "
531
+ "shortcodes) will be linked to Google Maps, using the event location as a "
532
+ "search parameter (possible attributes: <code>newwindow</code>)"
533
+ msgstr ""
534
+
535
+ #: admin/add.php:228 admin/edit.php:238
536
+ msgid ""
537
+ "The event description (possible attributes: <code>html</code>, "
538
+ "<code>markdown</code>, <code>limit</code>)"
539
+ msgstr ""
540
+
541
+ #: admin/add.php:229 admin/edit.php:239
542
+ msgid ""
543
+ "Anything between the opening and closing shortcode tags (inlcuding further "
544
+ "shortcodes) will be linked to the Google Calendar page for the event "
545
+ "(possible attributes: <code>newwindow</code>)"
546
+ msgstr ""
547
+
548
+ #: admin/add.php:230 admin/edit.php:240
549
+ msgid "The raw URL to the Google Calendar page for the event"
550
+ msgstr ""
551
+
552
+ #: admin/add.php:231 admin/edit.php:241
553
+ msgid ""
554
+ "The length of the event, in human-readable format (possible attributes: "
555
+ "<code>precision</code>)"
556
+ msgstr ""
557
+
558
+ #: admin/add.php:233 admin/edit.php:243
559
+ msgid "Feed information shortcodes:"
560
+ msgstr ""
561
+
562
+ #: admin/add.php:235 admin/edit.php:245
563
+ msgid "The title of the feed from which the event comes"
564
+ msgstr ""
565
+
566
+ #: admin/add.php:236 admin/edit.php:246
567
+ msgid "The ID of the feed from which the event comes"
568
+ msgstr ""
569
+
570
+ #: admin/add.php:238 admin/edit.php:248
571
+ msgid "Conditional shortcodes:"
572
+ msgstr ""
573
+
574
+ #: admin/add.php:239 admin/edit.php:249
575
+ msgid ""
576
+ "Anything entered between the opening and closing tags of each of the "
577
+ "following shortcodes will only be displayed if its condition (below) is met."
578
+ msgstr ""
579
+
580
+ #: admin/add.php:241 admin/edit.php:251
581
+ msgid "The event is an all-day event"
582
+ msgstr ""
583
+
584
+ #: admin/add.php:242 admin/edit.php:252
585
+ msgid "The event is not an all-day event"
586
+ msgstr ""
587
+
588
+ #: admin/add.php:243 admin/edit.php:253
589
+ msgid "The event has a title"
590
+ msgstr ""
591
+
592
+ #: admin/add.php:244 admin/edit.php:254
593
+ msgid "The event has a description"
594
+ msgstr ""
595
+
596
+ #: admin/add.php:245 admin/edit.php:255
597
+ msgid "The event has a location"
598
+ msgstr ""
599
+
600
+ #: admin/add.php:246 admin/edit.php:256
601
+ msgid "The event is to be displayed in a tooltip (not a list)"
602
+ msgstr ""
603
+
604
+ #: admin/add.php:247 admin/edit.php:257
605
+ msgid "The event is to be displayed in a list (not a tooltip)"
606
+ msgstr ""
607
+
608
+ #: admin/add.php:248 admin/edit.php:258
609
+ msgid ""
610
+ "The event is taking place now (after the start time, but before the end time)"
611
+ msgstr ""
612
+
613
+ #: admin/add.php:249 admin/edit.php:259
614
+ msgid "The event is not taking place now (may have ended or not yet started)"
615
+ msgstr ""
616
+
617
+ #: admin/add.php:250 admin/edit.php:260
618
+ msgid "The event has started (even if it has also ended)"
619
+ msgstr ""
620
+
621
+ #: admin/add.php:251 admin/edit.php:261
622
+ msgid "The event has not started"
623
+ msgstr ""
624
+
625
+ #: admin/add.php:252 admin/edit.php:262
626
+ msgid "The event has ended"
627
+ msgstr ""
628
+
629
+ #: admin/add.php:253 admin/edit.php:263
630
+ msgid "The event has not ended (even if it hasn't started)"
631
+ msgstr ""
632
+
633
+ #: admin/add.php:254 admin/edit.php:264
634
+ msgid "The event is the first of the day"
635
+ msgstr ""
636
+
637
+ #: admin/add.php:255 admin/edit.php:265
638
+ msgid "The event is not the first of the day"
639
+ msgstr ""
640
+
641
+ #: admin/add.php:256 admin/edit.php:266
642
+ msgid "The event spans multiple days"
643
+ msgstr ""
644
+
645
+ #: admin/add.php:257 admin/edit.php:267
646
+ msgid "The event does not span multiple days"
647
+ msgstr ""
648
+
649
+ #: admin/add.php:259 admin/edit.php:269
650
+ msgid "Attributes:"
651
+ msgstr ""
652
+
653
+ #: admin/add.php:260 admin/edit.php:270
654
+ msgid "The possible attributes mentioned above are explained here:"
655
+ msgstr ""
656
+
657
+ #: admin/add.php:262 admin/edit.php:272
658
+ msgid ""
659
+ "Whether or not to parse HTML that has been entered in the relevant field. "
660
+ "Can be <code>true</code> or <code>false</code>"
661
+ msgstr ""
662
+
663
+ #: admin/add.php:263 admin/edit.php:273
664
+ msgid ""
665
+ "Whether or not to parse <a href=\"http://daringfireball.net/projects/markdown"
666
+ "\" target=\"_blank\">Markdown</a> that has been entered in the relevant "
667
+ "field. <a href=\"http://michelf.com/projects/php-markdown\" target=\"_blank"
668
+ "\">PHP Markdown</a> must be installed for this to work. Can be <code>true</"
669
+ "code> or <code>false</code>"
670
+ msgstr ""
671
+
672
+ #: admin/add.php:264 admin/edit.php:274
673
+ msgid "The word limit for the field. Should be specified as a positive integer"
674
+ msgstr ""
675
+
676
+ #: admin/add.php:265 admin/edit.php:275
677
+ msgid ""
678
+ "The date / time format to use. Should specified as a <a href=\"http://php."
679
+ "net/manual/en/function.date.php\" target=\"_blank\">PHP date format</a> "
680
+ "string"
681
+ msgstr ""
682
+
683
+ #: admin/add.php:266 admin/edit.php:276
684
+ msgid ""
685
+ "Whether or not the link should open in a new window / tab. Can be "
686
+ "<code>true</code> or <code>false</code>"
687
+ msgstr ""
688
+
689
+ #: admin/add.php:267 admin/edit.php:277
690
+ msgid ""
691
+ "How precise to be when displaying a time difference in human-readable "
692
+ "format. Should be specified as a positive integer"
693
+ msgstr ""
694
+
695
+ #: admin/add.php:275 admin/edit.php:285
696
  msgid ""
697
  "You can use some HTML in the text fields, but ensure it is valid or things "
698
  "might go wonky. Text fields can be empty too."
699
  msgstr ""
700
 
701
+ #: admin/add.php:281 admin/edit.php:293
702
  msgid "Select how to display the start date / time."
703
  msgstr ""
704
 
705
+ #: admin/add.php:284 admin/edit.php:296
706
  msgid "Don't display start time or date"
707
  msgstr ""
708
 
709
+ #: admin/add.php:285 admin/edit.php:297
710
  msgid "Display start time"
711
  msgstr ""
712
 
713
+ #: admin/add.php:286 admin/edit.php:298
714
  msgid "Display start date"
715
  msgstr ""
716
 
717
+ #: admin/add.php:287 admin/edit.php:299
718
  msgid "Display start time and date (in that order)"
719
  msgstr ""
720
 
721
+ #: admin/add.php:288 admin/edit.php:300
722
  msgid "Display start date and time (in that order)"
723
  msgstr ""
724
 
725
+ #: admin/add.php:291 admin/edit.php:303
726
  msgid "Text to display before the start time."
727
  msgstr ""
728
 
729
+ #: admin/add.php:299 admin/edit.php:313
730
  msgid "Select how to display the end date / time."
731
  msgstr ""
732
 
733
+ #: admin/add.php:302 admin/edit.php:316
734
  msgid "Don't display end time or date"
735
  msgstr ""
736
 
737
+ #: admin/add.php:303 admin/edit.php:317
738
  msgid "Display end time"
739
  msgstr ""
740
 
741
+ #: admin/add.php:304 admin/edit.php:318
742
  msgid "Display end date"
743
  msgstr ""
744
 
745
+ #: admin/add.php:305 admin/edit.php:319
746
  msgid "Display end time and date (in that order)"
747
  msgstr ""
748
 
749
+ #: admin/add.php:306 admin/edit.php:320
750
  msgid "Display end date and time (in that order)"
751
  msgstr ""
752
 
753
+ #: admin/add.php:309 admin/edit.php:323
754
  msgid "Text to display before the end time."
755
  msgstr ""
756
 
757
+ #: admin/add.php:317 admin/edit.php:333
758
  msgid ""
759
  "If you have chosen to display both the time and date above, enter the text / "
760
  "characters to display between the time and date here (including any spaces)."
761
  msgstr ""
762
 
763
+ #: admin/add.php:326 admin/edit.php:344
764
  msgid "Show the location of events?"
765
  msgstr ""
766
 
767
+ #: admin/add.php:328 admin/edit.php:346
768
  msgid "Text to display before the location."
769
  msgstr ""
770
 
771
+ #: admin/add.php:337
772
  msgid ""
773
  "Show the description of events? (URLs in the description will be made into "
774
  "links)."
775
  msgstr ""
776
 
777
+ #: admin/add.php:339 admin/edit.php:359
778
  msgid "Text to display before the description."
779
  msgstr ""
780
 
781
+ #: admin/add.php:343 admin/edit.php:363
782
  msgid ""
783
  "Maximum number of words to show from description. Leave blank for no limit."
784
  msgstr ""
785
 
786
+ #: admin/add.php:352 admin/edit.php:374
787
  msgid "Show a link to the Google Calendar page for an event?"
788
  msgstr ""
789
 
790
+ #: admin/add.php:355 admin/edit.php:377
791
  msgid "Links open in a new window / tab?"
792
  msgstr ""
793
 
794
+ #: admin/add.php:357 admin/edit.php:379
795
  msgid "The link text to be displayed."
796
  msgstr ""
797
 
801
  "widgets or shortcodes associated with this feed)."
802
  msgstr ""
803
 
804
+ #: admin/refresh.php:9
805
+ msgid "Refresh Feed Cache"
806
+ msgstr ""
807
+
808
+ #: admin/refresh.php:17
809
+ msgid ""
810
+ "The plugin will automatically refresh the cache when it expires, but you can "
811
+ "manually clear the cache now by clicking the button below."
812
+ msgstr ""
813
+
814
+ #: admin/refresh.php:18
815
+ msgid "Are you want you want to clear the cache data for this feed?"
816
+ msgstr ""
817
+
818
  #: admin/edit.php:9
819
  msgid "Edit Feed"
820
  msgstr ""
825
  "Changes button."
826
  msgstr ""
827
 
828
+ #: admin/edit.php:70
829
+ msgid ""
830
+ "This will probably be something like: <code>http://www.google.com/calendar/"
831
+ "feeds/your-email@gmail.com/public/full</code>."
832
+ msgstr ""
833
+
834
+ #: admin/edit.php:357
835
  msgid ""
836
  "Show the description of events? (URLs in the description will be made into "
837
  "links)."
838
  msgstr ""
839
 
840
+ #: admin/main.php:2
841
+ msgid "Add a New Feed"
842
+ msgstr ""
843
+
844
+ #: admin/main.php:4
845
+ msgid "Click here to add a new feed"
846
+ msgstr ""
847
+
848
+ #: admin/main.php:7
849
+ msgid "Current Feeds"
850
+ msgstr ""
851
+
852
+ #: admin/main.php:16
853
+ msgid "You haven't added any Google Calendar feeds yet."
854
+ msgstr ""
855
+
856
+ #: admin/main.php:24 admin/main.php:32
857
+ msgid "ID"
858
+ msgstr ""
859
+
860
+ #: admin/main.php:25 admin/main.php:33
861
+ msgid "Title"
862
  msgstr ""
863
 
864
+ #: admin/main.php:26 admin/main.php:34
865
+ msgid "URL"
866
+ msgstr ""
867
+
868
+ #: admin/main.php:47
869
+ msgid "Refresh"
870
+ msgstr ""
871
+
872
+ #: admin/main.php:47
873
+ msgid "Edit"
874
+ msgstr ""
875
+
876
+ #: admin/main.php:47
877
+ msgid "Delete"
878
+ msgstr ""
879
+
880
+ #: admin/main.php:61
881
+ msgid "General Options"
882
+ msgstr ""
883
+
884
+ #: admin/main.php:65
885
+ msgid "Custom stylesheet URL"
886
+ msgstr ""
887
+
888
+ #: admin/main.php:67
889
  msgid ""
890
+ "If you want to alter the default plugin styling, create a new stylesheet on "
891
+ "your server (not in the <code>google-calendar-events</code> directory) and "
892
+ "then enter its URL below."
893
  msgstr ""
894
 
895
+ #: admin/main.php:72
896
+ msgid "Add JavaScript to footer?"
897
+ msgstr ""
898
+
899
+ #: admin/main.php:74
900
  msgid ""
901
+ "If you are having issues with tooltips not appearing or the AJAX "
902
+ "functionality not working, try ticking the checkbox below."
903
  msgstr ""
904
 
905
+ #: admin/main.php:79
906
+ msgid "Loading text"
907
  msgstr ""
908
 
909
+ #: admin/main.php:81
910
+ msgid "Text to display while calendar data is loading (on AJAX requests)."
911
  msgstr ""
912
 
913
+ #: admin/main.php:86
914
+ msgid "Error message"
915
  msgstr ""
916
 
917
+ #: admin/main.php:88
918
+ msgid ""
919
+ "An error message to display to non-admin users if events cannot be displayed "
920
+ "for any reason (admins will see a message indicating the cause of the "
921
+ "problem)."
922
  msgstr ""
923
 
924
+ #: admin/main.php:93
925
+ msgid "Optimise event retrieval?"
926
  msgstr ""
927
 
928
+ #: admin/main.php:95
929
+ msgid ""
930
+ "If this option is enabled, the plugin will use an experimental feature of "
931
+ "the Google Data API, which can improve performance significantly, especially "
932
+ "with large numbers of events. Google could potentially remove / change this "
933
+ "feature at any time."
934
  msgstr ""
935
 
936
+ #: admin/main.php:104
937
+ msgid "Save"
938
  msgstr ""
939
 
940
  #. Plugin URI of the plugin/theme
license.txt ADDED
@@ -0,0 +1,288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
6
+
7
+ Everyone is permitted to copy and distribute verbatim copies
8
+ of this license document, but changing it is not allowed.
9
+
10
+ Preamble
11
+
12
+ The licenses for most software are designed to take away your
13
+ freedom to share and change it. By contrast, the GNU General Public
14
+ License is intended to guarantee your freedom to share and change free
15
+ software--to make sure the software is free for all its users. This
16
+ General Public License applies to most of the Free Software
17
+ Foundation's software and to any other program whose authors commit to
18
+ using it. (Some other Free Software Foundation software is covered by
19
+ the GNU Library General Public License instead.) You can apply it to
20
+ your programs, too.
21
+
22
+ When we speak of free software, we are referring to freedom, not
23
+ price. Our General Public Licenses are designed to make sure that you
24
+ have the freedom to distribute copies of free software (and charge for
25
+ this service if you wish), that you receive source code or can get it
26
+ if you want it, that you can change the software or use pieces of it
27
+ in new free programs; and that you know you can do these things.
28
+
29
+ To protect your rights, we need to make restrictions that forbid
30
+ anyone to deny you these rights or to ask you to surrender the rights.
31
+ These restrictions translate to certain responsibilities for you if you
32
+ distribute copies of the software, or if you modify it.
33
+
34
+ For example, if you distribute copies of such a program, whether
35
+ gratis or for a fee, you must give the recipients all the rights that
36
+ you have. You must make sure that they, too, receive or can get the
37
+ source code. And you must show them these terms so they know their
38
+ rights.
39
+
40
+ We protect your rights with two steps: (1) copyright the software, and
41
+ (2) offer you this license which gives you legal permission to copy,
42
+ distribute and/or modify the software.
43
+
44
+ Also, for each author's protection and ours, we want to make certain
45
+ that everyone understands that there is no warranty for this free
46
+ software. If the software is modified by someone else and passed on, we
47
+ want its recipients to know that what they have is not the original, so
48
+ that any problems introduced by others will not reflect on the original
49
+ authors' reputations.
50
+
51
+ Finally, any free program is threatened constantly by software
52
+ patents. We wish to avoid the danger that redistributors of a free
53
+ program will individually obtain patent licenses, in effect making the
54
+ program proprietary. To prevent this, we have made it clear that any
55
+ patent must be licensed for everyone's free use or not licensed at all.
56
+
57
+ The precise terms and conditions for copying, distribution and
58
+ modification follow.
59
+
60
+ GNU GENERAL PUBLIC LICENSE
61
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
62
+
63
+ 0. This License applies to any program or other work which contains
64
+ a notice placed by the copyright holder saying it may be distributed
65
+ under the terms of this General Public License. The "Program", below,
66
+ refers to any such program or work, and a "work based on the Program"
67
+ means either the Program or any derivative work under copyright law:
68
+ that is to say, a work containing the Program or a portion of it,
69
+ either verbatim or with modifications and/or translated into another
70
+ language. (Hereinafter, translation is included without limitation in
71
+ the term "modification".) Each licensee is addressed as "you".
72
+
73
+ Activities other than copying, distribution and modification are not
74
+ covered by this License; they are outside its scope. The act of
75
+ running the Program is not restricted, and the output from the Program
76
+ is covered only if its contents constitute a work based on the
77
+ Program (independent of having been made by running the Program).
78
+ Whether that is true depends on what the Program does.
79
+
80
+ 1. You may copy and distribute verbatim copies of the Program's
81
+ source code as you receive it, in any medium, provided that you
82
+ conspicuously and appropriately publish on each copy an appropriate
83
+ copyright notice and disclaimer of warranty; keep intact all the
84
+ notices that refer to this License and to the absence of any warranty;
85
+ and give any other recipients of the Program a copy of this License
86
+ along with the Program.
87
+
88
+ You may charge a fee for the physical act of transferring a copy, and
89
+ you may at your option offer warranty protection in exchange for a fee.
90
+
91
+ 2. You may modify your copy or copies of the Program or any portion
92
+ of it, thus forming a work based on the Program, and copy and
93
+ distribute such modifications or work under the terms of Section 1
94
+ above, provided that you also meet all of these conditions:
95
+
96
+ a) You must cause the modified files to carry prominent notices
97
+ stating that you changed the files and the date of any change.
98
+
99
+ b) You must cause any work that you distribute or publish, that in
100
+ whole or in part contains or is derived from the Program or any
101
+ part thereof, to be licensed as a whole at no charge to all third
102
+ parties under the terms of this License.
103
+
104
+ c) If the modified program normally reads commands interactively
105
+ when run, you must cause it, when started running for such
106
+ interactive use in the most ordinary way, to print or display an
107
+ announcement including an appropriate copyright notice and a
108
+ notice that there is no warranty (or else, saying that you provide
109
+ a warranty) and that users may redistribute the program under
110
+ these conditions, and telling the user how to view a copy of this
111
+ License. (Exception: if the Program itself is interactive but
112
+ does not normally print such an announcement, your work based on
113
+ the Program is not required to print an announcement.)
114
+
115
+ These requirements apply to the modified work as a whole. If
116
+ identifiable sections of that work are not derived from the Program,
117
+ and can be reasonably considered independent and separate works in
118
+ themselves, then this License, and its terms, do not apply to those
119
+ sections when you distribute them as separate works. But when you
120
+ distribute the same sections as part of a whole which is a work based
121
+ on the Program, the distribution of the whole must be on the terms of
122
+ this License, whose permissions for other licensees extend to the
123
+ entire whole, and thus to each and every part regardless of who wrote it.
124
+ Thus, it is not the intent of this section to claim rights or contest
125
+ your rights to work written entirely by you; rather, the intent is to
126
+ exercise the right to control the distribution of derivative or
127
+ collective works based on the Program.
128
+
129
+ In addition, mere aggregation of another work not based on the Program
130
+ with the Program (or with a work based on the Program) on a volume of
131
+ a storage or distribution medium does not bring the other work under
132
+ the scope of this License.
133
+
134
+ 3. You may copy and distribute the Program (or a work based on it,
135
+ under Section 2) in object code or executable form under the terms of
136
+ Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+ a) Accompany it with the complete corresponding machine-readable
139
+ source code, which must be distributed under the terms of Sections
140
+ 1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+ b) Accompany it with a written offer, valid for at least three
143
+ years, to give any third party, for a charge no more than your
144
+ cost of physically performing source distribution, a complete
145
+ machine-readable copy of the corresponding source code, to be
146
+ distributed under the terms of Sections 1 and 2 above on a medium
147
+ customarily used for software interchange; or,
148
+
149
+ c) Accompany it with the information you received as to the offer
150
+ to distribute corresponding source code. (This alternative is
151
+ allowed only for noncommercial distribution and only if you
152
+ received the program in object code or executable form with such
153
+ an offer, in accord with Subsection b above.)
154
+
155
+ The source code for a work means the preferred form of the work for
156
+ making modifications to it. For an executable work, complete source
157
+ code means all the source code for all modules it contains, plus any
158
+ associated interface definition files, plus the scripts used to
159
+ control compilation and installation of the executable. However, as a
160
+ special exception, the source code distributed need not include
161
+ anything that is normally distributed (in either source or binary
162
+ form) with the major components (compiler, kernel, and so on) of the
163
+ operating system on which the executable runs, unless that component
164
+ itself accompanies the executable.
165
+
166
+ If distribution of executable or object code is made by offering
167
+ access to copy from a designated place, then offering equivalent
168
+ access to copy the source code from the same place counts as
169
+ distribution of the source code, even though third parties are not
170
+ compelled to copy the source along with the object code.
171
+
172
+ 4. You may not copy, modify, sublicense, or distribute the Program
173
+ except as expressly provided under this License. Any attempt
174
+ otherwise to copy, modify, sublicense or distribute the Program is
175
+ void, and will automatically terminate your rights under this License.
176
+ However, parties who have received copies, or rights, from you under
177
+ this License will not have their licenses terminated so long as such
178
+ parties remain in full compliance.
179
+
180
+ 5. You are not required to accept this License, since you have not
181
+ signed it. However, nothing else grants you permission to modify or
182
+ distribute the Program or its derivative works. These actions are
183
+ prohibited by law if you do not accept this License. Therefore, by
184
+ modifying or distributing the Program (or any work based on the
185
+ Program), you indicate your acceptance of this License to do so, and
186
+ all its terms and conditions for copying, distributing or modifying
187
+ the Program or works based on it.
188
+
189
+ 6. Each time you redistribute the Program (or any work based on the
190
+ Program), the recipient automatically receives a license from the
191
+ original licensor to copy, distribute or modify the Program subject to
192
+ these terms and conditions. You may not impose any further
193
+ restrictions on the recipients' exercise of the rights granted herein.
194
+ You are not responsible for enforcing compliance by third parties to
195
+ this License.
196
+
197
+ 7. If, as a consequence of a court judgment or allegation of patent
198
+ infringement or for any other reason (not limited to patent issues),
199
+ conditions are imposed on you (whether by court order, agreement or
200
+ otherwise) that contradict the conditions of this License, they do not
201
+ excuse you from the conditions of this License. If you cannot
202
+ distribute so as to satisfy simultaneously your obligations under this
203
+ License and any other pertinent obligations, then as a consequence you
204
+ may not distribute the Program at all. For example, if a patent
205
+ license would not permit royalty-free redistribution of the Program by
206
+ all those who receive copies directly or indirectly through you, then
207
+ the only way you could satisfy both it and this License would be to
208
+ refrain entirely from distribution of the Program.
209
+
210
+ If any portion of this section is held invalid or unenforceable under
211
+ any particular circumstance, the balance of the section is intended to
212
+ apply and the section as a whole is intended to apply in other
213
+ circumstances.
214
+
215
+ It is not the purpose of this section to induce you to infringe any
216
+ patents or other property right claims or to contest validity of any
217
+ such claims; this section has the sole purpose of protecting the
218
+ integrity of the free software distribution system, which is
219
+ implemented by public license practices. Many people have made
220
+ generous contributions to the wide range of software distributed
221
+ through that system in reliance on consistent application of that
222
+ system; it is up to the author/donor to decide if he or she is willing
223
+ to distribute software through any other system and a licensee cannot
224
+ impose that choice.
225
+
226
+ This section is intended to make thoroughly clear what is believed to
227
+ be a consequence of the rest of this License.
228
+
229
+ 8. If the distribution and/or use of the Program is restricted in
230
+ certain countries either by patents or by copyrighted interfaces, the
231
+ original copyright holder who places the Program under this License
232
+ may add an explicit geographical distribution limitation excluding
233
+ those countries, so that distribution is permitted only in or among
234
+ countries not thus excluded. In such case, this License incorporates
235
+ the limitation as if written in the body of this License.
236
+
237
+ 9. The Free Software Foundation may publish revised and/or new versions
238
+ of the General Public License from time to time. Such new versions will
239
+ be similar in spirit to the present version, but may differ in detail to
240
+ address new problems or concerns.
241
+
242
+ Each version is given a distinguishing version number. If the Program
243
+ specifies a version number of this License which applies to it and "any
244
+ later version", you have the option of following the terms and conditions
245
+ either of that version or of any later version published by the Free
246
+ Software Foundation. If the Program does not specify a version number of
247
+ this License, you may choose any version ever published by the Free Software
248
+ Foundation.
249
+
250
+ 10. If you wish to incorporate parts of the Program into other free
251
+ programs whose distribution conditions are different, write to the author
252
+ to ask for permission. For software which is copyrighted by the Free
253
+ Software Foundation, write to the Free Software Foundation; we sometimes
254
+ make exceptions for this. Our decision will be guided by the two goals
255
+ of preserving the free status of all derivatives of our free software and
256
+ of promoting the sharing and reuse of software generally.
257
+
258
+ NO WARRANTY
259
+
260
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+ REPAIR OR CORRECTION.
269
+
270
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
+ POSSIBILITY OF SUCH DAMAGES.
279
+
280
+ END OF TERMS AND CONDITIONS
281
+
282
+
283
+ WRITTEN OFFER
284
+
285
+ The source code for any program binaries or compressed scripts that are
286
+ included with WordPress can be freely obtained at the following URL:
287
+
288
+ http://wordpress.org/download/source/
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: rosshanney
3
  Donate link: http://www.rhanney.co.uk/plugins/google-calendar-events/#donate
4
  Tags: google, google calendar, calendar, event, events, ajax, widget
5
  Requires at least: 2.9.2
6
- Tested up to: 3.1.1
7
- Stable tag: 0.5
8
 
9
  Parses Google Calendar feeds and displays the events as a calendar grid or list on a page, post or widget.
10
 
@@ -30,9 +30,9 @@ There is also a demonstration page showing the plugin in action:
30
 
31
  * [Demo Page](http://www.rhanney.co.uk/plugins/google-calendar-events/gce-demo)
32
 
33
- I've also written a post explaining the new features and changes in version 0.5:
34
 
35
- * [0.5 Features](http://www.rhanney.co.uk/2011/04/18/google-calendar-events-0-5)
36
 
37
  == Installation ==
38
 
@@ -56,6 +56,14 @@ You can now start adding feeds. Visit the [plugin homepage](http://www.rhanney.c
56
 
57
  == Changelog ==
58
 
 
 
 
 
 
 
 
 
59
  = 0.5 =
60
  * Added [event display builder](http://www.rhanney.co.uk/plugins/google-calendar-events/event-display-builder) feature, which vastly improves the customization possibilities of the plugin. This feature encompasses many of the most requested features, such as:
61
  - All-day events can be handled differently than 'normal' events
@@ -127,4 +135,4 @@ Event retrieval date / time range is now much more flexible. Also adds event dis
127
 
128
  == Frequently Asked Questions ==
129
 
130
- Please visit the [plugin homepage](http://www.rhanney.co.uk/plugins/google-calendar-events) and leave a comment for help, or [contact me](http://www.rhanney.co.uk/contact) directly.
3
  Donate link: http://www.rhanney.co.uk/plugins/google-calendar-events/#donate
4
  Tags: google, google calendar, calendar, event, events, ajax, widget
5
  Requires at least: 2.9.2
6
+ Tested up to: 3.1.2
7
+ Stable tag: 0.6
8
 
9
  Parses Google Calendar feeds and displays the events as a calendar grid or list on a page, post or widget.
10
 
30
 
31
  * [Demo Page](http://www.rhanney.co.uk/plugins/google-calendar-events/gce-demo)
32
 
33
+ I've also written a post explaining the improvements and changes in version 0.6:
34
 
35
+ * [0.6 Features](http://www.rhanney.co.uk/2011/04/29/google-calendar-events-0-6)
36
 
37
  == Installation ==
38
 
56
 
57
  == Changelog ==
58
 
59
+ = 0.6 =
60
+ * Drastically reduced memory usage
61
+ * Improved feed data caching system
62
+ * Improved error reporting
63
+ * General performance and efficiency improvements
64
+ * Added a few more shortcodes to the event display builder
65
+ * Other [miscellaneous changes / additions and bug fixes](http://www.rhanney.co.uk/2011/04/29/google-calendar-events-0-6)
66
+
67
  = 0.5 =
68
  * Added [event display builder](http://www.rhanney.co.uk/plugins/google-calendar-events/event-display-builder) feature, which vastly improves the customization possibilities of the plugin. This feature encompasses many of the most requested features, such as:
69
  - All-day events can be handled differently than 'normal' events
135
 
136
  == Frequently Asked Questions ==
137
 
138
+ Please visit the [FAQ page](http://www.rhanney.co.uk/plugins/google-calendar-events/frequently-asked-questions). If you have further questions, leave a comment on the [plugin homepage](http://www.rhanney.co.uk/plugins/google-calendar-events), or [send me an email](http://www.rhanney.co.uk/contact).
uninstall.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if(!defined('WP_UNINSTALL_PLUGIN')) die();
3
+
4
+ $gce_options = get_option('gce_options');
5
+
6
+ //Remove any cached feed data
7
+ foreach($gce_options as $gce_feed){
8
+ if(isset($gce_feed['id'])){
9
+ delete_transient('gce_feed_' . $gce_feed['id']);
10
+ delete_transient('gce_feed_' . $gce_feed['id'] . '_url');
11
+ }
12
+ }
13
+
14
+ //Delete plugin options
15
+ delete_option('gce_options');
16
+ delete_option('gce_general');
17
+ delete_option('gce_version');
18
+ ?>
widget/gce-widget.php CHANGED
@@ -1,9 +1,11 @@
1
  <?php
2
- require_once WP_PLUGIN_DIR . '/' . GCE_PLUGIN_NAME . '/inc/gce-parser.php';
3
-
4
  class GCE_Widget extends WP_Widget{
5
  function GCE_Widget(){
6
- parent::WP_Widget(false, $name = __('Google Calendar Events', GCE_TEXT_DOMAIN), array('description' => __('Display a list or calendar grid of events from one or more Google Calendar feeds you have added', GCE_TEXT_DOMAIN)));
 
 
 
 
7
  }
8
 
9
  function widget($args, $instance){
@@ -39,7 +41,7 @@ class GCE_Widget extends WP_Widget{
39
  //Check that at least one valid feed id has been entered
40
  if(count((array)$feed_ids) == 0 || $no_feeds_exist){
41
  if(current_user_can('manage_options')){
42
- _e('No valid Feed IDs have been entered for this widget. Please check that you have entered the IDs correctly and that the Feeds have not been deleted.', GCE_TEXT_DOMAIN);
43
  }else{
44
  $options = get_option(GCE_GENERAL_OPTIONS_NAME);
45
  echo $options['error'];
@@ -151,11 +153,20 @@ class GCE_Widget extends WP_Widget{
151
  }
152
 
153
  function gce_widget_content_grid($feed_ids, $title_text, $max_events, $widget_id, $ajaxified = false, $month = null, $year = null){
 
 
 
 
154
  //Create new GCE_Parser object, passing array of feed id(s)
155
- $grid = new GCE_Parser(explode('-', $feed_ids), $title_text, $max_events);
 
 
 
 
 
 
 
156
 
157
- //If the feed(s) parsed ok, output the grid markup, otherwise output an error message
158
- if(count($grid->get_errors()) == 0){
159
  //Add AJAX script if required
160
  if($ajaxified) ?><script type="text/javascript">jQuery(document).ready(function($){gce_ajaxify("<?php echo $widget_id; ?>", "<?php echo $feed_ids; ?>", "<?php echo $max_events; ?>", "<?php echo $title_text; ?>", "widget");});</script><?php
161
 
@@ -163,7 +174,7 @@ function gce_widget_content_grid($feed_ids, $title_text, $max_events, $widget_id
163
  }else{
164
  //If current user is an admin, display an error message explaining problem. Otherwise, display a 'nice' error messsage
165
  if(current_user_can('manage_options')){
166
- printf(__('The following feeds were not parsed successfully: %s. Please check that the feed URLs are correct and that the feeds have public sharing enabled.'), implode(', ', $grid->get_errors()));
167
  }else{
168
  $options = get_option(GCE_GENERAL_OPTIONS_NAME);
169
  echo $options['error'];
@@ -172,16 +183,25 @@ function gce_widget_content_grid($feed_ids, $title_text, $max_events, $widget_id
172
  }
173
 
174
  function gce_widget_content_list($feed_ids, $title_text, $max_events, $grouped = false){
 
 
 
 
175
  //Create new GCE_Parser object, passing array of feed id(s)
176
- $list = new GCE_Parser(explode('-', $feed_ids), $title_text, $max_events);
 
 
 
 
 
 
 
177
 
178
- //If the feed(s) parsed ok, output the list markup, otherwise output an error message
179
- if(count($list->get_errors()) == 0){
180
  echo $list->get_list($grouped);
181
  }else{
182
- //If current user is an admin, display an error message explaining problem. Otherwise, display a 'nice' error messsage
183
  if(current_user_can('manage_options')){
184
- printf(__('The following feeds were not parsed successfully: %s. Please check that the feed URLs are correct and that the feeds have public sharing enabled.'), implode(', ', $list->get_errors()));
185
  }else{
186
  $options = get_option(GCE_GENERAL_OPTIONS_NAME);
187
  echo $options['error'];
1
  <?php
 
 
2
  class GCE_Widget extends WP_Widget{
3
  function GCE_Widget(){
4
+ parent::WP_Widget(
5
+ false,
6
+ $name = __('Google Calendar Events', GCE_TEXT_DOMAIN),
7
+ array('description' => __('Display a list or calendar grid of events from one or more Google Calendar feeds you have added', GCE_TEXT_DOMAIN))
8
+ );
9
  }
10
 
11
  function widget($args, $instance){
41
  //Check that at least one valid feed id has been entered
42
  if(count((array)$feed_ids) == 0 || $no_feeds_exist){
43
  if(current_user_can('manage_options')){
44
+ _e('No valid Feed IDs have been entered for this widget. Please check that you have entered the IDs correctly in the widget settings (Appearance > Widgets), and that the Feeds have not been deleted.', GCE_TEXT_DOMAIN);
45
  }else{
46
  $options = get_option(GCE_GENERAL_OPTIONS_NAME);
47
  echo $options['error'];
153
  }
154
 
155
  function gce_widget_content_grid($feed_ids, $title_text, $max_events, $widget_id, $ajaxified = false, $month = null, $year = null){
156
+ require_once WP_PLUGIN_DIR . '/' . GCE_PLUGIN_NAME . '/inc/gce-parser.php';
157
+
158
+ $ids = explode('-', $feed_ids);
159
+
160
  //Create new GCE_Parser object, passing array of feed id(s)
161
+ $grid = new GCE_Parser($ids, $title_text, $max_events);
162
+
163
+ $num_errors = $grid->get_num_errors();
164
+
165
+ //If there are less errors than feeds parsed, at least one feed must have parsed successfully so continue to display the grid
166
+ if($num_errors < count($ids)){
167
+ //If there was at least one error, and user is an admin, output error messages
168
+ if($num_errors > 0 && current_user_can('manage_options')) echo $grid->error_messages();
169
 
 
 
170
  //Add AJAX script if required
171
  if($ajaxified) ?><script type="text/javascript">jQuery(document).ready(function($){gce_ajaxify("<?php echo $widget_id; ?>", "<?php echo $feed_ids; ?>", "<?php echo $max_events; ?>", "<?php echo $title_text; ?>", "widget");});</script><?php
172
 
174
  }else{
175
  //If current user is an admin, display an error message explaining problem. Otherwise, display a 'nice' error messsage
176
  if(current_user_can('manage_options')){
177
+ echo $grid->error_messages();
178
  }else{
179
  $options = get_option(GCE_GENERAL_OPTIONS_NAME);
180
  echo $options['error'];
183
  }
184
 
185
  function gce_widget_content_list($feed_ids, $title_text, $max_events, $grouped = false){
186
+ require_once WP_PLUGIN_DIR . '/' . GCE_PLUGIN_NAME . '/inc/gce-parser.php';
187
+
188
+ $ids = explode('-', $feed_ids);
189
+
190
  //Create new GCE_Parser object, passing array of feed id(s)
191
+ $list = new GCE_Parser($ids, $title_text, $max_events);
192
+
193
+ $num_errors = $list->get_num_errors();
194
+
195
+ //If there are less errors than feeds parsed, at least one feed must have parsed successfully so continue to display the list
196
+ if($num_errors < count($ids)){
197
+ //If there was at least one error, and user is an admin, output error messages
198
+ if($num_errors > 0 && current_user_can('manage_options')) echo $list->error_messages();
199
 
 
 
200
  echo $list->get_list($grouped);
201
  }else{
202
+ //If current user is an admin, display an error message explaining problem(s). Otherwise, display a 'nice' error messsage
203
  if(current_user_can('manage_options')){
204
+ echo $list->error_messages();
205
  }else{
206
  $options = get_option(GCE_GENERAL_OPTIONS_NAME);
207
  echo $options['error'];