/** * With each call, clean up any really old caches that are no longer needed * * @param bool $force Force a collection even if it's not time * @return void */ public function collectGarbage($force = false) { // only garbage collect once per week $last = $this->cache->get('last_garbage_collection', null); // is it time for garbage collection? if (!$force && $last && $last >= Date::resolve('-1 week')) { // not time yet, we're good return; } // log that we're coming through $this->log->debug('Collecting garbage.'); // set last time $this->cache->put('last_garbage_collection', time()); // clean up troves $threshold = $this->fetchConfig('garbage_threshold', null, false, false, false); if ($threshold) { $this->cache->purgeFromBefore('-' . $threshold); } // clean up keys $keys = $this->cache->listAll('keys'); foreach ($keys as $key) { $hashes = $this->cache->getYAML('keys/' . $key); foreach ($hashes as $hash_key => $hash) { if (!$this->cache->exists('troves/' . $hash)) { unset($hashes[$hash_key]); } } if (!count($hashes)) { $this->cache->delete('keys/' . $key); } else { $this->cache->putYAML('keys/' . $key, $hashes); } } }
/** * Store a revision for a given $file * * @param string $file The file to save a revision for * @param string $content The content to store as data for this revision * @param string $message The commit message * @param null $timestamp An optional timestamp for when this revision occurred * @param bool $is_new Whether the file is new or not */ public function saveRevision($file, $content, $message, $timestamp = null, $is_new = false) { // store in folder of hashed file name $hash = Helper::makeHash($file); // determine revision number $nth_revision = count($this->storage->listAll($hash)) + 1; $revision_data = array('file' => $file, 'revision' => $nth_revision, 'message' => $message, 'timestamp' => $timestamp ? Date::resolve($timestamp) : time(), 'author_uid' => Auth::getCurrentMember()->getUID(), 'data' => $content); $location = $hash . '/' . str_pad($nth_revision, 4, '0', STR_PAD_LEFT); $this->storage->putYAML($location, $revision_data); }
public function index() { // if disabled, do nothing if (!$this->core->isEnabled()) { return Parse::contextualTemplate($this->content, array(), $this->context); } // grab and prepare parameters $key = $this->fetchParam('key', null, null, false, false); $age = time() - Date::resolve('-' . $this->fetch(array('for', 'default_cache_length'), '12 hours', null, false, false)); $hash = $this->fetch(array('scope', 'default_scope'), 'site') === 'page' ? Helper::makeHash(URL::getCurrent(), $this->content) : Helper::makeHash($this->content); $path = 'troves/' . $hash; // deal with keys if ($key) { // split on pipes $keys = explode('|', $key); // loop through keys, storing this hash to this key foreach ($keys as $key) { $key_path = 'keys/' . trim($key); // get existing keys $hashes = $this->cache->getYAML($key_path, array()); $new_hashes = array(); // check that the hashes are all still valid foreach ($hashes as $new_hash) { if ($this->cache->exists('troves/' . $new_hash)) { $new_hashes[] = $new_hash; } } // add this one $new_hashes[] = $hash; // append new ones $this->cache->putYAML($key_path, array_unique($new_hashes)); } } // check for pre-existing cache if (!$this->cache->exists($path) || $this->cache->getAge($path) > $age) { // cache doesn't exist or has expired, so parse this contextually... $html = Parse::contextualTemplate($this->content, array(), $this->context); // ...and store the HTML $this->cache->put($path, $html); } // garbage collection $this->core->collectGarbage(); // return what we know return $this->cache->get($path); }
public function index($value, $parameters = array()) { $use_smart_relative = !empty($parameters[0]) && $parameters[0] == 'smart'; if ($use_smart_relative) { // find today, yesterday, and beyond $today = Date::resolve('today midnight'); $yesterday = Date::resolve('yesterday midnight'); $tomorrow = Date::resolve('tomorrow midnight'); $two_days = Date::resolve('+2 days midnight'); $hour_ago = Date::resolve('-1 hour'); $in_an_hour = Date::resolve('+1 hour'); $now = time(); // normalize date $timestamp = Date::resolve($value); // now check if ($timestamp > $two_days || $timestamp < $yesterday) { // this is outside of an immediate window, just return date return Date::format(Config::getDateFormat(), $timestamp) . ' ' . __('at') . ' ' . Date::format(Config::getTimeFormat(), $timestamp); } elseif ($timestamp > $hour_ago && $timestamp < $in_an_hour) { // this is very near by, return relative date return Carbon::createFromTimestamp($timestamp)->diffForHumans(); } elseif ($timestamp < $now) { if ($timestamp > $today) { // this is today return __('today') . ' ' . __('at') . ' ' . Date::format(Config::getTimeFormat(), $timestamp); } else { // this is yesterday return __('yesterday') . ' ' . __('at') . ' ' . Date::format(Config::getTimeFormat(), $timestamp); } } else { // this is tomorrow return __('tomorrow') . ' ' . __('at') . ' ' . Date::format(Config::getTimeFormat(), $timestamp); } } else { if (is_numeric($value)) { // this is a timestamp return Carbon::createFromTimestamp($value)->diffForHumans(); } // this is a string return Carbon::parse($value)->diffForHumans(); } }
/** * Filters the current content set down based on the filters given * * @param array $filters Filters to use to narrow down content * @return void * @throws Exception */ public function filter($filters) { $hash = Debug::markStart('content', 'filtering'); $filters = Helper::ensureArray($filters); // nothing to filter, abort if (!$this->count()) { return; } $since_date = null; $until_date = null; $remove_hidden = null; $remove_drafts = null; $keep_type = "all"; $folders = null; $conditions = null; $located = false; $where = null; // standardize filters // ------------------- $given_filters = $filters; $filters = array('show_hidden' => isset($given_filters['show_hidden']) ? $given_filters['show_hidden'] : null, 'show_drafts' => isset($given_filters['show_drafts']) ? $given_filters['show_drafts'] : null, 'since' => isset($given_filters['since']) ? $given_filters['since'] : null, 'until' => isset($given_filters['until']) ? $given_filters['until'] : null, 'show_past' => isset($given_filters['show_past']) ? $given_filters['show_past'] : null, 'show_future' => isset($given_filters['show_future']) ? $given_filters['show_future'] : null, 'type' => isset($given_filters['type']) ? strtolower($given_filters['type']) : null, 'folders' => isset($given_filters['folders']) ? $given_filters['folders'] : null, 'conditions' => isset($given_filters['conditions']) ? $given_filters['conditions'] : null, 'located' => isset($given_filters['located']) ? $given_filters['located'] : null, 'where' => isset($given_filters['where']) ? $given_filters['where'] : null); // determine filters // ----------------- if (!is_null($filters['show_hidden'])) { $remove_hidden = !(bool) $filters['show_hidden']; } if (!is_null($filters['show_drafts'])) { $remove_drafts = !(bool) $filters['show_drafts']; } if ($filters['since']) { $since_date = Date::resolve($filters['since']); } if ($filters['show_past'] === false && (!$since_date || $since_date < time())) { $since_date = Config::getEntryTimestamps() ? time() : Date::resolve("today midnight"); } if ($filters['until']) { $until_date = Date::resolve($filters['until']); } if ($filters['show_future'] === false && (!$until_date || $until_date > time())) { $until_date = Config::getEntryTimestamps() ? time() : Date::resolve("tomorrow midnight") - 1; } if ($filters['type'] === "entries" || $filters['type'] === "pages") { $keep_type = $filters['type']; } if ($filters['folders']) { $folders = Parse::pipeList($filters['folders']); } if ($filters['conditions']) { $conditions = Parse::conditions($filters['conditions']); } if ($filters['located']) { $located = true; } if ($filters['where']) { $where = $filters['where']; } // before we run filters, we need to look through conditions if they // were set to see if we're going to need content or content_raw // ----------- if ($conditions) { // check for conditions involving content $uses_content = false; foreach ($conditions as $field => $instructions) { if (strtolower($field) === 'content') { $uses_content = true; break; } } // this uses content, which means we need to load it for all content if ($uses_content) { $this->prepare(true, false); $this->content_parsed = false; } } // run filters // ----------- foreach ($this->content as $key => $data) { // entry or page removal if ($keep_type === "pages" && !$data['_is_page']) { unset($this->content[$key]); continue; } elseif ($keep_type === "entries" && !$data['_is_entry']) { unset($this->content[$key]); continue; } // check for non-public content if ($remove_drafts && $data['_is_draft']) { unset($this->content[$key]); continue; } if ($remove_hidden && $data['_is_hidden']) { unset($this->content[$key]); continue; } // folder if ($folders) { $keep = false; foreach ($folders as $folder) { if ($folder === "*" || $folder === "/*") { // include all $keep = true; break; } elseif (substr($folder, -1) === "*") { // wildcard check if (strpos($data['_folder'], substr($folder, 0, -1)) === 0) { $keep = true; break; } } else { // plain check if ($folder == $data['_folder']) { $keep = true; break; } } } if (!$keep) { unset($this->content[$key]); continue; } } // since & show past if ($since_date && $data['datestamp'] && $data['datestamp'] < $since_date) { unset($this->content[$key]); continue; } // until & show future if ($until_date && $data['datestamp'] && $data['datestamp'] > $until_date) { unset($this->content[$key]); continue; } // where if ($where && !(bool) Parse::template("{{ if " . $where . " }}1{{ else }}0{{ endif }}", $data)) { unset($this->content[$key]); continue; } // conditions if ($conditions) { $case_sensitive_taxonomies = Config::getTaxonomyCaseSensitive(); foreach ($conditions as $field => $instructions) { $optional = substr($field, -1, 1) == '?'; $field = $optional ? trim(substr($field, 0, -1)) : $field; try { // are we looking for existence? if ($instructions['kind'] === "existence") { if ($instructions['type'] === "has") { if (!isset($data[$field]) || !$data[$field]) { throw new Exception("Does not fit condition"); } } elseif ($instructions['type'] === "lacks") { if (isset($data[$field]) && $data[$field]) { throw new Exception("Does not fit condition"); } } else { throw new Exception("Unknown existence type"); } // are we looking for a comparison? } elseif ($instructions['kind'] === "comparison") { $is_taxonomy = Taxonomy::isTaxonomy($field); $case_sensitive = $is_taxonomy && $case_sensitive_taxonomies; if (!isset($data[$field])) { $field = false; $values = null; } else { if ($case_sensitive) { $field = $data[$field]; $values = $instructions['value']; } else { $field = is_array($data[$field]) ? array_map('strtolower', $data[$field]) : strtolower($data[$field]); $values = is_array($instructions['value']) ? array_map('strtolower', $instructions['value']) : strtolower($instructions['value']); } } // convert boolean-like statements to boolean values if (is_array($values)) { foreach ($values as $item => $value) { if ($value == "true" || $value == "yes") { $values[$item] = true; } elseif ($value == "false" || $value == "no") { $values[$item] = false; } } } else { if ($values == "true" || $values == "yes") { $values = true; } elseif ($values == "false" || $values == "no") { $values = false; } } // convert date-like statements to timestamps for qualitative comparisons (not equals) if (in_array($instructions['type'], array('greater than or equal to', 'greater than', 'less than or equal to', 'less than'))) { if (!is_array($field) && !is_numeric($field) && Date::resolve($field) !== false) { $field = Date::resolve($field); } if (!is_array($values) && !is_numeric($values) && Date::resolve($values) !== false) { $values = Date::resolve($values); } } // equal comparisons if ($instructions['type'] == "equal") { // if this isn't set, it's not equal if (!$field) { throw new Exception("Field not set", 1); } if (!is_array($field)) { if ($field != $values) { throw new Exception("Does not fit condition", 0); } } elseif (!in_array($values, $field)) { throw new Exception("Does not fit condition", 0); } // greater than or equal to comparisons } elseif ($instructions['type'] == "greater than or equal to") { // if this isn't set, it's not greater than or equal to if (!$field) { throw new Exception("Field not set", 1); } if (is_array($field) || is_array($values)) { throw new Exception("Does not fit condition", 0); } if (!is_numeric($field) && Date::resolve($field) !== false) { $field = Date::resolve($field); } if (!is_numeric($values) && Date::resolve($values) !== false) { $values = Date::resolve($values); } if (!is_numeric($field) || !is_numeric($values) || $this->toNumber($field) < $this->toNumber($values)) { throw new Exception("Does not fit condition", 0); } // greater than to comparisons } elseif ($instructions['type'] == "greater than") { // if this isn't set, it's not less than if (!$field) { throw new Exception("Field not set", 1); } if (is_array($field) || is_array($values)) { throw new Exception("Does not fit condition", 0); } if (!is_numeric($field) && Date::resolve($field) !== false) { $field = Date::resolve($field); } if (!is_numeric($values) && Date::resolve($values) !== false) { $values = Date::resolve($values); } if (!is_numeric($field) || !is_numeric($values) || $this->toNumber($field) <= $this->toNumber($values)) { throw new Exception("Does not fit condition", 0); } // less than or equal to comparisons } elseif ($instructions['type'] == "less than or equal to") { // if this isn't set, it's not less than or equal to if (!$field) { throw new Exception("Field not set", 1); } if (is_array($field) || is_array($values)) { throw new Exception("Does not fit condition", 0); } if (!is_numeric($field) && Date::resolve($field) !== false) { $field = Date::resolve($field); } if (!is_numeric($values) && Date::resolve($values) !== false) { $values = Date::resolve($values); } if (!is_numeric($field) || !is_numeric($values) || $this->toNumber($field) > $this->toNumber($values)) { throw new Exception("Does not fit condition", 0); } // less than to comparisons } elseif ($instructions['type'] == "less than") { // if this isn't set, it's not less than if (!$field) { throw new Exception("Field not set", 1); } if (is_array($field) || is_array($values)) { throw new Exception("Does not fit condition", 0); } if (!is_numeric($field) && Date::resolve($field) !== false) { $field = Date::resolve($field); } if (!is_numeric($values) && Date::resolve($values) !== false) { $values = Date::resolve($values); } if (!is_numeric($field) || !is_numeric($values) || $this->toNumber($field) >= $this->toNumber($values)) { throw new Exception("Does not fit condition", 0); } // not-equal comparisons } elseif ($instructions['type'] == "not equal") { // if this isn't set, it's not equal, continue if (!$field) { continue; } if (!is_array($field)) { if ($field == $values) { throw new Exception("Does not fit condition", 0); } } elseif (in_array($values, $field)) { throw new Exception("Does not fit condition", 0); } // contains array comparisons } elseif ($instructions['type'] == "in") { if (!$field) { throw new Exception("Field not set", 1); } if (!count(array_intersect(Helper::ensureArray($field), $values))) { throw new Exception("Does not fit condition", 0); } // doesn't contain array comparisons } elseif ($instructions['type'] == "not in") { if (!$field) { throw new Exception("Field not set", 1); } if (count(array_intersect(Helper::ensureArray($field), $values))) { throw new Exception("Does not fit condition", 0); } // contains contains-text comparisons } elseif ($instructions['type'] == 'contains text') { if (!$field) { throw new Exception("Field not set", 1); } $field = Helper::ensureArray($field); $found = false; foreach ($field as $option) { // do we need to loop through values? if (is_array($values)) { // we do foreach ($values as $value) { if (strpos($option, strtolower($value)) !== false) { $found = true; break; } } if ($found) { break; } } else { // we don't if (strpos($option, strtolower($values)) !== false) { $found = true; break; } } } if (!$found) { throw new Exception("Does not fit condition", 0); } } // we don't know what this is } else { throw new Exception("Unknown kind of condition", -1); } } catch (Exception $e) { if ($optional && $e->getCode() === 1) { // we were only making the comparison if the field exists, // otherwise, this is ok continue; } // this was not an optional field, and something went wrong unset($this->content[$key]); continue; } } } // located if ($located && !isset($data['coordinates'])) { unset($this->content[$key]); continue; } } Debug::markEnd($hash); }
public function index($value, $parameters = array()) { $time = Date::resolve($value); return Carbon::createFromTimestamp($time)->isTomorrow(); }
/** * If the given redirect conditions are met, redirects the site to the given URL * * @param array $config Configuration of the site * @return bool */ public static function processVanityURLs($config) { // if no array or an empty one, we're done here if (!isset($config['_vanity_urls']) || empty($config['_vanity_urls'])) { return false; } // current path // note: not using API because it's not ready yet $uri = $_SERVER['REQUEST_URI']; $query = $_SERVER['QUERY_STRING']; $current = $query ? str_replace("?" . $query, "", $uri) : $uri; // loop through configured vanity URLs foreach ($config['_vanity_urls'] as $url => $redirect) { $redirect_forward = false; $redirect_url = null; // if this wasn't a match, move on if (Path::tidy("/" . $url) != $current) { continue; } // we have a match // now check to see how this redirect was set up if (is_array($redirect)) { // this was an array if (!isset($redirect['url'])) { Log::warn("Vanity URL `" . $url . "` matched, but no redirect URL was configred.", "core", "vanity"); continue; } $redirect_start = Helper::choose($redirect, 'start', null); $redirect_until = Helper::choose($redirect, 'until', null); $redirect_forward = Helper::choose($redirect, 'forward_query_string', false); $redirect_url = Helper::choose($redirect, 'url', $redirect); $redirect_type = (int) Helper::choose($redirect, 'type', 302); // if start date is set and it's before that date if ($redirect_start && time() < Date::resolve($redirect_start)) { Log::info("Vanity URL `" . $url . "` matched, but scheduling does not allowed redirecting yet.", "core", "vanity"); continue; } // if until date is set and it's after after that date if ($redirect_until && time() > Date::resolve($redirect_until)) { Log::info("Vanity URL `" . $url . "` matched, but scheduling for this redirect has expired.", "core", "vanity"); continue; } } else { // this was a string $redirect_url = $redirect; $redirect_type = 302; } // optionally forward any query string variables if ($query && $redirect_forward) { $redirect_url .= strstr($redirect_url, "?") !== false ? "&" : "?"; $redirect_url .= $query; } // ensure a complete URL if (!substr($redirect_url, 0, 4) == "http") { $redirect_url = Path::tidy(Config::getSiteRoot() . "/" . $redirect_url); } // ensure a valid redirect type if (!in_array($redirect_type, array(301, 302))) { $redirect_type = 302; } // redirect header("Location: " . $redirect_url, true, $redirect_type); exit; } }
/** * Takes a dot-notated key and finds the value for it in the given * array or object. * * @param string $key Dot-notated key to find * @param array|object $data Array or object to search * @param mixed $default Default value to use if not found * @return mixed */ protected function getVariable($key, $data, $default = null) { $modifiers = null; if (strpos($key, "|") === false) { } else { $parts = explode("|", $key); $key = $parts[0]; $modifiers = array_splice($parts, 1); } if (strpos($key, $this->scopeGlue) === false) { $parts = explode('.', $key); } else { $parts = explode($this->scopeGlue, $key); } foreach ($parts as $key_part) { if (is_array($data)) { if (!array_key_exists($key_part, $data)) { return $default; } $data = $data[$key_part]; } elseif (is_object($data)) { if (!isset($data->{$key_part})) { return $default; } $data = $data->{$key_part}; } else { return $default; } } if ($modifiers) { foreach ($modifiers as $mod) { if (strpos($mod, ":") === false) { $modifier_name = $mod; $modifier_params = array(); } else { $parts = explode(":", $mod); $modifier_name = $parts[0]; $modifier_params = array_splice($parts, 1); } if ($modifier_name == 'trim') { $data = trim($data); } elseif ($modifier_name == 'img') { $data = '<img src="' . \Path::toAsset($data) . '" />'; } elseif ($modifier_name == 'link') { if (filter_var($data, FILTER_VALIDATE_EMAIL)) { // email address $data = '<a href="mailto:' . $data . '" />' . $data . '</a>'; } else { $data = '<a href="' . $data . '" />' . $data . '</a>'; } } elseif ($modifier_name == 'upper') { $data = strtoupper($data); } else { if ($modifier_name == 'lower') { $data = strtolower($data); } else { if ($modifier_name == 'slugify') { $data = \Slug::make($data); } else { if ($modifier_name == 'deslugify') { $data = trim(preg_replace('~[-_]~', ' ', $data), " "); } else { if ($modifier_name == 'title') { $data = ucwords($data); } else { if ($modifier_name == 'format') { $data = date($modifier_params[0], $data); } else { if ($modifier_name == 'format_number') { $decimals = isset($modifier_params[0]) ? $modifier_params[0] : 0; $data = number_format($data, $decimals); } else { if ($modifier_name == 'in_future') { $data = \Date::resolve($data) > time() ? "true" : ""; } else { if ($modifier_name == 'in_past') { $data = \Date::resolve($data) < time() ? "true" : ""; } else { if ($modifier_name == 'markdown') { $data = Markdown($data); } else { if ($modifier_name == 'textile') { $textile = new \Textile(); $data = $textile->TextileThis($data); } else { if ($modifier_name == 'length') { if (is_array($data)) { $data = count($data); } else { $data = strlen($data); } } else { if ($modifier_name == 'scramble') { $data = str_shuffle($data); } else { if ($modifier_name == 'word_count') { $data = str_word_count($data); } else { if ($modifier_name == 'obfuscate') { $data = \HTML::obfuscateEmail($data); } else { if ($modifier_name == 'rot13') { $data = str_rot13($data); } else { if ($modifier_name == 'urlencode') { $data = urlencode($data); } else { if ($modifier_name == 'urldecode') { $data = urldecode($data); } else { if ($modifier_name == 'striptags') { $data = strip_tags($data); } else { if ($modifier_name == '%') { $divisor = isset($modifier_params[0]) ? $modifier_params[0] : 1; $data = $data % $divisor; } else { if ($modifier_name == 'empty') { $data = \Helper::isEmptyArray($data) ? "true" : ""; } else { if ($modifier_name == 'not_empty') { $data = !\Helper::isEmptyArray($data) ? "true" : ""; } else { if ($modifier_name == 'numeric') { $data = is_numeric($data) ? "true" : ""; } else { if ($modifier_name == 'repeat') { $multiplier = isset($modifier_params[0]) ? $modifier_params[0] : 1; $data = str_repeat($data, $multiplier); } else { if ($modifier_name == 'reverse') { $data = strrev($data); } else { if ($modifier_name == 'round') { $precision = isset($modifier_params[0]) ? (int) $modifier_params[0] : 0; $data = round((double) $data, $precision); } else { if ($modifier_name == 'floor') { $data = floor((double) $data); } else { if ($modifier_name == 'ceil') { $data = ceil((double) $data); } else { if ($modifier_name == '+') { if (isset($modifier_params[0])) { $number = $modifier_params[0]; $data = $data + $number; } } else { if ($modifier_name == '-') { if (isset($modifier_params[0])) { $number = $modifier_params[0]; $data = $data - $number; } } else { if ($modifier_name == '*') { if (isset($modifier_params[0])) { $number = $modifier_params[0]; $data = $data * $number; } } else { if ($modifier_name == '/') { if (isset($modifier_params[0])) { $number = $modifier_params[0]; $data = $data / $number; } } else { if ($modifier_name == '^') { if (isset($modifier_params[0])) { $exp = $modifier_params[0]; $data = pow($data, $exp); } } else { if ($modifier_name == 'sqrt') { $data = sqrt($data); } else { if ($modifier_name == 'abs') { $data = abs($data); } else { if ($modifier_name == 'log') { $base = isset($modifier_params[0]) ? (int) $modifier_params[0] : M_E; $data = log($data, $base); } else { if ($modifier_name == 'log10') { $data = log10($data); } else { if ($modifier_name == 'deg2rad') { $data = deg2rad($data); } else { if ($modifier_name == 'rad2deg') { $data = rad2deg($data); } else { if ($modifier_name == 'sin') { $data = sin($data); } else { if ($modifier_name == 'asin') { $data = asin($data); } else { if ($modifier_name == 'cos') { $data = cos($data); } else { if ($modifier_name == 'acos') { $data = acos($data); } else { if ($modifier_name == 'tan') { $data = tan($data); } else { if ($modifier_name == 'atan') { $data = atan($data); } else { if ($modifier_name == 'decbin') { $data = decbin($data); } else { if ($modifier_name == 'dechex') { $data = dechex($data); } else { if ($modifier_name == 'decoct') { $data = decoct($data); } else { if ($modifier_name == 'hexdec') { $data = hexdec($data); } else { if ($modifier_name == 'octdec') { $data = octdec($data); } else { if ($modifier_name == 'bindec') { $data = bindec((string) $data); } else { if ($modifier_name == 'distance_in_mi_from') { if (!isset($modifier_params[0])) { return 'Unknown'; } if (!preg_match(\Pattern::COORDINATES, $data, $point_1_matches)) { return 'Unknown'; } if (!preg_match(\Pattern::COORDINATES, $modifier_params[0], $point_2_matches)) { return 'Unknown'; } $point_1 = array($point_1_matches[1], $point_1_matches[2]); $point_2 = array($point_2_matches[1], $point_2_matches[2]); $distance = \Math::getDistanceInKilometers($point_1, $point_2); $data = \Math::convertKilometersToMiles($distance); } else { if ($modifier_name == 'distance_in_km_from') { if (!isset($modifier_params[0])) { return 'Unknown'; } if (!preg_match(\Pattern::COORDINATES, $data, $point_1_matches)) { return 'Unknown'; } if (!preg_match(\Pattern::COORDINATES, $modifier_params[0], $point_2_matches)) { return 'Unknown'; } $point_1 = array($point_1_matches[1], $point_1_matches[2]); $point_2 = array($point_2_matches[1], $point_2_matches[2]); $data = \Math::getDistanceInKilometers($point_1, $point_2); } else { if ($modifier_name == 'smartypants') { $data = SmartyPants($data, 2); } else { if ($modifier_name == 'widont') { // thanks to Shaun Inman for inspriation here // http://www.shauninman.com/archive/2008/08/25/widont_2_1_1 // if there are content tags if (preg_match("/<\\/(?:p|li|h1|h2|h3|h4|h5|h6|figcaption)>/ism", $data)) { $data = preg_replace("/(?<!<[p|li|h1|h2|h3|h4|h5|h6|div|figcaption])([^\\s])[ \t]+([^\\s]+(?:<\\/(?:p|li|h1|h2|h3|h4|h5|h6|div|figcaption)>))\$/im", "\$1 \$2", rtrim($data)); // otherwise } else { $data = preg_replace("/([^\\s])\\s+([^\\s]+)\\s*\$/im", "\$1 \$2", rtrim($data)); } } elseif ($modifier_name == 'backspace') { if (!is_array($data) && isset($modifier_params[0]) && $modifier_params[0] > 0) { $data = substr($data, 0, -$modifier_params[0]); } } else { if ($modifier_name == 'truncate') { $length = 30; $hellip = "…"; if (sizeof($modifier_params) > 0) { $length = (int) $modifier_params[0]; } else { if (isset($modifier_params[1])) { $hellip = (int) $modifier_params[1]; } } if (strlen($data) > $length) { $data = substr($data, 0, $length) . $hellip; } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } return $data; }
public function index($value, $parameters = array()) { return Date::resolve($value) < time() ? "true" : ""; }
/** * Filters the current content set down based on the filters given * * @param array $filters Filters to use to narrow down content * @return void * @throws Exception */ public function filter($filters) { $filters = Helper::ensureArray($filters); // nothing to filter, abort if (!$this->count()) { return; } $since_date = null; $until_date = null; $remove_hidden = null; $keep_type = "all"; $folders = null; $conditions = null; $located = false; // standardize filters // ------------------- $given_filters = $filters; $filters = array('show_all' => isset($given_filters['show_all']) ? $given_filters['show_all'] : null, 'since' => isset($given_filters['since']) ? $given_filters['since'] : null, 'until' => isset($given_filters['until']) ? $given_filters['until'] : null, 'show_past' => isset($given_filters['show_past']) ? $given_filters['show_past'] : null, 'show_future' => isset($given_filters['show_future']) ? $given_filters['show_future'] : null, 'type' => isset($given_filters['type']) ? strtolower($given_filters['type']) : null, 'folders' => isset($given_filters['folders']) ? $given_filters['folders'] : null, 'conditions' => isset($given_filters['conditions']) ? $given_filters['conditions'] : null, 'located' => isset($given_filters['located']) ? $given_filters['located'] : null); // determine filters // ----------------- if ($filters['show_all'] === false) { $remove_hidden = true; } if ($filters['since']) { $since_date = Date::resolve($filters['since']); } if ($filters['show_past'] === false && (!$since_date || $since_date < time())) { $since_date = time(); } if ($filters['until']) { $until_date = Date::resolve($filters['until']); } if ($filters['show_future'] === false && (!$until_date || $until_date > time())) { $until_date = time(); } if ($filters['type'] === "entries" || $filters['type'] === "pages") { $keep_type = $filters['type']; } if ($filters['folders']) { $folders = Helper::parseForFolders($filters['folders']); } if ($filters['conditions']) { $conditions = Parse::conditions($filters['conditions']); } if ($filters['located']) { $located = true; } // run filters // ----------- foreach ($this->content as $key => $data) { // entry or page removal if ($keep_type === "pages" && !$data['_is_page']) { unset($this->content[$key]); continue; } elseif ($keep_type === "entries" && !$data['_is_entry']) { unset($this->content[$key]); continue; } // check if this is hidden content if ($remove_hidden && strpos($data['_local_path'], "/_") !== false) { unset($this->content[$key]); continue; } // folder if ($folders) { $keep = false; foreach ($folders as $folder) { if ($folder === "*" || $folder === "/*") { // include all $keep = true; break; } elseif (substr($folder, -1) === "*") { // wildcard check if (strpos($data['_folder'], substr($folder, 0, -1)) === 0) { $keep = true; break; } } else { // plain check if ($folder == $data['_folder']) { $keep = true; break; } } } if (!$keep) { unset($this->content[$key]); continue; } } // since & show past if ($since_date && $data['datestamp'] && $data['datestamp'] < $since_date) { unset($this->content[$key]); continue; } // until & show future if ($until_date && $data['datestamp'] && $data['datestamp'] > $until_date) { unset($this->content[$key]); continue; } // conditions if ($conditions) { $case_sensitive_taxonomies = Config::getTaxonomyCaseSensitive(); foreach ($conditions as $field => $instructions) { try { // are we looking for existence? if ($instructions['kind'] === "existence") { if ($instructions['type'] === "has") { if (!isset($data[$field]) || !$data[$field]) { throw new Exception("Does not fit condition"); } } elseif ($instructions['type'] === "lacks") { if (isset($data[$field]) && $data[$field]) { throw new Exception("Does not fit condition"); } } else { throw new Exception("Unknown existence type"); } // are we looking for a comparison? } elseif ($instructions['kind'] === "comparison") { $is_taxonomy = Taxonomy::isTaxonomy($field); $case_sensitive = $is_taxonomy && $case_sensitive_taxonomies; if (!isset($data[$field])) { $field = false; $values = null; } else { if ($case_sensitive) { $field = $data[$field]; $values = $instructions['value']; } else { $field = is_array($data[$field]) ? array_map('strtolower', $data[$field]) : strtolower($data[$field]); $values = is_array($instructions['value']) ? array_map('strtolower', $instructions['value']) : strtolower($instructions['value']); } } // convert boolean-like statements to boolean values if (is_array($values)) { foreach ($values as $item => $value) { if ($value == "true" || $value == "yes") { $values[$item] = true; } elseif ($value == "false" || $value == "no") { $values[$item] = false; } } } else { if ($values == "true" || $values == "yes") { $values = true; } elseif ($values == "false" || $values == "no") { $values = false; } } // equal comparisons if ($instructions['type'] == "equal") { // if this isn't set, it's not equal if (!$field) { throw new Exception("Does not fit condition"); } if (!is_array($field)) { if ($field != $values) { throw new Exception("Does not fit condition"); } } elseif (!in_array($values, $field)) { throw new Exception("Does not fit condition"); } // not-equal comparisons } elseif ($instructions['type'] == "not equal") { // if this isn't set, it's not equal, continue if (!$field) { continue; } if (!is_array($field)) { if ($field == $values) { throw new Exception("Does not fit condition"); } } elseif (in_array($values, $field)) { throw new Exception("Does not fit condition"); } // contains comparisons } elseif ($instructions['type'] == "in") { if (!isset($field)) { throw new Exception("Does not fit condition"); } if (is_array($field)) { $found = false; foreach ($field as $option) { if (in_array($option, $values)) { $found = true; break; } } if (!$found) { throw new Exception("Does not fit condition"); } } elseif (!in_array($field, $values)) { throw new Exception("Does not fit condition"); } } // we don't know what this is } else { throw new Exception("Unknown kind of condition"); } } catch (Exception $e) { unset($this->content[$key]); continue; } } } // located if ($located && !isset($data['coordinates'])) { unset($this->content[$key]); continue; } } }