/**
  * Copies folders
  * 
  * @return void
  */
 public function copyAssets()
 {
     foreach (Helper::ensureArray($this->config['copy']) as $folder) {
         $folder = str_replace('{theme}', Config::getTheme(), $folder);
         $full_from_path = Path::assemble(BASE_PATH, $folder);
         $full_to_path = Path::assemble(BASE_PATH, $this->config['destination'], $folder);
         Folder::copy($full_from_path, $full_to_path);
     }
 }
Beispiel #2
0
	public function render()
	{
		// Let's make sure they set an upload destination
		if (array_get($this->field_config, 'destination', false) === false) {
			throw new Exception("You need to set a destination for your File field.");
		}

		// Normalize the destination
		$this->destination = trim(array_get($this->field_config, 'destination'), '/') . '/';

		// Allow a string or an array, but we want an array
		$has_data = ($this->field_data != '');
		$this->field_data = Helper::ensureArray($this->field_data);

		// Clean up {{ _site_root }} and lack of leading slash existence
		foreach ($this->field_data as $i => $file) {
			$this->field_data[$i] = URL::tidy('/' . str_replace('{{ _site_root }}', '', $file));
		}

		// Whether or not to allow the browse existing files functionality
		$allow_browse = array_get($this->field_config, 'browse', true);

		// Resizing config
		if ($resize = array_get($this->field_config, 'resize')) {
			$resize['resize'] = true;
			$resize = http_build_query($resize);
		}

		// If we're in a subdirectory, prepend it to all the filenames
		if (($site_root = Config::getSiteRoot()) != '/') {
			foreach ($this->field_data as $i => $file) {
				$this->field_data[$i] = URL::assemble($site_root, $file);
			}
		}

		// Send data to the view
		$vars = array(
			'field_id'     => $this->field_id,
			'field_name'   => $this->fieldname,
			'tabindex'     => $this->tabindex,
			'has_data'     => $has_data,
			'field_data'   => $this->field_data,
			'field_config' => $this->field_config,
			'destination'  => $this->destination,
			'allow_browse' => $allow_browse,
			'server_files' => ($allow_browse) ? json_encode($this->tasks->generateModal($this->field_config, $this->destination)) : null,
			'file_thumb'   => URL::assemble(Config::getSiteRoot(), Config::get('admin_path'), 'themes', Config::get('admin_theme'), '/img/file.png'),
			'resize'       => $resize
		);
		$template = File::get($this->getAddonLocation() . 'views/fieldtype.html');

		return Parse::template($template, $vars);
	}
 public function render()
 {
     $options = array_get($this->field_config, 'options', array());
     $html = '<input type="hidden" name="' . $this->fieldname . '" value="false" />';
     foreach ($options as $key => $option) {
         $attributes = array('name' => $this->fieldname . '[]', 'id' => $this->field_id . '_' . $key, 'class' => 'checkbox', 'tabindex' => $this->tabindex, 'value' => $key, 'checked' => '');
         if ($this->field_data && in_array($key, Helper::ensureArray($this->field_data))) {
             $attributes['checked'] = 'checked';
         }
         $html .= '<div class="checkbox-block">';
         $html .= HTML::makeInput('checkbox', $attributes, $this->is_required);
         $html .= '<label for="' . $this->field_id . '_' . $key . '">' . $option . '</label>';
         $html .= '</div>';
     }
     return $html;
 }
 public function render()
 {
     // Generate a hash unique to this field's config and data
     $hash = Helper::makeHash($this->field_config, $this->field_data);
     // If we've already saved the output, grab it from blink's cache
     // and avoid further processing.
     if ($this->blink->exists($hash)) {
         $html = $this->blink->get($hash);
         return $this->renderFieldReplacements($html);
     }
     // Let's make sure they set an upload destination
     if (array_get($this->field_config, 'destination', false) === false) {
         throw new Exception("You need to set a destination for your File field.");
     }
     // Normalize the destination
     $this->destination = trim(array_get($this->field_config, 'destination'), '/') . '/';
     // Allow a string or an array, but we want an array
     $has_data = $this->field_data != '';
     $this->field_data = Helper::ensureArray($this->field_data);
     // Clean up {{ _site_root }} and lack of leading slash existence
     foreach ($this->field_data as $i => $file) {
         $this->field_data[$i] = URL::tidy('/' . str_replace('{{ _site_root }}', '', $file));
     }
     // Whether or not to allow the browse existing files functionality
     $allow_browse = array_get($this->field_config, 'browse', true);
     // Resizing config
     if ($resize = array_get($this->field_config, 'resize')) {
         $resize['resize'] = true;
         $resize = http_build_query($resize);
     }
     // If we're in a subdirectory, prepend it to all the filenames
     if (($site_root = Config::getSiteRoot()) != '/') {
         foreach ($this->field_data as $i => $file) {
             $this->field_data[$i] = URL::assemble($site_root, $file);
         }
     }
     // Send data to the view
     $vars = array('field_id' => $this->field_id, 'field_name' => $this->fieldname, 'tabindex' => $this->tabindex, 'has_data' => $has_data, 'field_data' => $this->field_data, 'field_config' => $this->field_config, 'destination' => $this->destination, 'allow_browse' => $allow_browse, 'browse_url' => URL::assemble(Config::getSiteRoot(), Config::get('admin_path') . '.php/files?config=' . rawurlencode(Helper::encrypt(serialize($this->field_config)))), 'file_thumb' => $this->tasks->defaultFileThumbnail(), 'resize' => $resize);
     // Get the view template from the file
     $template = File::get($this->getAddonLocation() . 'views/fieldtype.html');
     // Parse it
     $html = Parse::template($template, $vars);
     // Save it to cache for other similar fields
     $this->blink->set($hash, $html);
     // Output!
     return $this->renderFieldReplacements($html);
 }
Beispiel #5
0
/**
 * Get an item from an array using "colon" notation.
 *
 * <code>
 *    // Get the $array['user']['name'] value from the array
 *    $name = array_get($array, 'user:name');
 *
 *    // Return a default from if the specified item doesn't exist
 *    $name = array_get($array, 'user:name', 'Batman');
 * 
 *    // Return the first found key, otherwise a default
 *    $name = array_get($array, array('user:name', 'user:first_name'), 'Bruce');
 * </code>
 *
 * @param  array   $array
 * @param  string|array  $key
 * @param  mixed   $default
 * @return mixed
 */
function array_get($array, $key, $default = null) {
    if (is_null($key)) return $array;
    $keys = Helper::ensureArray($key);
    
    // short-circuit
    if (!is_array($array)) {
        return Helper::resolveValue($default);
    }
    
    // a flag to remember whether something has been found or not
    $found = false;

    // To retrieve the array item using dot syntax, we'll iterate through
    // each segment in the key and look for that value. If it exists, we
    // will return it, otherwise we will set the depth of the array and
    // look for the next segment.
    foreach ($keys as $key) {
        foreach (explode(':', $key) as $segment) {
            if (!is_array($array) || !array_key_exists($segment, $array)) {
                // did we not find something? mark `found` as `false`
                $found = false;
                break;
            }

            // we found something, although not sure if this is the last thing,
            // mark `found` as `true` and let the outer loop handle it if this
            // *is* the last thing in the list
            $found = true;
            $array = $array[$segment];
        }
        
        // if `found` is `true`, the inner loop found something worth returning,
        // which means that we're done here
        if ($found) {
            break;
        }
    }
    
    if ($found) {
        // `found` is `true`, we found something, return that
        return $array;
    } else {
        // `found` isn't `true`, return the default
        return Helper::resolveValue($default);
    }
}
 /**
  * Fetches a value from the user-passed parameters
  *
  * @param mixed  $keys  Key of value to retrieve, an array will allow fallback param names
  * @param mixed  $default  Default value if no value is found
  * @param callable  $validity_check  Allows a callback function to validate parameter
  * @param boolean  $is_boolean  Indicates parameter is boolean
  * @param boolean  $force_lower  Force the parameter's value to be lowercase?
  * @return mixed
  */
 protected function fetchParam($keys, $default = NULL, $validity_check = NULL, $is_boolean = FALSE, $force_lower = TRUE)
 {
     $keys = Helper::ensureArray($keys);
     foreach ($keys as $key) {
         if (isset($this->attributes[$key])) {
             $value = $force_lower ? strtolower($this->attributes[$key]) : $this->attributes[$key];
             if (!$validity_check || $validity_check && is_callable($validity_check) && $validity_check($value) === TRUE) {
                 // account for yes/no parameters
                 if ($is_boolean === TRUE) {
                     return !in_array(strtolower($value), array("no", "false", "0", "", "-1"));
                 }
                 // otherwise, standard return
                 return $value;
             }
         }
     }
     return $default;
 }
 /**
  * Delete one or more keys' hashes
  * 
  * @param string|array  $keys  Key or keys whose hashes should be deleted
  * @return bool
  */
 public function deleteByKey($keys)
 {
     $keys = Helper::ensureArray($keys);
     foreach ($keys as $key) {
         if (!$this->cache->exists('keys/' . $key)) {
             continue;
         }
         // grab the hashes to invalidate
         $hashes = $this->cache->getYAML('keys/' . $key);
         foreach ($hashes as $hash) {
             // delete it
             if ($this->cache->exists('troves/' . $hash)) {
                 $this->cache->delete('troves/' . $hash);
             }
         }
     }
     return true;
 }
Beispiel #8
0
 /**
  * Filter
  *
  * @param array  $filters  Filter list
  * @return void
  */
 public function filter($filters)
 {
     $folders = array();
     $min_count = 0;
     if (isset($filters['folders'])) {
         $folders = Helper::ensureArray($filters['folders']);
     }
     if (isset($filters['min_count'])) {
         $min_count = (int) $filters['min_count'];
     }
     $data = $this->data;
     foreach ($data as $value => $parts) {
         $filters = array('folders' => $folders);
         $parts['content']->filter($filters);
         $parts['count'] = $parts['content']->count();
         if ($parts['count'] < $min_count) {
             unset($data[$value]);
         }
     }
     $this->data = $data;
 }
 /**
  * Filter
  *
  * @param array  $filters  Filter list
  * @return void
  */
 public function filter($filters)
 {
     $min_count = 0;
     $given_filters = $filters;
     $filters = array('min_count' => isset($given_filters['min_count']) ? $given_filters['min_count'] : null, 'show_drafts' => isset($given_filters['show_drafts']) ? $given_filters['show_drafts'] : null, 'show_hidden' => isset($given_filters['show_hidden']) ? $given_filters['show_hidden'] : 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, 'conditions' => isset($given_filters['conditions']) ? $given_filters['conditions'] : null, 'where' => isset($given_filters['where']) ? $given_filters['where'] : null, 'folders' => isset($given_filters['folders']) ? $given_filters['folders'] : null, 'located' => isset($given_filters['located']) ? $given_filters['located'] : null);
     // fix folders to be an array
     if (!is_null($filters['folders'])) {
         $filters['folders'] = Helper::ensureArray($filters['folders']);
     }
     if (!is_null($filters['min_count'])) {
         $min_count = (int) $filters['min_count'];
     }
     $data = $this->data;
     foreach ($data as $value => $parts) {
         $parts['content']->filter($filters);
         $parts['count'] = $parts['content']->count();
         if ($parts['count'] < $min_count) {
             unset($data[$value]);
         }
     }
     $this->data = $data;
     // re-tally results
     $this->tallyResults();
 }
Beispiel #10
0
    public function process($settings)
    {
        // If empty, save as null
        if ($this->field_data === '') {
            return null;
        }

        // If we're forcing lowercase taxonomies (which we are by default), save them as lower too
        if (array_get($settings, 'taxonomy', false) && Config::get('taxonomy_force_lowercase', false)) {
            $this->field_data = Helper::ensureArray($this->field_data);
            
            foreach ($this->field_data as $key => $value) {
                $this->field_data[$key] = strtolower($value);
            }
        }

        return $this->field_data;
    }
Beispiel #11
0
 private function metricTally($config, $data)
 {
     $field = $config['field'];
     $metrics = array();
     foreach ($data as $item) {
         $values = Helper::ensureArray($item['fields'][$field]);
         foreach ($values as $value) {
             if (array_get($metrics, $value)) {
                 $metrics[$value] = $metrics[$value] + 1;
             } else {
                 $metrics[$value] = 1;
             }
         }
     }
     if ($sort_by = array_get($config, 'sort_by')) {
         if ($sort_by === 'key') {
             ksort($metrics);
         } elseif ($sort_by === 'value') {
             arsort($metrics);
         }
         if (array_get($config, 'sort_dir') === 'desc') {
             $metrics = array_reverse($metrics, true);
         }
     }
     $config['metrics'] = $metrics;
     return $config;
 }
 /**
  * Supplements the content in the set
  *
  * @param array  $context  Context for supplementing
  * @return void
  */
 public function supplement($context = array())
 {
     $hash = Debug::markStart('content', 'supplementing');
     if ($this->supplemented) {
         return;
     }
     $this->supplemented = true;
     $context = Helper::ensureArray($context);
     // determine context
     $given_context = $context;
     $context = array('locate_with' => isset($given_context['locate_with']) ? $given_context['locate_with'] : null, 'center_point' => isset($given_context['center_point']) ? $given_context['center_point'] : null, 'list_helpers' => isset($given_content['list_helpers']) ? $given_context['list_helpers'] : true, 'context_urls' => isset($given_context['context_urls']) ? $given_context['context_urls'] : true, 'total_found' => isset($given_context['total_found']) ? $given_context['total_found'] : null, 'group_by_date' => isset($given_context['group_by_date']) ? $given_context['group_by_date'] : null, 'inherit_folder_data' => isset($given_context['inherit_folder_data']) ? $given_context['inherit_folder_data'] : true, 'merge_with_data' => isset($given_context['merge_with_data']) ? $given_context['merge_with_data'] : true);
     // set up helper variables
     $center_point = false;
     if ($context['center_point'] && preg_match(Pattern::COORDINATES, $context['center_point'], $matches)) {
         $center_point = array($matches[1], $matches[2]);
     }
     // contextual urls are based on current page, not individual data records
     // we can figure this out once and then set it with each one
     if ($context['context_urls']) {
         $raw_url = Request::getResourceURI();
         $page_url = Path::tidy($raw_url);
     }
     // iteration memory
     $last_date = null;
     // loop through content, supplementing each record with data
     foreach ($this->content as $content_key => $data) {
         // locate
         if ($context['locate_with']) {
             $location_data = isset($data[$context['locate_with']]) ? $data[$context['locate_with']] : null;
             // check that location data is fully set
             if (is_array($location_data) && isset($location_data['latitude']) && $location_data['latitude'] && isset($location_data['longitude']) && $location_data['longitude']) {
                 $data['latitude'] = $location_data['latitude'];
                 $data['longitude'] = $location_data['longitude'];
                 $data['coordinates'] = $location_data['latitude'] . "," . $location_data['longitude'];
                 // get distance from center
                 if ($center_point) {
                     $location = array($data['latitude'], $data['longitude']);
                     $data['distance_km'] = Math::getDistanceInKilometers($center_point, $location);
                     $data['distance_mi'] = Math::convertKilometersToMiles($data['distance_km']);
                 }
             }
         }
         // contextual urls
         if ($context['context_urls']) {
             $data['raw_url'] = $raw_url;
             $data['page_url'] = $page_url;
         }
         // total entries
         if ($context['total_found']) {
             $data['total_found'] = (int) $context['total_found'];
         }
         // group by date
         if ($context['group_by_date'] && $data['datestamp']) {
             $formatted_date = Date::format($context['group_by_date'], $data['datestamp']);
             if ($formatted_date !== $last_date) {
                 $last_date = $formatted_date;
                 $data['grouped_date'] = $formatted_date;
             } else {
                 $data['grouped_date'] = '';
             }
         }
         // loop through content to add data for variables that are arrays
         foreach ($data as $key => $value) {
             // Only run on zero indexed arrays/loops
             if (is_array($value) && isset($value[0]) && !is_array($value[0])) {
                 // list helpers
                 if ($context['list_helpers']) {
                     // make automagic lists
                     $data[$key . "_list"] = join(", ", $value);
                     $data[$key . "_spaced_list"] = join(" ", $value);
                     $data[$key . "_option_list"] = join("|", $value);
                     $data[$key . "_ordered_list"] = "<ol><li>" . join("</li><li>", $value) . "</li></ol>";
                     $data[$key . "_unordered_list"] = "<ul><li>" . join("</li><li>", $value) . "</li></ul>";
                     $data[$key . "_sentence_list"] = Helper::makeSentenceList($value);
                     $data[$key . "_ampersand_sentence_list"] = Helper::makeSentenceList($value, "&", false);
                     // handle taxonomies
                     if (Taxonomy::isTaxonomy($key)) {
                         $url_list = array_map(function ($item) use($data, $key, $value) {
                             return '<a href="' . Taxonomy::getURL($data['_folder'], $key, $item) . '">' . $item . '</a>';
                         }, $value);
                         $data[$key . "_url_list"] = join(", ", $url_list);
                         $data[$key . "_spaced_url_list"] = join(" ", $url_list);
                         $data[$key . "_ordered_url_list"] = "<ol><li>" . join("</li><li>", $url_list) . "</li></ol>";
                         $data[$key . "_unordered_url_list"] = "<ul><li>" . join("</li><li>", $url_list) . "</li></ul>";
                         $data[$key . "_sentence_url_list"] = Helper::makeSentenceList($url_list);
                         $data[$key . "_ampersand_sentence_url_list"] = Helper::makeSentenceList($url_list, "&", false);
                     }
                 }
             }
         }
         // update content with supplemented data merged with global config data
         if ($context['merge_with_data'] || $context['inherit_folder_data']) {
             $folder_data = array();
             $all_config = array();
             if ($context['inherit_folder_data']) {
                 $folder_data = $this->getFolderData($data['_file']);
             }
             if ($context['merge_with_data']) {
                 $all_config = Config::getAll();
             }
             // merge them all together
             $this->content[$content_key] = $data + $folder_data + $all_config;
         } else {
             $this->content[$content_key] = $data;
         }
     }
     Debug::markEnd($hash);
 }
 /**
  * Gets a tree of content information
  *
  * @param string  $base_url  URL for the base of the tree to load
  * @param int  $depth  Number of levels deep to return
  * @param boolean  $folders_only  Folders only
  * @param boolean  $include_entries  Should we include entries in our tree?
  * @param boolean  $show_hidden  Should we not include hidden content
  * @param boolean  $include_content  Should we include content from the found info?
  * @param mixed  $exclude  Array of URLs to exclude
  * @return array
  */
 public static function getContentTree($base_url, $depth = 12, $folders_only = true, $include_entries = false, $show_hidden = false, $include_content = false, $exclude = false)
 {
     // load structure and set up variables
     self::loadStructure();
     $output = array();
     // exclude URLs
     $exclude = Helper::ensureArray($exclude);
     // no depth asked for
     if ($depth == 0) {
         return array();
     }
     // make sure we can find the requested URL in the structure
     if (!isset(self::$structure[$base_url])) {
         Log::debug('Could not find URL in structure cache.', 'core', 'ContentService');
         return array();
     }
     // depth measurements
     $starting_depth = self::$structure[$base_url]['depth'] + 1;
     // start one deeper than the base URL's depth
     $current_depth = $starting_depth;
     // recursively grab the tree
     foreach (self::$structure as $url => $data) {
         // is this the right depth and not the 404 page?
         if ($data['depth'] !== $current_depth || $url == "/404") {
             continue;
         }
         // is this under the appropriate parent?
         if (!Pattern::startsWith(Path::tidy($data['parent'] . '/'), Path::tidy($base_url . '/'))) {
             continue;
         }
         // is this hidden?
         if ($data['is_draft'] || !$show_hidden && $data['is_hidden']) {
             continue;
         }
         // is this an entry when we don't want them?
         if (!$include_entries && $data['is_entry'] && !$data['is_page']) {
             continue;
         }
         // is this a non-folder when all we want is folders?
         if ($folders_only && $data['type'] != 'folder') {
             continue;
         }
         // is this in the excluded URLs list?
         if (in_array($url, $exclude)) {
             continue;
         }
         // get parent url
         $parent_url = substr($url, 0, strrpos($url, '/'));
         $parent_url = $parent_url == "" ? Config::getSiteRoot() : $parent_url;
         // look up parent data in cache
         if (!isset(self::$parent_cache[$parent_url])) {
             // doesn't exist, load it up
             $parent_data = Content::get($parent_url, $include_content, false);
             if ($include_content) {
                 // give them everything
                 $parent = $parent_data;
             } else {
                 // just the bare necessities
                 $parent = array('title' => isset($parent_data['title']) ? $parent_data['title'] : '', 'url' => isset($parent_data['url']) ? $parent_data['url'] : '');
             }
             // now stick this in the cache for next time
             self::$parent_cache[$parent_url] = $parent;
         }
         // get information
         $content = Content::get($url, $include_content, false);
         // data to be returned to the tree
         $for_output = array('type' => $data['type'], 'title' => isset($content['title']) ? $content['title'] : '', 'slug' => $content['slug'], 'url' => $url, 'depth' => $current_depth, 'children' => self::getContentTree($url, $depth - 1, $folders_only, $include_entries, $show_hidden, $include_content, $exclude), 'is_current' => URL::getCurrent() == $url, 'is_parent' => URL::getCurrent() != $url && Pattern::startsWith(URL::getCurrent(), $url . '/'), 'is_entry' => $data['is_entry'], 'is_page' => $data['is_page'], 'is_folder' => $data['type'] == 'folder', 'order_key' => $data['order_key'], 'sub_order_key' => $data['sub_order_key'], 'parent' => array(self::$parent_cache[$parent_url]));
         // if we're including content, merge that in
         if ($include_content) {
             $for_output = $content + $for_output;
         }
         // add it to the list
         $output[] = $for_output;
     }
     // now we need to sort the nav items
     uasort($output, function ($a, $b) {
         // sort on order_key
         $result = Helper::compareValues($a['order_key'], $b['order_key']);
         // if those matched, sort on sub_order_key
         if ($result === 0) {
             $result = Helper::compareValues($a['sub_order_key'], $b['sub_order_key']);
         }
         // return 1 or 0 or -1, whatever we ended up with
         return $result;
     });
     // re-key the array
     $output = array_values($output);
     // return what we know
     return $output;
 }
 /**
  * Checks to see if this member has a given $role
  * 
  * @param mixed  $role  Role to check
  * @return boolean
  */
 public function hasRole($role)
 {
     $role = array_map('strtolower', Helper::ensureArray($role));
     $member_roles = array_map('strtolower', $this->get('roles'));
     // check for intersection
     $matches = array_intersect($member_roles, $role);
     return (bool) count($matches);
 }
 /**
  * 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;
 }
 /**
  * Populate the email message
  */
 private function populateMessage()
 {
     $attributes = $this->attributes;
     $this->mailer->CharSet = 'UTF-8';
     $this->mailer->Subject = $attributes['subject'];
     $from_parts = Email::explodeEmailString($attributes['from']);
     $this->mailer->setFrom($from_parts['email'], $from_parts['name']);
     $to = Helper::ensureArray($this->attributes['to']);
     foreach ($to as $to_addr) {
         $to_parts = Email::explodeEmailString($to_addr);
         $this->mailer->addAddress($to_parts['email'], $to_parts['name']);
     }
     if (isset($attributes['cc'])) {
         $cc = Helper::ensureArray($attributes['cc']);
         foreach ($cc as $cc_addr) {
             $cc_parts = Email::explodeEmailString($cc_addr);
             $this->mailer->addCC($cc_parts['email'], $cc_parts['name']);
         }
     }
     if (isset($attributes['bcc'])) {
         $bcc = Helper::ensureArray($attributes['bcc']);
         foreach ($bcc as $bcc_addr) {
             $bcc_parts = Email::explodeEmailString($bcc_addr);
             $this->mailer->addBCC($bcc_parts['email'], $bcc_parts['name']);
         }
     }
     if (isset($attributes['html'])) {
         $this->mailer->msgHTML($attributes['html']);
         if (isset($attributes['text'])) {
             $this->mailer->AltBody = $attributes['text'];
         }
     } elseif (isset($attributes['text'])) {
         $this->mailer->msgHTML($attributes['text']);
     }
 }
Beispiel #17
0
    /**
     * Send an email using a Transactional email service
     * or native PHP as a fallback.
     *
     * @param array  $attributes  A list of attributes for sending
     * @return bool on success
     */
    public static function send($attributes = array())
    {
        /*
        |--------------------------------------------------------------------------
        | Required attributes
        |--------------------------------------------------------------------------
        |
        | We first need to ensure we have the minimum fields necessary to send
        | an email.
        |
        */
        $required = array_intersect_key($attributes, array_flip(self::$required));

        if (count($required) >= 3) {

            /*
            |--------------------------------------------------------------------------
            | Load handler from config
            |--------------------------------------------------------------------------
            |
            | We check the passed data for a mailer + key first, and then fall back
            | to the global Statamic config.
            |
            */
            $email_handler     = array_get($attributes, 'email_handler', Config::get('email_handler', null));
            $email_handler_key = array_get($attributes, 'email_handler_key', Config::get('email_handler_key', null));

            if (in_array($email_handler, self::$email_handlers) && $email_handler_key) {

                /*
                |--------------------------------------------------------------------------
                | Initialize Stampie
                |--------------------------------------------------------------------------
                |
                | Stampie provides numerous adapters for popular email handlers, such as
                | Mandrill, Postmark, and SendGrid. Each is written as an abstract
                | interface in an Adapter Pattern.
                |
                */
                $mailer = self::initializeEmailHandler($email_handler, $email_handler_key);

                /*
                |--------------------------------------------------------------------------
                | Initialize Message class
                |--------------------------------------------------------------------------
                |
                | The message class is an implementation of the Stampie MessageInterface
                |
                */
                $email = new Message($attributes['to']);

                /*
                |--------------------------------------------------------------------------
                | Set email attributes
                |--------------------------------------------------------------------------
                |
                | I hardly think this requires much explanation.
                |
                */
                $email->setFrom($attributes['from']);

                $email->setSubject($attributes['subject']);

                if (isset($attributes['text'])) {
                    $email->setText($attributes['text']);
                }

                if (isset($attributes['html'])) {
                    $email->setHtml($attributes['html']);
                }

                if (isset($attributes['cc'])) {
                    $email->setCc($attributes['cc']);
                }

                if (isset($attributes['bcc'])) {
                    $email->setBcc($attributes['bcc']);
                }

                if (isset($attributes['headers'])) {
                    $email->setHeaders($attributes['headers']);
                }

                $mailer->send($email);

                return true;

            } else {

                /*
                |--------------------------------------------------------------------------
                | Native PHP Mail
                |--------------------------------------------------------------------------
                |
                | We're utilizing the popular PHPMailer class to handle the messy
                | email headers and do-dads. Emailing from PHP in general isn't the best
                | idea known to man, so this is really a lackluster fallback.
                |
                */
            try {
                $email = new PHPMailer(true);

                // SMTP
                if ($attributes['smtp'] = array_get($attributes, 'smtp', Config::get('smtp'))) {
                    
                    $email->isSMTP();

                    if ($smtp_host = array_get($attributes, 'smtp:host', false)) {
                        $email->Host = $smtp_host;
                    }

                    if ($smtp_secure = array_get($attributes, 'smtp:secure', false)) {
                        $email->SMTPSecure = $smtp_secure;
                    }

                    if ($smtp_port = array_get($attributes, 'smtp:port', false)) {
                        $email->Port = $smtp_port;
                    }

                    if (array_get($attributes, 'smtp:auth', false) === TRUE) {
                        $email->SMTPAuth = TRUE;
                    }

                    if ($smtp_username = array_get($attributes, 'smtp:username', false)) {
                        $email->Username = $smtp_username;
                    }

                    if ($smtp_password = array_get($attributes, 'smtp:password', false)) {
                        $email->Password = $smtp_password;
                    }

                // SENDMAIL
                } elseif (array_get($attributes, 'sendmail', false)) {
                    $email->isSendmail();

                // PHP MAIL
                } else {
                    $email->isMail();
                }

                $email->CharSet = 'UTF-8';

                $from_parts = self::explodeEmailString($attributes['from']);
                $email->setFrom($from_parts['email'], $from_parts['name']);

                $to = Helper::ensureArray($attributes['to']);
                foreach ($to as $to_addr) {
                    $to_parts = self::explodeEmailString($to_addr);
                    $email->addAddress($to_parts['email'], $to_parts['name']);
                }

                $email->Subject  = $attributes['subject'];

                if (isset($attributes['html'])) {
                    $email->msgHTML($attributes['html']);

                    if (isset($attributes['text'])) {
                        $email->AltBody = $attributes['text'];
                    }

                } elseif (isset($attributes['text'])) {
                    $email->msgHTML($attributes['text']);
                }

                if (isset($attributes['cc'])) {
                    $cc = Helper::ensureArray($attributes['cc']);
                    foreach ($cc as $cc_addr) {
                        $cc_parts = self::explodeEmailString($cc_addr);
                        $email->addCC($cc_parts['email'], $cc_parts['name']);
                    }                    
                }

                if (isset($attributes['bcc'])) {
                    $bcc = Helper::ensureArray($attributes['bcc']);
                    foreach ($bcc as $bcc_addr) {
                        $bcc_parts = self::explodeEmailString($bcc_addr);
                        $email->addBCC($bcc_parts['email'], $bcc_parts['name']);
                    }      
                }

                $email->send();

                } catch (phpmailerException $e) {
                    echo $e->errorMessage(); //error messages from PHPMailer
                    Log::error($e->errorMessage(), 'core', 'email');
                } catch (Exception $e) {
                    echo $e->getMessage();
                    Log::error($e->getMessage(), 'core', 'email');
                }

            }
        }

        return false;
    }
 /**
  * Target for the member:register_form form
  * 
  * @return void
  */
 public function member__register()
 {
     $referrer = $_SERVER['HTTP_REFERER'];
     $token = filter_input(INPUT_POST, 'token', FILTER_SANITIZE_STRING);
     $return = filter_input(INPUT_POST, 'return', FILTER_SANITIZE_STRING);
     $auto_login = (bool) filter_input(INPUT_POST, 'auto_login', FILTER_SANITIZE_NUMBER_INT);
     // validate form token
     if (!$this->tokens->validate($token)) {
         $this->flash->set('login_error', 'Invalid token.');
         URL::redirect($referrer);
     }
     // is user logged in?
     if (Auth::isLoggedIn()) {
         URL::redirect($return);
     }
     // get configurations
     $allowed_fields = array_get($this->loadConfigFile('fields'), 'fields', array());
     // get username
     $username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
     // set up iterators and flags
     $submission = array('username' => $username);
     // create member object
     $member = new Member(array());
     // adjust allowed fields to include username and password
     if (!isset($allowed_fields['username'])) {
         $allowed_fields['username'] = array();
     }
     if (!isset($allowed_fields['password'])) {
         $allowed_fields['password'] = array();
     }
     // loop through allowed fields, validating and storing
     foreach ($allowed_fields as $field => $options) {
         if (!isset($_POST[$field])) {
             // field wasn't set, skip it
             continue;
         }
         // set value
         $value = filter_input(INPUT_POST, $field, FILTER_SANITIZE_STRING);
         // don't store this value if `save_value` is set to `false`
         if (array_get($options, 'save_value', true)) {
             $member->set($field, $value);
         }
         // add to submissions, including non-save_value fields because this
         // is the list that will be validated
         $submission[$field] = $value;
     }
     // ensure UID
     $member->ensureUID(false);
     // user-defined validation
     $errors = $this->tasks->validate($submission);
     // built-in validation
     // --------------------------------------------------------------------
     // username
     if (!$username) {
         $errors['username'] = '******';
     } elseif (!Member::isValidUsername($username)) {
         $errors['username'] = '******';
     } elseif (Member::exists($username)) {
         $errors['username'] = '******';
     }
     // password
     $password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING);
     $password_confirm = filter_input(INPUT_POST, 'password_confirmation', FILTER_SANITIZE_STRING);
     if (empty($password)) {
         $errors['password'] = '******';
     }
     if (!isset($errors['password']) && !is_null($password_confirm) && $password !== $password_confirm) {
         $errors['password_confirmation'] = 'Passwords did not match.';
     }
     if (count($errors)) {
         // errors were found, set a flash message and redirect
         $this->flash->set('register_error', 'Member not created.');
         $this->flash->set('register_field_errors', $errors);
         // remove password and password_confirm from submission
         if (isset($submission['password'])) {
             unset($submission['password']);
         }
         if (isset($submission['password_confirmation'])) {
             unset($submission['password_confirmation']);
         }
         $this->flash->set('register_old_values', $submission);
         // redirect back to the form
         URL::redirect($referrer);
     } else {
         // set new member roles
         $member->set('roles', Helper::ensureArray($this->fetchConfig('new_member_roles', array(), null, false, false)));
         if ($this->runHook('pre_process', 'replace', true, $member)) {
             // save member
             $member->save();
             // trigger a hook
             $this->runHook('register', 'call', null, $member);
             // user saved
             $this->flash->set('register_success', 'Member created.');
             if ($auto_login) {
                 Auth::login($username, $password);
             }
             // run hook
             $this->runHook('registration_complete', null, null, $member);
             // redirect to member home
             URL::redirect($return);
         } else {
             $this->runHook('registration_failure', null, null, $member);
             $this->flash->set('register_failure', 'Member creation failed.');
         }
     }
 }
Beispiel #19
0
Datei: cache.php Projekt: 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;
 }
Beispiel #20
0
    /**
     * Returns HTML to include one or more given $scripts
     *
     * @param mixed  $scripts  Script(s) to create HTML for
     * @return string
     */
    public function link($scripts)
    {
        $files = Helper::ensureArray($scripts);
        $html  = '';

        foreach ($files as $file) {
            $html .= HTML::includeScript($this->get($file));
        }

        return $html;
    }
Beispiel #21
0
 /**
  * Supplements the members in the set
  *
  * @param array  $context  Context for supplementing
  * @return void
  */
 public function supplement($context = array())
 {
     if ($this->supplemented) {
         return;
     }
     $this->supplemented = true;
     $context = Helper::ensureArray($context);
     // determine context
     $given_context = $context;
     $context = array('total_found' => isset($given_context['total_found']) ? $given_context['total_found'] : null);
     // loop through content, supplementing each record with data
     foreach ($this->members as $data) {
         // total entries
         if ($context['total_found']) {
             $data['total_found'] = (int) $context['total_found'];
         }
     }
 }
 /**
  * Compares two values based on the given $comparison
  *
  * @param mixed  $allowed  Allowed value(s)
  * @param mixed  $test_value  Value(s) to check
  * @param string  $comparison  Type of comparison to make
  * @return bool
  */
 public function compareValues($allowed, $test_value, $comparison = "==")
 {
     $allowed = Helper::ensureArray($allowed);
     $test_value = Helper::ensureArray($test_value);
     $comparison = strtolower($comparison);
     // loop through each allowed value
     foreach ($allowed as $allowed_value) {
         // loop through each test value
         foreach ($test_value as $sub_test_value) {
             switch ($comparison) {
                 case "=":
                 case "==":
                     if (strtolower($sub_test_value) == strtolower($allowed_value)) {
                         return true;
                     }
                     break;
                 case "!=":
                 case "<>":
                 case "not":
                     // backwards-from-standard check, returning false if found
                     if (strtolower($sub_test_value) == strtolower($allowed_value)) {
                         return false;
                     }
                     break;
                 case "<":
                     if ($sub_test_value < $allowed_value) {
                         return true;
                     }
                     break;
                 case "<=":
                     if ($sub_test_value <= $allowed_value) {
                         return true;
                     }
                     break;
                 case ">":
                     if ($sub_test_value > $allowed_value) {
                         return true;
                     }
                     break;
                 case ">=":
                     if ($sub_test_value >= $allowed_value) {
                         return true;
                     }
                     break;
                 case "has":
                 case "exists":
                     if (!empty($sub_test_value)) {
                         return true;
                     }
                     break;
                 case "lacks":
                 case "missing":
                     // backwards-from-standard check, returning false if found
                     if (!empty($sub_test_value)) {
                         return false;
                     }
                     break;
                 default:
                     return false;
             }
         }
     }
     // if we're looking for a negative match (`not` or `lacks`) and we got here, return true
     if (in_array($comparison, array('!=', '<>', 'not', 'lacks', 'missing'))) {
         return true;
     }
     // in all other cases, return false
     return false;
 }
 /**
  * Recursively parses all of the variables in the given text and
  * returns the parsed text.
  *
  * @param  string       $text Text to parse
  * @param  array|object $data Array or object to use
  * @param  callable  $callback  Callback function to call
  * @return string
  */
 public function parseVariables($text, $data, $callback = null)
 {
     $this->setupRegex();
     // <statamic>
     // allow avoid tag parsing
     $noparse = array();
     if (isset($data['_noparse'])) {
         $noparse = \Helper::ensureArray($data['_noparse']);
     }
     // </statamic>
     /**
      * $data_matches[][0][0] is the raw data loop tag
      * $data_matches[][0][1] is the offset of raw data loop tag
      * $data_matches[][1][0] is the data variable (dot notated)
      * $data_matches[][1][1] is the offset of data variable
      * $data_matches[][2][0] is the content to be looped over
      * $data_matches[][2][1] is the offset of content to be looped over
      */
     if (preg_match_all($this->variableLoopRegex, $text, $data_matches, PREG_SET_ORDER + PREG_OFFSET_CAPTURE)) {
         foreach ($data_matches as $match) {
             // <statamic>
             // if variable is in the no-parse list, don't parse it
             $var_name = strpos($match[1][0], '|') !== false ? substr($match[1][0], 0, strpos($match[1][0], '|')) : $match[1][0];
             if (in_array($var_name, $noparse)) {
                 $text = $this->createExtraction('noparse', $match[0][0], $match[2][0], $text);
                 continue;
             }
             // </statamic>
             $loop_data = $this->getVariable($match[1][0], $data);
             if ($loop_data) {
                 $looped_text = '';
                 $index = 0;
                 // <statamic>
                 // is this data an array?
                 if (is_array($loop_data)) {
                     // is this a list, or simply a set of named variables?
                     if ((bool) count(array_filter(array_keys($loop_data), 'is_string'))) {
                         // this is a set of named variables, don't actually loop over and over,
                         // instead, parse the inner contents with this set's local variables that
                         // have been merged into the bigger scope
                         // merge this local data with callback data before performing actions
                         $loop_value = $loop_data + $data + self::$callbackData;
                         // perform standard actions
                         $str = $this->extractLoopedTags($match[2][0], $loop_value, $callback);
                         $str = $this->parseConditionals($str, $loop_value, $callback);
                         $str = $this->injectExtractions($str, 'looped_tags');
                         $str = $this->parseVariables($str, $loop_value, $callback);
                         if (!is_null($callback)) {
                             $str = $this->injectExtractions($str, 'callback_blocks');
                             $str = $this->parseCallbackTags($str, $loop_value, $callback);
                         }
                         $looped_text .= $str;
                         $text = preg_replace('/' . preg_quote($match[0][0], '/') . '/m', addcslashes($looped_text, '\\$'), $text, 1);
                     } else {
                         // this is a list, let's loop
                         $total_results = count($loop_data);
                         foreach ($loop_data as $loop_key => $loop_value) {
                             $index++;
                             // is the value an array?
                             if (!is_array($loop_value)) {
                                 // no, make it one
                                 $loop_value = array('value' => $loop_value, 'name' => $loop_value);
                             }
                             // set contextual iteration values
                             $loop_value['key'] = $loop_key;
                             $loop_value['index'] = $index;
                             $loop_value['zero_index'] = $index - 1;
                             $loop_value['total_results'] = $total_results;
                             $loop_value['first'] = $index === 1 ? true : false;
                             $loop_value['last'] = $index === $loop_value['total_results'] ? true : false;
                             // merge this local data with callback data before performing actions
                             $loop_value = $loop_value + $data + self::$callbackData;
                             // perform standard actions
                             $str = $this->extractLoopedTags($match[2][0], $loop_value, $callback);
                             $str = $this->parseConditionals($str, $loop_value, $callback);
                             $str = $this->injectExtractions($str, 'looped_tags');
                             $str = $this->parseVariables($str, $loop_value, $callback);
                             if (!is_null($callback)) {
                                 $str = $this->injectExtractions($str, 'callback_blocks');
                                 $str = $this->parseCallbackTags($str, $loop_value, $callback);
                             }
                             $looped_text .= $str;
                         }
                         $text = preg_replace('/' . preg_quote($match[0][0], '/') . '/m', addcslashes($looped_text, '\\$'), $text, 1);
                     }
                 } else {
                     // no, so this is just a value, we're done here
                     return $loop_data;
                 }
                 // </statamic>
             } else {
                 // It's a callback block.
                 // Let's extract it so it doesn't conflict
                 // with the local scope variables in the next step.
                 $text = $this->createExtraction('callback_blocks', $match[0][0], $match[0][0], $text);
             }
         }
     }
     /**
      * $data_matches[0] is the raw data tag
      * $data_matches[1] is the data variable (dot notated)
      */
     if (preg_match_all($this->variableTagRegex, $text, $data_matches)) {
         // <statamic>
         // add ability to specify `or` to find matches
         foreach ($data_matches[1] as $index => $var) {
             // <statamic>
             // check for `or` options
             if (strpos($var, ' or ') !== false) {
                 $vars = preg_split('/\\s+or\\s+/ms', $var, null, PREG_SPLIT_NO_EMPTY);
             } else {
                 $vars = array($var);
             }
             $size = sizeof($vars);
             for ($i = 0; $i < $size; $i++) {
                 // <statamic>
                 // account for modifiers
                 $var = trim($vars[$i]);
                 $var_pipe = strpos($var, '|');
                 $var_name = $var_pipe !== false ? substr($var, 0, $var_pipe) : $var;
                 // </statamic>
                 if (strpos($var, '"') === 0 && strrpos($var, '"') === strlen($var) - 1) {
                     $text = str_replace($data_matches[0][$index], substr($var, 1, strlen($var) - 2), $text);
                     break;
                 }
                 // retrieve the value of $var, otherwise, a no-value string
                 $val = $this->getVariable($var, $data, '__lex_no_value__');
                 // we only want to keep going if either:
                 //   - $val has no value according to the parser
                 //   - $val *does* have a value, it's false-y *and* there are multiple options here *and* we're not on the last one
                 if ($val === '__lex_no_value__' || !$val && $size > 1 && $i < $size - 1) {
                     continue;
                 } else {
                     // prevent arrays trying to be printed as a string
                     if (is_array($val)) {
                         $val = "";
                         \Log::error("Cannot display tag `" . $data_matches[0][$index] . "` because it is a list, not a single value. To display list values, use a tag-pair.", "template", "parser");
                     }
                     // <statamic>
                     // if variable is in the no-parse list, extract it
                     // handles the very-special |noparse modifier
                     if ($var_pipe !== false && in_array('noparse', array_slice(explode('|', $var), 1)) || in_array($var_name, $noparse)) {
                         $text = $this->createExtraction('noparse', $data_matches[0][$index], $val, $text);
                     } else {
                         // </statamic>
                         $text = str_replace($data_matches[0][$index], $val, $text);
                         // <statamic>
                     }
                     break;
                 }
             }
         }
         // </statamic>
     }
     // <statamic>
     // we need to look for parameters on plain-old non-callback variable tags
     // right now, this only applies to `format` parameters for dates
     $regex = '/\\{\\{\\s*(' . $this->variableRegex . ')(\\s+.*?)?\\s*\\}\\}/ms';
     if (preg_match_all($regex, $text, $data_matches, PREG_SET_ORDER + PREG_OFFSET_CAPTURE)) {
         foreach ($data_matches as $match) {
             // grab some starting values & init variables
             $parameters = array();
             $tag = $match[0][0];
             $name = $match[1][0];
             // is this not the content tag, and is the value known?
             if ($name != 'content' && isset($data[$name])) {
                 // it is, are there parameters?
                 if (isset($match[2])) {
                     // there are, make a backup of our $data
                     $cb_data = $data;
                     // is $data an array?
                     if (is_array($data)) {
                         // it is, have we had callback data before?
                         if (!empty(self::$callbackData)) {
                             // we have, merge it all together
                             $cb_data = $data + self::$callbackData;
                         }
                         // grab the raw string of parameters
                         $raw_params = $this->injectExtractions($match[2][0], '__cond_str');
                         // parse them into an array
                         $parameters = $this->parseParameters($raw_params, $cb_data, $callback);
                     } elseif (is_string($data)) {
                         $text = str_replace($tag, $data, $text);
                     }
                 }
                 // check for certain parameters and do what they should do
                 if (isset($parameters['format'])) {
                     $text = str_replace($tag, \Date::format($parameters['format'], $data[$name]), $text);
                 }
             }
         }
     }
     // </statamic>
     return $text;
 }
 /**
  * Parse the error messages out of a fieldset config
  * 
  * @param $fields  array  List of fields with their configurations
  * @return array
  */
 public static function getErrorMessages($fields)
 {
     $fields = Helper::ensureArray($fields);
     $rules = array();
     foreach ($fields as $field => $options) {
         $rules[$field] = $messages = array_get($options, 'error_messages', null);
     }
     return $rules;
 }
 /**
  * Supplements a list of results with first, last, count, and total_results
  *
  * @param array  $output  The data array to supplement
  * @param array  $other_data  Other data to add to each record
  * @return mixed
  */
 public function supplement($output, $other_data = array())
 {
     $i = 1;
     $length = count($output);
     $other_data = Helper::ensureArray($other_data);
     foreach ($output as $key => $item) {
         $stats = array('first' => $i === 1, 'last' => $i === $length, 'count' => $i, 'total_results' => $length);
         $output[$key] = $other_data + $stats + $item;
         $i++;
     }
     return $output;
 }