function calculateAttentionScore() { global $user; logit(INFO, "Starting Attention Score Calculator"); $att = new AttentionAlerts(); $med = new Meds(); $user = new User(); $trends = new UserMetrics(); //check for flag if ($time = getFlag("MetiAttentionRun")) { $e = round((time() - $time) / 60, 2); //get hours if ($e > 360) { logit(WARN, "Error: calculateAttentionScore says it's been running for 6 hours " . __FILE__ . " on line: " . __LINE__); } logit(REPORT, " MetiAttention run aborted because it says it's still running. (Runtime: {$e} minutes, flag: MetiAttentionRun) in " . __FILE__ . " on line: " . __LINE__); return false; } else { setFlag("MetiAttentionRun", time()); } //ok flags are fine let's run this. Round up them doggies $sql = "SELECT * FROM users WHERE userType = 1 AND disabled = 0 "; if ($rc = dbQuery($sql)) { while ($row = dbFetch($rc)) { if (CLI_ECHO) { logit(INFO, "uRec: {$row["uRec"]}"); } $uRec = $row["uRec"]; $user->setUser($uRec); $user->getUser(); //$trends->setUser(); //$trends->getLatestSurveyCats(); $this->attentionAggregate = array(); $this->attentionAggregate["meds"] = 0; $this->attentionAggregate["survey"] = 0; $this->attentionAggregate["activity"] = 0; $this->attentionAggregate["medsAbs"] = 0; //remove med related scres $sql = "DELETE FROM attentionFlags WHERE uRec = '{$uRec}' AND (type = '{$att->attentionMeds}' OR type = '{$att->attentionMedAbs}') "; if ($rctemp = dbQuery($sql)) { //calc med score. $sql = "SELECT * FROM userMedCompliance WHERE uRec = '{$uRec}' AND period = '30' AND days = '30' "; if ($rcMed = dbQuery($sql)) { $med30 = array(); $med30Abs = array(); while ($rowMed = dbFetch($rcMed)) { $med30[$rowMed["medId"]] = $rowMed["taken"] / $rowMed["doses"]; //if patient has reported more than 50% record med compliance if ($rowMed["doses"] and $rowMed["unreported"] / $rowMed["doses"] < 0.5) { $med30Abs[$rowMed["medId"]] = $rowMed["taken"] / $rowMed["doses"]; } } } else { logit(WARN, " DB Error: {$sql} in " . __FILE__ . " on line: " . __LINE__); } //calculate abs med compliance if (is_array($med30) or is_array($med30Abs)) { $med->setUser(); $med->getUserMeds(TRUE, FALSE); } if (is_array($med30Abs)) { $temp = array(); //let's write flags for each foreach ($med30Abs as $key => $value) { $score = 0; if ($value < 0.8) { if ($value < 0.6) { $score = 3; } elseif ($value < 0.7) { $score = 2; } else { $score = 1; } $temp[] = $score; $in = ""; $in["uRec"] = $uRec; $in["ref"] = $key; $in["weight"] = $score; $in["type"] = $att->attentionMedAbs; $in["note"] = $med->userMeds[$key]["medOther"] . " compliance is " . round($value * 100, 0) . "%"; $in["expire"] = dbDate("+7 days"); $sql = "INSERT INTO attentionFlags " . makeSql($in, "insert"); if ($rcTemp = dbQuery($sql)) { } else { logit(WARN, " DB Error: {$sql} in " . __FILE__ . " on line: " . __LINE__); } } } //end for //get highest score if (count($temp) > 0) { $this->attentionAggregate["medsAbs"] = max($temp); } } $medAlertList = array(); //calculate window trend for med compliance //ok we got all of the 30s now let's get the 7s if (is_array($med30)) { foreach ($med30 as $key => $value) { $sql = "SELECT * FROM userMedCompliance WHERE medId = '{$key}' AND uRec = '{$uRec}' AND period = '7' AND days = '7' "; if ($rcMed = dbQuery($sql)) { while ($rowMed = dbFetch($rcMed)) { $med7 = $rowMed["taken"] / $rowMed["doses"]; if ($value > 0) { $d = ($med7 - $value) / $value; $delta = round($d * 100); } else { $delta = 0; } //got the delta, now let's calc att score $medScore = 0; if (is_numeric($delta) and $delta < -19) { if ($delta < -60) { $medScore = 3; } elseif ($delta < -40) { $medScore = 2; } else { $medScore = 1; } $this->attentionAggregate["meds"] = max($this->attentionAggregate["meds"], $medScore); //save score for this med. $in = ""; $in["uRec"] = $uRec; $in["ref"] = $key; $in["weight"] = $medAlertList[] = $medScore; $in["type"] = $att->attentionMeds; $in["note"] = $med->userMeds[$key]["medOther"] . " compliance has declined by " . abs($delta) . "%"; $in["expire"] = dbDate("+7 days"); $sql = "INSERT INTO attentionFlags " . makeSql($in, "insert"); if ($rcTemp = dbQuery($sql)) { } else { logit(WARN, " DB Error: {$sql} in " . __FILE__ . " on line: " . __LINE__); } } } } else { logit(WARN, " DB Error: {$sql} in " . __FILE__ . " on line: " . __LINE__); } } //end med 30 loop } //aggregate meds //if (count($medAlertList) > 0 ) $this->attentionAggregate["meds"] = array_sum($medAlertList) / count($medAlertList); } else { logit(WARN, " DB Error: {$sql} in " . __FILE__ . " on line: " . __LINE__); } //lookup survey $sql = "DELETE FROM attentionFlags WHERE uRec = '{$uRec}' AND type = '{$att->attentionSurvey}' "; if ($rctemp = dbQuery($sql)) { $trends->setUser(); $s = $trends->getLatestSurveyCats(); $delta = $s["min"]; $surveyScore = 0; if (is_numeric($delta) and $delta < -11) { if ($delta < -39) { $surveyScore = 3; } elseif ($delta < -19) { $surveyScore = 2; } else { $surveyScore = 1; } $this->attentionAggregate["survey"] = max($this->attentionAggregate["survey"], $surveyScore); //save score $in = ""; $in["uRec"] = $uRec; $in["ref"] = 0; $in["weight"] = $surveyScore; $in["type"] = $att->attentionSurvey; $in["note"] = "We\\'ve noticed a drop in some survey answers in the past 30 days."; $in["expire"] = dbDate("+7 days"); $sql = "INSERT INTO attentionFlags " . makeSql($in, "insert"); if ($rcTemp = dbQuery($sql)) { } else { logit(WARN, " DB Error: {$sql} in " . __FILE__ . " on line: " . __LINE__); } } } else { logit(WARN, " DB Error: {$sql} in " . __FILE__ . " on line: " . __LINE__); } //lookup activity $sql = "DELETE FROM attentionFlags WHERE uRec = '{$uRec}' AND type = '{$att->attentionActivity}' "; if ($rctemp = dbQuery($sql)) { $delta = $row["activityChange"]; $activityScore = 0; if (is_numeric($delta) and $delta < -19) { if ($delta < -59) { $activityScore = 3; } elseif ($delta < -39) { $activityScore = 2; } else { $activityScore = 1; } $this->attentionAggregate["activity"] = $activityScore; //save score $in = ""; $in["uRec"] = $uRec; $in["ref"] = 0; $in["weight"] = $activityScore; $in["type"] = $att->attentionActivity; $in["note"] = "C3HealthLink interaction has dropped by " . abs($delta) . "% in the past 30 days."; $in["expire"] = dbDate("+7 days"); $sql = "INSERT INTO attentionFlags " . makeSql($in, "insert"); if ($rcTemp = dbQuery($sql)) { } else { logit(WARN, " DB Error: {$sql} in " . __FILE__ . " on line: " . __LINE__); } } } //let's get the other alert scores $sqlArr = array(); $sqlArr["attentionDiaryRank"] = "SELECT MAX(weight) FROM attentionFlags WHERE uRec= {$uRec} AND type = {$att->attentionDiaryRank} "; $sqlArr["attentionDiaryKeyword"] = "SELECT MAX(weight) FROM attentionFlags WHERE uRec= {$uRec} AND type = {$att->attentionDiaryKeyword} "; $sqlArr["attentionSideEffect"] = "SELECT MAX(weight) FROM attentionFlags WHERE uRec= {$uRec} AND type = {$att->attentionSideEffect} "; $sqlArr["attentionMedComment"] = "SELECT MAX(weight) FROM attentionFlags WHERE uRec= {$uRec} AND type = {$att->attentionMedComment} "; foreach ($sqlArr as $key => $value) { $this->attentionAggregate[$key] = 0; if ($rcTemp = dbQuery($value)) { if ($rowTemp = dbFetch($rcTemp)) { $t = array_pop($rowTemp); if ($t) { $this->attentionAggregate[$key] = $t; } //logit(INFO,"$key : {$this->attentionAggregate[$key]}"); } } else { logit(WARN, " DB Error: {$sql} in " . __FILE__ . " on line: " . __LINE__); } } //logit(INFO,"ME: ".print_r($this->attentionAggregate,1)); //calculate /* The max score is 18 but it's very rare anyone will hit max in all six categories so we assume anything above 6 is a red alert */ $attAggTotal = array_sum($this->attentionAggregate); if ($attAggTotal > 0 and $attAggTotal < 4) { $attScore = 2; } elseif ($attAggTotal > 3 and $attAggTotal < 7) { $attScore = 3; } elseif ($attAggTotal > 6) { $attScore = 4; } elseif ($user->active) { $attScore = 1; } else { $attScore = 0; } //logit(INFO,"SCORE: $attScore\t MEAN: $attAggMean\tTOTAL: $attAggTotal\tMAX: $attMax"); // $sql = "UPDATE users SET attScore = $attScore WHERE uRec = '$uRec' "; // if (!$rcTemp = dbQuery($sql)) logit(WARN,"Error: in ".__FILE__." on line: ".__LINE__); } //urec loop } else { logit(WARN, " DB Error: {$sql} in " . __FILE__ . " on line: " . __LINE__); } clearFlag("MetiAttentionRun"); logit(INFO, "Ending Attention Score Calculator"); return true; }
function getArticleHTML() { /* Codes used in $this->status tp=total pages cp=current page */ global $config; $str = " "; //prevents null return $error = false; $this->loadArticleData(); if (is_array($this->art)) { //set left rail content if (trim($this->art["rail1"])) { $config["genVar"]["rail1"] = "<div style='padding: 0px 16px 0px 16px'>" . $this->art["rail1"] . "</div><br><br>"; } else { $config["genVar"]["rail1"] = ""; } $config["genVar"]["rail2"] = $this->art["rail2"]; //set printer friendly link $config["genVar"]["pf"] = "/{$config["cmsIdentifier"]}/printerfriendly/art{$this->art["artId"]}.html"; //determine if CME is on or off if (CME and dbDate() < $this->art["cmeExpire"] and $this->art["cmeStatus"] == 2) { $this->cme = true; } else { $this->cme = false; } //set footnote counter and start timer if (!$this->status["fcn"]) { $this->status["fcn"] = 1; } if (!is_numeric($this->status["start"])) { $this->status["start"] = time(); } //determine if art is multipages if ($this->cme and !$cme->needCredits and $this->art["inline"]) { $this->getPages(); } else { $this->page[1] = $this->art["body"]; } //START CONDITIONAL PROCESSING //check for printer friendly if (preg_match("|/printerfriendly/|", $_SERVER["SCRIPT_URL"], $match)) { define("PRINTERFRIENDLY", true, false); } else { define("PRINTERFRIENDLY", false, false); } //add date for all //$dateStamp="<div class='newsDate' style='padding: 0px'>".date("F j, Y",strtotime($this->art["releaseDate"]))."</div>"; $dateStamp = "<div class='newsDate' style='padding: 0px'>" . date("F j, Y", strtotime($this->art["releaseDate"])) . "</div>"; //start pager $pageNav = false; //break into pages if (!PRINTERFRIENDLY and $_GET["ts"] != "fullpage") { $this->getPages(); //add image /* if (strlen($this->art["image"])) { $this->page[1] = "<div style='float: left; padding: 12px;'> <img src = '{$this->art["image"]}'> </div>" . $this->page[1]; } */ $this->pageCount = count($this->page); //identify page current if (is_numeric($_GET["getPage"])) { $this->currentPage = $_GET["getPage"]; } else { $this->currentPage = 1; } $this->art["body"] = $this->page[$this->currentPage]; if ($this->pageCount == $this->currentPage and $this->art["type"] != 4) { $this->art["body"] .= $dateStamp; } //create page nav if ($this->pageCount > 1) { $nav = $this->pageNav(); //$this->art["body"]=$nav.$this->art["body"].$nav; //top Nav $this->art["body"] = $this->art["body"] . $nav; //bottom nav } } else { $this->art["body"] = preg_replace("/\\[\\[pagebreak\\]\\]/i", "", $this->art["body"]); $this->currentPage = 1; } //add date for news -- MOVED TO ABOVE //if ($this->art["type"]==1) $this->art["body"]=$this->art["body"]."<div class='newsDate' style='padding: 0px'>".date("F j, Y",strtotime($this->art["releaseDate"]))."</div>"; // -- END CONDITIONAL PROCESSING $this->status["tp"] = count($this->page); //set page if (is_numeric($this->status["cp"])) { if ($this->status["cp"] < $this->status["tp"]) { $this->status["cp"]++; } else { $this->status["cp"] = $this->status["tp"]; } } else { $this->status["cp"] = 1; } //set pagecontent //$this->art["body"]=$this->page[$this->status["cp"]]; //get template if (PRINTERFRIENDLY) { $template = "{$config["siteVault"]}/templates/printerFriendly.html"; } else { $template = "{$config["siteVault"]}/templates{$this->art["template"]}"; } if (is_file($template) and $htmlPage = getFile($template)) { //pre-process inserts $htmlPage = processInserts($htmlPage); //process art editor internal tags while (preg_match_all("/\\[\\[(.*?):(.*?)\\]\\]/is", $this->art["body"], $tagMatch)) { //dumpVar($tagMatch); //replace tags foreach ($tagMatch[0] as $key => $tag) { $cmd = $tagMatch[1][$key]; $item = trim($tagMatch[2][$key]); switch (true) { case $cmd == "FN": preg_match("/[0-9]?:([0-9]*)/", $item, $match); $item = $match[1]; //if (!$this->status["fnCounter"][$this->art["footnote"][$item]["fnId"]]) $this->status["fnCounter"][$this->art["footnote"][$item]["fnId"]]=$this->status["fcn"]++; if (is_numeric($this->art["footnote"][$item]["fnNum"])) { $number = $this->art["footnote"][$item]["fnNum"]; } else { $number = "*"; } if (!PRINTERFRIENDLY) { $swap = "<a href='javascript: void(null);' class='footnote'\r\n\t\t\t\t\t\tonMouseover=\"fixedtooltip('" . htmlentities(addslashes($this->art["footnote"][$item]["fnText"]), ENT_QUOTES, "UTF-8", false) . "', this, event, '250px')\" onMouseout=\"delayhidetip()\">(" . $number . ")</a>"; } else { $pfFootnoteDisplay[] = $number; $pfFootnoteText[] = htmlentities($this->art["footnote"][$item]["fnText"], ENT_QUOTES); $swap = "<font class='footnote'>({$number})</font>"; } break; case $cmd == "G": preg_match("/([0-9]*):(.*)/", $item, $match); if (!PRINTERFRIENDLY) { $sql = "SELECT * FROM glossary WHERE gid='{$match[1]}'"; if ($rc = dbQuery($sql) and $row = dbFetch($rc)) { $txt = "<b>{$row["term"]}</b>: {$row["definition"]}"; $txt = htmlentities(addslashes(str_replace("\n", "\\n", $txt)), ENT_QUOTES, "UTF-8", false); //$txt=htmlentities(str_replace("\n","\\n",$txt),ENT_QUOTES,"ISO-8859-1",false); $swap = "<a href='javascript: void(null);' class='glossary'\r\n\t\t\t\t\t\t\t\tonMouseover=\"fixedtooltip('{$txt}', this, event, '400px')\" onMouseout=\"delayhidetip()\">" . $match[2] . "</a>"; } else { $swap = $match[2]; } } else { $swap = $match[2]; } break; case $cmd == "CA": preg_match("/([0-9]*)/", $item, $match); $item = $match[1]; //if (!$this->status["fnCounter"][$this->art["footnote"][$item]["fnId"]]) $this->status["fnCounter"][$this->art["footnote"][$item]["fnId"]]=$this->status["fcn"]++; if (is_numeric($this->art["callout"][$item]["caNum"])) { $number = $this->art["callout"][$item]["caNum"]; } else { $number = "*"; } $swap = "<div id='calloutDiv' style='visibility:block;' >{$this->art["callout"][$item]["caText"]}</div>"; break; case $cmd == "PL": $swap = $this->portalLink($item); break; } $swap = str_replace("\$", "\\\$", $swap); //fix dollar sign problem $pattern = "|" . preg_quote($tag) . "|is"; //echo "$tag: $pattern : ".strlen($htmlPage)."<br>"; $this->art["body"] = preg_replace($pattern, $swap, $this->art["body"]); $swap = ""; } } //get template tags while (preg_match_all("/<#(art.*?) (.*?)#>/is", $htmlPage, $tagMatch)) { //replace tags foreach ($tagMatch[0] as $key => $tag) { $cmd = $tagMatch[1][$key]; $item = trim($tagMatch[2][$key]); switch (true) { case $cmd == "artfield": if (preg_match("/field=\"(.*)\"/iU", $item, $match)) { $field = $match[1]; } if ($field == "title") { if (is_numeric($this->art["conference"]) and $this->art["conference"] != 31) { $title = $this->confNames[$this->art["conference"]] . ": "; } $title .= $this->art["headline"] . " - The Doctor"; $swap = $title; break; } $swap = $this->art[$field]; //process wrappers from tags if ($swap) { if (preg_match("/class=\"(.*)\"/iU", $item, $match)) { $class = " class='{$match[1]}'"; } else { $class = ""; } if (preg_match("/prefix=\"(.*)\"/iU", $item, $match)) { $swap = "{$match[1]}{$swap}"; } if (preg_match("/suffix=\"(.*)\"/iU", $item, $match)) { $swap = "{$swap}{$match[1]}"; } if (preg_match("/wrapper=\"(.*)\"/iU", $item, $match)) { $swap = "<{$match[1]}{$class}>{$swap}</{$match[1]}>"; } if (preg_match("/html=\"omit\"/iU", $item, $match)) { $swap = preg_replace("/[\n\r]/", "", strip_tags($swap)); } } break; case $item == "meta": $url = "{$config["url"]}" . articleUrl($this->artId); if (is_array($this->art["subtopics"])) { $keywords = implode(",", $this->confNames); } if ($this->art["keywords"]) { $keywords .= "," . $this->art["keywords"]; } if ($keywords) { $swap = "<META name=\"keywords\" content=\"{$keywords}\">\n"; } if ($this->art["summary"]) { $description = $this->art["summary"]; } elseif ($this->art["tipLong"]) { $description = $this->art["tipLong"]; } elseif ($this->art["tipShort"]) { $description = $this->art["tipShort"]; } else { $description = $this->art["headline"]; } if (strlen($this->art["image"])) { $ogImage = "<meta property='og:image' content='http://www.thedoctorwillseeyounow.com/img_{$this->artId}.jpg'/>"; } else { $ogImage = "<meta property='og:image' content='http://www.thedoctorwillseeyounow.com/images/FB_no_image.jpg'/>"; } $swap .= "<META name=\"description\" content=\"{$description}\">\r\n{$ogImage}\r\n<link rel='original-source' href='{$url}' >\r\n<link rel='syndication-source' href='{$url}' >\r\n<link rel='canonical' href='{$url}' >\n"; break; case $item == "headline": if ($this->art["type"] == 1) { $class = "News"; } elseif ($this->art["type"] == 2) { $class = "Feature"; } elseif ($this->art["type"] == 4) { $class = "Portal"; } else { $class = "Books"; } // if ($this->currentPage==1 OR $this->art["type"]==3) $swap="<div class='headline{$class}'> // turns off 2nd page for books if ($this->currentPage == 1) { $swap = "<h1 class='headline{$class}'>\r\n\t\t\t\t\t\t<#artfield field=\"headline\"#>\r\n\t\t\t\t\t\t</h1>\r\n\t\t\t\t\t\t<div class='byline{$class}'>\r\n\t\t\t\t\t\t<#artfield field=\"byline\"#>\r\n\t\t\t\t\t\t</div>"; } else { $swap = "<br><div class='byline{$class}'>\r\n\t\t\t\t\t\t<#artfield field=\"byline\"#>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t<h1 class='headline{$class}2'>\r\n\t\t\t\t\t\t<#artfield field=\"headline\"#>\r\n\t\t\t\t\t\t</h1>\r\n\t\t\t\t\t\t"; } if ($this->art["type"] == 1) { $swap .= "<div style='border-bottom: 4px solid #377991; margin-bottom: 10px; height: 6px;'> </div>"; } else { $swap .= "<div style='border-bottom: 4px solid #f10065; margin-bottom: 10px; height: 6px;'> </div>"; } //big kludge for portals if ($this->art["type"] == 4) { $swap = "<h1 class='headline{$class}'>\r\n\t\t\t\t\t\t<#artfield field=\"headline\"#>\r\n\t\t\t\t\t\t</h1>"; } break; case $item == "portalRail": if ($this->portalLinks[$this->art["conference"]]["rail"]) { $swap = $this->portalLinks[$this->art["conference"]]["rail"]; } break; case $item == "portalBanner": if ($this->portalLinks[$this->art["conference"]]["banner"]) { $swap = $this->portalLinks[$this->art["conference"]]["banner"]; } break; case $item == "leftRailAd": if ($this->leftRailAd[$this->art["conference"]]) { $swap = $this->leftRailAd[$this->art["conference"]]; } break; } $swap = str_replace("\$", "\\\$", $swap); //fix dollar sign problem $pattern = "|" . preg_quote($tag) . "|is"; //echo "$tag: $pattern : ".strlen($htmlPage)."<br>"; $htmlPage = preg_replace($pattern, $swap, $htmlPage); $swap = ""; } } $str = $htmlPage; //print footnotes for printer friendly if (PRINTERFRIENDLY and is_array($pfFootnoteDisplay)) { asort($pfFootnoteDisplay); $dupCheck = array(); $str .= "<hr><div class='headlineFeature'>Footnotes</div><br><table width='680'>"; foreach ($pfFootnoteDisplay as $key => $value) { if (!in_array($pfFootnoteDisplay[$key], $dupCheck)) { $str .= "<tr><td>{$pfFootnoteDisplay[$key]}</td><td>{$pfFootnoteText[$key]}</td></tr>\n"; $dupCheck[] = $pfFootnoteDisplay[$key]; } } $str .= "</table>"; } } else { logit(INFO, "Could not open template {$template} in getArticleHTML in " . __FILE__ . " on line: " . __LINE__); $error = true; } } else { if ($_SERVER["HTTP_REFERER"]) { logit(WARN, "did not find art array in getArticleHTML REFER: {$_SERVER["HTTP_REFERER"]} in " . __FILE__ . " on line: " . __LINE__); } else { logit(INFO, "did not find art array in getArticleHTML REFER: {$_SERVER["HTTP_REFERER"]} in " . __FILE__ . " on line: " . __LINE__); } $error = true; } //dumpVar($this->page); //if ($error) return getFile($config["errorpage"]); if ($error) { return false; } return $str; }
function fetchBloodPressure($start = null, $end = null, $nullPad = false) { $sql = "SELECT * FROM deviceData WHERE device={$this->device} AND uRec='{$this->uRec}' " . "AND ( metric=" . $this->systolic_bp . " OR metric=" . $this->diastolic_bp . ")"; //default to last 30 days if (!$end) { $end = dbDate(); } if (!$start) { $start = dbDate(strtotime("-30 days")); } if ($start != null) { $sql .= " AND date >= '" . $start . "'"; } if ($end != null) { $sql .= " AND date <= '" . $end . "'"; } $sql .= " ORDER BY date ASC"; $data = array(); if ($rc = dbQuery($sql)) { while ($row = dbFetch($rc)) { if ($row['metric'] == $this->diastolic_bp) { $data[$row['date']]['dia'] = $row['value']; } elseif ($row['metric'] == $this->systolic_bp) { $data[$row['date']]['sys'] = $row['value']; } } } else { logit(WARN, " DB Error: {$sql} in " . __FILE__ . " on line: " . __LINE__); } $out = array(); $datesRecorded = array(); foreach ($data as $date => $vals) { $out[] = array('date' => $date, 'sys' => $vals['sys'], 'dia' => $vals['dia']); $datesRecorded[] = $date; } if ($nullPad == true) { if (strtotime($start) < strtotime("-1 years")) { $seriesBegin = new DateTime($out[0]['date']); } else { $seriesBegin = new DateTime($start); } $seriesEnd = new DateTime($end); $interval = DateInterval::createFromDateString('1 day'); $period = new DatePeriod($seriesBegin, $interval, $seriesEnd); foreach ($period as $dt) { $date = $dt->format("Y-m-d"); if (!in_array($date, $datesRecorded)) { $out[] = array('date' => $date, 'sys' => null, 'dia' => null); } } usort($out, function (array $a, array $b) { return strtotime($a["date"]) - strtotime($b["date"]); }); } return $out; }