private static function generate_data_for_day(SS_Datetime $date)
 {
     $data = array('timestamp' => time(), 'searchDate' => $date->Format("Y-m-d"), 'collections' => array('events' => array(), 'galleries' => array(), 'locations' => array()));
     $galleryIDs = array();
     $locationIDs = array();
     // Get events
     $where = sprintf("DATE(`StartDate`) = '%s'", $date->Format('Y-m-d'));
     $events = Event::get()->where($where)->exclude(array("GalleryID" => 0, "Gallery.LocationID" => 0));
     foreach ($events as $event) {
         $galleryIDs[] = $event->GalleryID;
         $data['collections']['events'][] = $event->forAPI();
     }
     // Get galleries
     $galleries = Gallery::get()->byIDs(array_unique($galleryIDs));
     foreach ($galleries as $gallery) {
         $locationIDs[] = $gallery->LocationID;
         $data['collections']['galleries'][] = $gallery->forAPI();
     }
     // Get locations
     $locations = Location::get()->byIDs(array_unique($locationIDs));
     foreach ($locations as $location) {
         $data['collections']['locations'][] = $location->forAPI();
     }
     return $data;
 }
 /**
  * @param $data
  * @param $field
  * @param array $options
  * @return string
  * @throws ValidationException
  */
 public static function validate_datetime($data, $field, $options = [])
 {
     $options = array_merge(['required' => true], $options);
     $required = $options['required'];
     if (isset($data[$field]) && is_string($data[$field])) {
         $date = $data[$field];
         $dateTime = new SS_Datetime();
         $dateTime->setValue($date);
         if (!$dateTime->getValue()) {
             throw new ValidationException("No valid datetime given.");
         }
         return $dateTime->Format('Y-m-d H:i:s');
     } else {
         if ($required) {
             throw new ValidationException("No {$field} given, but {$field} is required");
         }
     }
 }
    /**
     * this function will add more metatags to your template -
     * make sure to add it at the start of your metatags
     * We leave the / closing tags here, but they are not needed
     * yet not invalid in html5
     * @param Boolean $includeTitle - include the title tag
     * @param Boolean $addExtraSearchEngineData - add extra tags describing the page
     * @return String (HTML)
     */
    function ExtendedMetatags($includeTitle = true, $addExtraSearchEngineData = true)
    {
        $this->addBasicMetatagRequirements();
        $cacheKey = 'metatags_ExtendedMetaTags_' . abs($this->owner->ID) . preg_replace("/[^a-z0-9]/i", "", $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
        $cache = SS_Cache::factory($cacheKey);
        $tags = $cache->load($cacheKey);
        if (!$tags) {
            $themeFolder = SSViewer::get_theme_folder() . '/';
            $tags = "";
            $page = $this->owner;
            $siteConfig = SiteConfig::current_site_config();
            $title = "";
            if (Config::inst()->get("MetaTagsContentControllerEXT", "use_separate_metatitle") == 1) {
                $title = $page->MetaTitle;
            } else {
                $title = $page->Title;
                if (!$title) {
                    $title = $page->MenuTitle;
                }
            }
            //base tag
            $base = Director::absoluteBaseURL();
            $tags .= "<base href=\"{$base}\" />";
            if ($page->MetaDescription) {
                $description = '
			<meta name="description" content="' . Convert::raw2att($page->MetaDescription) . '" />';
                $noopd = '';
            } else {
                $noopd = "NOODP, ";
                $description = '';
            }
            $lastEdited = new SS_Datetime();
            $lastEdited->value = $page->LastEdited;
            //use base url rather than / so that sites that aren't a run from the root directory can have a favicon
            $faviconBase = $base;
            $faviconFileBase = "";
            if ($includeTitle) {
                $titleTag = '
			<title>' . trim(Convert::raw2att($siteConfig->PrependToMetaTitle . ' ' . $title . ' ' . $siteConfig->AppendToMetaTitle)) . '</title>';
            } else {
                $titleTag = '';
            }
            $tags .= '
			<meta charset="utf-8" />' . $titleTag;
            $hasBaseFolderFavicon = false;
            if (file_exists(Director::baseFolder() . '/' . $faviconFileBase . 'favicon.ico')) {
                $hasBaseFolderFavicon = true;
                //ie only...
                $tags .= '
			<link rel="SHORTCUT ICON" href="' . $faviconBase . 'favicon.ico" />';
            }
            if (!$page->ExtraMeta && $siteConfig->ExtraMeta) {
                $page->ExtraMeta = $siteConfig->ExtraMeta;
            }
            if (!$siteConfig->MetaDataCopyright) {
                $siteConfig->MetaDataCopyright = $siteConfig->Title;
            }
            if ($addExtraSearchEngineData) {
                $tags .= '
			<meta name="robots" content="' . $noopd . 'all, index, follow" />
			<meta name="googlebot" content="' . $noopd . 'all, index, follow" />
			<meta name="rights" content="' . Convert::raw2att($siteConfig->MetaDataCopyright) . '" />
			<meta name="created" content="' . $lastEdited->Format("Ymd") . '" />
			<meta name="viewport" content="' . Config::inst()->get("MetaTagsContentControllerEXT", "viewport_setting") . '" />
				' . $page->ExtraMeta . $description;
            }
            $tags .= $this->OGTags();
            $tags .= $this->iconTags($faviconBase, $hasBaseFolderFavicon);
            $cache->save($tags, $cacheKey);
        }
        return $tags;
    }
 /**
  * Parse URL parameters and set the filters
  *
  * @param boolean $produceErrorMessages Set to false to omit session messages.
  * @return array
  */
 public function parseParams($produceErrorMessages = true)
 {
     $tag = $this->request->getVar('tag');
     $from = $this->request->getVar('from');
     $to = $this->request->getVar('to');
     $year = $this->request->getVar('year');
     $month = $this->request->getVar('month');
     if ($tag == '') {
         $tag = null;
     }
     if ($from == '') {
         $from = null;
     }
     if ($to == '') {
         $to = null;
     }
     if ($year == '') {
         $year = null;
     }
     if ($month == '') {
         $month = null;
     }
     if (isset($tag)) {
         $tag = (int) $tag;
     }
     if (isset($from)) {
         $from = urldecode($from);
         $parser = new SS_Datetime();
         $parser->setValue($from);
         $from = $parser->Format('Y-m-d');
     }
     if (isset($to)) {
         $to = urldecode($to);
         $parser = new SS_Datetime();
         $parser->setValue($to);
         $to = $parser->Format('Y-m-d');
     }
     if (isset($year)) {
         $year = (int) $year;
     }
     if (isset($month)) {
         $month = (int) $month;
     }
     // If only "To" has been provided filter by single date. Normalise by swapping with "From".
     if (isset($to) && !isset($from)) {
         list($to, $from) = array($from, $to);
     }
     // Flip the dates if the order is wrong.
     if (isset($to) && isset($from) && strtotime($from) > strtotime($to)) {
         list($to, $from) = array($from, $to);
         if ($produceErrorMessages) {
             Session::setFormMessage('Form_DateRangeForm', _t('DateUpdateHolder.FilterAppliedMessage', 'Filter has been applied with the dates reversed.'), 'warning');
         }
     }
     // Notify the user that filtering by single date is taking place.
     if (isset($from) && !isset($to)) {
         if ($produceErrorMessages) {
             Session::setFormMessage('Form_DateRangeForm', _t('DateUpdateHolder.DateRangeFilterMessage', 'Filtered by a single date.'), 'warning');
         }
     }
     return array('tag' => $tag, 'from' => $from, 'to' => $to, 'year' => $year, 'month' => $month);
 }
    public function DetailedForecast($days = 5, $render = true)
    {
        $forecast = OpenWeatherMapAPI::detailed_forecast($this->OpenWeatherMapStationID, $days);
        $forecasts = array();
        $list = $forecast->list;
        $result = new ArrayList();
        $ctr = 0;
        $ctrmax = 8 * $days;
        // chart data
        $labels = array();
        $temperaturedata = array();
        $rainfalldata = array();
        $humiditydata = array();
        $cloudcoverdata = array();
        foreach ($list as $forecastdata) {
            error_log('Iterating list for forecast data');
            $fc = $this->json_weather_to_data_object($forecastdata);
            if (isset($forecastdata->rain)) {
                $fc->Rain3Hours = $forecastdata->rain->{'3h'};
            } else {
                $fc->Rain3Hours = 0;
            }
            $dt = $forecastdata->dt;
            $ssdt = new SS_Datetime();
            $ssdt->setValue($dt);
            $fc->DateTime = $ssdt;
            $result->push($fc);
            $q = '"';
            array_push($labels, $q . $ssdt->Format('H:i') . $q);
            array_push($temperaturedata, $q . $fc->TemperatureCurrent . $q);
            error_log('RAIN - pushing ' . $fc->Rain3Hours);
            array_push($rainfalldata, $q . $fc->Rain3Hours . $q);
            array_push($humiditydata, $q . $fc->Humidity . $q);
            array_push($cloudcoverdata, $q . $fc->CloudCoverPercentage . $q);
            $ctr++;
            if ($ctr >= $ctrmax) {
                break;
            }
        }
        $labelcsv = implode(',', $labels);
        $temperaturecsv = implode(',', $temperaturedata);
        $rainfallcsv = implode(',', $rainfalldata);
        $cloudcovercsv = implode(',', $cloudcoverdata);
        $humiditycsv = implode(',', $humiditydata);
        error_log($rainfallcsv);
        // initialise variables for templates
        $varsarray = array('Labels' => $labelcsv, 'Temperatures' => $temperaturecsv, 'Rainfall' => $rainfallcsv, 'Humidity' => $humiditycsv, 'CloudCover' => $cloudcovercsv, 'Forecasts' => $result, 'Station' => $this);
        $vars = new ArrayData($varsarray);
        // get the temperature JavaScript from a template.  Override in your own theme as desired
        $chartOptions = $vars->renderWith('ChartOptionsJS');
        $vars->setField('ChartOptions', $chartOptions);
        $temperatureJS = $vars->renderWith('TemperatureChartJS');
        $rainfallJS = $vars->renderWith('RainfallChartJS');
        $cloudhumidyJS = $vars->renderWith('CloudCoverHumidityChartJS');
        if ($render) {
            Requirements::css('openweathermap/css/openweathermap.css');
            Requirements::javascript('openweathermap/javascript/chart.min.js');
            Requirements::customScript(<<<JS
\t\t\t{$temperatureJS}
\t\t\t{$rainfallJS}
\t\t\t{$cloudhumidyJS}
JS
);
            return $vars->renderWith('ForecastDetailed');
        } else {
            $vars->setField('ChartsJavascript', $temperatureJS . "\n" . $rainfallJS . "\n" . $cloudhumidyJS . "\n");
        }
        $this->TemplateVars = $vars;
    }