function index() { list($params, $id) = $this->parse_params(func_get_args()); $t = new Theme(); $final = $t->read(); $final = Shutter::filter('api.themes', array($final)); $this->set_response_data($final); }
function index() { list($params, $id, $slug) = $this->parse_params(func_get_args()); // Create or update if ($this->method != 'get') { $c = new Content(); switch ($this->method) { case 'post': case 'put': if ($this->method == 'put') { // Update $c->get_by_id($id); if (!$c->exists()) { $this->error('404', "Content with ID: {$id} not found."); return; } $c->old_published_on = $c->published_on; $c->old_captured_on = $c->captured_on; $c->old_uploaded_on = $c->uploaded_on; if (isset($_POST['slug'])) { $c->current_slug = $c->slug; } } if (isset($_REQUEST['name'])) { if (isset($_REQUEST['upload_session_start'])) { $s = new Setting(); $s->where('name', 'last_upload')->get(); if ($s->exists() && $s->value != $_REQUEST['upload_session_start']) { $s->value = $_REQUEST['upload_session_start']; $s->save(); } } $file_name = $c->clean_filename($_REQUEST['name']); $chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0; $chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0; $tmp_dir = FCPATH . 'storage' . DIRECTORY_SEPARATOR . 'tmp'; $tmp_path = $tmp_dir . DIRECTORY_SEPARATOR . $file_name; make_child_dir($tmp_dir); if ($chunks == 0 || $chunk == $chunks - 1) { if (isset($_REQUEST['text'])) { $path = FCPATH . 'storage' . DIRECTORY_SEPARATOR . 'custom' . DIRECTORY_SEPARATOR; $internal_id = false; } else { if (isset($_REQUEST['plugin'])) { $info = pathinfo($_REQUEST['name']); $path = FCPATH . 'storage' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . $_REQUEST['plugin'] . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR; $file_name = $_REQUEST['basename'] . '.' . $info['extension']; $internal_id = false; } else { list($internal_id, $path) = $c->generate_internal_id(); } } if ($path) { $path .= $file_name; if ($chunks == 0) { $tmp_path = $path; } } else { $this->error('500', 'Unable to create directory for upload.'); return; } } // Look for the content type header if (isset($_SERVER["HTTP_CONTENT_TYPE"])) { $contentType = $_SERVER["HTTP_CONTENT_TYPE"]; } else { if (isset($_SERVER["CONTENT_TYPE"])) { $contentType = $_SERVER["CONTENT_TYPE"]; } else { $contentType = ''; } } if (strpos($contentType, "multipart") !== false) { if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) { $out = fopen($tmp_path, $chunk == 0 ? "wb" : "ab"); if ($out) { // Read binary input stream and append it to temp file $in = fopen($_FILES['file']['tmp_name'], "rb"); if ($in) { while ($buff = fread($in, 4096)) { fwrite($out, $buff); } } else { $this->error('500', 'Unable to read input stream.'); return; } fclose($out); unlink($_FILES['file']['tmp_name']); } else { $this->error('500', 'Unable to write to output file.'); return; } } else { $this->error('500', 'Unable to move uploaded file.'); return; } } else { $out = fopen($tmp_path, $chunk == 0 ? "wb" : "ab"); if ($out) { // Read binary input stream and append it to temp file $in = fopen("php://input", "rb"); if ($in) { while ($buff = fread($in, 4096)) { fwrite($out, $buff); } } else { $this->error('500', 'Unable to read uploaded file.'); return; } fclose($out); } else { $this->error('500', 'Unable to open output stream.'); return; } } if ($chunk < $chunks - 1) { // Don't continue until all chunks are uploaded exit; } else { if ($chunks > 0) { // Done, move to permanent location and save to DB rename($tmp_path, $path); } } if (!$internal_id) { // Custom text uploads can stop here die(json_encode(array('filename' => $file_name))); } $from = array(); $from['filename'] = $file_name; $from['internal_id'] = $internal_id; $from['file_modified_on'] = time(); } else { if (isset($_POST['localfile'])) { $filename = basename($_REQUEST['localfile']); list($internal_id, $path) = $c->generate_internal_id(); if (!file_exists($_REQUEST['localfile'])) { $this->error('500', '"localfile" does not exist.'); return; } if ($path) { $path .= $filename; } else { $this->error('500', 'Unable to create directory for upload.'); return; } copy($_REQUEST['localfile'], $path); $from = array(); $from['filename'] = $filename; $from['internal_id'] = $internal_id; $from['file_modified_on'] = time(); } else { if (isset($_POST['from_url'])) { $filename = basename($_POST['from_url']); list($internal_id, $path) = $c->generate_internal_id(); if ($path) { $path .= $filename; } else { $this->error('500', 'Unable to create directory for upload.'); return; } if ($this->_download(urldecode($_POST['from_url']), $path, true) && file_exists($path)) { $from = array(); $from['filename'] = $filename; $from['internal_id'] = $internal_id; $from['file_modified_on'] = time(); } else { $this->error('500', 'Unable to import file from provided URL.'); return; } } else { if (is_null($id)) { $this->error('403', 'New content records must be accompanied by an upload.'); return; } } } } if (isset($from)) { $from = array_merge($_POST, $from); } else { $from = $_POST; } if (isset($_REQUEST['rotate']) && is_numeric($_REQUEST['rotate']) && $c->exists()) { $r = $_REQUEST['rotate']; if (abs($r) != 90) { $this->error('403', 'Rotation can only be done in multiples of 90.'); return; } if (empty($c->storage_url)) { $path = $c->path_to_original(); $info = pathinfo($path); $midsize_path = preg_replace('/\\.' . $info['extension'] . '$/', '.1600.' . $info['extension'], $path); if (file_exists($midsize_path)) { $midsize = $midsize_path; } } else { $path = tempnam(sys_get_temp_dir(), 'original'); file_put_contents($path, file_get_contents($c->storage_url)); if (!empty($c->storage_url_midsize)) { $midsize = tempnam(sys_get_temp_dir(), 'midsize'); file_put_contents($midsize, file_get_contents($c->storage_url_midsize)); } } $s = new Setting(); $s->where('name', 'image_processing_library')->get(); include_once FCPATH . 'app' . DIRECTORY_SEPARATOR . 'koken' . DIRECTORY_SEPARATOR . 'DarkroomUtils.php'; $d = DarkroomUtils::init($s->value); $d->rotate($path, $r); if (isset($midsize)) { $d->rotate($midsize, $r); } if (!empty($c->storage_url)) { $key = $c->path . '/' . $c->filename; Shutter::store_original($path, $c->path . '/' . $c->filename); unlink($path); if (isset($midsize)) { $info = pathinfo($key); $key = preg_replace('/\\.' . $info['extension'] . '$/', '.1600.' . $info['extension'], $key); Shutter::store_original($midsize, $key); unlink($midsize); } } $c->clear_cache(); $from['width'] = $c->height; $from['height'] = $c->width; $from['aspect_ratio'] = $from['width'] / $from['height']; $from['file_modified_on'] = time(); } if (isset($_REQUEST['reset_internal_id']) && $_REQUEST['reset_internal_id'] && $c->exists()) { list($from['internal_id'], ) = $c->generate_internal_id(true); } $hook = 'content.' . ($id ? 'update' : 'create'); if (isset($from['filename']) && $id) { $c->clear_cache(); $hook .= '_with_upload'; $c->_before(); } $from = Shutter::filter("api.{$hook}", array_merge($from, array('id' => $id, 'file' => isset($path) ? $path : $c->path_to_original()))); unset($from['file']); try { $c->from_array($from, array(), true); } catch (Exception $e) { $this->error('400', $e->getMessage()); return; } if (isset($_POST['tags'])) { $c->_format_tags($_POST['tags']); } else { if ($this->method === 'put' && isset($_POST['visibility'])) { $c->_update_tag_counts(); } } $c->_readify(); $content = $c->to_array(array('auth' => true)); if ($hook === 'content.create' || $hook === 'content.update_with_upload') { if (ENVIRONMENT === 'production') { $this->load->library('mcurl'); if ($this->mcurl->is_enabled()) { $options = array(CURLOPT_HTTPHEADER => array('Connection: Close', 'Keep-Alive: 0')); $this->mcurl->add_call('normal', 'get', $content['presets']['medium_large']['url'], array(), $options); $this->mcurl->add_call('cropped', 'get', $content['presets']['medium_large']['cropped']['url'], array(), $options); $this->mcurl->execute(); } } $external_storage_url = Shutter::store_original($c->path_to_original(), str_replace('/storage/originals/', '', $content['original']['relative_url'])); if ($external_storage_url) { unlink($c->path_to_original()); $o = new Content(); $o->where('id', $content['id'])->update(array('storage_url' => $external_storage_url)); $content['storage_url'] = $external_storage_url; } } Shutter::hook($hook, $content); // Important to prevent failures from Lr plugin header('Connection: close'); $this->redirect("/content/{$c->id}" . (isset($params['context']) ? '/context:' . $params['context'] : '')); break; case 'delete': if (is_null($id)) { $this->error('403', 'Required parameter "id" not present.'); return; } else { $t = new Tag(); if (is_numeric($id)) { $content = $c->get_by_id($id); if ($c->exists()) { $trash = new Trash(); $this->db->query("DELETE from {$trash->table} WHERE id = 'content-{$c->id}'"); $c->do_delete(); } else { $this->error('404', "Content with ID: {$id} not found."); return; } } else { $is_trash = $id === 'trash'; if ($id === 'trash') { $id = array(); $trash = new Trash(); $trash->like('id', 'content-')->select_func('REPLACE', '@id', 'content-', '', 'actual_id')->get_iterated(); foreach ($trash as $item) { $id[] = (int) $item->actual_id; } } else { $id = explode(',', $id); } /* Multiple delete /content/n1/n2/n3 */ // Keep track of tags to -- $tags = array(); $c->where_in('id', $id); $contents = $c->get_iterated(); $trash = new Trash(); foreach ($contents as $c) { if ($c->exists()) { $tags = array_merge($tags, $c->tags); $this->db->query("DELETE from {$trash->table} WHERE id = 'content-{$c->id}'"); $c->do_delete(); } } } } exit; break; } } $c = new Content(); if ($slug || isset($id) && strpos($id, ',') === false) { $options = array('context' => false, 'neighbors' => false); $options = array_merge($options, $params); $original_context = $options['context']; if ($options['context'] && !in_array($options['context'], array('stream', 'favorites', 'features')) && strpos($options['context'], 'tag-') !== 0 && strpos($options['context'], 'category-') !== 0) { if (is_numeric($options['context'])) { $context_field = 'id'; } else { $context_field = 'slug'; $options['context'] = str_replace('slug-', '', $options['context']); } $a = new Album(); $a->group_start()->where($context_field, $options['context'])->or_where('internal_id', $options['context'])->group_end()->get(); $c->include_join_fields()->where_related_album('id', $a->id); } $with_token = false; if (is_numeric($id)) { $content = $c->where('deleted', 0)->get_by_id($id); } else { if ($slug) { $content = $c->where('deleted', 0)->group_start()->where('internal_id', $slug)->or_where('slug', $slug)->or_like('old_slug', ',' . $slug . ',', 'both')->group_end()->get(); } else { $content = $c->where('deleted', 0)->where('internal_id', $id)->get(); } if ($content->exists() && $content->internal_id === (is_null($id) ? $slug : $id)) { $with_token = true; } } if ($content->exists()) { if ($c->visibility == 1 && !$this->auth && !$with_token || !$this->auth && !is_numeric($id) && $c->visibility == 2) { $this->error('403', 'Private content.'); return; } $options['auth'] = $this->auth; if ($options['neighbors']) { // Make sure $neighbors is at least 2 $options['neighbors'] = max($options['neighbors'], 2); // Make sure neighbors is even if ($options['neighbors'] & 1 != 0) { $options['neighbors']++; } $options['neighbors'] = $options['neighbors'] / 2; $single_neighbors = false; } else { $options['neighbors'] = 1; $single_neighbors = true; } if ($options['context'] && !in_array($original_context, array('stream', 'favorites', 'features')) && strpos($original_context, 'tag-') !== 0 && strpos($original_context, 'category-') !== 0) { $options['in_album'] = $a; } $final = $content->to_array($options); if ($options['context']) { // TODO: Performance check $next = new Content(); $prev = new Content(); $in_a = new Album(); $next->where('deleted', 0); $prev->where('deleted', 0); $options['context'] = urldecode($options['context']); if (!in_array($original_context, array('stream', 'favorites', 'features')) && strpos($original_context, 'tag-') !== 0 && strpos($original_context, 'category-') !== 0) { if (!isset($options['context_order'])) { list($options['context_order'], $options['context_order_direction']) = explode(' ', $a->sort); } $final['context']['album'] = $a->to_array(array('auth' => $this->auth || $options['context'] === $a->internal_id)); $in_a->where("{$context_field} !=", $options['context']); $next->where_related_album('id', $a->id); $prev->where_related_album('id', $a->id); if ($options['context_order'] === 'manual') { $next->order_by_join_field('album', 'order', 'ASC')->group_start()->where_join_field('album', 'order >', $content->join_order)->or_group_start()->where_join_field('album', 'order', $content->join_order)->where_join_field('album', 'id >', $content->join_id)->group_end()->group_end(); $prev->order_by_join_field('album', 'order', 'DESC')->group_start()->where_join_field('album', 'order <', $content->join_order)->or_group_start()->where_join_field('album', 'order', $content->join_order)->where_join_field('album', 'id <', $content->join_id)->group_end()->group_end(); } else { $next_operator = strtolower($options['context_order_direction']) === 'desc' ? '<' : '>'; $prev_operator = $next_operator === '<' ? '>' : '<'; $next->group_start()->where($options['context_order'] . " {$next_operator}", $content->{$options['context_order']})->or_group_start()->where($options['context_order'], $content->{$options['context_order']})->where("id {$next_operator}", $content->id)->group_end()->group_end(); $prev->group_start()->where($options['context_order'] . " {$prev_operator}", $content->{$options['context_order']})->or_group_start()->where($options['context_order'], $content->{$options['context_order']})->where("id {$prev_operator}", $content->id)->group_end()->group_end(); } if (!$this->auth) { $next->where('visibility <', $final['context']['album']['visibility'] < 1 ? 1 : 2); $prev->where('visibility <', $final['context']['album']['visibility'] < 1 ? 1 : 2); } $in_album = $a; $final['context']['type'] = 'album'; $final['context']['title'] = $a->title; $final['context']['__koken_url'] = $final['context']['album']['__koken_url']; $final['context']['url'] = $final['context']['album']['url']; } else { if (!isset($options['context_order'])) { $options['context_order'] = 'captured_on'; $options['context_order_direction'] = 'DESC'; } else { if ($options['context_order'] === 'manual' && $original_context === 'favorites') { $options['context_order'] = 'favorite_order'; $options['context_order_direction'] = 'ASC'; } else { if ($options['context_order'] === 'manual' && $original_context === 'features') { $options['context_order'] = 'featured_order'; $options['context_order_direction'] = 'ASC'; } } } $next_operator = strtolower($options['context_order_direction']) === 'desc' ? '<' : '>'; $prev_operator = $next_operator === '<' ? '>' : '<'; $next->group_start()->where($options['context_order'] . " {$next_operator}", $content->{$options['context_order']})->or_group_start()->where($options['context_order'], $content->{$options['context_order']})->where("id {$next_operator}", $content->id)->group_end()->group_end(); $prev->group_start()->where($options['context_order'] . " {$prev_operator}", $content->{$options['context_order']})->or_group_start()->where($options['context_order'], $content->{$options['context_order']})->where("id {$prev_operator}", $content->id)->group_end()->group_end(); if (strpos($original_context, 'tag-') === 0) { $tag = str_replace('tag-', '', urldecode($original_context)); $t = new Tag(); $t->where('name', $tag)->get(); if ($t->exists()) { $next->where_related_tag('id', $t->id); $prev->where_related_tag('id', $t->id); $final['context']['type'] = 'tag'; $final['context']['title'] = $tag; $final['context']['slug'] = $tag; $t->model = 'tag_contents'; $t->slug = $t->name; $url = $t->url(); if ($url) { list($final['context']['__koken_url'], $final['context']['url']) = $url; } } } else { if (strpos($original_context, 'category-') === 0) { $category = str_replace('category-', '', $original_context); $cat = new Category(); $cat->where('slug', $category)->get(); if ($cat->exists()) { $next->where_related_category('id', $cat->id); $prev->where_related_category('id', $cat->id); $final['context']['type'] = 'category'; $final['context']['title'] = $cat->title; $final['context']['slug'] = $cat->slug; $cat->model = 'category_contents'; $url = $cat->url(); if ($url) { list($final['context']['__koken_url'], $final['context']['url']) = $url; } } } else { if ($original_context === 'favorites') { $url_data = $prev->get_data(); $urls = $prev->form_urls(); $next->where('favorite', 1); $prev->where('favorite', 1); $final['context']['type'] = 'favorite'; $final['context']['title'] = $url_data['favorite']['plural']; $final['context']['__koken_url'] = $urls['favorites']; if ($final['context']['__koken_url']) { $final['context']['url'] = $prev->get_base() . $final['context']['__koken_url'] . (defined('DRAFT_CONTEXT') && !is_numeric(DRAFT_CONTEXT) ? '&preview=' . DRAFT_CONTEXT : ''); } } else { if ($original_context === 'features') { $url_data = $prev->get_data(); $urls = $prev->form_urls(); $next->where('featured', 1); $prev->where('featured', 1); $final['context']['type'] = 'feature'; $final['context']['title'] = $url_data['feature']['plural']; $final['context']['__koken_url'] = isset($urls['features']) ? $urls['features'] : false; if ($final['context']['__koken_url']) { $final['context']['url'] = $prev->get_base() . $final['context']['__koken_url'] . (defined('DRAFT_CONTEXT') && !is_numeric(DRAFT_CONTEXT) ? '&preview=' . DRAFT_CONTEXT : ''); } } } } } if (!$this->auth) { $next->where('visibility', 0); $prev->where('visibility', 0); } $in_album = false; } $max = $next->get_clone()->count(); $min = $prev->get_clone()->count(); $final['context']['total'] = $max + $min + 1; $final['context']['position'] = $min + 1; $pre_limit = $next_limit = $options['neighbors']; if ($min < $pre_limit) { $next_limit += $pre_limit - $min; $pre_limit = $min; } if ($max < $next_limit) { $pre_limit = min($min, $pre_limit + ($next_limit - $max)); $next_limit = $max; } $final['context']['previous'] = array(); $final['context']['next'] = array(); if ($next_limit > 0) { if ($options['context_order'] !== 'manual') { $next->order_by($options['context_order'] . ' ' . $options['context_order_direction'] . ', id ' . $options['context_order_direction']); } $next->limit($next_limit)->get_iterated(); foreach ($next as $c) { $final['context']['next'][] = $c->to_array(array('auth' => $this->auth, 'in_album' => $in_album, 'context' => $original_context)); } } if ($pre_limit > 0) { if ($options['context_order'] !== 'manual') { $dir = strtolower($options['context_order_direction']) === 'desc' ? 'asc' : 'desc'; $prev->order_by($options['context_order'] . ' ' . $dir . ', id ' . $dir); } $prev->limit($pre_limit)->get_iterated(); foreach ($prev as $c) { $final['context']['previous'][] = $c->to_array(array('auth' => $this->auth, 'in_album' => $in_album, 'context' => $original_context)); } $final['context']['previous'] = array_reverse($final['context']['previous']); } } } else { $this->error('404', "Content with ID: {$id} not found."); return; } } else { if (isset($params['custom'])) { $final = $c->to_array_custom($params['custom']); } else { $c->where('deleted', 0); $params['auth'] = $this->auth; $final = $c->listing($params, $id); } } $this->set_response_data($final); }
function index() { list($params, $id) = $this->parse_params(func_get_args()); $site = new Setting(); $site->like('name', 'site_%')->or_like('name', 'image_%')->get_iterated(); $draft = new Draft(); $data = array(); $ds = DIRECTORY_SEPARATOR; $template_path = FCPATH . 'storage' . $ds . 'themes' . $ds; $defaults = json_decode(file_get_contents(FCPATH . 'app' . $ds . 'site' . $ds . 'defaults.json'), true); $default_template_path = FCPATH . 'app' . $ds . 'site' . $ds . 'themes' . $ds; $pulse_base = FCPATH . 'app' . $ds . 'site' . $ds . 'themes' . $ds . 'common' . $ds . 'js' . $ds . 'pulse.json'; $user = new User(); $user->get(); if (isset($params['preview'])) { $theme_root = $template_path . $params['preview'] . $ds; $template_info = json_decode(file_get_contents($theme_root . 'info.json'), true); if (!$template_info) { $this->set_response_data(array('error' => 'Unable to parse the info.json file for this theme.')); return; } $p = new Draft(); $p->path = $params['preview']; $p->init_draft_nav(); $draft->data = json_decode($p->data, true); } else { if (isset($params['draft'])) { $draft->where('draft', 1); } else { $draft->where('current', 1); } $draft->get(); if ($draft->exists()) { $theme_root = $template_path . $draft->path . $ds; $template_info = json_decode(file_get_contents($theme_root . 'info.json'), true); if (!$template_info) { $this->set_response_data(array('error' => 'Unable to parse the info.json file for this theme.')); return; } $is_live = $draft->current && $draft->data === $draft->live_data; $template_info['published'] = $is_live; $draft->data = json_decode(isset($params['draft']) ? $draft->data : $draft->live_data, true); } else { $this->error('404', 'Draft not found.'); return; } } foreach ($defaults['templates'] as $path => $info) { if (!file_exists($theme_root . $path . '.lens') && !file_exists($default_template_path . $path . '.lens')) { unset($defaults['templates'][$path]); } } foreach ($defaults['routes'] as $url => $info) { if (!isset($defaults['templates'][$info['template']])) { unset($defaults['routes'][$url]); } } if (isset($template_info['routes'])) { $template_info['routes'] = array_merge_custom($defaults['routes'], $template_info['routes']); } else { $template_info['routes'] = $defaults['routes']; } if (isset($template_info['templates'])) { $template_info['templates'] = array_merge_custom($defaults['templates'], $template_info['templates']); } else { $template_info['templates'] = $defaults['templates']; } $files = scandir($theme_root); foreach ($files as $file) { $info = pathinfo($file); if (isset($info['extension']) && $info['extension'] === 'lens' && $info['filename'] !== 'error' && !isset($template_info['templates'][$info['filename']])) { $template_info['templates'][$info['filename']] = array('name' => ucfirst(preg_replace('/[^a-z0-9]/', ' ', strtolower($info['filename'])))); } } if (isset($template_info['styles'])) { if (isset($draft->data['settings']['__style']) && isset($template_info['styles'][$draft->data['settings']['__style']])) { $key = $draft->data['settings']['__style']; } else { $key = $draft->data['settings']['__style'] = array_shift(array_keys($template_info['styles'])); } $template_info['style'] = array_merge(array('key' => $key), $template_info['styles'][$key]); $styles = array(); foreach ($template_info['styles'] as $key => $opts) { $styles[] = array_merge(array('key' => $key), $opts); } $template_info['styles'] = $styles; } else { $template_info['styles'] = array(); } if ($this->method == 'get') { list($data['urls'], $data['url_data'], $routes) = $draft->setup_urls($theme_root); if (isset($params['draft'])) { function get_live_updates($file, $draft, &$functions) { if (file_exists($file)) { // Strip comments so they don't confuse the parser $contents = preg_replace('/\\/\\*.*?\\*\\//si', '', file_get_contents($file)); preg_match_all('/@import\\surl\\(.*\\[?\\$([a-z_0-9]+)\\]?.*\\);/', $contents, $imports); foreach ($imports[1] as $setting) { if (!isset($functions[$setting])) { $functions[$setting] = 'reload'; } } $contents = preg_replace('/@import\\surl\\(.*\\);/', '', $contents); preg_match_all('/([^\\{]+)\\s*\\{([^\\}]+)\\}/s', $contents, $matches); foreach ($matches[2] as $index => $block) { $selector = $matches[1][$index]; preg_match_all('/([a-z\\-]+):([^;]+)( !important)?;/', $block, $rules); foreach ($rules[2] as $j => $rule) { $property = $rules[1][$j]; preg_match_all('/\\[?\\$([a-z_0-9]+)\\]?/', $rule, $options); if (count($options)) { foreach ($options[1] as $option) { if (!isset($functions[$option])) { $functions[$option] = array(); } else { if ($functions[$option] === 'reload') { continue; } } $functions[$option][] = array('selector' => trim(str_replace("\n", '', $selector)), 'property' => trim($property), 'template' => trim(str_replace('url(', "url(storage/themes/{$draft->path}/", $rule)), 'lightbox' => strpos($file, 'lightbox-settings.css.lens') !== false); } } } } } } $functions = array(); get_live_updates(FCPATH . $ds . 'storage' . $ds . 'themes' . $ds . $draft->path . $ds . 'css' . $ds . 'settings.css.lens', $draft, $functions); get_live_updates(FCPATH . $ds . 'storage' . $ds . 'themes' . $ds . $draft->path . $ds . 'css' . $ds . 'lightbox-settings.css.lens', $draft, $functions); $template_info['live_updates'] = $functions; } $pulse_settings = json_decode(file_get_contents($pulse_base), true); list($template_info['pulse'], $template_info['pulse_flat']) = $this->_prep_options($pulse_settings); if (isset($draft->data['pulse_groups'])) { $template_info['pulse_groups'] = $draft->data['pulse_groups']; foreach ($template_info['pulse_groups'] as &$group) { if (isset($group['transition_duration']) && is_numeric($group['transition_duration']) && $group['transition_duration'] > 10) { $group['transition_duration'] /= 1000; } } } else { $template_info['pulse_groups'] = array(); } if (!isset($template_info['templates'])) { $template_info['templates'] = array(); } if (!isset($template_info['routes'])) { $template_info['routes'] = array(); } if (isset($draft->data['routes'])) { $template_info['routes'] = array_merge_custom($template_info['routes'], $draft->data['routes']); } $template_info['navigation'] = $draft->data['navigation']; unset($template_info['navigation_groups']); $albums_flat = new Album(); $albums_flat->select('id,level,left_id')->where('deleted', 0)->order_by('left_id ASC')->get_iterated(); $albums_indexed = array(); $ceiling = 1; foreach ($albums_flat as $a) { $albums_indexed[$a->id] = array('level' => (int) $a->level); $ceiling = max($a->level, $ceiling); } $album_keys = array_keys($albums_indexed); function nest($nav, $routes, $albums_indexed, $album_keys, $ceiling) { $l = 1; $nested = array(); while ($l <= $ceiling) { foreach ($nav as $index => $item) { if (preg_match('/^(mailto|https?)/', $item['path']) || !isset($item['auto']) && !isset($routes[$item['path']])) { if ($l === 1) { $nested[] = $item; } continue; } if (isset($routes[$item['path']])) { $r = $routes[$item['path']]; } else { $r = false; } if (isset($item['auto']) && in_array($item['auto'], array('set', 'album')) || $r && isset($r['source']) && in_array($r['source'], array('set', 'album'))) { if (isset($item['auto'])) { $id = $item['id']; if ($item['auto'] === 'set') { $item['set'] = true; } } else { foreach ($r['filters'] as $f) { if (strpos($f, 'id=') === 0) { $id = array_pop(explode('=', $f)); break; } } if ($r['source'] === 'set') { $item['set'] = true; } } if (isset($albums_indexed[$id])) { $level = $albums_indexed[$id]['level']; if ($level === $l && $l === 1) { $nested[] = $item; $albums_indexed[$id]['nav'] =& $nested[count($nested) - 1]; unset($nav[$index]); } else { if ($level === $l) { while ($level > 0) { $level--; $done = false; $start = array_search($id, $album_keys); while ($start > 0) { $start--; $_id = $album_keys[$start]; if (array_key_exists($_id, $albums_indexed) && $albums_indexed[$_id]['level'] === $level && isset($albums_indexed[$_id]['nav'])) { $albums_indexed[$_id]['nav']['items'][] = $item; $albums_indexed[$id]['nav'] =& $albums_indexed[$_id]['nav']['items'][count($albums_indexed[$_id]['nav']['items']) - 1]; unset($nav[$index]); $done = true; break; } } if ($done) { break; } } } } } } else { if ($l === 1) { $nested[] = $item; unset($nav[$index]); } } } $l++; } return $nested; } function build_autos($items, $data, $user) { foreach ($items as $index => &$item) { if (isset($item['auto'])) { if (isset($data['urls'][$item['auto']])) { $item['path'] = $data['urls'][$item['auto']]; } else { if ($item['auto'] === 'set') { $item['path'] = ''; } } if ($item['auto'] === 'profile') { switch ($item['id']) { case 'twitter': $item['path'] = 'https://twitter.com/' . $user->twitter; break; default: $item['path'] = $user->{$item['id']}; if (empty($item['path'])) { unset($items[$index]); continue; } break; } if (!isset($item['label']) || empty($item['label'])) { $item['label'] = ucwords($item['id']) . ($item['id'] === 'google' ? '+' : ''); } } else { if ($item['auto'] === 'rss') { $item['path'] = '/feed/' . $item['id'] . ($item['id'] === 'essay' ? 's' : '') . '/recent.rss'; if (!isset($item['label'])) { $item['label'] = $data['url_data'][$item['id']]['plural'] . ' RSS'; } } else { if (preg_match('/s$/', $item['auto']) || $item['auto'] === 'timeline') { if ($item['auto'] === 'timeline' && isset($item['year'])) { $item['path'] .= $item['year'] . '/'; if (isset($item['month']) && $item['month'] !== false && $item['month'] !== 'any') { $m = str_pad($item['month'], 2, '0', STR_PAD_LEFT); $item['path'] .= $m . '/'; } } if (strpos($item['auto'], '_') !== false) { foreach (array('id', 'slug', 'month', 'year', 'day') as $id) { if ($id === 'month') { if (!isset($item['month']) || $item['month'] === 'any' || $item['month'] === false) { $item['month'] = ''; } else { $item['month'] = str_pad($item['month'], 2, '0', STR_PAD_LEFT); } } if ($id === 'day' && !isset($item['day'])) { $item['day'] = ''; } if ($id === 'slug' && !isset($item['slug']) && isset($item['id'])) { if (strpos($item['auto'], 'tag_') === 0) { $item['slug'] = $item['id']; } else { $c = new Category(); if (is_numeric($item['id'])) { $c->select('slug')->get_by_id($item['id']); $item['slug'] = $c->slug; } else { $item['slug'] = $item['id']; } } } if (isset($item[$id])) { $item['path'] = str_replace(":{$id}", $item[$id], $item['path']); } } } else { if (!isset($item['label'])) { $item['label'] = $data['url_data'][$item['auto'] === 'categories' ? 'category' : rtrim($item['auto'], 's')]['plural']; } } } else { if ($item['auto'] === 'home') { if (!isset($item['label'])) { $item['label'] = $data['url_data']['home']; } $item['path'] = '/home/'; } else { if ($item['auto'] === 'album' || $item['auto'] === 'set') { $a = new Album(); $a->select('id,slug,created_on,title'); if (is_numeric($item['id'])) { $a->where('id', $item['id']); } else { $a->where('slug', $item['id'])->or_where('internal_id', $item['id']); } $a->get(); if (!$a->exists()) { unset($items[$index]); continue; } $item['path'] = str_replace(':id', $a->id, $item['path']); $item['path'] = str_replace(':slug', $a->slug, $item['path']); $item['path'] = str_replace(':year', date('Y', $a->created_on), $item['path']); $item['path'] = str_replace(':month', date('m', $a->created_on), $item['path']); $item['path'] = str_replace(':day', date('d', $a->created_on), $item['path']); if (!isset($item['label'])) { $item['label'] = $a->title; } } else { if ($item['auto'] === 'page' || $item['auto'] === 'essay') { $t = new Text(); $t->select('id,slug,published_on,title'); if (is_numeric($item['id'])) { $t->where('id', $item['id']); } else { $t->where('slug', $item['id']); } $t->get(); if (!$t->exists()) { unset($items[$index]); continue; } $item['path'] = str_replace(':id', $t->id, $item['path']); $item['path'] = str_replace(':slug', $t->slug, $item['path']); $item['path'] = str_replace(':year', date('Y', $t->published_on), $item['path']); $item['path'] = str_replace(':month', date('m', $t->published_on), $item['path']); $item['path'] = str_replace(':day', date('d', $t->published_on), $item['path']); if (!isset($item['label'])) { $item['label'] = $t->title; } } else { if ($item['auto'] === 'content') { $c = new Content(); $c->select('id,slug,captured_on,title'); if (isset($item['album_id'])) { $item['path'] = preg_replace('/:(id|slug)/', ':album_$1', $data['urls']['album']) . substr(str_replace(':year/:month/', '', $data['urls']['content']), 1); $a = new Album(); $a->select('id,slug,created_on,title'); if (is_numeric($item['album_id'])) { $a->where('id', $item['album_id']); } else { $a->where('slug', $item['album_id'])->or_where('internal_id', $item['album_id']); } $a->get(); if (!$a->exists()) { unset($items[$index]); continue; } $item['path'] = str_replace(':album_id', $a->id, $item['path']); $item['path'] = str_replace(':album_slug', $a->slug, $item['path']); $date = $a->created_on; } else { $date = $c->captured_on; } if (is_numeric($item['id'])) { $c->where('id', $item['id']); } else { $c->where('slug', $item['id'])->or_where('internal_id', $item['id']); } $c->get(); if (!$c->exists()) { unset($items[$index]); continue; } $item['path'] = str_replace(':id', $c->id, $item['path']); $item['path'] = str_replace(':slug', $c->slug, $item['path']); $item['path'] = str_replace(':year', date('Y', $date), $item['path']); $item['path'] = str_replace(':month', date('m', $date), $item['path']); $item['path'] = str_replace(':day', date('d', $date), $item['path']); if (!isset($item['label'])) { $item['label'] = $c->title; } if (isset($item['lightbox']) && $item['lightbox']) { $item['path'] .= 'lightbox/'; } } else { if ($item['auto'] === 'tag') { $item['path'] = str_replace(':slug', $item['id'], $item['path']); } } } } } } } } if ($item['auto'] !== 'profile') { $item['path'] = str_replace(array(':year', ':month'), '', $item['path']); $item['path'] = preg_replace('/[\\(\\)\\?\\:]/', '', $item['path']); $item['path'] = preg_replace('~[/]+~', '/', $item['path']); } } } return $items; } $template_info['navigation']['items'] = build_autos($template_info['navigation']['items'], $data, $user); $template_info['navigation']['items_nested'] = nest($template_info['navigation']['items'], $template_info['routes'], $albums_indexed, $album_keys, $ceiling); foreach ($template_info['navigation']['groups'] as &$group) { $group['items'] = build_autos($group['items'], $data, $user); $group['items_nested'] = nest($group['items'], $template_info['routes'], $albums_indexed, $album_keys, $ceiling); } $pages = array(); $paths = array(); foreach ($template_info['routes'] as $path => $arr) { $pages[] = array_merge(array('path' => (string) $path), $arr); $paths[] = $path; } $template_info['routes'] = $pages; if (isset($template_info['settings'])) { $default_style_vars = array(); if (isset($template_info['styles']) && count($template_info['styles'])) { $tmp = array_reverse($template_info['styles']); foreach ($tmp as $style) { if (isset($style['variables'])) { $default_style_vars = array_merge($default_style_vars, $style['variables']); } } } list($template_info['settings'], $template_info['settings_flat']) = $this->_prep_options($template_info['settings'], isset($draft->data['settings']) ? $draft->data['settings'] : array(), isset($template_info['style']) && isset($template_info['style']['variables']) ? $template_info['style']['variables'] : array(), $default_style_vars); if (isset($draft->data['settings']) && isset($draft->data['settings']['__style'])) { $template_info['settings_flat']['__style'] = array('value' => $draft->data['settings']['__style']); } } else { $template_info['settings'] = $template_info['settings_flat'] = array(); } if (isset($template_info['style']) && isset($template_info['style']['variables'])) { foreach ($template_info['style']['variables'] as $key => &$varval) { if (preg_match('/#[a-z0-9]{3}$/i', $varval)) { $varval = $varval . substr($varval, 1); } if (!isset($template_info['settings_flat'][$key])) { $template_info['settings_flat'][$key] = array('value' => $varval); } } } $types = array(); $names = array(); $templates_indexed = $template_info['templates']; foreach ($template_info['templates'] as $key => $val) { if (isset($val['source']) && $val['source'] === 'date') { $val['source'] = 'archives'; } $types[] = array('path' => $key, 'info' => $val); $names[] = $val['name']; } natcasesort($names); $final = array(); foreach ($names as $index => $name) { $final[] = $types[$index]; } $template_info['templates'] = $final; $bools = array('site_hidpi'); foreach ($site as $s) { $clean_key = preg_replace('/^site_/', '', $s->name); if (isset($data[$clean_key])) { continue; } $val = $s->value; if (in_array($s->name, $bools)) { $val = $val == 'true'; } $data[$clean_key] = $val; } $data['draft_id'] = $draft->id; $data['theme'] = array('path' => isset($params['preview']) ? $params['preview'] : $draft->path); unset($data['id']); foreach ($template_info as $key => $val) { if (in_array($key, array('name', 'version', 'description', 'demo'))) { $data['theme'][$key] = $val; } else { $data[$key] = $val; } } $data['routes'] = array_merge($data['routes'], $routes); // templates always need to be after routes $templates_tmp = $data['templates']; $routes_tmp = $data['routes']; unset($data['templates']); unset($data['routes']); $data['routes'] = $routes_tmp; $data['templates'] = Shutter::filter('site.templates', array($templates_tmp)); $data['profile'] = array('name' => $user->public_display === 'both' ? $user->public_first_name . ' ' . $user->public_last_name : $user->{"public_{$user->public_display}_name"}, 'first' => $user->public_first_name, 'last' => $user->public_last_name, 'email' => $user->public_email, 'twitter' => str_replace('@', '', $user->twitter), 'facebook' => $user->facebook, 'google_plus' => $user->google); if (isset($draft->data['custom_css'])) { $data['custom_css'] = $draft->data['custom_css']; } else { $data['custom_css'] = ''; } $this->set_response_data($data); } else { switch ($this->method) { case 'put': global $raw_input_data; $data = json_decode($raw_input_data['data'], true); if (isset($data['revert'])) { if ($data['revert'] === 'all') { $draft->data = $draft->live_data; } else { unset($draft->data['settings']); $draft->data = json_encode($draft->data); } } else { if (isset($data['custom_css'])) { $draft->data['custom_css'] = $data['custom_css']; } if (isset($data['navigation'])) { unset($data['navigation']['active']); $draft->data['navigation'] = $data['navigation']; } if (isset($data['routes'])) { $pages = array(); foreach ($data['routes'] as $p) { if (isset($p['section'])) { continue; } $key = $p['path']; unset($p['path']); if (!in_array($p, $template_info['routes'])) { $pages[$key] = $p; } } $draft->data['routes'] = $pages; } if (isset($data['settings_send'])) { foreach ($data['settings_send'] as $key => $val) { $draft->data['settings'][$key] = $val; } } if (isset($data['url_data_send'])) { $source = $data['url_data_send']['source'] === 'categories' ? 'category' : rtrim($data['url_data_send']['source'], 's'); $u = new Url(); $u->order_by('id DESC')->get(); $new_data = unserialize($u->data); foreach ($new_data as &$url_data) { if ($url_data['type'] === $source) { $url_data['data'][$data['url_data_send']['order']] = $data['url_data_send']['value']; break; } } $u->data = serialize($new_data); $u->save(); } if (isset($data['pulse_settings_send']) && !empty($data['pulse_settings_send'])) { if (!isset($draft->data['pulse_groups'][$data['pulse_settings_group']])) { $draft->data['pulse_groups'][$data['pulse_settings_group']] = array(); } foreach ($data['pulse_settings_send'] as $key => $val) { $draft->data['pulse_groups'][$data['pulse_settings_group']][$key] = $val; } } $draft->data = json_encode($draft->data); } $draft->save(); $this->redirect("/site/draft:true"); break; } } }
function index() { if (!$this->auth) { $this->error('401', 'Not authorized to perform this action.'); return; } list($params, $id) = $this->parse_params(func_get_args()); $plugins = $this->parse_plugins(); $db_config = Shutter::get_db_configuration(); switch ($this->method) { case 'delete': $p = new Plugin(); $p->where('id', $id)->get(); if ($p->exists()) { $p->run_plugin_method('after_uninstall', $plugins); $plugin = $p->init($plugins); if ($plugin->database_fields) { $this->load->dbforge(); foreach ($plugin->database_fields as $table => $fields) { $table = $db_config['prefix'] . $table; foreach ($fields as $column => $info) { $this->dbforge->drop_column($table, $column); } } $this->_clear_datamapper_cache(); } $p->delete(); } $this->_compile_plugins(); exit; break; case 'post': $p = new Plugin(); $p->path = $_POST['path']; $p->setup = $p->run_plugin_method('require_setup', $plugins) === false; if ($p->save()) { $plugin = $p->init($plugins); if ($plugin->database_fields) { $this->load->dbforge(); foreach ($plugin->database_fields as $table => $fields) { $table = $db_config['prefix'] . $table; foreach ($fields as $column => $info) { $this->dbforge->add_column($table, array($column => $info)); } } $this->_clear_datamapper_cache(); } $p->run_plugin_method('after_install', $plugins); } $this->_compile_plugins(); $this->redirect('/plugins'); break; case 'put': unset($_POST['_method']); $data = serialize($_POST); $p = new Plugin(); $p->where('id', $id)->get(); $p->save_data($plugins, $_POST); $validate = $p->run_plugin_method('confirm_setup', $plugins, $data); if ($validate === true) { $p->setup = 1; $p->save(); $this->_compile_plugins(); exit; } else { $this->error(400, $validate); return; } break; default: $data = array('plugins' => $plugins); function sortByName($a, $b) { return $a['name'] > $b['name']; } usort($data['plugins'], 'sortByName'); $data['plugins'] = Shutter::filter('api.plugins', array($data['plugins'])); $data['custom_sources'] = Shutter::$custom_sources; $this->set_response_data($data); break; } }
public static function cache($contents) { $buster = self::$root_path . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'no-site-cache'; $cache_path = Shutter::filter('site.cache.write.path', self::$cache_path); if (isset($cache_path) && error_reporting() == 0 && !file_exists($buster)) { Shutter::write_cache($cache_path, $contents); } }
function index() { if (!$this->auth) { $this->error('403', 'Forbidden'); return; } $image_processing = new Setting(); $image_processing->where('name', 'image_processing_library')->get(); include FCPATH . 'app' . DIRECTORY_SEPARATOR . 'koken' . DIRECTORY_SEPARATOR . 'DarkroomUtils.php'; $libs = DarkroomUtils::libraries(); if ($image_processing->exists()) { if (!isset($libs[$image_processing->value])) { $top = array_shift(array_keys($libs)); $lib = $libs[$top]; $image_processing->value = $lib['key']; $image_processing->save(); } } else { if (!defined('MAGICK_PATH_FINAL') || (MAGICK_PATH_FINAL === 'convert' || !isset($libs[MAGICK_PATH_FINAL]))) { $top = array_shift(array_keys($libs)); $lib = $libs[$top]; } else { $lib = $libs[MAGICK_PATH_FINAL]; } $image_processing->name = 'image_processing_library'; $image_processing->value = $lib['key']; $image_processing->save(); } $last_check = new Setting(); $last_check->where('name', 'last_migration'); $last_check_count = $last_check->count(); if ($last_check_count > 1) { $last_check->where('name', 'last_migration')->order_by('value ASC')->limit($last_check_count - 1)->get(); $last_check->delete_all(); } $s = new Setting(); $settings = $s->get_iterated(); $data = array('image_processing_libraries' => array_values($libs)); $bools = array('has_toured', 'site_hidpi', 'retain_image_metadata', 'image_use_defaults', 'use_default_labels_links', 'uploading_publish_on_captured_date'); foreach ($settings as $setting) { // Don't allow dupes to screw things up if (isset($data[$setting->name])) { continue; } $value = $setting->value; if (in_array($setting->name, $bools)) { $value = $value == 'true'; } if ($setting->name === 'last_upload') { $value = $value === 'false' ? false : (int) $value; } $data[$setting->name] = $value; } if (!isset($data['uploading_publish_on_captured_date'])) { $data['uploading_publish_on_captured_date'] = false; } if (!isset($data['uploading_default_album_visibility'])) { $data['uploading_default_album_visibility'] = 'public'; } if (!isset($data['email_handler'])) { $data['email_handler'] = 'DDI_Email'; } $data['email_handlers'] = Shutter::get_email_handlers(); $disable_cache_file = FCPATH . 'storage' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'no-site-cache'; $data['enable_site_cache'] = !file_exists($disable_cache_file); if ($this->method != 'get') { if ($this->auth_role !== 'god') { $this->error('403', 'Forbidden'); return; } if (isset($_POST['signin_bg'])) { $c = new Content(); $c->get_by_id($_POST['signin_bg']); if ($c->exists()) { $_c = $c->to_array(); $large = array_pop($_c['presets']); // TODO: Error checking for permissions reject $f = $large['url']; $to = FCPATH . 'storage' . DIRECTORY_SEPARATOR . 'wallpaper' . DIRECTORY_SEPARATOR . 'signin.jpg'; if (extension_loaded('curl')) { $cp = curl_init($f); $fp = fopen($to, "w+"); if (!$fp) { curl_close($cp); } else { curl_setopt($cp, CURLOPT_FILE, $fp); curl_exec($cp); curl_close($cp); fclose($fp); } } elseif (ini_get('allow_url_fopen')) { copy($f, $to); } } } else { if (isset($_POST['enable_site_cache'])) { if ($_POST['enable_site_cache'] === 'true') { @unlink($disable_cache_file); } else { touch($disable_cache_file); delete_files(dirname($disable_cache_file) . DIRECTORY_SEPARATOR . 'site', true, 1); } unset($_POST['enable_site_cache']); } // TODO: Make sure new path is not inside real_base // TODO: Ensure that real_base is not deleted under any circumstances if (isset($_POST['site_url']) && $_POST['site_url'] !== $data['site_url']) { $_POST['site_url'] = strtolower(rtrim($_POST['site_url'], '/')); if (empty($_POST['site_url'])) { $_POST['site_url'] = '/'; } if (isset($_SERVER['PHP_SELF']) && isset($_SERVER['SCRIPT_FILENAME'])) { $php_self = str_replace('/', DIRECTORY_SEPARATOR, $_SERVER['PHP_SELF']); $doc_root = preg_replace('~' . $php_self . '$~i', '', $_SERVER['SCRIPT_FILENAME']); } else { $doc_root = $_SERVER['DOCUMENT_ROOT']; } $doc_root = realpath($doc_root); $target = $doc_root . str_replace('/', DIRECTORY_SEPARATOR, $_POST['site_url']); $php_include_base = rtrim(preg_replace('~^' . $doc_root . '~', '', FCPATH), DIRECTORY_SEPARATOR); $real_base = $doc_root; if (empty($php_include_base)) { $real_base .= DIRECTORY_SEPARATOR; } else { $real_base .= $php_include_base; } @($target_dir = dir($target)); $real_base_dir = dir($real_base); function compare_paths($one, $two) { return rtrim($one, DIRECTORY_SEPARATOR) === rtrim($two, DIRECTORY_SEPARATOR); } if ($target_dir && compare_paths($target_dir->path, $real_base_dir->path)) { $_POST['site_url'] = 'default'; $htaccess = create_htaccess(); $root_htaccess = FCPATH . '.htaccess'; $current = file_get_contents($root_htaccess); preg_match('/#MARK#.*/s', $htaccess, $match); $htaccess = preg_replace('/#MARK#.*/s', str_replace('$', '\\$', $match[0]), $current); file_put_contents($root_htaccess, $htaccess); } else { if ($target_dir) { $reserved = array('admin', 'app', 'storage'); foreach ($reserved as $dir) { $_dir = dir(rtrim($real_base_dir->path, '/') . "/{$dir}"); if (compare_paths($target_dir->path, $_dir->path)) { $this->error('400', "This directory is reserved for Koken core files. Please choose another location."); return; } } } if (!make_child_dir($target)) { $this->error('500', "Koken was not able to create the Site URL directory. Make sure the path provided is writable by the web server and try again."); return; } $php_include_rel = str_replace(DIRECTORY_SEPARATOR, '/', $php_include_base); $php_include_base = str_replace('\\', '\\\\', $php_include_base); $doc_root_php = str_replace('\\', '\\\\', $doc_root); $php = <<<OUT <?php \t\$rewrite = false; \t\$real_base_folder = '{$php_include_rel}'; \trequire '{$doc_root_php}{$php_include_base}' . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'site' . DIRECTORY_SEPARATOR . 'site.php'; OUT; $htaccess = create_htaccess($_POST['site_url']); if ($this->check_for_rewrite()) { $file = $target . DIRECTORY_SEPARATOR . '.htaccess'; $file_data = $htaccess; $put_mode = FILE_APPEND; if ($_POST['site_url'] !== 'default' && "{$doc_root}" . DIRECTORY_SEPARATOR !== FCPATH) { $root_htaccess = FCPATH . '.htaccess'; if (file_exists($root_htaccess)) { $current = file_get_contents($root_htaccess); $redirect = create_htaccess($_POST['site_url'], true); preg_match('/#MARK#.*/s', $redirect, $match); $redirect = preg_replace('/#MARK#.*/s', str_replace('$', '\\$', $match[0]), $current); file_put_contents($root_htaccess, $redirect); } } } else { $file = $target . DIRECTORY_SEPARATOR . 'index.php'; $file_data = $php; $put_mode = 0; } if (file_exists($file)) { rename($file, "{$file}.bkup"); } if (!file_put_contents($file, $file_data, $put_mode)) { $this->error('500', "Koken was not able to create the necessary files in the Site URL directory. Make sure that path has sufficient permissions so that Koken may write the files."); return; } } if ($data['site_url'] !== 'default') { $old = $doc_root . str_replace('/', DIRECTORY_SEPARATOR, $data['site_url']); $old_dir = dir($old); if (!compare_paths($old_dir->path, $real_base_dir->path)) { if ($this->check_for_rewrite()) { $old_file = $old . DIRECTORY_SEPARATOR . '.htaccess'; } else { $old_file = $old . DIRECTORY_SEPARATOR . 'index.php'; } unlink($old_file); $backup = $old_file . '.bkup'; if (file_exists($backup)) { rename($backup, $old_file); } // This will only remove the dir if it is empty @rmdir($old); } } } global $raw_input_data; if (isset($raw_input_data['url_data'])) { $url_data = json_decode($raw_input_data['url_data'], true); $u = new Url(); $u->order_by('id DESC')->get(); $existing_data = unserialize($u->data); $transformed = array(); foreach ($url_data as $key => $udata) { $transformed[] = array('type' => $key, 'data' => $udata); } if ($existing_data !== $transformed) { $n = new Url(); $n->data = serialize($transformed); $n->save(); } unset($_POST['url_data']); } $save = array(); foreach ($_POST as $key => $val) { if (isset($data[$key]) && $data[$key] !== $val) { if ($key === 'retain_image_metadata' || $key !== 'image_processing_library' && strpos($key, 'image_') === 0) { delete_files(FCPATH . 'storage' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'images', true, 1); } $save[$key] = $val; } } foreach ($save as $k => $v) { $s = new Setting(); $s->where('name', $k)->get(); if ($s->exists()) { $s->value = $v; $s->save(); } else { if (in_array($k, array('uploading_default_album_visibility', 'uploading_publish_on_captured_date', 'email_handler'))) { $n = new Setting(); $n->name = $k; $n->value = $v; $n->save(); } } } if (isset($save['email_handler']) || isset($save['email_delivery_address'])) { $this->_compile_plugins(); } } $this->redirect('/settings'); } if (!isset($data['site_timezone']) || empty($data['site_timezone']) || $data['site_timezone'] === 'Etc/UTC') { $data['site_timezone'] = 'UTC'; } else { if ($data['site_timezone'] === 'Etc/GMT+12') { $data['site_timezone'] = 'Pacific/Auckland'; } } $data['image_processing_library_label'] = $libs[$data['image_processing_library']]['label']; $migrate_path = FCPATH . 'app' . DIRECTORY_SEPARATOR . 'application' . DIRECTORY_SEPARATOR . 'models' . DIRECTORY_SEPARATOR . 'migrations' . DIRECTORY_SEPARATOR; $migrations = scandir($migrate_path); $data['migrations'] = array(); if (!isset($data['last_migration'])) { $migration_setting = new Setting(); $migration_setting->name = 'last_migration'; $migration_setting->value = '26'; $migration_setting->save(); $data['last_migration'] = '26'; } if (!isset($data['has_toured']) || ENVIRONMENT === 'development') { $data['has_toured'] = true; } foreach ($migrations as $migration) { $migration = str_replace('.php', '', $migration); $migration_int = (int) $migration; if ($migration_int > $data['last_migration']) { $data['migrations'][] = $migration; } } unset($data['last_migration']); $data = Shutter::filter('api.settings', array($data)); $this->set_response_data($data); }
function to_array($options = array()) { $options = array_merge(array('auth' => false, 'render' => true, 'expand' => false), $options); $koken_url_info = $this->config->item('koken_url_info'); $exclude = array('deleted', 'total_count', 'video_count', 'audio_count', 'featured_image_id', 'custom_featured_image', 'tags_old', 'old_slug'); $dates = array('created_on', 'modified_on', 'published_on', 'featured_on'); $strings = array('title', 'content', 'excerpt'); $bools = array('published', 'featured'); if (!$this->published) { $this->published_on = time(); } list($data, $public_fields) = $this->prepare_for_output($options, $exclude, $bools, $dates, $strings); if (strlen(trim($data['draft'])) === 0) { $data['draft'] = $data['content']; } if (strlen(trim($data['draft_title'])) === 0) { $data['draft_title'] = $data['title']; } if (!$data['featured']) { unset($data['featured_on']); } if ($data['page_type'] != 0) { unset($data['featured']); unset($data['featured_on']); } if (!$options['auth']) { unset($data['internal_id']); unset($data['draft']); unset($data['draft_title']); } if (array_key_exists('page_type', $data)) { switch ($data['page_type']) { case 1: $data['page_type'] = 'page'; break; default: $data['page_type'] = 'essay'; } } $data['__koken__'] = $data['page_type']; $data['tags'] = $this->_get_tags_for_output($options); $data['categories'] = array('count' => is_null($this->category_count) ? $this->categories->count() : (int) $this->category_count, 'url' => $koken_url_info->base . 'api.php?/text/' . $data['id'] . '/categories'); $data['topics'] = array('count' => is_null($this->album_count) ? $this->albums->count() : (int) $this->album_count, 'url' => $koken_url_info->base . 'api.php?/text/' . $data['id'] . '/topics'); if (is_numeric($this->featured_image_id) && !$this->featured_image->id) { $this->featured_image->get(); } if ($this->featured_image->id && $this->featured_image->deleted == 0) { $data['featured_image'] = $this->featured_image->to_array(); } else { if (!empty($this->custom_featured_image)) { $c = new Content(); $data['featured_image'] = $c->to_array_custom($this->custom_featured_image); } else { $data['featured_image'] = false; } } $rendered = Shutter::shortcodes($data['content'], array($this, $options)); if ($options['render']) { if ($options['expand']) { $rendered = preg_replace('/\\[read_more([^\\]]+)?\\]/', '<a id="more"></a>', $rendered); } else { $more = strpos($rendered, '[read_more'); if ($more !== false) { preg_match('/\\[read_more(?:\\s*label="(.*)")?\\]/', $rendered, $matches); $rendered = substr($rendered, 0, $more); $data['read_more'] = true; $data['read_more_label'] = count($matches) > 1 ? $matches[1] : 'Read more'; } } } if (!isset($data['read_more'])) { $data['read_more'] = false; } preg_match_all('/<koken:load source="content" filter:id="(\\d+)">/', $rendered, $loads); if (count($loads[0]) > 1) { $this->ids_for_array_index = array_unique($loads[1]); $rendered = '<koken:load source="contents" filter:id="' . join(',', $this->ids_for_array_index) . '">' . $rendered . '</koken:load>'; $rendered = preg_replace_callback('/<koken:load source="content" filter:id="(\\d+)">(.*)<\\/koken:load>/msU', array($this, '_array_index_callback'), $rendered); } if (empty($options) || isset($options['render']) && $options['render']) { $data['content'] = $rendered; if (isset($data['draft'])) { $data['draft'] = Shutter::shortcodes($data['draft'], array($this, $options)); } } if (empty($data['excerpt'])) { $rendered = preg_replace('/<script.*>.*?<\\/script>/msU', '', $rendered); $rendered = preg_replace('/<figure class="k-content-embed">.*?<\\/figure>/msU', '', $rendered); $clean_parts = explode(' ', preg_replace('/([\\.\\?\\!]+)([^\\s]\\s*[a-z][a-z\\s]*)/', '$1 $2', trim(strip_tags(preg_replace('/\\{\\{.*\\}\\}/', '', html_entity_decode($rendered)))))); $excerpt = ''; while (count($clean_parts) && ($next = array_shift($clean_parts)) && strlen(trim($excerpt) . ' ' . trim($next)) <= 254) { $excerpt .= ' ' . trim($next); } $data['excerpt'] = trim($excerpt); if (count($clean_parts)) { $data['excerpt'] = preg_replace('/[^\\w]$/u', '', $data['excerpt']) . '…'; } $more = strpos($data['excerpt'], '[read_more'); if ($more !== false) { $data['excerpt'] = trim(substr($data['excerpt'], 0, $more)); } } if (isset($options['order_by']) && in_array($options['order_by'], array('created_on', 'modified_on', 'published_on'))) { $data['date'] =& $data[$options['order_by']]; } else { if ($data['page_type'] === 'essay') { $data['date'] =& $data['published_on']; } } $cat = isset($options['category']) ? $options['category'] : (isset($options['context']) && strpos($options['context'], 'category-') === 0 ? str_replace('category-', '', $options['context']) : false); if ($cat) { if (is_numeric($cat)) { foreach ($this->categories->get_iterated() as $c) { if ($c->id == $cat) { $cat = $c->slug; break; } } } } $data['url'] = $this->url(array('date' => $data['published_on'], 'tag' => isset($options['tags']) ? $options['tags'] : (isset($options['context']) && strpos($options['context'], 'tag-') === 0 ? str_replace('tag-', '', $options['context']) : false), 'category' => $cat)); if ($data['url']) { list($data['__koken_url'], $data['url']) = $data['url']; $data['canonical_url'] = $data['url']; } return Shutter::filter('api.text', array($data, $this, $options)); }
function to_array($options = array()) { $options['auth'] = isset($options['auth']) ? $options['auth'] : false; $options['in_album'] = isset($options['in_album']) ? $options['in_album'] : false; $exclude = array('storage_url', 'storage_url_midsize', 'deleted', 'featured_order', 'favorite_order', 'old_slug', 'has_exif', 'has_iptc', 'tags_old'); $bools = array('featured', 'favorite'); $dates = array('uploaded_on', 'modified_on', 'captured_on', 'featured_on', 'file_modified_on', 'published_on'); $strings = array('title', 'caption'); list($data, $fields) = $this->prepare_for_output($options, $exclude, $bools, $dates, $strings); $data = Shutter::filter('api.content.before', array($data, $this, $options)); if (!$data['featured']) { unset($data['featured_on']); } if (!$data['favorite']) { unset($data['favorited_on']); } $koken_url_info = $this->config->item('koken_url_info'); if ($this->file_type != 0 && !empty($this->lg_preview)) { $preview_file = array_shift(explode(':', $this->lg_preview)); } if ($options['auth'] || $data['file_type'] != 0 || (int) $data['max_download'] === 1) { $pathinfo = pathinfo($this->filename); $path = 'storage/originals/' . str_replace(DIRECTORY_SEPARATOR, '/', $this->path) . '/' . $pathinfo['basename']; $url = $koken_url_info->base . $path; if (preg_match('/^https?:/', $this->filename)) { $data['original'] = array(); } else { if (!empty($this->storage_url)) { $data['original'] = array('url' => $this->storage_url, 'width' => (int) $this->width, 'height' => (int) $this->height); if (!empty($this->storage_url_midsize)) { $data['original']['midsize'] = $this->storage_url_midsize; } } else { $data['original'] = array('url' => $url, 'relative_url' => '/' . $path, 'width' => (int) $this->width, 'height' => (int) $this->height); } } if (isset($preview_file)) { $path .= '_previews/' . $preview_file; $url = $koken_url_info->base . $path; list($pw, $ph) = getimagesize(FCPATH . $path); $data['original']['preview'] = array('url' => $url, 'relative_url' => '/' . $path, 'width' => $pw, 'height' => $ph); } } if (!$options['auth'] && $data['visibility'] == 0) { unset($data['internal_id']); } if (!preg_match('~https?://~', $this->filename)) { $info = pathinfo($this->filename); $mimes = array('jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png', 'flv' => 'video/x-flv', 'f4v' => 'video/f4v', 'swf' => 'application/x-shockwave-flash', 'mov' => 'video/mp4', 'mp4' => 'video/mp4', 'm4v' => 'video/x-m4v', '3gp' => 'video/3gpp', '3g2' => 'video/3gpp2', 'mp3' => 'audio/mpeg'); if (array_key_exists(strtolower($info['extension']), $mimes)) { $data['mime_type'] = $mimes[strtolower($info['extension'])]; } else { if (function_exists('mime_content_type')) { $data['mime_type'] = mime_content_type($this->path_to_original()); } else { $data['mime_type'] = ''; } } } else { $data['mime_type'] = ''; } $data['__koken__'] = 'content'; if (!isset($options['include_presets']) || $options['include_presets']) { include_once FCPATH . 'app' . DIRECTORY_SEPARATOR . 'koken' . DIRECTORY_SEPARATOR . 'DarkroomUtils.php'; if ($this->file_type > 0 && empty($this->lg_preview)) { $prefix = $koken_url_info->base . 'admin/images/no-thumb,'; $data['cache_path'] = array('prefix' => $prefix, 'extension' => 'png'); $data['presets'] = array(); foreach (DarkroomUtils::$presets as $name => $opts) { $h = $opts['width'] * 2 / 3; $data['presets'][$name] = array('url' => $koken_url_info->base . "admin/images/no-thumb,{$name}.png", 'width' => $opts['width'], 'height' => round($h)); $data['presets'][$name]['cropped'] = array('url' => $koken_url_info->base . "admin/images/no-thumb,{$name}.crop.png", 'width' => $opts['width'], 'height' => $opts['width']); } } else { if ($this->file_type > 0 || !preg_match('~^https?://~', $this->filename)) { if (isset($info['extension'])) { $prefix = preg_replace("/\\.{$info['extension']}\$/", '', basename($this->filename)); } else { $prefix = basename($this->filename); } if (isset($preview_file)) { $info = pathinfo($preview_file); } $cache_base = $koken_url_info->base . (KOKEN_REWRITE ? 'storage/cache/images' : 'i.php?') . '/' . str_replace('\\', '/', $this->cache_path) . '/' . $prefix . ','; $data['cache_path'] = array('prefix' => $cache_base); $data['cache_path']['extension'] = $data['file_modified_on']['timestamp'] . '.' . $info['extension']; $data['presets'] = array(); foreach (DarkroomUtils::$presets as $name => $opts) { $dims = $this->compute_cache_size($opts['width'], $opts['height']); if ($dims) { list($w, $h) = $dims; $data['presets'][$name] = array('url' => $cache_base . "{$name}.{$data['file_modified_on']['timestamp']}.{$info['extension']}", 'hidpi_url' => $cache_base . "{$name}.2x.{$data['file_modified_on']['timestamp']}.{$info['extension']}", 'width' => (int) $w, 'height' => (int) $h); list($cx, $cy) = $this->compute_cache_size($opts['width'], $opts['height'], true); $data['presets'][$name]['cropped'] = array('url' => $cache_base . "{$name}.crop.{$data['file_modified_on']['timestamp']}.{$info['extension']}", 'hidpi_url' => $cache_base . "{$name}.crop.2x.{$data['file_modified_on']['timestamp']}.{$info['extension']}", 'width' => (int) $cx, 'height' => (int) $cy); } } } } } if ($data['file_type'] == 0) { unset($data['duration']); } if (array_key_exists('duration', $data)) { $r = $data['duration']; $data['duration'] = array(); $data['duration']['raw'] = $r; $m = floor($r / 60); $s = str_pad(floor($r % 60), 2, '0', STR_PAD_LEFT); if ($m > 60) { $h = floor($m / 60); $m = str_pad(floor($m % 60), 2, '0', STR_PAD_LEFT); $m = "{$h}:{$m}"; } $data['duration']['clean'] = "{$m}:{$s}"; } $data['iptc'] = $data['iptc_fields'] = $data['exif'] = $data['exif_fields'] = array(); if ($this->has_iptc) { list($data['iptc'], $data['iptc_fields']) = $this->iptc_to_human(); } $data['geolocation'] = false; if ($this->has_exif) { if (!isset($options['exif'])) { $options['exif'] = 'all'; } $exif = $this->_get_exif_data(); if (isset($exif['GPS']['GPSLatitude'])) { include_once FCPATH . 'app' . DIRECTORY_SEPARATOR . 'koken' . DIRECTORY_SEPARATOR . 'gps.php'; $gps = new GPS($exif['GPS']); $data['geolocation'] = array('latitude' => rtrim(sprintf('%.12f', $gps->latitude()), '0'), 'longitude' => rtrim(sprintf('%.12f', $gps->longitude()), '0')); } list($data['exif'], $data['exif_fields']) = $this->exif_to_human($data['exif'], $options['exif']); } if (array_key_exists('file_type', $data)) { switch ($data['file_type']) { // TODO: Make this array and include mime type? Ehhh? case 0: $data['file_type'] = 'image'; break; case 1: $data['file_type'] = 'video'; break; case 2: $data['file_type'] = 'audio'; break; } } if (array_key_exists('visibility', $data)) { switch ($data['visibility']) { case 1: $raw = 'unlisted'; break; case 2: $raw = 'private'; break; default: $raw = 'public'; break; } $data['visibility'] = array('raw' => $raw, 'clean' => ucwords($raw)); $data['public'] = $raw === 'public'; } if (array_key_exists('max_download', $data)) { switch ($data['max_download']) { case 0: $data['max_download'] = 'none'; $clean = 'None'; break; case 1: $data['max_download'] = 'original'; $clean = 'Original'; break; case 2: $data['max_download'] = 'huge'; $clean = 'Huge (2048)'; break; case 3: $data['max_download'] = 'xlarge'; $clean = 'X-Large (1600)'; break; case 4: $data['max_download'] = 'large'; $clean = 'Large (1024)'; break; case 5: $data['max_download'] = 'medium_large'; $clean = 'Medium-Large (800)'; break; case 6: $data['max_download'] = 'medium'; $clean = 'Medium (480)'; break; } $data['max_download'] = array('raw' => $data['max_download'], 'clean' => $clean); } if (array_key_exists('license', $data) && !is_null($data['license'])) { if ($data['license'] == 'all') { $clean = '© All rights reserved'; } else { // Data is stored as commercial,modifications ... (y|n),(y,s,n) // Example: NonCommercial ShareAlike == n,s list($commercial, $mods) = explode(',', $data['license']); $license_url = 'http://creativecommons.org/licenses/by'; if ($commercial == 'y') { $clean = 'Commercial'; } else { $license_url .= '-nc'; $clean = 'NonCommercial'; } switch ($mods) { case 'y': // Nothing to do here, standard license break; case 's': $clean .= '-ShareAlike'; $license_url .= '-sa'; break; case 'n': $clean .= '-NoDerivs'; $license_url .= '-nd'; break; } $license_url .= '/3.0/deed.en_US'; } $data['license'] = array('raw' => $data['license'], 'clean' => $clean); if (isset($license_url)) { $data['license']['url'] = $license_url; } } $data['tags'] = $this->_get_tags_for_output($options); $data['categories'] = array('count' => is_null($this->category_count) ? $this->categories->count() : (int) $this->category_count, 'url' => $koken_url_info->base . 'api.php?/content/' . $data['id'] . '/categories'); $data['albums'] = array('count' => is_null($this->album_count) ? $this->albums->count() : (int) $this->album_count, 'url' => $koken_url_info->base . 'api.php?/content/' . $data['id'] . '/albums'); if (isset($options['order_by']) && in_array($options['order_by'], array('uploaded_on', 'modified_on', 'captured_on'))) { $data['date'] =& $data[$options['order_by']]; } else { $data['date'] =& $data['published_on']; } if ($data['visibility'] === 'private') { $data['url'] = false; } else { $cat = isset($options['category']) ? $options['category'] : (isset($options['context']) && strpos($options['context'], 'category-') === 0 ? str_replace('category-', '', $options['context']) : false); if ($cat) { if (is_numeric($cat)) { foreach ($this->categories->get_iterated() as $c) { if ($c->id == $cat) { $cat = $c->slug; break; } } } } $data['url'] = $this->url(array('date' => $data['published_on'], 'album' => $options['in_album'], 'tag' => isset($options['tags']) ? $options['tags'] : (isset($options['context']) && strpos($options['context'], 'tag-') === 0 ? str_replace('tag-', '', $options['context']) : false), 'category' => $cat, 'favorite' => isset($options['favorite']) || isset($options['context']) && $options['context'] === 'favorites' ? true : false, 'feature' => isset($options['featured']) || isset($options['context']) && $options['context'] === 'features' ? true : false)); if ($data['url']) { list($data['__koken_url'], $data['url']) = $data['url']; $data['canonical_url'] = $data['url']; } } if (!$options['auth'] && $data['visibility'] === 'unlisted') { unset($data['url']); } if (empty($data['source'])) { $data['source'] = false; } else { $data['source'] = array('title' => $data['source'], 'url' => $data['source_url']); } unset($data['source_url']); $final = Shutter::filter('api.content', array($data, $this, $options)); if (!isset($final['html']) || empty($final['html'])) { $final['html'] = false; } return $final; }
function to_array($options = array()) { $options = array_merge(array('with_covers' => true, 'auth' => false), $options); $koken_url_info = $this->config->item('koken_url_info'); $exclude = array('deleted', 'total_count', 'video_count', 'featured_order', 'tags_old', 'old_slug'); $dates = array('created_on', 'modified_on', 'featured_on', 'published_on'); $strings = array('title', 'summary', 'description'); $bools = array('featured'); list($data, $public_fields) = $this->prepare_for_output($options, $exclude, $bools, $dates, $strings); if (!$options['auth'] && $data['visibility'] < 1) { unset($data['internal_id']); } if (!$data['featured']) { unset($data['featured_on']); } $sort = array(); list($sort['by'], $sort['direction']) = explode(' ', $data['sort']); $data['sort'] = $sort; $data['__koken__'] = 'album'; if (array_key_exists('album_type', $data)) { switch ($data['album_type']) { case 2: $data['album_type'] = 'set'; break; case 1: $data['album_type'] = 'smart'; break; default: $data['album_type'] = 'standard'; } } if ($this->album_type == 2) { $sum = new Album(); $sum->select_sum('total_count')->select_sum('video_count')->where('right_id <', $this->right_id)->where('left_id >', $this->left_id)->where('album_type', 0)->where('visibility', 0)->get(); $data['counts'] = array('total' => (int) $this->total_count, 'videos' => (int) $sum->video_count, 'images' => $sum->total_count - $sum->video_count); } else { $data['counts'] = array('total' => (int) $this->total_count, 'videos' => (int) $this->video_count, 'images' => $this->total_count - $this->video_count); } $data['tags'] = $this->_get_tags_for_output($options); $data['categories'] = array('count' => is_null($this->category_count) ? $this->categories->count() : (int) $this->category_count, 'url' => $koken_url_info->base . 'api.php?/albums/' . $data['id'] . '/categories'); $data['topics'] = array('count' => is_null($this->text_count) ? $this->text->count() : (int) $this->text_count, 'url' => $koken_url_info->base . 'api.php?/albums/' . $data['id'] . '/topics'); if ($options['with_covers']) { $data['covers'] = $existing = array(); $covers = $this->covers; if (isset($options['before'])) { $covers->where('published_on <=', $options['before']); $data['__cover_hint_before'] = $options['before']; } $covers->include_related_count('albums', NULL, array('visibility' => 0)); $covers->include_related_count('categories'); foreach ($covers->order_by("covers_{$this->db_join_prefix}albums_covers.id ASC")->get_iterated() as $f) { if ($f->exists()) { $data['covers'][] = $f->to_array(array('in_album' => $this)); $existing[] = $f->id; } } $covers_count_set = false; if ($this->album_type == 2) { $covers_count_set = $this->covers->count(); } if ($covers_count_set !== false && $covers_count_set < 3) { $a = new Album(); $ids = $a->select('id')->where('right_id <', $this->right_id)->where('left_id >', $this->left_id)->where('visibility', $this->visibility)->get_iterated(); $id_arr = array(); foreach ($ids as $id) { $id_arr[] = $id->id; } if (!empty($id_arr)) { $c = new Content(); $q = "SELECT DISTINCT cover_id FROM {$this->db_join_prefix}albums_covers WHERE album_id IN (" . join(',', $id_arr) . ")"; if (!empty($existing)) { $q .= ' AND cover_id NOT IN(' . join(',', $existing) . ')'; } $covers = $c->query($q . "GROUP BY album_id LIMIT " . (3 - $covers_count_set)); $f_ids = array(); foreach ($covers as $f) { $f_ids[] = $f->cover_id; } if (!empty($f_ids)) { $c->where_in('id', $f_ids)->get_iterated(); foreach ($c as $content) { // TODO: auth needs to be passed in here array_unshift($data['covers'], $content->to_array(array('in_album' => $this))); } } } } // Latest covers first $data['covers'] = array_reverse($data['covers']); } if (isset($options['order_by']) && in_array($options['order_by'], array('created_on', 'modified_on'))) { $data['date'] =& $data[$options['order_by']]; } else { $data['date'] =& $data['published_on']; } if ($data['level'] > 1 && (!array_key_exists('include_parent', $options) || $options['include_parent'])) { $parent = new Album(); $parent->where('left_id <', $data['left_id'])->where('level <', $data['level'])->where('visibility', $this->visibility)->where('deleted', 0)->order_by('left_id DESC')->limit(1)->get(); $data['parent'] = $parent->to_array(); } else { if ($data['level'] == 1) { $data['parent'] = false; } } $cat = isset($options['category']) ? $options['category'] : (isset($options['context']) && strpos($options['context'], 'category-') === 0 ? str_replace('category-', '', $options['context']) : false); if ($cat) { if (is_numeric($cat)) { foreach ($this->categories->get_iterated() as $c) { if ($c->id == $cat) { $cat = $c->slug; break; } } } } $data['url'] = $this->url(array('date' => $data['published_on'], 'tag' => isset($options['tags']) ? $options['tags'] : (isset($options['context']) && strpos($options['context'], 'tag-') === 0 ? str_replace('tag-', '', $options['context']) : false), 'category' => $cat)); if ($data['url']) { list($data['__koken_url'], $data['url']) = $data['url']; $data['canonical_url'] = $data['url']; } if (!$options['auth'] && $data['visibility'] > 0) { unset($data['url']); } if (array_key_exists('visibility', $data)) { switch ($data['visibility']) { case 1: $raw = 'unlisted'; break; case 2: $raw = 'private'; break; default: $raw = 'public'; break; } $data['visibility'] = array('raw' => $raw, 'clean' => ucwords($raw)); $data['public'] = $raw === 'public'; } return Shutter::filter('api.album', array($data, $this, $options)); }
function go($tmpl, $pass = 1) { $raw = Koken::parse($tmpl); // Fix PHP whitespace issues in koken:loops $raw = preg_replace('/\\s+<\\?php\\s+endforeach/', '<?php endforeach', $raw); $raw = preg_replace('/<a(.*)>\\s+<\\?php/', '<a$1><?php', $raw); $raw = preg_replace('/\\?>\\s+<\\/a>/', '?></a>', $raw); if ($pass === 1) { global $final_path; $is_lightbox = 'false'; if ($final_path === 'lightbox.lens') { $is_lightbox = 'true'; } // Filters $raw = str_replace('<head>', "<head><?php Shutter::hook('after_opening_head', array(array('lightbox' => {$is_lightbox}))); ?>", $raw); $raw = str_replace('</head>', "<?php Shutter::hook('before_closing_head', array(array('lightbox' => {$is_lightbox}))); ?></head>", $raw); $raw = str_replace('<body>', "<body><?php Shutter::hook('after_opening_body', array(array('lightbox' => {$is_lightbox}))); ?>", $raw); $raw = str_replace('</body>', "<?php Shutter::hook('before_closing_body', array(array('lightbox' => {$is_lightbox}))); ?></body>", $raw); // die($raw); Koken::$location['page_class'] = Koken::$page_class; $dynamic_array = array(); foreach (Koken::$dynamic_location_parts as $key) { $dynamic_array[$key] = Koken::$location[$key]; } unset($dynamic_array['parameters']['__overrides']); unset($dynamic_array['parameters']['__overrides_display']); $location_json = json_encode($dynamic_array); if (Koken::$pjax) { $js = "<script>\$K.location = \$.extend(\$K.location, {$location_json});\$(window).trigger('k-pjax-end');</script>"; } else { $location = Koken::$location; $site = Koken::$site; $stamp = '?' . KOKEN_VERSION; $generator = 'Koken ' . KOKEN_VERSION; $theme = Koken::$site['theme']['name'] . ' ' . Koken::$site['theme']['version']; $koken_js = Koken::$location['root_folder'] . '/' . (Koken::$draft ? 'preview.php?/' : (Koken::$rewrite ? '' : 'index.php?/')) . 'koken.js' . (Koken::$preview ? '&preview=' . Koken::$preview : ''); if (strpos($koken_js, '.php?') === false) { $koken_js .= '?' . Shutter::get_site_scripts_timestamp(); } if (Koken::$has_video) { $me = "\n\n\t<link href=\"{$location['real_root_folder']}/app/site/themes/common/css/mediaelement/mediaelementplayer.min.css{$stamp}\" rel=\"stylesheet\">\n"; } else { $me = ''; } $js = <<<JS \t<meta name="generator" content="{$generator}" /> \t<meta name="theme" content="{$theme}" />{$me} \t<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> \t<script>window.jQuery || document.write('<script src="{$location['real_root_folder']}/app/site/themes/common/js/jquery.min.js"><\\/script>')</script> \t<script src="{$koken_js}"></script> \t<script>\$K.location = \$.extend(\$K.location, {$location_json});</script> \t<link rel="alternate" type="application/atom+xml" title="{$site['title']}: All uploads" href="{$location['root']}/feed/content/recent.rss" /> \t<link rel="alternate" type="application/atom+xml" title="{$site['title']}: Essays" href="{$location['root']}/feed/essays/recent.rss" /> \t<link rel="alternate" type="application/atom+xml" title="{$site['title']}: Timeline" href="{$location['root']}/feed/timeline/recent.rss" /> JS; } if (Koken::$draft && !Koken::$preview && !Koken::$pjax) { $original_url = Koken::$original_url; $js .= <<<JS <script> if (parent && parent.\$) { \tparent.\$(parent.document).trigger('previewready', '{$original_url}'); \t\$(function() { parent.\$(parent.document).trigger('previewdomready'); }); \t\$(document).on('pjax:end pjax:transition:end', function(event) { \t\tif (event.type === 'pjax:end') { \t\t\tparent.\$(parent.document).trigger('previewready', location.href); \t\t} \t\tparent.\$(parent.document).trigger('previewdomready'); \t}); \t\$(document).on('page:change.console', function() { \t\tparent.\$(parent.document).trigger('previewready', location.href); \t\tparent.\$(parent.document).trigger('previewdomready'); \t}); } if (parent && parent.__koken__) { \t\$(window).on('keydown', function(e) { parent.__koken__.shortcuts(e); }); \t\$(function() { parent.__koken__.panel(); }); } </script> <style type="text/css"> i.k-control-structure { font-style: normal !important; } \tdiv[data-pulse-group] div.cover { \t\twidth: 100%; \t\theight: 100%; \t\tz-index: 1000; \t\tborder: 5px solid transparent; \t\tbox-sizing: border-box; \t\tposition: absolute; \t\tbox-shadow: 0 0 20px rgba(0,0,0,0.6); \t\tdisplay: none; \t\tpointer-events:none; \t\ttop: 0; \t\tleft: 0; \t} \tdiv[data-pulse-group]:hover div.cover, div[data-pulse-group] div.cover.active { \t\tdisplay: block !important; \t} \tdiv[data-pulse-group] div.cover.active { \t\tborder-color: #ff6e00 !important; \t} \tdiv[data-pulse-group] div.cover div { \t\tpointer-events:auto; \t\twidth: 10%; \t\theight: 10%; \t\tmin-width: 28px; \t\tmin-height: 28px; \t\tbackground-size: 28px 28px; \t\tbackground-position:top right; \t\tbackground-repeat:no-repeat; \t\tbackground-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOC4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyOCAyOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMjggMjgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPGcgaWQ9IkxheWVyXzIiPg0KCTxjaXJjbGUgZmlsbD0iIzFFMUUxRSIgY3g9IjE0IiBjeT0iMTQiIHI9IjE0Ii8+DQo8L2c+DQo8ZyBpZD0iTGF5ZXJfMSI+DQoJPGcgaWQ9ImNvZ18xXyI+DQoJCTxwYXRoIGZpbGw9IiNCQkJCQkIiIGQ9Ik0xNCwyMC41Yy0wLjMsMC0wLjYsMC0wLjgtMC4xbC0wLjQtMS43bC0wLjEsMGMtMC40LTAuMS0wLjctMC4zLTEuMS0wLjRsLTAuMSwwTDEwLDE5LjENCgkJCWMtMC41LTAuNC0wLjktMC44LTEuMi0xLjJsMC45LTEuNWwwLTAuMWMtMC4yLTAuMy0wLjMtMC43LTAuNC0xLjFsMC0wLjFsLTEuNy0wLjRjMC0wLjMtMC4xLTAuNi0wLjEtMC44YzAtMC4zLDAtMC42LDAuMS0wLjgNCgkJCWwxLjctMC40bDAtMC4xYzAuMS0wLjQsMC4yLTAuNywwLjQtMS4xbDAtMC4xTDguOSwxMEM5LjIsOS42LDkuNiw5LjIsMTAsOC45bDEuNSwwLjlsMC4xLDBjMC4zLTAuMiwwLjctMC4zLDEuMS0wLjRsMC4xLDANCgkJCWwwLjQtMS43YzAuMywwLDAuNi0wLjEsMC44LTAuMWMwLjMsMCwwLjYsMCwwLjgsMC4xbDAuNCwxLjdsMC4xLDBjMC40LDAuMSwwLjcsMC4yLDEuMSwwLjRsMC4xLDBMMTgsOC45YzAuNSwwLjQsMC45LDAuOCwxLjIsMS4yDQoJCQlsLTAuOSwxLjVsMCwwLjFjMC4yLDAuMywwLjMsMC43LDAuNCwxLjFsMCwwLjFsMS43LDAuNGMwLDAuMywwLjEsMC42LDAuMSwwLjhjMCwwLjMsMCwwLjYtMC4xLDAuOGwtMS43LDAuNGwwLDAuMQ0KCQkJYy0wLjEsMC40LTAuMywwLjctMC40LDEuMWwwLDAuMWwwLjksMS41Yy0wLjQsMC41LTAuOCwwLjktMS4yLDEuMmwtMS41LTAuOWwtMC4xLDBjLTAuMywwLjItMC43LDAuMy0xLjEsMC40bC0wLjEsMGwtMC40LDEuNw0KCQkJQzE0LjUsMjAuNSwxNC4zLDIwLjUsMTQsMjAuNXogTTE0LDExLjZjLTEuMywwLTIuNCwxLjEtMi40LDIuNGMwLDEuMywxLjEsMi40LDIuNCwyLjRjMS4zLDAsMi40LTEuMSwyLjQtMi40DQoJCQlDMTYuNCwxMi43LDE1LjMsMTEuNiwxNCwxMS42eiIvPg0KCTwvZz4NCjwvZz4NCjwvc3ZnPg0K);\t\tposition: absolute; \t\ttop: 4px; \t\tright: 4px; \t\tcursor: pointer; \t\tz-index: 1001; \t} \tdiv[data-pulse-group] div.cover div:hover { \t\tbackground-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOC4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyOCAyOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMjggMjgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPGcgaWQ9IkxheWVyXzIiPg0KCTxjaXJjbGUgZmlsbD0iIzFFMUUxRSIgY3g9IjE0IiBjeT0iMTQiIHI9IjE0Ii8+DQo8L2c+DQo8ZyBpZD0iTGF5ZXJfMSI+DQoJPGcgaWQ9ImNvZ18yXyI+DQoJCTxwYXRoIGZpbGw9IiNFRUVFRUUiIGQ9Ik0xNCwyMC41Yy0wLjMsMC0wLjYsMC0wLjgtMC4xbC0wLjQtMS43bC0wLjEsMGMtMC40LTAuMS0wLjctMC4zLTEuMS0wLjRsLTAuMSwwTDEwLDE5LjENCgkJCWMtMC41LTAuNC0wLjktMC44LTEuMi0xLjJsMC45LTEuNWwwLTAuMWMtMC4yLTAuMy0wLjMtMC43LTAuNC0xLjFsMC0wLjFsLTEuNy0wLjRjMC0wLjMtMC4xLTAuNi0wLjEtMC44YzAtMC4zLDAtMC42LDAuMS0wLjgNCgkJCWwxLjctMC40bDAtMC4xYzAuMS0wLjQsMC4yLTAuNywwLjQtMS4xbDAtMC4xTDguOSwxMEM5LjIsOS42LDkuNiw5LjIsMTAsOC45bDEuNSwwLjlsMC4xLDBjMC4zLTAuMiwwLjctMC4zLDEuMS0wLjRsMC4xLDANCgkJCWwwLjQtMS43YzAuMywwLDAuNi0wLjEsMC44LTAuMWMwLjMsMCwwLjYsMCwwLjgsMC4xbDAuNCwxLjdsMC4xLDBjMC40LDAuMSwwLjcsMC4yLDEuMSwwLjRsMC4xLDBMMTgsOC45YzAuNSwwLjQsMC45LDAuOCwxLjIsMS4yDQoJCQlsLTAuOSwxLjVsMCwwLjFjMC4yLDAuMywwLjMsMC43LDAuNCwxLjFsMCwwLjFsMS43LDAuNGMwLDAuMywwLjEsMC42LDAuMSwwLjhjMCwwLjMsMCwwLjYtMC4xLDAuOGwtMS43LDAuNGwwLDAuMQ0KCQkJYy0wLjEsMC40LTAuMywwLjctMC40LDEuMWwwLDAuMWwwLjksMS41Yy0wLjQsMC41LTAuOCwwLjktMS4yLDEuMmwtMS41LTAuOWwtMC4xLDBjLTAuMywwLjItMC43LDAuMy0xLjEsMC40bC0wLjEsMGwtMC40LDEuNw0KCQkJQzE0LjUsMjAuNSwxNC4zLDIwLjUsMTQsMjAuNXogTTE0LDExLjZjLTEuMywwLTIuNCwxLjEtMi40LDIuNGMwLDEuMywxLjEsMi40LDIuNCwyLjRjMS4zLDAsMi40LTEuMSwyLjQtMi40DQoJCQlDMTYuNCwxMi43LDE1LjMsMTEuNiwxNCwxMS42eiIvPg0KCTwvZz4NCjwvZz4NCjwvc3ZnPg0K); \t} </style> JS; } } $contents = Koken::render($raw); if ($pass === 1) { // Rerun parse to catch shortcode renders while (strpos($contents, '<koken:') !== false && $pass < 3) { $pass++; $contents = go($contents, $pass); } } else { return $contents; } $contents .= Koken::cleanup(); if (strpos($contents, 'settings.css.lens"') === false && !empty(Koken::$site['custom_css']) || Koken::$draft) { $js .= '<style id="koken_custom_css">' . Koken::$site['custom_css'] . '</style>'; } preg_match_all('/<\\!\\-\\- KOKEN HEAD BEGIN \\-\\->(.*)<!\\-\\- KOKEN HEAD END \\-\\->/msU', $contents, $headers); $contents = preg_replace('/<\\!\\-\\- KOKEN HEAD BEGIN \\-\\->(.*)<!\\-\\- KOKEN HEAD END \\-\\->/msU', '', $contents); $header_str = ''; foreach ($headers[1] as $header) { $header_str .= "\t" . $header . "\n"; } if (strpos($header_str, '<title>') !== false) { $contents = preg_replace('/<title>.*<\\/title>/msU', '', $contents); $header_str = preg_replace('/<koken_title>.*<\\/koken_title>/', '', $header_str); } else { if (strpos($header_str, '<koken_title>') !== false && strpos($contents, '<koken_title') !== false) { $contents = preg_replace('/<title>.*<\\/title>/msU', '', $contents); $header_str = str_replace('koken_title', 'title', $header_str); } else { if (strpos($contents, '<koken_title') !== false) { $contents = str_replace('koken_title', 'title', $contents); } } } if (Koken::$pjax && strpos($header_str, '<title>')) { preg_match('~<title>.*</title>~', $header_str, $title_match); $contents .= $title_match[0]; } $contents = preg_replace('/<koken_title>.*<\\/koken_title>/msU', '', $contents); $header_str .= "\n\t<!--[if IE]>\n\t<script src=\"" . Koken::$location['real_root_folder'] . "/app/site/themes/common/js/html5shiv.js\"></script>\n\t<![endif]-->\n"; if (strpos($contents, '<head>')) { preg_match('/<head>(.*)?<\\/head>/msU', $contents, $header); if (count($header)) { $head = isset($header[1]) ? $header[1] : ''; preg_match_all('/<script.*<\\/script>/msU', $head, $head_js); $head = preg_replace('/\\s*<script.*<\\/script>\\s*/msU', '', $head) . "\n{$header_str}\n{$js}\n" . join("\n", $head_js[0]); $contents = preg_replace('/<head>(.*)?<\\/head>/msU', "<head>\n" . str_replace('$', '\\$', $head) . "\n</head>", $contents); } } else { if (strpos($contents, '</body>')) { $contents = str_replace('</body>', "{$js}\n{$header_str}\n</body>", $contents); } else { if (Koken::$pjax) { $contents .= $js; } } } $final_page_classes = trim(join(' ', array_merge(explode(' ', Koken::$page_class), Shutter::get_body_classes()))); if (preg_match_all('/<body(?:[^>]+)?>/', $contents, $match) && !empty($final_page_classes)) { foreach ($match[0] as $body) { if (strpos($body, 'class="') !== false) { $new_body = preg_replace('/class="([^"]+)"/', "class=\"\$1 " . $final_page_classes . "\"", $body); } else { $new_body = str_replace('>', ' class="' . $final_page_classes . '">', $body); } $contents = str_replace($body, $new_body, $contents); } } if (preg_match_all('/<html(?:[^>]+)?>/', $contents, $match) && !empty($final_page_classes)) { foreach ($match[0] as $html) { if (strpos($html, 'class="') !== false) { $new_html = preg_replace('/class="([^"]+)"/', "class=\"\$1 " . $final_page_classes . "\"", $html); } else { $new_html = str_replace('>', ' class="' . $final_page_classes . '">', $html); } $contents = str_replace($html, $new_html, $contents); } } preg_match('/<!-- KOKEN META DESCRIPTION BEGIN -->(.*)<!-- KOKEN META DESCRIPTION END -->/msU', $contents, $meta_description); preg_match('/<!-- KOKEN META KEYWORDS BEGIN -->(.*)<!-- KOKEN META KEYWORDS END -->/msU', $contents, $meta_keywords); $contents = preg_replace('/<!-- KOKEN META (DESCRIPTION|KEYWORDS) BEGIN -->.*<!-- KOKEN META (DESCRIPTION|KEYWORDS) END -->/msU', '', $contents); $contents = preg_replace('/\\t+/', "\t", $contents); $contents = preg_replace('/\\n\\t*\\n/', "\n", $contents); $contents = preg_replace('/\\n{2,}/', "\n\n", $contents); $contents = preg_replace('/<title>\\s*/ms', '<title>', $contents); if (count($meta_description) && strlen($meta_description[1]) > 0) { $contents = preg_replace('/<meta name="description" content=".*" \\/>/', '<meta name="description" content="' . str_replace('$', '\\$', $meta_description[1]) . '" />', $contents); } if (count($meta_keywords) && strlen($meta_keywords[1]) > 0) { $contents = preg_replace('/<meta name="keywords" content="(.*)" \\/>/', "<meta name=\"keywords\" content=\"\$1, {$meta_keywords[1]}\" />", $contents); } if (Koken::$rss) { $contents = '<?xml version="1.0" encoding="utf-8"?>' . "\n{$contents}"; } else { $contents = Shutter::filter('site.output', $contents); } Koken::cache($contents); if (Koken::$rss) { header('Content-type: text/xml; charset=UTF-8'); } else { header('Content-type: text/html; charset=UTF-8'); } die($contents); }