public function _routes__before() { // check that caching is turned on if (!$this->core->isEnabled()) { return; } $today = Date::format('F j, Y'); $keys = $this->fetchConfig('new_day_invalidation', null, null, false, false); if (empty($keys) || $this->cache->get('last_new_day', null) == $today) { // don't need to do this return; } // set that we did this today $this->cache->put('last_new_day', $today); // invalidate if needed $this->core->deleteByKey(Parse::pipeList($keys)); }
/** * Is HTML-caching enabled (either globally or for $url)? * * @param string $url URL to check specifically for * @return bool */ public function isEnabled($url) { // check to see if html-caching is on $global_enable = (bool) $this->fetchConfig('enable', false, null, true); if (!$global_enable || !Cache::exists()) { return false; } // check that the URL being requested is a content file $data = ContentService::getContent($this->removeQueryString($url)); // not a content file, not enabled if (!$data) { return false; } // check for exclude on the current page $exclude_raw = $this->fetchConfig('exclude'); // if excludes were set if ($exclude_raw) { $excluded = Parse::pipeList($exclude_raw); // loop through excluded options foreach ($excluded as $exclude) { // account for non-/-starting locations $this_url = substr($exclude, 0, 1) !== "/" ? ltrim($url, '/') : $url; if ($exclude === "*" || $exclude === "/*") { // exclude all return false; } elseif (substr($exclude, -1) === "*") { // wildcard check if (strpos($this_url, substr($exclude, 0, -1)) === 0) { return false; } } else { // plain check if ($exclude == $this_url) { return false; } } } } // all is well, return true return 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) { $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); }
/** * Gets cached content for pages from given folders * * @param array $folders Folders to grab from * @return ContentSet */ public static function getContentByFolders($folders) { self::loadCache(); $content = array(); $folders = Parse::pipeList($folders); foreach ($folders as $folder) { foreach (self::$cache['content'] as $content_folder => $content_pages) { if (!Folder::matchesPattern($content_folder, $folder)) { continue; } foreach ($content_pages as $data) { $content[$data['path']] = $data['data']; } } } return new ContentSet($content); }
/** * Gets the target data from the cache * * @param array $config Configuration array * @return array */ public function getData($config) { // load data if ($config['taxonomy']) { $taxonomy_parts = Taxonomy::getCriteria(URL::getCurrent()); $taxonomy_type = $taxonomy_parts[0]; $taxonomy_slug = Config::get('_taxonomy_slugify') ? Slug::humanize($taxonomy_parts[1]) : urldecode($taxonomy_parts[1]); $content_set = ContentService::getContentByTaxonomyValue($taxonomy_type, $taxonomy_slug, $config['folders']); } else { $content_set = ContentService::getContentByFolders($config['folders']); } // filters $content_set->filter($config); // custom filter, remove the 404 page if needed if (!$config['include_404']) { $content_set->customFilter(function ($item) { return $item['url'] !== '/404'; }); } // custom filter, remove any excluded folders if ($config['exclude']) { $excluded = Parse::pipeList($config['exclude']); $content_set->customFilter(function ($item) use($excluded) { foreach ($excluded as $exclude) { if ($exclude === "*" || $exclude === "/*") { // exclude all return false; } elseif (substr($exclude, -1) === "*") { // wildcard check if (strpos($item['_folder'], substr($exclude, 0, -1)) === 0) { return false; } } else { // plain check if ($exclude == $item['_folder']) { return false; } } } return true; }); } $content_set->supplement(array('merge_with_data' => false)); $content_set->prepare($config['include_content']); $data = $content_set->get(); return $data; }
/** * Filters the current users based on the filters given * * @param array $filters Filters to apply * @return void */ public function filter($filters) { $filters = Helper::ensureArray($filters); // nothing to filter, abort if (!$this->count()) { return; } $roles = null; $conditions = null; $where = null; // standardize filters $given_filters = $filters; $filters = array('role' => isset($given_filters['role']) ? $given_filters['role'] : null, 'conditions' => isset($given_filters['conditions']) ? $given_filters['conditions'] : null, 'where' => isset($given_filters['where']) ? $given_filters['where'] : null); // determine filters if ($filters['role']) { $roles = Parse::pipeList($filters['role']); } if ($filters['conditions']) { $conditions = Parse::conditions($filters['conditions']); } if ($filters['where']) { $where = $filters['where']; } // run filters foreach ($this->members as $username => $data) { if ($roles) { $found = false; foreach ($roles as $role) { if (in_array($role, $data['roles'])) { $found = true; break; } } if (!$found) { unset($this->members[$username]); continue; } } if ($where && !(bool) Parse::template("{{ if " . $where . " }}1{{ else }}0{{ endif }}", $data)) { unset($this->members[$username]); continue; } if ($conditions) { 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") { if (!isset($data[$field])) { $field = false; $values = null; } 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"); } // 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("Does not fit condition"); } if (is_array($field) || is_array($values) || !is_numeric($field) || !is_numeric($values) || $field < $values) { throw new Exception("Does not fit condition"); } // greater than to comparisons } elseif ($instructions['type'] == "greater than") { // if this isn't set, it's not less than if (!$field) { throw new Exception("Does not fit condition"); } if (is_array($field) || is_array($values) || !is_numeric($field) || !is_numeric($values) || $field <= $values) { throw new Exception("Does not fit condition"); } // 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("Does not fit condition"); } if (is_array($field) || is_array($values) || !is_numeric($field) || !is_numeric($values) || $field > $values) { throw new Exception("Does not fit condition"); } // less than to comparisons } elseif ($instructions['type'] == "less than") { // if this isn't set, it's not less than if (!$field) { throw new Exception("Does not fit condition"); } if (is_array($field) || is_array($values) || !is_numeric($field) || !is_numeric($values) || $field >= $values) { 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"); } } elseif ($instructions['type'] == "not in") { if (!isset($field)) { throw new Exception("Does not fit condition"); } if (is_array($field)) { foreach ($field as $option) { if (in_array($option, $values)) { 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->members[$username]); continue; } } } } }
/** * Parses a mixed folder representation into a standardized array * * @deprecated * @param mixed $folders Folders * @return array */ public static function parseForFolders($folders) { Log::warn('Helper::parseForFolders has been deprecated. Use Parse::pipeList() instead.', 'core', 'api'); return Parse::pipeList($folders); }