123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752 |
- <?php
- ?>
- <?php
-
- class BaseRecurrence {
-
- var $store;
-
-
- var $message;
-
-
- var $messageprops;
-
- var $proptags;
-
- var $recur;
-
- var $tz;
-
- function __construct($store, $message)
- {
- $this->store = $store;
- if(is_array($message)) {
- $this->messageprops = $message;
- } else {
- $this->message = $message;
- $this->messageprops = mapi_getprops($this->message, $this->proptags);
- }
- if(isset($this->messageprops[$this->proptags["recurring_data"]])) {
-
- if (strlen($this->messageprops[$this->proptags["recurring_data"]]) >= 255)
- $this->getFullRecurrenceBlob();
- $this->recur = $this->parseRecurrence($this->messageprops[$this->proptags["recurring_data"]]);
- }
- if (isset($this->proptags["timezone_data"]) && isset($this->messageprops[$this->proptags["timezone_data"]]))
- $this->tz = $this->parseTimezone($this->messageprops[$this->proptags["timezone_data"]]);
- }
- function getRecurrence()
- {
- return $this->recur;
- }
- function getFullRecurrenceBlob()
- {
- $message = mapi_msgstore_openentry($this->store, $this->messageprops[PR_ENTRYID]);
- $recurrBlob = '';
- $stream = mapi_openproperty($message, $this->proptags["recurring_data"], IID_IStream, 0, 0);
- $stat = mapi_stream_stat($stream);
- for ($i = 0; $i < $stat['cb']; $i += 1024)
- $recurrBlob .= mapi_stream_read($stream, 1024);
- if (!empty($recurrBlob))
- $this->messageprops[$this->proptags["recurring_data"]] = $recurrBlob;
- }
-
- function parseRecurrence($rdata)
- {
- if (strlen($rdata) < 10)
- return;
-
- $ret["changed_occurences"] = array();
- $ret["deleted_occurences"] = array();
-
- $data = unpack("Vconst1/Crtype/Cconst2/Vrtype2", $rdata);
-
- $ret["type"] = $data["rtype"];
- $ret["subtype"] = $data["rtype2"];
- $rdata = substr($rdata, 10);
-
- switch ($data["rtype"])
- {
- case 0x0a:
-
- if (strlen($rdata) < 12)
- return $ret;
- $data = unpack("Vunknown/Veveryn/Vregen", $rdata);
- $ret["everyn"] = $data["everyn"];
- $ret["regen"] = $data["regen"];
- switch ($ret["subtype"])
- {
- case 0:
- $rdata = substr($rdata, 12);
- break;
- case 1:
- $rdata = substr($rdata, 16);
- break;
- }
- break;
- case 0x0b:
-
- if (strlen($rdata) < 16)
- return $ret;
- $data = unpack("Vconst1/Veveryn/Vregen", $rdata);
- $rdata = substr($rdata, 12);
- $ret["everyn"] = $data["everyn"];
- $ret["regen"] = $data["regen"];
- $ret["weekdays"] = 0;
- if ($data["regen"] == 0) {
- $data = unpack("Vweekdays", $rdata);
- $rdata = substr($rdata, 4);
- $ret["weekdays"] = $data["weekdays"];
- }
- break;
- case 0x0c:
-
- if (strlen($rdata) < 16)
- return $ret;
- $data = unpack("Vconst1/Veveryn/Vregen/Vmonthday", $rdata);
- $ret["everyn"] = $data["everyn"];
- $ret["regen"] = $data["regen"];
- if ($ret["subtype"] == 3)
- $ret["weekdays"] = $data["monthday"];
- else
- $ret["monthday"] = $data["monthday"];
- $rdata = substr($rdata, 16);
- if ($ret["subtype"] == 3) {
- $data = unpack("Vnday", $rdata);
- $ret["nday"] = $data["nday"];
- $rdata = substr($rdata, 4);
- }
- break;
- case 0x0d:
-
- if (strlen($rdata) < 16)
- return $ret;
- $data = unpack("Vmonth/Veveryn/Vregen/Vmonthday", $rdata);
- $ret["month"] = $data["month"];
- $ret["everyn"] = $data["everyn"];
- $ret["regen"] = $data["regen"];
- if ($ret["subtype"] == 3)
- $ret["weekdays"] = $data["monthday"];
- else
- $ret["monthday"] = $data["monthday"];
- $rdata = substr($rdata, 16);
- if ($ret["subtype"] == 3) {
- $data = unpack("Vnday", $rdata);
- $ret["nday"] = $data["nday"];
- $rdata = substr($rdata, 4);
- }
- break;
- }
-
- if (strlen($rdata) < 16)
- return $ret;
-
- $data = unpack("Cterm/C3const1/Vnumoccur/Vconst2/Vnumexcept", $rdata);
-
- $rdata = substr($rdata, 16);
-
- $ret["term"] = $data["term"];
- $ret["numoccur"] = $data["numoccur"];
- $ret["numexcept"] = $data["numexcept"];
-
-
- $exc_base_dates = array();
- for($i = 0; $i < $ret["numexcept"]; $i++)
- {
- if (strlen($rdata) < 4)
-
-
-
- return $ret;
- $data = unpack("Vbasedate", $rdata);
- $rdata = substr($rdata, 4);
- $exc_base_dates[] = $this->recurDataToUnixData($data["basedate"]);
- }
- if (strlen($rdata) < 4)
- return $ret;
- $data = unpack("Vnumexceptmod", $rdata);
- $rdata = substr($rdata, 4);
-
- $ret["numexceptmod"] = $data["numexceptmod"];
-
-
-
- $exc_changed = array();
- for($i = 0; $i < $ret["numexceptmod"]; $i++)
- {
- if (strlen($rdata) < 4)
-
-
-
- return $ret;
- $data = unpack("Vstartdate", $rdata);
- $rdata = substr($rdata, 4);
- $exc_changed[] = $this->recurDataToUnixData($data["startdate"]);
- }
-
- if (strlen($rdata) < 8)
- return $ret;
- $data = unpack("Vstart/Vend", $rdata);
- $rdata = substr($rdata, 8);
- $ret["start"] = $this->recurDataToUnixData($data["start"]);
- $ret["end"] = $this->recurDataToUnixData($data["end"]);
-
- if (strlen($rdata) < 16)
- return $ret;
- $data = unpack("Vreaderversion/Vwriterversion/Vstartmin/Vendmin", $rdata);
- $rdata = substr($rdata, 16);
- $ret["startocc"] = $data["startmin"];
- $ret["endocc"] = $data["endmin"];
- $readerversion = $data["readerversion"];
- $writerversion = $data["writerversion"];
- $data = unpack("vnumber", $rdata);
- $rdata = substr($rdata, 2);
- $nexceptions = $data["number"];
- $exc_changed_details = array();
-
- for($i=0;$i<$nexceptions;$i++)
- {
- $item = array();
-
- $data = unpack("Vstartdate/Venddate/Vbasedate", $rdata);
- $rdata = substr($rdata, 12);
-
- $startdate = $this->recurDataToUnixData($data["startdate"]);
- $enddate = $this->recurDataToUnixData($data["enddate"]);
- $basedate = $this->recurDataToUnixData($data["basedate"]);
-
- $item["basedate"] = $this->dayStartOf($basedate);
- $item["start"] = $startdate;
- $item["end"] = $enddate;
- $data = unpack("vbitmask", $rdata);
- $rdata = substr($rdata, 2);
- $item["bitmask"] = $data["bitmask"];
-
- $bitmask = $data["bitmask"];
-
-
- if(($bitmask &(1 << 0))) {
- $data = unpack("vnull_length/vlength", $rdata);
- $rdata = substr($rdata, 4);
- $length = $data["length"];
- $item["subject"] = "";
- for($j = 0; $j < $length && strlen($rdata); $j++)
- {
- $data = unpack("Cchar", $rdata);
- $rdata = substr($rdata, 1);
- $item["subject"] .= chr($data["char"]);
- }
- }
-
- if (($bitmask & (1 << 1)))
- $rdata = substr($rdata, 4);
-
-
-
- if(($bitmask &(1 << 2))) {
- $data = unpack("Vremind_before", $rdata);
- $rdata = substr($rdata, 4);
- $item["remind_before"] = $data["remind_before"];
- }
-
-
- if(($bitmask &(1 << 3))) {
- $data = unpack("Vreminder_set", $rdata);
- $rdata = substr($rdata, 4);
- $item["reminder_set"] = $data["reminder_set"];
- }
-
-
-
- if(($bitmask &(1 << 4))) {
- $data = unpack("vnull_length/vlength", $rdata);
- $rdata = substr($rdata, 4);
- $item["location"] = "";
- $length = $data["length"];
- $data = substr($rdata, 0, $length);
- $rdata = substr($rdata, $length);
- $item["location"] .= $data;
- }
-
-
- if(($bitmask &(1 << 5))) {
- $data = unpack("Vbusystatus", $rdata);
- $rdata = substr($rdata, 4);
- $item["busystatus"] = $data["busystatus"];
- }
-
- if (($bitmask &(1 << 6)))
-
- $rdata = substr($rdata, 4);
-
-
- if(($bitmask &(1 << 7))) {
- $data = unpack("Vallday", $rdata);
- $rdata = substr($rdata, 4);
- $item["alldayevent"] = $data["allday"];
- }
-
-
- if(($bitmask &(1 << 8))) {
- $data = unpack("Vlabel", $rdata);
- $rdata = substr($rdata, 4);
- $item["label"] = $data["label"];
- }
-
- if (($bitmask & (1 << 9)))
- ;
- array_push($exc_changed_details, $item);
- }
-
-
- $deleted_occurences = array();
-
- foreach($exc_base_dates as $base_date) {
- $found = false;
-
- foreach($exc_changed_details as $details) {
- if($details["basedate"] == $base_date) {
- $found = true;
- break;
- }
- }
- if (!$found)
-
- $deleted_occurences[] = $base_date;
- }
- $ret["deleted_occurences"] = $deleted_occurences;
- $ret["changed_occurences"] = $exc_changed_details;
-
- if (strlen($rdata) < 16)
- return $ret;
- $data = unpack("Vreservedsize", $rdata);
- $rdata = substr($rdata, 4 + $data["reservedsize"]);
- for($i=0;$i<$nexceptions;$i++)
- {
-
- if ($writerversion >= 0x3009) {
- $data = unpack("Vsize/Vvalue", $rdata);
- $rdata = substr($rdata, 4 + $data["size"]);
- }
- $data = unpack("Vreservedsize", $rdata);
- $rdata = substr($rdata, 4 + $data["reservedsize"]);
-
- if ($exc_changed_details[$i]["bitmask"] & 0x11) {
- $data = unpack("Vstart/Vend/Vorig", $rdata);
- $rdata = substr($rdata, 4 * 3);
- $exc_changed_details[$i]["ex_start_datetime"] = $data["start"];
- $exc_changed_details[$i]["ex_end_datetime"] = $data["end"];
- $exc_changed_details[$i]["ex_orig_date"] = $data["orig"];
- }
-
- if ($exc_changed_details[$i]["bitmask"] & 0x01) {
-
- $data = unpack("vlength", $rdata);
- $rdata = substr($rdata, 2);
- $length = $data["length"];
- $data = substr($rdata, 0, $length * 2);
- $rdata = substr($rdata, $length * 2);
- $subject = iconv("UCS-2LE", "UTF-8", $data);
-
- $exc_changed_details[$i]["subject"] = $subject;
- }
-
- if ($exc_changed_details[$i]["bitmask"] & 0x10) {
-
- $data = unpack("vlength", $rdata);
- $rdata = substr($rdata, 2);
- $length = $data["length"];
- $data = substr($rdata, 0, $length * 2);
- $rdata = substr($rdata, $length * 2);
- $location = iconv("UCS-2LE", "UTF-8", $data);
-
- $exc_changed_details[$i]["location"] = $location;
- }
-
- if ($exc_changed_details[$i]["bitmask"] & 0x11) {
- $data = unpack("Vreservedsize", $rdata);
- $rdata = substr($rdata, 4 + $data["reservedsize"]);
- }
- }
-
- $ret["changed_occurences"] = $exc_changed_details;
- return $ret;
- }
-
- function saveRecurrence()
- {
-
- if(!isset($this->message))
- return;
-
- if (!isset($this->recur["type"]) && !isset($this->recur["subtype"]))
- return;
- if (!isset($this->recur["start"]) && !isset($this->recur["end"]))
- return;
- if (!isset($this->recur["startocc"]) && !isset($this->recur["endocc"]))
- return;
- $rdata = pack("CCCCCCV", 0x04, 0x30, 0x04, 0x30, (int) $this->recur["type"], 0x20, (int) $this->recur["subtype"]);
- $weekstart = 1;
- $forwardcount = 0;
- $restocc = 0;
- $dayofweek = (int) gmdate("w", (int) $this->recur["start"]);
- $term = (int) $this->recur["type"];
- switch($term)
- {
- case 0x0A:
-
- if (!isset($this->recur["everyn"]))
- return;
- if ($this->recur["subtype"] == 1) {
-
- $rdata .= pack("VVVV", (6 * 24 * 60), 1, 0, 0x3E);
- } else {
-
- $everyn = ((int) $this->recur["everyn"]) / 1440;
-
- $firstocc = $this->unixDataToRecurData($this->recur["start"]) % ((int) $this->recur["everyn"]);
- $rdata .= pack("VVV", $firstocc, (int) $this->recur["everyn"], $this->recur["regen"] ? 1 : 0);
- }
- break;
- case 0x0B:
-
- if (!isset($this->recur["everyn"]))
- return;
- if (!$this->recur["regen"] && !isset($this->recur["weekdays"]))
- return;
-
- if (!$this->recur['regen']) {
-
-
- $daycount = 0;
- $dayskip = -1;
- for ($j = 0; $j < 7; $j++) {
- if (((int) $this->recur["weekdays"]) & (1 << (($dayofweek + $j) % 7))) {
- if ($dayskip == -1)
- $dayskip = $j;
- $daycount++;
- }
- }
-
-
- $weekskip = 0;
- if (($dayofweek < $weekstart && $dayskip > 0) || ($dayofweek + $dayskip) > 6)
- $weekskip = 1;
-
-
- if (((int) $this->recur["term"]) == 0x22) {
-
-
-
-
- $forwardcount = floor((int) ($this->recur["numoccur"] - 1) / $daycount);
-
-
- $restocc = ((int) $this->recur["numoccur"]) - ($forwardcount * $daycount) - 1;
-
- $forwardcount *= (int) $this->recur["everyn"];
- }
-
- $this->recur["start"] = ((int) $this->recur["start"]) + ($dayskip * 24 * 60 * 60)+ ($weekskip * (((int) $this->recur["everyn"]) - 1) * 7 * 24 * 60 * 60);
- }
-
- $firstocc = ($this->unixDataToRecurData($this->recur["start"])) % (((int) $this->recur["everyn"]) * 7 * 24 * 60);
- $firstocc -= (((int) gmdate("w", (int) $this->recur["start"])) - 1) * 24 * 60;
- if ($this->recur["regen"])
- $rdata .= pack("VVV", $firstocc, (int) $this->recur["everyn"], 1);
- else
- $rdata .= pack("VVVV", $firstocc, (int) $this->recur["everyn"], 0, (int) $this->recur["weekdays"]);
- break;
- case 0x0C:
-
- case 0x0D:
-
- if (!isset($this->recur["everyn"]))
- return;
- if ($term == 0x0D && !isset($this->recur["month"]))
- return;
- if ($term == 0x0C )
- $everyn = (int) $this->recur["everyn"];
- else
- $everyn = $this->recur["regen"] ? ((int) $this->recur["everyn"]) * 12 : 12;
-
- $curmonthday = gmdate("j", (int) $this->recur["start"]);
- $curyear = gmdate("Y", (int) $this->recur["start"]);
- $curmonth = gmdate("n", (int) $this->recur["start"]);
-
-
- if (((int) $this->recur["term"]) == 0x22)
-
-
- $forwardcount = ((((int) $this->recur["numoccur"]) - 1) * $everyn);
-
- if ($term == 0x0D )
- $selmonth = floor(((int) $this->recur["month"]) / (24 * 60 *29)) + 1;
- switch ((int) $this->recur["subtype"])
- {
-
- case 2:
- if (!isset($this->recur["monthday"]))
- return;
-
-
-
- $this->recur["start"] -= ($curmonthday-1) * 24 * 60 * 60;
-
- $this->recur["start"] += (((int) $this->recur["monthday"]) - 1) * 24 * 60 * 60;
-
- if (($term == 0x0C && ((int) $this->recur["monthday"]) < $curmonthday) ||
- ($term == 0x0D && ($selmonth < $curmonth || ($selmonth == $curmonth && ((int) $this->recur["monthday"]) < $curmonthday))))
- {
- if ($term == 0x0D )
- $count = ($everyn - ($curmonth - $selmonth));
- else
- $count = $everyn;
-
- for ($i = 0; $i < $count; $i++) {
- $this->recur["start"] += $this->getMonthInSeconds($curyear, $curmonth);
- if ($curmonth == 12) {
- $curyear++;
- $curmonth = 0;
- }
- $curmonth++;
- }
- }
-
-
-
-
-
- if (((int) $this->recur["monthday"]) >= 28 && ((int) $this->recur["monthday"]) <= 31 &&
- gmdate("j", ((int) $this->recur["start"])) < ((int) $this->recur["monthday"]))
- $this->recur["start"] -= gmdate("j", ((int) $this->recur["start"])) * 24 * 60 * 60;
-
- if ($term == 0x0C ) {
-
- $monthIndex = ((((12 % $everyn) * ((((int) gmdate("Y", $this->recur["start"])) - 1601)%$everyn)) % $everyn) + (((int) gmdate("n", $this->recur["start"])) - 1)) % $everyn;
- $firstocc = 0;
- for ($i = 0; $i < $monthIndex; $i++)
- $firstocc+= $this->getMonthInSeconds(1601 + floor($i / 12), ($i % 12) + 1) / 60;
- $rdata .= pack("VVVV", $firstocc, $everyn, $this->recur["regen"], (int) $this->recur["monthday"]);
- } else{
-
- $firstocc = 0;
- $monthIndex = (int) gmdate("n", $this->recur["start"]);
- for ($i = 1; $i < $monthIndex; $i++)
- $firstocc += $this->getMonthInSeconds(1601 + floor($i / 12), $i) / 60;
- $rdata .= pack("VVVV", $firstocc, $everyn, $this->recur["regen"], (int) $this->recur["monthday"]);
- }
- break;
- case 3:
-
-
- if (!isset($this->recur["weekdays"]) && !isset($this->recur["nday"]))
- return;
- $weekdays = (int) $this->recur["weekdays"];
- $nday = (int) $this->recur["nday"];
-
- $monthbegindow = (int) $this->recur["start"];
- if ($nday == 5)
-
- $monthbegindow += (gmdate("t", $monthbegindow ) - gmdate("j", $monthbegindow )) * 24 * 60 * 60;
- else
-
- $monthbegindow -= ((gmdate("j", $monthbegindow )-1) * 24 * 60 * 60);
- if ($term == 0x0D ) {
-
- if ($selmonth < $curmonth)
- $tmp = 12 - $curmonth + $selmonth;
- else
- $tmp = ($selmonth - $curmonth);
- for ($i = 0; $i < $tmp; $i++) {
- $monthbegindow += $this->getMonthInSeconds($curyear, $curmonth);
- if ($curmonth == 12) {
- $curyear++;
- $curmonth = 0;
- }
- $curmonth++;
- }
- } else {
-
- for ($i = 0; $i < 7; $i++) {
- if ($nday == 5 && (1 << ((gmdate("w", $monthbegindow) - $i) % 7)) & $weekdays) {
- $day = gmdate("j", $monthbegindow) - $i;
- break;
- } else if ($nday != 5 && (1 << ((gmdate("w", $monthbegindow) + $i) % 7)) & $weekdays) {
- $day = (($nday - 1) * 7) + ($i + 1);
- break;
- }
- }
-
- if (isset($day) && ($day < gmdate("j", (int) $this->recur["start"]))) {
- if ($nday == 5) {
- $monthbegindow += 24 * 60 * 60;
- if ($curmonth == 12) {
- $curyear++;
- $curmonth = 0;
- }
- $curmonth++;
- }
- for ($i = 0; $i < $everyn; $i++) {
- $monthbegindow += $this->getMonthInSeconds($curyear, $curmonth);
- if ($curmonth == 12) {
- $curyear++;
- $curmonth = 0;
- }
- $curmonth++;
- }
- if ($nday == 5)
- $monthbegindow -= 24 * 60 * 60;
- }
- }
-
- $day = 0;
-
- for ($i = 0; $i < 7; $i++) {
- if ($nday == 5 && (1 << ((gmdate("w", $monthbegindow) - $i) % 7)) & $weekdays) {
- $day = $i;
- break;
- } else if ($nday != 5 && (1 << ((gmdate("w", $monthbegindow) + $i) % 7)) & $weekdays) {
- $day = ($nday - 1) * 7 + ($i + 1);
- break;
- }
- }
- if ($nday == 5)
- $monthbegindow -= $day * 24 * 60 * 60;
- else
- $monthbegindow += ($day - 1) * 24 * 60 * 60;
- $firstocc = 0;
- if ($term == 0x0C ) {
-
- $monthIndex = ((((12 % $everyn) * (((int) gmdate("Y", $this->recur["start"]) - 1601) % $everyn)) % $everyn) + (((int) gmdate("n", $this->recur["start"])) - 1)) % $everyn;
- for ($i = 0; $i < $monthIndex; $i++)
- $firstocc += $this->getMonthInSeconds(1601 + floor($i / 12), ($i % 12) + 1) / 60;
- $rdata .= pack("VVVVV", $firstocc, $everyn, 0, $weekdays, $nday);
- break;
- }
-
- $monthIndex = (int) gmdate("n", $this->recur["start"]);
- for ($i = 1; $i < $monthIndex; $i++)
- $firstocc += $this->getMonthInSeconds(1601 + floor($i / 12), $i) / 60;
- $rdata .= pack("VVVVV", $firstocc, $everyn, 0, $weekdays, $nday);
- break;
- }
- break;
- }
-
- if (!isset($this->recur["term"]))
- return;
-
-
- $term = (int) $this->recur["term"];
- $rdata .= pack("CCCC", $term, 0x20, 0x00, 0x00);
-
- switch($term)
- {
-
- case 0x21:
- $rdata .= pack("V", 10);
- break;
-
- case 0x22:
- if (!isset($this->recur["numoccur"]))
- return;
- $rdata .= pack("V", (int) $this->recur["numoccur"]);
- break;
-
- case 0x23:
- $rdata .= pack("V", 0);
- break;
- }
-
-
- if (((int) $this->recur["type"]) == 0x0B && ((int) $this->recur["subtype"]) == 1)
- $rdata .= pack("V", 1);
- else
- $rdata .= pack("V", 0);
-
-
-
- $deleted_items = $this->recur["deleted_occurences"];
- $changed_items = $this->recur["changed_occurences"];
-
-
- $items = $deleted_items;
-
- foreach($changed_items as $changed_item)
- array_push($items, $changed_item["basedate"]);
- sort($items);
-
-
- $rdata .= pack("V", count($items));
- foreach($items as $item)
- $rdata .= pack("V", $this->unixDataToRecurData($item));
-
-
- $rdata .= pack("V", count($changed_items));
- $items = array();
-
- foreach($changed_items as $changed_item)
- $items[] = $this->dayStartOf($changed_item["start"]);
- sort($items);
-
- foreach($items as $item)
- $rdata .= pack("V", $this->unixDataToRecurData($item));
-
-
- $rdata .= pack("V", $this->unixDataToRecurData((int) $this->recur["start"]));
-
-
- switch($term)
- {
-
- case 0x21:
- $rdata .= pack("V", $this->unixDataToRecurData((int) $this->recur["end"]));
- break;
-
- case 0x22:
-
- $occenddate = (int) $this->recur["start"];
- switch ((int) $this->recur["type"]) {
- case 0x0A:
- if ($this->recur["subtype"] != 1) {
-
- $occenddate += (((int) $this->recur["everyn"]) * 60 * (((int) $this->recur["numoccur"] - 1)));
- break;
- }
-
- $restocc = (int) $this->recur["numoccur"];
-
- $nowtime = $this->gmtime($occenddate);
- $j = $nowtime["tm_wday"];
- while (1)
- {
- if (($j % 7) > 0 && ($j % 7) < 6)
- $restocc--;
- $j++;
- if ($restocc <= 0)
- break;
- $occenddate += 24 * 60 * 60;
- }
- break;
- case 0x0B:
-
-
-
-
- $occenddate += ($forwardcount * 7 * 24 * 60 * 60);
- $dayofweek = gmdate("w", $occenddate);
-
- for ($j = 1; $restocc > 0; $j++)
- {
-
- if ((($dayofweek + $j) % 7) == $weekstart)
- $occenddate += (((int) $this->recur["everyn"]) - 1) * 7 * 24 * 60 * 60;
-
- if (((int) $this->recur["weekdays"]) & (1 << (($dayofweek + $j) % 7)))
- $restocc--;
-
- $occenddate += 24 * 60 * 60;
- }
- break;
- case 0x0C:
- case 0x0D:
- $curyear = gmdate("Y", (int) $this->recur["start"] );
- $curmonth = gmdate("n", (int) $this->recur["start"] );
-
- switch ((int) $this->recur["subtype"])
- {
- case 2:
- while ($forwardcount > 0)
- {
- $occenddate += $this->getMonthInSeconds($curyear, $curmonth);
- if ($curmonth >=12) {
- $curmonth = 1;
- $curyear++;
- } else {
- $curmonth++;
- }
- $forwardcount--;
- }
-
- if (((int) $this->recur["monthday"]) >= 28 && ((int) $this->recur["monthday"]) <= 31 &&
- gmdate("j", $occenddate) < ((int) $this->recur["monthday"]))
- {
- if (gmdate("j", $occenddate) < 28)
- $occenddate -= gmdate("j", $occenddate) * 24 * 60 * 60;
- else
- $occenddate += (gmdate("t", $occenddate) - gmdate("j", $occenddate)) * 24 * 60 * 60;
- }
- break;
- case 3:
- $nday = (int) $this->recur["nday"];
- $weekdays = (int) $this->recur["weekdays"];
- while ($forwardcount > 0)
- {
- $occenddate += $this->getMonthInSeconds($curyear, $curmonth);
- if ($curmonth >=12) {
- $curmonth = 1;
- $curyear++;
- } else {
- $curmonth++;
- }
- $forwardcount--;
- }
- if ($nday == 5)
-
- $occenddate += (gmdate("t", $occenddate ) - gmdate("j", $occenddate )) * 24 * 60 * 60;
- else
-
- $occenddate -= (gmdate("j", $occenddate )-1) * 24 * 60 * 60;
- for ($i = 0; $i < 7; $i++) {
- if ($nday == 5 && (1 << ((gmdate("w", $occenddate) - $i) % 7)) & $weekdays) {
- $occenddate -= $i * 24 * 60 * 60;
- break;
- } else if ($nday != 5 && (1 << ((gmdate("w", $occenddate) + $i) % 7)) & $weekdays) {
- $occenddate += ($i + (($nday - 1) * 7)) * 24 * 60 * 60;
- break;
- }
- }
- break;
- }
- break;
- }
- if (defined("PHP_INT_MAX") && $occenddate > PHP_INT_MAX)
- $occenddate = PHP_INT_MAX;
- $this->recur["end"] = $occenddate;
- $rdata .= pack("V", $this->unixDataToRecurData((int) $this->recur["end"]) );
- break;
-
- case 0x23:
- default:
- $this->recur["end"] = 0x7fffffff;
- $rdata .= pack("V", 0x5AE980DF);
- break;
- }
-
- $utcstart = $this->toGMT($this->tz, (int) $this->recur["start"]);
- $utcend = $this->toGMT($this->tz, (int) $this->recur["end"]);
-
-
- $utcfirstoccstartdatetime = (isset($this->recur["startocc"])) ? $utcstart + (((int) $this->recur["startocc"])*60) : $utcstart;
- $utcfirstoccenddatetime = (isset($this->recur["endocc"])) ? $utcstart + (((int) $this->recur["endocc"]) * 60) : $utcstart;
-
-
- mapi_setprops($this->message, Array($this->proptags["reminder_time"] => $utcfirstoccstartdatetime ));
-
- mapi_setprops($this->message, Array($this->proptags["startdate"] => $utcfirstoccstartdatetime ));
- mapi_setprops($this->message, Array($this->proptags["duedate"] => $utcfirstoccenddatetime ));
- mapi_setprops($this->message, Array($this->proptags["commonstart"] => $utcfirstoccstartdatetime ));
- mapi_setprops($this->message, Array($this->proptags["commonend"] => $utcfirstoccenddatetime ));
-
- if (isset($this->recur["message_class"]) && $this->recur["message_class"] == "IPM.Appointment") {
-
- mapi_setprops($this->message, Array($this->proptags["startdate_recurring"] => $utcstart));
- mapi_setprops($this->message, Array($this->proptags["enddate_recurring"] => $utcend));
-
-
- mapi_setprops($this->message, Array($this->proptags["recurrencetype"] => ((int) $this->recur["type"]) - 0x9));
-
- mapi_setprops($this->message, Array($this->proptags["side_effects"] => 369));
- } else {
- mapi_setprops($this->message, Array($this->proptags["side_effects"] => 3441));
- }
-
-
-
-
-
- $reminderprops = mapi_getprops($this->message, array($this->proptags["reminder_minutes"]) );
- if(isset($reminderprops[$this->proptags["reminder_minutes"]]) ) {
- $occ = false;
- $occurrences = $this->getItems(time(), 0x7ff00000, 3, true);
- for($i = 0, $len = count($occurrences) ; $i < $len; $i++) {
-
-
-
-
-
- if(($occurrences[$i][$this->proptags["startdate"]] - $reminderprops[$this->proptags["reminder_minutes"]] * 60) > time()) {
- $occ = $occurrences[$i];
- break;
- }
- }
-
- if($occ)
- mapi_setprops($this->message, Array($this->proptags["flagdueby"] => $occ[$this->proptags["startdate"]] - ($reminderprops[$this->proptags["reminder_minutes"]] * 60) ));
- else
-
- mapi_setprops($this->message, Array($this->proptags["reminder"] => false, $this->proptags["flagdueby"] => 0x7ff00000));
- }
-
-
-
- $rdata .= pack("VCCCC", 0x00003006, 0x08, 0x30, 0x00, 0x00);
-
- if(isset($this->recur["startocc"]) && isset($this->recur["endocc"]))
-
- $rdata .= pack("VV", (int) $this->recur["startocc"], (int) $this->recur["endocc"]);
-
-
- $changed_items = $this->recur["changed_occurences"];
-
- $rdata .= pack("v", count($changed_items));
-
- foreach($changed_items as $changed_item)
- {
-
- $rdata .= pack("V", $this->unixDataToRecurData($changed_item["start"]));
- $rdata .= pack("V", $this->unixDataToRecurData($changed_item["end"]));
- $rdata .= pack("V", $this->unixDataToRecurData($changed_item["basedate"]));
-
- $bitmask = 0;
-
- if (isset($changed_item["subject"]))
- $bitmask |= 1 << 0;
- if (isset($changed_item["remind_before"]))
- $bitmask |= 1 << 2;
- if (isset($changed_item["reminder_set"]))
- $bitmask |= 1 << 3;
- if (isset($changed_item["location"]))
- $bitmask |= 1 << 4;
- if (isset($changed_item["busystatus"]))
- $bitmask |= 1 << 5;
- if (isset($changed_item["alldayevent"]))
- $bitmask |= 1 << 7;
- if (isset($changed_item["label"]))
- $bitmask |= 1 << 8;
- $rdata .= pack("v", $bitmask);
-
- if(isset($changed_item["subject"])) {
-
- $subject = iconv("UTF-8", "windows-1252//TRANSLIT", $changed_item["subject"]);
- $length = strlen($subject);
- $rdata .= pack("vv", $length + 1, $length);
- $rdata .= pack("a".$length, $subject);
- }
- if (isset($changed_item["remind_before"]))
- $rdata .= pack("V", $changed_item["remind_before"]);
- if (isset($changed_item["reminder_set"]))
- $rdata .= pack("V", $changed_item["reminder_set"]);
- if(isset($changed_item["location"])) {
- $location = iconv("UTF-8", "windows-1252//TRANSLIT", $changed_item["location"]);
- $length = strlen($location);
- $rdata .= pack("vv", $length + 1, $length);
- $rdata .= pack("a".$length, $location);
- }
- if (isset($changed_item["busystatus"]))
- $rdata .= pack("V", $changed_item["busystatus"]);
- if (isset($changed_item["alldayevent"]))
- $rdata .= pack("V", $changed_item["alldayevent"]);
- if (isset($changed_item["label"]))
- $rdata .= pack("V", $changed_item["label"]);
- }
- $rdata .= pack("V", 0);
-
- foreach($changed_items as $changed_item)
- {
- $rdata .= pack("V", 0);
- if(isset($changed_item["subject"]) || isset($changed_item["location"])) {
- $rdata .= pack("V", $this->unixDataToRecurData($changed_item["start"]));
- $rdata .= pack("V", $this->unixDataToRecurData($changed_item["end"]));
- $rdata .= pack("V", $this->unixDataToRecurData($changed_item["basedate"]));
- }
- if(isset($changed_item["subject"])) {
- $subject = iconv("UTF-8", "UCS-2LE", $changed_item["subject"]);
- $length = iconv_strlen($subject, "UCS-2LE");
- $rdata .= pack("v", $length);
- $rdata .= pack("a".$length*2, $subject);
- }
- if(isset($changed_item["location"])) {
- $location = iconv("UTF-8", "UCS-2LE", $changed_item["location"]);
- $length = iconv_strlen($location, "UCS-2LE");
- $rdata .= pack("v", $length);
- $rdata .= pack("a".$length*2, $location);
- }
- if (isset($changed_item["subject"]) || isset($changed_item["location"]))
- $rdata .= pack("V", 0);
- }
- $rdata .= pack("V", 0);
-
- mapi_setprops($this->message, Array($this->proptags["recurring_data"] => $rdata, $this->proptags["recurring"] => true));
- if(isset($this->tz) && $this->tz){
- $timezone = "GMT";
- if ($this->tz["timezone"]!=0){
-
- $timezone = sprintf("(GMT %s%02d:%02d)", (-$this->tz["timezone"]>0 ? "+" : "-"),
- abs($this->tz["timezone"]/60),
- abs($this->tz["timezone"]%60));
- }
- mapi_setprops($this->message, Array($this->proptags["timezone_data"] => $this->getTimezoneData($this->tz),
- $this->proptags["timezone"] => $timezone));
- }
- }
-
-
- function recurDataToUnixData($rdate)
- {
- return ($rdate - 194074560) * 60 ;
- }
-
-
- function unixDataToRecurData($date)
- {
- return ($date / 60) + 194074560;
- }
-
- function GetTZOffset($ts)
- {
- $Offset = date("O", $ts);
- $Parity = $Offset < 0 ? -1 : 1;
- $Offset = $Parity * $Offset;
- $Offset = ($Offset - ($Offset % 100)) / 100 * 60 + $Offset % 100;
- return $Parity * $Offset;
- }
-
- function gmtime($time)
- {
- $TZOffset = $this->GetTZOffset($time);
- $t_time = $time - $TZOffset * 60;
- $t_arr = localtime($t_time, 1);
- return $t_arr;
- }
- function isLeapYear($year) {
- return ( $year % 4 == 0 && ($year % 100 != 0 || $year % 400 == 0) );
- }
- function getMonthInSeconds($year, $month)
- {
- if( in_array($month, array(1,3,5,7,8,10,12) ) ) {
- $day = 31;
- } else if( in_array($month, array(4,6,9,11) ) ) {
- $day = 30;
- } else {
- $day = 28;
- if( $this->isLeapYear($year) == 1 )
- $day++;
- }
- return $day * 24 * 60 * 60;
- }
-
- function getDateByYearMonthWeekDayHour($year, $month, $week, $day, $hour)
- {
-
- $date = gmmktime(0,0,0,$month,0,$year + 1900);
-
- $gmdate = $this->gmtime($date);
- $date -= $gmdate["tm_wday"] * 24 * 60 * 60;
- $date += $week * 7 * 24 * 60 * 60;
- $date += $day * 24 * 60 * 60;
- $date += $hour * 60 * 60;
- $gmdate = $this->gmtime($date);
-
-
- if($gmdate["tm_mon"]+1 != $month)
- $date -= 7 * 24 * 60 * 60;
- return $date;
- }
-
- function getTimezone($tz, $date)
- {
-
- if(!isset($tz["timezone"]))
- return 0;
- $dst = false;
- $gmdate = $this->gmtime($date);
- $dststart = $this->getDateByYearMonthWeekDayHour($gmdate["tm_year"], $tz["dststartmonth"], $tz["dststartweek"], 0, $tz["dststarthour"]);
- $dstend = $this->getDateByYearMonthWeekDayHour($gmdate["tm_year"], $tz["dstendmonth"], $tz["dstendweek"], 0, $tz["dstendhour"]);
- if($dststart <= $dstend) {
-
- if ($date > $dststart && $date < $dstend)
- $dst = true;
- } else {
-
- if ($date < $dstend || $date > $dststart)
- $dst = true;
- }
- if ($dst)
- return $tz["timezone"] + $tz["timezonedst"];
- else
- return $tz["timezone"];
- }
-
- function getWeekNr($date)
- {
- $gmdate = gmtime($date);
- $gmdate["tm_mday"] = 0;
- return strftime("%W", $date) - strftime("%W", gmmktime($gmdate)) + 1;
- }
-
- function parseTimezone($data)
- {
- if(strlen($data) < 48)
- return;
- $tz = unpack("ltimezone/lunk/ltimezonedst/lunk/ldstendmonth/vdstendweek/vdstendhour/lunk/lunk/vunk/ldststartmonth/vdststartweek/vdststarthour/lunk/vunk", $data);
- return $tz;
- }
- function getTimezoneData($tz)
- {
- $data = pack("lllllvvllvlvvlv", $tz["timezone"], 0, $tz["timezonedst"], 0, $tz["dstendmonth"], $tz["dstendweek"], $tz["dstendhour"], 0, 0, 0, $tz["dststartmonth"], $tz["dststartweek"], $tz["dststarthour"], 0 ,0);
- return $data;
- }
-
- function createTimezone($tz)
- {
- $data = pack("lxxxxlxxxxlvvxxxxxxxxxxlvvxxxxxx",
- $tz["timezone"],
- array_key_exists("timezonedst",$tz)?$tz["timezonedst"]:0,
- array_key_exists("dstendmonth",$tz)?$tz["dstendmonth"]:0,
- array_key_exists("dstendweek",$tz)?$tz["dstendweek"]:0,
- array_key_exists("dstendhour",$tz)?$tz["dstendhour"]:0,
- array_key_exists("dststartmonth",$tz)?$tz["dststartmonth"]:0,
- array_key_exists("dststartweek",$tz)?$tz["dststartweek"]:0,
- array_key_exists("dststarthour",$tz)?$tz["dststarthour"]:0
- );
- return $data;
- }
-
- function toGMT($tz, $date) {
- if(!isset($tz['timezone']))
- return $date;
- $offset = $this->getTimezone($tz, $date);
- return $date + $offset * 60;
- }
-
- function fromGMT($tz, $date) {
- $offset = $this->getTimezone($tz, $date);
- return $date - $offset * 60;
- }
-
- function dayStartOf($date)
- {
- $time1 = $this->gmtime($date);
- return gmmktime(0, 0, 0, $time1["tm_mon"] + 1, $time1["tm_mday"], $time1["tm_year"] + 1900);
- }
-
-
- function monthStartOf($date)
- {
- $time1 = $this->gmtime($date);
- return gmmktime(0, 0, 0, $time1["tm_mon"] + 1, 1, $time1["tm_year"] + 1900);
- }
-
-
- function yearStartOf($date)
- {
- $time1 = $this->gmtime($date);
- return gmmktime(0, 0, 0, 1, 1, $time1["tm_year"] + 1900);
- }
-
- function getItems($start, $end, $limit = 0, $remindersonly = false)
- {
- $items = array();
- if(isset($this->recur)) {
-
-
- if($remindersonly && (!isset($this->messageprops[$this->proptags["reminder"]]) || $this->messageprops[$this->proptags["reminder"]] == false)) {
-
- uasort($this->recur["changed_occurences"], array($this, "sortExceptionStart"));
-
- foreach($this->recur["changed_occurences"] as $exception) {
-
- if(!isset($exception["reminder"]) || $exception["reminder"] == false)
- continue;
-
- $occstart = $this->toGMT($tz, $exception["start"]);
- $occend = $this->toGMT($tz, $exception["end"]);
-
- if($occstart > $end || $occend < $start)
- continue;
-
- array_push($items, $this->getExceptionProperties($exception));
- if($limit && (count($items) == $limit))
- break;
- }
- uasort($items, array($this, "sortStarttime"));
- return $items;
- }
-
-
- if ($this->recur['regen'] && isset($this->action['datecompleted']))
- $daystart = $this->dayStartOf($this->action['datecompleted']);
- else
- $daystart = $this->dayStartOf($this->recur["start"]);
-
-
- if ($end > $this->toGMT($this->tz, $this->recur["end"]))
- $rangeend = $this->toGMT($this->tz, $this->recur["end"]);
- else
- $rangeend = $end;
- $dayend = $this->dayStartOf($this->fromGMT($this->tz, $rangeend));
-
- switch($this->recur["type"])
- {
- case 10:
-
- if($this->recur["everyn"] <= 0)
- $this->recur["everyn"] = 1440;
-
- if($this->recur["subtype"] == 0) {
-
- for ($now = $daystart; $now <= $dayend && ($limit == 0 || count($items) < $limit); $now += 60 * $this->recur["everyn"])
- $this->processOccurrenceItem($items, $start, $end, $now, $this->recur["startocc"], $this->recur["endocc"], $this->tz, $remindersonly);
- break;
- }
-
- for ($now = $daystart; $now <= $dayend && ($limit == 0 || count($items) < $limit); $now += 60 * 1440)
- {
- $nowtime = $this->gmtime($now);
- if ($nowtime["tm_wday"] > 0 && $nowtime["tm_wday"] < 6)
- $this->processOccurrenceItem($items, $start, $end, $now, $this->recur["startocc"], $this->recur["endocc"], $this->tz, $remindersonly);
- }
- break;
- case 11:
-
- if($this->recur["everyn"] <= 0)
- $this->recur["everyn"] = 1;
-
- if ($this->recur['regen']) $daystart += (60 * 60 * 24 * 7 * $this->recur["everyn"]);
- for($now = $daystart; $now <= $dayend && ($limit == 0 || count($items) < $limit); $now += (60 * 60 * 24 * 7 * $this->recur["everyn"]))
- {
- if ($this->recur['regen']) {
- $this->processOccurrenceItem($items, $start, $end, $now, $this->recur["startocc"], $this->recur["endocc"], $this->tz, $remindersonly);
- continue;
- }
-
- for ($wday = 0; $wday < 7; $wday++)
- {
- $daynow = $now + $wday * 60 * 60 * 24;
-
- if ($daynow > $dayend)
- continue;
- $nowtime = $this->gmtime($daynow);
- if (($this->recur["weekdays"] &(1 << $nowtime["tm_wday"])))
- $this->processOccurrenceItem($items, $start, $end, $daynow, $this->recur["startocc"], $this->recur["endocc"], $this->tz, $remindersonly);
- }
- }
- break;
- case 12:
-
- if($this->recur["everyn"] <= 0)
- $this->recur["everyn"] = 1;
-
- for($now = $this->monthStartOf($daystart); $now <= $dayend && ($limit == 0 || count($items) < $limit); $now += $this->daysInMonth($now, $this->recur["everyn"]) * 24 * 60 * 60 )
- {
- if(isset($this->recur["monthday"]) &&($this->recur['monthday'] != "undefined") && !$this->recur['regen']) {
- $difference = 1;
- if ($this->daysInMonth($now, $this->recur["everyn"]) < $this->recur["monthday"])
- $difference = $this->recur["monthday"] - $this->daysInMonth($now, $this->recur["everyn"]) + 1;
- $daynow = $now + (($this->recur["monthday"] - $difference) * 24 * 60 * 60);
-
- if ($daynow <= $dayend)
- $this->processOccurrenceItem($items, $start, $end, $daynow, $this->recur["startocc"], $this->recur["endocc"], $this->tz, $remindersonly);
- }
- else if(isset($this->recur["nday"]) && isset($this->recur["weekdays"])) {
-
- if($this->recur["weekdays"] == 0)
- $this->recur["weekdays"] = 1;
-
-
- if ($this->recur["nday"] < 5) {
-
- $ndaycounter = 0;
-
- for($day = 0; $day < $this->daysInMonth($now, 1); $day++)
- {
- $daynow = $now + $day * 60 * 60 * 24;
- $nowtime = $this->gmtime($daynow);
- if ($this->recur["weekdays"] & (1 << $nowtime["tm_wday"]))
- $ndaycounter ++;
-
- if($this->recur["nday"] == $ndaycounter){
- $firstday = $day;
- break;
- }
- }
-
- $daynow = $now + $firstday * 60 * 60 * 24;
- }else{
-
- $NumDaysInMonth = $this->daysInMonth($now, 1);
- $daynow = $now + (($NumDaysInMonth-1) * 24*60*60);
- $nowtime = $this->gmtime($daynow);
- while (($this->recur["weekdays"] & (1 << $nowtime["tm_wday"]))==0){
- $daynow -= 86400;
- $nowtime = $this->gmtime($daynow);
- }
- }
-
- if ($daynow <= $dayend && $daynow >= $daystart)
- $this->processOccurrenceItem($items, $start, $end, $daynow, $this->recur["startocc"], $this->recur["endocc"], $this->tz , $remindersonly);
- } else if ($this->recur['regen']) {
- $next_month_start = $now + ($this->daysInMonth($now, 1) * 24 * 60 * 60);
- $now = $daystart +($this->daysInMonth($next_month_start, $this->recur['everyn']) * 24 * 60 * 60);
- if ($now <= $dayend)
- $this->processOccurrenceItem($items, $daystart, $end, $now, $this->recur["startocc"], $this->recur["endocc"], $this->tz, $remindersonly);
- }
- }
- break;
- case 13:
-
- if($this->recur["everyn"] <= 0)
- $this->recur["everyn"] = 12;
- for($now = $this->yearStartOf($daystart); $now <= $dayend && ($limit == 0 || count($items) < $limit); $now += $this->daysInMonth($now, $this->recur["everyn"]) * 24 * 60 * 60 )
- {
- if(isset($this->recur["monthday"]) && !$this->recur['regen']) {
-
- $month = $this->monthOfYear($this->recur["month"]);
- $monthday = $this->recur["monthday"];
- $monthstart = $now + $this->daysInMonth($now, $month) * 24 * 60 * 60;
- if($monthday > $this->daysInMonth($monthstart, 1))
- $monthday = $this->daysInMonth($monthstart, 1);
- $daynow = $monthstart + ($monthday-1) * 24 * 60 * 60;
- $this->processOccurrenceItem($items, $start, $end, $daynow, $this->recur["startocc"], $this->recur["endocc"], $this->tz, $remindersonly);
- }
- else if(isset($this->recur["nday"]) && isset($this->recur["weekdays"])) {
-
- $monthnow = $now + $this->daysInMonth($now, $this->monthOfYear($this->recur["month"])) * 24 * 60 * 60;
-
- for($wday = 0; $wday < 7; $wday++)
- {
- $daynow = $monthnow + $wday * 60 * 60 * 24;
- $nowtime = $this->gmtime($daynow);
- if($this->recur["weekdays"] & (1 << $nowtime["tm_wday"])) {
- $firstday = $wday;
- break;
- }
- }
-
- $daynow = $monthnow + ($firstday + ($this->recur["nday"]-1)*7) * 60 * 60 * 24;
- while ($this->monthStartOf($daynow) != $this->monthStartOf($monthnow))
- $daynow -= 7 * 60 * 60 * 24;
- $this->processOccurrenceItem($items, $start, $end, $daynow, $this->recur["startocc"], $this->recur["endocc"], $this->tz, $remindersonly);
- } else if ($this->recur['regen']) {
- $year_starttime = $this->gmtime($now);
- $is_next_leapyear = $this->isLeapYear($year_starttime['tm_year'] + 1900 + 1);
- $now = $daystart + ($is_next_leapyear ? 31622400 : 31536000 );
- if ($now <= $dayend)
- $this->processOccurrenceItem($items, $daystart, $end, $now, $this->recur["startocc"], $this->recur["endocc"], $this->tz, $remindersonly);
- }
- }
- }
-
- if (!empty($this->recur['changed_occurences']))
- $this->processExceptionItems($items, $start, $end);
- }
-
- usort($items, array($this, "sortStarttime"));
-
- return $items;
- }
- function sortStarttime($a, $b)
- {
- $aTime = $a[$this->proptags["startdate"]];
- $bTime = $b[$this->proptags["startdate"]];
- return $aTime==$bTime?0:($aTime>$bTime?1:-1);
- }
-
- function daysInMonth($date, $months) {
- $days = 0;
- for ($i = 0; $i < $months; $i++)
- $days += date("t", $date + $days * 24 * 60 * 60);
- return $days;
- }
-
-
- function monthOfYear($minutes) {
- $d = gmmktime(0,0,0,1,1,2001);
-
- $d += $minutes*60;
-
- $dtime = $this->gmtime($d);
-
- return $dtime["tm_mon"];
- }
- function sortExceptionStart($a, $b)
- {
- return $a["start"] == $b["start"] ? 0 : ($a["start"] > $b["start"] ? 1 : -1 );
- }
- }
- ?>
|