/** * Preveri, če datum dela prost dan * * @param string $datum datum, za katerega preverjamo, če je dela prost dan v ISO8601 obliki, npr. "2017-01-01T01:00:00+0100" * @return true|false true če je dela prost dan, false sicer * @throws \Max\Exception\UnauthException */ public function delaProstDan($datum) { // preverjanje avtorizacije $this->expectPermission("Praznik-read"); $this->expectIsoDate($datum, $this->translate("Datum ({$datum}) ni datum v ISO8601 obliki"), 1001110); $datumD = Functions::stringToDateTime($datum); /** * preračun imamo v posebnem servisu, tako, da ga lahko kličemo direktno iz PHP-ja na strežniški strani */ $service = $this->serviceLocator->get('praznik.service'); return $service->delaProstDan($datumD); }
/** * preveri vhodne parametre RPC klicev in nasilno prekini program, če niso v redu * */ private function preveriVhodneParametre($uprizoritveIds, $alternacije, $zacetek, $konec) { foreach ($uprizoritveIds as $u) { $this->expectUUID($u, 'Pričakujem ID uprizoritev v prvem parametru', 1001670); } foreach ($alternacije as $key => $foo) { $this->expect(is_array($foo) && is_integer($key), 'Pričakujem array fun:(os,os,..) v drugem parametru', 1001676); foreach ($foo as $fun => $osebe) { $this->expectUUID($fun, 'Pričakujem Id funkcije kot ključ v drugem parametru', 1001674); foreach ($osebe as $o) { $this->expectUUID($o, 'Pričakujem Id oseb v drugem parametru', 1001675); } } } if (!empty($zacetek)) { $this->expectIsoDate($zacetek, $this->translate('Začetek (' . $zacetek . ') ni datum v ISO8601 obliki'), 1001671); } if (!empty($konec)) { $this->expectIsoDate($konec, $this->translate('Konec (' . $konec . ') ni datum v ISO8601 obliki'), 1001672); } $this->expect(empty($zacetek) && empty($konec) || !empty($zacetek) && !empty($konec), "Začetek in konec morata biti ali oba prazna ali oba čas", 1001673); /** * konec mora biti >=začetek */ if (!empty($zacetek) && !empty($konec)) { /* * pretvorimo v datum za vsak slučaj, če bi bila $zacetek in $konec * v različnih time zone-ah */ $zacTime = Functions::stringToDateTime($zacetek); $konTime = Functions::stringToDateTime($konec); $this->expect($zacTime <= $konTime, "Konec ne sme biti pred začetkom", 1001677); } }
/** * Razmnoži dogodek * * novi dogodki so v obdobju začetek obdobja - konec obdobja (oz. število ponovitev), * upoštevajoč flage za praznik, soboto in nedelj * in tedenske termine, če ni števila ponovitev * * @param uuid $dogodekId dogodek, ki ga kopiramo * @param string $zacetekObdobja začetek obdobja, kjer naj bodo kopirani dogodki v ISO obliki * @param string $konecObdobja začetek obdobja, kjer naj bodo kopirani dogodki * @param boolean $upostevajPraznike če true, potem novi dogodki ne bodo na praznik * @param boolean $upostevajSobote če true, potem novi dogodki ne bodo v soboto * @param boolean $upostevajNedelje če true, potem novi dogodki ne bodo v nedeljo * [ h => ura, m=> minuta] * @param integer $steviloPonovitev če polje obstaja, se kreira toliko novih dogodkov * * spodnji parametri se upoštevajo le, če ni števila ponovitev: * @param array $dopoldanOd čas začetka dopoldanskega termina v obliki * [ h => ura, m=> minuta] * @param array $popoldanOd čas začetka popoldanskega termina v obliki * [ h => ura, m=> minuta] * @param array $zvecerOd čas začetka večernega termina v obliki * [ h => ura, m=> minuta] * @param array $tedenskiTermini če polje obstaja, se dogodki kreirajo v sklopu teh omejitev * oblika: [ [dan_v_tednu], [termin,...]] pri čemer je: * dan_v_tednu 1-ponedeljek .. 7 - nedelja * termin DOP-dopoldan, POP-popoldan, ZVE-zvečer * * @return array id-ji kreiranih dogodkov * @throws \Max\Exception\UnauthException */ public function razmnozi($dogodekId, $zacetekObdobja = null, $konecObdobja = null, $upostevajPraznike = false, $upostevajSobote = false, $upostevajNedelje = false, $dopoldanOd = null, $popoldanOd = null, $zvecerOd = null, $steviloPonovitev = null, $tedenskiTermini = null) { /* * preverjanje avtorizacije */ $this->expectPermission("Dogodek-write"); $this->expectPermission("TerminStoritve-write"); $this->expectPermission("Option-read"); $this->expectPermission("OptionValue-read"); $this->expectPermission("Praznik-read"); $em = $this->serviceLocator->get("\\Doctrine\\ORM\\EntityManager"); /* * preverjanje parametrov */ $dogodek = $em->getRepository("Koledar\\Entity\\Dogodek")->findOneById($dogodekId); if (!$dogodek) { throw new \Max\Exception\UnauthException($this->translate('Ni dogodka'), 1001249); } if (!empty($zacetekObdobja)) { $this->expectIsoDate($zacetekObdobja, $this->translate('Začetek obdobja (' . $zacetekObdobja . ') ni datum v ISO8601 obliki'), 1001250); } else { /* * takoj naslednji dan zjutraj */ $zacetekObdobja = clone $dogodek->getKonec(); $zacetekObdobja->modify("+1 day"); $zacetekObdobja->setTime(0, 0); } $zacetekObdobjaD = Functions::stringToDateTime($zacetekObdobja); if (!empty($steviloPonovitev)) { $this->expect(is_integer($steviloPonovitev), 'Število ponovitev ' . $steviloPonovitev . 'mora biti integer', 1001251); $this->expect($steviloPonovitev > 0, 'Število ponovitev (' . $steviloPonovitev . ') mora biti pozitivno število', 1001254); $strategijaPoStevilu = TRUE; } else { $strategijaPoStevilu = false; // strategija po tedenskih terminih } if (!empty($konecObdobja)) { $this->expectIsoDate($konecObdobja, $this->translate('Konec obdobja(' . $konecObdobja . ') ni datum v ISO8601 obliki'), 1001252); $konecObdobjaD = Functions::stringToDateTime($konecObdobja); $this->expect($zacetekObdobjaD < $konecObdobjaD, 'Konec obdobja(' . $konecObdobja . 'mora biti po začetku', 1001253); } else { $konecObdobjaD = null; } $this->expect(!empty($konecObdobja) || $strategijaPoStevilu, "Prisoten mora biti parameter ali konec obdobja ali število ponovitev", 1001255); if (!$strategijaPoStevilu) { /* * strategija kopiranja po tedenskih terminih */ $this->expect(!empty($zacetekObdobja) && !empty($konecObdobja) && !empty($tedenskiTermini), 'V kolikor ni parametra steviloPonovitev, so parametri ' . 'zacetekObdobja,konecObdobja in tedenskiTermini obvezni', 1001263); array_walk_recursive($tedenskiTermini, function ($val, $key) { $this->expect(in_array($val, [self::DOPOLDAN, self::POPOLDAN, self::ZVECER]), "Dovoljene vrednosti za tedenskiTermini so le" . self::DOPOLDAN . "," . self::POPOLDAN . "," . self::ZVECER, 1001264); }); array_walk($tedenskiTermini, function ($val, $key) { $this->expect(is_integer($key) && $key >= 0 && $key <= 7, "Dovoljeno ključi za tedenskiTermini so med 1 in 7", 1001266); $this->expect(is_array($val), "Vrednosti morajo biti v array-u", 1001267); }); /* * napolni $tedenskiTerminiBA (boolean array) iz parametra $tedenskiTermini , * tako da imamo v polju termine posortirane naraščujoče */ for ($dow = 1; $dow <= 7; $dow++) { // dan v tednu for ($dpz = 1; $dpz <= 3; $dpz++) { // dopoldan, popoldan , zvečer $tedenskiTerminiBA[$dow][$dpz] = false; //init } } foreach ($tedenskiTermini as $dow => $dpzA) { foreach ($dpzA as $dpz) { switch ($dpz) { case self::DOPOLDAN: $tedenskiTerminiBA[$dow][1] = true; break; case self::POPOLDAN: $tedenskiTerminiBA[$dow][2] = true; break; case self::ZVECER: $tedenskiTerminiBA[$dow][3] = true; break; default: $this->expect(false, "Dovoljene vrednosti za tedenskiTermini so le" . self::DOPOLDAN . ", " . self::POPOLDAN . ", " . self::ZVECER, 1001265); break; } } } $dopoldanOd = $this->preveriOdParameter($dopoldanOd, self::DOPOLDAN); $popoldanOd = $this->preveriOdParameter($popoldanOd, self::POPOLDAN); $zvecerOd = $this->preveriOdParameter($zvecerOd, self::ZVECER); /* * dopoldanOd < popoldanOd < zvečerOd */ $this->expect($dopoldanOd['h'] * 60 + $dopoldanOd['m'] < $popoldanOd['h'] * 60 + $popoldanOd['m'] && $popoldanOd['h'] * 60 + $popoldanOd['m'] < $zvecerOd['h'] * 60 + $zvecerOd['m'], "Veljati mora dopoldanOd < popoldanOd < zvecerOd", 1001268); } /* * izvedba kopiranj */ $stNovih = 0; $noviIds = []; if ($strategijaPoStevilu) { $zacetekNaslednjega = clone $zacetekObdobjaD; $zacetekNaslednjega->modify('-1 day'); $zacetekNaslednjega->setTime(intval($dogodek->getZacetek()->format('G')), intval($dogodek->getZacetek()->format('i'))); /* * glede na št. ponovitev */ $konec = FALSE; $i = 1; while ($i <= $steviloPonovitev && !$konec) { /* * določi naslednji datum dogodka */ do { $zacetekNaslednjega->modify("+1 day"); $ustrezenCas = TRUE; //init $this->preveriZacetekNaslednjega($zacetekNaslednjega, $konecObdobjaD, $upostevajSobote, $upostevajNedelje, $upostevajPraznike, $konec, $ustrezenCas); } while (!$ustrezenCas && !$konec); if (!$konec) { $this->kopirajEnega($dogodek, $zacetekNaslednjega, $noviIds, $stNovih); } $i++; } } else { /* * kopiranje po tedenskem vzorcu */ $zacetekNaslednjega = clone $zacetekObdobjaD; $zacetekNaslednjega->modify('-1 minute'); $konec = FALSE; while (!$konec) { /* * določi naslednji datum dogodka */ do { $najdenNoviZacetekKorak2 = false; $konec = false; while (!$konec && !$najdenNoviZacetekKorak2) { /* * najdi naslednji čas glede na dopoldanske, popoldanske in večerne termine */ $danNasl = intval($zacetekNaslednjega->format('N')); // dan $uraNasl = intval($zacetekNaslednjega->format('G')); // ura $minNasl = intval($zacetekNaslednjega->format('i')); // min /* * najkasneje do jutrišnjega dopoldanskega termina * -> $zacetekNaslednjega, $dow, $dpz */ $j = 1; $najdenNoviZacetekKorak1 = FALSE; while ($j <= 4 && !$najdenNoviZacetekKorak1) { $jmod = fmod($j - 1, 3) + 1; $hj = $this->hmDopPopZve($jmod, $dopoldanOd, $popoldanOd, $zvecerOd)['h']; $mj = $this->hmDopPopZve($jmod, $dopoldanOd, $popoldanOd, $zvecerOd)['m']; if ($j == 4 || $hj * 60 + $mj > $uraNasl * 60 + $minNasl) { $dpz = $jmod; $dow = $danNasl; if ($j == 4) { // naslednji dan dopoldan $dow++; $zacetekNaslednjega->modify('+1 day'); } $dow = fmod($dow - 1, 7) + 1; $zacetekNaslednjega->setTime($hj, $mj); $najdenNoviZacetekKorak1 = true; } $j++; } $this->expect($najdenNoviZacetekKorak1, "Novi začetek v koraku 1 ni najden " . $zacetekNaslednjega->format('d.m.Y H:i O'), 1001261); if (!is_null($konecObdobjaD) && $zacetekNaslednjega > $konecObdobjaD) { /* * $$ zaenkrat še vedno dovoli, da je konec dogodka po koncu obdobja */ $konec = true; } if ($tedenskiTerminiBA[$dow][$dpz]) { $najdenNoviZacetekKorak2 = true; } } $ustrezenCas = TRUE; //init if (!$konec) { $this->preveriZacetekNaslednjega($zacetekNaslednjega, $konecObdobjaD, $upostevajSobote, $upostevajNedelje, $upostevajPraznike, $konec, $ustrezenCas); } } while (!$ustrezenCas && !$konec); if (!$konec) { $this->kopirajEnega($dogodek, $zacetekNaslednjega, $noviIds, $stNovih); } } } /* * $$ ali kontrole, da se novi dogodki ne prekrivajo med sabo? */ $em->flush(); return $noviIds; }