function aggregate($type, $options = array()) { $options = array_merge(array('featured' => false), $options); $shared_params = array(); if ($type === 'tag') { $shared_params['tags'] = $options['tag_slug']; } else { if ($type === 'category') { $shared_params['category'] = $options['category']; } } $album_params = $shared_params; $date_marker = false; if ($type === 'date') { $s = new Setting(); $s->where('name', 'site_timezone')->get(); $tz = new DateTimeZone($s->value); $offset = $tz->getOffset(new DateTime('now', new DateTimeZone('UTC'))); if ($offset === 0) { $shift = ''; } else { $shift = ($offset < 0 ? '-' : '+') . abs($offset); } // Need to - the offset here, as we need to shift this timestamp by the inverse of the offset to match DB UTC time. // For example. Midnight in user's time (say, CT -5) is UTC+5. $album_params['before'] = $date_marker = strtotime("{$options['year']}-{$options['month']}-{$options['day']} 23:59:59") - $offset; } $aggregate = $essay_ids = $album_ids = $content_ids = $updated_album_ids = $exclude_albums = $exclude_content = $sets = $range = array(); $t = new Text(); $t->select('id, featured, featured_image_id, published_on')->where('page_type', 0)->where('published', 1); if ($type === 'date') { $t->where("YEAR(FROM_UNIXTIME({$t->table}.published_on{$shift}))", $options['year'])->where("MONTH(FROM_UNIXTIME({$t->table}.published_on{$shift}))", $options['month'])->where("DAY(FROM_UNIXTIME({$t->table}.published_on{$shift}))", $options['day']); } else { if ($type === 'tag') { $t->where_related('tag', 'id', $options['tag']); } else { $t->where_related('category', 'id', $options['category']); } } if ($options['featured']) { $t->where('featured', 1); } $t->include_related('album', 'id')->order_by($t->table . '.published_on DESC')->get_iterated(); foreach ($t as $essay) { $essay_ids[$essay->id] = $essay->published_on; $aggregate[] = array('type' => 'essay', 'id' => $essay->id, 'date' => $essay->published_on, 'featured' => $essay->featured); if ($essay->album_id) { $exclude_albums[] = $essay->album_id; } if (is_numeric($essay->featured_image_id)) { $exclude_content[] = $essay->featured_image_id; } } $a = new Album(); $a->select('id, featured, published_on, left_id, right_id, level')->where('visibility', 0)->where('deleted', 0)->where('total_count >', 0); if ($type === 'date') { $a->where("YEAR(FROM_UNIXTIME({$a->table}.published_on{$shift}))", $options['year'])->where("MONTH(FROM_UNIXTIME({$a->table}.published_on{$shift}))", $options['month'])->where("DAY(FROM_UNIXTIME({$a->table}.published_on{$shift}))", $options['day']); } else { if ($type === 'tag') { $a->where_related('tag', 'id', $options['tag']); } else { $a->where_related('category', 'id', $options['category']); } } if ($options['featured']) { $a->where('featured', 1); } $a->include_related('content', 'id')->order_by($a->table . '.published_on DESC')->get_iterated(); foreach ($a as $album) { if (is_numeric($album->content_id)) { $exclude_content[] = $album->content_id; } if (!array_key_exists($album->id, $album_ids) && !in_array($album->id, $exclude_albums)) { $album_ids[$album->id] = $album->published_on; $aggregate[] = array('type' => 'album', 'id' => $album->id, 'date' => $album->published_on, 'featured' => $album->featured); } if ($album->level < 2) { $range = array_merge($range, range($album->left_id, $album->right_id)); } if ($album->level > 1) { $sets[$album->id] = $album->left_id; } } foreach ($sets as $id => $left) { if (in_array($left, $range)) { unset($album_ids[$id]); foreach ($aggregate as $i => $info) { if ($info['type'] === 'album' && $info['id'] == $id) { unset($aggregate[$i]); } } } } $c = new Content(); $c->select('id, published_on, featured'); if (!empty($exclude_content)) { $c->where_not_in('id', $exclude_content); } $c->where('visibility', 0)->where('deleted', 0); if ($type === 'date') { $c->include_related('album')->where("YEAR(FROM_UNIXTIME({$c->table}.published_on{$shift}))", $options['year'])->where("MONTH(FROM_UNIXTIME({$c->table}.published_on{$shift}))", $options['month'])->where("DAY(FROM_UNIXTIME({$c->table}.published_on{$shift}))", $options['day'])->group_start()->where($a->table . '.id', null)->or_where($a->table . '.deleted', 0)->group_end(); } else { if ($type === 'tag') { $c->where_related('tag', 'id', $options['tag']); } else { $c->where_related('category', 'id', $options['category']); } } if ($options['featured']) { $c->where('featured', 1); } $c->order_by($c->table . '.published_on DESC')->get_iterated(); foreach ($c as $content) { if ($content->album_id && $content->album_visibility < 1 && $content->album_published_on <= $date_marker) { if (!isset($updated_album_ids[$content->album_id])) { $updated_album_ids[$content->album_id] = array('items' => array($content->id), 'date' => $content->published_on, 'featured' => $content->album_featured); } else { $updated_album_ids[$content->album_id]['items'][] = $content->id; $updated_album_ids[$content->album_id]['date'] = max($content->published_on, $updated_album_ids[$content->album_id]['date']); } } else { if (!$content->album_id) { $content_ids[$content->id] = $content->published_on; $aggregate[] = array('type' => 'content', 'id' => $content->id, 'date' => $content->published_on, 'featured' => $content->featured); } } } foreach ($updated_album_ids as $id => $a) { $aggregate[] = array('type' => 'updated_album', 'id' => $id, 'date' => $a['date'], 'featured' => $a['featured']); } $total = count($aggregate); if (!function_exists('_sort')) { function _sort($one, $two) { if ($one['featured'] && !$two['featured']) { return -1; } else { if ($one['featured'] && $two['featured']) { return $one['date'] < $two['date'] ? 1 : -1; } } return $two['featured'] || $one['date'] < $two['date'] || $one['date'] === $two['date'] && $two['id'] > $one['id'] ? 1 : -1; } } usort($aggregate, '_sort'); $stream = array('page' => (int) isset($options['page']) ? (int) $options['page'] : 1, 'pages' => (int) ceil($total / $options['limit']), 'per_page' => (int) min($options['limit'], $total), 'total' => (int) $total); $load = array_slice($aggregate, ($stream['page'] - 1) * $options['limit'], $options['limit']); $counts = array('essays' => count($essay_ids), 'albums' => count($album_ids), 'content' => count($content_ids)); $counts['total'] = $counts['essays'] + $counts['albums'] + $counts['content']; $updated_album_ids_arr = $updated_album_ids; $essay_ids = $album_ids = $content_ids = $updated_album_ids = $final = $index = array(); foreach ($load as $i => $item) { $index[$item['type'] . '-' . $item['id']] = $i; ${$item['type'] . '_ids'}[] = $item['id']; } if (!empty($essay_ids)) { $e = new Text(); $e->where_in('id', $essay_ids)->get_iterated(); foreach ($e as $essay) { $final[$index['essay-' . $essay->id]] = $essay->to_array($shared_params); } } if (!empty($album_ids)) { $a = new Album(); $a->where_in('id', $album_ids)->get_iterated(); foreach ($a as $album) { $final[$index['album-' . $album->id]] = $album->to_array($album_params); } } if (!empty($content_ids)) { $c = new Content(); $c->where_in('id', $content_ids)->get_iterated(); foreach ($c as $content) { $final[$index['content-' . $content->id]] = $content->to_array(array_merge($shared_params, array('order_by' => 'published_on'))); } } if (!empty($updated_album_ids)) { $a = new Album(); $a->where_in('id', $updated_album_ids)->get_iterated(); foreach ($a as $album) { $arr = $album->to_array(); $arr['event_type'] = 'album_update'; $arr['content'] = array(); $info = $updated_album_ids_arr[$album->id]; $c = new Content(); $c->where_in('id', $info['items'])->order_by('published_on DESC')->get_iterated(); foreach ($c as $i => $content) { $carr = $content->to_array(array('order_by' => 'published_on', 'in_album' => $album)); if ($i === 0) { $arr['date'] = $carr['date']; } $arr['content'][] = $carr; } $final[$index['updated_album-' . $album->id]] = $arr; } } ksort($final); $stream['items'] = array_values($final); return array($stream, $counts); }
function _order($order, $album = false) { $ids = explode(',', $order); $new_order_map = array(); foreach ($ids as $key => $val) { $pos = $key + 1; $new_order_map[$val] = $pos; } $contents = new Album(); $contents->where_in('id', $ids); $sql = $contents->get_sql() . ' ORDER BY FIELD(id, ' . join(',', $ids) . ')'; $contents->query($sql); $next_slot = $album ? $album->left_id + 1 : 1; $this->db->trans_begin(); $start = strtotime(gmdate("M d Y H:i:s", time())); foreach ($contents as $sub_album) { $size = $sub_album->right_id - $sub_album->left_id + 1; if ($sub_album->left_id != $next_slot) { $delta = $sub_album->left_id - $next_slot; $delta = $delta >= 0 ? '- ' . $delta : '+ ' . abs($delta); $_a = new Album(); $_a->where('left_id >=', $sub_album->left_id)->where('right_id <=', $sub_album->right_id)->where('level >=', $sub_album->level)->where('modified_on <', $start)->update(array('left_id' => "left_id {$delta}", 'right_id' => "right_id {$delta}", 'modified_on' => $start), false); } $next_slot += $size; } $this->db->trans_complete(); }
function topics() { list($params, $id) = $this->parse_params(func_get_args()); if ($this->method === 'get') { $a = new Album(); $params['auth'] = $this->auth; $params['flat'] = true; $final = $a->where_related('text', 'id', $id)->listing($params); $this->set_response_data($final); } else { list($text_id, $album_id) = $id; $text = new Text(); $t = $text->get_by_id($text_id); if (is_numeric($album_id)) { $album_id = array($album_id); } else { $album_id = explode(',', $album_id); } $album = new Album(); $albums = $album->where_in('id', $album_id)->get_iterated(); foreach ($albums as $a) { if ($this->method === 'post') { $a->save($t); } else { $a->delete($t); } } $this->redirect("/text/{$text_id}"); exit; } }