My Calendar - Version 1.0.0

Version Description

  • Initial launch.

=

Download this release

Release Info

Developer joedolson
Plugin Icon 128x128 My Calendar
Version 1.0.0
Comparing to
See all releases

Version 1.0.0

date-utilities.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ function add_date($givendate,$day=0,$mth=0,$yr=0) {
5
+ $cd = strtotime($givendate);
6
+ $newdate = date('Y-m-d', mktime(date('h',$cd),date('i',$cd), date('s',$cd), date('m',$cd)+$mth,date('d',$cd)+$day, date('Y',$cd)+$yr));
7
+ return $newdate;
8
+ }
9
+ function date_comp($early,$late) {
10
+ $firstdate = strtotime($early);
11
+ $lastdate = strtotime($late);
12
+ if ($firstdate <= $lastdate) {
13
+ return true;
14
+ } else {
15
+ return false;
16
+ }
17
+ }
18
+
19
+ function date_equal($early,$late) {
20
+ $firstdate = strtotime($early);
21
+ $lastdate = strtotime($late);
22
+ if ($early == $late) {
23
+ return true;
24
+ } else {
25
+ return false;
26
+ }
27
+ }
28
+
29
+ // Function to compare time in event objects
30
+ function time_cmp($a, $b) {
31
+ if ($a->event_time == $b->event_time) {
32
+ return 0;
33
+ }
34
+ return ($a->event_time < $b->event_time) ? -1 : 1;
35
+ }
36
+
37
+ // Function to compare datetime in event objects
38
+ function datetime_cmp($a, $b) {
39
+ $event_dt_a = strtotime($a->event_begin .' '. $a->event_time);
40
+ $event_dt_b = strtotime($b->event_begin .' '. $b->event_time);
41
+ if ($event_dt_a == $event_dt_b ) {
42
+ return 0;
43
+ }
44
+ return ( $event_dt_a < $event_dt_b ) ? -1 : 1;
45
+ }
46
+
47
+ function timediff_cmp($a, $b) {
48
+ $event_dt_a = strtotime($a->event_begin .' '. $a->event_time);
49
+ $event_dt_b = strtotime($b->event_begin .' '. $b->event_time);
50
+ $diff_a = jd_date_diff_precise($event_dt_a);
51
+ $diff_b = jd_date_diff_precise($event_dt_b);
52
+
53
+ if ( $diff_a == $diff_b ) {
54
+ return 0;
55
+ }
56
+ return ( $diff_a < $diff_b ) ? -1 : 1;
57
+ }
58
+
59
+ function jd_date_diff_precise($start,$end="NOW") {
60
+ if ($end == "NOW") {
61
+ $end = strtotime("NOW");
62
+ }
63
+ $sdate = $start;
64
+ $edate = $end;
65
+
66
+ $time = $edate - $sdate;
67
+
68
+ return abs($time);
69
+ }
70
+
71
+ function jd_date_diff($start, $end="NOW") {
72
+ $sdate = strtotime($start);
73
+ $edate = strtotime($end);
74
+
75
+ $time = $edate - $sdate;
76
+ if ($time < 86400 && $time > -86400) {
77
+ return false;
78
+ } else {
79
+ $pday = ($edate - $sdate) / 86400;
80
+ $preday = explode('.',$pday);
81
+ return $preday[0];
82
+ }
83
+ }
84
+
85
+ ?>
icons/art.png ADDED
Binary file
icons/concert.png ADDED
Binary file
icons/event.png ADDED
Binary file
icons/games.png ADDED
Binary file
icons/globe.png ADDED
Binary file
icons/meeting.png ADDED
Binary file
icons/rehearsal.png ADDED
Binary file
icons/school.png ADDED
Binary file
images/event-details.jpg ADDED
Binary file
images/event-details.png ADDED
Binary file
js/jquery-colorpicker.js ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function($){var _remove=$.fn.remove;$.fn.remove=function(){$("*",this).add(this).triggerHandler("remove");return _remove.apply(this,arguments);};function isVisible(element){function checkStyles(element){var style=element.style;return(style.display!='none'&&style.visibility!='hidden');}
2
+ var visible=checkStyles(element);(visible&&$.each($.dir(element,'parentNode'),function(){return(visible=checkStyles(this));}));return visible;}
3
+ $.extend($.expr[':'],{data:function(a,i,m){return $.data(a,m[3]);},tabbable:function(a,i,m){var nodeName=a.nodeName.toLowerCase();return(a.tabIndex>=0&&(('a'==nodeName&&a.href)||(/input|select|textarea|button/.test(nodeName)&&'hidden'!=a.type&&!a.disabled))&&isVisible(a));}});$.keyCode={BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38};function getter(namespace,plugin,method,args){function getMethods(type){var methods=$[namespace][plugin][type]||[];return(typeof methods=='string'?methods.split(/,?\s+/):methods);}
4
+ var methods=getMethods('getter');if(args.length==1&&typeof args[0]=='string'){methods=methods.concat(getMethods('getterSetter'));}
5
+ return($.inArray(method,methods)!=-1);}
6
+ $.widget=function(name,prototype){var namespace=name.split(".")[0];name=name.split(".")[1];$.fn[name]=function(options){var isMethodCall=(typeof options=='string'),args=Array.prototype.slice.call(arguments,1);if(isMethodCall&&options.substring(0,1)=='_'){return this;}
7
+ if(isMethodCall&&getter(namespace,name,options,args)){var instance=$.data(this[0],name);return(instance?instance[options].apply(instance,args):undefined);}
8
+ return this.each(function(){var instance=$.data(this,name);(!instance&&!isMethodCall&&$.data(this,name,new $[namespace][name](this,options)));(instance&&isMethodCall&&$.isFunction(instance[options])&&instance[options].apply(instance,args));});};$[namespace][name]=function(element,options){var self=this;this.widgetName=name;this.widgetEventPrefix=$[namespace][name].eventPrefix||name;this.widgetBaseClass=namespace+'-'+name;this.options=$.extend({},$.widget.defaults,$[namespace][name].defaults,$.metadata&&$.metadata.get(element)[name],options);this.element=$(element).bind('setData.'+name,function(e,key,value){return self._setData(key,value);}).bind('getData.'+name,function(e,key){return self._getData(key);}).bind('remove',function(){return self.destroy();});this._init();};$[namespace][name].prototype=$.extend({},$.widget.prototype,prototype);$[namespace][name].getterSetter='option';};$.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName);},option:function(key,value){var options=key,self=this;if(typeof key=="string"){if(value===undefined){return this._getData(key);}
9
+ options={};options[key]=value;}
10
+ $.each(options,function(key,value){self._setData(key,value);});},_getData:function(key){return this.options[key];},_setData:function(key,value){this.options[key]=value;if(key=='disabled'){this.element[value?'addClass':'removeClass'](this.widgetBaseClass+'-disabled');}},enable:function(){this._setData('disabled',false);},disable:function(){this._setData('disabled',true);},_trigger:function(type,e,data){var eventName=(type==this.widgetEventPrefix?type:this.widgetEventPrefix+type);e=e||$.event.fix({type:eventName,target:this.element[0]});return this.element.triggerHandler(eventName,[e,data],this.options[type]);}};$.widget.defaults={disabled:false};$.ui={plugin:{add:function(module,option,set){var proto=$.ui[module].prototype;for(var i in set){proto.plugins[i]=proto.plugins[i]||[];proto.plugins[i].push([option,set[i]]);}},call:function(instance,name,args){var set=instance.plugins[name];if(!set){return;}
11
+ for(var i=0;i<set.length;i++){if(instance.options[set[i][0]]){set[i][1].apply(instance.element,args);}}}},cssCache:{},css:function(name){if($.ui.cssCache[name]){return $.ui.cssCache[name];}
12
+ var tmp=$('<div class="ui-gen">').addClass(name).css({position:'absolute',top:'-5000px',left:'-5000px',display:'block'}).appendTo('body');$.ui.cssCache[name]=!!((!(/auto|default/).test(tmp.css('cursor'))||(/^[1-9]/).test(tmp.css('height'))||(/^[1-9]/).test(tmp.css('width'))||!(/none/).test(tmp.css('backgroundImage'))||!(/transparent|rgba\(0, 0, 0, 0\)/).test(tmp.css('backgroundColor'))));try{$('body').get(0).removeChild(tmp.get(0));}catch(e){}
13
+ return $.ui.cssCache[name];},disableSelection:function(el){return $(el).attr('unselectable','on').css('MozUserSelect','none').bind('selectstart.ui',function(){return false;});},enableSelection:function(el){return $(el).attr('unselectable','off').css('MozUserSelect','').unbind('selectstart.ui');},hasScroll:function(e,a){if($(e).css('overflow')=='hidden'){return false;}
14
+ var scroll=(a&&a=='left')?'scrollLeft':'scrollTop',has=false;if(e[scroll]>0){return true;}
15
+ e[scroll]=1;has=(e[scroll]>0);e[scroll]=0;return has;}};$.ui.mouse={_mouseInit:function(){var self=this;this.element.bind('mousedown.'+this.widgetName,function(e){return self._mouseDown(e);});if($.browser.msie){this._mouseUnselectable=this.element.attr('unselectable');this.element.attr('unselectable','on');}
16
+ this.started=false;},_mouseDestroy:function(){this.element.unbind('.'+this.widgetName);($.browser.msie&&this.element.attr('unselectable',this._mouseUnselectable));},_mouseDown:function(e){(this._mouseStarted&&this._mouseUp(e));this._mouseDownEvent=e;var self=this,btnIsLeft=(e.which==1),elIsCancel=(typeof this.options.cancel=="string"?$(e.target).parents().add(e.target).filter(this.options.cancel).length:false);if(!btnIsLeft||elIsCancel||!this._mouseCapture(e)){return true;}
17
+ this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){self.mouseDelayMet=true;},this.options.delay);}
18
+ if(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)){this._mouseStarted=(this._mouseStart(e)!==false);if(!this._mouseStarted){e.preventDefault();return true;}}
19
+ this._mouseMoveDelegate=function(e){return self._mouseMove(e);};this._mouseUpDelegate=function(e){return self._mouseUp(e);};$(document).bind('mousemove.'+this.widgetName,this._mouseMoveDelegate).bind('mouseup.'+this.widgetName,this._mouseUpDelegate);return false;},_mouseMove:function(e){if($.browser.msie&&!e.button){return this._mouseUp(e);}
20
+ if(this._mouseStarted){this._mouseDrag(e);return false;}
21
+ if(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,e)!==false);(this._mouseStarted?this._mouseDrag(e):this._mouseUp(e));}
22
+ return!this._mouseStarted;},_mouseUp:function(e){$(document).unbind('mousemove.'+this.widgetName,this._mouseMoveDelegate).unbind('mouseup.'+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._mouseStop(e);}
23
+ return false;},_mouseDistanceMet:function(e){return(Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance);},_mouseDelayMet:function(e){return this.mouseDelayMet;},_mouseStart:function(e){},_mouseDrag:function(e){},_mouseStop:function(e){},_mouseCapture:function(e){return true;}};$.ui.mouse.defaults={cancel:null,distance:1,delay:0};})(jQuery);(function($){$.widget("ui.colorpicker",{_init:function(){this.charMin=65;var o=this.options,self=this,tpl='<div class="ui-colorpicker clearfix"><div class="ui-colorpicker-color"><div><div></div></div></div><div class="ui-colorpicker-hue"><div></div></div><div class="ui-colorpicker-new-color"></div><div class="ui-colorpicker-current-color"></div><div class="ui-colorpicker-hex"><label for="ui-colorpicker-hex" title="hex"></label><input type="text" maxlength="6" size="6" /></div><div class="ui-colorpicker-rgb-r ui-colorpicker-field"><label for="ui-colorpicker-rgb-r"></label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-rgb-g ui-colorpicker-field"><label for="ui-colorpicker-rgb-g"></label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-rgb-b ui-colorpicker-field"><label for="ui-colorpicker-rgb-b"</label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-hsb-h ui-colorpicker-field"><label for="ui-colorpicker-hsb-h"></label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-hsb-s ui-colorpicker-field"><label for="ui-colorpicker-hsb-s"></label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-hsb-b ui-colorpicker-field"><label for="ui-colorpicker-hsb-b"></label><input type="text" maxlength="3" size="2" /><span></span></div><button class="ui-colorpicker-submit ui-default-state" name="submit" type="button">Done</button></div>';if(typeof o.color=='string'){this.color=this._HexToHSB(o.color);}else if(o.color.r!=undefined&&o.color.g!=undefined&&o.color.b!=undefined){this.color=this._RGBToHSB(o.color);}else if(o.color.h!=undefined&&o.color.s!=undefined&&o.color.b!=undefined){this.color=this._fixHSB(o.color);}else{return this;}
24
+ this.origColor=this.color;this.picker=$(tpl);if(o.flat){this.picker.appendTo(this.element).show();}else{this.picker.appendTo(document.body);}
25
+ this.fields=this.picker.find('input').bind('keydown',function(e){return self._keyDown.call(self,e);}).bind('change',function(e){return self._change.call(self,e);}).bind('blur',function(e){return self._blur.call(self,e);}).bind('focus',function(e){return self._focus.call(self,e);});this.picker.find('span').bind('mousedown',function(e){return self._downIncrement.call(self,e);});this.selector=this.picker.find('div.ui-colorpicker-color').bind('mousedown',function(e){return self._downSelector.call(self,e);});this.selectorIndic=this.selector.find('div div');this.hue=this.picker.find('div.ui-colorpicker-hue div');this.picker.find('div.ui-colorpicker-hue').bind('mousedown',function(e){return self._downHue.call(self,e);});this.newColor=this.picker.find('div.ui-colorpicker-new-color');this.currentColor=this.picker.find('div.ui-colorpicker-current-color');this.picker.find('.ui-colorpicker-submit').bind('mouseenter',function(e){return self._enterSubmit.call(self,e);}).bind('mouseleave',function(e){return self._leaveSubmit.call(self,e);}).bind('click',function(e){return self._clickSubmit.call(self,e);});this._fillRGBFields(this.color);this._fillHSBFields(this.color);this._fillHexFields(this.color);this._setHue(this.color);this._setSelector(this.color);this._setCurrentColor(this.color);this._setNewColor(this.color);if(o.flat){this.picker.css({position:'relative',display:'block'});}else{$(this.element).bind(o.eventName+".colorpicker",function(e){return self._show.call(self,e);});}},destroy:function(){this.picker.remove();this.element.removeData("colorpicker").unbind(".colorpicker");},_fillRGBFields:function(hsb){var rgb=this._HSBToRGB(hsb);this.fields.eq(1).val(rgb.r).end().eq(2).val(rgb.g).end().eq(3).val(rgb.b).end();},_fillHSBFields:function(hsb){this.fields.eq(4).val(hsb.h).end().eq(5).val(hsb.s).end().eq(6).val(hsb.b).end();},_fillHexFields:function(hsb){this.fields.eq(0).val(this._HSBToHex(hsb)).end();},_setSelector:function(hsb){this.selector.css('backgroundColor','#'+this._HSBToHex({h:hsb.h,s:100,b:100}));this.selectorIndic.css({left:parseInt(150*hsb.s/100,10),top:parseInt(150*(100-hsb.b)/100,10)});},_setHue:function(hsb){this.hue.css('top',parseInt(150-150*hsb.h/360,10));},_setCurrentColor:function(hsb){this.currentColor.css('backgroundColor','#'+this._HSBToHex(hsb));},_setNewColor:function(hsb){this.newColor.css('backgroundColor','#'+this._HSBToHex(hsb));},_keyDown:function(e){var pressedKey=e.charCode||e.keyCode||-1;if((pressedKey>=this.charMin&&pressedKey<=90)||pressedKey==32){return false;}},_change:function(e,target){var col;target=target||e.target;if(target.parentNode.className.indexOf('-hex')>0){this.color=col=this._HexToHSB(this.value);this._fillRGBFields(col.color);this._fillHSBFields(col);}else if(target.parentNode.className.indexOf('-hsb')>0){this.color=col=this._fixHSB({h:parseInt(this.fields.eq(4).val(),10),s:parseInt(this.fields.eq(5).val(),10),b:parseInt(this.fields.eq(6).val(),10)});this._fillRGBFields(col);this._fillHexFields(col);}else{this.color=col=this._RGBToHSB(this._fixRGB({r:parseInt(this.fields.eq(1).val(),10),g:parseInt(this.fields.eq(2).val(),10),b:parseInt(this.fields.eq(3).val(),10)}));this._fillHexFields(col);this._fillHSBFields(col);}
26
+ this._setSelector(col);this._setHue(col);this._setNewColor(col);this._trigger('change',e,{options:this.options,hsb:col,hex:this._HSBToHex(col),rgb:this._HSBToRGB(col)});},_blur:function(e){var col=this.color;this._fillRGBFields(col);this._fillHSBFields(col);this._fillHexFields(col);this._setHue(col);this._setSelector(col);this._setNewColor(col);this.fields.parent().removeClass('ui-colorpicker-focus');},_focus:function(e){this.charMin=e.target.parentNode.className.indexOf('-hex')>0?70:65;this.fields.parent().removeClass('ui-colorpicker-focus');$(e.target.parentNode).addClass('ui-colorpicker-focus');},_downIncrement:function(e){var field=$(e.target).parent().find('input').focus(),self=this;this.currentIncrement={el:$(e.target).parent().addClass('ui-colorpicker-slider'),max:e.target.parentNode.className.indexOf('-hsb-h')>0?360:(e.target.parentNode.className.indexOf('-hsb')>0?100:255),y:e.pageY,field:field,val:parseInt(field.val(),10)};$(document).bind('mouseup.cpSlider',function(e){return self._upIncrement.call(self,e);});$(document).bind('mousemove.cpSlider',function(e){return self._moveIncrement.call(self,e);});return false;},_moveIncrement:function(e){this.currentIncrement.field.val(Math.max(0,Math.min(this.currentIncrement.max,parseInt(this.currentIncrement.val+e.pageY-this.currentIncrement.y,10))));this._change.apply(this,[e,this.currentIncrement.field.get(0)]);return false;},_upIncrement:function(e){this.currentIncrement.el.removeClass('ui-colorpicker-slider').find('input').focus();this._change.apply(this,[e,this.currentIncrement.field.get(0)]);$(document).unbind('mouseup.cpSlider');$(document).unbind('mousemove.cpSlider');return false;},_downHue:function(e){this.currentHue={y:this.picker.find('div.ui-colorpicker-hue').offset().top};this._change.apply(this,[e,this.fields.eq(4).val(parseInt(360*(150-Math.max(0,Math.min(150,(e.pageY-this.currentHue.y))))/150,10)).get(0)]);var self=this;$(document).bind('mouseup.cpSlider',function(e){return self._upHue.call(self,e);});$(document).bind('mousemove.cpSlider',function(e){return self._moveHue.call(self,e);});return false;},_moveHue:function(e){this._change.apply(this,[e,this.fields.eq(4).val(parseInt(360*(150-Math.max(0,Math.min(150,(e.pageY-this.currentHue.y))))/150,10)).get(0)]);return false;},_upHue:function(e){$(document).unbind('mouseup.cpSlider');$(document).unbind('mousemove.cpSlider');return false;},_downSelector:function(e){var self=this;this.currentSelector={pos:this.picker.find('div.ui-colorpicker-color').offset()};this._change.apply(this,[e,this.fields.eq(6).val(parseInt(100*(150-Math.max(0,Math.min(150,(e.pageY-this.currentSelector.pos.top))))/150,10)).end().eq(5).val(parseInt(100*(Math.max(0,Math.min(150,(e.pageX-this.currentSelector.pos.left))))/150,10)).get(0)]);$(document).bind('mouseup.cpSlider',function(e){return self._upSelector.call(self,e);});$(document).bind('mousemove.cpSlider',function(e){return self._moveSelector.call(self,e);});return false;},_moveSelector:function(e){this._change.apply(this,[e,this.fields.eq(6).val(parseInt(100*(150-Math.max(0,Math.min(150,(e.pageY-this.currentSelector.pos.top))))/150,10)).end().eq(5).val(parseInt(100*(Math.max(0,Math.min(150,(e.pageX-this.currentSelector.pos.left))))/150,10)).get(0)]);return false;},_upSelector:function(e){$(document).unbind('mouseup.cpSlider');$(document).unbind('mousemove.cpSlider');return false;},_enterSubmit:function(e){this.picker.find('.ui-colorpicker-submit').addClass('ui-colorpicker-focus');},_leaveSubmit:function(e){this.picker.find('.ui-colorpicker-submit').removeClass('ui-colorpicker-focus');},_clickSubmit:function(e){var col=this.color;this.origColor=col;this._setCurrentColor(col);this._trigger("submit",e,{options:this.options,hsb:col,hex:this._HSBToHex(col),rgb:this._HSBToRGB(col)});return false;},_show:function(e){this._trigger("beforeShow",e,{options:this.options,hsb:this.color,hex:this._HSBToHex(this.color),rgb:this._HSBToRGB(this.color)});var pos=this.element.offset();var viewPort=this._getScroll();var top=pos.top+this.element[0].offsetHeight;var left=pos.left;if(top+176>viewPort.t+Math.min(viewPort.h,viewPort.ih)){top-=this.element[0].offsetHeight+176;}
27
+ if(left+356>viewPort.l+Math.min(viewPort.w,viewPort.iw)){left-=356;}
28
+ this.picker.css({left:left+'px',top:top+'px'});if(this._trigger("show",e,{options:this.options,hsb:this.color,hex:this._HSBToHex(this.color),rgb:this._HSBToRGB(this.color)})!=false){this.picker.show();}
29
+ var self=this;$(document).bind('mousedown.colorpicker',function(e){return self._hide.call(self,e);});return false;},_hide:function(e){if(!this._isChildOf(this.picker[0],e.target,this.picker[0])){if(this._trigger("hide",e,{options:this.options,hsb:this.color,hex:this._HSBToHex(this.color),rgb:this._HSBToRGB(this.color)})!=false){this.picker.hide();}
30
+ $(document).unbind('mousedown.colorpicker');}},_isChildOf:function(parentEl,el,container){if(parentEl==el){return true;}
31
+ if(parentEl.contains&&!$.browser.safari){return parentEl.contains(el);}
32
+ if(parentEl.compareDocumentPosition){return!!(parentEl.compareDocumentPosition(el)&16);}
33
+ var prEl=el.parentNode;while(prEl&&prEl!=container){if(prEl==parentEl)
34
+ return true;prEl=prEl.parentNode;}
35
+ return false;},_getScroll:function(){var t,l,w,h,iw,ih;if(document.documentElement){t=document.documentElement.scrollTop;l=document.documentElement.scrollLeft;w=document.documentElement.scrollWidth;h=document.documentElement.scrollHeight;}else{t=document.body.scrollTop;l=document.body.scrollLeft;w=document.body.scrollWidth;h=document.body.scrollHeight;}
36
+ iw=self.innerWidth||document.documentElement.clientWidth||document.body.clientWidth||0;ih=self.innerHeight||document.documentElement.clientHeight||document.body.clientHeight||0;return{t:t,l:l,w:w,h:h,iw:iw,ih:ih};},_fixHSB:function(hsb){return{h:Math.min(360,Math.max(0,hsb.h)),s:Math.min(100,Math.max(0,hsb.s)),b:Math.min(100,Math.max(0,hsb.b))};},_fixRGB:function(rgb){return{r:Math.min(255,Math.max(0,rgb.r)),g:Math.min(255,Math.max(0,rgb.g)),b:Math.min(255,Math.max(0,rgb.b))};},_HexToRGB:function(hex){var hex=parseInt(((hex.indexOf('#')>-1)?hex.substring(1):hex),16);return{r:hex>>16,g:(hex&0x00FF00)>>8,b:(hex&0x0000FF)};},_HexToHSB:function(hex){return this._RGBToHSB(this._HexToRGB(hex));},_RGBToHSB:function(rgb){var hsb={};hsb.b=Math.max(Math.max(rgb.r,rgb.g),rgb.b);hsb.s=(hsb.b<=0)?0:Math.round(100*(hsb.b-Math.min(Math.min(rgb.r,rgb.g),rgb.b))/hsb.b);hsb.b=Math.round((hsb.b/255)*100);if((rgb.r==rgb.g)&&(rgb.g==rgb.b))hsb.h=0;else if(rgb.r>=rgb.g&&rgb.g>=rgb.b)hsb.h=60*(rgb.g-rgb.b)/(rgb.r-rgb.b);else if(rgb.g>=rgb.r&&rgb.r>=rgb.b)hsb.h=60+60*(rgb.g-rgb.r)/(rgb.g-rgb.b);else if(rgb.g>=rgb.b&&rgb.b>=rgb.r)hsb.h=120+60*(rgb.b-rgb.r)/(rgb.g-rgb.r);else if(rgb.b>=rgb.g&&rgb.g>=rgb.r)hsb.h=180+60*(rgb.b-rgb.g)/(rgb.b-rgb.r);else if(rgb.b>=rgb.r&&rgb.r>=rgb.g)hsb.h=240+60*(rgb.r-rgb.g)/(rgb.b-rgb.g);else if(rgb.r>=rgb.b&&rgb.b>=rgb.g)hsb.h=300+60*(rgb.r-rgb.b)/(rgb.r-rgb.g);else hsb.h=0;hsb.h=Math.round(hsb.h);return hsb;},_HSBToRGB:function(hsb){var rgb={};var h=Math.round(hsb.h);var s=Math.round(hsb.s*255/100);var v=Math.round(hsb.b*255/100);if(s==0){rgb.r=rgb.g=rgb.b=v;}else{var t1=v;var t2=(255-s)*v/255;var t3=(t1-t2)*(h%60)/60;if(h==360)h=0;if(h<60){rgb.r=t1;rgb.b=t2;rgb.g=t2+t3;}
37
+ else if(h<120){rgb.g=t1;rgb.b=t2;rgb.r=t1-t3;}
38
+ else if(h<180){rgb.g=t1;rgb.r=t2;rgb.b=t2+t3;}
39
+ else if(h<240){rgb.b=t1;rgb.r=t2;rgb.g=t1-t3;}
40
+ else if(h<300){rgb.b=t1;rgb.g=t2;rgb.r=t2+t3;}
41
+ else if(h<360){rgb.r=t1;rgb.g=t2;rgb.b=t1-t3;}
42
+ else{rgb.r=0;rgb.g=0;rgb.b=0;}}
43
+ return{r:Math.round(rgb.r),g:Math.round(rgb.g),b:Math.round(rgb.b)};},_RGBToHex:function(rgb){var hex=[rgb.r.toString(16),rgb.g.toString(16),rgb.b.toString(16)];$.each(hex,function(nr,val){if(val.length==1){hex[nr]='0'+val;}});return hex.join('');},_HSBToHex:function(hsb){return this._RGBToHex(this._HSBToRGB(hsb));},setColor:function(col){if(typeof col=='string'){col=this._HexToHSB(col);}else if(col.r!=undefined&&col.g!=undefined&&col.b!=undefined){col=this._RGBToHSB(col);}else if(col.h!=undefined&&col.s!=undefined&&col.b!=undefined){col=this._fixHSB(col);}else{return this;}
44
+ this.color=col;this.origColor=col;this._fillRGBFields(col);this._fillHSBFields(col);this._fillHexFields(col);this._setHue(col);this._setSelector(col);this._setCurrentColor(col);this._setNewColor(col);}});$.extend($.ui.colorpicker,{defaults:{eventName:'click',color:'ff0000',flat:false}});})(jQuery);
js/ui.datepicker.css ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Main Style Sheet for jQuery UI date picker */
2
+ #ui-datepicker-div, .ui-datepicker-inline {
3
+ font-size: 13px;
4
+ padding: 0;
5
+ margin: 0;
6
+ background: #ddd;
7
+ width: 185px;
8
+ }
9
+ #ui-datepicker-div {
10
+ display: none;
11
+ border: 1px solid #3185bb;
12
+ z-index: 9999;
13
+ /*must have*/
14
+ }
15
+ .ui-datepicker-inline {
16
+ float: left;
17
+ display: block;
18
+ border: 0;
19
+ }
20
+ .ui-datepicker-rtl {
21
+ direction: rtl;
22
+ }
23
+ .ui-datepicker-dialog {
24
+ padding: 5px !important;
25
+ border: 4px ridge #ccc!important;
26
+ }
27
+ button.ui-datepicker-trigger {
28
+ width: 25px;
29
+ }
30
+ img.ui-datepicker-trigger {
31
+ margin: 2px;
32
+ vertical-align: middle;
33
+ }
34
+ .ui-datepicker-prompt {
35
+ float: left;
36
+ padding: 2px;
37
+ background: #ddd;
38
+ color: #000;
39
+ }
40
+ * html .ui-datepicker-prompt {
41
+ width: 185px;
42
+ }
43
+ .ui-datepicker-control, .ui-datepicker-links, .ui-datepicker-header, .ui-datepicker {
44
+ clear: both;
45
+ float: left;
46
+ width: 100%;
47
+ color: #fff;
48
+ }
49
+ .ui-datepicker-control {
50
+ background: #21759b;
51
+ padding: 2px 0px;
52
+ }
53
+ .ui-datepicker-links {
54
+ background: #222;
55
+ padding: 2px 0px;
56
+ }
57
+ .ui-datepicker-control, .ui-datepicker-links {
58
+ font-weight: bold;
59
+ font-size: 80%;
60
+ }
61
+ .ui-datepicker-links label {
62
+ /* disabled links */
63
+ padding: 2px 5px;
64
+ color: #888;
65
+ }
66
+ .ui-datepicker-clear, .ui-datepicker-prev {
67
+ float: left;
68
+ width: 34%;
69
+ }
70
+ .ui-datepicker-rtl .ui-datepicker-clear, .ui-datepicker-rtl .ui-datepicker-prev {
71
+ float: right;
72
+ text-align: right;
73
+ }
74
+ .ui-datepicker-current {
75
+ float: left;
76
+ width: 30%;
77
+ text-align: center;
78
+ }
79
+ .ui-datepicker-close, .ui-datepicker-next {
80
+ float: right;
81
+ width: 34%;
82
+ text-align: right;
83
+ }
84
+ .ui-datepicker-rtl .ui-datepicker-close, .ui-datepicker-rtl .ui-datepicker-next {
85
+ float: left;
86
+ text-align: left;
87
+ }
88
+ .ui-datepicker-header {
89
+ padding: 1px 0 3px;
90
+ background: #333;
91
+ text-align: center;
92
+ font-weight: bold;
93
+ height: 1.3em;
94
+ }
95
+ .ui-datepicker-header select {
96
+ background: #333;
97
+ color: #fff;
98
+ border: 0px;
99
+ font-weight: bold;
100
+ }
101
+ .ui-datepicker {
102
+ background: #ccc;
103
+ text-align: center;
104
+ font-size: 100%;
105
+ }
106
+ .ui-datepicker a {
107
+ display: block;
108
+ width: 100%;
109
+ }
110
+ .ui-datepicker-title-row {
111
+ background: #666;
112
+ }
113
+ .ui-datepicker-days-row {
114
+ background: #e6e6e6;
115
+ color: #666;
116
+ }
117
+ .ui-datepicker-week-col {
118
+ background: #666;
119
+ color: #fff;
120
+ }
121
+ .ui-datepicker-days-cell {
122
+ color: #000;
123
+ border: 1px solid #ddd;
124
+ }
125
+ .ui-datepicker-days-cell a {
126
+ display: block;
127
+ }
128
+ .ui-datepicker-week-end-cell {
129
+ background: #e6e6e6;
130
+ }
131
+ .ui-datepicker-title-row .ui-datepicker-week-end-cell {
132
+ background: #666;
133
+ }
134
+ .ui-datepicker-days-cell-over {
135
+ background: #fff;
136
+ border: 1px solid #01355b;
137
+ }
138
+ .ui-datepicker-unselectable {
139
+ color: #888;
140
+ }
141
+ .ui-datepicker-today {
142
+ background: #fcc !important;
143
+ }
144
+ .ui-datepicker-current-day {
145
+ background: #ccc !important;
146
+ }
147
+ .ui-datepicker-status {
148
+ background: #ddd;
149
+ width: 100%;
150
+ font-size: 80%;
151
+ text-align: center;
152
+ }
153
+ /* ________ Datepicker Links _______** Reset link properties and then override them with !important */
154
+ #ui-datepicker-div a, .ui-datepicker-inline a {
155
+ cursor: pointer;
156
+ margin: 0;
157
+ padding: 0;
158
+ background: none;
159
+ color: #000;
160
+ }
161
+ .ui-datepicker-inline .ui-datepicker-links a {
162
+ padding: 0 5px !important;
163
+ }
164
+ .ui-datepicker-control a, .ui-datepicker-links a {
165
+ padding: 2px 5px !important;
166
+ color: #eee !important;
167
+ }
168
+ .ui-datepicker-title-row a {
169
+ color: #eee !important;
170
+ }
171
+ .ui-datepicker-control a:hover {
172
+ background: #fdd !important;
173
+ color: #333 !important;
174
+ }
175
+ .ui-datepicker-links a:hover, .ui-datepicker-title-row a:hover {
176
+ background: #ddd !important;
177
+ color: #333 !important;
178
+ }
179
+ /* ___________ MULTIPLE MONTHS _________*/
180
+ .ui-datepicker-multi .ui-datepicker {
181
+ border: 1px solid #777;
182
+ }
183
+ .ui-datepicker-one-month {
184
+ float: left;
185
+ width: 185px;
186
+ }
187
+ .ui-datepicker-new-row {
188
+ clear: left;
189
+ }
190
+ /* ___________ IE6 IFRAME FIX ________ */
191
+ .ui-datepicker-cover {
192
+ display: none;
193
+ /*sorry for IE5*/
194
+ display
195
+ /**/
196
+ : block;
197
+ /*sorry for IE5*/
198
+ position: absolute;
199
+ /*must have*/
200
+ z-index: -1;
201
+ /*must have*/
202
+ filter: mask();
203
+ /*must have*/
204
+ top: -4px;
205
+ /*must have*/
206
+ left: -4px;
207
+ /*must have*/
208
+ width: 200px;
209
+ /*must have*/
210
+ height: 200px;
211
+ /*must have*/
212
+ }
js/ui.datepicker.js ADDED
@@ -0,0 +1,1718 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery UI Datepicker @VERSION
3
+ *
4
+ * Copyright (c) 2006, 2007, 2008 Marc Grabanski
5
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
6
+ * and GPL (GPL-LICENSE.txt) licenses.
7
+ *
8
+ * http://docs.jquery.com/UI/Datepicker
9
+ *
10
+ * Depends:
11
+ * ui.core.js
12
+ *
13
+ * Marc Grabanski (m@marcgrabanski.com) and Keith Wood (kbwood@virginbroadband.com.au).
14
+ */
15
+
16
+ (function($) { // hide the namespace
17
+
18
+ var PROP_NAME = 'datepicker';
19
+
20
+ /* Date picker manager.
21
+ Use the singleton instance of this class, $.datepicker, to interact with the date picker.
22
+ Settings for (groups of) date pickers are maintained in an instance object,
23
+ allowing multiple different settings on the same page. */
24
+
25
+ function Datepicker() {
26
+ this.debug = false; // Change this to true to start debugging
27
+ this._curInst = null; // The current instance in use
28
+ this._disabledInputs = []; // List of date picker inputs that have been disabled
29
+ this._datepickerShowing = false; // True if the popup picker is showing , false if not
30
+ this._inDialog = false; // True if showing within a "dialog", false if not
31
+ this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
32
+ this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
33
+ this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
34
+ this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
35
+ this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
36
+ this._promptClass = 'ui-datepicker-prompt'; // The name of the dialog prompt marker class
37
+ this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
38
+ this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
39
+ this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
40
+ this.regional = []; // Available regional settings, indexed by language code
41
+ this.regional[''] = { // Default regional settings
42
+ clearText: 'Clear', // Display text for clear link
43
+ clearStatus: 'Erase the current date', // Status text for clear link
44
+ closeText: 'Close', // Display text for close link
45
+ closeStatus: 'Close without change', // Status text for close link
46
+ prevText: '&#x3c;Prev', // Display text for previous month link
47
+ prevStatus: 'Show the previous month', // Status text for previous month link
48
+ prevBigText: '&#x3c;&#x3c;', // Display text for previous year link
49
+ prevBigStatus: 'Show the previous year', // Status text for previous year link
50
+ nextText: 'Next&#x3e;', // Display text for next month link
51
+ nextStatus: 'Show the next month', // Status text for next month link
52
+ nextBigText: '&#x3e;&#x3e;', // Display text for next year link
53
+ nextBigStatus: 'Show the next year', // Status text for next year link
54
+ currentText: 'Today', // Display text for current month link
55
+ currentStatus: 'Show the current month', // Status text for current month link
56
+ monthNames: ['January','February','March','April','May','June',
57
+ 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
58
+ monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
59
+ monthStatus: 'Show a different month', // Status text for selecting a month
60
+ yearStatus: 'Show a different year', // Status text for selecting a year
61
+ weekHeader: 'Wk', // Header for the week of the year column
62
+ weekStatus: 'Week of the year', // Status text for the week of the year column
63
+ dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
64
+ dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
65
+ dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
66
+ dayStatus: 'Set DD as first week day', // Status text for the day of the week selection
67
+ dateStatus: 'Select DD, M d', // Status text for the date selection
68
+ dateFormat: 'mm/dd/yy', // See format options on parseDate
69
+ firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
70
+ initStatus: 'Select a date', // Initial Status text on opening
71
+ isRTL: false // True if right-to-left language, false if left-to-right
72
+ };
73
+ this._defaults = { // Global defaults for all the date picker instances
74
+ showOn: 'focus', // 'focus' for popup on focus,
75
+ // 'button' for trigger button, or 'both' for either
76
+ showAnim: 'show', // Name of jQuery animation for popup
77
+ showOptions: {}, // Options for enhanced animations
78
+ defaultDate: null, // Used when field is blank: actual date,
79
+ // +/-number for offset from today, null for today
80
+ appendText: '', // Display text following the input box, e.g. showing the format
81
+ buttonText: '...', // Text for trigger button
82
+ buttonImage: '', // URL for trigger button image
83
+ buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
84
+ closeAtTop: true, // True to have the clear/close at the top,
85
+ // false to have them at the bottom
86
+ mandatory: false, // True to hide the Clear link, false to include it
87
+ hideIfNoPrevNext: false, // True to hide next/previous month links
88
+ // if not applicable, false to just disable them
89
+ navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
90
+ showBigPrevNext: false, // True to show big prev/next links
91
+ gotoCurrent: false, // True if today link goes back to current selection instead
92
+ changeMonth: true, // True if month can be selected directly, false if only prev/next
93
+ changeYear: true, // True if year can be selected directly, false if only prev/next
94
+ showMonthAfterYear: false, // True if the year select precedes month, false for month then year
95
+ yearRange: '-10:+10', // Range of years to display in drop-down,
96
+ // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)
97
+ changeFirstDay: true, // True to click on day name to change, false to remain as set
98
+ highlightWeek: false, // True to highlight the selected week
99
+ showOtherMonths: false, // True to show dates in other months, false to leave blank
100
+ showWeeks: false, // True to show week of the year, false to omit
101
+ calculateWeek: this.iso8601Week, // How to calculate the week of the year,
102
+ // takes a Date and returns the number of the week for it
103
+ shortYearCutoff: '+10', // Short year values < this are in the current century,
104
+ // > this are in the previous century,
105
+ // string value starting with '+' for current year + value
106
+ showStatus: false, // True to show status bar at bottom, false to not show it
107
+ statusForDate: this.dateStatus, // Function to provide status text for a date -
108
+ // takes date and instance as parameters, returns display text
109
+ minDate: null, // The earliest selectable date, or null for no limit
110
+ maxDate: null, // The latest selectable date, or null for no limit
111
+ duration: 'normal', // Duration of display/closure
112
+ beforeShowDay: null, // Function that takes a date and returns an array with
113
+ // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
114
+ // [2] = cell title (optional), e.g. $.datepicker.noWeekends
115
+ beforeShow: null, // Function that takes an input field and
116
+ // returns a set of custom settings for the date picker
117
+ onSelect: null, // Define a callback function when a date is selected
118
+ onChangeMonthYear: null, // Define a callback function when the month or year is changed
119
+ onClose: null, // Define a callback function when the datepicker is closed
120
+ numberOfMonths: 1, // Number of months to show at a time
121
+ showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
122
+ stepMonths: 1, // Number of months to step back/forward
123
+ stepBigMonths: 12, // Number of months to step back/forward for the big links
124
+ rangeSelect: false, // Allows for selecting a date range on one date picker
125
+ rangeSeparator: ' - ', // Text between two dates in a range
126
+ altField: '', // Selector for an alternate field to store selected dates into
127
+ altFormat: '', // The date format to use for the alternate field
128
+ constrainInput: true // The input is constrained by the current date format
129
+ };
130
+ $.extend(this._defaults, this.regional['']);
131
+ this.dpDiv = $('<div id="' + this._mainDivId + '" style="display: none;"></div>');
132
+ }
133
+
134
+ $.extend(Datepicker.prototype, {
135
+ /* Class name added to elements to indicate already configured with a date picker. */
136
+ markerClassName: 'hasDatepicker',
137
+
138
+ /* Debug logging (if enabled). */
139
+ log: function () {
140
+ if (this.debug)
141
+ console.log.apply('', arguments);
142
+ },
143
+
144
+ /* Override the default settings for all instances of the date picker.
145
+ @param settings object - the new settings to use as defaults (anonymous object)
146
+ @return the manager object */
147
+ setDefaults: function(settings) {
148
+ extendRemove(this._defaults, settings || {});
149
+ return this;
150
+ },
151
+
152
+ /* Attach the date picker to a jQuery selection.
153
+ @param target element - the target input field or division or span
154
+ @param settings object - the new settings to use for this date picker instance (anonymous) */
155
+ _attachDatepicker: function(target, settings) {
156
+ // check for settings on the control itself - in namespace 'date:'
157
+ var inlineSettings = null;
158
+ for (attrName in this._defaults) {
159
+ var attrValue = target.getAttribute('date:' + attrName);
160
+ if (attrValue) {
161
+ inlineSettings = inlineSettings || {};
162
+ try {
163
+ inlineSettings[attrName] = eval(attrValue);
164
+ } catch (err) {
165
+ inlineSettings[attrName] = attrValue;
166
+ }
167
+ }
168
+ }
169
+ var nodeName = target.nodeName.toLowerCase();
170
+ var inline = (nodeName == 'div' || nodeName == 'span');
171
+ if (!target.id)
172
+ target.id = 'dp' + (++this.uuid);
173
+ var inst = this._newInst($(target), inline);
174
+ inst.settings = $.extend({}, settings || {}, inlineSettings || {});
175
+ if (nodeName == 'input') {
176
+ this._connectDatepicker(target, inst);
177
+ } else if (inline) {
178
+ this._inlineDatepicker(target, inst);
179
+ }
180
+ },
181
+
182
+ /* Create a new instance object. */
183
+ _newInst: function(target, inline) {
184
+ var id = target[0].id.replace(/([:\[\]\.])/g, '\\\\$1'); // escape jQuery meta chars
185
+ return {id: id, input: target, // associated target
186
+ selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
187
+ drawMonth: 0, drawYear: 0, // month being drawn
188
+ inline: inline, // is datepicker inline or not
189
+ dpDiv: (!inline ? this.dpDiv : // presentation div
190
+ $('<div class="' + this._inlineClass + '"></div>'))};
191
+ },
192
+
193
+ /* Attach the date picker to an input field. */
194
+ _connectDatepicker: function(target, inst) {
195
+ var input = $(target);
196
+ if (input.hasClass(this.markerClassName))
197
+ return;
198
+ var appendText = this._get(inst, 'appendText');
199
+ var isRTL = this._get(inst, 'isRTL');
200
+ if (appendText)
201
+ input[isRTL ? 'before' : 'after']('<span class="' + this._appendClass + '">' + appendText + '</span>');
202
+ var showOn = this._get(inst, 'showOn');
203
+ if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
204
+ input.focus(this._showDatepicker);
205
+ if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
206
+ var buttonText = this._get(inst, 'buttonText');
207
+ var buttonImage = this._get(inst, 'buttonImage');
208
+ var trigger = $(this._get(inst, 'buttonImageOnly') ?
209
+ $('<img/>').addClass(this._triggerClass).
210
+ attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
211
+ $('<button type="button"></button>').addClass(this._triggerClass).
212
+ html(buttonImage == '' ? buttonText : $('<img/>').attr(
213
+ { src:buttonImage, alt:buttonText, title:buttonText })));
214
+ input[isRTL ? 'before' : 'after'](trigger);
215
+ trigger.click(function() {
216
+ if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target)
217
+ $.datepicker._hideDatepicker();
218
+ else
219
+ $.datepicker._showDatepicker(target);
220
+ return false;
221
+ });
222
+ }
223
+ input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).
224
+ bind("setData.datepicker", function(event, key, value) {
225
+ inst.settings[key] = value;
226
+ }).bind("getData.datepicker", function(event, key) {
227
+ return this._get(inst, key);
228
+ });
229
+ $.data(target, PROP_NAME, inst);
230
+ },
231
+
232
+ /* Attach an inline date picker to a div. */
233
+ _inlineDatepicker: function(target, inst) {
234
+ var divSpan = $(target);
235
+ if (divSpan.hasClass(this.markerClassName))
236
+ return;
237
+ divSpan.addClass(this.markerClassName).append(inst.dpDiv).
238
+ bind("setData.datepicker", function(event, key, value){
239
+ inst.settings[key] = value;
240
+ }).bind("getData.datepicker", function(event, key){
241
+ return this._get(inst, key);
242
+ });
243
+ $.data(target, PROP_NAME, inst);
244
+ this._setDate(inst, this._getDefaultDate(inst));
245
+ this._updateDatepicker(inst);
246
+ },
247
+
248
+ /* Tidy up after displaying the date picker. */
249
+ _inlineShow: function(inst) {
250
+ var numMonths = this._getNumberOfMonths(inst); // fix width for dynamic number of date pickers
251
+ inst.dpDiv.width(numMonths[1] * $('.ui-datepicker', inst.dpDiv[0]).width());
252
+ },
253
+
254
+ /* Pop-up the date picker in a "dialog" box.
255
+ @param input element - ignored
256
+ @param dateText string - the initial date to display (in the current format)
257
+ @param onSelect function - the function(dateText) to call when a date is selected
258
+ @param settings object - update the dialog date picker instance's settings (anonymous object)
259
+ @param pos int[2] - coordinates for the dialog's position within the screen or
260
+ event - with x/y coordinates or
261
+ leave empty for default (screen centre)
262
+ @return the manager object */
263
+ _dialogDatepicker: function(input, dateText, onSelect, settings, pos) {
264
+ var inst = this._dialogInst; // internal instance
265
+ if (!inst) {
266
+ var id = 'dp' + (++this.uuid);
267
+ this._dialogInput = $('<input type="text" id="' + id +
268
+ '" size="1" style="position: absolute; top: -100px;"/>');
269
+ this._dialogInput.keydown(this._doKeyDown);
270
+ $('body').append(this._dialogInput);
271
+ inst = this._dialogInst = this._newInst(this._dialogInput, false);
272
+ inst.settings = {};
273
+ $.data(this._dialogInput[0], PROP_NAME, inst);
274
+ }
275
+ extendRemove(inst.settings, settings || {});
276
+ this._dialogInput.val(dateText);
277
+
278
+ this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
279
+ if (!this._pos) {
280
+ var browserWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
281
+ var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
282
+ var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
283
+ var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
284
+ this._pos = // should use actual width/height below
285
+ [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
286
+ }
287
+
288
+ // move input on screen for focus, but hidden behind dialog
289
+ this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px');
290
+ inst.settings.onSelect = onSelect;
291
+ this._inDialog = true;
292
+ this.dpDiv.addClass(this._dialogClass);
293
+ this._showDatepicker(this._dialogInput[0]);
294
+ if ($.blockUI)
295
+ $.blockUI(this.dpDiv);
296
+ $.data(this._dialogInput[0], PROP_NAME, inst);
297
+ return this;
298
+ },
299
+
300
+ /* Detach a datepicker from its control.
301
+ @param target element - the target input field or division or span */
302
+ _destroyDatepicker: function(target) {
303
+ var $target = $(target);
304
+ if (!$target.hasClass(this.markerClassName)) {
305
+ return;
306
+ }
307
+ var nodeName = target.nodeName.toLowerCase();
308
+ $.removeData(target, PROP_NAME);
309
+ if (nodeName == 'input') {
310
+ $target.siblings('.' + this._appendClass).remove().end().
311
+ siblings('.' + this._triggerClass).remove().end().
312
+ removeClass(this.markerClassName).
313
+ unbind('focus', this._showDatepicker).
314
+ unbind('keydown', this._doKeyDown).
315
+ unbind('keypress', this._doKeyPress);
316
+ } else if (nodeName == 'div' || nodeName == 'span')
317
+ $target.removeClass(this.markerClassName).empty();
318
+ },
319
+
320
+ /* Enable the date picker to a jQuery selection.
321
+ @param target element - the target input field or division or span */
322
+ _enableDatepicker: function(target) {
323
+ var $target = $(target);
324
+ if (!$target.hasClass(this.markerClassName)) {
325
+ return;
326
+ }
327
+ var nodeName = target.nodeName.toLowerCase();
328
+ if (nodeName == 'input') {
329
+ target.disabled = false;
330
+ $target.siblings('button.' + this._triggerClass).
331
+ each(function() { this.disabled = false; }).end().
332
+ siblings('img.' + this._triggerClass).
333
+ css({opacity: '1.0', cursor: ''});
334
+ }
335
+ else if (nodeName == 'div' || nodeName == 'span') {
336
+ $target.children('.' + this._disableClass).remove();
337
+ }
338
+ this._disabledInputs = $.map(this._disabledInputs,
339
+ function(value) { return (value == target ? null : value); }); // delete entry
340
+ },
341
+
342
+ /* Disable the date picker to a jQuery selection.
343
+ @param target element - the target input field or division or span */
344
+ _disableDatepicker: function(target) {
345
+ var $target = $(target);
346
+ if (!$target.hasClass(this.markerClassName)) {
347
+ return;
348
+ }
349
+ var nodeName = target.nodeName.toLowerCase();
350
+ if (nodeName == 'input') {
351
+ target.disabled = true;
352
+ $target.siblings('button.' + this._triggerClass).
353
+ each(function() { this.disabled = true; }).end().
354
+ siblings('img.' + this._triggerClass).
355
+ css({opacity: '0.5', cursor: 'default'});
356
+ }
357
+ else if (nodeName == 'div' || nodeName == 'span') {
358
+ var inline = $target.children('.' + this._inlineClass);
359
+ var offset = inline.offset();
360
+ var relOffset = {left: 0, top: 0};
361
+ inline.parents().each(function() {
362
+ if ($(this).css('position') == 'relative') {
363
+ relOffset = $(this).offset();
364
+ return false;
365
+ }
366
+ });
367
+ $target.prepend('<div class="' + this._disableClass + '" style="' +
368
+ ($.browser.msie ? 'background-color: transparent; ' : '') +
369
+ 'width: ' + inline.width() + 'px; height: ' + inline.height() +
370
+ 'px; left: ' + (offset.left - relOffset.left) +
371
+ 'px; top: ' + (offset.top - relOffset.top) + 'px;"></div>');
372
+ }
373
+ this._disabledInputs = $.map(this._disabledInputs,
374
+ function(value) { return (value == target ? null : value); }); // delete entry
375
+ this._disabledInputs[this._disabledInputs.length] = target;
376
+ },
377
+
378
+ /* Is the first field in a jQuery collection disabled as a datepicker?
379
+ @param target element - the target input field or division or span
380
+ @return boolean - true if disabled, false if enabled */
381
+ _isDisabledDatepicker: function(target) {
382
+ if (!target)
383
+ return false;
384
+ for (var i = 0; i < this._disabledInputs.length; i++) {
385
+ if (this._disabledInputs[i] == target)
386
+ return true;
387
+ }
388
+ return false;
389
+ },
390
+
391
+ /* Retrieve the instance data for the target control.
392
+ @param target element - the target input field or division or span
393
+ @return object - the associated instance data
394
+ @throws error if a jQuery problem getting data */
395
+ _getInst: function(target) {
396
+ try {
397
+ return $.data(target, PROP_NAME);
398
+ }
399
+ catch (err) {
400
+ throw 'Missing instance data for this datepicker';
401
+ }
402
+ },
403
+
404
+ /* Update the settings for a date picker attached to an input field or division.
405
+ @param target element - the target input field or division or span
406
+ @param name object - the new settings to update or
407
+ string - the name of the setting to change or
408
+ @param value any - the new value for the setting (omit if above is an object) */
409
+ _optionDatepicker: function(target, name, value) {
410
+ var settings = name || {};
411
+ if (typeof name == 'string') {
412
+ settings = {};
413
+ settings[name] = value;
414
+ }
415
+ var inst = this._getInst(target);
416
+ if (inst) {
417
+ if (this._curInst == inst) {
418
+ this._hideDatepicker(null);
419
+ }
420
+ extendRemove(inst.settings, settings);
421
+ var date = new Date();
422
+ extendRemove(inst, {rangeStart: null, // start of range
423
+ endDay: null, endMonth: null, endYear: null, // end of range
424
+ selectedDay: date.getDate(), selectedMonth: date.getMonth(),
425
+ selectedYear: date.getFullYear(), // starting point
426
+ currentDay: date.getDate(), currentMonth: date.getMonth(),
427
+ currentYear: date.getFullYear(), // current selection
428
+ drawMonth: date.getMonth(), drawYear: date.getFullYear()}); // month being drawn
429
+ this._updateDatepicker(inst);
430
+ }
431
+ },
432
+
433
+ // change method deprecated
434
+ _changeDatepicker: this._optionDatepicker,
435
+
436
+ /* Redraw the date picker attached to an input field or division.
437
+ @param target element - the target input field or division or span */
438
+ _refreshDatepicker: function(target) {
439
+ var inst = this._getInst(target);
440
+ if (inst) {
441
+ this._updateDatepicker(inst);
442
+ }
443
+ },
444
+
445
+ /* Set the dates for a jQuery selection.
446
+ @param target element - the target input field or division or span
447
+ @param date Date - the new date
448
+ @param endDate Date - the new end date for a range (optional) */
449
+ _setDateDatepicker: function(target, date, endDate) {
450
+ var inst = this._getInst(target);
451
+ if (inst) {
452
+ this._setDate(inst, date, endDate);
453
+ this._updateDatepicker(inst);
454
+ this._updateAlternate(inst);
455
+ }
456
+ },
457
+
458
+ /* Get the date(s) for the first entry in a jQuery selection.
459
+ @param target element - the target input field or division or span
460
+ @return Date - the current date or
461
+ Date[2] - the current dates for a range */
462
+ _getDateDatepicker: function(target) {
463
+ var inst = this._getInst(target);
464
+ if (inst && !inst.inline)
465
+ this._setDateFromField(inst);
466
+ return (inst ? this._getDate(inst) : null);
467
+ },
468
+
469
+ /* Handle keystrokes. */
470
+ _doKeyDown: function(e) {
471
+ var inst = $.datepicker._getInst(e.target);
472
+ var handled = true;
473
+ if ($.datepicker._datepickerShowing)
474
+ switch (e.keyCode) {
475
+ case 9: $.datepicker._hideDatepicker(null, '');
476
+ break; // hide on tab out
477
+ case 13: if ($('td.ui-datepicker-days-cell-over', inst.dpDiv)[0])
478
+ $.datepicker._selectDay(e.target, inst.selectedMonth, inst.selectedYear,
479
+ $('td.ui-datepicker-days-cell-over', inst.dpDiv)[0]);
480
+ return false; // don't submit the form
481
+ break; // select the value on enter
482
+ case 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));
483
+ break; // hide on escape
484
+ case 33: $.datepicker._adjustDate(e.target, (e.ctrlKey ?
485
+ -$.datepicker._get(inst, 'stepBigMonths') :
486
+ -$.datepicker._get(inst, 'stepMonths')), 'M');
487
+ break; // previous month/year on page up/+ ctrl
488
+ case 34: $.datepicker._adjustDate(e.target, (e.ctrlKey ?
489
+ +$.datepicker._get(inst, 'stepBigMonths') :
490
+ +$.datepicker._get(inst, 'stepMonths')), 'M');
491
+ break; // next month/year on page down/+ ctrl
492
+ case 35: if (e.ctrlKey || e.metaKey) $.datepicker._clearDate(e.target);
493
+ handled = e.ctrlKey;
494
+ break; // clear on ctrl or command +end
495
+ case 36: if (e.ctrlKey || e.metaKey) $.datepicker._gotoToday(e.target);
496
+ handled = e.ctrlKey;
497
+ break; // current on ctrl or command +home
498
+ case 37: if (e.ctrlKey || e.metaKey) $.datepicker._adjustDate(e.target, -1, 'D');
499
+ handled = e.ctrlKey;
500
+ // -1 day on ctrl or command +left
501
+ if (e.originalEvent.altKey) $.datepicker._adjustDate(e.target, (e.ctrlKey ?
502
+ -$.datepicker._get(inst, 'stepBigMonths') :
503
+ -$.datepicker._get(inst, 'stepMonths')), 'M');
504
+ // next month/year on alt +left on Mac
505
+ break;
506
+ case 38: if (e.ctrlKey || e.metaKey) $.datepicker._adjustDate(e.target, -7, 'D');
507
+ handled = e.ctrlKey;
508
+ break; // -1 week on ctrl or command +up
509
+ case 39: if (e.ctrlKey || e.metaKey) $.datepicker._adjustDate(e.target, +1, 'D');
510
+ handled = e.ctrlKey;
511
+ // +1 day on ctrl or command +right
512
+ if (e.originalEvent.altKey) $.datepicker._adjustDate(e.target, (e.ctrlKey ?
513
+ +$.datepicker._get(inst, 'stepBigMonths') :
514
+ +$.datepicker._get(inst, 'stepMonths')), 'M');
515
+ // next month/year on alt +right
516
+ break;
517
+ case 40: if (e.ctrlKey || e.metaKey) $.datepicker._adjustDate(e.target, +7, 'D');
518
+ handled = e.ctrlKey;
519
+ break; // +1 week on ctrl or command +down
520
+ default: handled = false;
521
+ }
522
+ else if (e.keyCode == 36 && e.ctrlKey) // display the date picker on ctrl+home
523
+ $.datepicker._showDatepicker(this);
524
+ else
525
+ handled = false;
526
+ if (handled) {
527
+ e.preventDefault();
528
+ e.stopPropagation();
529
+ }
530
+ },
531
+
532
+ /* Filter entered characters - based on date format. */
533
+ _doKeyPress: function(e) {
534
+ var inst = $.datepicker._getInst(e.target);
535
+ if ($.datepicker._get(inst, 'constrainInput')) {
536
+ var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
537
+ var chr = String.fromCharCode(e.charCode == undefined ? e.keyCode : e.charCode);
538
+ return e.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
539
+ }
540
+ },
541
+
542
+ /* Pop-up the date picker for a given input field.
543
+ @param input element - the input field attached to the date picker or
544
+ event - if triggered by focus */
545
+ _showDatepicker: function(input) {
546
+ input = input.target || input;
547
+ if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
548
+ input = $('input', input.parentNode)[0];
549
+ if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
550
+ return;
551
+ var inst = $.datepicker._getInst(input);
552
+ var beforeShow = $.datepicker._get(inst, 'beforeShow');
553
+ extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
554
+ $.datepicker._hideDatepicker(null, '');
555
+ $.datepicker._lastInput = input;
556
+ $.datepicker._setDateFromField(inst);
557
+ if ($.datepicker._inDialog) // hide cursor
558
+ input.value = '';
559
+ if (!$.datepicker._pos) { // position below input
560
+ $.datepicker._pos = $.datepicker._findPos(input);
561
+ $.datepicker._pos[1] += input.offsetHeight; // add the height
562
+ }
563
+ var isFixed = false;
564
+ $(input).parents().each(function() {
565
+ isFixed |= $(this).css('position') == 'fixed';
566
+ return !isFixed;
567
+ });
568
+ if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
569
+ $.datepicker._pos[0] -= document.documentElement.scrollLeft;
570
+ $.datepicker._pos[1] -= document.documentElement.scrollTop;
571
+ }
572
+ var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
573
+ $.datepicker._pos = null;
574
+ inst.rangeStart = null;
575
+ // determine sizing offscreen
576
+ inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
577
+ $.datepicker._updateDatepicker(inst);
578
+ // fix width for dynamic number of date pickers
579
+ inst.dpDiv.width($.datepicker._getNumberOfMonths(inst)[1] *
580
+ $('.ui-datepicker', inst.dpDiv[0])[0].offsetWidth);
581
+ // and adjust position before showing
582
+ offset = $.datepicker._checkOffset(inst, offset, isFixed);
583
+ inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
584
+ 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
585
+ left: offset.left + 'px', top: offset.top + 'px'});
586
+ if (!inst.inline) {
587
+ var showAnim = $.datepicker._get(inst, 'showAnim') || 'show';
588
+ var duration = $.datepicker._get(inst, 'duration');
589
+ var postProcess = function() {
590
+ $.datepicker._datepickerShowing = true;
591
+ if ($.browser.msie && parseInt($.browser.version,10) < 7) // fix IE < 7 select problems
592
+ $('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4,
593
+ height: inst.dpDiv.height() + 4});
594
+ };
595
+ if ($.effects && $.effects[showAnim])
596
+ inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
597
+ else
598
+ inst.dpDiv[showAnim](duration, postProcess);
599
+ if (duration == '')
600
+ postProcess();
601
+ if (inst.input[0].type != 'hidden')
602
+ inst.input[0].focus();
603
+ $.datepicker._curInst = inst;
604
+ }
605
+ },
606
+
607
+ /* Generate the date picker content. */
608
+ _updateDatepicker: function(inst) {
609
+ var dims = {width: inst.dpDiv.width() + 4,
610
+ height: inst.dpDiv.height() + 4};
611
+ inst.dpDiv.empty().append(this._generateHTML(inst)).
612
+ find('iframe.ui-datepicker-cover').
613
+ css({width: dims.width, height: dims.height});
614
+ var numMonths = this._getNumberOfMonths(inst);
615
+ inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
616
+ 'Class']('ui-datepicker-multi');
617
+ inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
618
+ 'Class']('ui-datepicker-rtl');
619
+ if (inst.input && inst.input[0].type != 'hidden' && inst == $.datepicker._curInst)
620
+ $(inst.input[0]).focus();
621
+ },
622
+
623
+ /* Check positioning to remain on screen. */
624
+ _checkOffset: function(inst, offset, isFixed) {
625
+ var pos = inst.input ? this._findPos(inst.input[0]) : null;
626
+ var browserWidth = window.innerWidth || (document.documentElement ?
627
+ document.documentElement.clientWidth : document.body.clientWidth);
628
+ var browserHeight = window.innerHeight || (document.documentElement ?
629
+ document.documentElement.clientHeight : document.body.clientHeight);
630
+ var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
631
+ var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
632
+ // reposition date picker horizontally if outside the browser window
633
+ if (this._get(inst, 'isRTL') || (offset.left + inst.dpDiv.width() - scrollX) > browserWidth)
634
+ offset.left = Math.max((isFixed ? 0 : scrollX),
635
+ pos[0] + (inst.input ? inst.input.width() : 0) - (isFixed ? scrollX : 0) - inst.dpDiv.width() -
636
+ (isFixed && $.browser.opera ? document.documentElement.scrollLeft : 0));
637
+ else
638
+ offset.left -= (isFixed ? scrollX : 0);
639
+ // reposition date picker vertically if outside the browser window
640
+ if ((offset.top + inst.dpDiv.height() - scrollY) > browserHeight)
641
+ offset.top = Math.max((isFixed ? 0 : scrollY),
642
+ pos[1] - (isFixed ? scrollY : 0) - (this._inDialog ? 0 : inst.dpDiv.height()) -
643
+ (isFixed && $.browser.opera ? document.documentElement.scrollTop : 0));
644
+ else
645
+ offset.top -= (isFixed ? scrollY : 0);
646
+ return offset;
647
+ },
648
+
649
+ /* Find an object's position on the screen. */
650
+ _findPos: function(obj) {
651
+ while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
652
+ obj = obj.nextSibling;
653
+ }
654
+ var position = $(obj).offset();
655
+ return [position.left, position.top];
656
+ },
657
+
658
+ /* Hide the date picker from view.
659
+ @param input element - the input field attached to the date picker
660
+ @param duration string - the duration over which to close the date picker */
661
+ _hideDatepicker: function(input, duration) {
662
+ var inst = this._curInst;
663
+ if (!inst || (input && inst != $.data(input, PROP_NAME)))
664
+ return;
665
+ var rangeSelect = this._get(inst, 'rangeSelect');
666
+ if (rangeSelect && inst.stayOpen)
667
+ this._selectDate('#' + inst.id, this._formatDate(inst,
668
+ inst.currentDay, inst.currentMonth, inst.currentYear));
669
+ inst.stayOpen = false;
670
+ if (this._datepickerShowing) {
671
+ duration = (duration != null ? duration : this._get(inst, 'duration'));
672
+ var showAnim = this._get(inst, 'showAnim');
673
+ var postProcess = function() {
674
+ $.datepicker._tidyDialog(inst);
675
+ };
676
+ if (duration != '' && $.effects && $.effects[showAnim])
677
+ inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'),
678
+ duration, postProcess);
679
+ else
680
+ inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' :
681
+ (showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess);
682
+ if (duration == '')
683
+ this._tidyDialog(inst);
684
+ var onClose = this._get(inst, 'onClose');
685
+ if (onClose)
686
+ onClose.apply((inst.input ? inst.input[0] : null),
687
+ [(inst.input ? inst.input.val() : ''), inst]); // trigger custom callback
688
+ this._datepickerShowing = false;
689
+ this._lastInput = null;
690
+ inst.settings.prompt = null;
691
+ if (this._inDialog) {
692
+ this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
693
+ if ($.blockUI) {
694
+ $.unblockUI();
695
+ $('body').append(this.dpDiv);
696
+ }
697
+ }
698
+ this._inDialog = false;
699
+ }
700
+ this._curInst = null;
701
+ },
702
+
703
+ /* Tidy up after a dialog display. */
704
+ _tidyDialog: function(inst) {
705
+ inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker');
706
+ $('.' + this._promptClass, inst.dpDiv).remove();
707
+ },
708
+
709
+ /* Close date picker if clicked elsewhere. */
710
+ _checkExternalClick: function(event) {
711
+ if (!$.datepicker._curInst)
712
+ return;
713
+ var $target = $(event.target);
714
+ if (($target.parents('#' + $.datepicker._mainDivId).length == 0) &&
715
+ !$target.hasClass($.datepicker.markerClassName) &&
716
+ !$target.hasClass($.datepicker._triggerClass) &&
717
+ $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
718
+ $.datepicker._hideDatepicker(null, '');
719
+ },
720
+
721
+ /* Adjust one of the date sub-fields. */
722
+ _adjustDate: function(id, offset, period) {
723
+ var target = $(id);
724
+ var inst = this._getInst(target[0]);
725
+ this._adjustInstDate(inst, offset, period);
726
+ this._updateDatepicker(inst);
727
+ },
728
+
729
+ /* Action for current link. */
730
+ _gotoToday: function(id) {
731
+ var target = $(id);
732
+ var inst = this._getInst(target[0]);
733
+ if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
734
+ inst.selectedDay = inst.currentDay;
735
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth;
736
+ inst.drawYear = inst.selectedYear = inst.currentYear;
737
+ }
738
+ else {
739
+ var date = new Date();
740
+ inst.selectedDay = date.getDate();
741
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
742
+ inst.drawYear = inst.selectedYear = date.getFullYear();
743
+ }
744
+ this._notifyChange(inst);
745
+ this._adjustDate(target);
746
+ },
747
+
748
+ /* Action for selecting a new month/year. */
749
+ _selectMonthYear: function(id, select, period) {
750
+ var target = $(id);
751
+ var inst = this._getInst(target[0]);
752
+ inst._selectingMonthYear = false;
753
+ inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
754
+ inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
755
+ parseInt(select.options[select.selectedIndex].value,10);
756
+ this._notifyChange(inst);
757
+ this._adjustDate(target);
758
+ },
759
+
760
+ /* Restore input focus after not changing month/year. */
761
+ _clickMonthYear: function(id) {
762
+ var target = $(id);
763
+ var inst = this._getInst(target[0]);
764
+ if (inst.input && inst._selectingMonthYear && !$.browser.msie)
765
+ inst.input[0].focus();
766
+ inst._selectingMonthYear = !inst._selectingMonthYear;
767
+ },
768
+
769
+ /* Action for changing the first week day. */
770
+ _changeFirstDay: function(id, day) {
771
+ var target = $(id);
772
+ var inst = this._getInst(target[0]);
773
+ inst.settings.firstDay = day;
774
+ this._updateDatepicker(inst);
775
+ },
776
+
777
+ /* Action for selecting a day. */
778
+ _selectDay: function(id, month, year, td) {
779
+ if ($(td).hasClass(this._unselectableClass))
780
+ return;
781
+ var target = $(id);
782
+ var inst = this._getInst(target[0]);
783
+ var rangeSelect = this._get(inst, 'rangeSelect');
784
+ if (rangeSelect) {
785
+ inst.stayOpen = !inst.stayOpen;
786
+ if (inst.stayOpen) {
787
+ $('.ui-datepicker td', inst.dpDiv).removeClass(this._currentClass);
788
+ $(td).addClass(this._currentClass);
789
+ }
790
+ }
791
+ inst.selectedDay = inst.currentDay = $('a', td).html();
792
+ inst.selectedMonth = inst.currentMonth = month;
793
+ inst.selectedYear = inst.currentYear = year;
794
+ if (inst.stayOpen) {
795
+ inst.endDay = inst.endMonth = inst.endYear = null;
796
+ }
797
+ else if (rangeSelect) {
798
+ inst.endDay = inst.currentDay;
799
+ inst.endMonth = inst.currentMonth;
800
+ inst.endYear = inst.currentYear;
801
+ }
802
+ this._selectDate(id, this._formatDate(inst,
803
+ inst.currentDay, inst.currentMonth, inst.currentYear));
804
+ if (inst.stayOpen) {
805
+ inst.rangeStart = new Date(inst.currentYear, inst.currentMonth, inst.currentDay);
806
+ this._updateDatepicker(inst);
807
+ }
808
+ else if (rangeSelect) {
809
+ inst.selectedDay = inst.currentDay = inst.rangeStart.getDate();
810
+ inst.selectedMonth = inst.currentMonth = inst.rangeStart.getMonth();
811
+ inst.selectedYear = inst.currentYear = inst.rangeStart.getFullYear();
812
+ inst.rangeStart = null;
813
+ if (inst.inline)
814
+ this._updateDatepicker(inst);
815
+ }
816
+ },
817
+
818
+ /* Erase the input field and hide the date picker. */
819
+ _clearDate: function(id) {
820
+ var target = $(id);
821
+ var inst = this._getInst(target[0]);
822
+ if (this._get(inst, 'mandatory'))
823
+ return;
824
+ inst.stayOpen = false;
825
+ inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null;
826
+ this._selectDate(target, '');
827
+ },
828
+
829
+ /* Update the input field with the selected date. */
830
+ _selectDate: function(id, dateStr) {
831
+ var target = $(id);
832
+ var inst = this._getInst(target[0]);
833
+ dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
834
+ if (this._get(inst, 'rangeSelect') && dateStr)
835
+ dateStr = (inst.rangeStart ? this._formatDate(inst, inst.rangeStart) :
836
+ dateStr) + this._get(inst, 'rangeSeparator') + dateStr;
837
+ if (inst.input)
838
+ inst.input.val(dateStr);
839
+ this._updateAlternate(inst);
840
+ var onSelect = this._get(inst, 'onSelect');
841
+ if (onSelect)
842
+ onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
843
+ else if (inst.input)
844
+ inst.input.trigger('change'); // fire the change event
845
+ if (inst.inline)
846
+ this._updateDatepicker(inst);
847
+ else if (!inst.stayOpen) {
848
+ this._hideDatepicker(null, this._get(inst, 'duration'));
849
+ this._lastInput = inst.input[0];
850
+ if (typeof(inst.input[0]) != 'object')
851
+ inst.input[0].focus(); // restore focus
852
+ this._lastInput = null;
853
+ }
854
+ },
855
+
856
+ /* Update any alternate field to synchronise with the main field. */
857
+ _updateAlternate: function(inst) {
858
+ var altField = this._get(inst, 'altField');
859
+ if (altField) { // update alternate field too
860
+ var altFormat = this._get(inst, 'altFormat');
861
+ var date = this._getDate(inst);
862
+ dateStr = (isArray(date) ? (!date[0] && !date[1] ? '' :
863
+ this.formatDate(altFormat, date[0], this._getFormatConfig(inst)) +
864
+ this._get(inst, 'rangeSeparator') + this.formatDate(
865
+ altFormat, date[1] || date[0], this._getFormatConfig(inst))) :
866
+ this.formatDate(altFormat, date, this._getFormatConfig(inst)));
867
+ $(altField).each(function() { $(this).val(dateStr); });
868
+ }
869
+ },
870
+
871
+ /* Set as beforeShowDay function to prevent selection of weekends.
872
+ @param date Date - the date to customise
873
+ @return [boolean, string] - is this date selectable?, what is its CSS class? */
874
+ noWeekends: function(date) {
875
+ var day = date.getDay();
876
+ return [(day > 0 && day < 6), ''];
877
+ },
878
+
879
+ /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
880
+ @param date Date - the date to get the week for
881
+ @return number - the number of the week within the year that contains this date */
882
+ iso8601Week: function(date) {
883
+ var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(),
884
+ (date.getTimezoneOffset() / -60));
885
+ var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan
886
+ var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7
887
+ firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday
888
+ if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary
889
+ checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year
890
+ return $.datepicker.iso8601Week(checkDate);
891
+ } else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year
892
+ firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;
893
+ if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary
894
+ return 1;
895
+ }
896
+ }
897
+ return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date
898
+ },
899
+
900
+ /* Provide status text for a particular date.
901
+ @param date the date to get the status for
902
+ @param inst the current datepicker instance
903
+ @return the status display text for this date */
904
+ dateStatus: function(date, inst) {
905
+ return $.datepicker.formatDate($.datepicker._get(inst, 'dateStatus'),
906
+ date, $.datepicker._getFormatConfig(inst));
907
+ },
908
+
909
+ /* Parse a string value into a date object.
910
+ See formatDate below for the possible formats.
911
+
912
+ @param format string - the expected format of the date
913
+ @param value string - the date in the above format
914
+ @param settings Object - attributes include:
915
+ shortYearCutoff number - the cutoff year for determining the century (optional)
916
+ dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
917
+ dayNames string[7] - names of the days from Sunday (optional)
918
+ monthNamesShort string[12] - abbreviated names of the months (optional)
919
+ monthNames string[12] - names of the months (optional)
920
+ @return Date - the extracted date value or null if value is blank */
921
+ parseDate: function (format, value, settings) {
922
+ if (format == null || value == null)
923
+ throw 'Invalid arguments';
924
+ value = (typeof value == 'object' ? value.toString() : value + '');
925
+ if (value == '')
926
+ return null;
927
+ var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
928
+ var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
929
+ var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
930
+ var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
931
+ var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
932
+ var year = -1;
933
+ var month = -1;
934
+ var day = -1;
935
+ var doy = -1;
936
+ var literal = false;
937
+ // Check whether a format character is doubled
938
+ var lookAhead = function(match) {
939
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
940
+ if (matches)
941
+ iFormat++;
942
+ return matches;
943
+ };
944
+ // Extract a number from the string value
945
+ var getNumber = function(match) {
946
+ lookAhead(match);
947
+ var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2)));
948
+ var size = origSize;
949
+ var num = 0;
950
+ while (size > 0 && iValue < value.length &&
951
+ value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') {
952
+ num = num * 10 + parseInt(value.charAt(iValue++),10);
953
+ size--;
954
+ }
955
+ if (size == origSize)
956
+ throw 'Missing number at position ' + iValue;
957
+ return num;
958
+ };
959
+ // Extract a name from the string value and convert to an index
960
+ var getName = function(match, shortNames, longNames) {
961
+ var names = (lookAhead(match) ? longNames : shortNames);
962
+ var size = 0;
963
+ for (var j = 0; j < names.length; j++)
964
+ size = Math.max(size, names[j].length);
965
+ var name = '';
966
+ var iInit = iValue;
967
+ while (size > 0 && iValue < value.length) {
968
+ name += value.charAt(iValue++);
969
+ for (var i = 0; i < names.length; i++)
970
+ if (name == names[i])
971
+ return i + 1;
972
+ size--;
973
+ }
974
+ throw 'Unknown name at position ' + iInit;
975
+ };
976
+ // Confirm that a literal character matches the string value
977
+ var checkLiteral = function() {
978
+ if (value.charAt(iValue) != format.charAt(iFormat))
979
+ throw 'Unexpected literal at position ' + iValue;
980
+ iValue++;
981
+ };
982
+ var iValue = 0;
983
+ for (var iFormat = 0; iFormat < format.length; iFormat++) {
984
+ if (literal)
985
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
986
+ literal = false;
987
+ else
988
+ checkLiteral();
989
+ else
990
+ switch (format.charAt(iFormat)) {
991
+ case 'd':
992
+ day = getNumber('d');
993
+ break;
994
+ case 'D':
995
+ getName('D', dayNamesShort, dayNames);
996
+ break;
997
+ case 'o':
998
+ doy = getNumber('o');
999
+ break;
1000
+ case 'm':
1001
+ month = getNumber('m');
1002
+ break;
1003
+ case 'M':
1004
+ month = getName('M', monthNamesShort, monthNames);
1005
+ break;
1006
+ case 'y':
1007
+ year = getNumber('y');
1008
+ break;
1009
+ case '@':
1010
+ var date = new Date(getNumber('@'));
1011
+ year = date.getFullYear();
1012
+ month = date.getMonth() + 1;
1013
+ day = date.getDate();
1014
+ break;
1015
+ case "'":
1016
+ if (lookAhead("'"))
1017
+ checkLiteral();
1018
+ else
1019
+ literal = true;
1020
+ break;
1021
+ default:
1022
+ checkLiteral();
1023
+ }
1024
+ }
1025
+ if (year < 100)
1026
+ year += new Date().getFullYear() - new Date().getFullYear() % 100 +
1027
+ (year <= shortYearCutoff ? 0 : -100);
1028
+ if (doy > -1) {
1029
+ month = 1;
1030
+ day = doy;
1031
+ do {
1032
+ var dim = this._getDaysInMonth(year, month - 1);
1033
+ if (day <= dim)
1034
+ break;
1035
+ month++;
1036
+ day -= dim;
1037
+ } while (true);
1038
+ }
1039
+ var date = new Date(year, month - 1, day);
1040
+ if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
1041
+ throw 'Invalid date'; // E.g. 31/02/*
1042
+ return date;
1043
+ },
1044
+
1045
+ /* Standard date formats. */
1046
+ ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
1047
+ COOKIE: 'D, dd M yy',
1048
+ ISO_8601: 'yy-mm-dd',
1049
+ RFC_822: 'D, d M y',
1050
+ RFC_850: 'DD, dd-M-y',
1051
+ RFC_1036: 'D, d M y',
1052
+ RFC_1123: 'D, d M yy',
1053
+ RFC_2822: 'D, d M yy',
1054
+ RSS: 'D, d M y', // RFC 822
1055
+ TIMESTAMP: '@',
1056
+ W3C: 'yy-mm-dd', // ISO 8601
1057
+
1058
+ /* Format a date object into a string value.
1059
+ The format can be combinations of the following:
1060
+ d - day of month (no leading zero)
1061
+ dd - day of month (two digit)
1062
+ o - day of year (no leading zeros)
1063
+ oo - day of year (three digit)
1064
+ D - day name short
1065
+ DD - day name long
1066
+ m - month of year (no leading zero)
1067
+ mm - month of year (two digit)
1068
+ M - month name short
1069
+ MM - month name long
1070
+ y - year (two digit)
1071
+ yy - year (four digit)
1072
+ @ - Unix timestamp (ms since 01/01/1970)
1073
+ '...' - literal text
1074
+ '' - single quote
1075
+
1076
+ @param format string - the desired format of the date
1077
+ @param date Date - the date value to format
1078
+ @param settings Object - attributes include:
1079
+ dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
1080
+ dayNames string[7] - names of the days from Sunday (optional)
1081
+ monthNamesShort string[12] - abbreviated names of the months (optional)
1082
+ monthNames string[12] - names of the months (optional)
1083
+ @return string - the date in the above format */
1084
+ formatDate: function (format, date, settings) {
1085
+ if (!date)
1086
+ return '';
1087
+ var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
1088
+ var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
1089
+ var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
1090
+ var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
1091
+ // Check whether a format character is doubled
1092
+ var lookAhead = function(match) {
1093
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
1094
+ if (matches)
1095
+ iFormat++;
1096
+ return matches;
1097
+ };
1098
+ // Format a number, with leading zero if necessary
1099
+ var formatNumber = function(match, value, len) {
1100
+ var num = '' + value;
1101
+ if (lookAhead(match))
1102
+ while (num.length < len)
1103
+ num = '0' + num;
1104
+ return num;
1105
+ };
1106
+ // Format a name, short or long as requested
1107
+ var formatName = function(match, value, shortNames, longNames) {
1108
+ return (lookAhead(match) ? longNames[value] : shortNames[value]);
1109
+ };
1110
+ var output = '';
1111
+ var literal = false;
1112
+ if (date)
1113
+ for (var iFormat = 0; iFormat < format.length; iFormat++) {
1114
+ if (literal)
1115
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
1116
+ literal = false;
1117
+ else
1118
+ output += format.charAt(iFormat);
1119
+ else
1120
+ switch (format.charAt(iFormat)) {
1121
+ case 'd':
1122
+ output += formatNumber('d', date.getDate(), 2);
1123
+ break;
1124
+ case 'D':
1125
+ output += formatName('D', date.getDay(), dayNamesShort, dayNames);
1126
+ break;
1127
+ case 'o':
1128
+ var doy = date.getDate();
1129
+ for (var m = date.getMonth() - 1; m >= 0; m--)
1130
+ doy += this._getDaysInMonth(date.getFullYear(), m);
1131
+ output += formatNumber('o', doy, 3);
1132
+ break;
1133
+ case 'm':
1134
+ output += formatNumber('m', date.getMonth() + 1, 2);
1135
+ break;
1136
+ case 'M':
1137
+ output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
1138
+ break;
1139
+ case 'y':
1140
+ output += (lookAhead('y') ? date.getFullYear() :
1141
+ (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
1142
+ break;
1143
+ case '@':
1144
+ output += date.getTime();
1145
+ break;
1146
+ case "'":
1147
+ if (lookAhead("'"))
1148
+ output += "'";
1149
+ else
1150
+ literal = true;
1151
+ break;
1152
+ default:
1153
+ output += format.charAt(iFormat);
1154
+ }
1155
+ }
1156
+ return output;
1157
+ },
1158
+
1159
+ /* Extract all possible characters from the date format. */
1160
+ _possibleChars: function (format) {
1161
+ var chars = '';
1162
+ var literal = false;
1163
+ for (var iFormat = 0; iFormat < format.length; iFormat++)
1164
+ if (literal)
1165
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
1166
+ literal = false;
1167
+ else
1168
+ chars += format.charAt(iFormat);
1169
+ else
1170
+ switch (format.charAt(iFormat)) {
1171
+ case 'd': case 'm': case 'y': case '@':
1172
+ chars += '0123456789';
1173
+ break;
1174
+ case 'D': case 'M':
1175
+ return null; // Accept anything
1176
+ case "'":
1177
+ if (lookAhead("'"))
1178
+ chars += "'";
1179
+ else
1180
+ literal = true;
1181
+ break;
1182
+ default:
1183
+ chars += format.charAt(iFormat);
1184
+ }
1185
+ return chars;
1186
+ },
1187
+
1188
+ /* Get a setting value, defaulting if necessary. */
1189
+ _get: function(inst, name) {
1190
+ return inst.settings[name] !== undefined ?
1191
+ inst.settings[name] : this._defaults[name];
1192
+ },
1193
+
1194
+ /* Parse existing date and initialise date picker. */
1195
+ _setDateFromField: function(inst) {
1196
+ var dateFormat = this._get(inst, 'dateFormat');
1197
+ var dates = inst.input ? inst.input.val().split(this._get(inst, 'rangeSeparator')) : null;
1198
+ inst.endDay = inst.endMonth = inst.endYear = null;
1199
+ var date = defaultDate = this._getDefaultDate(inst);
1200
+ if (dates.length > 0) {
1201
+ var settings = this._getFormatConfig(inst);
1202
+ if (dates.length > 1) {
1203
+ date = this.parseDate(dateFormat, dates[1], settings) || defaultDate;
1204
+ inst.endDay = date.getDate();
1205
+ inst.endMonth = date.getMonth();
1206
+ inst.endYear = date.getFullYear();
1207
+ }
1208
+ try {
1209
+ date = this.parseDate(dateFormat, dates[0], settings) || defaultDate;
1210
+ } catch (e) {
1211
+ this.log(e);
1212
+ date = defaultDate;
1213
+ }
1214
+ }
1215
+ inst.selectedDay = date.getDate();
1216
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
1217
+ inst.drawYear = inst.selectedYear = date.getFullYear();
1218
+ inst.currentDay = (dates[0] ? date.getDate() : 0);
1219
+ inst.currentMonth = (dates[0] ? date.getMonth() : 0);
1220
+ inst.currentYear = (dates[0] ? date.getFullYear() : 0);
1221
+ this._adjustInstDate(inst);
1222
+ },
1223
+
1224
+ /* Retrieve the default date shown on opening. */
1225
+ _getDefaultDate: function(inst) {
1226
+ var date = this._determineDate(this._get(inst, 'defaultDate'), new Date());
1227
+ var minDate = this._getMinMaxDate(inst, 'min', true);
1228
+ var maxDate = this._getMinMaxDate(inst, 'max');
1229
+ date = (minDate && date < minDate ? minDate : date);
1230
+ date = (maxDate && date > maxDate ? maxDate : date);
1231
+ return date;
1232
+ },
1233
+
1234
+ /* A date may be specified as an exact value or a relative one. */
1235
+ _determineDate: function(date, defaultDate) {
1236
+ var offsetNumeric = function(offset) {
1237
+ var date = new Date();
1238
+ date.setUTCDate(date.getUTCDate() + offset);
1239
+ return date;
1240
+ };
1241
+ var offsetString = function(offset, getDaysInMonth) {
1242
+ var date = new Date();
1243
+ var year = date.getFullYear();
1244
+ var month = date.getMonth();
1245
+ var day = date.getDate();
1246
+ var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
1247
+ var matches = pattern.exec(offset);
1248
+ while (matches) {
1249
+ switch (matches[2] || 'd') {
1250
+ case 'd' : case 'D' :
1251
+ day += parseInt(matches[1],10); break;
1252
+ case 'w' : case 'W' :
1253
+ day += parseInt(matches[1],10) * 7; break;
1254
+ case 'm' : case 'M' :
1255
+ month += parseInt(matches[1],10);
1256
+ day = Math.min(day, getDaysInMonth(year, month));
1257
+ break;
1258
+ case 'y': case 'Y' :
1259
+ year += parseInt(matches[1],10);
1260
+ day = Math.min(day, getDaysInMonth(year, month));
1261
+ break;
1262
+ }
1263
+ matches = pattern.exec(offset);
1264
+ }
1265
+ return new Date(year, month, day);
1266
+ };
1267
+ date = (date == null ? defaultDate :
1268
+ (typeof date == 'string' ? offsetString(date, this._getDaysInMonth) :
1269
+ (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : date)));
1270
+ return (date && date.toString() == 'Invalid Date' ? defaultDate : date);
1271
+ },
1272
+
1273
+ /* Set the date(s) directly. */
1274
+ _setDate: function(inst, date, endDate) {
1275
+ var clear = !(date);
1276
+ var origMonth = inst.selectedMonth;
1277
+ var origYear = inst.selectedYear;
1278
+ date = this._determineDate(date, new Date());
1279
+ inst.selectedDay = inst.currentDay = date.getDate();
1280
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth();
1281
+ inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear();
1282
+ if (this._get(inst, 'rangeSelect')) {
1283
+ if (endDate) {
1284
+ endDate = this._determineDate(endDate, null);
1285
+ inst.endDay = endDate.getDate();
1286
+ inst.endMonth = endDate.getMonth();
1287
+ inst.endYear = endDate.getFullYear();
1288
+ } else {
1289
+ inst.endDay = inst.currentDay;
1290
+ inst.endMonth = inst.currentMonth;
1291
+ inst.endYear = inst.currentYear;
1292
+ }
1293
+ }
1294
+ if (origMonth != inst.selectedMonth || origYear != inst.selectedYear)
1295
+ this._notifyChange(inst);
1296
+ this._adjustInstDate(inst);
1297
+ if (inst.input)
1298
+ inst.input.val(clear ? '' : this._formatDate(inst) +
1299
+ (!this._get(inst, 'rangeSelect') ? '' : this._get(inst, 'rangeSeparator') +
1300
+ this._formatDate(inst, inst.endDay, inst.endMonth, inst.endYear)));
1301
+ },
1302
+
1303
+ /* Retrieve the date(s) directly. */
1304
+ _getDate: function(inst) {
1305
+ var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
1306
+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
1307
+ if (this._get(inst, 'rangeSelect')) {
1308
+ return [inst.rangeStart || startDate,
1309
+ (!inst.endYear ? inst.rangeStart || startDate :
1310
+ new Date(inst.endYear, inst.endMonth, inst.endDay))];
1311
+ } else
1312
+ return startDate;
1313
+ },
1314
+
1315
+ /* Generate the HTML for the current state of the date picker. */
1316
+ _generateHTML: function(inst) {
1317
+ var today = new Date();
1318
+ today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); // clear time
1319
+ var showStatus = this._get(inst, 'showStatus');
1320
+ var initStatus = this._get(inst, 'initStatus') || '&#xa0;';
1321
+ var isRTL = this._get(inst, 'isRTL');
1322
+ // build the date picker HTML
1323
+ var clear = (this._get(inst, 'mandatory') ? '' :
1324
+ '<div class="ui-datepicker-clear"><a onclick="jQuery.datepicker._clearDate(\'#' + inst.id + '\');"' +
1325
+ this._addStatus(showStatus, inst.id, this._get(inst, 'clearStatus'), initStatus) + '>' +
1326
+ this._get(inst, 'clearText') + '</a></div>');
1327
+ var controls = '<div class="ui-datepicker-control">' + (isRTL ? '' : clear) +
1328
+ '<div class="ui-datepicker-close"><a onclick="jQuery.datepicker._hideDatepicker();"' +
1329
+ this._addStatus(showStatus, inst.id, this._get(inst, 'closeStatus'), initStatus) + '>' +
1330
+ this._get(inst, 'closeText') + '</a></div>' + (isRTL ? clear : '') + '</div>';
1331
+ var prompt = this._get(inst, 'prompt');
1332
+ var closeAtTop = this._get(inst, 'closeAtTop');
1333
+ var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
1334
+ var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
1335
+ var showBigPrevNext = this._get(inst, 'showBigPrevNext');
1336
+ var numMonths = this._getNumberOfMonths(inst);
1337
+ var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
1338
+ var stepMonths = this._get(inst, 'stepMonths');
1339
+ var stepBigMonths = this._get(inst, 'stepBigMonths');
1340
+ var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
1341
+ var currentDate = (!inst.currentDay ? new Date(9999, 9, 9) :
1342
+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
1343
+ var minDate = this._getMinMaxDate(inst, 'min', true);
1344
+ var maxDate = this._getMinMaxDate(inst, 'max');
1345
+ var drawMonth = inst.drawMonth - showCurrentAtPos;
1346
+ var drawYear = inst.drawYear;
1347
+ if (drawMonth < 0) {
1348
+ drawMonth += 12;
1349
+ drawYear--;
1350
+ }
1351
+ if (maxDate) {
1352
+ var maxDraw = new Date(maxDate.getFullYear(),
1353
+ maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate());
1354
+ maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
1355
+ while (new Date(drawYear, drawMonth, 1) > maxDraw) {
1356
+ drawMonth--;
1357
+ if (drawMonth < 0) {
1358
+ drawMonth = 11;
1359
+ drawYear--;
1360
+ }
1361
+ }
1362
+ }
1363
+ // controls and links
1364
+ var prevText = this._get(inst, 'prevText');
1365
+ prevText = (!navigationAsDateFormat ? prevText : this.formatDate(
1366
+ prevText, new Date(drawYear, drawMonth - stepMonths, 1), this._getFormatConfig(inst)));
1367
+ var prevBigText = (showBigPrevNext ? this._get(inst, 'prevBigText') : '');
1368
+ prevBigText = (!navigationAsDateFormat ? prevBigText : this.formatDate(
1369
+ prevBigText, new Date(drawYear, drawMonth - stepBigMonths, 1), this._getFormatConfig(inst)));
1370
+ var prev = '<div class="ui-datepicker-prev">' + (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
1371
+ (showBigPrevNext ? '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepBigMonths + ', \'M\');"' +
1372
+ this._addStatus(showStatus, inst.id, this._get(inst, 'prevBigStatus'), initStatus) + '>' + prevBigText + '</a>' : '') +
1373
+ '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
1374
+ this._addStatus(showStatus, inst.id, this._get(inst, 'prevStatus'), initStatus) + '>' + prevText + '</a>' :
1375
+ (hideIfNoPrevNext ? '' : '<label>' + prevBigText + '</label><label>' + prevText + '</label>')) + '</div>';
1376
+ var nextText = this._get(inst, 'nextText');
1377
+ nextText = (!navigationAsDateFormat ? nextText : this.formatDate(
1378
+ nextText, new Date(drawYear, drawMonth + stepMonths, 1), this._getFormatConfig(inst)));
1379
+ var nextBigText = (showBigPrevNext ? this._get(inst, 'nextBigText') : '');
1380
+ nextBigText = (!navigationAsDateFormat ? nextBigText : this.formatDate(
1381
+ nextBigText, new Date(drawYear, drawMonth + stepBigMonths, 1), this._getFormatConfig(inst)));
1382
+ var next = '<div class="ui-datepicker-next">' + (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
1383
+ '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
1384
+ this._addStatus(showStatus, inst.id, this._get(inst, 'nextStatus'), initStatus) + '>' + nextText + '</a>' +
1385
+ (showBigPrevNext ? '<a onclick="jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepBigMonths + ', \'M\');"' +
1386
+ this._addStatus(showStatus, inst.id, this._get(inst, 'nextBigStatus'), initStatus) + '>' + nextBigText + '</a>' : '') :
1387
+ (hideIfNoPrevNext ? '' : '<label>' + nextText + '</label><label>' + nextBigText + '</label>')) + '</div>';
1388
+ var currentText = this._get(inst, 'currentText');
1389
+ var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
1390
+ currentText = (!navigationAsDateFormat ? currentText :
1391
+ this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
1392
+ var html = (prompt ? '<div class="' + this._promptClass + '">' + prompt + '</div>' : '') +
1393
+ (closeAtTop && !inst.inline ? controls : '') +
1394
+ '<div class="ui-datepicker-links">' + (isRTL ? next : prev) +
1395
+ (this._isInRange(inst, gotoDate) ? '<div class="ui-datepicker-current">' +
1396
+ '<a onclick="jQuery.datepicker._gotoToday(\'#' + inst.id + '\');"' +
1397
+ this._addStatus(showStatus, inst.id, this._get(inst, 'currentStatus'), initStatus) + '>' +
1398
+ currentText + '</a></div>' : '') + (isRTL ? prev : next) + '</div>';
1399
+ var firstDay = this._get(inst, 'firstDay');
1400
+ var changeFirstDay = this._get(inst, 'changeFirstDay');
1401
+ var dayNames = this._get(inst, 'dayNames');
1402
+ var dayNamesShort = this._get(inst, 'dayNamesShort');
1403
+ var dayNamesMin = this._get(inst, 'dayNamesMin');
1404
+ var monthNames = this._get(inst, 'monthNames');
1405
+ var beforeShowDay = this._get(inst, 'beforeShowDay');
1406
+ var highlightWeek = this._get(inst, 'highlightWeek');
1407
+ var showOtherMonths = this._get(inst, 'showOtherMonths');
1408
+ var showWeeks = this._get(inst, 'showWeeks');
1409
+ var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
1410
+ var weekStatus = this._get(inst, 'weekStatus');
1411
+ var status = (showStatus ? this._get(inst, 'dayStatus') || initStatus : '');
1412
+ var dateStatus = this._get(inst, 'statusForDate') || this.dateStatus;
1413
+ var endDate = inst.endDay ? new Date(inst.endYear, inst.endMonth, inst.endDay) : currentDate;
1414
+ for (var row = 0; row < numMonths[0]; row++)
1415
+ for (var col = 0; col < numMonths[1]; col++) {
1416
+ var selectedDate = new Date(drawYear, drawMonth, inst.selectedDay);
1417
+ html += '<div class="ui-datepicker-one-month' + (col == 0 ? ' ui-datepicker-new-row' : '') + '">' +
1418
+ this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
1419
+ selectedDate, row > 0 || col > 0, showStatus, initStatus, monthNames) + // draw month headers
1420
+ '<table class="ui-datepicker" cellpadding="0" cellspacing="0"><thead>' +
1421
+ '<tr class="ui-datepicker-title-row">' +
1422
+ (showWeeks ? '<td' + this._addStatus(showStatus, inst.id, weekStatus, initStatus) + '>' +
1423
+ this._get(inst, 'weekHeader') + '</td>' : '');
1424
+ for (var dow = 0; dow < 7; dow++) { // days of the week
1425
+ var day = (dow + firstDay) % 7;
1426
+ var dayStatus = (status.indexOf('DD') > -1 ? status.replace(/DD/, dayNames[day]) :
1427
+ status.replace(/D/, dayNamesShort[day]));
1428
+ html += '<td' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end-cell"' : '') + '>' +
1429
+ (!changeFirstDay ? '<span' :
1430
+ '<a onclick="jQuery.datepicker._changeFirstDay(\'#' + inst.id + '\', ' + day + ');"') +
1431
+ this._addStatus(showStatus, inst.id, dayStatus, initStatus) + ' title="' + dayNames[day] + '">' +
1432
+ dayNamesMin[day] + (changeFirstDay ? '</a>' : '</span>') + '</td>';
1433
+ }
1434
+ html += '</tr></thead><tbody>';
1435
+ var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
1436
+ if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
1437
+ inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
1438
+ var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
1439
+ var tzDate = new Date(drawYear, drawMonth, 1 - leadDays);
1440
+ var utcDate = new Date(drawYear, drawMonth, 1 - leadDays);
1441
+ var printDate = utcDate;
1442
+ var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
1443
+ for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
1444
+ html += '<tr class="ui-datepicker-days-row">' +
1445
+ (showWeeks ? '<td class="ui-datepicker-week-col"' +
1446
+ this._addStatus(showStatus, inst.id, weekStatus, initStatus) + '>' +
1447
+ calculateWeek(printDate) + '</td>' : '');
1448
+ for (var dow = 0; dow < 7; dow++) { // create date picker days
1449
+ var daySettings = (beforeShowDay ?
1450
+ beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
1451
+ var otherMonth = (printDate.getMonth() != drawMonth);
1452
+ var unselectable = otherMonth || !daySettings[0] ||
1453
+ (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
1454
+ html += '<td class="ui-datepicker-days-cell' +
1455
+ ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end-cell' : '') + // highlight weekends
1456
+ (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
1457
+ (printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth ?
1458
+ ' ui-datepicker-days-cell-over' : '') + // highlight selected day
1459
+ (unselectable ? ' ' + this._unselectableClass : '') + // highlight unselectable days
1460
+ (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
1461
+ (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range
1462
+ ' ' + this._currentClass : '') + // highlight selected day
1463
+ (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
1464
+ ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
1465
+ (unselectable ? (highlightWeek ? ' onmouseover="jQuery(this).parent().addClass(\'ui-datepicker-week-over\');"' + // highlight selection week
1466
+ ' onmouseout="jQuery(this).parent().removeClass(\'ui-datepicker-week-over\');"' : '') : // unhighlight selection week
1467
+ ' onmouseover="jQuery(this).addClass(\'ui-datepicker-days-cell-over\')' + // highlight selection
1468
+ (highlightWeek ? '.parent().addClass(\'ui-datepicker-week-over\')' : '') + ';' + // highlight selection week
1469
+ (!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#ui-datepicker-status-' +
1470
+ inst.id + '\').html(\'' + (dateStatus.apply((inst.input ? inst.input[0] : null),
1471
+ [printDate, inst]) || initStatus) +'\');') + '"' +
1472
+ ' onmouseout="jQuery(this).removeClass(\'ui-datepicker-days-cell-over\')' + // unhighlight selection
1473
+ (highlightWeek ? '.parent().removeClass(\'ui-datepicker-week-over\')' : '') + ';' + // unhighlight selection week
1474
+ (!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#ui-datepicker-status-' +
1475
+ inst.id + '\').html(\'' + initStatus + '\');') + '" onclick="jQuery.datepicker._selectDay(\'#' +
1476
+ inst.id + '\',' + drawMonth + ',' + drawYear + ', this);"') + '>' + // actions
1477
+ (otherMonth ? (showOtherMonths ? printDate.getDate() : '&#xa0;') : // display for other months
1478
+ (unselectable ? printDate.getDate() : '<a>' + printDate.getDate() + '</a>')) + '</td>'; // display for this month
1479
+ tzDate.setDate(tzDate.getDate() + 1);
1480
+ utcDate.setUTCDate(utcDate.getUTCDate() + 1);
1481
+ printDate = (tzDate > utcDate ? tzDate : utcDate);
1482
+ }
1483
+ html += '</tr>';
1484
+ }
1485
+ drawMonth++;
1486
+ if (drawMonth > 11) {
1487
+ drawMonth = 0;
1488
+ drawYear++;
1489
+ }
1490
+ html += '</tbody></table></div>';
1491
+ }
1492
+ html += (showStatus ? '<div style="clear: both;"></div><div id="ui-datepicker-status-' + inst.id +
1493
+ '" class="ui-datepicker-status">' + initStatus + '</div>' : '') +
1494
+ (!closeAtTop && !inst.inline ? controls : '') +
1495
+ '<div style="clear: both;"></div>' +
1496
+ ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
1497
+ '<iframe src="javascript:false;" class="ui-datepicker-cover"></iframe>' : '');
1498
+ return html;
1499
+ },
1500
+
1501
+ /* Generate the month and year header. */
1502
+ _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
1503
+ selectedDate, secondary, showStatus, initStatus, monthNames) {
1504
+ minDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate);
1505
+ var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
1506
+ var html = '<div class="ui-datepicker-header">';
1507
+ var monthHtml = '';
1508
+ // month selection
1509
+ if (secondary || !this._get(inst, 'changeMonth'))
1510
+ monthHtml += monthNames[drawMonth] + '&#xa0;';
1511
+ else {
1512
+ var inMinYear = (minDate && minDate.getFullYear() == drawYear);
1513
+ var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
1514
+ monthHtml += '<select class="ui-datepicker-new-month" ' +
1515
+ 'onchange="jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
1516
+ 'onclick="jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
1517
+ this._addStatus(showStatus, inst.id, this._get(inst, 'monthStatus'), initStatus) + '>';
1518
+ for (var month = 0; month < 12; month++) {
1519
+ if ((!inMinYear || month >= minDate.getMonth()) &&
1520
+ (!inMaxYear || month <= maxDate.getMonth()))
1521
+ monthHtml += '<option value="' + month + '"' +
1522
+ (month == drawMonth ? ' selected="selected"' : '') +
1523
+ '>' + monthNames[month] + '</option>';
1524
+ }
1525
+ monthHtml += '</select>';
1526
+ }
1527
+ if (!showMonthAfterYear)
1528
+ html += monthHtml;
1529
+ // year selection
1530
+ if (secondary || !this._get(inst, 'changeYear'))
1531
+ html += drawYear;
1532
+ else {
1533
+ // determine range of years to display
1534
+ var years = this._get(inst, 'yearRange').split(':');
1535
+ var year = 0;
1536
+ var endYear = 0;
1537
+ if (years.length != 2) {
1538
+ year = drawYear - 10;
1539
+ endYear = drawYear + 10;
1540
+ } else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') {
1541
+ year = endYear = new Date().getFullYear();
1542
+ year += parseInt(years[0], 10);
1543
+ endYear += parseInt(years[1], 10);
1544
+ } else {
1545
+ year = parseInt(years[0], 10);
1546
+ endYear = parseInt(years[1], 10);
1547
+ }
1548
+ year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
1549
+ endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
1550
+ html += '<select class="ui-datepicker-new-year" ' +
1551
+ 'onchange="jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
1552
+ 'onclick="jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
1553
+ this._addStatus(showStatus, inst.id, this._get(inst, 'yearStatus'), initStatus) + '>';
1554
+ for (; year <= endYear; year++) {
1555
+ html += '<option value="' + year + '"' +
1556
+ (year == drawYear ? ' selected="selected"' : '') +
1557
+ '>' + year + '</option>';
1558
+ }
1559
+ html += '</select>';
1560
+ }
1561
+ if (showMonthAfterYear)
1562
+ html += monthHtml;
1563
+ html += '</div>'; // Close datepicker_header
1564
+ return html;
1565
+ },
1566
+
1567
+ /* Provide code to set and clear the status panel. */
1568
+ _addStatus: function(showStatus, id, text, initStatus) {
1569
+ return (showStatus ? ' onmouseover="jQuery(\'#ui-datepicker-status-' + id +
1570
+ '\').html(\'' + (text || initStatus) + '\');" ' +
1571
+ 'onmouseout="jQuery(\'#ui-datepicker-status-' + id +
1572
+ '\').html(\'' + initStatus + '\');"' : '');
1573
+ },
1574
+
1575
+ /* Adjust one of the date sub-fields. */
1576
+ _adjustInstDate: function(inst, offset, period) {
1577
+ var year = inst.drawYear + (period == 'Y' ? offset : 0);
1578
+ var month = inst.drawMonth + (period == 'M' ? offset : 0);
1579
+ var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
1580
+ (period == 'D' ? offset : 0);
1581
+ var date = new Date(year, month, day);
1582
+ // ensure it is within the bounds set
1583
+ var minDate = this._getMinMaxDate(inst, 'min', true);
1584
+ var maxDate = this._getMinMaxDate(inst, 'max');
1585
+ date = (minDate && date < minDate ? minDate : date);
1586
+ date = (maxDate && date > maxDate ? maxDate : date);
1587
+ inst.selectedDay = date.getDate();
1588
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
1589
+ inst.drawYear = inst.selectedYear = date.getFullYear();
1590
+ if (period == 'M' || period == 'Y')
1591
+ this._notifyChange(inst);
1592
+ },
1593
+
1594
+ /* Notify change of month/year. */
1595
+ _notifyChange: function(inst) {
1596
+ var onChange = this._get(inst, 'onChangeMonthYear');
1597
+ if (onChange)
1598
+ onChange.apply((inst.input ? inst.input[0] : null),
1599
+ [inst.selectedYear, inst.selectedMonth + 1, inst]);
1600
+ },
1601
+
1602
+ /* Determine the number of months to show. */
1603
+ _getNumberOfMonths: function(inst) {
1604
+ var numMonths = this._get(inst, 'numberOfMonths');
1605
+ return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
1606
+ },
1607
+
1608
+ /* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */
1609
+ _getMinMaxDate: function(inst, minMax, checkRange) {
1610
+ var date = this._determineDate(this._get(inst, minMax + 'Date'), null);
1611
+ if (date) {
1612
+ date.setHours(0);
1613
+ date.setMinutes(0);
1614
+ date.setSeconds(0);
1615
+ date.setMilliseconds(0);
1616
+ }
1617
+ return (!checkRange || !inst.rangeStart ? date :
1618
+ (!date || inst.rangeStart > date ? inst.rangeStart : date));
1619
+ },
1620
+
1621
+ /* Find the number of days in a given month. */
1622
+ _getDaysInMonth: function(year, month) {
1623
+ return 32 - new Date(year, month, 32).getDate();
1624
+ },
1625
+
1626
+ /* Find the day of the week of the first of a month. */
1627
+ _getFirstDayOfMonth: function(year, month) {
1628
+ return new Date(year, month, 1).getDay();
1629
+ },
1630
+
1631
+ /* Determines if we should allow a "next/prev" month display change. */
1632
+ _canAdjustMonth: function(inst, offset, curYear, curMonth) {
1633
+ var numMonths = this._getNumberOfMonths(inst);
1634
+ var date = new Date(curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1);
1635
+ if (offset < 0)
1636
+ date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
1637
+ return this._isInRange(inst, date);
1638
+ },
1639
+
1640
+ /* Is the given date in the accepted range? */
1641
+ _isInRange: function(inst, date) {
1642
+ // during range selection, use minimum of selected date and range start
1643
+ var newMinDate = (!inst.rangeStart ? null :
1644
+ new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay));
1645
+ newMinDate = (newMinDate && inst.rangeStart < newMinDate ? inst.rangeStart : newMinDate);
1646
+ var minDate = newMinDate || this._getMinMaxDate(inst, 'min');
1647
+ var maxDate = this._getMinMaxDate(inst, 'max');
1648
+ return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate));
1649
+ },
1650
+
1651
+ /* Provide the configuration settings for formatting/parsing. */
1652
+ _getFormatConfig: function(inst) {
1653
+ var shortYearCutoff = this._get(inst, 'shortYearCutoff');
1654
+ shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
1655
+ new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
1656
+ return {shortYearCutoff: shortYearCutoff,
1657
+ dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
1658
+ monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
1659
+ },
1660
+
1661
+ /* Format the given date for display. */
1662
+ _formatDate: function(inst, day, month, year) {
1663
+ if (!day) {
1664
+ inst.currentDay = inst.selectedDay;
1665
+ inst.currentMonth = inst.selectedMonth;
1666
+ inst.currentYear = inst.selectedYear;
1667
+ }
1668
+ var date = (day ? (typeof day == 'object' ? day : new Date(year, month, day)) :
1669
+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
1670
+ return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
1671
+ }
1672
+ });
1673
+
1674
+ /* jQuery extend now ignores nulls! */
1675
+ function extendRemove(target, props) {
1676
+ $.extend(target, props);
1677
+ for (var name in props)
1678
+ if (props[name] == null || props[name] == undefined)
1679
+ target[name] = props[name];
1680
+ return target;
1681
+ };
1682
+
1683
+ /* Determine whether an object is an array. */
1684
+ function isArray(a) {
1685
+ return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
1686
+ (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
1687
+ };
1688
+
1689
+ /* Invoke the datepicker functionality.
1690
+ @param options string - a command, optionally followed by additional parameters or
1691
+ Object - settings for attaching new datepicker functionality
1692
+ @return jQuery object */
1693
+ $.fn.datepicker = function(options){
1694
+
1695
+ /* Initialise the date picker. */
1696
+ if (!$.datepicker.initialized) {
1697
+ $(document.body).append($.datepicker.dpDiv).
1698
+ mousedown($.datepicker._checkExternalClick);
1699
+ $.datepicker.initialized = true;
1700
+ }
1701
+
1702
+ var otherArgs = Array.prototype.slice.call(arguments, 1);
1703
+ if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate'))
1704
+ return $.datepicker['_' + options + 'Datepicker'].
1705
+ apply($.datepicker, [this[0]].concat(otherArgs));
1706
+ return this.each(function() {
1707
+ typeof options == 'string' ?
1708
+ $.datepicker['_' + options + 'Datepicker'].
1709
+ apply($.datepicker, [this].concat(otherArgs)) :
1710
+ $.datepicker._attachDatepicker(this, options);
1711
+ });
1712
+ };
1713
+
1714
+ $.datepicker = new Datepicker(); // singleton instance
1715
+ $.datepicker.initialized = false;
1716
+ $.datepicker.uuid = new Date().getTime();
1717
+
1718
+ })(jQuery);
my-calendar-categories.php ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Function to handle the management of categories
3
+
4
+ function dirList() {
5
+ $directory = dirname(__FILE__).'/icons/';
6
+ // create an array to hold directory list
7
+ $results = array();
8
+ // create a handler for the directory
9
+ $handler = opendir($directory);
10
+ // keep going until all files in directory have been read
11
+ while ($file = readdir($handler)) {
12
+ // if $file isn't this directory or its parent,
13
+ // add it to the results array
14
+ if ($file != '.' && $file != '..')
15
+ $results[] = $file;
16
+ }
17
+ // tidy up: close the handler
18
+ closedir($handler);
19
+ // done!
20
+ sort($results,SORT_STRING);
21
+ return $results;
22
+ }
23
+
24
+
25
+ function manage_categories() {
26
+ global $wpdb;
27
+
28
+ // My Calendar must be installed and upgraded before this will work
29
+ check_calendar();
30
+
31
+ ?>
32
+ <div class="wrap">
33
+ <?php
34
+ // We do some checking to see what we're doing
35
+ if (isset($_POST['mode']) && $_POST['mode'] == 'add') {
36
+ $sql = "INSERT INTO " . MY_CALENDAR_CATEGORIES_TABLE . " SET category_name='".mysql_escape_string($_POST['category_name'])."', category_color='".mysql_escape_string($_POST['category_color'])."', category_icon='".mysql_escape_string($_POST['category_icon'])."'";
37
+ $wpdb->get_results($sql);
38
+ echo "<div class=\"updated\"><p><strong>".__('Category added successfully','my-calendar')."</strong></p></div>";
39
+ } else if (isset($_GET['mode']) && isset($_GET['category_id']) && $_GET['mode'] == 'delete') {
40
+ $sql = "DELETE FROM " . MY_CALENDAR_CATEGORIES_TABLE . " WHERE category_id=".mysql_escape_string($_GET['category_id']);
41
+ $wpdb->get_results($sql);
42
+ $sql = "UPDATE " . MY_CALENDAR_TABLE . " SET event_category=1 WHERE event_category=".mysql_escape_string($_GET['category_id']);
43
+ $wpdb->get_results($sql);
44
+ echo "<div class=\"updated\"><p><strong>".__('Category deleted successfully','my-calendar')."</strong></p></div>";
45
+ } else if (isset($_GET['mode']) && isset($_GET['category_id']) && $_GET['mode'] == 'edit' && !isset($_POST['mode'])) {
46
+ $sql = "SELECT * FROM " . MY_CALENDAR_CATEGORIES_TABLE . " WHERE category_id=".mysql_escape_string($_GET['category_id']);
47
+ $cur_cat = $wpdb->get_row($sql);
48
+ ?>
49
+ <h2><?php _e('Edit Category','my-calendar'); ?></h2>
50
+ <?php show_support_box(); ?>
51
+ <div id="poststuff" class="jd-my-calendar">
52
+ <div class="postbox">
53
+ <h3><?php _e('Category Editor','my-calendar'); ?></h3>
54
+ <div class="inside">
55
+ <form name="my-calendar" id="my-calendar" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?page=my-calendar-categories">
56
+ <div>
57
+ <input type="hidden" name="mode" value="edit" />
58
+ <input type="hidden" name="category_id" value="<?php echo $cur_cat->category_id ?>" />
59
+ </div>
60
+ <fieldset>
61
+ <legend><?php _e('Edit Category','my-calendar'); ?></legend>
62
+ <label for="category_name"><?php _e('Category Name','my-calendar'); ?>:</label> <input type="text" id="category_name" name="category_name" class="input" size="30" maxlength="30" value="<?php echo $cur_cat->category_name ?>" /><br />
63
+ <label for="category_color"><?php _e('Category Color (Hex format)','my-calendar'); ?>:</label> <input type="text" id="category_color" name="category_color" class="input" size="10" maxlength="7" value="<?php echo $cur_cat->category_color ?>" /><br />
64
+ <label for="category_icon"><?php _e('Category Icon','my-calendar'); ?>:</label> <select name="category_icon" id="category_icon">
65
+ <?php
66
+ $files = dirList();
67
+ foreach ($files as $value) {
68
+ if ($cur_cat->category_icon == $value) {
69
+ $selected = " selected='selected'";
70
+ } else {
71
+ $selected = "";
72
+ }
73
+ echo "<option value='$value'$selected style='background: url(".WP_PLUGIN_URL."/my-calendar/icons/$value) left 50% no-repeat;'>$value</option>";
74
+ }
75
+ ?>
76
+ </select>
77
+ </fieldset>
78
+ <p>
79
+ <input type="submit" name="save" class="button-primary" value="<?php _e('Save Changes','my-calendar'); ?> &raquo;" />
80
+ </p>
81
+ </form>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ <?php
86
+ } else if (isset($_POST['mode']) && isset($_POST['category_id']) && isset($_POST['category_name']) && isset($_POST['category_color']) && $_POST['mode'] == 'edit') {
87
+ $sql = "UPDATE " . MY_CALENDAR_CATEGORIES_TABLE . " SET category_name='".mysql_escape_string($_POST['category_name'])."', category_color='".mysql_escape_string($_POST['category_color'])."', category_icon='".mysql_escape_string($_POST['category_icon'])."' WHERE category_id=".mysql_escape_string($_POST['category_id']);
88
+ $wpdb->get_results($sql);
89
+ echo "<div class=\"updated\"><p><strong>".__('Category edited successfully','my-calendar')."</strong></p></div>";
90
+ }
91
+
92
+ if ($_GET['mode'] != 'edit' || $_POST['mode'] == 'edit') {
93
+ ?>
94
+
95
+ <h2><?php _e('Add Category','my-calendar'); ?></h2>
96
+ <?php show_support_box(); ?>
97
+ <div id="poststuff" class="jd-my-calendar">
98
+ <div class="postbox">
99
+ <h3><?php _e('Add New Category','my-calendar'); ?></h3>
100
+ <div class="inside">
101
+ <form name="my-calendar" id="my-calendar" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?page=my-calendar-categories">
102
+ <div>
103
+ <input type="hidden" name="mode" value="add" />
104
+ <input type="hidden" name="category_id" value="" />
105
+ </div>
106
+ <fieldset>
107
+ <legend><?php _e('Add Category'); ?></legend>
108
+ <label for="category_name"><?php _e('Category Name','my-calendar'); ?>:</label> <input type="text" id="category_name" name="category_name" class="input" size="30" maxlength="30" value="" /><br />
109
+ <label for="category_color"><?php _e('Category Color (Hex format)','my-calendar'); ?>:</label> <input type="text" id="category_color" name="category_color" class="input" size="10" maxlength="7" value="#" /><br />
110
+ <label for="category_icon"><?php _e('Category Icon','my-calendar'); ?>:</label> <select name="category_icon" id="category_icon">
111
+ <?php
112
+ $files = dirList();
113
+ foreach ($files as $value) {
114
+ echo "<option value='$value' style='background: url(".WP_PLUGIN_URL."/my-calendar/icons/$value) no-repeat;'>$value</option>";
115
+ }
116
+ ?>
117
+ </select>
118
+ </fieldset>
119
+ <p>
120
+ <input type="submit" name="save" class="button-primary" value="<?php _e('Add Category','my-calendar'); ?> &raquo;" />
121
+ </p>
122
+ </form>
123
+ </div>
124
+ </div>
125
+ </div>
126
+ <h2><?php _e('Manage Categories','my-calendar'); ?></h2>
127
+ <?php
128
+
129
+ // We pull the categories from the database
130
+ $categories = $wpdb->get_results("SELECT * FROM " . MY_CALENDAR_CATEGORIES_TABLE . " ORDER BY category_id ASC");
131
+
132
+ if ( !empty($categories) )
133
+ {
134
+ ?>
135
+ <table class="widefat page fixed" id="my-calendar-category-listing" summary="Manage Categories Listing">
136
+ <thead>
137
+ <tr>
138
+ <th class="manage-column" scope="col"><?php _e('ID','my-calendar') ?></th>
139
+ <th class="manage-column" scope="col"><?php _e('Category Name','my-calendar') ?></th>
140
+ <th class="manage-column" scope="col"><?php _e('Category Color','my-calendar') ?></th>
141
+ <th class="manage-column" scope="col"><?php _e('Category Icon','my-calendar'); ?></th>
142
+ <th class="manage-column" scope="col"><?php _e('Edit','my-calendar') ?></th>
143
+ <th class="manage-column" scope="col"><?php _e('Delete','my-calendar') ?></th>
144
+ </tr>
145
+ </thead>
146
+ <?php
147
+ $class = '';
148
+ foreach ( $categories as $category ) {
149
+ $class = ($class == 'alternate') ? '' : 'alternate';
150
+ ?>
151
+ <tr class="<?php echo $class; ?>">
152
+ <th scope="row"><?php echo $category->category_id; ?></th>
153
+ <td><?php echo $category->category_name; ?></td>
154
+ <td style="background-color:<?php echo $category->category_color; ?>;">&nbsp;</td>
155
+ <td style="background-color:<?php echo $category->category_color; ?>;"><img src="<?php echo WP_PLUGIN_URL; ?>/my-calendar/icons/<?php echo $category->category_icon; ?>" alt="" /></td>
156
+ <td><a href="<?php echo $_SERVER['PHP_SELF'] ?>?page=my-calendar-categories&amp;mode=edit&amp;category_id=<?php echo $category->category_id;?>" class='edit'><?php echo __('Edit','my-calendar'); ?></a></td>
157
+ <?php
158
+ if ($category->category_id == 1) {
159
+ echo '<td>'.__('N/A','my-calendar').'</td>';
160
+ } else {
161
+ ?>
162
+ <td><a href="<?php echo $_SERVER['PHP_SELF'] ?>?page=my-calendar-categories&amp;mode=delete&amp;category_id=<?php echo $category->category_id;?>" class="delete" onclick="return confirm('<?php echo __('Are you sure you want to delete this category?','my-calendar'); ?>')"><?php echo __('Delete','my-calendar'); ?></a></td>
163
+ <?php
164
+ }
165
+ ?>
166
+ </tr>
167
+ <?php
168
+ }
169
+ ?>
170
+ </table>
171
+ <?php
172
+ } else {
173
+ echo '<p>'.__('There are no categories in the database - something has gone wrong!','my-calendar').'</p>';
174
+ }
175
+ ?>
176
+ </div>
177
+
178
+ <?php
179
+ }
180
+ ?>
181
+ </div>
182
+ <?php
183
+ }
184
+ ?>
my-calendar-event-manager.php ADDED
@@ -0,0 +1,653 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // The actual function called to render the manage events page and
3
+ // to deal with posts
4
+ function edit_calendar() {
5
+ global $current_user, $wpdb, $users_entries;
6
+ ?>
7
+
8
+ <?php
9
+ // First some quick cleaning up
10
+ $edit = $create = $save = $delete = false;
11
+
12
+ $action = !empty($_POST['action']) ? $_POST['action'] : '';
13
+ $event_id = !empty($_POST['event_id']) ? $_POST['event_id'] : '';
14
+
15
+ if ($_GET['action'] == 'edit') {
16
+ $action = "edit";
17
+ $event_id = (int) $_GET['event_id'];
18
+ }
19
+
20
+ // Lets see if this is first run and create us a table if it is!
21
+ check_calendar();
22
+
23
+ if ($_GET['action'] == 'delete') {
24
+ $sql = "SELECT event_title FROM " . MY_CALENDAR_TABLE . " WHERE event_id=" . (int) $_GET['event_id'];
25
+ $result = $wpdb->get_results($sql);
26
+ ?>
27
+ <div class="error">
28
+ <p><strong><?php _e('Delete Event','my-calendar'); ?>:</strong> <?php _e('Are you sure you want to delete this event?','my-calendar'); ?></p>
29
+ <form action="<?php echo $_SERVER['PHP_SELF']; ?>?page=my-calendar" method="post">
30
+ <div>
31
+ <input type="hidden" value="delete" name="action" />
32
+ <input type="hidden" value="<?php echo (int) $_GET['event_id']; ?>" name="event_id" />
33
+ <input type="submit" name="submit" class="button-primary" value="<?php _e('Delete','my-calendar'); echo " &quot;".$result[0]->event_title."&quot;"; ?>" />
34
+ </div>
35
+ </form>
36
+ </div>
37
+ <?php
38
+ }
39
+
40
+ // Deal with adding an event to the database
41
+ if ( $action == 'add' ) {
42
+ $title = !empty($_POST['event_title']) ? $_POST['event_title'] : '';
43
+ $desc = !empty($_POST['event_desc']) ? $_POST['event_desc'] : '';
44
+ $begin = !empty($_POST['event_begin']) ? $_POST['event_begin'] : '';
45
+ $end = !empty($_POST['event_end']) ? $_POST['event_end'] : $begin;
46
+ $time = !empty($_POST['event_time']) ? $_POST['event_time'] : '';
47
+ $recur = !empty($_POST['event_recur']) ? $_POST['event_recur'] : '';
48
+ $repeats = !empty($_POST['event_repeats']) ? $_POST['event_repeats'] : '';
49
+ $category = !empty($_POST['event_category']) ? $_POST['event_category'] : '';
50
+ $linky = !empty($_POST['event_link']) ? $_POST['event_link'] : '';
51
+ $event_label = !empty($_POST['event_label']) ? $_POST['event_label'] : '';
52
+ $event_street = !empty($_POST['event_street']) ? $_POST['event_street'] : '';
53
+ $event_street2 = !empty($_POST['event_street2']) ? $_POST['event_street2'] : '';
54
+ $event_city = !empty($_POST['event_city']) ? $_POST['event_city'] : '';
55
+ $event_state = !empty($_POST['event_state']) ? $_POST['event_state'] : '';
56
+ $event_postcode = !empty($_POST['event_postcode']) ? $_POST['event_postcode'] : '';
57
+ $event_country = !empty($_POST['event_country']) ? $_POST['event_country'] : '';
58
+
59
+ // Deal with the fools who have left magic quotes turned on
60
+ if ( ini_get('magic_quotes_gpc') ) {
61
+ $title = stripslashes($title);
62
+ $desc = stripslashes($desc);
63
+ $begin = stripslashes($begin);
64
+ $end = stripslashes($end);
65
+ $time = stripslashes($time);
66
+ $recur = stripslashes($recur);
67
+ $repeats = stripslashes($repeats);
68
+ $category = stripslashes($category);
69
+ $linky = stripslashes($linky);
70
+ $event_label = stripslashes($event_label);
71
+ $event_street = stripslashes($event_street);
72
+ $event_street2 = stripslashes($event_street2);
73
+ $event_city = stripslashes($event_city);
74
+ $event_state = stripslashes($event_state);
75
+ $event_postcode = stripslashes($event_postcode);
76
+ $event_country = stripslashes($event_country);
77
+ }
78
+
79
+ // Perform some validation on the submitted dates - this checks for valid years and months
80
+ $date_format_one = '/^([0-9]{4})-([0][1-9])-([0-3][0-9])$/';
81
+ $date_format_two = '/^([0-9]{4})-([1][0-2])-([0-3][0-9])$/';
82
+ if ((preg_match($date_format_one,$begin) || preg_match($date_format_two,$begin)) && (preg_match($date_format_one,$end) || preg_match($date_format_two,$end))) {
83
+ // We know we have a valid year and month and valid integers for days so now we do a final check on the date
84
+ $begin_split = split('-',$begin);
85
+ $begin_y = $begin_split[0];
86
+ $begin_m = $begin_split[1];
87
+ $begin_d = $begin_split[2];
88
+ $end_split = split('-',$end);
89
+ $end_y = $end_split[0];
90
+ $end_m = $end_split[1];
91
+ $end_d = $end_split[2];
92
+ if (checkdate($begin_m,$begin_d,$begin_y) && checkdate($end_m,$end_d,$end_y)) {
93
+ // Ok, now we know we have valid dates, we want to make sure that they are either equal or that the end date is later than the start date
94
+ if (strtotime($end) >= strtotime($begin)) {
95
+ $start_date_ok = 1;
96
+ $end_date_ok = 1;
97
+ } else {
98
+ ?>
99
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('Your event end date must be either after or the same as your event begin date','my-calendar'); ?></p></div>
100
+ <?php
101
+ }
102
+ } else {
103
+ ?>
104
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('Your date formatting is correct but one or more of your dates is invalid. Check for number of days in month and leap year related errors.','my-calendar'); ?></p></div>
105
+ <?php
106
+ }
107
+ } else {
108
+ ?>
109
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('Both start and end dates must be entered and be in the format YYYY-MM-DD','my-calendar'); ?></p></div>
110
+ <?php
111
+ }
112
+ // We check for a valid time, or an empty one
113
+ $time_format_one = '/^([0-1][0-9]):([0-5][0-9])$/';
114
+ $time_format_two = '/^([2][0-3]):([0-5][0-9])$/';
115
+ if (preg_match($time_format_one,$time) || preg_match($time_format_two,$time) || $time == '') {
116
+ $time_ok = 1;
117
+ } else {
118
+ ?>
119
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('The time field must either be blank or be entered in the format hh:mm','my-calendar'); ?></p></div>
120
+ <?php
121
+ }
122
+ // We check to make sure the URL is alright
123
+ if (preg_match('/^(http)(s?)(:)\/\//',$linky) || $linky == '') {
124
+ $url_ok = 1;
125
+ } else {
126
+ ?>
127
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('The URL entered must either be prefixed with http:// or be completely blank','my-calendar'); ?></p></div>
128
+ <?php
129
+ }
130
+ // The title must be at least one character in length and no more than 60 - only basic punctuation is allowed
131
+ if (preg_match('/^[a-zA-Z0-9\'\"]{1}[a-zA-Z0-9[:space:][.,;:()\'\"]{0,60}$/',$title)) {
132
+ $title_ok =1;
133
+ } else {
134
+ ?>
135
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('The event title must be between 1 and 60 characters in length. Some punctuation characters may not be allowed.','my-calendar'); ?></p></div>
136
+ <?php
137
+ }
138
+ // We run some checks on recurrance
139
+ if (($repeats == 0 && $recur == 'S') || (($repeats >= 0) && ($recur == 'W' || $recur == 'M' || $recur == 'Y' || $recur == 'D'))) {
140
+ $recurring_ok = 1;
141
+ } else {
142
+ ?>
143
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('The repetition value must be 0 unless a type of recurrance is selected in which case the repetition value must be 0 or higher','my-calendar'); ?></p></div>
144
+ <?php
145
+ }
146
+ if ($start_date_ok == 1 && $end_date_ok == 1 && $time_ok == 1 && $url_ok == 1 && $title_ok == 1 && $recurring_ok == 1) {
147
+ $sql = "INSERT INTO " . MY_CALENDAR_TABLE . " SET
148
+ event_title='" . mysql_escape_string($title) . "',
149
+ event_desc='" . mysql_escape_string($desc) . "',
150
+ event_begin='" . mysql_escape_string($begin) . "',
151
+ event_end='" . mysql_escape_string($end) . "',
152
+ event_time='" . mysql_escape_string($time) . "',
153
+ event_recur='" . mysql_escape_string($recur) . "',
154
+ event_repeats='" . mysql_escape_string($repeats) . "',
155
+ event_author=".$current_user->ID.",
156
+ event_category=".mysql_escape_string($category).",
157
+ event_link='".mysql_escape_string($linky)."',
158
+ event_label='".mysql_escape_string($event_label)."',
159
+ event_street='".mysql_escape_string($event_street)."',
160
+ event_street2='".mysql_escape_string($event_street2)."',
161
+ event_city='".mysql_escape_string($event_city)."',
162
+ event_state='".mysql_escape_string($event_state)."',
163
+ event_postcode='".mysql_escape_string($event_postcode)."',
164
+ event_country='".mysql_escape_string($event_country)."'";
165
+
166
+ $wpdb->get_results($sql);
167
+
168
+ $sql = "SELECT event_id FROM " . MY_CALENDAR_TABLE . " WHERE event_title='" . mysql_escape_string($title) . "'"
169
+ . " AND event_desc='" . mysql_escape_string($desc) . "' AND event_begin='" . mysql_escape_string($begin) . "' AND event_end='" . mysql_escape_string($end) . "' AND event_recur='" . mysql_escape_string($recur) . "' AND event_repeats='" . mysql_escape_string($repeats) . "' LIMIT 1";
170
+ $result = $wpdb->get_results($sql);
171
+
172
+ if ( empty($result) || empty($result[0]->event_id) ) {
173
+ ?>
174
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('An event with the details you submitted could not be found in the database. This may indicate a problem with your database or the way in which it is configured.','my-calendar'); ?></p></div>
175
+ <?php
176
+ } else {
177
+ ?>
178
+ <div class="updated"><p><?php _e('Event added. It will now show in your calendar.','my-calendar'); ?></p></div>
179
+ <?php
180
+ }
181
+ } else {
182
+ // The form is going to be rejected due to field validation issues, so we preserve the users entries here
183
+ $users_entries->event_title = $title;
184
+ $users_entries->event_desc = $desc;
185
+ $users_entries->event_begin = $begin;
186
+ $users_entries->event_end = $end;
187
+ $users_entries->event_time = $time;
188
+ $users_entries->event_recur = $recur;
189
+ $users_entries->event_repeats = $repeats;
190
+ $users_entries->event_category = $category;
191
+ $users_entries->event_link = $linky;
192
+ $users_entries->event_label = $event_label;
193
+ $users_entries->event_street = $event_street;
194
+ $users_entries->event_street2 = $event_street2;
195
+ $users_entries->event_city = $event_city;
196
+ $users_entries->event_state = $event_state;
197
+ $users_entries->event_postcode = $event_postcode;
198
+ $users_entries->event_country = $event_country;
199
+ }
200
+ // Permit saving of events that have been edited
201
+ } elseif ( $action == 'edit_save' ) {
202
+ $title = !empty($_POST['event_title']) ? $_POST['event_title'] : '';
203
+ $desc = !empty($_POST['event_desc']) ? $_POST['event_desc'] : '';
204
+ $begin = !empty($_POST['event_begin']) ? $_POST['event_begin'] : '';
205
+ $end = !empty($_POST['event_end']) ? $_POST['event_end'] : $begin;
206
+ $time = !empty($_POST['event_time']) ? $_POST['event_time'] : '';
207
+ $recur = !empty($_POST['event_recur']) ? $_POST['event_recur'] : '';
208
+ $repeats = !empty($_POST['event_repeats']) ? $_POST['event_repeats'] : '';
209
+ $category = !empty($_POST['event_category']) ? $_POST['event_category'] : '';
210
+ $linky = !empty($_POST['event_link']) ? $_POST['event_link'] : '';
211
+ $event_label = !empty($_POST['event_label']) ? $_POST['event_label'] : '';
212
+ $event_street = !empty($_POST['event_street']) ? $_POST['event_street'] : '';
213
+ $event_street2 = !empty($_POST['event_street2']) ? $_POST['event_street2'] : '';
214
+ $event_city = !empty($_POST['event_city']) ? $_POST['event_city'] : '';
215
+ $event_state = !empty($_POST['event_state']) ? $_POST['event_state'] : '';
216
+ $event_postcode = !empty($_POST['event_postcode']) ? $_POST['event_postcode'] : '';
217
+ $event_country = !empty($_POST['event_country']) ? $_POST['event_country'] : '';
218
+
219
+
220
+ // Deal with the fools who have left magic quotes turned on
221
+ if ( ini_get('magic_quotes_gpc') ) {
222
+ $title = stripslashes($title);
223
+ $desc = stripslashes($desc);
224
+ $begin = stripslashes($begin);
225
+ $end = stripslashes($end);
226
+ $time = stripslashes($time);
227
+ $recur = stripslashes($recur);
228
+ $repeats = stripslashes($repeats);
229
+ $category = stripslashes($category);
230
+ $linky = stripslashes($linky);
231
+ $event_label = stripslashes($event_label);
232
+ $event_street = stripslashes($event_street);
233
+ $event_street2 = stripslashes($event_street2);
234
+ $event_city = stripslashes($event_city);
235
+ $event_state = stripslashes($event_state);
236
+ $event_postcode = stripslashes($event_postcode);
237
+ $event_country = stripslashes($event_country);
238
+ }
239
+
240
+ if ( empty($event_id) ) {
241
+ ?>
242
+ <div class="error"><p><strong><?php _e('Failure','my-calendar'); ?>:</strong> <?php _e("You can't update an event if you haven't submitted an event id",'my-calendar'); ?></p></div>
243
+ <?php
244
+ } else {
245
+ // Perform some validation on the submitted dates - this checks for valid years and months
246
+ $date_format_one = '/^([0-9]{4})-([0][1-9])-([0-3][0-9])$/';
247
+ $date_format_two = '/^([0-9]{4})-([1][0-2])-([0-3][0-9])$/';
248
+ if ((preg_match($date_format_one,$begin) || preg_match($date_format_two,$begin)) && (preg_match($date_format_one,$end) || preg_match($date_format_two,$end))) {
249
+ // We know we have a valid year and month and valid integers for days so now we do a final check on the date
250
+ $begin_split = split('-',$begin);
251
+ $begin_y = $begin_split[0];
252
+ $begin_m = $begin_split[1];
253
+ $begin_d = $begin_split[2];
254
+ $end_split = split('-',$end);
255
+ $end_y = $end_split[0];
256
+ $end_m = $end_split[1];
257
+ $end_d = $end_split[2];
258
+ if (checkdate($begin_m,$begin_d,$begin_y) && checkdate($end_m,$end_d,$end_y)) {
259
+ // Ok, now we know we have valid dates, we want to make sure that they are either equal or that the end date is later than the start date
260
+ if (strtotime($end) >= strtotime($begin)) {
261
+ $start_date_ok = 1;
262
+ $end_date_ok = 1;
263
+ } else {
264
+ ?>
265
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('Your event end date must be either after or the same as your event begin date','my-calendar'); ?></p></div>
266
+ <?php
267
+ }
268
+ } else {
269
+ ?>
270
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('Your date formatting is correct but one or more of your dates is invalid. Check for number of days in month and leap year related errors.','my-calendar'); ?></p></div>
271
+ <?php
272
+ }
273
+ } else {
274
+ ?>
275
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('Both start and end dates must be entered and be in the format YYYY-MM-DD','my-calendar'); ?></p></div>
276
+ <?php
277
+ }
278
+ // We check for a valid time, or an empty one
279
+ $time_format_one = '/^([0-1][0-9]):([0-5][0-9])$/';
280
+ $time_format_two = '/^([2][0-3]):([0-5][0-9])$/';
281
+ if (preg_match($time_format_one,$time) || preg_match($time_format_two,$time) || $time == '') {
282
+ $time_ok = 1;
283
+ } else {
284
+ ?>
285
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('The time field must either be blank or be entered in the format hh:mm','my-calendar'); ?></p></div>
286
+ <?php
287
+ }
288
+ // We check to make sure the URL is alright
289
+ if (preg_match('/^(http)(s?)(:)\/\//',$linky) || $linky == '') {
290
+ $url_ok = 1;
291
+ } else {
292
+ ?>
293
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('The URL entered must either be prefixed with http:// or be completely blank','my-calendar'); ?></p></div>
294
+ <?php
295
+ }
296
+ // The title must be at least one character in length and no more than 60 - no non-standard characters allowed
297
+ if (preg_match('/^[a-zA-Z0-9\'\"]{1}[a-zA-Z0-9[:space:][.,;:()\'\"]{0,60}$/',$title)) {
298
+ $title_ok =1;
299
+ } else {
300
+ ?>
301
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('The event title must be between 1 and 60 characters in length. Some punctuation characters may not be allowed.','my-calendar'); ?></p></div>
302
+ <?php
303
+ }
304
+ // We run some checks on recurrance
305
+ if (($repeats == 0 && $recur == 'S') || (($repeats >= 0) && ($recur == 'W' || $recur == 'M' || $recur == 'Y' || $recur == 'D' ))) {
306
+ $recurring_ok = 1;
307
+ } else {
308
+ ?>
309
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('The repetition value must be 0 unless a type of recurrance is selected in which case the repetition value must be 0 or higher','my-calendar'); ?></p></div>
310
+ <?php
311
+ }
312
+ if ($start_date_ok == 1 && $end_date_ok == 1 && $time_ok == 1 && $url_ok == 1 && $title_ok && $recurring_ok == 1) {
313
+ $sql = "UPDATE " . MY_CALENDAR_TABLE . " SET
314
+ event_title='" . mysql_escape_string($title) . "',
315
+ event_desc='" . mysql_escape_string($desc) . "',
316
+ event_begin='" . mysql_escape_string($begin) . "',
317
+ event_end='" . mysql_escape_string($end) . "',
318
+ event_time='" . mysql_escape_string($time) . "',
319
+ event_recur='" . mysql_escape_string($recur) . "',
320
+ event_repeats='" . mysql_escape_string($repeats) . "',
321
+ event_author=".$current_user->ID . ",
322
+ event_category=".mysql_escape_string($category).",
323
+ event_link='".mysql_escape_string($linky)."',
324
+ event_label='".mysql_escape_string($event_label)."',
325
+ event_street='".mysql_escape_string($event_street)."',
326
+ event_street2='".mysql_escape_string($event_street2)."',
327
+ event_city='".mysql_escape_string($event_city)."',
328
+ event_state='".mysql_escape_string($event_state)."',
329
+ event_postcode='".mysql_escape_string($event_postcode)."',
330
+ event_country='".mysql_escape_string($event_country)."'
331
+ WHERE event_id='" . mysql_escape_string($event_id) . "'";
332
+
333
+ $wpdb->get_results($sql);
334
+
335
+ $sql = "SELECT event_id FROM " . MY_CALENDAR_TABLE . " WHERE event_title='" . mysql_escape_string($title) . "'"
336
+ . " AND event_desc='" . mysql_escape_string($desc) . "' AND event_begin='" . mysql_escape_string($begin) . "' AND event_end='" . mysql_escape_string($end) . "' AND event_recur='" . mysql_escape_string($recur) . "' AND event_repeats='" . mysql_escape_string($repeats) . "' LIMIT 1";
337
+ $result = $wpdb->get_results($sql);
338
+
339
+ if ( empty($result) || empty($result[0]->event_id) ) {
340
+ ?>
341
+ <div class="error"><p><strong><?php _e('Failure','my-calendar'); ?>:</strong> <?php _e('The database failed to return data to indicate the event has been updated sucessfully. This may indicate a problem with your database or the way in which it is configured.','my-calendar'); ?></p></div>
342
+ <?php
343
+ } else {
344
+ ?>
345
+ <div class="updated"><p><?php _e('Event updated successfully','my-calendar'); ?></p></div>
346
+ <?php
347
+ }
348
+ } else {
349
+ // The form is going to be rejected due to field validation issues, so we preserve the users entries here
350
+ $users_entries->event_title = $title;
351
+ $users_entries->event_desc = $desc;
352
+ $users_entries->event_begin = $begin;
353
+ $users_entries->event_end = $end;
354
+ $users_entries->event_time = $time;
355
+ $users_entries->event_recur = $recur;
356
+ $users_entries->event_repeats = $repeats;
357
+ $users_entries->event_category = $category;
358
+ $users_entries->event_link = $linky;
359
+ $users_entries->event_label = $event_label;
360
+ $users_entries->event_street = $event_street;
361
+ $users_entries->event_street2 = $event_street2;
362
+ $users_entries->event_city = $event_city;
363
+ $users_entries->event_state = $event_state;
364
+ $users_entries->event_postcode = $event_postcode;
365
+ $users_entries->event_country = $event_country;
366
+ $error_with_saving = 1;
367
+ }
368
+ }
369
+ } elseif ( $action == 'delete' ) {
370
+ // Deal with deleting an event from the database
371
+
372
+ if ( empty($event_id) ) {
373
+ ?>
374
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e("You can't delete an event if you haven't submitted an event id",'my-calendar'); ?></p></div>
375
+ <?php
376
+ } else {
377
+ $sql = "DELETE FROM " . MY_CALENDAR_TABLE . " WHERE event_id='" . mysql_escape_string($event_id) . "'";
378
+ $wpdb->get_results($sql);
379
+
380
+ $sql = "SELECT event_id FROM " . MY_CALENDAR_TABLE . " WHERE event_id='" . mysql_escape_string($event_id) . "'";
381
+ $result = $wpdb->get_results($sql);
382
+
383
+ if ( empty($result) || empty($result[0]->event_id) ) {
384
+ ?>
385
+ <div class="updated"><p><?php _e('Event deleted successfully','my-calendar'); ?></p></div>
386
+ <?php
387
+ } else {
388
+ ?>
389
+ <div class="error"><p><strong><?php _e('Error','my-calendar'); ?>:</strong> <?php _e('Despite issuing a request to delete, the event still remains in the database. Please investigate.','my-calendar'); ?></p></div>
390
+ <?php
391
+
392
+ }
393
+ }
394
+ }
395
+
396
+ // Now follows a little bit of code that pulls in the main
397
+ // components of this page; the edit form and the list of events
398
+ ?>
399
+
400
+ <div class="wrap">
401
+ <?php
402
+ if ( $action == 'edit' || ($action == 'edit_save' && $error_with_saving == 1)) {
403
+ ?>
404
+ <h2><?php _e('Edit Event','my-calendar'); ?></h2>
405
+ <?php show_support_box(); ?>
406
+ <?php
407
+ if ( empty($event_id) ) {
408
+ echo "<div class=\"error\"><p>".__("You must provide an event id in order to edit it",'my-calendar')."</p></div>";
409
+ } else {
410
+ wp_events_edit_form('edit_save', $event_id);
411
+ }
412
+ } else {
413
+ ?>
414
+ <h2><?php _e('Add Event','my-calendar'); ?></h2>
415
+ <?php show_support_box(); ?>
416
+
417
+ <?php wp_events_edit_form(); ?>
418
+
419
+ <h2><?php _e('Manage Events','my-calendar'); ?></h2>
420
+
421
+ <?php wp_events_display_list();
422
+ }
423
+ ?>
424
+ </div>
425
+
426
+ <?php
427
+ }
428
+
429
+ // The event edit form for the manage events admin page
430
+ function wp_events_edit_form($mode='add', $event_id=false) {
431
+ global $wpdb,$users_entries;
432
+ $data = false;
433
+
434
+ if ( $event_id !== false ) {
435
+ if ( intval($event_id) != $event_id ) {
436
+ echo "<div class=\"error\"><p>".__('Sorry! That\'s an invalid event key.','my-calendar')."</p></div>";
437
+ return;
438
+ } else {
439
+ $data = $wpdb->get_results("SELECT * FROM " . MY_CALENDAR_TABLE . " WHERE event_id='" . mysql_escape_string($event_id) . "' LIMIT 1");
440
+ if ( empty($data) ) {
441
+ echo "<div class=\"error\"><p>".__("Sorry! We couldn't find an event with that ID.",'my-calendar')."</p></div>";
442
+ return;
443
+ }
444
+ $data = $data[0];
445
+ }
446
+ // Recover users entries if they exist; in other words if editing an event went wrong
447
+ if (!empty($users_entries)) {
448
+ $data = $users_entries;
449
+ }
450
+ } else {
451
+ // Deal with possibility that form was submitted but not saved due to error - recover user's entries here
452
+ $data = $users_entries;
453
+ }
454
+
455
+ ?>
456
+ <div id="poststuff" class="jd-my-calendar">
457
+ <div class="postbox">
458
+ <h3><?php if ($mode == "add") { _e('Add an Event','my-calendar'); } else { _e('Edit Event'); } ?></h3>
459
+ <div class="inside">
460
+ <form name="my-calendar" id="my-calendar" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?page=my-calendar">
461
+ <div>
462
+ <input type="hidden" name="action" value="<?php echo $mode; ?>" />
463
+ <input type="hidden" name="event_id" value="<?php echo $event_id; ?>" />
464
+ </div>
465
+ <fieldset>
466
+ <legend><?php _e('Enter your Event Information','my-calendar'); ?></legend>
467
+ <p>
468
+ <label for="event_title"><?php _e('Event Title','my-calendar'); ?></label> <input type="text" id="event_title" name="event_title" class="input" size="40" maxlength="60" value="<?php if ( !empty($data) ) echo htmlspecialchars($data->event_title); ?>" />
469
+ </p>
470
+ <p>
471
+ <label for="event_desc"><?php _e('Event Description (<abbr title="hypertext markup language">HTML</abbr> allowed)','my-calendar'); ?></label><br /><textarea id="event_desc" name="event_desc" class="input" rows="5" cols="50"><?php if ( !empty($data) ) echo htmlspecialchars($data->event_desc); ?></textarea>
472
+ </p>
473
+ <p>
474
+ <label for="event_category"><?php _e('Event Category','my-calendar'); ?></label>
475
+ <select id="event_category" name="event_category">
476
+ <?php
477
+ // Grab all the categories and list them
478
+ $sql = "SELECT * FROM " . MY_CALENDAR_CATEGORIES_TABLE;
479
+ $cats = $wpdb->get_results($sql);
480
+ foreach($cats as $cat) {
481
+ echo '<option value="'.$cat->category_id.'"';
482
+ if (!empty($data)) {
483
+ if ($data->event_category == $cat->category_id){
484
+ echo 'selected="selected"';
485
+ }
486
+ }
487
+ echo '>'.$cat->category_name.'</option>';
488
+ }
489
+ ?>
490
+ </select>
491
+ </p>
492
+ <p>
493
+ <label for="event_link"><?php _e('Event Link (Optional)','my-calendar'); ?></label> <input type="text" id="event_link" name="event_link" class="input" size="40" value="<?php if ( !empty($data) ) echo htmlspecialchars($data->event_link); ?>" />
494
+ </p>
495
+ <p>
496
+ <label for="event_begin"><?php _e('Start Date (YYYY-MM-DD)','my-calendar'); ?></label> <input type="text" id="event_begin" name="event_begin" class="calendar_input" size="12" value="<?php if ( !empty($data) ) { echo htmlspecialchars($data->event_begin);} else {echo date("Y-m-d");} ?>" />
497
+ </p>
498
+ <p>
499
+ <label for="event_end"><?php _e('End Date (YYYY-MM-DD) (Optional)','calendar'); ?></label> <input type="text" name="event_end" id="event_end" class="calendar_input" size="12" value="<?php if ( !empty($data) ) {echo htmlspecialchars($data->event_end);} ?>" />
500
+ </p>
501
+ <p>
502
+ <label for="event_time"><?php _e('Time (hh:mm)','calendar'); ?></label> <input type="text" id="event_time" name="event_time" class="input" size="12"
503
+ value="<?php
504
+ if ( !empty($data) ) {
505
+ if ($data->event_time == "00:00:00") {
506
+ echo '';
507
+ } else {
508
+ echo date("H:i",strtotime(htmlspecialchars($data->event_time)));
509
+ }
510
+ } else {
511
+ echo date("H:i",strtotime(current_time('mysql')));
512
+ }
513
+ ?>" /> <?php _e('Optional, set blank if your event is an all-day event or does not happen at a specific time.','my-calendar'); ?> <?php _e('Current time difference from GMT is ','my-calendar'); echo get_option('gmt_offset'); _e(' hour(s)', 'my-calendar'); ?>
514
+ </p>
515
+ </fieldset>
516
+ <fieldset>
517
+ <legend><?php _e('Recurring Events','my-calendar'); ?></legend> <?php
518
+ if ($data->event_repeats != NULL) {
519
+ $repeats = $data->event_repeats;
520
+ } else {
521
+ $repeats = 0;
522
+ }
523
+ if ($data->event_recur == "S") {
524
+ $selected_s = 'selected="selected"';
525
+ } else if ($data->event_recur == "D") {
526
+ $selected_d = 'selected="selected"';
527
+ } else if ($data->event_recur == "W") {
528
+ $selected_w = 'selected="selected"';
529
+ } else if ($data->event_recur == "M") {
530
+ $selected_m = 'selected="selected"';
531
+ } else if ($data->event_recur == "Y") {
532
+ $selected_y = 'selected="selected"';
533
+ }
534
+ ?>
535
+ <p>
536
+ <label for="event_repeats"><?php _e('Repeats for','my-calendar'); ?></label> <input type="text" name="event_repeats" id="event_repeats" class="input" size="1" value="<?php echo $repeats; ?>" />
537
+ <label for="event_recur"><?php _e('Units','my-calendar'); ?></label> <select name="event_recur" class="input" id="event_recur">
538
+ <option class="input" <?php echo $selected_s; ?> value="S">Does not recur</option>
539
+ <option class="input" <?php echo $selected_d; ?> value="D">Days</option>
540
+ <option class="input" <?php echo $selected_w; ?> value="W">Weeks</option>
541
+ <option class="input" <?php echo $selected_m; ?> value="M">Months</option>
542
+ <option class="input" <?php echo $selected_y; ?> value="Y">Years</option>
543
+ </select><br />
544
+ <?php _e('Entering 0 means forever, if a unit is selected. If the recurrance unit is left at "Does not recur," the event will not reoccur.','my-calendar'); ?>
545
+ </p>
546
+ </fieldset>
547
+ <?php if ( get_option( 'my_calendar_show_address' ) == 'true' || get_option( 'my_calendar_show_map' ) == 'true' ) { ?>
548
+ <fieldset>
549
+ <legend>Event Location</legend>
550
+ <p>
551
+ <?php _e('All location fields are optional: <em>insufficient information may result in an inaccurate map</em>.','my-calendar'); ?>
552
+ </p>
553
+ <p>
554
+ <label for="event_label"><?php _e('Name of Location (e.g. <em>Joe\'s Bar and Grill</em>)','my-calendar'); ?></label> <input type="text" id="event_label" name="event_label" class="input" size="40" value="<?php if ( !empty($data) ) echo htmlspecialchars($data->event_label); ?>" />
555
+ </p>
556
+ <p>
557
+ <label for="event_street"><?php _e('Street Address','my-calendar'); ?></label> <input type="text" id="event_street" name="event_street" class="input" size="40" value="<?php if ( !empty($data) ) echo htmlspecialchars($data->event_street); ?>" />
558
+ </p>
559
+ <p>
560
+ <label for="event_street2"><?php _e('Street Address (2)','my-calendar'); ?></label> <input type="text" id="event_street2" name="event_street2" class="input" size="40" value="<?php if ( !empty($data) ) echo htmlspecialchars($data->event_street2); ?>" />
561
+ </p>
562
+ <p>
563
+ <label for="event_city"><?php _e('City','my-calendar'); ?></label> <input type="text" id="event_city" name="event_city" class="input" size="40" value="<?php if ( !empty($data) ) echo htmlspecialchars($data->event_city); ?>" /> <label for="event_state"><?php _e('State/Province','my-calendar'); ?></label> <input type="text" id="event_state" name="event_state" class="input" size="10" value="<?php if ( !empty($data) ) echo htmlspecialchars($data->event_state); ?>" /> <label for="event_postcode"><?php _e('Postal Code','my-calendar'); ?></label> <input type="text" id="event_postcode" name="event_postcode" class="input" size="10" value="<?php if ( !empty($data) ) echo htmlspecialchars($data->event_postcode); ?>" />
564
+ </p>
565
+ <p>
566
+ <label for="event_country"><?php _e('Country','my-calendar'); ?></label> <input type="text" id="event_country" name="event_country" class="input" size="10" value="<?php if ( !empty($data) ) echo htmlspecialchars($data->event_country); ?>" />
567
+ </p>
568
+ </fieldset>
569
+ <?php } ?>
570
+ <p>
571
+ <input type="submit" name="save" class="button-primary" value="<?php _e('Save Event','my-calendar'); ?> &raquo;" />
572
+ </p>
573
+ <div id="datepicker1">
574
+ </div>
575
+ </form>
576
+ </div>
577
+ </div>
578
+ </div>
579
+ <?php
580
+ }
581
+ // Used on the manage events admin page to display a list of events
582
+ function wp_events_display_list() {
583
+ global $wpdb;
584
+
585
+ $events = $wpdb->get_results("SELECT * FROM " . MY_CALENDAR_TABLE . " ORDER BY event_begin DESC");
586
+
587
+ if ( !empty($events) ) {
588
+ ?>
589
+ <table class="widefat page fixed" id="my-calendar-admin-table" summary="Table of Calendar Events">
590
+ <thead>
591
+ <tr>
592
+ <th class="manage-column n4" scope="col"><?php _e('ID','my-calendar') ?></th>
593
+ <th class="manage-column" scope="col"><?php _e('Title','my-calendar') ?></th>
594
+ <th class="manage-column n8" scope="col"><?php _e('Description','my-calendar') ?></th>
595
+ <th class="manage-column" scope="col"><?php _e('Start Date','my-calendar') ?></th>
596
+ <?php /* <th class="manage-column" scope="col"><?php _e('End Date','my-calendar') ?></th> */ ?>
597
+ <th class="manage-column n6" scope="col"><?php _e('Recurs','my-calendar') ?></th>
598
+ <th class="manage-column n6" scope="col"><?php _e('Repeats','my-calendar') ?></th>
599
+ <th class="manage-column" scope="col"><?php _e('Author','my-calendar') ?></th>
600
+ <th class="manage-column" scope="col"><?php _e('Category','my-calendar') ?></th>
601
+ <th class="manage-column n7" scope="col"><?php _e('Edit / Delete','my-calendar') ?></th>
602
+ </tr>
603
+ </thead>
604
+ <?php
605
+ $class = '';
606
+ foreach ( $events as $event ) {
607
+ $class = ($class == 'alternate') ? '' : 'alternate';
608
+ ?>
609
+ <tr class="<?php echo $class; ?>">
610
+ <th scope="row"><?php echo $event->event_id; ?></th>
611
+ <td><?php echo $event->event_title; ?></td>
612
+ <td><?php echo $event->event_desc; ?></td>
613
+ <td><?php echo $event->event_begin; ?></td>
614
+ <?php /* <td><?php echo $event->event_end; ?></td> */ ?>
615
+ <td>
616
+ <?php
617
+ // Interpret the DB values into something human readable
618
+ if ($event->event_recur == 'S') { _e('Never','my-calendar'); }
619
+ else if ($event->event_recur == 'D') { _e('Daily','my-calendar'); }
620
+ else if ($event->event_recur == 'W') { _e('Weekly','my-calendar'); }
621
+ else if ($event->event_recur == 'M') { _e('Monthly','my-calendar'); }
622
+ else if ($event->event_recur == 'Y') { _e('Yearly','my-calendar'); }
623
+ ?>
624
+ </td>
625
+ <td>
626
+ <?php
627
+ // Interpret the DB values into something human readable
628
+ if ($event->event_recur == 'S') { echo __('N/A','my-calendar'); }
629
+ else if ($event->event_repeats == 0) { echo __('Forever','my-calendar'); }
630
+ else if ($event->event_repeats > 0) { echo $event->event_repeats.' '.__('Times','my-calendar'); }
631
+ ?>
632
+ </td>
633
+ <td><?php $e = get_userdata($event->event_author); echo $e->display_name; ?></td>
634
+ <?php
635
+ $sql = "SELECT * FROM " . MY_CALENDAR_CATEGORIES_TABLE . " WHERE category_id=".$event->event_category;
636
+ $this_cat = $wpdb->get_row($sql);
637
+ ?>
638
+ <td style="background-color:<?php echo $this_cat->category_color;?>;"><?php echo $this_cat->category_name; ?></td>
639
+ <?php unset($this_cat); ?>
640
+ <td><a href="<?php echo $_SERVER['PHP_SELF'] ?>?page=my-calendar&amp;action=edit&amp;event_id=<?php echo $event->event_id;?>" class='edit'><?php echo __('Edit','my-calendar'); ?></a> &middot; <a href="<?php echo $_SERVER['PHP_SELF'] ?>?page=my-calendar&amp;action=delete&amp;event_id=<?php echo $event->event_id;?>" class="delete"><?php echo __('Delete','my-calendar'); ?></a></td> </tr>
641
+ <?php
642
+ }
643
+ ?>
644
+ </table>
645
+ <?php
646
+ } else {
647
+ ?>
648
+ <p><?php _e("There are no events in the database!",'my-calendar') ?></p>
649
+ <?php
650
+ }
651
+ }
652
+
653
+ ?>
my-calendar-help.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function my_calendar_help() {
3
+
4
+ ?>
5
+ <div class="wrap">
6
+ <h2><?php _e('How to use My Calendar','my-calendar'); ?></h2>
7
+ <?php show_support_box(); ?>
8
+
9
+ <div id="poststuff" class="jd-my-calendar">
10
+ <div class="postbox">
11
+ <h3><?php _e('Shortcode Syntax','my-calendar'); ?></h3>
12
+ <div class="inside">
13
+
14
+ <ul>
15
+ <li><code>[my_calendar]</code><br />
16
+ <?php _e('This basic shortcode will show the calendar on a post or page including all categories and the category key, in a traditional month-by-month format.','my-calendar'); ?>
17
+ </li>
18
+ <li><code>[my_calendar category="General" format="list" showkey="no"]</code><br />
19
+ <?php _e('The shortcode supports three attributes, <code>category</code>, <code>format</code> and <code>showkey</code>. There is currently only one alternate option for <code>format</code> &mdash; <code>list</code> &mdash; which will show the calendar in a list format, skipping dates without any events. The <code>category</code> attribute requires either the name of or ID number one of your event categories (the name is case-sensitive). This will show a calendar only including events in that category. Setting <code>showkey</code> to <code>no</code> will prevent the category key from being displayed &mdash; this can be useful with single-category output.','my-calendar'); ?>
20
+ </li>
21
+ </ul>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ <div id="poststuff" class="jd-my-calendar">
26
+ <div class="postbox">
27
+ <h3><?php _e('Category Icons','my-calendar'); ?></h3>
28
+ <div class="inside">
29
+ <p>
30
+ <?php _e('My Calendar is designed to manage multiple calendars. The basis for these calendars are categories; you can easily setup a calendar page which includes all categories, or you can dedicate separate pages to calendars in each category. For an example, this might be useful for you in managing the tour calendars for multiple bands; event calendars for a variety of locations, etc.','my-calendar'); ?>
31
+ </p>
32
+ <p>
33
+ <?php _e('The pre-installed category icons may not be especially useful for your needs or design. I\'m assuming that you\'re going to upload your own icons -- all you need to do is upload them to the plugin\'s icons folder, and they\'ll be available for immediate use.','my-calendar'); ?> <?php _e('Your icons folder is:','my-calendar'); ?> <code><?php echo WP_PLUGIN_DIR; ?>/my-calendar/icons/</code>
34
+ </p>
35
+ </div>
36
+ </div>
37
+ </div>
38
+
39
+ <div id="poststuff" class="jd-my-calendar">
40
+ <div class="postbox">
41
+ <h3 id="template"><?php _e('Widget Templating','my-calendar'); ?></h3>
42
+ <div class="inside">
43
+ <p>
44
+ <?php _e('These codes are available in calendar widgets to create your own custom calendar format.'); ?>
45
+ </p>
46
+ <dl>
47
+ <dt><code>{category}</code></dt>
48
+ <dd><?php _e('Displays the name of the category the event is in.','my-calendar'); ?></dd>
49
+
50
+ <dt><code>{title}</code></dt>
51
+ <dd><?php _e('Displays the title of the event.','my-calendar'); ?></dd>
52
+
53
+ <dt><code>{time}</code></dt>
54
+ <dd><?php _e('Displays the start time for the event.','my-calendar'); ?></dd>
55
+
56
+ <dt><code>{date}</code></dt>
57
+ <dd><?php _e('Displays the date on which the event begins.','my-calendar'); ?></dd>
58
+
59
+ <dt><code>{author}</code></dt>
60
+ <dd><?php _e('Displays the WordPress author who posted the event.','my-calendar'); ?></dd>
61
+
62
+ <dt><code>{link}</code></dt>
63
+ <dd><?php _e('Displays the URL provided for the event.','my-calendar'); ?></dd>
64
+
65
+ <dt><code>{description}</code></dt>
66
+ <dd><?php _e('Displays the description of the event.','my-calendar'); ?></dd>
67
+
68
+ <dt><code>{link_title}</code></dt>
69
+ <dd><?php _e('Displays title of the event as a link if a URL is present, or the title alone if no URL is available.','my-calendar'); ?></dd>
70
+
71
+ <dt><code>{location}</code></dt>
72
+ <dd><?php _e('Displays the name of the location of the event.','my-calendar'); ?></dd>
73
+
74
+ <dt><code>{street}</code></dt>
75
+ <dd><?php _e('Displays the first line of the site address.','my-calendar'); ?></dd>
76
+
77
+ <dt><code>{street2}</code></dt>
78
+ <dd><?php _e('Displays the second line of the site address.','my-calendar'); ?></dd>
79
+
80
+ <dt><code>{city}</code></dt>
81
+ <dd><?php _e('Displays the city for the event.','my-calendar'); ?></dd>
82
+
83
+ <dt><code>{state}</code></dt>
84
+ <dd><?php _e('Displays the state for the event.','my-calendar'); ?></dd>
85
+
86
+ <dt><code>{postcode}</code></dt>
87
+ <dd><?php _e('Displays the postcode for the event.','my-calendar'); ?></dd>
88
+
89
+ <dt><code>{country}</code></dt>
90
+ <dd><?php _e('Displays the country for the event location.','my-calendar'); ?></dd>
91
+
92
+ <dt><code>{hcard}</code></dt>
93
+ <dd><?php _e('Displays the event address in <a href="http://microformats.org/wiki/hcard">hcard</a> format.','my-calendar'); ?></dd>
94
+
95
+ <dt><code>{link_map}</code></dt>
96
+ <dd><?php _e('Displays a link to a Google Map of the event, if sufficient address information is available. If not, will be empty.','my-calendar'); ?></dd>
97
+ </div>
98
+ </div>
99
+ </div>
100
+ </div>
101
+ <?php } ?>
my-calendar-settings.php ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Display the admin configuration page
3
+ function edit_my_calendar_config() {
4
+ global $wpdb, $initial_style;
5
+
6
+ // We can't use this page unless My Calendar is installed/upgraded
7
+ check_calendar();
8
+
9
+ if (isset($_POST['permissions']) && isset($_POST['style'])) {
10
+ if ($_POST['permissions'] == 'subscriber') { $new_perms = 'read'; }
11
+ else if ($_POST['permissions'] == 'contributor') { $new_perms = 'edit_posts'; }
12
+ else if ($_POST['permissions'] == 'author') { $new_perms = 'publish_posts'; }
13
+ else if ($_POST['permissions'] == 'editor') { $new_perms = 'moderate_comments'; }
14
+ else if ($_POST['permissions'] == 'admin') { $new_perms = 'manage_options'; }
15
+ else { $new_perms = 'manage_options'; }
16
+
17
+ $my_calendar_style = $_POST['style'];
18
+ $my_calendar_show_months = (int) $_POST['my_calendar_show_months'];
19
+ $my_calendar_date_format = $_POST['my_calendar_date_format'];
20
+
21
+ if (mysql_escape_string($_POST['display_author']) == 'on') {
22
+ $disp_author = 'true';
23
+ } else {
24
+ $disp_author = 'false';
25
+ }
26
+
27
+ if (mysql_escape_string($_POST['display_jump']) == 'on') {
28
+ $disp_jump = 'true';
29
+ } else {
30
+ $disp_jump = 'false';
31
+ }
32
+
33
+ if (mysql_escape_string($_POST['use_styles']) == 'on') {
34
+ $use_styles = 'true';
35
+ } else {
36
+ $use_styles = 'false';
37
+ }
38
+
39
+ if (mysql_escape_string($_POST['my_calendar_show_map']) == 'on') {
40
+ $my_calendar_show_map = 'true';
41
+ } else {
42
+ $my_calendar_show_map = 'false';
43
+ }
44
+
45
+ if (mysql_escape_string($_POST['my_calendar_show_address']) == 'on') {
46
+ $my_calendar_show_address = 'true';
47
+ } else {
48
+ $my_calendar_show_address = 'false';
49
+ }
50
+
51
+ update_option('can_manage_events',$new_perms);
52
+ update_option('my_calendar_style',$my_calendar_style);
53
+ update_option('display_author',$disp_author);
54
+ update_option('display_jump',$disp_jump);
55
+ update_option('my_calendar_use_styles',$use_styles);
56
+ update_option('my_calendar_show_months',$my_calendar_show_months);
57
+ update_option('my_calendar_date_format',$my_calendar_date_format);
58
+ update_option('my_calendar_show_map',$my_calendar_show_map);
59
+ update_option('my_calendar_show_address',$my_calendar_show_address);
60
+ update_option('calendar_javascript', (int) $_POST['calendar_javascript']);
61
+ update_option('list_javascript', (int) $_POST['list_javascript']);
62
+ // Check to see if we are replacing the original style
63
+
64
+ if (mysql_escape_string($_POST['reset_styles']) == 'on') {
65
+ update_option('my_calendar_style',$initial_style);
66
+ }
67
+ echo "<div class=\"updated\"><p><strong>".__('Settings saved','my-calendar').".</strong></p></div>";
68
+ }
69
+
70
+ // Pull the values out of the database that we need for the form
71
+ $allowed_group = get_option('can_manage_events');
72
+ $my_calendar_style = stripcslashes(get_option('my_calendar_style'));
73
+ $my_calendar_use_styles = get_option('my_calendar_use_styles');
74
+ $my_calendar_show_months = get_option('my_calendar_show_months');
75
+ $my_calendar_show_map = get_option('my_calendar_show_map');
76
+ $my_calendar_show_address = get_option('my_calendar_show_address');
77
+ $disp_author = get_option('display_author');
78
+ $calendar_javascript = get_option('calendar_javascript');
79
+ $list_javascript = get_option('list_javascript');
80
+ // checkbox
81
+ $disp_jump = get_option('display_jump');
82
+ //checkbox
83
+
84
+ if ($allowed_group == 'read') { $subscriber_selected='selected="selected"';}
85
+ else if ($allowed_group == 'edit_posts') { $contributor_selected='selected="selected"';}
86
+ else if ($allowed_group == 'publish_posts') { $author_selected='selected="selected"';}
87
+ else if ($allowed_group == 'moderate_comments') { $editor_selected='selected="selected"';}
88
+ else if ($allowed_group == 'manage_options') { $admin_selected='selected="selected"';}
89
+
90
+ // Now we render the form
91
+ ?>
92
+ <div class="wrap">
93
+
94
+ <h2><?php _e('My Calendar Options','my-calendar'); ?></h2>
95
+ <?php show_support_box(); ?>
96
+ <div id="poststuff" class="jd-my-calendar">
97
+ <div class="postbox">
98
+ <h3><?php _e('Calendar Settings','my-calendar'); ?></h3>
99
+ <div class="inside">
100
+ <form name="my-calendar" id="my-calendar" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?page=my-calendar-config">
101
+ <fieldset>
102
+ <legend><?php _e('Primary Calendar Options','my-calendar'); ?></legend>
103
+ <p>
104
+ <label for="permissions"><?php _e('Choose the lowest user group that may manage events','my-calendar'); ?></label> <select id="permissions" name="permissions">
105
+ <option value="subscriber"<?php echo $subscriber_selected ?>><?php _e('Subscriber','my-calendar')?></option>
106
+ <option value="contributor" <?php echo $contributor_selected ?>><?php _e('Contributor','my-calendar')?></option>
107
+ <option value="author" <?php echo $author_selected ?>><?php _e('Author','my-calendar')?></option>
108
+ <option value="editor" <?php echo $editor_selected ?>><?php _e('Editor','my-calendar')?></option>
109
+ <option value="admin" <?php echo $admin_selected ?>><?php _e('Administrator','my-calendar')?></option>
110
+ </select>
111
+ </p>
112
+ <p>
113
+ <label for="display_author"><?php _e('Do you want to display the author name on events?','my-calendar'); ?></label> <select id="display_author" name="display_author">
114
+ <option value="on" <?php jd_cal_checkSelect('display_author','true'); ?>><?php _e('Yes','my-calendar') ?></option>
115
+ <option value="off" <?php jd_cal_checkSelect('display_author','false'); ?>><?php _e('No','my-calendar') ?></option>
116
+ </select>
117
+ </p>
118
+ <p>
119
+ <label for="display_jump"><?php _e('Display a jumpbox for changing month and year quickly?','my-calendar'); ?></label> <select id="display_jump" name="display_jump">
120
+ <option value="on" <?php jd_cal_checkSelect('display_jump','true'); ?>><?php _e('Yes','my-calendar') ?></option>
121
+ <option value="off" <?php jd_cal_checkSelect('display_jump','false'); ?>><?php _e('No','my-calendar') ?></option>
122
+ </select>
123
+ </p>
124
+ <p>
125
+ <label for="my_calendar_show_months"><?php _e('In list mode, show how many months of events at a time:','my-calendar'); ?></label> <input type="text" size="3" id="my_calendar_show_months" name="my_calendar_show_months" value="<?php echo $my_calendar_show_months; ?>" />
126
+ </p>
127
+ <p>
128
+ <label for="my_calendar_date_format"><?php _e('Date format in list mode','my-calendar'); ?></label> <input type="text" id="my_calendar_date_format" name="my_calendar_date_format" value="<?php if ( get_option('my_calendar_date_format') == "") { echo get_option('date_format'); } else { echo get_option( 'my_calendar_date_format'); } ?>" /> Current: <?php if ( get_option('my_calendar_date_format') == '') { echo date(get_option('date_format')); } else { echo date(get_option('my_calendar_date_format')); } ?><br />
129
+ <small><?php _e('Date format uses the same syntax as the <a href="http://php.net/date">PHP <code>date()</code> function</a>. Save option to update sample output.','my-calendar'); ?></small>
130
+ </p>
131
+ <p>
132
+ <input type="checkbox" id="my_calendar_show_map" name="my_calendar_show_map" <?php jd_cal_checkCheckbox('my_calendar_show_map','true'); ?> /> <label for="my_calendar_show_map"><?php _e('Show Link to Google Map (when sufficient address information is available.)','my-calendar'); ?></label><br />
133
+ <input type="checkbox" id="my_calendar_show_address" name="my_calendar_show_address" <?php jd_cal_checkCheckbox('my_calendar_show_address','true'); ?> /> <label for="my_calendar_show_address"><?php _e('Show Event Address in Details','my-calendar'); ?></label>
134
+ </p>
135
+ </fieldset>
136
+ <fieldset>
137
+ <legend><?php _e('Calendar Styles','my-calendar'); ?></legend>
138
+ <p>
139
+ <input type="checkbox" id="reset_styles" name="reset_styles" /> <label for="reset_styles"><?php _e('Reset the My Calendar style to default','my-calendar'); ?></label><br />
140
+ <input type="checkbox" id="use_styles" name="use_styles" <?php jd_cal_checkCheckbox('my_calendar_use_styles','true'); ?> /> <label for="use_styles"><?php _e('Disable My Calendar Stylesheet','my-calendar'); ?></label>
141
+ </p>
142
+ <p>
143
+ <label for="style"><?php _e('Edit the stylesheet for My Calendar','my-calendar'); ?></label><br /><textarea id="style" name="style" rows="10" cols="60" tabindex="2"><?php echo $my_calendar_style; ?></textarea>
144
+ </p>
145
+ </fieldset>
146
+ <fieldset>
147
+ <legend><?php _e('Calendar Behaviors','my-calendar'); ?></legend>
148
+ <p>
149
+ <input type="checkbox" id="list_javascript" name="list_javascript" value="1" <?php jd_cal_checkCheckbox('list_javascript',1); ?> /> <label for="list_javascript"><?php _e('Disable List Javascript Effects','my-calendar'); ?></label><br />
150
+ <input type="checkbox" id="calendar_javascript" name="calendar_javascript" value="1" <?php jd_cal_checkCheckbox('calendar_javascript',1); ?>/> <label for="calendar_javascript"><?php _e('Disable Calendar Javascript Effects','my-calendar'); ?></label>
151
+ </p>
152
+ <p>
153
+ <input type="submit" name="save" class="button-primary" value="<?php _e('Save','my-calendar'); ?> &raquo;" />
154
+ </p>
155
+ </form>
156
+ </div>
157
+ </div>
158
+ </div>
159
+ </div>
160
+ <?php
161
+
162
+
163
+ }
164
+ ?>
my-calendar-widgets.php ADDED
@@ -0,0 +1,330 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // The widget to show todays events in the sidebar
3
+ function init_my_calendar_today() {
4
+ // Check for required functions
5
+ if (!function_exists('register_sidebar_widget')) {
6
+ return;
7
+ }
8
+ function my_calendar_today($args) {
9
+ extract($args);
10
+ $the_title = get_option('my_calendar_today_title');
11
+ $widget_title = empty($the_title) ? __('Today\'s Events','my-calendar') : $the_title;
12
+ $the_events = todays_events();
13
+ if ($the_events != '') {
14
+ echo $before_widget;
15
+ echo $before_title . $widget_title . $after_title;
16
+ echo $the_events;
17
+ echo $after_widget;
18
+ }
19
+ }
20
+
21
+ function my_calendar_today_control() {
22
+ $widget_title = get_option('my_calendar_today_title');
23
+ $widget_template = get_option('my_calendar_today_template');
24
+ if (isset($_POST['my_calendar_today_title'])) {
25
+ update_option('my_calendar_today_title',strip_tags($_POST['my_calendar_today_title']));
26
+ }
27
+ if (isset($_POST['my_calendar_today_template'])) {
28
+ update_option('my_calendar_today_template',$_POST['my_calendar_today_template']);
29
+ }
30
+ ?>
31
+ <p>
32
+ <label for="my_calendar_today_title"><?php _e('Title','my-calendar'); ?>:</label><br />
33
+ <input class="widefat" type="text" id="my_calendar_today_title" name="my_calendar_today_title" value="<?php echo $widget_title; ?>"/>
34
+ </p>
35
+ <p>
36
+ <label for="my_calendar_today_template"><?php _e('Template','my-calendar'); ?></label><br />
37
+ <textarea class="widefat" rows="8" cols="20" id="my_calendar_today_template" name="my_calendar_today_template"><?php echo stripcslashes($widget_template); ?></textarea>
38
+ </p>
39
+ <?php
40
+ }
41
+
42
+ register_sidebar_widget(__('Today\'s Events','my-calendar'),'my_calendar_today');
43
+ register_widget_control(__('Today\'s Events','my-calendar'),'my_calendar_today_control');
44
+ }
45
+
46
+ // replace upcoming_events_widget with my_calendar
47
+ // The widget to show todays events in the sidebar
48
+ function init_my_calendar_upcoming() {
49
+ // Check for required functions
50
+ if (!function_exists('register_sidebar_widget'))
51
+ return;
52
+
53
+ function my_calendar_upcoming($args) {
54
+ extract($args);
55
+ $the_title = get_option('my_calendar_upcoming_title');
56
+ $widget_title = empty($the_title) ? __('Upcoming Events','my-calendar') : $the_title;
57
+ $the_events = upcoming_events();
58
+ if ($the_events != '') {
59
+ echo $before_widget;
60
+ echo $before_title . $widget_title . $after_title;
61
+ echo $the_events;
62
+ echo $after_widget;
63
+ }
64
+ }
65
+
66
+ function my_calendar_upcoming_control() {
67
+ $widget_title = get_option('my_calendar_upcoming_title');
68
+ $widget_template = get_option('my_calendar_upcoming_template');
69
+ $upcoming_days = get_option('display_upcoming_days');
70
+ $past_days = get_option('display_past_days');
71
+ $upcoming_events = get_option('display_upcoming_events');
72
+ $past_events = get_option('display_past_events');
73
+
74
+ if (isset($_POST['my_calendar_upcoming_title'])) {
75
+ update_option('my_calendar_upcoming_title',strip_tags($_POST['my_calendar_upcoming_title']));
76
+ }
77
+ if (isset($_POST['my_calendar_upcoming_template'])) {
78
+ update_option('my_calendar_upcoming_template',$_POST['my_calendar_upcoming_template']);
79
+ }
80
+
81
+ if (isset($_POST['display_upcoming_type'])) {
82
+ $display_upcoming_type = $_POST['display_upcoming_type'];
83
+ update_option('display_upcoming_type',$display_upcoming_type);
84
+ }
85
+
86
+ if (isset($_POST['display_upcoming_days'])) {
87
+ $display_upcoming_days = (int) $_POST['display_upcoming_days'];
88
+ update_option('display_upcoming_days',$display_upcoming_days);
89
+ }
90
+
91
+ if (isset($_POST['display_upcoming_events'])) {
92
+ $display_upcoming_events = (int) $_POST['display_upcoming_events'];
93
+ update_option('display_upcoming_events',$display_upcoming_events);
94
+ }
95
+
96
+ if (isset($_POST['display_past_events'])) {
97
+ $display_past_events = (int) $_POST['display_past_events'];
98
+ update_option('display_past_events',$display_past_events);
99
+ }
100
+
101
+ if (isset($_POST['display_past_days'])) {
102
+ $display_past_days = (int) $_POST['display_past_days'];
103
+ update_option('display_past_days',$display_past_days);
104
+ }
105
+ // add options for days/events
106
+ ?>
107
+ <p>
108
+ <label for="my_calendar_upcoming_title"><?php _e('Title','my-calendar'); ?>:</label><br />
109
+ <input class="widefat" type="text" id="my_calendar_upcoming_title" name="my_calendar_upcoming_title" value="<?php echo $widget_title; ?>"/>
110
+ </p>
111
+ <p>
112
+ <label for="my_calendar_upcoming_template"><?php _e('Template','my-calendar'); ?></label><br />
113
+ <textarea class="widefat" rows="8" cols="20" id="my_calendar_upcoming_template" name="my_calendar_upcoming_template"><?php echo stripcslashes($widget_template); ?></textarea>
114
+ </p>
115
+ <fieldset>
116
+ <legend><?php _e('Widget Options','my-calendar'); ?></legend>
117
+ <p>
118
+ <label for="display_upcoming_type"><?php _e('Display upcoming events by:','my-calendar'); ?></label> <select id="display_upcoming_type" name="display_upcoming_type">
119
+ <option value="events" <?php jd_cal_checkSelect('display_upcoming_type','events'); ?>><?php _e('Events (e.g. 2 past, 3 future)','my-calendar') ?></option>
120
+ <option value="days" <?php jd_cal_checkSelect('display_upcoming_type','days'); ?>><?php _e('Dates (e.g. 4 days past, 5 forward)','my-calendar') ?></option>
121
+ </select>
122
+ </p>
123
+ <p>
124
+ <input type="text" id="display_upcoming_events" name="display_upcoming_events" value="<?php echo $upcoming_events ?>" size="1" maxlength="2" /> <label for="display_upcoming_events"><?php _e('events into the future;','my-calendar'); ?></label><br />
125
+ <input type="text" id="display_past_events" name="display_past_events" value="<?php echo $past_events ?>" size="1" maxlength="2" /> <label for="display_past_events"><?php _e('events from the past','my-calendar'); ?></label>
126
+ </p>
127
+ <p>
128
+ <input type="text" id="display_upcoming_days" name="display_upcoming_days" value="<?php echo $upcoming_days ?>" size="1" maxlength="2" /> <label for="display_upcoming_days"><?php _e('days into the future;','my-calendar'); ?></label><br />
129
+ <input type="text" id="display_past_days" name="display_past_days" value="<?php echo $past_days ?>" size="1" maxlength="2" /> <label for="display_past_days"><?php _e('days from the past','my-calendar'); ?></label>
130
+ </p>
131
+ </fieldset>
132
+ <?php
133
+ }
134
+
135
+ register_sidebar_widget(__('Upcoming Events','my-calendar'),'my_calendar_upcoming');
136
+ register_widget_control(__('Upcoming Events','my-calendar'),'my_calendar_upcoming_control');
137
+ }
138
+
139
+
140
+ // Widget upcoming events
141
+ function upcoming_events() {
142
+ global $wpdb;
143
+
144
+ // This function cannot be called unless calendar is up to date
145
+ check_calendar();
146
+ $template = get_option('my_calendar_upcoming_template');
147
+ $display_upcoming_type = get_option('display_upcoming_type');
148
+
149
+
150
+ // Get number of days we should go into the future
151
+ $future_days = get_option('display_upcoming_days');
152
+ // Get number of days we should go into the past
153
+ $past_days = get_option('display_past_days');
154
+ $future_events = get_option('display_past_events');
155
+ $past_events = get_option('display_upcoming_events');
156
+
157
+ $day_count = -($past_days);
158
+ $output = "<ul>";
159
+
160
+ if ($display_upcoming_type == "date") {
161
+ while ($day_count < $future_days+1) {
162
+ list($y,$m,$d) = split("-",date("Y-m-d",mktime($day_count*24,0,0,date("m"),date("d"),date("Y"))));
163
+ $events = grab_events( $y,$m,$d );
164
+
165
+ usort($events, "time_cmp");
166
+ foreach($events as $event) {
167
+ $event_details = event_as_array($event);
168
+ $output .= "<li>".draw_widget_event($event_details,$template)."</li>";
169
+ }
170
+ $day_count = $day_count+1;
171
+ }
172
+ } else {
173
+ $events = get_all_events( ); // grab all events WITHIN reasonable proximity
174
+ usort($events, "timediff_cmp");// sort all events by proximity to current date
175
+ for ($i=0;$i<=($past_events+$future_events);$i++) {
176
+ if ($events[$i]) {
177
+ $near_events[] = $events[$i]; // split off a number of events equal to the past + future settings
178
+ }
179
+ }
180
+
181
+ $events = $near_events;
182
+ usort($events, "datetime_cmp"); // sort split events by date
183
+
184
+ foreach($events as $event) {
185
+ $event_details = event_as_array($event);
186
+ $today = date('Y').'-'.date('m').'-'.date('d');
187
+ $date = date('Y-m-d',strtotime($event_details['date']));
188
+ if (date_comp($date,$today)===true) {
189
+ $class = "past-event";
190
+ } else {
191
+ $class = "future-event";
192
+ }
193
+ if (date_equal($date,$today)) {
194
+ $class = "today";
195
+ }
196
+ $output .= "<li class=\"$class\">".draw_widget_event($event_details,$template)."</li>\n";
197
+ }
198
+ $day_count = $day_count+1;
199
+ }
200
+
201
+ if ($output != '') {
202
+ $output .= "</ul>";
203
+ return $output;
204
+ }
205
+ }
206
+
207
+ // Widget todays events
208
+ function todays_events() {
209
+ global $wpdb;
210
+
211
+ // This function cannot be called unless calendar is up to date
212
+ check_calendar();
213
+
214
+ $template = get_option('my_calendar_today_template');
215
+
216
+ $events = grab_events(date("Y"),date("m"),date("d"));
217
+ if (count($events) != 0) {
218
+ $output = "<ul>";
219
+ }
220
+ usort($events, "time_cmp");
221
+ foreach($events as $event) {
222
+ $event_details = event_as_array($event);
223
+
224
+ if (get_option('my_calendar_date_format') != '') {
225
+ $date = date(get_option('my_calendar_date_format'),time());
226
+ } else {
227
+ $date = date(get_option('date_format'),time());
228
+ }
229
+ // correct displayed time to today
230
+ $event_details['date'] = $date;
231
+ $output .= "<li>".draw_widget_event($event_details,$template)."</li>";
232
+ }
233
+ if (count($events) != 0) {
234
+ $output .= "</ul>";
235
+ return $output;
236
+ }
237
+ }
238
+
239
+ function draw_widget_event($array,$template) {
240
+ //1st argument: array of details
241
+ //2nd argument: template to print details into
242
+ foreach ($array as $key=>$value) {
243
+ $search = "{".$key."}";
244
+ $template = stripcslashes(str_replace($search,$value,$template));
245
+ }
246
+ return $template;
247
+ }
248
+
249
+ // Draw an event but customise the HTML for use in the widget
250
+ function event_as_array($event) {
251
+ global $wpdb;
252
+ // My Calendar must be updated to run this function
253
+ check_calendar();
254
+
255
+ $sql = "SELECT category_name FROM " . MY_CALENDAR_CATEGORIES_TABLE . " WHERE category_id=".$event->event_category;
256
+ $category_name = $wpdb->get_row($sql);
257
+ $e = get_userdata($event->event_author);
258
+
259
+ $hcard = "<div class=\"address vcard\">";
260
+ $hcard .= "<div class=\"adr\">";
261
+ if ($event->event_label != "") {
262
+ $hcard .= "<strong class=\"org\">".$event->event_label."</strong><br />";
263
+ }
264
+ if ($event->event_street != "") {
265
+ $hcard .= "<div class=\"street-address\">".$event->event_street."</div>";
266
+ }
267
+ if ($event->event_street2 != "") {
268
+ $hcard .= "<div class=\"street-address\">".$event->event_street2."</div>";
269
+ }
270
+ if ($event->event_city != "") {
271
+ $hcard .= "<span class=\"locality\">".$event->event_city.",</span>";
272
+ }
273
+ if ($event->event_state != "") {
274
+ $hcard .= "<span class=\"region\">".$event->event_state."</span> ";
275
+ }
276
+ if ($event->event_postcode != "") {
277
+ $hcard .= " <span class=\"postal-code\">".$event->event_postcode."</span>";
278
+ }
279
+ if ($event->event_country != "") {
280
+ $hcard .= "<div class=\"country-name\">".$event->event_country."</div>";
281
+ }
282
+ $hcard .= "</div>\n</div>";
283
+
284
+ $map_string = $event->event_street.' '.$event->event_street2.' '.$event->event_city.' '.$event->event_state.' '.$event->event_postcode.' '.$event->event_country;
285
+ if (strlen($map_string) > 10) {
286
+ $map_string = str_replace(" ","+",$map_string);
287
+ if ($event->event_label != "") {
288
+ $map_label = $event->event_label;
289
+ } else {
290
+ $map_label = $event->event_title;
291
+ }
292
+ $map = "<a href=\"http://maps.google.com/maps?f=q&z=15&q=$map_string\">Map<span> to $map_label</span></a>";
293
+ } else {
294
+ $map = "";
295
+ }
296
+
297
+ if (get_option('my_calendar_date_format') != '') {
298
+ $date = date(get_option('my_calendar_date_format'),strtotime($event->event_begin));
299
+ } else {
300
+ $date = date(get_option('date_format'),strtotime($event->event_begin));
301
+ }
302
+
303
+ $details = array();
304
+ $details['category'] = $category_name->category_name;
305
+ $details['title'] = $event->event_title;
306
+ $details['time'] = date(get_option('time_format'),strtotime($event->event_time));
307
+ $details['author'] = $e->display_name;
308
+ $details['link'] = $event->event_link;
309
+ $details['description'] = $event->event_desc;
310
+ if ($event->event_link != '') {
311
+ $details['link_title'] = "<a href='".$event->event_link."'>".$event->event_title."</a>";
312
+ } else {
313
+ $details['link_title'] = $event->event_title;
314
+ }
315
+ $details['date'] = $date;
316
+ $details['location'] = $event->event_label;
317
+ $details['street'] = $event->event_street;
318
+ $details['street2'] = $event->event_street2;
319
+ $details['city'] = $event->event_city;
320
+ $details['state'] = $event->event_state;
321
+ $details['postcode'] = $event->event_postcode;
322
+ $details['country'] = $event->event_country;
323
+ $details['hcard'] = $hcard;
324
+ $details['link_map'] = $map;
325
+
326
+ return $details;
327
+ }
328
+
329
+
330
+ ?>
my-calendar.php ADDED
@@ -0,0 +1,1572 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: My Calendar
4
+ Plugin URI: http://www.joedolson.com/articles/my-calendar/
5
+ Description: Accessible WordPress event calendar plugin. Show events from multiple calendars on pages, in posts, or in widgets.
6
+ Author: Joseph C Dolson
7
+ Author URI: http://www.joedolson.com
8
+ Version: 1.0.0
9
+ */
10
+ /* Copyright 2009 Joe Dolson (email : joe@joedolson.com)
11
+
12
+ This program is free software; you can redistribute it and/or modify
13
+ it under the terms of the GNU General Public License as published by
14
+ the Free Software Foundation; either version 2 of the License, or
15
+ (at your option) any later version.
16
+
17
+ This program is distributed in the hope that it will be useful,
18
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ GNU General Public License for more details.
21
+
22
+ You should have received a copy of the GNU General Public License
23
+ along with this program; if not, write to the Free Software
24
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
+ */
26
+
27
+ // Enable internationalisation
28
+ $plugin_dir = basename(dirname(__FILE__));
29
+ load_plugin_textdomain( 'my-calendar','wp-content/plugins/'.$plugin_dir, $plugin_dir);
30
+
31
+ // Define the tables used in My Calendar
32
+ define('MY_CALENDAR_TABLE', $table_prefix . 'my_calendar');
33
+ define('MY_CALENDAR_CATEGORIES_TABLE', $table_prefix . 'my_calendar_categories');
34
+ // Create a master category for My Calendar and its sub-pages
35
+ add_action('admin_menu', 'my_calendar_menu');
36
+ // Add the function that puts style information in the header
37
+ add_action('wp_head', 'my_calendar_wp_head');
38
+ // Add the function that deals with deleted users
39
+ add_action('delete_user', 'wp_deal_with_deleted_user');
40
+ // Add the widgets if we are using version 2.8
41
+ add_action('widgets_init', 'init_my_calendar_today');
42
+ add_action('widgets_init', 'init_my_calendar_upcoming');
43
+
44
+ function jd_calendar_plugin_action($links, $file) {
45
+ if ($file == plugin_basename(dirname(__FILE__).'/my-calendar.php'))
46
+ $links[] = "<a href='admin.php?page=my-calendar-config'>" . __('Settings', 'my-calendar') . "</a>";
47
+ return $links;
48
+ }
49
+ add_filter('plugin_action_links', 'jd_calendar_plugin_action', -10, 2);
50
+
51
+ include(dirname(__FILE__).'/my-calendar-settings.php' );
52
+ include(dirname(__FILE__).'/my-calendar-categories.php' );
53
+ include(dirname(__FILE__).'/my-calendar-help.php' );
54
+ include(dirname(__FILE__).'/my-calendar-event-manager.php' );
55
+ include(dirname(__FILE__).'/my-calendar-widgets.php' );
56
+ include(dirname(__FILE__).'/date-utilities.php' );
57
+
58
+
59
+ // Before we get on with the functions, we need to define the initial style used for My Calendar
60
+
61
+ function show_support_box() {
62
+ ?>
63
+ <div class="resources">
64
+ <ul>
65
+ <li><a href="http://www.joedolson.com/articles/my-calendar/"><?php _e("Get Support",'my-calendar'); ?></a></li>
66
+ <li><a href="http://www.joedolson.com/donate.php"><?php _e("Make a Donation",'my-calendar'); ?></a></li>
67
+ <li><form action="https://www.paypal.com/cgi-bin/webscr" method="post">
68
+ <div>
69
+ <input type="hidden" name="cmd" value="_s-xclick" />
70
+ <input type="hidden" name="hosted_button_id" value="8490399" />
71
+ <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donate_SM.gif" name="submit" alt="Donate" />
72
+ <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
73
+ </div>
74
+ </form></li>
75
+ </ul>
76
+
77
+ </div>
78
+ <?php
79
+ }
80
+
81
+ // Function to deal with events posted by a user when that user is deleted
82
+ function deal_with_deleted_user($id) {
83
+ global $wpdb;
84
+ // This wouldn't work unless the database was up to date. Lets check.
85
+ check_calendar();
86
+ // Do the query
87
+ $wpdb->get_results( "UPDATE ".MY_CALENDAR_TABLE." SET event_author=".$wpdb->get_var("SELECT MIN(ID) FROM ".$wpdb->prefix."users",0,0)." WHERE event_author=".$id );
88
+ }
89
+
90
+ // Function to add the calendar style into the header
91
+ function my_calendar_wp_head() {
92
+ global $wpdb;
93
+ // If the calendar isn't installed or upgraded this won't work
94
+ check_calendar();
95
+ $styles = stripcslashes(get_option('my_calendar_style'));
96
+ if ( get_option('my_calendar_use_styles') != 'true' ) {
97
+ echo "
98
+ <style type=\"text/css\">
99
+ <!--
100
+ // Styles from My Calendar - Joseph C Dolson http://www.joedolson.com/
101
+ $styles
102
+ -->
103
+ </style>";
104
+ }
105
+ }
106
+
107
+ // Function to deal with adding the calendar menus
108
+ function my_calendar_menu() {
109
+ global $wpdb;
110
+ // We make use of the My Calendar tables so we must have installed My Calendar
111
+ check_calendar();
112
+ // Set admin as the only one who can use My Calendar for security
113
+ $allowed_group = 'manage_options';
114
+ // Use the database to *potentially* override the above if allowed
115
+ $allowed_group = get_option('can_manage_events');
116
+
117
+
118
+ // Add the admin panel pages for My Calendar. Use permissions pulled from above
119
+ if (function_exists('add_menu_page')) {
120
+ add_menu_page(__('My Calendar','my-calendar'), __('My Calendar','my-calendar'), $allowed_group, 'my-calendar', 'edit_calendar');
121
+ }
122
+ if (function_exists('add_submenu_page')) {
123
+ add_submenu_page('my-calendar', __('Add/Edit Events','my-calendar'), __('Add/Edit Events','my-calendar'), $allowed_group, 'my-calendar', 'edit_calendar');
124
+ add_action( "admin_head", 'my_calendar_write_js' );
125
+ add_action( "admin_head", 'my_calendar_add_styles' );
126
+ // Note only admin can change calendar options
127
+ add_submenu_page('my-calendar', __('Manage Categories','my-calendar'), __('Manage Categories','my-calendar'), 'manage_options', 'my-calendar-categories', 'manage_categories');
128
+ add_submenu_page('my-calendar', __('Settings','my-calendar'), __('Settings','my-calendar'), 'manage_options', 'my-calendar-config', 'edit_my_calendar_config');
129
+ add_submenu_page('my-calendar', __('My Calendar Help','my-calendar'), __('Help','my-calendar'), 'manage_options', 'my-calendar-help', 'my_calendar_help');
130
+ }
131
+ }
132
+ add_action( "admin_menu", 'my_calendar_add_javascript' );
133
+
134
+ // Function to add the javascript to the admin header
135
+ function my_calendar_add_javascript() {
136
+ if ($_GET['page'] == 'my-calendar') {
137
+ wp_enqueue_script('jquery-ui-datepicker',WP_PLUGIN_URL . '/my-calendar/js/ui.datepicker.js', array('jquery','jquery-ui-core') );
138
+ }
139
+ if ($_GET['page'] == 'my-calendar-categories') {
140
+ wp_enqueue_script('jquery-colorpicker',WP_PLUGIN_URL . '/my-calendar/js/jquery-colorpicker.js', array('jquery') );
141
+ }
142
+ }
143
+ function my_calendar_write_js() {
144
+ if ($_GET['page']=='my-calendar') {
145
+ echo '
146
+ <script type="text/javascript">
147
+ //<![CDATA[
148
+ jQuery(document).ready(function($) {
149
+ $("#event_begin").datepicker({
150
+ numberOfMonths: 2,
151
+ dateFormat: "yy-mm-dd"
152
+ });
153
+ $("#event_end").datepicker({
154
+ numberOfMonths: 2,
155
+ dateFormat: "yy-mm-dd"
156
+ });
157
+ });
158
+ //]]>
159
+ </script>
160
+ ';
161
+ }
162
+ if ($_GET['page']=='my-calendar-categories') {
163
+ ?>
164
+ <script type=\"text/javascript\">
165
+ //<![CDATA[
166
+ //jQuery(document).ready(function($) {
167
+ //$('#category_color').colorpicker({ flat: true });
168
+ //]]>
169
+ </script>
170
+ <?php
171
+ }
172
+ }
173
+ function my_calendar_add_display_javascript() {
174
+ wp_enqueue_script('jquery');
175
+ }
176
+ add_action('init','my_calendar_add_display_javascript');
177
+
178
+ function my_calendar_calendar_javascript() {
179
+ if ( get_option('calendar_javascript') != 1 ) {
180
+ ?>
181
+ <script type='text/javascript'>
182
+ var $j = jQuery.noConflict();
183
+
184
+ $j(document).ready(function() {
185
+ $j('.calendar-event').children().not('h3').hide();
186
+ $j('.calendar-event h3').toggle(
187
+ function() {
188
+ $j('.calendar-event').children().not('h3').hide();
189
+ $j(this).parent().children().not('h3').show('fast');
190
+ },
191
+ function() {
192
+ $j('.calendar-event').children().not('h3').hide('fast');
193
+ }
194
+ );
195
+ });
196
+ </script>
197
+ <?php
198
+ }
199
+ if ( get_option('list_javascript') != 1 ) {
200
+ ?>
201
+ <script type='text/javascript'>
202
+ var $j = jQuery.noConflict();
203
+
204
+ $j(document).ready(function() {
205
+ $j('#calendar-list li').children().not('.event-date').hide();
206
+ $j('.event-date').toggle(
207
+ function() {
208
+ $j('#calendar-list li').children().not('.event-date').hide();
209
+ $j(this).parent().children().not('.event-date').show('fast');
210
+ },
211
+ function() {
212
+ $j('#calendar-list li').children().not('.event-date').hide('fast');
213
+ }
214
+ );
215
+ });
216
+ </script>
217
+ <?php
218
+ }
219
+ }
220
+ add_action('wp_head','my_calendar_calendar_javascript');
221
+
222
+ function my_calendar_add_styles() {
223
+ ?>
224
+ <link type="text/css" rel="stylesheet" href="<?php echo WP_PLUGIN_URL; ?>/my-calendar/js/ui.datepicker.css" />
225
+ <?php
226
+ echo '
227
+ <style type="text/css">
228
+ <!--
229
+ .jd-my-calendar {
230
+ margin-right: 150px!important;
231
+ }
232
+ #my-calendar legend {
233
+ font-weight: 700;
234
+ font-size: 1em;
235
+ }
236
+ .resources {
237
+ float: right;
238
+ border: 1px solid #aaa;
239
+ padding: 10px 10px 0;
240
+ margin-left: 10px;
241
+ -moz-border-radius: 5px;
242
+ -webkit-border-radius: 5px;
243
+ border-radius: 5px;
244
+ background: #fff;
245
+ text-align: center;
246
+ }
247
+ .resources form {
248
+ margin: 0!important;
249
+ }
250
+ #category_icon option {
251
+ padding: 5px 0 5px 24px;
252
+ }
253
+ #my-calendar-admin-table .delete {
254
+ background: #a00;
255
+ color: #fff;
256
+ padding: 2px 8px;
257
+ font-size: .8em;
258
+ border: 1px solid #fff;
259
+ -moz-border-radius: 8px;
260
+ -webkit-border-radius: 8px;
261
+ border-radius: 8px;
262
+ text-decoration: none;
263
+ }
264
+ #my-calendar-admin-table .delete:hover, #my-calendar-admin-table .delete:focus {
265
+ border: 1px solid #999;
266
+ background: #b11;
267
+ }
268
+ .n4 {width: 16px;}
269
+ .n5 {width: 32px;}
270
+ .n6 {width: 64px;}
271
+ .n7 {width: 128px;}
272
+ .n8 {width: 256px;}
273
+ //-->
274
+ </style>';
275
+ }
276
+
277
+ function my_calendar_insert($atts) {
278
+ extract(shortcode_atts(array(
279
+ 'name' => 'all',
280
+ 'format' => 'calendar',
281
+ 'category' => 'all',
282
+ 'showkey' => 'yes',
283
+ ), $atts));
284
+ return my_calendar($name,$format,$category,$showkey);
285
+ }
286
+ // add shortcode interpreter
287
+ add_shortcode('my_calendar','my_calendar_insert');
288
+
289
+ // Function to check what version of My Calendar is installed and install if needed
290
+ function check_calendar() {
291
+ // Checks to make sure My Calendar is installed, if not it adds the default
292
+ // database tables and populates them with test data. If it is, then the
293
+ // version is checked through various means and if it is not up to date
294
+ // then it is upgraded. (Or will be, once there's a need.)
295
+
296
+ // Lets see if this is first run and create a table if it is!
297
+ global $wpdb, $initial_style;
298
+
299
+ // default styles will go into the options table on a new install
300
+ $initial_style = "
301
+ #jd-calendar caption {
302
+ margin-top:-8px;
303
+ background:#f6f6f6;
304
+ border:1px solid #ddd;
305
+ font-weight:700;
306
+ padding:2px 0;
307
+ }
308
+
309
+ #jd-calendar table {
310
+ width:100%;
311
+ line-height:1.2;
312
+ border-collapse:collapse;
313
+ }
314
+
315
+ #jd-calendar td {
316
+ vertical-align:top;
317
+ border:1px solid #eee;
318
+ text-align:left;
319
+ width:60px;
320
+ height:70px;
321
+ padding:2px!important;
322
+ }
323
+
324
+ #jd-calendar h3 {
325
+ font-size:1em;
326
+ font-weight:700;
327
+ margin:3px 0;
328
+ padding:0;
329
+ }
330
+ #jd-calendar h3 img {
331
+ vertical-align: bottom;
332
+ margin: 0 3px 0 0!important;
333
+ }
334
+ #jd-calendar #calendar-list h3 img {
335
+ vertical-align: middle;
336
+ }
337
+
338
+ #jd-calendar .list-event h3 {
339
+ font-size:1.2em;
340
+ margin:0;
341
+ }
342
+
343
+ #jd-calendar .calendar-event .details {
344
+ position:absolute;
345
+ width:300px;
346
+ background:#cae0f5;
347
+ color:#000;
348
+ border:1px solid;
349
+ -moz-border-radius:10px;
350
+ -moz-box-shadow:4px 4px 12px #777;
351
+ -webkit-box-shadow:4px 4px 12px #777;
352
+ box-shadow:4px 4px 12px #777;
353
+ padding:5px;
354
+ z-index: 3;
355
+ }
356
+
357
+ #jd-calendar .list-event .details {
358
+ background:#fafafa;
359
+ border:1px solid #eee;
360
+ -moz-border-radius:5px;
361
+ -webkit-border-radius:5px;
362
+ border-radius:5px;
363
+ margin:5px 0;
364
+ padding:5px 5px 0;
365
+ color: #333;
366
+ }
367
+
368
+ #jd-calendar #calendar-list li {
369
+ padding:5px;
370
+ list-style-type: none;
371
+ margin: 0;
372
+ }
373
+
374
+ #jd-calendar #calendar-list .odd {
375
+ background:#d3e3e3;
376
+ }
377
+
378
+ #jd-calendar .odd .list-event .details {
379
+ background:#e3f3f3;
380
+ border:1px solid #c3d3d3;
381
+ }
382
+
383
+ #jd-calendar .current-day {
384
+ background:#ffd;
385
+ }
386
+
387
+ #jd-calendar td span {
388
+ display:block;
389
+ background:#f6f6f6;
390
+ margin:-2px -2px 2px;
391
+ padding:2px 4px;
392
+ }
393
+
394
+ #jd-calendar .calendar-event span {
395
+ display:inline;
396
+ background:none;
397
+ margin:0;
398
+ padding:0;
399
+ }
400
+
401
+ #jd-calendar .weekend {
402
+ font-weight:700;
403
+ background:#fdd;
404
+ }
405
+
406
+ #jd-calendar th {
407
+ font-size:.8em;
408
+ text-transform:uppercase;
409
+ padding:2px 4px 2px 0;
410
+ }
411
+
412
+ .category-icon {
413
+ margin-right:5px;
414
+ margin-bottom:5px;
415
+ vertical-align:middle;
416
+ }
417
+
418
+ #calendar-list li {
419
+ text-indent:0;
420
+ margin:0;
421
+ padding:0;
422
+ }
423
+
424
+ #jd-calendar .event-time {
425
+ display:block;
426
+ float:left;
427
+ height:100%;
428
+ margin-right:10px;
429
+ margin-bottom:10px;
430
+ font-weight:700;
431
+ font-size:.9em;
432
+ }
433
+
434
+ #jd-calendar p {
435
+ line-height:1.5;
436
+ margin:0 0 1em;
437
+ padding:0;
438
+ }
439
+
440
+ #jd-calendar .sub-details {
441
+ margin-left:6em;
442
+ }
443
+
444
+ #jd-calendar .vcard {
445
+ font-size:.9em;
446
+ margin:10px 0;
447
+ }
448
+
449
+ #jd-calendar .calendar-event .vcard {
450
+ margin:0 0 10px;
451
+ }
452
+
453
+ #jd-calendar,#calendar-list {
454
+ clear:left;
455
+ background: #fff;
456
+ }
457
+ #jd-calendar {
458
+ padding: 5px;
459
+ -moz-border-radius: 5px;
460
+ -webkit-border-radius: 5px;
461
+ border-radius: 5px;
462
+ }
463
+ #jd-calendar img {
464
+ border: none;
465
+ }
466
+ .category-color-sample img {
467
+ margin-right: 5px;
468
+ vertical-align: top;
469
+ }
470
+ .my-calendar-nav {
471
+ height:1em;
472
+ }
473
+
474
+ #jd-calendar .my-calendar-nav ul {
475
+ list-style-type:none;
476
+ height:2.2em;
477
+ border-bottom:1px solid #ccc;
478
+ margin:0;
479
+ padding:0;
480
+ }
481
+
482
+ #jd-calendar .my-calendar-nav li {
483
+ float:left;
484
+ list-style-type: none;
485
+ }
486
+
487
+ #jd-calendar .my-calendar-nav li:before {
488
+ content:'';
489
+ }
490
+
491
+ my-calendar-nav .my-calendar-next {
492
+ text-align:right;
493
+ }
494
+
495
+ .my-calendar-nav li a {
496
+ display:block;
497
+ background:#eee;
498
+ border:1px solid #ddd;
499
+ -moz-border-radius:5px 5px 0 0;
500
+ -webkit-border-radius:5px 5px 0 0;
501
+ border-radius:5px 5px 0 0;
502
+ border-bottom:none;
503
+ text-align:center;
504
+ padding:1px 20px;
505
+ }
506
+
507
+ .my-calendar-nav li a:hover {
508
+ background:#fff;
509
+ }";
510
+
511
+ $default_template = "<strong>{date}</strong> &#8211; {link_title}<br /><span>{time}, {category}</span>";
512
+
513
+ // Assume this is not a new install until we prove otherwise
514
+ $new_install = false;
515
+
516
+ $my_calendar_exists = false;
517
+ $upgrade_path = false;
518
+
519
+ // Determine the calendar version
520
+ $tables = $wpdb->get_results("show tables;");
521
+ foreach ( $tables as $table ) {
522
+ foreach ( $table as $value ) {
523
+ if ( $value == MY_CALENDAR_TABLE ) {
524
+ $my_calendar_exists = true;
525
+ $current_version = get_option('my_calendar_version');
526
+ // check whether installed version matches most recent version, establish upgrade process.
527
+ }
528
+ }
529
+ }
530
+ if ( $my_calendar_exists == false ) {
531
+ $new_install = true;
532
+ }
533
+
534
+ // Now we've determined what the current install is or isn't
535
+ if ( $new_install == true ) {
536
+ $sql = "CREATE TABLE " . MY_CALENDAR_TABLE . " (
537
+ event_id INT(11) NOT NULL AUTO_INCREMENT ,
538
+ event_begin DATE NOT NULL ,
539
+ event_end DATE NOT NULL ,
540
+ event_title VARCHAR(60) NOT NULL ,
541
+ event_desc TEXT NOT NULL ,
542
+ event_time TIME ,
543
+ event_recur CHAR(1) ,
544
+ event_repeats INT(3) ,
545
+ event_author BIGINT(20) UNSIGNED,
546
+ event_category BIGINT(20) UNSIGNED,
547
+ event_link TEXT,
548
+ event_label VARCHAR(60) NOT NULL ,
549
+ event_street VARCHAR(60) NOT NULL ,
550
+ event_street2 VARCHAR(60) NOT NULL ,
551
+ event_city VARCHAR(60) NOT NULL ,
552
+ event_state VARCHAR(60) NOT NULL ,
553
+ event_postcode VARCHAR(10) NOT NULL ,
554
+ event_country VARCHAR(60) NOT NULL ,
555
+ PRIMARY KEY (event_id)
556
+ )";
557
+ $wpdb->get_results($sql);
558
+ add_option('can_manage_events','edit_posts');
559
+ add_option('my_calendar_style',"$initial_style");
560
+ add_option('display_author','false');
561
+ add_option('display_jump','false');
562
+ add_option('display_todays','true');
563
+ add_option('display_upcoming','true');
564
+ add_option('display_upcoming_days',7);
565
+ add_option('my_calendar_version','1.0');
566
+ add_option('display_upcoming_type','false');
567
+ add_option('display_upcoming_events',3);
568
+ add_option('display_past_days',0);
569
+ add_option('display_past_events',2);
570
+ add_option('my_calendar_use_styles','true');
571
+ add_option('my_calendar_show_months',1);
572
+ add_option('my_calendar_show_map','true');
573
+ add_option('my_calendar_show_address','false');
574
+ add_option('my_calendar_today_template',$default_template);
575
+ add_option('my_calendar_upcoming_template',$default_template);
576
+ add_option('my_calendar_today_title','Today\'s Events');
577
+ add_option('my_calendar_upcoming_title','Upcoming Events');
578
+ add_option('calendar_javascript',1);
579
+ add_option('list_javascript',1);
580
+ $sql = "UPDATE " . MY_CALENDAR_TABLE . " SET event_category=1";
581
+ $wpdb->get_results($sql);
582
+
583
+ $sql = "CREATE TABLE " . MY_CALENDAR_CATEGORIES_TABLE . " (
584
+ category_id INT(11) NOT NULL AUTO_INCREMENT,
585
+ category_name VARCHAR(30) NOT NULL ,
586
+ category_color VARCHAR(30) NOT NULL ,
587
+ category_icon VARCHAR(128) NOT NULL ,
588
+ PRIMARY KEY (category_id)
589
+ )";
590
+ $wpdb->get_results($sql);
591
+ $sql = "INSERT INTO " . MY_CALENDAR_CATEGORIES_TABLE . " SET category_id=1, category_name='General', category_color='#ffffff', category_icon='event.png'";
592
+ $wpdb->get_results($sql);
593
+ }
594
+
595
+ // placeholder for future upgrades
596
+
597
+ switch ($upgrade_path) {
598
+ case $upgrade_path == FALSE:
599
+ break;
600
+ default:
601
+ break;
602
+ }
603
+
604
+ }
605
+ function jd_cal_checkCheckbox( $theFieldname,$theValue ){
606
+ if( get_option( $theFieldname ) == $theValue ){
607
+ echo 'checked="checked"';
608
+ }
609
+ }
610
+ function jd_cal_checkSelect( $theFieldname,$theValue ) {
611
+ if ( get_option( $theFieldname ) == $theValue) {
612
+ echo 'selected="selected"';
613
+ }
614
+ }
615
+
616
+ // Function to return a prefix which will allow the correct
617
+ // placement of arguments into the query string.
618
+ function permalink_prefix() {
619
+ // Get the permalink structure from WordPress
620
+ $p_link = get_permalink();
621
+
622
+ // Work out what the real URL we are viewing is
623
+ $s = empty($_SERVER["HTTPS"]) ? '' : ($_SERVER["HTTPS"] == "on") ? "s" : "";
624
+ $protocol = substr(strtolower($_SERVER["SERVER_PROTOCOL"]), 0, strpos(strtolower($_SERVER["SERVER_PROTOCOL"]), "/")).$s;
625
+ $port = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":".$_SERVER["SERVER_PORT"]);
626
+ $real_link = $protocol.'://'.$_SERVER['SERVER_NAME'].$port.$_SERVER['REQUEST_URI'];
627
+
628
+ // Now use all of that to get the correctly craft the My Calendar link prefix
629
+ if (strstr($p_link, '?') && $p_link == $real_link) {
630
+ $link_part = $p_link.'&';
631
+ } else if ($p_link == $real_link) {
632
+ $link_part = $p_link.'?';
633
+ } else if (strstr($real_link, '?')) {
634
+ if (isset($_GET['month']) && isset($_GET['yr'])) {
635
+ $new_tail = split("&", $real_link);
636
+ foreach ($new_tail as $item) {
637
+ if (!strstr($item, 'month') && !strstr($item, 'yr')) {
638
+ $link_part .= $item.'&amp;';
639
+ }
640
+ }
641
+ if (!strstr($link_part, '?')) {
642
+ $new_tail = split("month", $link_part);
643
+ $link_part = $new_tail[0].'?'.$new_tail[1];
644
+ }
645
+ } else {
646
+ $link_part = $real_link.'&amp;';
647
+ }
648
+ } else {
649
+ $link_part = $real_link.'?';
650
+ }
651
+ return $link_part;
652
+ }
653
+
654
+ // Configure the "Next" link in the calendar
655
+ function next_link($cur_year,$cur_month) {
656
+ $mod_rewrite_months = array(1=>'jan','feb','mar','apr','may','jun','jul','aug','sept','oct','nov','dec');
657
+ $next_year = $cur_year + 1;
658
+
659
+ $num_months = get_option('my_calendar_show_months');
660
+ if ($num_months <= 1) {
661
+ if ($cur_month == 12) {
662
+ return '<a href="' . permalink_prefix() . 'month=jan&amp;yr=' . $next_year . '" rel="nofollow">'.__('Next Events','my-calendar').' &raquo;</a>';
663
+ } else {
664
+ $next_month = $cur_month + 1;
665
+ $month = $mod_rewrite_months[$next_month];
666
+ return '<a href="' . permalink_prefix() . 'month='.$month.'&amp;yr=' . $cur_year . '" rel="nofollow">'.__('Next Events','my-calendar').' &raquo;</a>';
667
+ }
668
+ } else {
669
+ if (($cur_month + $num_months) > 12) {
670
+ $next_month = ($cur_month + $num_months) - 12;
671
+ } else {
672
+ $next_month = $cur_month + $num_months;
673
+ }
674
+ $month = $mod_rewrite_months[$next_month];
675
+ if ($cur_month >= (12-$num_months)) {
676
+ return '<a href="' . permalink_prefix() . 'month='.$month.'&amp;yr=' . $next_year . '" rel="nofollow">'.__('Next Events','my-calendar').' &raquo;</a>';
677
+ } else {
678
+ return '<a href="' . permalink_prefix() . 'month='.$month.'&amp;yr=' . $cur_year . '" rel="nofollow">'.__('Next Events','my-calendar').' &raquo;</a>';
679
+ }
680
+ }
681
+ }
682
+
683
+ // Configure the "Previous" link in the calendar
684
+ function prev_link($cur_year,$cur_month) {
685
+ $mod_rewrite_months = array(1=>'jan','feb','mar','apr','may','jun','jul','aug','sept','oct','nov','dec');
686
+ $last_year = $cur_year - 1;
687
+
688
+ $num_months = get_option('my_calendar_show_months');
689
+ if ($num_months <= 1) {
690
+ if ($cur_month == 1) {
691
+ return '<a href="' . permalink_prefix() . 'month=dec&amp;yr='. $last_year .'" rel="nofollow">&laquo; '.__('Previous Events','my-calendar').'</a>';
692
+ } else {
693
+ $next_month = $cur_month - 1;
694
+ $month = $mod_rewrite_months[$next_month];
695
+ return '<a href="' . permalink_prefix() . 'month='.$month.'&amp;yr=' . $cur_year . '" rel="nofollow">&laquo; '.__('Previous Events','my-calendar').'</a>';
696
+ }
697
+ } else {
698
+ if ($cur_month > $num_months) {
699
+ $next_month = $cur_month - $num_months;
700
+ } else {
701
+ $next_month = ($cur_month - $num_months) + 12;
702
+ }
703
+ $month = $mod_rewrite_months[$next_month];
704
+ if ($cur_month <= $num_months) {
705
+ return '<a href="' . permalink_prefix() . 'month='.$month.'&amp;yr=' . $last_year . '" rel="nofollow">&laquo; '.__('Previous Events','my-calendar').'</a>';
706
+ } else {
707
+ return '<a href="' . permalink_prefix() . 'month='.$month.'&amp;yr=' . $cur_year . '" rel="nofollow">&laquo; '.__('Previous Events','my-calendar').'</a>';
708
+ }
709
+ }
710
+ }
711
+
712
+ // Used to draw multiple events
713
+ function draw_events($events, $type) {
714
+ // We need to sort arrays of objects by time
715
+ usort($events, "time_cmp");
716
+ foreach($events as $event) {
717
+ $output .= draw_event($event, $type);
718
+ }
719
+ return $output;
720
+ }
721
+
722
+ // Used to draw an event to the screen
723
+ function draw_event($event, $type="calendar") {
724
+ global $wpdb;
725
+
726
+ // My Calendar must be updated to run this function
727
+ check_calendar();
728
+
729
+ $display_author = get_option('display_author');
730
+ $display_map = get_option('my_calendar_show_map');
731
+ $display_address = get_option('my_calendar_show_address');
732
+ $sql = "SELECT * FROM " . MY_CALENDAR_CATEGORIES_TABLE . " WHERE category_id=".$event->event_category;
733
+ $cat_details = $wpdb->get_row($sql);
734
+ $style = "background-color:".$cat_details->category_color.";";
735
+ if ($cat_details->category_icon != "") {
736
+ $image = '<img src="'.WP_PLUGIN_URL.'/my-calendar/icons/'.$cat_details->category_icon.'" alt="" class="category-icon" style="background:'.$cat_details->category_color.';" />';
737
+ } else {
738
+ $image = "";
739
+ }
740
+ $location_string = $event->event_street.$event->event_street2.$event->event_city.$event->event_state.$event->event_postcode.$event->event_country;
741
+ if (($display_address == 'true' || $display_map == 'true') && strlen($location_string) > 5) {
742
+ $map_string = $event->event_street.' '.$event->event_street2.' '.$event->event_city.' '.$event->event_state.' '.$event->event_postcode.' '.$event->event_country;
743
+
744
+ $address .= '<div class="address vcard">';
745
+
746
+ if ($display_address == 'true' && strlen($location_string) > 5) {
747
+ $address .= "<div class=\"adr\">";
748
+ if ($event->event_label != "") {
749
+ $address .= "<strong class=\"org\">".$event->event_label."</strong><br />";
750
+ }
751
+ if ($event->event_street != "") {
752
+ $address .= "<div class=\"street-address\">".$event->event_street."</div>";
753
+ }
754
+ if ($event->event_street2 != "") {
755
+ $address .= "<div class=\"street-address\">".$event->event_street2."</div>";
756
+ }
757
+ if ($event->event_city != "") {
758
+ $address .= "<span class=\"locality\">".$event->event_city.",</span>";
759
+ }
760
+ if ($event->event_state != "") {
761
+ $address .= " <span class=\"region\">".$event->event_state."</span> ";
762
+ }
763
+ if ($event->event_postcode != "") {
764
+ $address .= " <span class=\"postal-code\">".$event->event_postcode."</span>";
765
+ }
766
+ if ($event->event_country != "") {
767
+ $address .= "<div class=\"country-name\">".$event->event_country."</div>";
768
+ }
769
+ $address .= "</div>";
770
+ }
771
+ if ($display_map == 'true') {
772
+ if (strlen($location_string) > 5) {
773
+ $map_string = str_replace(" ","+",$map_string);
774
+ if ($event->event_label != "") {
775
+ $map_label = $event->event_label;
776
+ } else {
777
+ $map_label = $event->event_title;
778
+ }
779
+ $map = "<a href=\"http://maps.google.com/maps?f=q&amp;z=15&amp;q=$map_string\">Map<span> to $map_label</span></a>";
780
+ $address .= "<div class=\"url map\">$map</div>";
781
+ }
782
+ }
783
+ $address .= "</div>";
784
+ }
785
+
786
+ $my_calendar_directory = get_bloginfo( 'wpurl' ) . '/' . PLUGINDIR . '/' . dirname( plugin_basename(__FILE__) );
787
+
788
+ $header_details .= "\n<div class='$type-event'>\n";
789
+ if ($type == "calendar") {
790
+ $header_details .= "<h3 class='event-title'>$image".$event->event_title." <a href='#'><img src='$my_calendar_directory/images/event-details.png' alt='".__('Event Details','my-calendar')."' /></a></h3>\n";
791
+ }
792
+ $header_details .= "<div class='details'>";
793
+ if ($event->event_time != "00:00:00") {
794
+ $header_details .= "<span class='event-time'>".date(get_option('time_format'), strtotime($event->event_time)) . "</span>\n";
795
+ } else {
796
+ $header_details .= "<span class='event-time'><abbr title='".__('Not Applicable','my-calendar')."'>".__('N/A','my-calendar')."</abbr></span>\n";
797
+ }
798
+ $header_details .= "<div class='sub-details'>";
799
+ if ($type != "calendar") {
800
+ $header_details .= "<h3 class='event-title'>$image".$event->event_title."</h3>\n";
801
+ }
802
+ if ($display_author == 'true') {
803
+ $e = get_userdata($event->event_author);
804
+ $header_details .= '<span class="event-author">'.__('Posted by', 'my-calendar').': <span class="author-name">'.$e->display_name."</span></span><br />\n ";
805
+ }
806
+ if ($display_address == 'true' || $display_map == 'true') {
807
+ $header_details .= $address;
808
+ }
809
+
810
+ if ($event->event_link != '') { $linky = $event->event_link; } else { $linky = '#'; }
811
+ if ($linky != "#") {
812
+ $details = "\n". $header_details . '' . wpautop($event->event_desc,1) . '<p><a href="'.$linky.'" class="event-link">' . $event->event_title . '&raquo; </a></p>'."</div></div></div>\n";
813
+ } else {
814
+ $details = "\n". $header_details . '' . wpautop($event->event_desc,1) . "</div></div></div>\n";
815
+ }
816
+ return $details;
817
+ }
818
+ // used to generate upcoming events lists
819
+ function get_all_events() {
820
+ global $wpdb;
821
+ $events = $wpdb->get_results("SELECT * FROM " . MY_CALENDAR_TABLE);
822
+ $date = date('Y').'-'.date('m').'-'.date('d');
823
+ if (!empty($events)) {
824
+ foreach($events as $event) {
825
+ if ($event->event_recur != "S") {
826
+ $orig_begin = $event->event_begin;
827
+ $orig_end = $event->event_end;
828
+ $numback = 0;
829
+ $numforward = $event->event_repeats;
830
+ if ($event->event_repeats != 0) {
831
+ switch ($event->event_recur) {
832
+ case "D":
833
+ for ($i=$numback;$i<=$numforward;$i++) {
834
+ $begin = add_date($orig_begin,$i,0,0);
835
+ $end = add_date($orig_end,$i,0,0);
836
+ ${$i} = clone $event;
837
+ ${$i}->event_begin = $begin;
838
+ ${$i}->event_end = $end;
839
+ $arr_events[]=${$i};
840
+ }
841
+ break;
842
+ case "W":
843
+ for ($i=$numback;$i<=$numforward;$i++) {
844
+ $begin = add_date($orig_begin,($i*7),0,0);
845
+ $end = add_date($orig_end,($i*7),0,0);
846
+ ${$i} = clone $event;
847
+ ${$i}->event_begin = $begin;
848
+ ${$i}->event_end = $end;
849
+ $arr_events[]=${$i};
850
+ }
851
+ break;
852
+ case "M":
853
+ for ($i=$numback;$i<=$numforward;$i++) {
854
+ $begin = add_date($orig_begin,0,$i,0);
855
+ $end = add_date($orig_end,0,$i,0);
856
+ ${$i} = clone $event;
857
+ ${$i}->event_begin = $begin;
858
+ ${$i}->event_end = $end;
859
+ $arr_events[]=${$i};
860
+ }
861
+ break;
862
+ case "Y":
863
+ for ($i=$numback;$i<=$numforward;$i++) {
864
+ $begin = add_date($orig_begin,0,0,$i);
865
+ $end = add_date($orig_end,0,0,$i);
866
+ ${$i} = clone $event;
867
+ ${$i}->event_begin = $begin;
868
+ ${$i}->event_end = $end;
869
+ $arr_events[]=${$i};
870
+ }
871
+ break;
872
+ }
873
+ } else {
874
+ switch ($event->event_recur) {
875
+ case "D":
876
+ $event_begin = $event->event_begin;
877
+ $today = date('Y').'-'.date('m').'-'.date('d');
878
+ $nDays = get_option('display_past_events');
879
+ $fDays = get_option('display_upcoming_events');
880
+ if ( date_comp($event_begin, $today) ) { // compare first date against today's date
881
+ if (date_comp( $event_begin, add_date($this_date,-($nDays),0,0) )) {
882
+ $diff = jd_date_diff_precise(strtotime($event_begin));
883
+ $diff_days = $diff/(86400);
884
+ $days = explode(".",$diff_days);
885
+ $realStart = $days[0] - $nDays;
886
+ $realFinish = $days[0] + $fDays;
887
+
888
+ for ($realStart;$realStart<=$realFinish;$realStart++) { // jump forward to near present.
889
+ $this_date = add_date($event_begin,($realStart),0,0);
890
+ if ( date_comp( $event->event_begin,$this_date ) ) {
891
+ ${$realStart} = clone $event;
892
+ ${$realStart}->event_begin = $this_date;
893
+ $arr_events[] = ${$realStart};
894
+ }
895
+ }
896
+
897
+ } else {
898
+ $realDays = -($nDays);
899
+ for ($realDays;$realDays<=$fDays;$realDays++) { // for each event within plus or minus range, mod date and add to array.
900
+ $this_date = add_date($event_begin,$realDays,0,0);
901
+ if ( date_comp( $event->event_begin,$this_date ) == true ) {
902
+ ${$realDays} = clone $event;
903
+ ${$realDays}->event_begin = $this_date;
904
+ $arr_events[] = ${$realDays};
905
+ }
906
+ }
907
+ }
908
+ } else {
909
+ break;
910
+ }
911
+ break;
912
+
913
+ case "W":
914
+ $event_begin = $event->event_begin;
915
+ $today = date('Y').'-'.date('m').'-'.date('d');
916
+ $nDays = get_option('display_past_events');
917
+ $fDays = get_option('display_upcoming_events');
918
+
919
+ if ( date_comp($event_begin, $today) ) { // compare first date against today's date
920
+ if (date_comp( $event_begin, add_date($this_date,-($nDays*7),0,0) )) {
921
+ $diff = jd_date_diff_precise(strtotime($event_begin));
922
+ $diff_weeks = $diff/(86400*7);
923
+ $weeks = explode(".",$diff_weeks);
924
+ $realStart = $weeks[0] - $nDays;
925
+ $realFinish = $weeks[0] + $fDays;
926
+
927
+ for ($realStart;$realStart<=$realFinish;$realStart++) { // jump forward to near present.
928
+ $this_date = add_date($event_begin,($realStart*7),0,0);
929
+ if ( date_comp( $event->event_begin,$this_date ) ) {
930
+ ${$realStart} = clone $event;
931
+ ${$realStart}->event_begin = $this_date;
932
+ $arr_events[] = ${$realStart};
933
+ }
934
+ }
935
+
936
+ } else {
937
+ $realDays = -($nDays);
938
+ for ($realDays;$realDays<=$fDays;$realDays++) { // for each event within plus or minus range, mod date and add to array.
939
+ $this_date = add_date($event_begin,($realDays*7),0,0);
940
+ if ( date_comp( $event->event_begin,$this_date ) ) {
941
+ ${$realDays} = clone $event;
942
+ ${$realDays}->event_begin = $this_date;
943
+ $arr_events[] = ${$realDays};
944
+ }
945
+ }
946
+ }
947
+ } else {
948
+ break;
949
+ }
950
+ break;
951
+
952
+ case "M":
953
+ $event_begin = $event->event_begin;
954
+ $today = date('Y').'-'.date('m').'-'.date('d');
955
+ $nDays = get_option('display_past_events');
956
+ $fDays = get_option('display_upcoming_events');
957
+
958
+ if ( date_comp($event_begin, $today) ) { // compare first date against today's date
959
+ if (date_comp( $event_begin, add_date($this_date,-($nDays),0,0) )) {
960
+ $diff = jd_date_diff_precise(strtotime($event_begin));
961
+ $diff_days = $diff/(86400*30);
962
+ $days = explode(".",$diff_days);
963
+ $realStart = $days[0] - $nDays;
964
+ $realFinish = $days[0] + $fDays;
965
+
966
+ for ($realStart;$realStart<=$realFinish;$realStart++) { // jump forward to near present.
967
+ $this_date = add_date($event_begin,0,$realStart,0);
968
+ if ( date_comp( $event->event_begin,$this_date ) ) {
969
+ ${$realStart} = clone $event;
970
+ ${$realStart}->event_begin = $this_date;
971
+ $arr_events[] = ${$realStart};
972
+ }
973
+ }
974
+
975
+ } else {
976
+ $realDays = -($nDays);
977
+ for ($realDays;$realDays<=$fDays;$realDays++) { // for each event within plus or minus range, mod date and add to array.
978
+ $this_date = add_date($event_begin,0,$realDays,0);
979
+ if ( date_comp( $event->event_begin,$this_date ) == true ) {
980
+ ${$realDays} = clone $event;
981
+ ${$realDays}->event_begin = $this_date;
982
+ $arr_events[] = ${$realDays};
983
+ }
984
+ }
985
+ }
986
+ } else {
987
+ break;
988
+ }
989
+ break;
990
+
991
+ case "Y":
992
+ $event_begin = $event->event_begin;
993
+ $today = date('Y').'-'.date('m').'-'.date('d');
994
+ $nDays = get_option('display_past_events');
995
+ $fDays = get_option('display_upcoming_events');
996
+
997
+ if ( date_comp($event_begin, $today) ) { // compare first date against today's date
998
+ if (date_comp( $event_begin, add_date($this_date,-($nDays),0,0) )) {
999
+ $diff = jd_date_diff_precise(strtotime($event_begin));
1000
+ $diff_days = $diff/(86400*365);
1001
+ $days = explode(".",$diff_days);
1002
+ $realStart = $days[0] - $nDays;
1003
+ $realFinish = $days[0] + $fDays;
1004
+
1005
+ for ($realStart;$realStart<=$realFinish;$realStart++) { // jump forward to near present.
1006
+ $this_date = add_date($event_begin,0,0,$realStart);
1007
+ if ( date_comp( $event->event_begin,$this_date ) ) {
1008
+ ${$realStart} = clone $event;
1009
+ ${$realStart}->event_begin = $this_date;
1010
+ $arr_events[] = ${$realStart};
1011
+ }
1012
+ }
1013
+
1014
+ } else {
1015
+ $realDays = -($nDays);
1016
+ for ($realDays;$realDays<=$fDays;$realDays++) { // for each event within plus or minus range, mod date and add to array.
1017
+ $this_date = add_date($event_begin,0,0,$realDays);
1018
+ if ( date_comp( $event->event_begin,$this_date ) == true ) {
1019
+ ${$realDays} = clone $event;
1020
+ ${$realDays}->event_begin = $this_date;
1021
+ $arr_events[] = ${$realDays};
1022
+ }
1023
+ }
1024
+ }
1025
+ } else {
1026
+ break;
1027
+ }
1028
+ break;
1029
+ }
1030
+ }
1031
+ } else {
1032
+ $arr_events[]=$event;
1033
+ }
1034
+ }
1035
+ }
1036
+ return $arr_events;
1037
+ }
1038
+ // Grab all events for the requested date from calendar
1039
+ function grab_events($y,$m,$d,$category=null) {
1040
+ global $wpdb;
1041
+
1042
+ if ( $category!=null ) {
1043
+ if (is_numeric($category)) {
1044
+ $select_category = "event_category = $category AND";
1045
+ } else {
1046
+ $cat = $wpdb->get_row("SELECT category_id FROM " . MY_CALENDAR_CATEGORIES_TABLE . " WHERE category_name = '$category'");
1047
+ $category_id = $cat->category_id;
1048
+ if (!$category_id) {
1049
+ //if the requested category doesn't exist, fail silently
1050
+ $select_category = "";
1051
+ } else {
1052
+ $select_category = "event_category = $category_id AND";
1053
+ }
1054
+ }
1055
+ }
1056
+ $arr_events = array();
1057
+
1058
+ // Get the date format right
1059
+ $date = $y . '-' . $m . '-' . $d;
1060
+
1061
+ // First we check for conventional events. These will form the first instance of a recurring event
1062
+ // or the only instance of a one-off event
1063
+ $events = $wpdb->get_results("SELECT * FROM " . MY_CALENDAR_TABLE . " WHERE $select_category event_begin <= '$date' AND event_end >= '$date' AND event_recur = 'S' ORDER BY event_id");
1064
+ if (!empty($events)) {
1065
+ foreach($events as $event) {
1066
+ $arr_events[]=$event;
1067
+ }
1068
+ }
1069
+
1070
+ // Deal with forever recurring year events
1071
+ $events = $wpdb->get_results("SELECT * FROM " . MY_CALENDAR_TABLE . " WHERE $select_category event_recur = 'Y' AND EXTRACT(YEAR FROM '$date') >= EXTRACT(YEAR FROM event_begin) AND event_repeats = 0 ORDER BY event_id");
1072
+
1073
+ if (!empty($events)) {
1074
+ foreach($events as $event) {
1075
+ // Technically we don't care about the years, but we need to find out if the
1076
+ // event spans the turn of a year so we can deal with it appropriately.
1077
+ $year_begin = date('Y',strtotime($event->event_begin));
1078
+ $year_end = date('Y',strtotime($event->event_end));
1079
+
1080
+ if ($year_begin == $year_end) {
1081
+ if (date('m-d',strtotime($event->event_begin)) <= date('m-d',strtotime($date)) &&
1082
+ date('m-d',strtotime($event->event_end)) >= date('m-d',strtotime($date))) {
1083
+ $arr_events[]=$event;
1084
+ }
1085
+ } else if ($year_begin < $year_end) {
1086
+ if (date('m-d',strtotime($event->event_begin)) <= date('m-d',strtotime($date)) ||
1087
+ date('m-d',strtotime($event->event_end)) >= date('m-d',strtotime($date))) {
1088
+ $arr_events[]=$event;
1089
+ }
1090
+ }
1091
+ }
1092
+ }
1093
+
1094
+ // Now the ones that happen a finite number of times
1095
+ $events = $wpdb->get_results("SELECT * FROM " . MY_CALENDAR_TABLE . " WHERE $select_category event_recur = 'Y' AND EXTRACT(YEAR FROM '$date') >= EXTRACT(YEAR FROM event_begin) AND event_repeats != 0 AND (EXTRACT(YEAR FROM '$date')-EXTRACT(YEAR FROM event_begin)) <= event_repeats ORDER BY event_id");
1096
+ if (!empty($events)) {
1097
+ foreach($events as $event) {
1098
+ // Technically we don't care about the years, but we need to find out if the
1099
+ // event spans the turn of a year so we can deal with it appropriately.
1100
+ $year_begin = date('Y',strtotime($event->event_begin));
1101
+ $year_end = date('Y',strtotime($event->event_end));
1102
+
1103
+ if ($year_begin == $year_end) {
1104
+ if (date('m-d',strtotime($event->event_begin)) <= date('m-d',strtotime($date)) &&
1105
+ date('m-d',strtotime($event->event_end)) >= date('m-d',strtotime($date))) {
1106
+ $arr_events[]=$event;
1107
+ }
1108
+ } else if ($year_begin < $year_end) {
1109
+ if (date('m-d',strtotime($event->event_begin)) <= date('m-d',strtotime($date)) ||
1110
+ date('m-d',strtotime($event->event_end)) >= date('m-d',strtotime($date))) {
1111
+ $arr_events[]=$event;
1112
+ }
1113
+ }
1114
+ }
1115
+ }
1116
+ // The monthly events that never stop recurring
1117
+ $events = $wpdb->get_results("SELECT * FROM " . MY_CALENDAR_TABLE . " WHERE $select_category event_recur = 'M' AND EXTRACT(YEAR FROM '$date') >= EXTRACT(YEAR FROM event_begin) AND event_repeats = 0 ORDER BY event_id");
1118
+ if (!empty($events)) {
1119
+ foreach($events as $event) {
1120
+
1121
+ // Technically we don't care about the years or months, but we need to find out if the
1122
+ // event spans the turn of a year or month so we can deal with it appropriately.
1123
+ $month_begin = date('m',strtotime($event->event_begin));
1124
+ $month_end = date('m',strtotime($event->event_end));
1125
+
1126
+ if ($month_begin == $month_end) {
1127
+ if (date('d',strtotime($event->event_begin)) <= date('d',strtotime($date)) &&
1128
+ date('d',strtotime($event->event_end)) >= date('d',strtotime($date))) {
1129
+ $arr_events[]=$event;
1130
+ }
1131
+ } else if ($month_begin < $month_end) {
1132
+ if ( ($event->event_begin <= date('Y-m-d',strtotime($date))) && (date('d',strtotime($event->event_begin)) <= date('d',strtotime($date)) ||
1133
+ date('d',strtotime($event->event_end)) >= date('d',strtotime($date))) ) {
1134
+ $arr_events[]=$event;
1135
+ }
1136
+ }
1137
+ }
1138
+ }
1139
+
1140
+ // Now the ones that happen a finite number of times
1141
+ $events = $wpdb->get_results("SELECT * FROM " . MY_CALENDAR_TABLE . " WHERE $select_category event_recur = 'M' AND EXTRACT(YEAR FROM '$date') >= EXTRACT(YEAR FROM event_begin) AND event_repeats != 0 AND (PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM '$date'),EXTRACT(YEAR_MONTH FROM event_begin))) <= event_repeats ORDER BY event_id");
1142
+ if (!empty($events)) {
1143
+ foreach($events as $event) {
1144
+
1145
+ // Technically we don't care about the years or months, but we need to find out if the
1146
+ // event spans the turn of a year or month so we can deal with it appropriately.
1147
+ $month_begin = date('m',strtotime($event->event_begin));
1148
+ $month_end = date('m',strtotime($event->event_end));
1149
+
1150
+ if ($month_begin == $month_end) {
1151
+ if (date('d',strtotime($event->event_begin)) <= date('d',strtotime($date)) &&
1152
+ date('d',strtotime($event->event_end)) >= date('d',strtotime($date))) {
1153
+ $arr_events[]=$event;
1154
+ }
1155
+ } else if ($month_begin < $month_end) {
1156
+ if ( ($event->event_begin <= date('Y-m-d',strtotime($date))) && (date('d',strtotime($event->event_begin)) <= date('d',strtotime($date)) ||
1157
+ date('d',strtotime($event->event_end)) >= date('d',strtotime($date))) ) {
1158
+ $arr_events[]=$event;
1159
+ }
1160
+ }
1161
+ }
1162
+ }
1163
+
1164
+ /*
1165
+ Weekly - well isn't this fun! We need to scan all weekly events, find what day they fell on
1166
+ and see if that matches the current day. If it does, we check to see if the repeats are 0.
1167
+ If they are, display the event, if not, we fast forward from the original day in week blocks
1168
+ until the number is exhausted. If the date we arrive at is in the future, display the event.
1169
+ */
1170
+
1171
+ // The weekly events that never stop recurring
1172
+ $events = $wpdb->get_results("SELECT * FROM " . MY_CALENDAR_TABLE . " WHERE $select_category event_recur = 'W' AND '$date' >= event_begin AND event_repeats = 0 ORDER BY event_id");
1173
+ if (!empty($events))
1174
+ {
1175
+ foreach($events as $event)
1176
+ {
1177
+ // This is going to get complex so lets setup what we would place in for
1178
+ // an event so we can drop it in with ease
1179
+
1180
+ // Now we are going to check to see what day the original event
1181
+ // fell on and see if the current date is both after it and on
1182
+ // the correct day. If it is, display the event!
1183
+ $day_start_event = date('D',strtotime($event->event_begin));
1184
+ $day_end_event = date('D',strtotime($event->event_end));
1185
+ $current_day = date('D',strtotime($date));
1186
+
1187
+ $plan = array("Mon"=>1,"Tue"=>2,"Wed"=>3,"Thu"=>4,"Fri"=>5,"Sat"=>6,"Sun"=>7);
1188
+
1189
+ if ($plan[$day_start_event] > $plan[$day_end_event]) {
1190
+ if (($plan[$day_start_event] <= $plan[$current_day]) || ($plan[$current_day] <= $plan[$day_end_event])) {
1191
+ $arr_events[]=$event;
1192
+ }
1193
+ } else if (($plan[$day_start_event] < $plan[$day_end_event]) || ($plan[$day_start_event]== $plan[$day_end_event])) {
1194
+ if (($plan[$day_start_event] <= $plan[$current_day]) && ($plan[$current_day] <= $plan[$day_end_event])) {
1195
+ $arr_events[]=$event;
1196
+ }
1197
+ }
1198
+
1199
+ }
1200
+ }
1201
+
1202
+ // The weekly events that have a limit on how many times they occur
1203
+ $events = $wpdb->get_results("SELECT * FROM " . MY_CALENDAR_TABLE . " WHERE $select_category event_recur = 'W' AND '$date' >= event_begin AND event_repeats != 0 AND (event_repeats*7) >= (TO_DAYS('$date') - TO_DAYS(event_end)) ORDER BY event_id");
1204
+ if (!empty($events)) {
1205
+ foreach($events as $event) {
1206
+
1207
+ // Now we are going to check to see what day the original event
1208
+ // fell on and see if the current date is both after it and on
1209
+ // the correct day. If it is, display the event!
1210
+ $day_start_event = date('D',strtotime($event->event_begin));
1211
+ $day_end_event = date('D',strtotime($event->event_end));
1212
+ $current_day = date('D',strtotime($date));
1213
+
1214
+ $plan = array("Mon"=>1,"Tue"=>2,"Wed"=>3,"Thu"=>4,"Fri"=>5,"Sat"=>6,"Sun"=>7);
1215
+
1216
+ if ($plan[$day_start_event] > $plan[$day_end_event]) {
1217
+ if (($plan[$day_start_event] <= $plan[$current_day]) || ($plan[$current_day] <= $plan[$day_end_event])) {
1218
+ $arr_events[]=$event;
1219
+ }
1220
+ } else if (($plan[$day_start_event] < $plan[$day_end_event]) || ($plan[$day_start_event]== $plan[$day_end_event])) {
1221
+ if (($plan[$day_start_event] <= $plan[$current_day]) && ($plan[$current_day] <= $plan[$day_end_event])) {
1222
+ $arr_events[]=$event;
1223
+ }
1224
+ }
1225
+
1226
+ }
1227
+ }
1228
+
1229
+
1230
+ // The daily events that never stop recurring
1231
+ $events = $wpdb->get_results("SELECT * FROM " . MY_CALENDAR_TABLE . " WHERE $select_category event_recur = 'D' AND '$date' >= event_begin AND event_repeats = 0 ORDER BY event_id");
1232
+ if (!empty($events)) {
1233
+ foreach($events as $event) {
1234
+ // checking events which recur by day is easy: just shove 'em all in there!
1235
+ $arr_events[]=$event;
1236
+ }
1237
+ }
1238
+
1239
+ // The daily events that have a limit on how many times they occur
1240
+ $events = $wpdb->get_results("SELECT * FROM " . MY_CALENDAR_TABLE . " WHERE $select_category event_recur = 'D' AND '$date' >= event_begin AND event_repeats != 0 AND (event_repeats) >= (TO_DAYS('$date') - TO_DAYS(event_end)) ORDER BY event_id");
1241
+ if (!empty($events)) {
1242
+ foreach($events as $event) {
1243
+ // checking events which recur by day is easy: just shove 'em all in there!
1244
+ $arr_events[]=$event;
1245
+ }
1246
+ }
1247
+ // end daily events
1248
+ return $arr_events;
1249
+ }
1250
+
1251
+ function month_comparison($month) {
1252
+ $current_month = strtolower(date("M", time()));
1253
+ if (isset($_GET['yr']) && isset($_GET['month'])) {
1254
+ if ($month == $_GET['month']) {
1255
+ return ' selected="selected"';
1256
+ }
1257
+ } elseif ($month == $current_month) {
1258
+ return ' selected="selected"';
1259
+ }
1260
+ }
1261
+ function year_comparison($year) {
1262
+ $current_year = strtolower(date("Y", time()));
1263
+ if (isset($_GET['yr']) && isset($_GET['month'])) {
1264
+ if ($year == $_GET['yr']) {
1265
+ return ' selected="selected"';
1266
+ }
1267
+ } else if ($year == $current_year) {
1268
+ return ' selected="selected"';
1269
+ }
1270
+ }
1271
+ function build_date_switcher() {
1272
+ $my_calendar_body = "";
1273
+ $my_calendar_body .= '<div class="my-calendar-date-switcher">
1274
+ <form method="get" action=""><div>';
1275
+ $qsa = array();
1276
+ parse_str($_SERVER['QUERY_STRING'],$qsa);
1277
+ foreach ($qsa as $name => $argument) {
1278
+ if ($name != 'month' && $name != 'yr') {
1279
+ $my_calendar_body .= '<input type="hidden" name="'.$name.'" value="'.$argument.'" />';
1280
+ }
1281
+ }
1282
+ // We build the months in the switcher
1283
+ $my_calendar_body .= '
1284
+ <label for="my-calendar-month">'.__('Month','my-calendar').':</label> <select id="my-calendar-month" name="month" style="width:100px;">
1285
+ <option value="jan"'.month_comparison('jan').'>'.__('January','my-calendar').'</option>
1286
+ <option value="feb"'.month_comparison('feb').'>'.__('February','my-calendar').'</option>
1287
+ <option value="mar"'.month_comparison('mar').'>'.__('March','my-calendar').'</option>
1288
+ <option value="apr"'.month_comparison('apr').'>'.__('April','my-calendar').'</option>
1289
+ <option value="may"'.month_comparison('may').'>'.__('May','my-calendar').'</option>
1290
+ <option value="jun"'.month_comparison('jun').'>'.__('June','my-calendar').'</option>
1291
+ <option value="jul"'.month_comparison('jul').'>'.__('July','my-calendar').'</option>
1292
+ <option value="aug"'.month_comparison('aug').'>'.__('August','my-calendar').'</option>
1293
+ <option value="sept"'.month_comparison('sept').'>'.__('September','my-calendar').'</option>
1294
+ <option value="oct"'.month_comparison('oct').'>'.__('October','my-calendar').'</option>
1295
+ <option value="nov"'.month_comparison('nov').'>'.__('November','my-calendar').'</option>
1296
+ <option value="dec"'.month_comparison('dec').'>'.__('December','my-calendar').'</option>
1297
+ </select>
1298
+ <label for="my-calendar-year">'.__('Year','my-calendar').':</label> <select id="my-calendar-year" name="yr">
1299
+ ';
1300
+ // The year builder is string mania. If you can make sense of this, you know your PHP!
1301
+ $past = 2;
1302
+ $future = 2;
1303
+ $fut = 1;
1304
+ while ($past > 0) {
1305
+ $p .= ' <option value="';
1306
+ $p .= date("Y",time())-$past;
1307
+ $p .= '"'.year_comparison(date("Y",time())-$past).'>';
1308
+ $p .= date("Y",time())-$past."</option>\n";
1309
+ $past = $past - 1;
1310
+ }
1311
+ while ($fut < $future) {
1312
+ $f .= ' <option value="';
1313
+ $f .= date("Y",time())+$fut;
1314
+ $f .= '"'.year_comparison(date("Y",time())+$fut).'>';
1315
+ $f .= date("Y",time())+$fut."</option>\n";
1316
+ $fut = $fut + 1;
1317
+ }
1318
+ $my_calendar_body .= $p;
1319
+ $my_calendar_body .= '<option value="'.date("Y",time()).'"'.year_comparison(date("Y",time())).'>'.date("Y",time())."</option>\n";
1320
+ $my_calendar_body .= $f;
1321
+ $my_calendar_body .= '</select> <input type="submit" value="'.__('Go','my-calendar').'" /></div>
1322
+ </form></div>';
1323
+ return $my_calendar_body;
1324
+ }
1325
+
1326
+ // Actually do the printing of the calendar
1327
+ // Compared to searching for and displaying events
1328
+ // this bit is really rather easy!
1329
+ function my_calendar($name,$format,$category,$showkey) {
1330
+ global $wpdb;
1331
+ if ($category == "") {
1332
+ $category=null;
1333
+ }
1334
+ // First things first, make sure calendar is up to date
1335
+ check_calendar();
1336
+
1337
+ // Deal with the week not starting on a monday
1338
+ if (get_option('start_of_week') == 0) {
1339
+ $name_days = array(1=>__('<abbr title="Sunday">Sun</abbr>','my-calendar'),__('<abbr title="Monday">Mon</abbr>','my-calendar'),__('<abbr title="Tuesday">Tues</abbr>','my-calendar'),__('<abbr title="Wednesday">Wed</abbr>','my-calendar'),__('<abbr title="Thursday">Thur</abbr>','my-calendar'),__('<abbr title="Friday">Fri</abbr>','my-calendar'),__('<abbr title="Saturday">Sat</abbr>','my-calendar'));
1340
+ } else {
1341
+ // Choose Monday if anything other than Sunday is set
1342
+ $name_days = array(1=>__('<abbr title="Monday">Mon</abbr>','my-calendar'),__('<abbr title="Tuesday">Tues</abbr>','my-calendar'),__('<abbr title="Wednesday">Wed</abbr>','my-calendar'),__('<abbr title="Thursday">Thur</abbr>','my-calendar'),__('<abbr title="Friday">Fri</abbr>','my-calendar'),__('<abbr title="Saturday">Sat</abbr>','my-calendar'),__('<abbr title="Sunday">Sun</abbr>','my-calendar'));
1343
+ }
1344
+
1345
+ // Carry on with the script
1346
+ $name_months = array(1=>__('January','my-calendar'),__('February','my-calendar'),__('March','my-calendar'),__('April','my-calendar'),__('May','my-calendar'),__('June','my-calendar'),__('July','my-calendar'),__('August','my-calendar'),__('September','my-calendar'),__('October','my-calendar'),__('November','my-calendar'),__('December','my-calendar'));
1347
+
1348
+ // If we don't pass arguments we want a calendar that is relevant to today
1349
+ if (empty($_GET['month']) || empty($_GET['yr'])) {
1350
+ $c_year = date("Y");
1351
+ $c_month = date("m");
1352
+ $c_day = date("d");
1353
+ }
1354
+
1355
+ // Years get funny if we exceed 3000, so we use this check
1356
+ if ($_GET['yr'] <= 3000 && $_GET['yr'] >= 0) {
1357
+ // This is just plain nasty and all because of permalinks
1358
+ // which are no longer used, this will be cleaned up soon
1359
+ if ($_GET['month'] == 'jan' || $_GET['month'] == 'feb' || $_GET['month'] == 'mar' || $_GET['month'] == 'apr' || $_GET['month'] == 'may' || $_GET['month'] == 'jun' || $_GET['month'] == 'jul' || $_GET['month'] == 'aug' || $_GET['month'] == 'sept' || $_GET['month'] == 'oct' || $_GET['month'] == 'nov' || $_GET['month'] == 'dec') {
1360
+ // Again nasty code to map permalinks into something
1361
+ // databases can understand. This will be cleaned up
1362
+ $c_year = mysql_escape_string($_GET['yr']);
1363
+ if ($_GET['month'] == 'jan') { $t_month = 1; }
1364
+ else if ($_GET['month'] == 'feb') { $t_month = 2; }
1365
+ else if ($_GET['month'] == 'mar') { $t_month = 3; }
1366
+ else if ($_GET['month'] == 'apr') { $t_month = 4; }
1367
+ else if ($_GET['month'] == 'may') { $t_month = 5; }
1368
+ else if ($_GET['month'] == 'jun') { $t_month = 6; }
1369
+ else if ($_GET['month'] == 'jul') { $t_month = 7; }
1370
+ else if ($_GET['month'] == 'aug') { $t_month = 8; }
1371
+ else if ($_GET['month'] == 'sept') { $t_month = 9; }
1372
+ else if ($_GET['month'] == 'oct') { $t_month = 10; }
1373
+ else if ($_GET['month'] == 'nov') { $t_month = 11; }
1374
+ else if ($_GET['month'] == 'dec') { $t_month = 12; }
1375
+ $c_month = $t_month;
1376
+ $c_day = date("d");
1377
+ } else {
1378
+ // No valid month causes the calendar to default to today
1379
+ $c_year = date("Y");
1380
+ $c_month = date("m");
1381
+ $c_day = date("d");
1382
+ }
1383
+ } else {
1384
+ // No valid year causes the calendar to default to today
1385
+ $c_year = date("Y");
1386
+ $c_month = date("m");
1387
+ $c_day = date("d");
1388
+ }
1389
+
1390
+ // Fix the days of the week if week start is not on a monday
1391
+ if (get_option('start_of_week') == 0) {
1392
+ $first_weekday = date("w",mktime(0,0,0,$c_month,1,$c_year));
1393
+ $first_weekday = ($first_weekday==0?1:$first_weekday+1);
1394
+ } else {
1395
+ $first_weekday = date("w",mktime(0,0,0,$c_month,1,$c_year));
1396
+ $first_weekday = ($first_weekday==0?7:$first_weekday);
1397
+ }
1398
+
1399
+ $days_in_month = date("t", mktime (0,0,0,$c_month,1,$c_year));
1400
+ if ($category != "" && $category != "all") {
1401
+ $category_label = $category . ' ';
1402
+ } else {
1403
+ $category_label = "";
1404
+ }
1405
+ // Start the calendar and add header and navigation
1406
+ $my_calendar_body .= "<div id=\"jd-calendar\">";
1407
+ // Add the calendar table and heading
1408
+ if ($format == "calendar") {
1409
+ $my_calendar_body .= '<div class="my-calendar-header">';
1410
+
1411
+ // We want to know if we should display the date switcher
1412
+ $date_switcher = get_option('display_jump');
1413
+
1414
+ if ($date_switcher == 'true') {
1415
+ $my_calendar_body .= build_date_switcher();
1416
+ }
1417
+
1418
+ // The header of the calendar table and the links. Note calls to link functions
1419
+ $my_calendar_body .= '
1420
+ <div class="my-calendar-nav">
1421
+ <ul>
1422
+ <li class="my-calendar-prev">' . prev_link($c_year,$c_month) . '</li>
1423
+ <li class="my-calendar-next">' . next_link($c_year,$c_month) . '</li>
1424
+ </ul>
1425
+ </div>
1426
+ </div>';
1427
+ $my_calendar_body .= "\n<table class=\"my-calendar-table\" summary=\"$category_label".__('Calendar','my-calendar')."\">\n";
1428
+ $my_calendar_body .= '<caption class="my-calendar-month">'.$name_months[(int)$c_month].' '.$c_year."</caption>\n";
1429
+ } else {
1430
+ $my_calendar_body .= "\n<h2 class=\"my-calendar-header\">$category_label".__('Calendar','my-calendar')."</h2>\n";
1431
+
1432
+ $num_months = get_option('my_calendar_show_months');
1433
+ if ($num_months <= 1) {
1434
+ $my_calendar_body .= '<h3 class="my-calendar-month">'.__('Events in','my-calendar').' '.$name_months[(int)$c_month].' '.$c_year."</h3>\n";
1435
+ } else {
1436
+ $my_calendar_body .= '<h3 class="my-calendar-month">'.$name_months[(int)$c_month].'&thinsp;&ndash;&thinsp;'.$name_months[(int)$c_month+$num_months-1].' '.$c_year."</h3>\n";
1437
+ }
1438
+ $my_calendar_body .= '<div class="my-calendar-header">';
1439
+
1440
+ // We want to know if we should display the date switcher
1441
+ $date_switcher = get_option('display_jump');
1442
+
1443
+ if ($date_switcher == 'true') {
1444
+ $my_calendar_body .= build_date_switcher();
1445
+ }
1446
+
1447
+ // The header of the calendar table and the links. Note calls to link functions
1448
+ $my_calendar_body .= '
1449
+ <div class="my-calendar-nav">
1450
+ <ul>
1451
+ <li class="my-calendar-prev">' . prev_link($c_year,$c_month) . '</li>
1452
+ <li class="my-calendar-next">' . next_link($c_year,$c_month) . '</li>
1453
+ </ul>
1454
+ </div>
1455
+ </div>';
1456
+ }
1457
+ // If in calendar format, print the headings of the days of the week
1458
+ //$my_calendar_body .= "$format, $category, $name";
1459
+ if ($format == "calendar") {
1460
+ $my_calendar_body .= "<thead>\n<tr>\n";
1461
+ for ($i=1; $i<=7; $i++) {
1462
+ // Colors need to be different if the starting day of the week is different
1463
+
1464
+ if (get_option('start_of_week') == 0) {
1465
+ $my_calendar_body .= '<th scope="col" class="'.($i<7&&$i>1?'day-heading':'weekend-heading').'">'.$name_days[$i]."</th>\n";
1466
+ } else {
1467
+ $my_calendar_body .= '<th scope="col" class="'.($i<6?'day-heading':'weekend-heading').'">'.$name_days[$i]."</th>\n";
1468
+ }
1469
+ }
1470
+ $my_calendar_body .= "</tr>\n</thead>\n<tbody>";
1471
+
1472
+ for ($i=1; $i<=$days_in_month;) {
1473
+ $my_calendar_body .= '<tr>';
1474
+ for ($ii=1; $ii<=7; $ii++) {
1475
+ if ($ii==$first_weekday && $i==1) {
1476
+ $go = TRUE;
1477
+ } elseif ($i > $days_in_month ) {
1478
+ $go = FALSE;
1479
+ }
1480
+
1481
+ if ($go) {
1482
+ // Colors again, this time for the day numbers
1483
+ if (get_option('start_of_week') == 0) {
1484
+ // This bit of code is for styles believe it or not.
1485
+ $grabbed_events = grab_events($c_year,$c_month,$i,$category);
1486
+ $no_events_class = '';
1487
+ if (!count($grabbed_events)) {
1488
+ $no_events_class = ' no-events';
1489
+ }
1490
+ $my_calendar_body .= '<td class="'.(date("Ymd", mktime (0,0,0,$c_month,$i,$c_year))==date("Ymd")?'current-day':'day-with-date').$no_events_class.'">'."\n ".'<span'.($ii<7&&$ii>1?'':' class="weekend"').'>'.$i++.'</span>'."\n ". draw_events($grabbed_events, $format) . "\n</td>\n";
1491
+ } else {
1492
+ $grabbed_events = grab_events($c_year,$c_month,$i,$category);
1493
+ $no_events_class = '';
1494
+ if (!count($grabbed_events))
1495
+ {
1496
+ $no_events_class = ' no-events';
1497
+ }
1498
+ $my_calendar_body .= '<td class="'.(date("Ymd", mktime (0,0,0,$c_month,$i,$c_year))==date("Ymd")?'current-day':'day-with-date').$no_events_class.'">'."\n ".'<span'.($ii<6?'':' class="weekend"').'>'.$i++.'</span>'."\n ". draw_events($grabbed_events, $format) . "\n</td>\n";
1499
+ }
1500
+ } else {
1501
+ $my_calendar_body .= "<td class='day-without-date'>&nbsp;</td>\n";
1502
+ }
1503
+ }
1504
+ $my_calendar_body .= "</tr>";
1505
+ }
1506
+ $my_calendar_body .= "\n</tbody>\n</table>";
1507
+ } else if ($format == "list") {
1508
+ $my_calendar_body .= "<ul id=\"calendar-list\">";
1509
+ // show calendar as list
1510
+ $date_format = get_option('my_calendar_date_format');
1511
+ if ($date_format == "") {
1512
+ $date_format = "l, F j, Y";
1513
+ }
1514
+ $num_months = get_option('my_calendar_show_months');
1515
+ $num_events = 0;
1516
+ for ($m=0;$m<$num_months;$m++) {
1517
+ if ($m == 0) {
1518
+ $add_month = 0;
1519
+ } else {
1520
+ $add_month = 1;
1521
+ }
1522
+ $c_month = (int) $c_month + $add_month;
1523
+ for ($i=1; $i<=$days_in_month; $i++) {
1524
+ $grabbed_events = grab_events($c_year,$c_month,$i,$category);
1525
+ if (count($grabbed_events)) {
1526
+ if ( get_option('list_javascript') != 1) {
1527
+ $is_anchor = "<a href='#'>";
1528
+ $is_close_anchor = "</a>";
1529
+ } else {
1530
+ $is_anchor = $is_close_anchor = "";
1531
+ }
1532
+ $my_calendar_body .= "<li$class><strong class=\"event-date\">$is_anchor".date($date_format,mktime(0,0,0,$c_month,$i,$c_year))."$is_close_anchor</strong>".draw_events($grabbed_events, $format)."</li>";
1533
+ $num_events++;
1534
+ }
1535
+ if (is_odd($num_events)) {
1536
+ $class = " class='odd'";
1537
+ } else {
1538
+ $class = "";
1539
+ }
1540
+ }
1541
+ }
1542
+ if ($num_events == 0) {
1543
+ $my_calendar_body .= "<li class='no-events'>".__('There are no events scheduled during this period.','my-calendar') . "</li>";
1544
+ }
1545
+ $my_calendar_body .= "</ul>";
1546
+ } else {
1547
+ $my_calendar_body .= "Unrecognized calendar format.";
1548
+ }
1549
+ if ($showkey != 'no') {
1550
+ $sql = "SELECT * FROM " . MY_CALENDAR_CATEGORIES_TABLE . " ORDER BY category_name ASC";
1551
+ $cat_details = $wpdb->get_results($sql);
1552
+ $my_calendar_body .= '<div class="category-key">
1553
+ <h3>'.__('Category Key','my-calendar')."</h3>\n<ul>\n";
1554
+ foreach($cat_details as $cat_detail) {
1555
+ if ($cat_detail->category_icon != "") {
1556
+ $my_calendar_body .= '<li><span class="category-color-sample"><img src="'.WP_PLUGIN_URL.'/my-calendar/icons/'.$cat_detail->category_icon.'" alt="" style="background:'.$cat_detail->category_color.';" /></span>'.$cat_detail->category_name."</li>\n";
1557
+ } else {
1558
+ $my_calendar_body .= '<li><span class="category-color-sample" style="background:'.$cat_detail->category_color.';"> &nbsp; </span>'.$cat_detail->category_name."</li>\n";
1559
+ }
1560
+ }
1561
+ $my_calendar_body .= "</ul>\n</div>";
1562
+ }
1563
+ $my_calendar_body .= "\n</div>";
1564
+ // The actual printing is done by the shortcode function.
1565
+ return $my_calendar_body;
1566
+ }
1567
+
1568
+ function is_odd( $int ) {
1569
+ return( $int & 1 );
1570
+ }
1571
+
1572
+ ?>
my-calendar.pot ADDED
@@ -0,0 +1,861 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Translation of the WordPress plugin My Calendar 1.0.0 by Joseph C Dolson.
2
+ # Copyright (C) 2010 Joseph C Dolson
3
+ # This file is distributed under the same license as the My Calendar package.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
5
+ #
6
+ #, fuzzy
7
+ msgid ""
8
+ msgstr ""
9
+ "Project-Id-Version: My Calendar 1.0.0\n"
10
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/my-calendar\n"
11
+ "POT-Creation-Date: 2010-04-05 23:03+0000\n"
12
+ "PO-Revision-Date: 2010-MO-DA HO:MI+ZONE\n"
13
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
+ "Language-Team: LANGUAGE <LL@li.org>\n"
15
+ "MIME-Version: 1.0\n"
16
+ "Content-Type: text/plain; charset=utf-8\n"
17
+ "Content-Transfer-Encoding: 8bit\n"
18
+
19
+ #: my-calendar-categories.php:38
20
+ msgid "Category added successfully"
21
+ msgstr ""
22
+
23
+ #: my-calendar-categories.php:44
24
+ msgid "Category deleted successfully"
25
+ msgstr ""
26
+
27
+ #: my-calendar-categories.php:49 my-calendar-categories.php:61
28
+ msgid "Edit Category"
29
+ msgstr ""
30
+
31
+ #: my-calendar-categories.php:53
32
+ msgid "Category Editor"
33
+ msgstr ""
34
+
35
+ #: my-calendar-categories.php:62 my-calendar-categories.php:108
36
+ #: my-calendar-categories.php:139
37
+ msgid "Category Name"
38
+ msgstr ""
39
+
40
+ #: my-calendar-categories.php:63 my-calendar-categories.php:109
41
+ msgid "Category Color (Hex format)"
42
+ msgstr ""
43
+
44
+ #: my-calendar-categories.php:64 my-calendar-categories.php:110
45
+ #: my-calendar-categories.php:141
46
+ msgid "Category Icon"
47
+ msgstr ""
48
+
49
+ #: my-calendar-categories.php:79
50
+ msgid "Save Changes"
51
+ msgstr ""
52
+
53
+ #: my-calendar-categories.php:89
54
+ msgid "Category edited successfully"
55
+ msgstr ""
56
+
57
+ #: my-calendar-categories.php:95 my-calendar-categories.php:107
58
+ #: my-calendar-categories.php:120
59
+ msgid "Add Category"
60
+ msgstr ""
61
+
62
+ #: my-calendar-categories.php:99
63
+ msgid "Add New Category"
64
+ msgstr ""
65
+
66
+ #: my-calendar-categories.php:126 my-calendar.php:127
67
+ msgid "Manage Categories"
68
+ msgstr ""
69
+
70
+ #: my-calendar-categories.php:138 my-calendar-event-manager.php:592
71
+ msgid "ID"
72
+ msgstr ""
73
+
74
+ #: my-calendar-categories.php:140
75
+ msgid "Category Color"
76
+ msgstr ""
77
+
78
+ #: my-calendar-categories.php:142 my-calendar-categories.php:156
79
+ #: my-calendar-event-manager.php:640
80
+ msgid "Edit"
81
+ msgstr ""
82
+
83
+ #: my-calendar-categories.php:143 my-calendar-categories.php:162
84
+ #: my-calendar-event-manager.php:33 my-calendar-event-manager.php:640
85
+ msgid "Delete"
86
+ msgstr ""
87
+
88
+ #: my-calendar-categories.php:159 my-calendar-event-manager.php:628
89
+ #: my-calendar.php:796
90
+ msgid "N/A"
91
+ msgstr ""
92
+
93
+ #: my-calendar-categories.php:162
94
+ msgid "Are you sure you want to delete this category?"
95
+ msgstr ""
96
+
97
+ #: my-calendar-categories.php:173
98
+ msgid "There are no categories in the database - something has gone wrong!"
99
+ msgstr ""
100
+
101
+ #: my-calendar-event-manager.php:28
102
+ msgid "Delete Event"
103
+ msgstr ""
104
+
105
+ #: my-calendar-event-manager.php:28
106
+ msgid "Are you sure you want to delete this event?"
107
+ msgstr ""
108
+
109
+ #: my-calendar-event-manager.php:99 my-calendar-event-manager.php:104
110
+ #: my-calendar-event-manager.php:109 my-calendar-event-manager.php:119
111
+ #: my-calendar-event-manager.php:127 my-calendar-event-manager.php:135
112
+ #: my-calendar-event-manager.php:143 my-calendar-event-manager.php:174
113
+ #: my-calendar-event-manager.php:265 my-calendar-event-manager.php:270
114
+ #: my-calendar-event-manager.php:275 my-calendar-event-manager.php:285
115
+ #: my-calendar-event-manager.php:293 my-calendar-event-manager.php:301
116
+ #: my-calendar-event-manager.php:309 my-calendar-event-manager.php:374
117
+ #: my-calendar-event-manager.php:389
118
+ msgid "Error"
119
+ msgstr ""
120
+
121
+ #: my-calendar-event-manager.php:99 my-calendar-event-manager.php:265
122
+ msgid ""
123
+ "Your event end date must be either after or the same as your event begin date"
124
+ msgstr ""
125
+
126
+ #: my-calendar-event-manager.php:104 my-calendar-event-manager.php:270
127
+ msgid ""
128
+ "Your date formatting is correct but one or more of your dates is invalid. "
129
+ "Check for number of days in month and leap year related errors."
130
+ msgstr ""
131
+
132
+ #: my-calendar-event-manager.php:109 my-calendar-event-manager.php:275
133
+ msgid ""
134
+ "Both start and end dates must be entered and be in the format YYYY-MM-DD"
135
+ msgstr ""
136
+
137
+ #: my-calendar-event-manager.php:119 my-calendar-event-manager.php:285
138
+ msgid "The time field must either be blank or be entered in the format hh:mm"
139
+ msgstr ""
140
+
141
+ #: my-calendar-event-manager.php:127 my-calendar-event-manager.php:293
142
+ msgid ""
143
+ "The URL entered must either be prefixed with http:// or be completely blank"
144
+ msgstr ""
145
+
146
+ #: my-calendar-event-manager.php:135 my-calendar-event-manager.php:301
147
+ msgid ""
148
+ "The event title must be between 1 and 60 characters in length. Some "
149
+ "punctuation characters may not be allowed."
150
+ msgstr ""
151
+
152
+ #: my-calendar-event-manager.php:143 my-calendar-event-manager.php:309
153
+ msgid ""
154
+ "The repetition value must be 0 unless a type of recurrance is selected in "
155
+ "which case the repetition value must be 0 or higher"
156
+ msgstr ""
157
+
158
+ #: my-calendar-event-manager.php:174
159
+ msgid ""
160
+ "An event with the details you submitted could not be found in the database. "
161
+ "This may indicate a problem with your database or the way in which it is "
162
+ "configured."
163
+ msgstr ""
164
+
165
+ #: my-calendar-event-manager.php:178
166
+ msgid "Event added. It will now show in your calendar."
167
+ msgstr ""
168
+
169
+ #: my-calendar-event-manager.php:242 my-calendar-event-manager.php:341
170
+ msgid "Failure"
171
+ msgstr ""
172
+
173
+ #: my-calendar-event-manager.php:242
174
+ msgid "You can't update an event if you haven't submitted an event id"
175
+ msgstr ""
176
+
177
+ #: my-calendar-event-manager.php:341
178
+ msgid ""
179
+ "The database failed to return data to indicate the event has been updated "
180
+ "sucessfully. This may indicate a problem with your database or the way in "
181
+ "which it is configured."
182
+ msgstr ""
183
+
184
+ #: my-calendar-event-manager.php:345
185
+ msgid "Event updated successfully"
186
+ msgstr ""
187
+
188
+ #: my-calendar-event-manager.php:374
189
+ msgid "You can't delete an event if you haven't submitted an event id"
190
+ msgstr ""
191
+
192
+ #: my-calendar-event-manager.php:385
193
+ msgid "Event deleted successfully"
194
+ msgstr ""
195
+
196
+ #: my-calendar-event-manager.php:389
197
+ msgid ""
198
+ "Despite issuing a request to delete, the event still remains in the "
199
+ "database. Please investigate."
200
+ msgstr ""
201
+
202
+ #: my-calendar-event-manager.php:404 my-calendar-event-manager.php:458
203
+ msgid "Edit Event"
204
+ msgstr ""
205
+
206
+ #: my-calendar-event-manager.php:408
207
+ msgid "You must provide an event id in order to edit it"
208
+ msgstr ""
209
+
210
+ #: my-calendar-event-manager.php:414
211
+ msgid "Add Event"
212
+ msgstr ""
213
+
214
+ #: my-calendar-event-manager.php:419
215
+ msgid "Manage Events"
216
+ msgstr ""
217
+
218
+ #: my-calendar-event-manager.php:436
219
+ msgid "Sorry! That's an invalid event key."
220
+ msgstr ""
221
+
222
+ #: my-calendar-event-manager.php:441
223
+ msgid "Sorry! We couldn't find an event with that ID."
224
+ msgstr ""
225
+
226
+ #: my-calendar-event-manager.php:458
227
+ msgid "Add an Event"
228
+ msgstr ""
229
+
230
+ #: my-calendar-event-manager.php:466
231
+ msgid "Enter your Event Information"
232
+ msgstr ""
233
+
234
+ #: my-calendar-event-manager.php:468
235
+ msgid "Event Title"
236
+ msgstr ""
237
+
238
+ #: my-calendar-event-manager.php:471
239
+ msgid ""
240
+ "Event Description (<abbr title=\"hypertext markup language\">HTML</abbr> "
241
+ "allowed)"
242
+ msgstr ""
243
+
244
+ #: my-calendar-event-manager.php:474
245
+ msgid "Event Category"
246
+ msgstr ""
247
+
248
+ #: my-calendar-event-manager.php:493
249
+ msgid "Event Link (Optional)"
250
+ msgstr ""
251
+
252
+ #: my-calendar-event-manager.php:496
253
+ msgid "Start Date (YYYY-MM-DD)"
254
+ msgstr ""
255
+
256
+ #: my-calendar-event-manager.php:499
257
+ msgid "End Date (YYYY-MM-DD) (Optional)"
258
+ msgstr ""
259
+
260
+ #: my-calendar-event-manager.php:502
261
+ msgid "Time (hh:mm)"
262
+ msgstr ""
263
+
264
+ #: my-calendar-event-manager.php:513
265
+ msgid ""
266
+ "Optional, set blank if your event is an all-day event or does not happen at "
267
+ "a specific time."
268
+ msgstr ""
269
+
270
+ #: my-calendar-event-manager.php:513
271
+ msgid "Current time difference from GMT is "
272
+ msgstr ""
273
+
274
+ #: my-calendar-event-manager.php:513
275
+ msgid " hour(s)"
276
+ msgstr ""
277
+
278
+ #: my-calendar-event-manager.php:517
279
+ msgid "Recurring Events"
280
+ msgstr ""
281
+
282
+ #: my-calendar-event-manager.php:536
283
+ msgid "Repeats for"
284
+ msgstr ""
285
+
286
+ #: my-calendar-event-manager.php:537
287
+ msgid "Units"
288
+ msgstr ""
289
+
290
+ #: my-calendar-event-manager.php:544
291
+ msgid ""
292
+ "Entering 0 means forever, if a unit is selected. If the recurrance unit is "
293
+ "left at \"Does not recur,\" the event will not reoccur."
294
+ msgstr ""
295
+
296
+ #: my-calendar-event-manager.php:551
297
+ msgid ""
298
+ "All location fields are optional: <em>insufficient information may result in "
299
+ "an inaccurate map</em>."
300
+ msgstr ""
301
+
302
+ #: my-calendar-event-manager.php:554
303
+ msgid "Name of Location (e.g. <em>Joe's Bar and Grill</em>)"
304
+ msgstr ""
305
+
306
+ #: my-calendar-event-manager.php:557
307
+ msgid "Street Address"
308
+ msgstr ""
309
+
310
+ #: my-calendar-event-manager.php:560
311
+ msgid "Street Address (2)"
312
+ msgstr ""
313
+
314
+ #: my-calendar-event-manager.php:563
315
+ msgid "City"
316
+ msgstr ""
317
+
318
+ #: my-calendar-event-manager.php:563
319
+ msgid "State/Province"
320
+ msgstr ""
321
+
322
+ #: my-calendar-event-manager.php:563
323
+ msgid "Postal Code"
324
+ msgstr ""
325
+
326
+ #: my-calendar-event-manager.php:566
327
+ msgid "Country"
328
+ msgstr ""
329
+
330
+ #: my-calendar-event-manager.php:571
331
+ msgid "Save Event"
332
+ msgstr ""
333
+
334
+ #: my-calendar-event-manager.php:593 my-calendar-widgets.php:32
335
+ #: my-calendar-widgets.php:108
336
+ msgid "Title"
337
+ msgstr ""
338
+
339
+ #: my-calendar-event-manager.php:594
340
+ msgid "Description"
341
+ msgstr ""
342
+
343
+ #: my-calendar-event-manager.php:595
344
+ msgid "Start Date"
345
+ msgstr ""
346
+
347
+ #: my-calendar-event-manager.php:597
348
+ msgid "Recurs"
349
+ msgstr ""
350
+
351
+ #: my-calendar-event-manager.php:598
352
+ msgid "Repeats"
353
+ msgstr ""
354
+
355
+ #: my-calendar-event-manager.php:599 my-calendar-settings.php:107
356
+ msgid "Author"
357
+ msgstr ""
358
+
359
+ #: my-calendar-event-manager.php:600
360
+ msgid "Category"
361
+ msgstr ""
362
+
363
+ #: my-calendar-event-manager.php:601
364
+ msgid "Edit / Delete"
365
+ msgstr ""
366
+
367
+ #: my-calendar-event-manager.php:618
368
+ msgid "Never"
369
+ msgstr ""
370
+
371
+ #: my-calendar-event-manager.php:619
372
+ msgid "Daily"
373
+ msgstr ""
374
+
375
+ #: my-calendar-event-manager.php:620
376
+ msgid "Weekly"
377
+ msgstr ""
378
+
379
+ #: my-calendar-event-manager.php:621
380
+ msgid "Monthly"
381
+ msgstr ""
382
+
383
+ #: my-calendar-event-manager.php:622
384
+ msgid "Yearly"
385
+ msgstr ""
386
+
387
+ #: my-calendar-event-manager.php:629
388
+ msgid "Forever"
389
+ msgstr ""
390
+
391
+ #: my-calendar-event-manager.php:630
392
+ msgid "Times"
393
+ msgstr ""
394
+
395
+ #: my-calendar-event-manager.php:648
396
+ msgid "There are no events in the database!"
397
+ msgstr ""
398
+
399
+ #: my-calendar-help.php:6
400
+ msgid "How to use My Calendar"
401
+ msgstr ""
402
+
403
+ #: my-calendar-help.php:11
404
+ msgid "Shortcode Syntax"
405
+ msgstr ""
406
+
407
+ #: my-calendar-help.php:16
408
+ msgid ""
409
+ "This basic shortcode will show the calendar on a post or page including all "
410
+ "categories and the category key, in a traditional month-by-month format."
411
+ msgstr ""
412
+
413
+ #: my-calendar-help.php:19
414
+ msgid ""
415
+ "The shortcode supports three attributes, <code>category</code>, "
416
+ "<code>format</code> and <code>showkey</code>. There is currently only one "
417
+ "alternate option for <code>format</code> &mdash; <code>list</code> &mdash; "
418
+ "which will show the calendar in a list format, skipping dates without any "
419
+ "events. The <code>category</code> attribute requires either the name of or "
420
+ "ID number one of your event categories (the name is case-sensitive). This "
421
+ "will show a calendar only including events in that category. Setting "
422
+ "<code>showkey</code> to <code>no</code> will prevent the category key from "
423
+ "being displayed &mdash; this can be useful with single-category output."
424
+ msgstr ""
425
+
426
+ #: my-calendar-help.php:27
427
+ msgid "Category Icons"
428
+ msgstr ""
429
+
430
+ #: my-calendar-help.php:30
431
+ msgid ""
432
+ "My Calendar is designed to manage multiple calendars. The basis for these "
433
+ "calendars are categories; you can easily setup a calendar page which "
434
+ "includes all categories, or you can dedicate separate pages to calendars in "
435
+ "each category. For an example, this might be useful for you in managing the "
436
+ "tour calendars for multiple bands; event calendars for a variety of "
437
+ "locations, etc."
438
+ msgstr ""
439
+
440
+ #: my-calendar-help.php:33
441
+ msgid ""
442
+ "The pre-installed category icons may not be especially useful for your needs "
443
+ "or design. I'm assuming that you're going to upload your own icons -- all "
444
+ "you need to do is upload them to the plugin's icons folder, and they'll be "
445
+ "available for immediate use."
446
+ msgstr ""
447
+
448
+ #: my-calendar-help.php:33
449
+ msgid "Your icons folder is:"
450
+ msgstr ""
451
+
452
+ #: my-calendar-help.php:41
453
+ msgid "Widget Templating"
454
+ msgstr ""
455
+
456
+ #: my-calendar-help.php:44
457
+ msgid ""
458
+ "These codes are available in calendar widgets to create your own custom "
459
+ "calendar format."
460
+ msgstr ""
461
+
462
+ #: my-calendar-help.php:48
463
+ msgid "Displays the name of the category the event is in."
464
+ msgstr ""
465
+
466
+ #: my-calendar-help.php:51
467
+ msgid "Displays the title of the event."
468
+ msgstr ""
469
+
470
+ #: my-calendar-help.php:54
471
+ msgid "Displays the start time for the event."
472
+ msgstr ""
473
+
474
+ #: my-calendar-help.php:57
475
+ msgid "Displays the date on which the event begins."
476
+ msgstr ""
477
+
478
+ #: my-calendar-help.php:60
479
+ msgid "Displays the WordPress author who posted the event."
480
+ msgstr ""
481
+
482
+ #: my-calendar-help.php:63
483
+ msgid "Displays the URL provided for the event."
484
+ msgstr ""
485
+
486
+ #: my-calendar-help.php:66
487
+ msgid "Displays the description of the event."
488
+ msgstr ""
489
+
490
+ #: my-calendar-help.php:69
491
+ msgid ""
492
+ "Displays title of the event as a link if a URL is present, or the title "
493
+ "alone if no URL is available."
494
+ msgstr ""
495
+
496
+ #: my-calendar-help.php:72
497
+ msgid "Displays the name of the location of the event."
498
+ msgstr ""
499
+
500
+ #: my-calendar-help.php:75
501
+ msgid "Displays the first line of the site address."
502
+ msgstr ""
503
+
504
+ #: my-calendar-help.php:78
505
+ msgid "Displays the second line of the site address."
506
+ msgstr ""
507
+
508
+ #: my-calendar-help.php:81
509
+ msgid "Displays the city for the event."
510
+ msgstr ""
511
+
512
+ #: my-calendar-help.php:84
513
+ msgid "Displays the state for the event."
514
+ msgstr ""
515
+
516
+ #: my-calendar-help.php:87
517
+ msgid "Displays the postcode for the event."
518
+ msgstr ""
519
+
520
+ #: my-calendar-help.php:90
521
+ msgid "Displays the country for the event location."
522
+ msgstr ""
523
+
524
+ #: my-calendar-help.php:93
525
+ msgid ""
526
+ "Displays the event address in <a href=\"http://microformats.org/wiki/hcard"
527
+ "\">hcard</a> format."
528
+ msgstr ""
529
+
530
+ #: my-calendar-help.php:96
531
+ msgid ""
532
+ "Displays a link to a Google Map of the event, if sufficient address "
533
+ "information is available. If not, will be empty."
534
+ msgstr ""
535
+
536
+ #: my-calendar-settings.php:67
537
+ msgid "Settings saved"
538
+ msgstr ""
539
+
540
+ #: my-calendar-settings.php:94
541
+ msgid "My Calendar Options"
542
+ msgstr ""
543
+
544
+ #: my-calendar-settings.php:98
545
+ msgid "Calendar Settings"
546
+ msgstr ""
547
+
548
+ #: my-calendar-settings.php:102
549
+ msgid "Primary Calendar Options"
550
+ msgstr ""
551
+
552
+ #: my-calendar-settings.php:104
553
+ msgid "Choose the lowest user group that may manage events"
554
+ msgstr ""
555
+
556
+ #: my-calendar-settings.php:105
557
+ msgid "Subscriber"
558
+ msgstr ""
559
+
560
+ #: my-calendar-settings.php:106
561
+ msgid "Contributor"
562
+ msgstr ""
563
+
564
+ #: my-calendar-settings.php:108
565
+ msgid "Editor"
566
+ msgstr ""
567
+
568
+ #: my-calendar-settings.php:109
569
+ msgid "Administrator"
570
+ msgstr ""
571
+
572
+ #: my-calendar-settings.php:113
573
+ msgid "Do you want to display the author name on events?"
574
+ msgstr ""
575
+
576
+ #: my-calendar-settings.php:114 my-calendar-settings.php:120
577
+ msgid "Yes"
578
+ msgstr ""
579
+
580
+ #: my-calendar-settings.php:115 my-calendar-settings.php:121
581
+ msgid "No"
582
+ msgstr ""
583
+
584
+ #: my-calendar-settings.php:119
585
+ msgid "Display a jumpbox for changing month and year quickly?"
586
+ msgstr ""
587
+
588
+ #: my-calendar-settings.php:125
589
+ msgid "In list mode, show how many months of events at a time:"
590
+ msgstr ""
591
+
592
+ #: my-calendar-settings.php:128
593
+ msgid "Date format in list mode"
594
+ msgstr ""
595
+
596
+ #: my-calendar-settings.php:129
597
+ msgid ""
598
+ "Date format uses the same syntax as the <a href=\"http://php.net/date\">PHP "
599
+ "<code>date()</code> function</a>. Save option to update sample output."
600
+ msgstr ""
601
+
602
+ #: my-calendar-settings.php:132
603
+ msgid ""
604
+ "Show Link to Google Map (when sufficient address information is available.)"
605
+ msgstr ""
606
+
607
+ #: my-calendar-settings.php:133
608
+ msgid "Show Event Address in Details"
609
+ msgstr ""
610
+
611
+ #: my-calendar-settings.php:137
612
+ msgid "Calendar Styles"
613
+ msgstr ""
614
+
615
+ #: my-calendar-settings.php:139
616
+ msgid "Reset the My Calendar style to default"
617
+ msgstr ""
618
+
619
+ #: my-calendar-settings.php:140
620
+ msgid "Disable My Calendar Stylesheet"
621
+ msgstr ""
622
+
623
+ #: my-calendar-settings.php:143
624
+ msgid "Edit the stylesheet for My Calendar"
625
+ msgstr ""
626
+
627
+ #: my-calendar-settings.php:147
628
+ msgid "Calendar Behaviors"
629
+ msgstr ""
630
+
631
+ #: my-calendar-settings.php:149
632
+ msgid "Disable List Javascript Effects"
633
+ msgstr ""
634
+
635
+ #: my-calendar-settings.php:150
636
+ msgid "Disable Calendar Javascript Effects"
637
+ msgstr ""
638
+
639
+ #: my-calendar-settings.php:153
640
+ msgid "Save"
641
+ msgstr ""
642
+
643
+ #: my-calendar-widgets.php:11 my-calendar-widgets.php:42
644
+ #: my-calendar-widgets.php:43
645
+ msgid "Today's Events"
646
+ msgstr ""
647
+
648
+ #: my-calendar-widgets.php:36 my-calendar-widgets.php:112
649
+ msgid "Template"
650
+ msgstr ""
651
+
652
+ #: my-calendar-widgets.php:56 my-calendar-widgets.php:135
653
+ #: my-calendar-widgets.php:136
654
+ msgid "Upcoming Events"
655
+ msgstr ""
656
+
657
+ #: my-calendar-widgets.php:116
658
+ msgid "Widget Options"
659
+ msgstr ""
660
+
661
+ #: my-calendar-widgets.php:118
662
+ msgid "Display upcoming events by:"
663
+ msgstr ""
664
+
665
+ #: my-calendar-widgets.php:119
666
+ msgid "Events (e.g. 2 past, 3 future)"
667
+ msgstr ""
668
+
669
+ #: my-calendar-widgets.php:120
670
+ msgid "Dates (e.g. 4 days past, 5 forward)"
671
+ msgstr ""
672
+
673
+ #: my-calendar-widgets.php:124
674
+ msgid "events into the future;"
675
+ msgstr ""
676
+
677
+ #: my-calendar-widgets.php:125
678
+ msgid "events from the past"
679
+ msgstr ""
680
+
681
+ #: my-calendar-widgets.php:128
682
+ msgid "days into the future;"
683
+ msgstr ""
684
+
685
+ #: my-calendar-widgets.php:129
686
+ msgid "days from the past"
687
+ msgstr ""
688
+
689
+ #: my-calendar.php:46 my-calendar.php:128
690
+ msgid "Settings"
691
+ msgstr ""
692
+
693
+ #: my-calendar.php:65
694
+ msgid "Get Support"
695
+ msgstr ""
696
+
697
+ #: my-calendar.php:66
698
+ msgid "Make a Donation"
699
+ msgstr ""
700
+
701
+ #. #-#-#-#-# plugin.pot (My Calendar 1.0.0) #-#-#-#-#
702
+ #. Plugin Name of the plugin/theme
703
+ #: my-calendar.php:120
704
+ msgid "My Calendar"
705
+ msgstr ""
706
+
707
+ #: my-calendar.php:123
708
+ msgid "Add/Edit Events"
709
+ msgstr ""
710
+
711
+ #: my-calendar.php:129
712
+ msgid "My Calendar Help"
713
+ msgstr ""
714
+
715
+ #: my-calendar.php:129
716
+ msgid "Help"
717
+ msgstr ""
718
+
719
+ #: my-calendar.php:662 my-calendar.php:666 my-calendar.php:676
720
+ #: my-calendar.php:678
721
+ msgid "Next Events"
722
+ msgstr ""
723
+
724
+ #: my-calendar.php:691 my-calendar.php:695 my-calendar.php:705
725
+ #: my-calendar.php:707
726
+ msgid "Previous Events"
727
+ msgstr ""
728
+
729
+ #: my-calendar.php:790
730
+ msgid "Event Details"
731
+ msgstr ""
732
+
733
+ #: my-calendar.php:796
734
+ msgid "Not Applicable"
735
+ msgstr ""
736
+
737
+ #: my-calendar.php:804
738
+ msgid "Posted by"
739
+ msgstr ""
740
+
741
+ #: my-calendar.php:1284
742
+ msgid "Month"
743
+ msgstr ""
744
+
745
+ #: my-calendar.php:1285 my-calendar.php:1346
746
+ msgid "January"
747
+ msgstr ""
748
+
749
+ #: my-calendar.php:1286 my-calendar.php:1346
750
+ msgid "February"
751
+ msgstr ""
752
+
753
+ #: my-calendar.php:1287 my-calendar.php:1346
754
+ msgid "March"
755
+ msgstr ""
756
+
757
+ #: my-calendar.php:1288 my-calendar.php:1346
758
+ msgid "April"
759
+ msgstr ""
760
+
761
+ #: my-calendar.php:1289 my-calendar.php:1346
762
+ msgid "May"
763
+ msgstr ""
764
+
765
+ #: my-calendar.php:1290 my-calendar.php:1346
766
+ msgid "June"
767
+ msgstr ""
768
+
769
+ #: my-calendar.php:1291 my-calendar.php:1346
770
+ msgid "July"
771
+ msgstr ""
772
+
773
+ #: my-calendar.php:1292 my-calendar.php:1346
774
+ msgid "August"
775
+ msgstr ""
776
+
777
+ #: my-calendar.php:1293 my-calendar.php:1346
778
+ msgid "September"
779
+ msgstr ""
780
+
781
+ #: my-calendar.php:1294 my-calendar.php:1346
782
+ msgid "October"
783
+ msgstr ""
784
+
785
+ #: my-calendar.php:1295 my-calendar.php:1346
786
+ msgid "November"
787
+ msgstr ""
788
+
789
+ #: my-calendar.php:1296 my-calendar.php:1346
790
+ msgid "December"
791
+ msgstr ""
792
+
793
+ #: my-calendar.php:1298
794
+ msgid "Year"
795
+ msgstr ""
796
+
797
+ #: my-calendar.php:1321
798
+ msgid "Go"
799
+ msgstr ""
800
+
801
+ #: my-calendar.php:1339 my-calendar.php:1342
802
+ msgid "<abbr title=\"Sunday\">Sun</abbr>"
803
+ msgstr ""
804
+
805
+ #: my-calendar.php:1339 my-calendar.php:1342
806
+ msgid "<abbr title=\"Monday\">Mon</abbr>"
807
+ msgstr ""
808
+
809
+ #: my-calendar.php:1339 my-calendar.php:1342
810
+ msgid "<abbr title=\"Tuesday\">Tues</abbr>"
811
+ msgstr ""
812
+
813
+ #: my-calendar.php:1339 my-calendar.php:1342
814
+ msgid "<abbr title=\"Wednesday\">Wed</abbr>"
815
+ msgstr ""
816
+
817
+ #: my-calendar.php:1339 my-calendar.php:1342
818
+ msgid "<abbr title=\"Thursday\">Thur</abbr>"
819
+ msgstr ""
820
+
821
+ #: my-calendar.php:1339 my-calendar.php:1342
822
+ msgid "<abbr title=\"Friday\">Fri</abbr>"
823
+ msgstr ""
824
+
825
+ #: my-calendar.php:1339 my-calendar.php:1342
826
+ msgid "<abbr title=\"Saturday\">Sat</abbr>"
827
+ msgstr ""
828
+
829
+ #: my-calendar.php:1427 my-calendar.php:1430
830
+ msgid "Calendar"
831
+ msgstr ""
832
+
833
+ #: my-calendar.php:1434
834
+ msgid "Events in"
835
+ msgstr ""
836
+
837
+ #: my-calendar.php:1543
838
+ msgid "There are no events scheduled during this period."
839
+ msgstr ""
840
+
841
+ #: my-calendar.php:1553
842
+ msgid "Category Key"
843
+ msgstr ""
844
+
845
+ #. Plugin URI of the plugin/theme
846
+ msgid "http://www.joedolson.com/articles/my-calendar/"
847
+ msgstr ""
848
+
849
+ #. Description of the plugin/theme
850
+ msgid ""
851
+ "Accessible WordPress event calendar plugin. Show events from multiple "
852
+ "calendars on pages, in posts, or in widgets."
853
+ msgstr ""
854
+
855
+ #. Author of the plugin/theme
856
+ msgid "Joseph C Dolson"
857
+ msgstr ""
858
+
859
+ #. Author URI of the plugin/theme
860
+ msgid "http://www.joedolson.com"
861
+ msgstr ""
readme.txt ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === My Calendar ===
2
+ Contributors: joedolson
3
+ Donate link: http://www.joedolson.com/donate.php
4
+ Tags: calendar, dates, times, events, scheduling
5
+ Requires at least: 2.7
6
+ Tested up to: 2.9.2
7
+ Stable tag: trunk
8
+
9
+ Accessible WordPress event calendar plugin. Show events from multiple calendars on pages, in posts, or in widgets.
10
+
11
+ == Description ==
12
+
13
+ This calendar is branched from [Kieran O'Shea's Calendar plugin](http://wordpress.org/extend/plugins/calendar/). The output has been pretty much completely re-written, the settings methods have been revamped, and the widgets have been completely revamped. The information you can provide for an event has been expanded to include location information. The UI has been completely revamped.
14
+
15
+ In short, there isn't actually much left of the original plugin.
16
+
17
+ Features:
18
+
19
+ * Monthly view of events
20
+ * List view of events; multiple months can be viewed at once.
21
+ * Events can have a timestamp (optional)
22
+ * Events can display their author (optional)
23
+ * Events can span more than one day
24
+ * Events can include location information
25
+ * Event listings can show address and/or a link to a Google Map with the address
26
+ * Locations can be shown in [hCard format](http://microformats.org/wiki/hcard).
27
+ * Multiple events per day possible
28
+ * Events can repeat on a daily, weekly, monthly or yearly basis
29
+ * Repeats can occur indefinitely or a limited number of times
30
+ * Easy to use events manager
31
+ * Widget to show today's events
32
+ * Highly configurable widget to show upcoming events
33
+ * Widget templating to control what information is displayed in widget output.
34
+ * Extensive settings panel for administration
35
+ * Edit or disable default CSS from the settings page
36
+ * Optional drop down boxes to quickly change month and year
37
+ * User groups other than admin can be permitted to manage events
38
+ * Events can be placed into categories
39
+ * A calendar of events can be displayed including a single category or all categories
40
+ * Events can be links pointing to a location of your choice
41
+
42
+ == Installation ==
43
+
44
+ 1. Upload the `/my-calendar/` directory into your WordPress plugins directory.
45
+
46
+ 2. Activate the plugin on your WordPress plugins page
47
+
48
+ 3. Configure My Calendar using the following pages in the admin panel:
49
+
50
+ My Calendar -> Manage Events
51
+
52
+ My Calendar -> Manage Categories
53
+
54
+ My Calendar -> Calendar Options
55
+
56
+ 5. Edit or create a page on your blog which includes the shortcode [my_calendar] and visit
57
+ the page you have edited or created. You should see your calendar. Visit My Calendar -> Help for assistance
58
+ with shortcode options or widget configuration.
59
+
60
+ == Changelog ==
61
+
62
+ = 1.0.0 =
63
+
64
+ * Initial launch.
65
+
66
+ == Frequently Asked Questions ==
67
+
68
+ = This looks terrible with my template! You suck! =
69
+
70
+ Hey, give me a break. I'm only going to release this with one default CSS - it works pretty well with Kubrick or Twenty Ten, and should be usable in many other themes. However, I'm not about to make any guarantees that it'll work with your theme. If you want it to look a particular way, you'll need to do some customization.
71
+
72
+ == Screenshots ==
73
+
74
+ 1. Calendar using calendar list format.
75
+ 2. Calendar using monthly calendar format.
76
+ 3. Event management page
77
+ 4. Category management page
78
+ 5. Settings page
79
+
80
+ == Upgrade Notice ==
screenshot-1.png ADDED
Binary file
screenshot-2.png ADDED
Binary file
screenshot-3.png ADDED
Binary file
screenshot-4.png ADDED
Binary file
screenshot-5.png ADDED
Binary file
uninstall.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !defined( 'ABSPATH' ) && !defined( 'WP_UNINSTALL_PLUGIN' ) ) {
3
+ exit();
4
+ } else {
5
+ delete_option('can_manage_events');
6
+ delete_option('my_calendar_style');
7
+ delete_option('display_author');
8
+ delete_option('display_jump');
9
+ delete_option('display_todays');
10
+ delete_option('display_upcoming');
11
+ delete_option('display_upcoming_days');
12
+ delete_option('my_calendar_version');
13
+ delete_option('display_upcoming_type');
14
+ delete_option('display_upcoming_events');
15
+ delete_option('display_past_days');
16
+ delete_option('display_past_events');
17
+ delete_option('my_calendar_use_styles');
18
+ delete_option('my_calendar_show_months');
19
+ delete_option('my_calendar_show_map');
20
+ delete_option('my_calendar_show_address');
21
+ delete_option('my_calendar_today_template');
22
+ delete_option('my_calendar_upcoming_template');
23
+ delete_option('my_calendar_today_title');
24
+ delete_option('my_calendar_upcoming_title');
25
+ // Widget options
26
+ delete_option('my_calendar_today_title');
27
+ delete_option('my_calendar_today_template');
28
+ delete_option('my_calendar_upcoming_title');
29
+ delete_option('my_calendar_upcoming_template');
30
+ delete_option('display_upcoming_type');
31
+ delete_option('display_upcoming_days');
32
+ delete_option('display_upcoming_events');
33
+ delete_option('display_past_events');
34
+ delete_option('display_past_days');
35
+
36
+ }
37
+ ?>