Example #1
0
 /**
  * Helper to get instance of AutoloadBuilder with cli options applied
  *
  * @throws \RuntimeException
  * @return \TheSeer\Autoload\AutoloadBuilder|\TheSeer\Autoload\StaticBuilder
  */
 public function getBuilder(ClassFinder $finder)
 {
     $isStatic = $this->config->isStaticMode();
     $isPhar = $this->config->isPharMode();
     $isCompat = $this->config->isCompatMode();
     $noLower = !$this->config->isLowercaseMode();
     $isOnce = $this->config->isOnceMode();
     $tplType = $noLower ? 'cs' : 'ci';
     if ($isStatic === TRUE) {
         $builder = new StaticBuilder($finder->getMerged());
         $builder->setDependencies($finder->getDependencies());
         $builder->setPharMode($isPhar);
         $builder->setRequireOnce($isOnce);
     } else {
         $builder = new AutoloadBuilder($finder->getMerged());
     }
     $builder->setCompat($isCompat);
     $basedir = $this->config->getBaseDirectory();
     if (!$basedir || !is_dir($basedir)) {
         throw new \RuntimeException("Given basedir '{$basedir}' does not exist or is not a directory");
     }
     $builder->setBaseDir($basedir);
     $template = $this->config->getTemplate();
     if ($template !== NULL) {
         if (!file_exists($template)) {
             $alternative = __DIR__ . '/templates/' . $tplType . '/' . $template;
             if (file_exists($alternative)) {
                 $template = $alternative;
             }
         }
         $builder->setTemplateFile($template);
     } else {
         // determine auto template to use
         $tplFile = 'default.php.tpl';
         if ($isCompat) {
             $tplFile = 'php52.php.tpl';
         }
         if ($isPhar) {
             if ($isStatic) {
                 $tplFile = 'staticphar.php.tpl';
             } else {
                 $tplFile = 'phar.php.tpl';
             }
         } elseif ($isStatic) {
             $tplFile = 'static.php.tpl';
             $tplType = '.';
         }
         $builder->setTemplateFile(__DIR__ . '/templates/' . $tplType . '/' . $tplFile);
     }
     $format = $this->config->getDateFormat();
     if ($format) {
         $builder->setDateTimeFormat($format);
     }
     $builder->setIndent($this->config->getIndent());
     $builder->setLineBreak($this->config->getLinebreak());
     foreach ($this->config->getVariables() as $name => $value) {
         $builder->setVariable($name, $value);
     }
     return $builder;
 }
 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();
     }
 }
 /**
  * Add to the top of the publish form
  *
  * @return string
  */
 public function control_panel__add_to_publish_form_header()
 {
     // master switch for revisions
     if (!$this->core->isEnabled()) {
         return false;
     }
     $app = \Slim\Slim::getInstance();
     // hidden message field
     $html = '<input type="hidden" name="revisions__commit_message" id="revision-message">';
     $html .= '<div id="revision-default-serialized" style="display: none !important;"></div>';
     if ($this->blink->get('is_revision') && !$this->blink->get('is_latest_revision')) {
         // get the revision data
         $timestamp = $this->core->getRevisionTimestamp($this->core->getPath(), $this->blink->get('current_revision'));
         $html .= '<div class="revisions-feedback">';
         $html .= '  <span class="ss-icon">help</span>';
         $html .= '  ' . sprintf(__('viewing_revision'), Date::format(Config::getDateFormat(), $timestamp)) . ' ';
         $html .= '  <a href="' . $app->urlFor('publish') . '?path=' . URL::sanitize(Request::get('path')) . '">' . __('viewing_revision_link') . '.';
         $html .= '</div>';
     }
     return $html;
 }
Example #4
0
 /**
  * Helper to get instance of AutoloadRenderer with cli options applied
  *
  * @throws \RuntimeException
  * @return \TheSeer\Autoload\AutoloadRenderer|\TheSeer\Autoload\StaticRenderer
  */
 public function getRenderer(CollectorResult $result)
 {
     $isStatic = $this->config->isStaticMode();
     $isPhar = $this->config->isPharMode();
     $isCompat = $this->config->isCompatMode();
     $isOnce = $this->config->isOnceMode();
     if ($isStatic === TRUE) {
         $renderer = new StaticRenderer($result->getUnits());
         $renderer->setDependencies($result->getDependencies());
         $renderer->setPharMode($isPhar);
         $renderer->setRequireOnce($isOnce);
     } else {
         $renderer = new AutoloadRenderer($result->getUnits());
         if ($this->config->usePrepend()) {
             $renderer->prependAutoloader();
         }
         if ($this->config->useExceptions()) {
             $renderer->enableExceptions();
         }
     }
     $renderer->setCompat($isCompat);
     $basedir = $this->config->getBaseDirectory();
     if (!$basedir || !is_dir($basedir)) {
         throw new \RuntimeException("Given basedir '{$basedir}' does not exist or is not a directory");
     }
     $renderer->setBaseDir($basedir);
     $format = $this->config->getDateFormat();
     if ($format) {
         $renderer->setDateTimeFormat($format);
     }
     $renderer->setIndent($this->config->getIndent());
     $renderer->setLineBreak($this->config->getLinebreak());
     foreach ($this->config->getVariables() as $name => $value) {
         $renderer->setVariable($name, $value);
     }
     return $renderer;
 }
 public function index($value, $parameters = array())
 {
     $format = isset($parameters[0]) ? $parameters[0] : Config::getDateFormat();
     return Date::format($format, $value);
 }
Example #6
0
 public static function get_content_meta($slug, $folder = null, $raw = false, $parse = true)
 {
     $app = \Slim\Slim::getInstance();
     $site_root = Config::getSiteRoot();
     $content_root = Config::getContentRoot();
     $content_type = Config::getContentType();
     $file = $folder ? "{$content_root}/{$folder}/{$slug}.{$content_type}" : "{$content_root}/{$slug}.{$content_type}";
     $file = Path::tidy($file);
     $meta_raw = File::exists($file) ? file_get_contents($file) : '';
     if (Pattern::endsWith($meta_raw, "---")) {
         $meta_raw .= "\n";
         # prevent parse failure
     }
     # Parse YAML Front Matter
     if (strpos($meta_raw, "---") === false) {
         $meta = self::loadYamlCached($meta_raw);
         if (is_array($meta)) {
             $meta = array_merge($meta, $app->config);
         }
         $meta['content'] = "";
         if ($raw) {
             $meta['content_raw'] = "";
         }
     } else {
         list($yaml, $content) = preg_split("/\n---/", $meta_raw, 2, PREG_SPLIT_NO_EMPTY);
         $meta = self::loadYamlCached($yaml);
         if ($raw) {
             $meta['content_raw'] = $content;
         }
         // Parse the content if necessary
         //$meta['content'] = $parse ? Content::parse($content, $meta) : $content;
         $meta['content'] = $content;
     }
     if (File::exists($file)) {
         $meta['last_modified'] = filemtime($file);
     }
     if (!$raw) {
         $meta['homepage'] = Config::getSiteRoot();
         $meta['raw_url'] = Request::getResourceURI();
         $meta['page_url'] = Request::getResourceURI();
         # Is date formatted correctly?
         if (Config::getEntryTimestamps() && Slug::isDateTime($slug)) {
             $datetimestamp = Slug::getTimestamp($slug);
             $datestamp = Slug::getTimestamp($slug);
             $meta['datetimestamp'] = $datetimestamp;
             $meta['datestamp'] = $datestamp;
             $meta['date'] = Date::format(Config::getDateFormat(), $datestamp);
             $meta['time'] = Date::format(Config::getTimeFormat(), $datetimestamp);
             $meta['page_url'] = preg_replace(Pattern::DATETIME, '', $meta['page_url']);
             # clean url override
         } elseif (Slug::isDate($slug)) {
             $datestamp = Slug::getTimestamp($slug);
             $meta['datestamp'] = $datestamp;
             $meta['date'] = Date::format(Config::getDateFormat(), $datestamp);
             $meta['page_url'] = preg_replace(Pattern::DATE, '', $meta['page_url']);
             # clean url override
         } elseif (Slug::isNumeric($slug)) {
             $meta['numeric'] = Slug::getOrderNumber($slug);
         }
         $meta['permalink'] = Path::tidy(Config::getSiteURL() . '/' . $meta['page_url']);
         $taxonomy_slugify = isset($app->config['_taxonomy_slugify']) && $app->config['_taxonomy_slugify'];
         # Jam it all together, brother.
         # @todo: functionize/abstract this method for more flexibility and readability
         foreach ($meta as $key => $value) {
             if (!is_array($value) && Taxonomy::isTaxonomy($key)) {
                 $value = array($value);
                 $meta[$key] = $value;
             }
             if (is_array($value)) {
                 $list = array();
                 $url_list = array();
                 $i = 1;
                 $total_results = count($meta[$key]);
                 foreach ($meta[$key] as $k => $v) {
                     $url = null;
                     if (Taxonomy::isTaxonomy($key) && !is_array($v)) {
                         // DO NOT DO numerical regex replace on the actual taxonomy item
                         $url = Path::tidy(strtolower($site_root . '/' . $folder . '/' . $key));
                         $url = preg_replace(Pattern::NUMERIC, '', $url);
                         if ($taxonomy_slugify) {
                             $url .= "/" . strtolower(Slug::make($v));
                         } else {
                             $url .= "/" . strtolower($v);
                         }
                         $list[] = array('name' => $v, 'count' => $i, 'url' => $url, 'total_results' => $total_results, 'first' => $i == 1 ? true : false, 'last' => $i == $total_results ? true : false);
                         $url_list[] = '<a href="' . $url . '">' . $v . '</a>';
                     } elseif (!is_array($v)) {
                         $list[] = array('name' => $v, 'count' => $i, 'url' => $url, 'total_results' => $total_results, 'first' => $i == 1 ? true : false, 'last' => $i == $total_results ? true : false);
                     }
                     // account for known structure
                     // -
                     //   name: something
                     //   url: http://example.com
                     if (is_array($v) && isset($v['name']) && isset($v['url'])) {
                         $url_list[] = '<a href="' . $v['url'] . '">' . $v['name'] . '</a>';
                     }
                     $i++;
                 }
                 if (isset($url) || count($url_list)) {
                     $meta[$key . '_url_list'] = implode(', ', $url_list);
                     $meta[$key . '_spaced_url_list'] = join(" ", $url_list);
                     $meta[$key . '_ordered_url_list'] = "<ol><li>" . join("</li><li>", $url_list) . "</li></ol>";
                     $meta[$key . '_unordered_url_list'] = "<ul><li>" . join("</li><li>", $url_list) . "</li></ul>";
                     $meta[$key . '_sentence_url_list'] = Helper::makeSentenceList($url_list);
                     $meta[$key . '_ampersand_sentence_url_list'] = Helper::makeSentenceList($url_list, "&", false);
                 }
                 if (isset($meta[$key][0]) && !is_array($meta[$key][0])) {
                     $meta[$key . '_list'] = implode(', ', $meta[$key]);
                     $meta[$key . '_option_list'] = implode('|', $meta[$key]);
                     $meta[$key . '_spaced_list'] = implode(' ', $meta[$key]);
                     $meta[$key . '_ordered_list'] = "<ol><li>" . join("</li><li>", $meta[$key]) . "</li></ol>";
                     $meta[$key . '_unordered_list'] = "<ul><li>" . join("</li><li>", $meta[$key]) . "</li></ul>";
                     $meta[$key . '_sentence_list'] = Helper::makeSentenceList($meta[$key]);
                     $meta[$key . '_ampersand_sentence_list'] = Helper::makeSentenceList($meta[$key], "&", false);
                     $meta[$key] = $list;
                 }
             }
         }
     }
     return $meta;
 }
Example #7
0
    ?>
"><?php 
    print isset($entry['title']) && $entry['title'] != '' ? $entry['title'] : Slug::prettify($entry['slug']);
    ?>
</a>
            </td>

            <?php 
    if ($type == 'date') {
        ?>
              <td data-fulldate="<?php 
        echo $entry['datestamp'];
        ?>
">
                  <?php 
        echo Date::format(Config::getDateFormat('Y/m/d'), $entry['datestamp']);
        ?>
              </td>
            <?php 
    } elseif ($type == 'number') {
        ?>
              <td><?php 
        print $entry['numeric'];
        ?>
</td>
            <?php 
    }
    ?>
            <td class="margin status status-<?php 
    print $status;
    ?>
Example #8
0
 if (is_writable($data['path'])) {
     $data['logs_writable'] = TRUE;
 }
 // do any logs exist here?
 try {
     $filename_regex = "/^" . $data['prefix'] . "_(\\d{4})-(\\d{2})-(\\d{2})/i";
     $dir = opendir($data['path']);
     if (!$dir) {
         throw new Exception("Directory not found");
     }
     while (FALSE !== ($file = readdir($dir))) {
         if (!preg_match($filename_regex, $file, $matches)) {
             // no match, nothing to see here
             continue;
         }
         $data['logs'][$matches[1] . "-" . $matches[2] . "-" . $matches[3]] = array("date" => Date::format(Config::getDateFormat(), $matches[1] . "-" . $matches[2] . "-" . $matches[3]), "raw_date" => $matches[1] . "-" . $matches[2] . "-" . $matches[3], "filename" => $file, "full_path" => $data['path'] . DIRECTORY_SEPARATOR . $file);
         // we have found at least one valid log
         $data['logs_exist'] = TRUE;
     }
     ksort($data['logs']);
     closedir($dir);
     // flip the order of logs
     $data['logs'] = array_reverse($data['logs']);
 } catch (Exception $e) {
     // no logs exist
     $data['logs_exist'] = FALSE;
 }
 // filter
 $match = array('DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL');
 $filter = filter_input(INPUT_GET, 'filter');
 if ($filter) {
Example #9
0
File: cache.php Project: nob/joi
 /**
  * Updates the internal content cache
  *
  * @return boolean
  */
 public static function update()
 {
     // track if any files have changed
     $files_changed = false;
     // grab length of content type extension
     $content_type = Config::getContentType();
     $full_content_root = rtrim(Path::tidy(BASE_PATH . "/" . Config::getContentRoot()), "/");
     $content_type_length = strlen($content_type) + 1;
     // the cache file we'll use
     $cache_file = BASE_PATH . "/_cache/_app/content/content.php";
     $time_file = BASE_PATH . "/_cache/_app/content/last.php";
     $now = time();
     // grab the existing cache
     $cache = unserialize(File::get($cache_file));
     if (!is_array($cache)) {
         $cache = array("urls" => array(), "content" => array(), "taxonomies" => array());
     }
     $last = File::get($time_file);
     // grab a list of all files
     $finder = new Finder();
     $files = $finder->files()->name("*." . Config::getContentType())->in(Config::getContentRoot());
     // grab a separate list of files that have changed since last check
     $updated_files = clone $files;
     $updated = array();
     if ($last) {
         $updated_files->date(">= " . Date::format("Y-m-d H:i:s", $last));
         foreach ($updated_files as $file) {
             // we don't want directories, they may show up as being modified
             // if a file inside them has changed or been renamed
             if (is_dir($file)) {
                 continue;
             }
             // this isn't a directory, add it to the list
             $updated[] = Path::trimFilesystem(Path::standardize($file->getRealPath()));
         }
     }
     // loop over current files
     $current_files = array();
     foreach ($files as $file) {
         $current_files[] = Path::trimFilesystem(Path::standardize($file->getRealPath()));
     }
     // get a diff of files we know about and files currently existing
     $new_files = array_diff($current_files, $cache['urls']);
     // create a master list of files that need updating
     $changed_files = array_unique(array_merge($new_files, $updated));
     // add to the cache if files have been updated
     if (count($changed_files)) {
         $files_changed = true;
         // build content cache
         foreach ($changed_files as $file) {
             $file = $full_content_root . $file;
             $local_path = Path::trimFilesystem($file);
             $local_filename = Path::clean($local_path);
             // file parsing
             $content = substr(File::get($file), 3);
             $divide = strpos($content, "\n---");
             $front_matter = trim(substr($content, 0, $divide));
             // parse data
             $data = YAML::parse($front_matter);
             // set additional information
             $data['_file'] = $file;
             $data['_local_path'] = $local_path;
             $data['_order_key'] = null;
             $data['datetimestamp'] = null;
             // legacy
             $data['datestamp'] = null;
             $data['date'] = null;
             $data['time'] = null;
             $data['numeric'] = null;
             $data['last_modified'] = filemtime($file);
             $data['_is_hidden'] = false;
             $data['_is_draft'] = false;
             // folder
             $data['_folder'] = preg_replace(Pattern::ORDER_KEY, "", str_replace($full_content_root, "", $data['_file']));
             $slash = strrpos($data['_folder'], "/");
             $data['_folder'] = $slash === 0 ? "" : substr($data['_folder'], 1, $slash - 1);
             // fix hidden/draft files
             $slug = basename($file, "." . $content_type);
             if (substr($slug, 0, 2) === "__") {
                 $data['_is_hidden'] = true;
                 $data['slug'] = substr($slug, 2);
             } elseif (substr($slug, 0, 1) === "_") {
                 $data['_is_draft'] = true;
                 $data['slug'] = substr($slug, 1);
             } else {
                 $data['slug'] = $slug;
             }
             $data['_basename'] = $data['slug'] . "." . $content_type;
             $data['_filename'] = $data['slug'];
             $data['_is_entry'] = preg_match(Pattern::ENTRY_FILEPATH, $data['_basename']);
             $data['_is_page'] = preg_match(Pattern::PAGE_FILEPATH, $data['_basename']);
             // 404 is special
             if ($data['_local_path'] === "/404.{$content_type}") {
                 $local_filename = $local_path;
                 // order key
             } elseif (preg_match(Pattern::DATE_OR_DATETIME, $data['_basename'], $matches)) {
                 $date = $matches[1] . '-' . $matches[2] . '-' . $matches[3];
                 $time = NULL;
                 if (isset($matches[4])) {
                     $time = substr($matches[4], 0, 2) . ":" . substr($matches[4], 2);
                     $date = $date . " " . $time;
                     $data['slug'] = substr($data['slug'], 16);
                     $data['datetimestamp'] = $data['_order_key'];
                 } else {
                     $data['slug'] = substr($data['slug'], 11);
                 }
                 $data['_order_key'] = strtotime($date);
                 $data['datestamp'] = $data['_order_key'];
                 $data['date'] = Date::format(Config::getDateFormat(), $data['_order_key']);
                 $data['time'] = $time ? Date::format(Config::getTimeFormat(), $data['_order_key']) : NULL;
             } elseif (preg_match(Pattern::NUMERIC, $data['_basename'], $matches)) {
                 $data['_order_key'] = $matches[1];
                 $data['numeric'] = $data['_order_key'];
                 $data['slug'] = substr($data['slug'], strlen($matches[1]) + 1);
             } else {
                 $data['_order_key'] = $data['_basename'];
             }
             // determine url
             $data['url'] = preg_replace("/\\/__?/", "/", $local_filename);
             // remove any content type extensions from the end of filename
             if (substr($data['url'], -$content_type_length) === "." . $content_type) {
                 $data['url'] = substr($data['url'], 0, strlen($data['url']) - $content_type_length);
             }
             // remove any base pages from filename
             if (substr($data['url'], -5) == "/page") {
                 $data['url'] = substr($data['url'], 0, strlen($data['url']) - 5);
             }
             // add the site root
             $data['url'] = Path::tidy(Config::getSiteRoot() . $data['url']);
             // add the site URL to get the permalink
             $data['permalink'] = Path::tidy(Config::getSiteURL() . $data['url']);
             // add to cache file
             $cache['content'][$local_path] = $data;
             $cache['urls'][$data['url']] = $local_path;
         }
     }
     // loop through all cached content for deleted files
     // this isn't as expensive as you'd think in real-world situations
     foreach ($cache['content'] as $local_path => $data) {
         if (File::exists($full_content_root . $local_path)) {
             continue;
         }
         $files_changed = TRUE;
         // remove from content cache
         unset($cache['content'][$local_path]);
         // remove from url cache
         $url = array_search($local_path, $cache['urls']);
         if ($url !== FALSE) {
             unset($cache['urls'][$url]);
         }
     }
     // build taxonomy cache
     // only happens if files were added, updated, or deleted above
     if ($files_changed) {
         $taxonomies = Config::getTaxonomies();
         $force_lowercase = Config::getTaxonomyForceLowercase();
         $case_sensitive = Config::getTaxonomyCaseSensitive();
         $cache['taxonomies'] = array();
         if (count($taxonomies)) {
             // set up taxonomy array
             foreach ($taxonomies as $taxonomy) {
                 $cache['taxonomies'][$taxonomy] = array();
             }
             // loop through content to build cached array
             foreach ($cache['content'] as $file => $data) {
                 // do not grab anything not public
                 if (array_get($data, '_is_hidden', FALSE) || array_get($data, '_is_draft', FALSE)) {
                     continue;
                 }
                 // loop through the types of taxonomies
                 foreach ($taxonomies as $taxonomy) {
                     // if this file contains this type of taxonomy
                     if (isset($data[$taxonomy])) {
                         $values = Helper::ensureArray($data[$taxonomy]);
                         // add the file name to the list of found files for a given taxonomy value
                         foreach ($values as $value) {
                             if (!$value) {
                                 continue;
                             }
                             $key = !$case_sensitive ? strtolower($value) : $value;
                             if (!isset($cache['taxonomies'][$taxonomy][$key])) {
                                 $cache['taxonomies'][$taxonomy][$key] = array("name" => $force_lowercase ? strtolower($value) : $value, "files" => array());
                             }
                             array_push($cache['taxonomies'][$taxonomy][$key]['files'], $data['url']);
                         }
                     }
                 }
             }
         }
         if (File::put($cache_file, serialize($cache)) === false) {
             if (!File::isWritable($cache_file)) {
                 Log::fatal("Cache folder is not writable.", "core", "content-cache");
             }
             Log::fatal("Could not write to the cache.", "core", "content-cache");
             return false;
         }
     }
     File::put($time_file, $now);
     return true;
 }
 /**
  * Updates the internal content cache
  *
  * @return boolean
  */
 public static function update()
 {
     // start measuring
     $content_hash = Debug::markStart('caching', 'content');
     // track if any files have changed
     $files_changed = false;
     $settings_changed = false;
     $members_changed = false;
     // grab length of content type extension
     $content_type = Config::getContentType();
     $full_content_root = rtrim(Path::tidy(BASE_PATH . "/" . Config::getContentRoot()), "/");
     $content_type_length = strlen($content_type) + 1;
     // the cache files we'll use
     $cache_file = BASE_PATH . '/_cache/_app/content/content.php';
     $settings_file = BASE_PATH . '/_cache/_app/content/settings.php';
     $structure_file = BASE_PATH . '/_cache/_app/content/structure.php';
     $time_file = BASE_PATH . '/_cache/_app/content/last.php';
     $members_file = BASE_PATH . '/_cache/_app/members/members.php';
     $now = time();
     // start measuring settings hash
     $settings_hash = Debug::markStart('caching', 'settings');
     // check for current and new settings
     $settings = unserialize(File::get($settings_file));
     if (!is_array($settings)) {
         $settings = array('site_root' => '', 'site_url' => '', 'timezone' => '', 'date_format' => '', 'time_format' => '', 'content_type' => '', 'taxonomy' => '', 'taxonomy_case_sensitive' => '', 'taxonomy_force_lowercase' => '', 'entry_timestamps' => '', 'base_path' => '', 'app_version' => '');
     }
     // look up current settings
     $current_settings = array('site_root' => Config::getSiteRoot(), 'site_url' => Config::getSiteURL(), 'timezone' => Config::get('timezone'), 'date_format' => Config::get('date_format'), 'time_format' => Config::get('time_format'), 'content_type' => Config::get('content_type'), 'taxonomy' => Config::getTaxonomies(), 'taxonomy_case_sensitive' => Config::getTaxonomyCaseSensitive(), 'taxonomy_force_lowercase' => Config::getTaxonomyForceLowercase(), 'entry_timestamps' => Config::getEntryTimestamps(), 'base_path' => BASE_PATH, 'app_version' => STATAMIC_VERSION);
     // have cache-altering settings changed?
     if ($settings !== $current_settings) {
         // settings have changed
         $settings_changed = true;
         // clear the cache and set current settings
         $cache = self::getCleanCacheArray();
         $settings = $current_settings;
         $last = null;
     } else {
         // grab the existing cache
         $cache = unserialize(File::get($cache_file));
         if (!is_array($cache)) {
             $cache = self::getCleanCacheArray();
         }
         $last = File::get($time_file);
     }
     // mark end of settings hash measuring
     Debug::markEnd($settings_hash);
     // grab a list of all content files
     $files = File::globRecursively(Path::tidy(BASE_PATH . '/' . Config::getContentRoot() . '/*'), Config::getContentType());
     // grab a separate list of files that have changed since last check
     $updated = array();
     $current_files = array();
     // loop through files, getting local paths and checking for updated files
     foreach ($files as $file) {
         $local_file = Path::trimFilesystemFromContent(Path::standardize($file));
         // add to current files
         $current_files[] = $local_file;
         // is this updated?
         if ($last && File::getLastModified($file) >= $last) {
             $updated[] = $local_file;
         }
     }
     // get a diff of files we know about and files currently existing
     $known_files = array();
     foreach ($cache['urls'] as $url_data) {
         array_push($known_files, $url_data['path']);
     }
     $new_files = array_diff($current_files, $known_files);
     // create a master list of files that need updating
     $changed_files = array_unique(array_merge($new_files, $updated));
     // store a list of changed URLs
     $changed_urls = array();
     // add to the cache if files have been updated
     if (count($changed_files)) {
         $files_changed = true;
         // build content cache
         foreach ($changed_files as $file) {
             $file = $full_content_root . $file;
             $local_path = Path::trimFilesystemFromContent($file);
             // before cleaning anything, check for hidden or draft content
             $is_hidden = Path::isHidden($local_path);
             $is_draft = Path::isDraft($local_path);
             // now clean up the path
             $local_filename = Path::clean($local_path);
             // file parsing
             $content = substr(File::get($file), 3);
             $divide = strpos($content, "\n---");
             $front_matter = trim(substr($content, 0, $divide));
             $content_raw = trim(substr($content, $divide + 4));
             // parse data
             $data = YAML::parse($front_matter);
             if ($content_raw) {
                 $data['content'] = 'true';
                 $data['content_raw'] = 'true';
             }
             // set additional information
             $data['_file'] = $file;
             $data['_local_path'] = $local_path;
             $data['_order_key'] = null;
             $data['datetimestamp'] = null;
             // legacy
             $data['datestamp'] = null;
             $data['date'] = null;
             $data['time'] = null;
             $data['numeric'] = null;
             $data['last_modified'] = filemtime($file);
             $data['_is_hidden'] = $is_hidden;
             $data['_is_draft'] = $is_draft;
             // get initial slug (may be changed below)
             $data['slug'] = ltrim(basename($file, "." . $content_type), "_");
             // folder
             $instance = $data['slug'] == 'page' ? 1 : 0;
             $data['_folder'] = Path::clean($data['_local_path']);
             $slash = Helper::strrpos_count($data['_folder'], '/', $instance);
             $data['_folder'] = !$slash ? '' : substr($data['_folder'], 1, $slash - 1);
             $data['_folder'] = !strlen($data['_folder']) ? "/" : $data['_folder'];
             $data['_basename'] = $data['slug'] . '.' . $content_type;
             $data['_filename'] = $data['slug'];
             $data['_is_entry'] = preg_match(Pattern::ENTRY_FILEPATH, $data['_basename']);
             $data['_is_page'] = preg_match(Pattern::PAGE_FILEPATH, $data['_basename']);
             // 404 is special
             if ($data['_local_path'] === "/404.{$content_type}") {
                 $local_filename = $local_path;
                 // order key: date or datetime
             } elseif (preg_match(Pattern::DATE_OR_DATETIME, $data['_basename'], $matches)) {
                 // order key: date or datetime
                 $date = $matches[1] . '-' . $matches[2] . '-' . $matches[3];
                 $time = null;
                 if (Config::getEntryTimestamps() && isset($matches[4])) {
                     $time = substr($matches[4], 0, 2) . ":" . substr($matches[4], 2);
                     $date = $date . " " . $time;
                     $data['slug'] = substr($data['slug'], 16);
                     $data['datetimestamp'] = $data['_order_key'];
                 } else {
                     $data['slug'] = substr($data['slug'], 11);
                 }
                 $data['_order_key'] = strtotime($date);
                 $data['datestamp'] = $data['_order_key'];
                 $data['date'] = Date::format(Config::getDateFormat(), $data['_order_key']);
                 $data['time'] = $time ? Date::format(Config::getTimeFormat(), $data['_order_key']) : null;
                 // order key: slug is page, back up a level
             } elseif ($data['slug'] == 'page' && preg_match(Pattern::NUMERIC, substr($data['_local_path'], Helper::strrpos_count($data['_local_path'], '/', 1)), $matches)) {
                 // order key: slug is page, back up a level
                 $data['_order_key'] = $matches[1];
                 $data['numeric'] = $data['_order_key'];
                 // order key: numeric
             } elseif (preg_match(Pattern::NUMERIC, $data['_basename'], $matches)) {
                 // order key: numeric
                 $data['_order_key'] = $matches[1];
                 $data['numeric'] = $data['_order_key'];
                 $data['slug'] = substr($data['slug'], strlen($matches[1]) + 1);
                 // order key: other
             } else {
                 // order key: other
                 $data['_order_key'] = $data['_basename'];
             }
             // determine url
             $data['url'] = preg_replace('#/__?#', '/', $local_filename);
             // remove any content type extensions from the end of filename
             if (substr($data['url'], -$content_type_length) === '.' . $content_type) {
                 $data['url'] = substr($data['url'], 0, strlen($data['url']) - $content_type_length);
             }
             // remove any base pages from filename
             if (substr($data['url'], -5) == '/page') {
                 $data['url'] = substr($data['url'], 0, strlen($data['url']) - 5);
             }
             // add the site root
             $data['url'] = Path::tidy(Config::getSiteRoot() . $data['url']);
             // add the site URL to get the permalink
             $data['permalink'] = Path::tidy(Config::getSiteURL() . $data['url']);
             // new content
             if (!isset($cache['content'][$data['_folder']]) || !is_array($cache['content'][$data['_folder']])) {
                 $cache['content'][$data['_folder']] = array();
             }
             $slug_with_extension = $data['_filename'] == 'page' ? substr($data['url'], strrpos($data['url'], '/') + 1) . '/' . $data['_filename'] . "." . $content_type : $data['_filename'] . "." . $content_type;
             $cache['content'][$data['_folder']][$slug_with_extension] = array('folder' => $data['_folder'], 'path' => $local_path, 'file' => $slug_with_extension, 'url' => $data['url'], 'data' => $data);
             $cache['urls'][$data['url']] = array('folder' => $data['_folder'], 'path' => $local_path, 'file' => $slug_with_extension);
             $changed_urls[$data['url']] = true;
         }
     }
     // loop through all cached content for deleted files
     // this isn't as expensive as you'd think in real-world situations
     foreach ($cache['content'] as $folder => $folder_contents) {
         foreach ($folder_contents as $path => $data) {
             if (File::exists($full_content_root . $data['path'])) {
                 // still here, keep it
                 continue;
             }
             $files_changed = true;
             // get URL
             $url = isset($cache['content'][$folder][$path]['url']) ? $cache['content'][$folder][$path]['url'] : null;
             // only remove from URLs list if not in changed URLs list
             if (!isset($changed_urls[$url]) && !is_null($url)) {
                 // remove from url cache
                 unset($cache['urls'][$url]);
             }
             // remove from content cache
             unset($cache['content'][$folder][$path]);
         }
     }
     // build taxonomy cache
     // only happens if files were added, updated, or deleted above
     if ($files_changed) {
         $taxonomies = Config::getTaxonomies();
         $force_lowercase = Config::getTaxonomyForceLowercase();
         $case_sensitive = Config::getTaxonomyCaseSensitive();
         $cache['taxonomies'] = array();
         // rebuild taxonomies
         if (count($taxonomies)) {
             // set up taxonomy array
             foreach ($taxonomies as $taxonomy) {
                 $cache['taxonomies'][$taxonomy] = array();
             }
             // loop through content to build cached array
             foreach ($cache['content'] as $pages) {
                 foreach ($pages as $item) {
                     $data = $item['data'];
                     // loop through the types of taxonomies
                     foreach ($taxonomies as $taxonomy) {
                         // if this file contains this type of taxonomy
                         if (isset($data[$taxonomy])) {
                             $values = Helper::ensureArray($data[$taxonomy]);
                             // add the file name to the list of found files for a given taxonomy value
                             foreach ($values as $value) {
                                 if (!$value) {
                                     continue;
                                 }
                                 $key = !$case_sensitive ? strtolower($value) : $value;
                                 if (!isset($cache['taxonomies'][$taxonomy][$key])) {
                                     $cache['taxonomies'][$taxonomy][$key] = array('name' => $force_lowercase ? strtolower($value) : $value, 'files' => array());
                                 }
                                 array_push($cache['taxonomies'][$taxonomy][$key]['files'], $data['url']);
                             }
                         }
                     }
                 }
             }
         }
         // build structure cache
         $structure = array();
         $home = Path::tidy('/' . Config::getSiteRoot() . '/');
         foreach ($cache['content'] as $pages) {
             foreach ($pages as $item) {
                 // set up base variables
                 $parent = null;
                 // Trim off home and any /page.md ending so that all URLs are treated
                 // equally regardless of page type.
                 $order_key = str_replace('/page.md', '', str_replace($home, '', $item['path']));
                 $sub_order_key = $item['data']['_order_key'];
                 // does this have a parent (and if so, what is it?)
                 if ($item['url'] !== $home) {
                     $parent = $home;
                     $depth = substr_count(str_replace($home, '/', $item['url']), '/');
                     $last_slash = strrpos($item['url'], '/', 1);
                     $last_order_slash = strrpos($order_key, '/', 0);
                     if ($last_slash !== false) {
                         $parent = substr($item['url'], 0, $last_slash);
                     }
                     if ($last_order_slash !== false) {
                         $order_key = substr($order_key, 0, $last_order_slash);
                     }
                     if ($item['data']['_is_page']) {
                         $type = $item['data']['slug'] == 'page' ? 'folder' : 'page';
                     } else {
                         $type = 'entry';
                     }
                 } else {
                     $depth = 0;
                     $type = 'folder';
                     $order_key = $home;
                 }
                 $structure[$item['url']] = array('parent' => $parent, 'is_entry' => $item['data']['_is_entry'], 'is_page' => $item['data']['_is_page'], 'is_hidden' => $item['data']['_is_hidden'], 'is_draft' => $item['data']['_is_draft'], 'depth' => $depth, 'order_key' => $order_key ? $order_key : $sub_order_key, 'sub_order_key' => $sub_order_key, 'type' => $type);
             }
         }
     }
     // mark ending of content cache measuring
     Debug::markEnd($content_hash);
     if (!Config::get('disable_member_cache')) {
         // build member cache
         // ----------------------------------------------------------------
         // start measuring
         $member_hash = Debug::markStart('caching', 'member');
         // grab a list of existing members
         $users = File::globRecursively(Path::tidy(Config::getConfigPath() . '/users/*'), 'yaml');
         // clone for reuse, set up our list of updated users
         $updated = array();
         $current_users = array();
         foreach ($users as $user) {
             $local_file = Path::trimFilesystemFromContent(Path::standardize($user));
             // add to current users
             $current_users[] = $local_file;
             // is this updated?
             if ($last && File::getLastModified($user) >= $last) {
                 $updated[] = $local_file;
             }
         }
         // get users from the file
         $members = unserialize(File::get($members_file));
         // get a diff of users we know about and files currently existing
         $known_users = array();
         if (!empty($members)) {
             foreach ($members as $username => $member_data) {
                 $known_users[$username] = $member_data['_path'];
             }
         }
         // create a master list of users that need updating
         $changed_users = array_unique(array_merge(array_diff($current_users, $known_users), $updated));
         $removed_users = array_diff($known_users, $current_users);
         if (count($changed_users)) {
             $members_changed = true;
             foreach ($changed_users as $user_file) {
                 // file parsing
                 $last_slash = strrpos($user_file, '/') + 1;
                 $last_dot = strrpos($user_file, '.');
                 $username = substr($user_file, $last_slash, $last_dot - $last_slash);
                 $content = substr(File::get($user_file), 3);
                 $divide = strpos($content, "\n---");
                 $data = YAML::parse(trim(substr($content, 0, $divide)));
                 $bio_raw = trim(substr($content, $divide + 4));
                 $data['_path'] = $user_file;
                 if ($bio_raw) {
                     $data['biography'] = 'true';
                     $data['biography_raw'] = 'true';
                 }
                 $members[$username] = $data;
             }
         }
         // loop through all cached content for deleted files
         // this isn't as expensive as you'd think in real-world situations
         if (!empty($removed_users)) {
             $members_changed = true;
             $members = array_diff_key($members, $removed_users);
         }
         // mark ending of member cache measuring
         Debug::markEnd($member_hash);
     }
     // write to caches
     // --------------------------------------------------------------------
     // add file-writing to content-cache actions
     $content_hash = Debug::markStart('caching', 'content');
     if ($files_changed) {
         // store the content cache
         if (File::put($cache_file, serialize($cache)) === false) {
             if (!File::isWritable($cache_file)) {
                 Log::fatal('Cache folder is not writable.', 'core', 'content-cache');
             }
             Log::fatal('Could not write to the cache.', 'core', 'content-cache');
             return false;
         }
         // store the structure cache
         if (File::put($structure_file, serialize($structure)) === false) {
             if (!File::isWritable($structure_file)) {
                 Log::fatal('Structure cache file is not writable.', 'core', 'structure-cache');
             }
             Log::fatal('Could not write to the structure cache.', 'core', 'structure-cache');
             return false;
         }
     }
     // mark ending of content cache file write measuring
     Debug::markEnd($content_hash);
     // add file-writing to settings-cache actions
     $settings_hash = Debug::markStart('caching', 'settings');
     // store the settings cache
     if ($settings_changed) {
         if (File::put($settings_file, serialize($settings)) === false) {
             if (!File::isWritable($settings_file)) {
                 Log::fatal('Settings cache file is not writable.', 'core', 'settings-cache');
             }
             Log::fatal('Could not write to the settings cache file.', 'core', 'settings-cache');
             return false;
         }
     }
     // mark ending of settings cache file write measuring
     Debug::markEnd($settings_hash);
     if (!Config::get('disable_member_cache')) {
         // add file-writing to settings-cache actions
         $member_hash = Debug::markStart('caching', 'member');
         // store the members cache
         if ($members_changed) {
             if (File::put($members_file, serialize($members)) === false) {
                 if (!File::isWritable($members_file)) {
                     Log::fatal('Member cache file is not writable.', 'core', 'member-cache');
                 }
                 Log::fatal('Could not write to the member cache file.', 'core', 'member-cache');
                 return false;
             }
         }
         // mark ending of member cache file write measuring
         Debug::markEnd($member_hash);
     }
     File::put($time_file, $now - 1);
     return true;
 }