Example #1
0
 protected function checkSecurityToken()
 {
     /** @var Request $request */
     $request = $this->container['request'];
     $nonce = $request->get->get('nonce');
     return isset($nonce) && Utils::verifyNonce($nonce, 'gantry-admin');
 }
Example #2
0
 /**
  * Save a group
  */
 public function save()
 {
     $blueprints = new Blueprints('blueprints://');
     $blueprint = $blueprints->get('user/group');
     $fields = $blueprint->fields();
     self::getGrav()['config']->set("groups.{$this->groupname}", []);
     foreach ($fields as $field) {
         if ($field['type'] == 'text') {
             $value = $field['name'];
             if (isset($this->items[$value])) {
                 self::getGrav()['config']->set("groups.{$this->groupname}.{$value}", $this->items[$value]);
             }
         }
         if ($field['type'] == 'array') {
             $value = $field['name'];
             $arrayValues = Utils::resolve($this->items, $field['name']);
             if ($arrayValues) {
                 foreach ($arrayValues as $arrayIndex => $arrayValue) {
                     self::getGrav()['config']->set("groups.{$this->groupname}.{$value}.{$arrayIndex}", $arrayValue);
                 }
             }
         }
     }
     $type = 'groups';
     $blueprints = $this->blueprints("config/{$type}");
     $obj = new Data(self::getGrav()['config']->get($type), $blueprints);
     $file = CompiledYamlFile::instance(self::getGrav()['locator']->findResource("config://{$type}.yaml"));
     $obj->file($file);
     $obj->save();
 }
 public function init()
 {
     $this->shortcode->getHandlers()->add('fa', function (ShortcodeInterface $sc) {
         // Load assets if required
         if ($this->config->get('plugins.shortcode-core.fontawesome.load', false)) {
             $this->shortcode->addAssets('css', $this->config->get('plugins.shortcode-core.fontawesome.url'));
         }
         // Get shortcode content and parameters
         $str = $sc->getContent();
         $icon = $sc->getParameter('icon', false);
         if (!$icon) {
             $icon = $sc->getParameter('fa', trim($sc->getParameterAt(0), '='));
         }
         if (!Utils::startsWith($icon, 'fa-')) {
             $icon = 'fa-' . $icon;
         }
         $extras = explode(',', $sc->getParameter('extras', ''));
         foreach ($extras as $extra) {
             if (!Utils::startsWith($extra, 'fa-')) {
                 $extra = 'fa-' . $extra;
             }
             $icon .= ' ' . $extra;
         }
         $output = '<i class="fa ' . $icon . '">' . $str . '</i>';
         return $output;
     });
 }
Example #4
0
 /**
  * If the admin path matches, initialize the Login plugin configuration and set the admin
  * as active.
  */
 public function setup()
 {
     // Autoloader
     spl_autoload_register(function ($class) {
         if (Utils::startsWith($class, 'Grav\\Plugin\\Admin')) {
             require_once __DIR__ . '/classes/' . strtolower(basename(str_replace("\\", "/", $class))) . '.php';
         }
     });
     $route = $this->config->get('plugins.admin.route');
     if (!$route) {
         return;
     }
     $this->base = '/' . trim($route, '/');
     $this->admin_route = rtrim($this->grav['pages']->base(), '/') . $this->base;
     $this->uri = $this->grav['uri'];
     // check for existence of a user account
     $account_dir = $file_path = $this->grav['locator']->findResource('account://');
     $user_check = glob($account_dir . '/*.yaml');
     // If no users found, go to register
     if ($user_check == false || count((array) $user_check) == 0) {
         if (!$this->isAdminPath()) {
             $this->grav->redirect($this->admin_route);
         }
         $this->template = 'register';
     }
     // Only activate admin if we're inside the admin path.
     if ($this->isAdminPath()) {
         $this->active = true;
         // Set cache based on admin_cache option
         if (method_exists($this->grav['cache'], 'setEnabled')) {
             $this->grav['cache']->setEnabled($this->config->get('plugins.admin.cache_enabled'));
         }
     }
 }
Example #5
0
 /**
  * Makes a request to the URL by using the preferred method
  * @param  string $uri URL to call
  * @param  array $options An array of parameters for both `curl` and `fopen`
  * @param  callable $callback Either a function or callback in array notation
  * @return string The response of the request
  */
 public static function get($uri = '', $options = [], $callback = null)
 {
     if (!self::isCurlAvailable() && !self::isFopenAvailable()) {
         throw new \RuntimeException('Could not start an HTTP request. `allow_url_open` is disabled and `cURL` is not available');
     }
     // disable time limit if possible to help with slow downloads
     if (!Utils::isFunctionDisabled('set_time_limit') && !ini_get('safe_mode')) {
         set_time_limit(0);
     }
     $options = array_replace_recursive(self::$defaults, $options);
     $method = 'get' . ucfirst(strtolower(self::$method));
     self::$callback = $callback;
     return static::$method($uri, $options, $callback);
 }
 private function getContents($fn)
 {
     if (Utils::startswith($fn, 'data:')) {
         $path = $this->grav['locator']->findResource('user://data', true);
         $fn = ltrim($fn, 'data:');
     } else {
         $path = $this->grav['page']->path();
     }
     $path = $path . DS . $fn;
     if (file_exists($path)) {
         return file_get_contents($path);
     }
     return null;
 }
Example #7
0
 /**
  * Makes a request to the URL by using the preferred method
  *
  * @param  string   $uri      URL to call
  * @param  array    $options  An array of parameters for both `curl` and `fopen`
  * @param  callable $callback Either a function or callback in array notation
  *
  * @return string The response of the request
  */
 public static function get($uri = '', $options = [], $callback = null)
 {
     if (!self::isCurlAvailable() && !self::isFopenAvailable()) {
         throw new \RuntimeException('Could not start an HTTP request. `allow_url_open` is disabled and `cURL` is not available');
     }
     // check if this function is available, if so use it to stop any timeouts
     try {
         if (!Utils::isFunctionDisabled('set_time_limit') && !ini_get('safe_mode') && function_exists('set_time_limit')) {
             set_time_limit(0);
         }
     } catch (\Exception $e) {
     }
     $options = array_replace_recursive(self::$defaults, $options);
     $method = 'get' . ucfirst(strtolower(self::$method));
     self::$callback = $callback;
     return static::$method($uri, $options, $callback);
 }
 public function filecontent($path)
 {
     $path_info = pathinfo($path);
     $config = Grav::instance()['config']->get('plugins.file-content');
     if (in_array($path_info['extension'], $config['allowed_extensions'])) {
         if (Utils::startsWith($path, '/')) {
             if ($config['allow_in_grav'] && file_exists(GRAV_ROOT . $path)) {
                 return file_get_contents(GRAV_ROOT . $path);
             } elseif ($config['allow_in_filesystem'] && file_exists($path)) {
                 return file_get_contents($path);
             }
         } else {
             $page_path = Grav::instance()['page']->path() . '/' . $path;
             if ($config['allow_in_page'] && file_exists($page_path)) {
                 return file_get_contents($page_path);
             }
         }
     }
     return $path;
 }
 public function init()
 {
     $this->shortcode->getHandlers()->add('ui-animated-text', function (ShortcodeInterface $sc) {
         // Add assets
         $this->shortcode->addAssets('css', 'plugin://shortcode-ui/css/ui-atext.css');
         $this->shortcode->addAssets('js', 'plugin://shortcode-ui/js/ui-atext.js');
         $content = $sc->getContent();
         $animation = $sc->getParameter('animation', 'rotate-1');
         $words = $sc->getParameter('words', 'cool, funky, fresh');
         $visible = $sc->getParameter('visible', 1);
         if (Utils::contains($content, '%WORDS%')) {
             $content = explode('%WORDS%', $content);
         } else {
             $content = (array) $content;
         }
         if (intval($visible) > count($words)) {
             $visible = 1;
         }
         $output = $this->twig->processTemplate('partials/ui-atext.html.twig', ['content' => $content, 'words' => explode(',', $words), 'animation' => $animation, 'element' => $sc->getParameter('element', 'h1'), 'wrapper_extra' => Utils::contains($animation, 'type') ? ' waiting' : '', 'visible' => $visible]);
         return $output;
     });
 }
Example #10
0
 /**
  * @return int|null|void
  */
 protected function serve()
 {
     $this->options = $this->input->getOptions();
     $this->gpm = new GPM($this->options['force']);
     $this->displayGPMRelease();
     $this->data = $this->gpm->getRepository();
     $data = $this->filter($this->data);
     $climate = new CLImate();
     $climate->extend('Grav\\Console\\TerminalObjects\\Table');
     if (!$data) {
         $this->output->writeln('No data was found in the GPM repository stored locally.');
         $this->output->writeln('Please try clearing cache and running the <green>bin/gpm index -f</green> command again');
         $this->output->writeln('If this doesn\'t work try tweaking your GPM system settings.');
         $this->output->writeln('');
         $this->output->writeln('For more help go to:');
         $this->output->writeln(' -> <yellow>https://learn.getgrav.org/troubleshooting/common-problems#cannot-connect-to-the-gpm</yellow>');
         die;
     }
     foreach ($data as $type => $packages) {
         $this->output->writeln("<green>" . strtoupper($type) . "</green> [ " . count($packages) . " ]");
         $packages = $this->sort($packages);
         if (!empty($packages)) {
             $table = [];
             $index = 0;
             foreach ($packages as $slug => $package) {
                 $row = ['Count' => $index++ + 1, 'Name' => "<cyan>" . Utils::truncate($package->name, 20, false, ' ', '...') . "</cyan> ", 'Slug' => $slug, 'Version' => $this->version($package), 'Installed' => $this->installed($package)];
                 $table[] = $row;
             }
             $climate->table($table);
         }
         $this->output->writeln('');
     }
     $this->output->writeln('You can either get more informations about a package by typing:');
     $this->output->writeln('    <green>' . $this->argv . ' info <cyan><package></cyan></green>');
     $this->output->writeln('');
     $this->output->writeln('Or you can install a package by typing:');
     $this->output->writeln('    <green>' . $this->argv . ' install <cyan><package></cyan></green>');
     $this->output->writeln('');
 }
Example #11
0
 /**
  * Makes a request to the URL by using the preferred method
  *
  * @param  string   $uri      URL to call
  * @param  array    $options  An array of parameters for both `curl` and `fopen`
  * @param  callable $callback Either a function or callback in array notation
  *
  * @return string The response of the request
  */
 public static function get($uri = '', $options = [], $callback = null)
 {
     if (!self::isCurlAvailable() && !self::isFopenAvailable()) {
         throw new \RuntimeException('Could not start an HTTP request. `allow_url_open` is disabled and `cURL` is not available');
     }
     // check if this function is available, if so use it to stop any timeouts
     try {
         if (!Utils::isFunctionDisabled('set_time_limit') && !ini_get('safe_mode') && function_exists('set_time_limit')) {
             set_time_limit(0);
         }
     } catch (\Exception $e) {
     }
     $config = Grav::instance()['config'];
     $overrides = [];
     // SSL Verify Peer and Proxy Setting
     $settings = ['method' => $config->get('system.gpm.method', self::$method), 'verify_peer' => $config->get('system.gpm.verify_peer', true), 'proxy_url' => $config->get('system.gpm.proxy_url', $config->get('system.proxy_url', false))];
     if (!$settings['verify_peer']) {
         $overrides = array_replace_recursive([], $overrides, ['curl' => [CURLOPT_SSL_VERIFYPEER => $settings['verify_peer']], 'fopen' => ['ssl' => ['verify_peer' => $settings['verify_peer'], 'verify_peer_name' => $settings['verify_peer']]]]);
     }
     // Proxy Setting
     if ($settings['proxy_url']) {
         $proxy = parse_url($settings['proxy_url']);
         $fopen_proxy = ($proxy['scheme'] ?: 'http') . '://' . $proxy['host'] . (isset($proxy['port']) ? ':' . $proxy['port'] : '');
         $overrides = array_replace_recursive([], $overrides, ['curl' => [CURLOPT_PROXY => $proxy['host'], CURLOPT_PROXYTYPE => 'HTTP'], 'fopen' => ['proxy' => $fopen_proxy, 'request_fulluri' => true]]);
         if (isset($proxy['port'])) {
             $overrides['curl'][CURLOPT_PROXYPORT] = $proxy['port'];
         }
         if (isset($proxy['user']) && isset($proxy['pass'])) {
             $fopen_auth = $auth = base64_encode($proxy['user'] . ':' . $proxy['pass']);
             $overrides['curl'][CURLOPT_PROXYUSERPWD] = $proxy['user'] . ':' . $proxy['pass'];
             $overrides['fopen']['header'] = "Proxy-Authorization: Basic {$fopen_auth}";
         }
     }
     $options = array_replace_recursive(self::$defaults, $options, $overrides);
     $method = 'get' . ucfirst(strtolower($settings['method']));
     self::$callback = $callback;
     return static::$method($uri, $options, $callback);
 }
Example #12
0
 /**
  * Handle the email to activate the user account.
  *
  * @return bool True if the action was performed.
  */
 protected function sendActivationEmail($user)
 {
     if (empty($user->email)) {
         throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.USER_NEEDS_EMAIL_FIELD'));
     }
     $token = md5(uniqid(mt_rand(), true));
     $expire = time() + 604800;
     // next week
     $user->activation_token = $token . '::' . $expire;
     $user->save();
     $param_sep = $this->grav['config']->get('system.param_sep', ':');
     $activation_link = $this->grav['base_url_absolute'] . $this->config->get('plugins.login.route_activate') . '/token' . $param_sep . $token . '/username' . $param_sep . $user->username . '/nonce' . $param_sep . Utils::getNonce('user-activation');
     $sitename = $this->grav['config']->get('site.title', 'Website');
     $subject = $this->grav['language']->translate(['PLUGIN_LOGIN.ACTIVATION_EMAIL_SUBJECT', $sitename]);
     $content = $this->grav['language']->translate(['PLUGIN_LOGIN.ACTIVATION_EMAIL_BODY', $user->username, $activation_link, $sitename]);
     $to = $user->email;
     $sent = LoginUtils::sendEmail($subject, $content, $to);
     if ($sent < 1) {
         throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.EMAIL_SENDING_FAILURE'));
     }
     return true;
 }
Example #13
0
 /**
  * Recursive function to load & build page relationships.
  *
  * @param string $directory
  * @param Page|null $parent
  * @return Page
  * @throws \RuntimeException
  * @internal
  */
 protected function recurse($directory, Page &$parent = null)
 {
     $directory = rtrim($directory, DS);
     $page = new Page();
     /** @var Config $config */
     $config = $this->grav['config'];
     /** @var Language $language */
     $language = $this->grav['language'];
     // stuff to do at root page
     if ($parent === null) {
         // Fire event for memory and time consuming plugins...
         if ($config->get('system.pages.events.page')) {
             $this->grav->fireEvent('onBuildPagesInitialized');
         }
     }
     $page->path($directory);
     if ($parent) {
         $page->parent($parent);
     }
     $page->orderDir($config->get('system.pages.order.dir'));
     $page->orderBy($config->get('system.pages.order.by'));
     // Add into instances
     if (!isset($this->instances[$page->path()])) {
         $this->instances[$page->path()] = $page;
         if ($parent && $page->path()) {
             $this->children[$parent->path()][$page->path()] = array('slug' => $page->slug());
         }
     } else {
         throw new \RuntimeException('Fatal error when creating page instances.');
     }
     $content_exists = false;
     $pages_found = glob($directory . '/*' . CONTENT_EXT);
     $page_extensions = $language->getFallbackPageExtensions();
     if ($pages_found) {
         foreach ($page_extensions as $extension) {
             foreach ($pages_found as $found) {
                 if (preg_match('/^.*\\/[0-9A-Za-z\\-\\_]+(' . $extension . ')$/', $found)) {
                     $page_found = $found;
                     $page_extension = $extension;
                     break 2;
                 }
             }
         }
     }
     if ($parent && !empty($page_found)) {
         $file = new \SplFileInfo($page_found);
         $page->init($file, $page_extension);
         $content_exists = true;
         if ($config->get('system.pages.events.page')) {
             $this->grav->fireEvent('onPageProcessed', new Event(['page' => $page]));
         }
     }
     // set current modified of page
     $last_modified = $page->modified();
     /** @var \DirectoryIterator $file */
     foreach (new \FilesystemIterator($directory) as $file) {
         $name = $file->getFilename();
         // Ignore all hidden files if set.
         if ($this->ignore_hidden) {
             if ($name && $name[0] == '.') {
                 continue;
             }
         }
         if ($file->isFile()) {
             // Update the last modified if it's newer than already found
             if (!in_array($file->getBasename(), $this->ignore_files) && ($modified = $file->getMTime()) > $last_modified) {
                 $last_modified = $modified;
             }
         } elseif ($file->isDir() && !in_array($file->getFilename(), $this->ignore_folders)) {
             if (!$page->path()) {
                 $page->path($file->getPath());
             }
             $path = $directory . DS . $name;
             $child = $this->recurse($path, $page);
             if (Utils::startsWith($name, '_')) {
                 $child->routable(false);
             }
             $this->children[$page->path()][$child->path()] = array('slug' => $child->slug());
             if ($config->get('system.pages.events.page')) {
                 $this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page]));
             }
         }
     }
     // Set routability to false if no page found
     if (!$content_exists) {
         $page->routable(false);
     }
     // Override the modified and ID so that it takes the latest change into account
     $page->modified($last_modified);
     $page->id($last_modified . md5($page->filePath()));
     // Sort based on Defaults or Page Overridden sort order
     $this->children[$page->path()] = $this->sort($page);
     return $page;
 }
Example #14
0
 /**
  * Provides the ability to download a file to the browser
  *
  * @param      $file            the full path to the file to be downloaded
  * @param bool $force_download  as opposed to letting browser choose if to download or render
  */
 public static function download($file, $force_download = true)
 {
     if (file_exists($file)) {
         // fire download event
         self::getGrav()->fireEvent('onBeforeDownload', new Event(['file' => $file]));
         $file_parts = pathinfo($file);
         $filesize = filesize($file);
         // check if this function is available, if so use it to stop any timeouts
         if (function_exists('set_time_limit')) {
             set_time_limit(0);
         }
         ignore_user_abort(false);
         if ($force_download) {
             header('Content-Description: File Transfer');
             header('Content-Type: application/octet-stream');
             header('Content-Disposition: attachment; filename=' . $file_parts['basename']);
             header('Content-Transfer-Encoding: binary');
             header('Expires: 0');
             header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
             header('Pragma: public');
         } else {
             header("Content-Type: " . Utils::getMimeType($file_parts['extension']));
         }
         header('Content-Length: ' . $filesize);
         // 8kb chunks for now
         $chunk = 8 * 1024;
         $fh = fopen($file, "rb");
         if ($fh === false) {
             return;
         }
         // Repeat reading until EOF
         while (!feof($fh)) {
             echo fread($fh, $chunk);
             ob_flush();
             // flush output
             flush();
         }
         exit;
     }
 }
Example #15
0
File: GPM.php Project: re-pe/grav
 /**
  * Searches for a list of Packages in the repository
  * @param  array $searches An array of either slugs or names
  * @return array Array of found Packages
  *                        Format: ['total' => int, 'not_found' => array, <found-slugs>]
  */
 public function findPackages($searches = [])
 {
     $packages = ['total' => 0, 'not_found' => []];
     foreach ($searches as $search) {
         $repository = '';
         // if this is an object, get the search data from the key
         if (is_object($search)) {
             $search = (array) $search;
             $key = key($search);
             $repository = $search[$key];
             $search = $key;
         }
         if ($found = $this->findPackage($search)) {
             // set override respository if provided
             if ($repository) {
                 $found->override_repository = $repository;
             }
             if (!isset($packages[$found->package_type])) {
                 $packages[$found->package_type] = [];
             }
             $packages[$found->package_type][$found->slug] = $found;
             $packages['total']++;
         } else {
             // make a best guess at the type based on the repo URL
             if (Utils::contains($repository, '-theme')) {
                 $type = 'themes';
             } else {
                 $type = 'plugins';
             }
             $not_found = new \stdClass();
             $not_found->name = Inflector::camelize($search);
             $not_found->slug = $search;
             $not_found->package_type = $type;
             $not_found->install_path = str_replace('%name%', $search, $this->install_paths[$type]);
             $not_found->override_repository = $repository;
             $packages['not_found'][$search] = $not_found;
         }
     }
     return $packages;
 }
Example #16
0
 /**
  * Return URL to image.
  *
  * @param bool $reset
  * @return string
  */
 public function url($reset = true)
 {
     $image_path = self::$grav['locator']->findResource('cache://images', true);
     $image_dir = self::$grav['locator']->findResource('cache://images', false);
     $saved_image_path = $this->saveImage();
     $output = preg_replace('|^' . preg_quote(GRAV_ROOT) . '|', '', $saved_image_path);
     if (Utils::startsWith($output, $image_path)) {
         $output = '/' . $image_dir . preg_replace('|^' . preg_quote($image_path) . '|', '', $output);
     }
     if ($reset) {
         $this->reset();
     }
     return self::$grav['base_url'] . $output . $this->querystring() . $this->urlHash();
 }
 /**
  * Build search results.
  */
 public function onPagesInitialized()
 {
     $page = $this->grav['page'];
     // If a page exists merge the configs
     if ($page) {
         $this->config->set('plugins.simplesearch', $this->mergeConfig($page));
     }
     /** @var Uri $uri */
     $uri = $this->grav['uri'];
     $query = $uri->param('query') ?: $uri->query('query');
     $route = $this->config->get('plugins.simplesearch.route');
     // performance check
     if ($route && $query && $route == $uri->path()) {
         $this->enable(['onTwigSiteVariables' => ['onTwigSiteVariables', 0]]);
     } else {
         return;
     }
     $this->query = explode(',', $query);
     /** @var Taxonomy $taxonomy_map */
     $taxonomy_map = $this->grav['taxonomy'];
     $taxonomies = [];
     $filters = (array) $this->config->get('plugins.simplesearch.filters');
     $operator = $this->config->get('plugins.simplesearch.filter_combinator', 'and');
     // see if the filter uses the new 'items-type' syntax
     $new_approach = false;
     foreach ($filters as $filter) {
         $filter_saved = $filter;
         if (is_array($filter)) {
             $filter = key($filter);
         }
         if (Utils::startsWith($filter, '@')) {
             if ($filter == '@self') {
                 $new_approach = true;
             }
             if ($filter == '@taxonomy') {
                 $taxonomies = $filter_saved[$filter];
             }
         }
     }
     if ($new_approach) {
         $params = $page->header()->content;
         $params['query'] = $this->config->get('plugins.simplesearch.query');
         $this->collection = $page->collection($params, false);
     } else {
         $this->collection = new Collection();
         $this->collection->append($taxonomy_map->findTaxonomy($filters, $operator)->toArray());
     }
     $extras = [];
     /** @var Page $cpage */
     foreach ($this->collection as $cpage) {
         foreach ($this->query as $query) {
             $query = trim($query);
             $taxonomy_match = false;
             if (!empty($taxonomies)) {
                 $page_taxonomies = $cpage->taxonomy();
                 foreach ((array) $taxonomies as $taxonomy) {
                     if (array_key_exists($taxonomy, $page_taxonomies)) {
                         $taxonomy_values = implode('|', $page_taxonomies[$taxonomy]);
                         if (stripos($taxonomy_values, $query) !== false) {
                             $taxonomy_match = true;
                             break;
                         }
                     }
                 }
             }
             if ($taxonomy_match === false && stripos($cpage->content(), $query) === false && stripos($cpage->title(), $query) === false) {
                 $this->collection->remove($cpage);
                 continue;
             }
             if ($cpage->modular()) {
                 $this->collection->remove($cpage);
                 $parent = $cpage->parent();
                 $extras[$parent->path()] = ['slug' => $parent->slug()];
             }
         }
     }
     if (!empty($extras)) {
         $this->collection->append($extras);
     }
     // use a configured sorting order if not already done
     if (!$new_approach) {
         $this->collection = $this->collection->order($this->config->get('plugins.simplesearch.order.by'), $this->config->get('plugins.simplesearch.order.dir'));
     }
     // if page doesn't have settings set, create a page
     if (!isset($page->header()->simplesearch)) {
         // create the search page
         $page = new Page();
         $page->init(new \SplFileInfo(__DIR__ . '/pages/simplesearch.md'));
         // override the template is set in the config
         $template_override = $this->config->get('plugins.simplesearch.template');
         if ($template_override) {
             $page->template($template_override);
         }
         // fix RuntimeException: Cannot override frozen service "page" issue
         unset($this->grav['page']);
         $this->grav['page'] = $page;
     }
 }
 /**
  * Handle the email password recovery procedure.
  *
  * @return bool True if the action was performed.
  */
 protected function taskForgot()
 {
     $param_sep = $this->grav['config']->get('system.param_sep', ':');
     $data = $this->post;
     $username = isset($data['username']) ? $data['username'] : '';
     $user = !empty($username) ? User::load($username) : null;
     /** @var Language $l */
     $language = $this->grav['language'];
     $messages = $this->grav['messages'];
     if (!isset($this->grav['Email'])) {
         $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error');
         $this->setRedirect('/');
         return true;
     }
     if (!$user || !$user->exists()) {
         $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_USERNAME_DOES_NOT_EXIST', $username]), 'error');
         $this->setRedirect('/forgot');
         return true;
     }
     if (empty($user->email)) {
         $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL', $username]), 'error');
         $this->setRedirect('/forgot');
         return true;
     }
     $token = md5(uniqid(mt_rand(), true));
     $expire = time() + 604800;
     // next week
     $user->reset = $token . '::' . $expire;
     $user->save();
     $author = $this->grav['config']->get('site.author.name', '');
     $fullname = $user->fullname ?: $username;
     $reset_link = $this->grav['base_url_absolute'] . $this->grav['config']->get('plugins.login.route_reset') . '/task:login.reset/token' . $param_sep . $token . '/user' . $param_sep . $username . '/nonce' . $param_sep . Utils::getNonce('reset-form');
     $sitename = $this->grav['config']->get('site.title', 'Website');
     $from = $this->grav['config']->get('plugins.email.from');
     if (empty($from)) {
         $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error');
         $this->setRedirect('/forgot');
         return true;
     }
     $to = $user->email;
     $subject = $language->translate(['PLUGIN_ADMIN.FORGOT_EMAIL_SUBJECT', $sitename]);
     $content = $language->translate(['PLUGIN_ADMIN.FORGOT_EMAIL_BODY', $fullname, $reset_link, $author, $sitename]);
     $sent = LoginUtils::sendEmail($subject, $content, $to);
     if ($sent < 1) {
         $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_FAILED_TO_EMAIL'), 'error');
     } else {
         $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL', $to]), 'info');
     }
     $this->setRedirect('/');
     return true;
 }
Example #19
0
 /**
  * Finds relative CSS urls() and rewrites the URL with an absolute one
  *
  * @param $file                 the css source file
  * @param $relative_path        relative path to the css file
  *
  * @return mixed
  */
 protected function cssRewrite($file, $relative_path)
 {
     // Strip any sourcemap comments
     $file = preg_replace(self::CSS_SOURCEMAP_REGEX, '', $file);
     // Find any css url() elements, grab the URLs and calculate an absolute path
     // Then replace the old url with the new one
     $file = preg_replace_callback(self::CSS_URL_REGEX, function ($matches) use($relative_path) {
         $old_url = $matches[1];
         // ensure this is not a data url
         if (strpos($old_url, 'data:') === 0) {
             return $matches[0];
         }
         $new_url = $this->base_url . ltrim(Utils::normalizePath($relative_path . '/' . $old_url), '/');
         return str_replace($old_url, $new_url, $matches[0]);
     }, $file);
     return $file;
 }
Example #20
0
 /**
  * Used to add a nonce to a form. Call {{ nonce_field('action') }} specifying a string representing the action.
  *
  * For maximum protection, ensure that the string representing the action is as specific as possible.
  *
  * @todo evaluate if adding referrer or not
  *
  * @param string action         the action
  * @param string nonceParamName a custom nonce param name
  *
  * @return string the nonce input field
  */
 public function nonceFieldFunc($action, $nonceParamName = 'nonce')
 {
     $string = '<input type="hidden" id="' . $nonceParamName . '" name="' . $nonceParamName . '" value="' . Utils::getNonce($action) . '" />';
     return $string;
 }
Example #21
0
 /**
  * Gets and sets the date for this Page object. This is typically passed in via the page headers
  *
  * @param  string $var string representation of a date
  * @return int         unix timestamp representation of the date
  */
 public function date($var = null)
 {
     if ($var !== null) {
         $this->date = Utils::date2timestamp($var);
     }
     if (!$this->date) {
         $this->date = $this->modified;
     }
     return $this->date;
 }
Example #22
0
 /**
  * Recursive function to load & build page relationships.
  *
  * @param string $directory
  * @param Page|null $parent
  * @return Page
  * @throws \RuntimeException
  * @internal
  */
 protected function recurse($directory, Page &$parent = null)
 {
     $directory = rtrim($directory, DS);
     $iterator = new \DirectoryIterator($directory);
     $page = new Page();
     /** @var Config $config */
     $config = $this->grav['config'];
     $page->path($directory);
     if ($parent) {
         $page->parent($parent);
     }
     $page->orderDir($config->get('system.pages.order.dir'));
     $page->orderBy($config->get('system.pages.order.by'));
     // Add into instances
     if (!isset($this->instances[$page->path()])) {
         $this->instances[$page->path()] = $page;
         if ($parent && $page->path()) {
             $this->children[$parent->path()][$page->path()] = array('slug' => $page->slug());
         }
     } else {
         throw new \RuntimeException('Fatal error when creating page instances.');
     }
     // set current modified of page
     $last_modified = $page->modified();
     // flat for content availability
     $content_exists = false;
     /** @var \DirectoryIterator $file */
     foreach ($iterator as $file) {
         if ($file->isDot()) {
             continue;
         }
         $name = $file->getFilename();
         if ($file->isFile()) {
             // Update the last modified if it's newer than already found
             if ($file->getBasename() !== '.DS_Store' && ($modified = $file->getMTime()) > $last_modified) {
                 $last_modified = $modified;
             }
             if (preg_match('/^[^.].*' . CONTENT_EXT . '$/', $name)) {
                 $page->init($file);
                 $content_exists = true;
                 if ($config->get('system.pages.events.page')) {
                     $this->grav->fireEvent('onPageProcessed', new Event(['page' => $page]));
                 }
             }
         } elseif ($file->isDir()) {
             if (!$page->path()) {
                 $page->path($file->getPath());
             }
             $path = $directory . DS . $name;
             $child = $this->recurse($path, $page);
             if (Utils::startsWith($name, '_')) {
                 $child->routable(false);
             }
             $this->children[$page->path()][$child->path()] = array('slug' => $child->slug());
             if ($config->get('system.pages.events.page')) {
                 $this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page]));
             }
         }
     }
     // Set routability to false if no page found
     if (!$content_exists) {
         $page->routable(false);
     }
     // Override the modified and ID so that it takes the latest change into account
     $page->modified($last_modified);
     $page->id($last_modified . md5($page->filePath()));
     // Sort based on Defaults or Page Overridden sort order
     $this->children[$page->path()] = $this->sort($page);
     return $page;
 }
Example #23
0
 /**
  * Process an image excerpt
  *
  * @param $excerpt
  * @param $page
  * @return mixed
  */
 public static function processImageExcerpt($excerpt, $page)
 {
     $url = $excerpt['element']['attributes']['src'];
     $url_parts = parse_url(htmlspecialchars_decode(urldecode($url)));
     if (isset($url_parts['scheme']) && !Utils::startsWith($url_parts['scheme'], 'http')) {
         $stream_path = $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path'];
         $url_parts['path'] = $stream_path;
         unset($url_parts['host']);
         unset($url_parts['scheme']);
     }
     $this_host = isset($url_parts['host']) && $url_parts['host'] == Grav::instance()['uri']->host();
     // if there is no host set but there is a path, the file is local
     if ((!isset($url_parts['host']) || $this_host) && isset($url_parts['path'])) {
         $path_parts = pathinfo($url_parts['path']);
         $media = null;
         // get the local path to page media if possible
         if ($path_parts['dirname'] == $page->url(false, false, false)) {
             // get the media objects for this page
             $media = $page->media();
         } else {
             // see if this is an external page to this one
             $base_url = rtrim(Grav::instance()['base_url_relative'] . Grav::instance()['pages']->base(), '/');
             $page_route = '/' . ltrim(str_replace($base_url, '', $path_parts['dirname']), '/');
             $ext_page = Grav::instance()['pages']->dispatch($page_route, true);
             if ($ext_page) {
                 $media = $ext_page->media();
             } else {
                 Grav::instance()->fireEvent('onMediaLocate', new Event(['route' => $page_route, 'media' => &$media]));
             }
         }
         // if there is a media file that matches the path referenced..
         if ($media && isset($media->all()[$path_parts['basename']])) {
             // get the medium object
             /** @var Medium $medium */
             $medium = $media->all()[$path_parts['basename']];
             // Process operations
             $medium = static::processMediaActions($medium, $url_parts);
             $alt = isset($excerpt['element']['attributes']['alt']) ? $excerpt['element']['attributes']['alt'] : '';
             $title = isset($excerpt['element']['attributes']['title']) ? $excerpt['element']['attributes']['title'] : '';
             $class = isset($excerpt['element']['attributes']['class']) ? $excerpt['element']['attributes']['class'] : '';
             $id = isset($excerpt['element']['attributes']['id']) ? $excerpt['element']['attributes']['id'] : '';
             $excerpt['element'] = $medium->parseDownElement($title, $alt, $class, $id, true);
         } else {
             // not a current page media file, see if it needs converting to relative
             $excerpt['element']['attributes']['src'] = Uri::buildUrl($url_parts);
         }
     }
     return $excerpt;
 }
 /**
  * @param $package
  *
  * @return bool|string
  */
 private function getSymlinkSource($package)
 {
     $matches = $this->getGitRegexMatches($package);
     foreach ($this->local_config as $path) {
         if (Utils::endsWith($matches[2], '.git')) {
             $repo_dir = preg_replace('/\\.git$/', '', $matches[2]);
         } else {
             $repo_dir = $matches[2];
         }
         $from = rtrim($path, '/') . '/' . $repo_dir;
         if (file_exists($from)) {
             return $from;
         }
     }
     return false;
 }
Example #25
0
 /**
  * Handle form processing instructions.
  *
  * @param Event $event
  */
 public function onFormProcessed(Event $event)
 {
     $form = $event['form'];
     $action = $event['action'];
     $params = $event['params'];
     $this->process($form);
     switch ($action) {
         case 'captcha':
             if (isset($params['recaptcha_secret'])) {
                 $recaptchaSecret = $params['recaptcha_secret'];
             } else {
                 if (isset($params['recatpcha_secret'])) {
                     // Included for backwards compatibility with typo (issue #51)
                     $recaptchaSecret = $params['recatpcha_secret'];
                 } else {
                     $recaptchaSecret = $this->config->get('plugins.form.recaptcha.secret_key');
                 }
             }
             // Validate the captcha
             $query = http_build_query(['secret' => $recaptchaSecret, 'response' => $form->value('g-recaptcha-response', true)]);
             $url = 'https://www.google.com/recaptcha/api/siteverify?' . $query;
             $response = json_decode(file_get_contents($url), true);
             if (!isset($response['success']) || $response['success'] !== true) {
                 $this->grav->fireEvent('onFormValidationError', new Event(['form' => $form, 'message' => $this->grav['language']->translate('PLUGIN_FORM.ERROR_VALIDATING_CAPTCHA')]));
                 $event->stopPropagation();
                 return;
             }
             break;
         case 'ip':
             $label = isset($params['label']) ? $params['label'] : 'User IP';
             $blueprint = $form->value()->blueprints();
             $blueprint->set('form/fields/ip', ['name' => 'ip', 'label' => $label]);
             $form->setFields($blueprint->fields());
             $form->setData('ip', Uri::ip());
             break;
         case 'message':
             $translated_string = $this->grav['language']->translate($params);
             $vars = array('form' => $form);
             /** @var Twig $twig */
             $twig = $this->grav['twig'];
             $processed_string = $twig->processString($translated_string, $vars);
             $form->message = $processed_string;
             break;
         case 'redirect':
             $this->grav['session']->setFlashObject('form', $form);
             $this->grav->redirect((string) $params);
             break;
         case 'reset':
             if (Utils::isPositive($params)) {
                 $form->reset();
             }
             break;
         case 'display':
             $route = (string) $params;
             if (!$route || $route[0] != '/') {
                 /** @var Uri $uri */
                 $uri = $this->grav['uri'];
                 $route = rtrim($uri->route(), '/') . '/' . ($route ?: '');
             }
             /** @var Twig $twig */
             $twig = $this->grav['twig'];
             $twig->twig_vars['form'] = $form;
             /** @var Pages $pages */
             $pages = $this->grav['pages'];
             $page = $pages->dispatch($route, true);
             if (!$page) {
                 throw new \RuntimeException('Display page not found. Please check the page exists.', 400);
             }
             unset($this->grav['page']);
             $this->grav['page'] = $page;
             break;
         case 'save':
             $prefix = !empty($params['fileprefix']) ? $params['fileprefix'] : '';
             $format = !empty($params['dateformat']) ? $params['dateformat'] : 'Ymd-His-u';
             $ext = !empty($params['extension']) ? '.' . trim($params['extension'], '.') : '.txt';
             $filename = !empty($params['filename']) ? $params['filename'] : '';
             $operation = !empty($params['operation']) ? $params['operation'] : 'create';
             if (!$filename) {
                 $filename = $prefix . $this->udate($format) . $ext;
             }
             /** @var Twig $twig */
             $twig = $this->grav['twig'];
             $vars = ['form' => $form];
             // Process with Twig
             $filename = $twig->processString($filename, $vars);
             $locator = $this->grav['locator'];
             $path = $locator->findResource('user://data', true);
             $dir = $path . DS . $form->name();
             $fullFileName = $dir . DS . $filename;
             $file = File::instance($fullFileName);
             if ($operation == 'create') {
                 $body = $twig->processString(!empty($params['body']) ? $params['body'] : '{% include "forms/data.txt.twig" %}', $vars);
                 $file->save($body);
             } elseif ($operation == 'add') {
                 if (!empty($params['body'])) {
                     // use body similar to 'create' action and append to file as a log
                     $body = $twig->processString($params['body'], $vars);
                     // create folder if it doesn't exist
                     if (!file_exists($dir)) {
                         mkdir($dir);
                     }
                     // append data to existing file
                     file_put_contents($fullFileName, $body, FILE_APPEND | LOCK_EX);
                 } else {
                     // serialize YAML out to file for easier parsing as data sets
                     $vars = $vars['form']->value()->toArray();
                     foreach ($form->fields as $field) {
                         if (isset($field['process']) && isset($field['process']['ignore']) && $field['process']['ignore']) {
                             unset($vars[$field['name']]);
                         }
                     }
                     if (file_exists($fullFileName)) {
                         $data = Yaml::parse($file->content());
                         if (count($data) > 0) {
                             array_unshift($data, $vars);
                         } else {
                             $data[] = $vars;
                         }
                     } else {
                         $data[] = $vars;
                     }
                     $file->save(Yaml::dump($data));
                 }
             }
             break;
     }
 }
Example #26
0
 /**
  * Twig process that renders the site layout. This is the main twig process that renders the overall
  * page and handles all the layout for the site display.
  *
  * @param string $format Output format (defaults to HTML).
  * @return string the rendered output
  * @throws \RuntimeException
  */
 public function processSite($format = null)
 {
     // set the page now its been processed
     $this->grav->fireEvent('onTwigSiteVariables');
     $pages = $this->grav['pages'];
     $page = $this->grav['page'];
     $content = $page->content();
     $config = $this->grav['config'];
     $twig_vars = $this->twig_vars;
     $twig_vars['pages'] = $pages->root();
     $twig_vars['page'] = $page;
     $twig_vars['header'] = $page->header();
     $twig_vars['content'] = $content;
     $ext = '.' . ($format ? $format : 'html') . TWIG_EXT;
     // determine if params are set, if so disable twig cache
     $params = $this->grav['uri']->params(null, true);
     if (!empty($params)) {
         $this->twig->setCache(false);
     }
     // Get Twig template layout
     $template = $this->template($page->template() . $ext);
     try {
         $output = $this->twig->render($template, $twig_vars);
     } catch (\Twig_Error_Loader $e) {
         // If loader error, and not .html.twig, try it as fallback
         if (Utils::contains($e->getMessage(), $template)) {
             $inflector = new Inflector();
             $error_msg = 'The template file for this page: "' . $template . '" is not provided by the theme: "' . $inflector->titleize($config->get('system.pages.theme')) . '"';
         } else {
             $error_msg = $e->getMessage();
         }
         // Try html version of this template if initial template was NOT html
         if ($ext != '.html' . TWIG_EXT) {
             try {
                 $output = $this->twig->render($page->template() . '.html' . TWIG_EXT, $twig_vars);
             } catch (\Twig_Error_Loader $e) {
                 throw new \RuntimeException($error_msg, 400, $e);
             }
         } else {
             throw new \RuntimeException($error_msg, 400, $e);
         }
     }
     return $output;
 }
Example #27
0
 /**
  * Returns the items between a set of date ranges of either the page date field (default) or
  * an arbitrary datetime page field where end date is optional
  * Dates can be passed in as text that strtotime() can process
  * http://php.net/manual/en/function.strtotime.php
  *
  * @param      $startDate
  * @param bool $endDate
  * @param      $field
  *
  * @return $this
  * @throws \Exception
  */
 public function dateRange($startDate, $endDate = false, $field = false)
 {
     $start = Utils::date2timestamp($startDate);
     $end = $endDate ? Utils::date2timestamp($endDate) : strtotime("now +1000 years");
     $date_range = [];
     foreach ($this->items as $path => $slug) {
         $page = $this->pages->get($path);
         $date = $field ? strtotime($page->value($field)) : $page->date();
         if ($date > $start && $date < $end) {
             $date_range[$path] = $slug;
         }
     }
     $this->items = $date_range;
     return $this;
 }
Example #28
0
 /**
  * Get the summary.
  *
  * @param  int    $size Max summary size.
  * @return string
  */
 public function summary($size = null)
 {
     /** @var Config $config */
     $config = self::getGrav()['config']->get('site.summary');
     if (isset($this->header->summary)) {
         $config = array_merge($config, $this->header->summary);
     }
     // Return summary based on settings in site config file
     if (!$config['enabled']) {
         return $this->content();
     }
     // Set up variables to process summary from page or from custom summary
     if ($this->summary === null) {
         $content = $this->content();
         $summary_size = $this->summary_size;
     } else {
         $content = $this->summary;
         $summary_size = mb_strlen($this->summary);
     }
     // Return calculated summary based on summary divider's position
     $format = $config['format'];
     // Return entire page content on wrong/ unknown format
     if (!in_array($format, array('short', 'long'))) {
         return $content;
     } elseif ($format === 'short' && isset($summary_size)) {
         return mb_substr($content, 0, $summary_size);
     }
     // Get summary size from site config's file
     if (is_null($size)) {
         $size = $config['size'];
     }
     // If the size is zero, return the entire page content
     if ($size === 0) {
         return $content;
         // Return calculated summary based on defaults
     } elseif (!is_numeric($size) || $size < 0) {
         $size = 300;
     }
     return Utils::truncateHTML($content, $size);
 }
Example #29
0
 /**
  * This attempts to find media, other files, and download them
  * @param $page
  * @param $path
  */
 protected function fallbackUrl($page, $path)
 {
     /** @var Uri $uri */
     $uri = $this['uri'];
     /** @var Config $config */
     $config = $this['config'];
     $uri_extension = $uri->extension();
     $fallback_types = $config->get('system.media.allowed_fallback_types', null);
     $supported_types = $config->get('media');
     // Check whitelist first, then ensure extension is a valid media type
     if (!empty($fallback_types) && !in_array($uri_extension, $fallback_types)) {
         return;
     } elseif (!array_key_exists($uri_extension, $supported_types)) {
         return;
     }
     $path_parts = pathinfo($path);
     $page = $this['pages']->dispatch($path_parts['dirname'], true);
     if ($page) {
         $media = $page->media()->all();
         $parsed_url = parse_url(urldecode($uri->basename()));
         $media_file = $parsed_url['path'];
         // if this is a media object, try actions first
         if (isset($media[$media_file])) {
             $medium = $media[$media_file];
             foreach ($uri->query(null, true) as $action => $params) {
                 if (in_array($action, ImageMedium::$magic_actions)) {
                     call_user_func_array(array(&$medium, $action), explode(',', $params));
                 }
             }
             Utils::download($medium->path(), false);
         }
         // unsupported media type, try to download it...
         if ($uri_extension) {
             $extension = $uri_extension;
         } else {
             if (isset($path_parts['extension'])) {
                 $extension = $path_parts['extension'];
             } else {
                 $extension = null;
             }
         }
         if ($extension) {
             $download = true;
             if (in_array(ltrim($extension, '.'), $config->get('system.media.unsupported_inline_types', []))) {
                 $download = false;
             }
             Utils::download($page->path() . DIRECTORY_SEPARATOR . $uri->basename(), $download);
         }
     }
 }
Example #30
0
 /**
  * Generate a random string
  *
  * @param int $count
  *
  * @return string
  */
 public function randomStringFunc($count = 5)
 {
     return Utils::generateRandomString($count);
 }