protected function displayContent()
 {
     $stats = $this->getPhotoStats();
     if ($stats->last_date === null) {
         echo Pinhole::_('No photos have been added.');
     } else {
         $locale = SwatI18NLocale::get();
         $first_date = new SwatDate($stats->first_date);
         $last_date = new SwatDate($stats->last_date);
         echo '<ul>';
         $li_tag = new SwatHtmlTag('li');
         $li_tag->setContent(sprintf(Pinhole::_('%s photos have been uploaded since ' . '<a href="%stag?date.date=%s">%s</a>'), $locale->formatNumber($stats->photo_count), $this->app->config->pinhole->path, $first_date->formatLikeIntl('yyyy-MM-dd'), $first_date->formatLikeIntl(SwatDate::DF_DATE)), 'text/xml');
         $li_tag->display();
         $days = $last_date->diff($first_date)->days;
         $avg = round((double) $stats->photo_count / (double) $days, 2);
         $li_tag = new SwatHtmlTag('li');
         $li_tag->setContent(sprintf(Pinhole::_('Approximately %s photos have been uploaded ' . 'per day'), $locale->formatNumber($avg)));
         $li_tag->display();
         $li_tag->setContent(sprintf(Pinhole::_('Last photo uploaded on ' . '<a href="%stag?date=%s">%s</a>'), $this->app->config->pinhole->path, $last_date->formatLikeIntl('yyyy-MM-dd'), $last_date->formatLikeIntl(SwatDate::DF_DATE)), 'text/xml');
         $li_tag->display();
         $tag_stats = $this->getTagStats();
         if ($tag_stats->tag_count > 0) {
             $li_tag = new SwatHtmlTag('li');
             $li_tag->setContent(sprintf(Pinhole::_('<a href="%s/tags/alphabetical">%s tags</a> ' . 'have been added'), $this->app->config->pinhole->path, $locale->formatNumber($tag_stats->tag_count)), 'text/xml');
             $li_tag->display();
             $a_tag = new SwatHtmlTag('a');
             $a_tag->setContent($tag_stats->popular_tag_title);
             $a_tag->href = $this->app->config->pinhole->path . 'tag?' . SwatString::minimizeEntities($tag_stats->popular_tag_name);
             $li_tag = new SwatHtmlTag('li');
             $li_tag->setContent(sprintf(Pinhole::_('The most popular tag “%s” has %s photos'), (string) $a_tag, $locale->formatNumber($tag_stats->popular_tag_count)), 'text/xml');
             $li_tag->display();
         }
         echo '</ul>';
     }
 }
Example #2
0
 /**
  * Gets translatable string resources for the JavaScript object for
  * this gadget
  *
  * @return string translatable JavaScript string resources for this gadget.
  */
 protected function getInlineJavaScriptTranslations()
 {
     $throbber_text = Blorg::_('loading …');
     $visit_text = Blorg::_('Visit the Last.fm page for this track');
     $none_text = Blorg::_('‹none›');
     $months = array();
     $short_months = array();
     $date = new SwatDate('2000-01-01T00:00:00Z');
     for ($i = 1; $i <= 12; $i++) {
         $months[] = SwatString::quoteJavaScriptString($date->formatLikeIntl('MMMM'));
         $short_months[] = SwatString::quoteJavaScriptString($date->formatLikeIntl('MMM'));
         $date->setMonth($i + 1);
     }
     $months = implode(', ', $months);
     $short_months = implode(', ', $short_months);
     return sprintf("BlorgLastFmGadget.throbber_text = '%s';\n" . "BlorgLastFmGadget.visit_text = '%s';\n" . "BlorgLastFmGadget.none_text = '%s';\n" . "BlorgLastFmGadget.months = [%s];\n" . "BlorgLastFmGadget.short_months = [%s];\n", $throbber_text, $visit_text, $none_text, $months, $short_months);
 }
 public function getCampaignShortname()
 {
     if ($this->send_date === null) {
         $shortname = Deliverance::_('DRAFT');
     } else {
         $shortname = $this->send_date->formatLikeIntl('yy-MM-dd');
     }
     return $shortname;
 }
 protected function getContainer()
 {
     $date = new SwatDate();
     if (isset($this->app->memcache)) {
         $cache_key = sprintf('PinholeDateBrowserGadget.getContent.%s.%s', $date->formatLikeIntl('MM/yyyy'), $this->app->session->isLoggedIn() ? 'private' : 'public');
         $container = $this->app->memcache->getNs('photos', $cache_key);
         if ($container !== false) {
             return $container;
         }
     }
     $container = new SwatContainer();
     $months = $this->getMonths();
     if (count($months) == 0) {
         $content = new SwatContentBlock();
         $content->content = Pinhole::_('No photos have been uploaded yet.');
         $container->add($content);
         return $container;
     }
     $months_array = array();
     foreach ($months as $month) {
         $date = new SwatDate($month->photo_date);
         $key = $date->getYear() . '/' . $date->getMonth();
         $months_array[$key] = $month;
     }
     $locale = SwatI18NLocale::get();
     $start_date = new SwatDate($months->getFirst()->photo_date);
     $start_year = $start_date->getYear();
     $index = count($months) - 1;
     $end_date = new SwatDate($months->getByIndex($index)->photo_date);
     $end_year = $end_date->getYear();
     $date = new SwatDate();
     $date->clearTime();
     for ($year = $start_year; $year >= $end_year; $year--) {
         $year_count = 0;
         $disclosure = new SwatDisclosure();
         $disclosure->title = $year;
         $disclosure->open = false;
         ob_start();
         echo '<ul>';
         for ($i = 1; $i <= 12; $i++) {
             echo '<li class="clearfix"><div>';
             $date->setDate($year, $i, 1);
             if (isset($months_array[$year . '/' . $i])) {
                 $a_tag = new SwatHtmlTag('a');
                 $a_tag->setContent($date->getMonthName());
                 $a_tag->href = $this->app->config->pinhole->path . 'tag?date.year=' . $year . '/date.month=' . $i;
                 $a_tag->display();
                 $photo_count = $months_array[$year . '/' . $i]->photo_count;
                 echo '<span>' . $locale->formatNumber($photo_count) . '</span>';
                 $year_count += $photo_count;
             } else {
                 $div_tag = new SwatHtmlTag('div');
                 $div_tag->setContent($date->getMonthName());
                 $div_tag->display();
             }
             echo '</div></li>';
             if ($i == 12 && $year_count > 0) {
                 echo '<li class="clearfix"><div>';
                 $a_tag = new SwatHtmlTag('a');
                 $a_tag->setContent(sprintf(Pinhole::_('View all photos from %s'), $year));
                 $a_tag->href = $this->app->config->pinhole->path . 'tag?date.year=' . $year;
                 $a_tag->display();
                 echo '<span>' . $locale->formatNumber($year_count) . '</span>';
                 echo '</div></li>';
             }
         }
         echo '</ul>';
         $content = new SwatContentBlock();
         $content->content_type = 'text/xml';
         $content->content = ob_get_clean();
         $disclosure->add($content);
         $container->add($disclosure);
     }
     if (isset($this->app->memcache)) {
         $this->app->memcache->setNs('photos', $cache_key, $container);
     }
     return $container;
 }
Example #5
0
    public function getPostByDateAndShortname(SwatDate $date, $shortname)
    {
        $post = false;
        if ($this->memcache !== null) {
            $key = $date->formatLikeIntl('yyyyMMdd') . $shortname;
            $key = $this->getPostCacheKey($key);
            $post = $this->memcache->getNs('posts', $key);
        }
        if ($post === false) {
            $sql = $this->getSelectClause();
            $sql .= $this->getWhereClause();
            $sql .= sprintf(' and BlorgPost.shortname = %s and
				date_trunc(\'month\', convertTZ(publish_date, %s)) =
					date_trunc(\'month\', timestamp %s)', $this->db->quote($shortname, 'text'), $this->db->quote($date->getTimezone()->getName(), 'text'), $this->db->quote($date->getDate(), 'date'));
            $this->db->setLimit(1, 0);
            $post_wrapper = SwatDBClassMap::get('BlorgPostWrapper');
            $posts = SwatDB::query($this->db, $sql, $post_wrapper);
            if (in_array('author', $this->fields)) {
                $this->loadPostAuthors($posts);
            }
            if ($this->load_files) {
                $this->loadPostFiles($posts);
            }
            if ($this->load_tags) {
                $this->loadPostTags($posts);
            }
            $post = $posts->getFirst();
            if ($this->memcache !== null) {
                $this->memcache->setNs('posts', $key, $post);
            }
        } else {
            if ($post !== null) {
                $post->setDatabase($this->db);
            }
        }
        return $post;
    }
Example #6
0
    /**
     * Gets a summary of the number of photos in this tag list indexed
     * and grouped by the specified date part
     *
     * @param string $date_part the date part with which to index and group
     *                           photo counts.
     *
     * @return array an array indexed by the relevant date part with values
     *                indicating the number of photos in the tag list
     *                for the date part index. If the tag list has no photos
     *                on a specific date, the returned array does not contain
     *                an index at that date.
     */
    public function getPhotoCountByDate($date_part)
    {
        $args = func_get_args();
        $cache_key = $this->getCacheKey(__FUNCTION__, $args);
        $value = $this->app->getCacheValue($cache_key, 'photos');
        if ($value !== false) {
            return $value;
        }
        $group_by_parts = array();
        switch ($date_part) {
            case 'day':
                $group_by_parts[] = 'day';
                $group_by_parts[] = 'month';
                $group_by_parts[] = 'year';
                $date_format = 'yyyy-MM-dd';
                break;
            case 'month':
                $group_by_parts[] = 'month';
                $group_by_parts[] = 'year';
                $date_format = 'yyyy-MM';
                break;
            case 'year':
                $group_by_parts[] = 'year';
                $date_format = 'yyyy';
                break;
        }
        $group_by_clause = '';
        $count = 0;
        foreach ($group_by_parts as $part) {
            if ($count > 0) {
                $group_by_clause .= ', ';
            }
            $group_by_clause .= sprintf('date_part(%s, convertTZ(PinholePhoto.photo_date,
				PinholePhoto.photo_time_zone))', $this->db->quote($part, 'text'));
            $count++;
        }
        $sql = 'select
				count(PinholePhoto.id) as photo_count,
				max(convertTZ(PinholePhoto.photo_date,
				PinholePhoto.photo_time_zone)) as photo_date
			from PinholePhoto
			inner join ImageSet on PinholePhoto.image_set = ImageSet.id';
        $join_clauses = implode(' ', $this->getJoinClauses());
        if ($join_clauses != '') {
            $sql .= ' ' . $join_clauses . ' ';
        }
        $where_clause = $this->getWhereClause();
        if ($where_clause != '') {
            $sql .= ' where ' . $where_clause;
        }
        if ($group_by_clause != '') {
            $sql .= ' group by ' . $group_by_clause;
        }
        $rows = SwatDB::query($this->db, $sql, null);
        $dates = array();
        while ($row = $rows->fetchRow(MDB2_FETCHMODE_OBJECT)) {
            if ($row->photo_date === null) {
                continue;
            }
            $date = new SwatDate($row->photo_date);
            $dates[$date->formatLikeIntl($date_format)] = $row->photo_count;
        }
        $this->app->addCacheValue($dates, $cache_key, 'photos');
        return $dates;
    }
Example #7
0
 protected function getFilename(SwatDate $quarter, CMEProvider $provider)
 {
     // replace spaces with dashes
     $title = str_replace(' ', '-', $provider->title);
     // strip non-word or dash characters
     $title = preg_replace('/[^\\w-]/', '', $title);
     return sprintf($this->getFilenamePattern(), $title, $quarter->formatLikeIntl('QQQ-yyyy'));
 }
 public function build()
 {
     if (isset($this->layout->navbar)) {
         $this->buildNavBar();
     }
     $this->layout->startCapture('content');
     Blorg::displayAd($this->app, 'top');
     $this->displayPosts();
     Blorg::displayAd($this->app, 'bottom');
     $this->layout->endCapture();
     $date = new SwatDate();
     $date->setDate($this->year, $this->month, 1);
     $date->setTZ($this->app->default_time_zone);
     $this->layout->data->title = $date->formatLikeIntl(SwatDate::DF_MY);
 }
Example #9
0
 protected function saveDBData()
 {
     $schedule = true;
     $relocate = true;
     $message = null;
     // Note: DeliveranceMailChimpList expects campaign send dates to be in
     // local time. Send date must be set on the newsletter so that its
     // internal campaign can get the correct send_date.
     if ($this->ui->getWidget('send_date')->value instanceof SwatDate) {
         $message_text = Deliverance::ngettext('“%1$s” will be sent to one subscriber on %3$s at %4$s %5$s.', '“%1$s” will be sent to %2$s subscribers on %3$s at %4$s %5$s.', $this->send_count);
         // Preserve all the date fields
         $send_date = $this->ui->getWidget('send_date')->value;
         $send_date->setTZ($this->app->default_time_zone);
     } else {
         $schedule = false;
         $message_text = Deliverance::ngettext('“%1$s” was sent to one subscriber.', '“%1$s” was sent to %2$s subscribers.', $this->send_count);
         // Convert all the date fields to the timezone
         $send_date = new SwatDate();
         $send_date->setTimezone($this->app->default_time_zone);
     }
     // build the success message before date conversion to prevent needing
     // to convert to UTC for saving and then back to local time for display.
     $locale = SwatI18NLocale::get();
     $message = new SwatMessage(sprintf($message_text, $this->newsletter->subject, $locale->formatNumber($this->send_count), $send_date->formatLikeIntl(SwatDate::DF_DATE), $send_date->formatLikeIntl(SwatDate::DF_TIME), $send_date->formatTZ(SwatDate::TZ_CURRENT_SHORT)));
     $message->secondary_content = Deliverance::_('Subscriber counts are ' . 'estimates. Full statistics will be available once the newsletter ' . 'has been sent.');
     $campaign_type = $this->newsletter->instance instanceof SiteInstance ? $this->newsletter->instance->shortname : null;
     // grab campaign with old send date to clear out the resources.
     $campaign = $this->newsletter->getCampaign($this->app, $campaign_type);
     // If not a draft, remove the resources first in case they came from an
     // old directory. Don't delete draft newsletter resources as they are
     // shared across all drafts.
     if ($this->newsletter->isScheduled()) {
         DeliveranceCampaign::removeResources($this->app, $campaign);
     }
     // Finally set the date with the local timezone.
     // As DeliveranceMailChimpList expects.
     $this->newsletter->send_date = $send_date;
     // re-grab the campaign with the new send_date;
     $campaign = $this->newsletter->getCampaign($this->app, $campaign_type);
     try {
         // resave campaign so that resource urls are rewritten.
         $this->list->saveCampaign($campaign, false);
         // save/update campaign resources.
         DeliveranceCampaign::uploadResources($this->app, $campaign);
         if ($schedule) {
             $this->list->scheduleCampaign($campaign);
         } else {
             $this->list->sendCampaign($campaign);
         }
         // Before we save the newsletter we need to convert it to UTC.
         $this->newsletter->send_date->toUTC();
         $this->newsletter->save();
     } catch (DeliveranceAPIConnectionException $e) {
         // send date needs to be reset to null so the page titles stay
         // correct.
         $this->newsletter->send_date = null;
         $relocate = false;
         // log api connection exceptions in the admin to keep a track of how
         // frequent they are.
         $e->processAndContinue();
         $message = new SwatMessage(Deliverance::_('There was an issue connecting to the email ' . 'service provider.'), 'error');
         $message->content_type = 'text/xml';
         if ($schedule) {
             $message->secondary_content = sprintf('<strong>%s</strong><br />%s', sprintf(Deliverance::_('“%s” has not been scheduled.'), $this->newsletter->subject), Deliverance::_('Connection issues are typically ' . 'short-lived  and attempting to schedule the ' . 'newsletter again after a delay will usually be ' . 'successful.'));
         } else {
             $message->secondary_content = sprintf('<strong>%s</strong><br />%s', sprintf(Deliverance::_('“%s” has not been sent.'), $this->newsletter->subject), Deliverance::_('Connection issues are typically ' . 'short-lived and attempting to send the newsletter ' . 'again after a delay will usually be successful.'));
         }
     } catch (Exception $e) {
         // send date needs to be reset to null so the page titles stay
         // correct.
         $this->newsletter->send_date = null;
         $relocate = false;
         $e = new DeliveranceException($e);
         $e->processAndContinue();
         if ($schedule) {
             $message_text = Deliverance::_('An error has occurred. The ' . 'newsletter has not been scheduled.');
         } else {
             $message_text = Deliverance::_('An error has occurred. The ' . 'newsletter has not been sent.');
         }
         $message = new SwatMessage($message_text, 'system-error');
     }
     if ($message !== null) {
         $this->app->messages->add($message);
     }
     return $relocate;
 }
Example #10
0
 /**
  * Gets the previous tag before this tag
  *
  * @return PinholeDateTag the previous tag before this tag or null if there
  *                         is no previous tag.
  */
 public function prev()
 {
     $returned_tag = null;
     switch ($this->name) {
         case 'date':
             $date = new SwatDate($this->value);
             $date->subtractDays(1);
             $value = $date->formatLikeIntl('yyyy-MM-dd');
             break;
         case 'week':
             if (ctype_digit($this->value)) {
                 $value = $this->value > 1 ? $this->value - 1 : null;
             } else {
                 // beginning of previous week
                 $start_date = new SwatDate($this->value);
                 $start_date->subtractDays(7 + $start_date->getDayOfWeek());
                 $value = $start_date->formatLikeIntl('yyyy-MM-dd');
             }
             break;
         case 'year':
             $value = $this->value > 0 ? $this->value - 1 : null;
             break;
         case 'month':
             $value = $this->value > 1 ? $this->value - 1 : null;
             break;
         case 'day':
             $value = $this->value > 1 ? $this->value - 1 : null;
             break;
         default:
             $value = null;
             break;
     }
     if ($value !== null) {
         $string = sprintf('%s.%s=%s', self::NS, $this->name, $value);
         $tag = new PinholeDateTag();
         if ($tag->parse($string, $this->db, $this->instance) !== false) {
             $returned_tag = $tag;
         }
     }
     return $returned_tag;
 }
    protected function buildPhotoDate(SwatDetailsView $view)
    {
        $photo_date = $view->getField('photo_date');
        if ($this->photo->photo_date === null) {
            $photo_date->visible = false;
        } else {
            $date = new SwatDate($this->photo->photo_date);
            $date->convertTZById($this->photo->photo_time_zone);
            $date_links = $photo_date->getRenderer('date_links');
            $date_links->content_type = 'text/xml';
            $date_links->text = sprintf(Pinhole::_('
				(view photos taken on the same: ' . '<a href="tag?date.date=%1$s-%2$s-%3$s">day</a>, ' . '<a href="tag?date.week=%1$s-%2$s-%3$s">week</a>, ' . '<a href="tag?date.month=%2$s/date.year=%1$s">month</a>, ' . '<a href="tag?date.year=%1$s">year</a>)'), $date->formatLikeIntl('yyyy'), $date->formatLikeIntl('MM'), $date->formatLikeIntl('dd'));
        }
    }
Example #12
0
 protected function displayArchive()
 {
     $years = $this->getYears();
     if (count($years) === 0) {
         return;
     }
     $current_year = date('Y');
     $path = $this->app->config->blorg->path . 'archive';
     $locale = SwatI18NLocale::get();
     $year_ul_tag = new SwatHtmLTag('ul');
     $year_ul_tag->class = 'blorg-archive-years';
     $year_ul_tag->open();
     foreach ($years as $year => $values) {
         $year_li_tag = new SwatHtmlTag('li');
         $year_li_tag->open();
         $year_anchor_tag = new SwatHtmlTag('a');
         $year_anchor_tag->href = sprintf('%s/%s', $path, $year);
         $year_anchor_tag->setContent($year);
         $year_anchor_tag->display();
         $post_count_span = new SwatHtmlTag('span');
         $post_count_span->setContent(sprintf(Blorg::ngettext(' (%s post)', ' (%s posts)', $values['post_count']), $locale->formatNumber($values['post_count'])));
         $post_count_span->display();
         // show month links for current year
         if ($year == $current_year) {
             $month_ul_tag = new SwatHtmlTag('ul');
             $month_ul_tag->open();
             foreach ($values['months'] as $month => $post_count) {
                 $date = new SwatDate();
                 $date->setMonth($month);
                 $month_li_tag = new SwatHtmlTag('li');
                 $month_li_tag->open();
                 $month_anchor_tag = new SwatHtmlTag('a');
                 $month_anchor_tag->href = sprintf('%s/%s/%s', $path, $year, BlorgPageFactory::$month_names[$month]);
                 $month_anchor_tag->setContent($date->formatLikeIntl('MMMM'));
                 $month_anchor_tag->display();
                 $post_count_span = new SwatHtmlTag('span');
                 $post_count_span->setContent(sprintf(Blorg::ngettext(' (%s post)', ' (%s posts)', $post_count), $locale->formatNumber($post_count)));
                 $post_count_span->display();
                 $month_li_tag->close();
             }
             $month_ul_tag->close();
         }
         $year_li_tag->close();
     }
     $year_ul_tag->close();
 }
 /**
  * Displays date.date tags for all the photos in the site instance of
  * this date tag browser's tag list
  *
  * The <i>$start_date</i> and <i>$end_date</i> are used to tell which
  * day, month and year are currently selected.
  *
  * @param SwatDate $start_date the start date of the photos in this date
  *                              tag browser's tag list.
  * @param SwatDate $end_date the end date of the photos in this date
  *                              tag browser's tag list.
  */
 protected function displayDays(SwatDate $start_date, SwatDate $end_date)
 {
     $date = new SwatDate();
     /*
      * Setting the month and year to the $start_date month and year makes
      * sense because the day list is only displayed if the start year and
      * month are the same as the end year and month.
      */
     $date->setMonth($start_date->getMonth());
     $date->setYear($start_date->getYear());
     // get selected day if it exists
     if ($start_date->getDay() == $end_date->getDay()) {
         $selected_day = $start_date->getDay();
     } else {
         $selected_day = null;
     }
     // create base tag list that new date.month tags will be added to
     $tag_list = $this->tag_list->filter(array('PinholeDateTag'));
     $tag_list->add(sprintf('date.year=%s', $date->formatLikeIntl('yyyy')));
     $tag_list->add(sprintf('date.month=%s', $date->formatLikeIntl('MM')));
     $photos = $tag_list->getPhotoCountByDate('day');
     // Filter again since the day list uses date.date tags instead of
     // combined date.year, date.month and date.day tags.
     $tag_list = $this->tag_list->filter(array('PinholeDateTag'));
     // display date.date tags for each day
     $div_tag = new SwatHtmlTag('div');
     $div_tag->class = 'days clearfix';
     $div_tag->open();
     $days_in_month = $date->getDaysInMonth();
     for ($i = 1; $i <= $days_in_month; $i++) {
         $date->setDay($i);
         $key = $date->formatLikeIntl('yyyy-MM-dd');
         $tag_string = sprintf('date.date=%s', $date->formatLikeIntl('yyyy-MM-dd'));
         $tag_list->add($tag_string);
         if ($selected_day === $i) {
             $span_tag = new SwatHtmlTag('span');
             $span_tag->setContent($date->formatLikeIntl('dd'));
             $span_tag->class = 'selected';
             $span_tag->display();
         } elseif (array_key_exists($key, $photos)) {
             $a_tag = new SwatHtmlTag('a');
             $a_tag->href = $this->base . '?' . $tag_list->__toString();
             $a_tag->title = sprintf(Pinhole::ngettext('1 photo', '%s photos', $photos[$key]), SwatString::numberFormat($photos[$key]));
             $a_tag->setContent($date->formatLikeIntl('dd'));
             $a_tag->display();
         } else {
             $span_tag = new SwatHtmlTag('span');
             $span_tag->setContent($date->formatLikeIntl('dd'));
             $span_tag->display();
         }
         $tag_list->remove($tag_string);
     }
     $div_tag->close();
 }
 protected function getTitle()
 {
     $end_date = clone $this->end_date;
     $end_date->subtractMonths(1);
     return sprintf(CME::_('%s Program Evaluation Report for %s to %s'), $this->app->config->site->title, $this->start_date->formatLikeIntl('MMMM yyyy'), $end_date->formatLikeIntl('MMMM yyyy'));
 }
Example #15
0
 protected function getTableModel(SwatView $view)
 {
     $now = new SwatDate();
     $now->setTimezone($this->app->default_time_zone);
     $year = $this->start_date->getYear();
     $start_date = new SwatDate();
     $start_date->setTime(0, 0, 0);
     $start_date->setDate($year, 1, 1);
     $start_date->setTZ($this->app->default_time_zone);
     $end_date = clone $start_date;
     $end_date->addMonths(3);
     $display_end_date = clone $end_date;
     $display_end_date->subtractMonths(1);
     $store = new SwatTableStore();
     while ($end_date->before($now)) {
         for ($i = 1; $i <= 4; $i++) {
             // Only add the quarter to the table model if the start date
             // is within or prior to that quarter.
             if ($this->start_date->before($end_date)) {
                 $ds = new SwatDetailsStore();
                 $quarter = $start_date->formatLikeIntl('yyyy-qq');
                 $ds->date = clone $start_date;
                 $ds->year = $year;
                 $ds->quarter = $quarter;
                 $ds->quarter_title = sprintf(CME::_('Q%s - %s to %s'), $i, $start_date->formatLikeIntl('MMMM yyyy'), $display_end_date->formatLikeIntl('MMMM yyyy'));
                 foreach ($this->providers as $provider) {
                     $shortname = $provider->shortname;
                     $sensitive = isset($this->reports_by_quarter[$quarter][$shortname]);
                     $ds->{'is_' . $shortname . '_sensitive'} = $sensitive;
                 }
                 $store->add($ds);
             }
             $start_date->addMonths(3);
             $end_date->addMonths(3);
             $display_end_date->addMonths(3);
         }
         $year++;
     }
     return $store;
 }
 public static function getPhotoCountPerDay(SiteWebApplication $app, SwatDate $date)
 {
     if (isset($app->memcache)) {
         $cache_key = sprintf('PinholeCalendarGadget.count.%s.%s', $date->formatLikeIntl('yyyy-MM'), $app->session->isLoggedIn() ? 'private' : 'public');
         $count = $app->memcache->getNs('photos', $cache_key);
         if ($count !== false) {
             return $count;
         }
     }
     $sql = "select count(PinholePhoto.id) as photo_count,\n\t\t\t\tdate_part('day', max(convertTZ(PinholePhoto.photo_date,\n\t\t\t\t\tPinholePhoto.photo_time_zone))) as photo_day\n\t\t\tfrom PinholePhoto\n\t\t\tinner join ImageSet on PinholePhoto.image_set = ImageSet.id\n\t\t\twhere ImageSet.instance %s %s and PinholePhoto.status = %s\n\t\t\t\tand PinholePhoto.photo_date is not null\n\t\t\t\tand convertTZ(PinholePhoto.photo_date,\n\t\t\t\t\tPinholePhoto.photo_time_zone) >= %s\n\t\t\t\tand convertTZ(PinholePhoto.photo_date,\n\t\t\t\t\tPinholePhoto.photo_time_zone) < %s\n\t\t\t\t%s\n\t\t\tgroup by date_part('day', convertTZ(PinholePhoto.photo_date,\n\t\t\t\tPinholePhoto.photo_time_zone))";
     $end_date = clone $date;
     $end_date->addMonths(1);
     if (!$app->session->isLoggedIn()) {
         $private_where_clause = sprintf('and PinholePhoto.private = %s', $app->db->quote(false, 'boolean'));
     } else {
         $private_where_clause = '';
     }
     $sql = sprintf($sql, SwatDB::equalityOperator($app->getInstanceId()), $app->db->quote($app->getInstanceId(), 'integer'), $app->db->quote(PinholePhoto::STATUS_PUBLISHED), $app->db->quote($date->getDate(), 'date'), $app->db->quote($end_date->getDate(), 'date'), $private_where_clause);
     $days = SwatDB::query($app->db, $sql);
     $day_count = array();
     foreach ($days as $day) {
         $day_count[$day->photo_day] = $day->photo_count;
     }
     if (isset($app->memcache)) {
         $app->memcache->setNs('photos', $cache_key, $day_count);
     }
     return $day_count;
 }