/** * Backup * * @param null $destination * @param callable|null $messager * * @return null|string */ public static function backup($destination = null, callable $messager = null) { if (!$destination) { $destination = Grav::instance()['locator']->findResource('backup://', true); if (!$destination) { throw new \RuntimeException('The backup folder is missing.'); } } $name = substr(strip_tags(Grav::instance()['config']->get('site.title', basename(GRAV_ROOT))), 0, 20); $inflector = new Inflector(); if (is_dir($destination)) { $date = date('YmdHis', time()); $filename = trim($inflector->hyphenize($name), '-') . '-' . $date . '.zip'; $destination = rtrim($destination, DS) . DS . $filename; } $messager && $messager(['type' => 'message', 'level' => 'info', 'message' => 'Creating new Backup "' . $destination . '"']); $messager && $messager(['type' => 'message', 'level' => 'info', 'message' => '']); $zip = new \ZipArchive(); $zip->open($destination, \ZipArchive::CREATE); $max_execution_time = ini_set('max_execution_time', 600); static::folderToZip(GRAV_ROOT, $zip, strlen(rtrim(GRAV_ROOT, DS) . DS), $messager); $messager && $messager(['type' => 'progress', 'percentage' => false, 'complete' => true]); $messager && $messager(['type' => 'message', 'level' => 'info', 'message' => '']); $messager && $messager(['type' => 'message', 'level' => 'info', 'message' => 'Saving and compressing archive...']); $zip->close(); if ($max_execution_time !== false) { ini_set('max_execution_time', $max_execution_time); } return $destination; }
/** * Session init */ public function init() { /** @var Uri $uri */ $uri = $this->grav['uri']; $config = $this->grav['config']; $is_admin = false; $base_url = $uri->rootUrl(false); $session_timeout = $config->get('system.session.timeout', 1800); $session_path = $config->get('system.session.path'); if (!$session_path) { $session_path = '/' . ltrim($base_url, '/'); } // Activate admin if we're inside the admin path. if ($config->get('plugins.admin.enabled')) { $route = $config->get('plugins.admin.route'); // Uri::route() is not processed yet, let's quickly get what we need $current_route = str_replace($base_url, '', parse_url($uri->url(true), PHP_URL_PATH)); $base = '/' . trim($route, '/'); if (substr($current_route, 0, strlen($base)) == $base || substr($current_route, 3, strlen($base)) == $base || substr($current_route, 6, strlen($base)) == $base) { //handle region specific language prefix (en-US) $session_timeout = $config->get('plugins.admin.session.timeout', 1800); $is_admin = true; } } if ($config->get('system.session.enabled') || $is_admin) { $domain = $uri->host(); if ($domain === 'localhost') { $domain = ''; } // Fix for HUGE session timeouts if ($session_timeout > 99999999999) { $session_timeout = 9999999999; } // Define session service. parent::__construct($session_timeout, $session_path, $domain); $secure = $config->get('system.session.secure', false); $httponly = $config->get('system.session.httponly', true); $unique_identifier = GRAV_ROOT; $inflector = new Inflector(); $session_name = $inflector->hyphenize($config->get('system.session.name', 'grav_site')) . '-' . substr(md5($unique_identifier), 0, 7); $split_session = $config->get('system.session.split', true); if ($is_admin && $split_session) { $session_name .= '-admin'; } $this->setName($session_name); $this->start(); setcookie(session_name(), session_id(), time() + $session_timeout, $session_path, $domain, $secure, $httponly); } }
/** * Recurses through the plugins directory creating Plugin objects for each plugin it finds. * * @return array|Plugin[] array of Plugin objects * @throws \RuntimeException */ public function init() { /** @var Config $config */ $config = self::getGrav()['config']; $plugins = (array) $config->get('plugins'); /** @var EventDispatcher $events */ $events = self::getGrav()['events']; foreach ($plugins as $plugin => $data) { if (empty($data['enabled'])) { // Only load enabled plugins. continue; } $locator = self::getGrav()['locator']; $filePath = $locator->findResource('plugins://' . $plugin . DS . $plugin . PLUGIN_EXT); if (!is_file($filePath)) { self::getGrav()['log']->addWarning(sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clear-cache`", $plugin)); continue; } require_once $filePath; $pluginClassFormat = ['Grav\\Plugin\\' . ucfirst($plugin) . 'Plugin', 'Grav\\Plugin\\' . Inflector::camelize($plugin) . 'Plugin']; $pluginClassName = false; foreach ($pluginClassFormat as $pluginClass) { if (class_exists($pluginClass)) { $pluginClassName = $pluginClass; break; } } if (false === $pluginClassName) { throw new \RuntimeException(sprintf("Plugin '%s' class not found! Try reinstalling this plugin.", $plugin)); } $instance = new $pluginClassName($plugin, self::getGrav(), $config); if ($instance instanceof EventSubscriberInterface) { $events->addSubscriber($instance); } } return $this->items; }
/** * Create user. * * @param string $data['username'] The username of the OAuth user * @param string $data['password'] The unique id of the Oauth user * setting as password * @param string $data['email'] The email of the OAuth user * @param string $data['language'] Language * @param bool $save Save user * * @return User A user object */ protected function createUser($data, $save = false) { /** @var User $user */ $user = $this->grav['user']; $accountFile = Inflector::underscorize($data['username']); $accountFile = $this->grav['locator']->findResource('user://accounts/' . strtolower("{$accountFile}.{$this->action}") . YAML_EXT, true, true); $user->set('username', $data['username']); $user->set('password', md5($data['id'])); $user->set('email', $data['email']); $user->set('lang', $data['lang']); // Set access rights $user->join('access', $this->grav['config']->get('plugins.login.oauth.user.access', [])); // Authorize OAuth user to access page(s) $user->authenticated = $user->authorize('site.login'); if ($save) { $user->file(CompiledYamlFile::instance($accountFile)); $user->save(); } return $user; }
/** * 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; }
/** * 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; }
/** * Process the admin registration form. * * @param Event $event */ public function onFormProcessed(Event $event) { $form = $event['form']; $action = $event['action']; switch ($action) { case 'register_admin_user': if (!$this->config->get('plugins.login.enabled')) { throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.PLUGIN_LOGIN_DISABLED')); } $data = []; $username = $form->value('username'); if ($form->value('password1') != $form->value('password2')) { $this->grav->fireEvent('onFormValidationError', new Event(['form' => $form, 'message' => $this->grav['language']->translate('PLUGIN_LOGIN.PASSWORDS_DO_NOT_MATCH')])); $event->stopPropagation(); return; } $data['password'] = $form->value('password1'); $fields = ['email', 'fullname', 'title']; foreach ($fields as $field) { // Process value of field if set in the page process.register_user if (!isset($data[$field]) && $form->value($field)) { $data[$field] = $form->value($field); } } unset($data['password1']); unset($data['password2']); // Don't store the username: that is part of the filename unset($data['username']); // Extra lowercase to ensure file is saved lowercase $username = strtolower($username); $inflector = new Inflector(); $data['fullname'] = isset($data['fullname']) ? $data['fullname'] : $inflector->titleize($username); $data['title'] = isset($data['title']) ? $data['title'] : 'Administrator'; $data['state'] = 'enabled'; $data['access'] = ['admin' => ['login' => true, 'super' => true], 'site' => ['login' => true]]; // Create user object and save it $user = new User($data); $file = CompiledYamlFile::instance($this->grav['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true)); $user->file($file); $user->save(); $user = User::load($username); //Login user $this->grav['session']->user = $user; unset($this->grav['user']); $this->grav['user'] = $user; $user->authenticated = $user->authorize('site.login'); $messages = $this->grav['messages']; $messages->add($this->grav['language']->translate('PLUGIN_ADMIN.LOGIN_LOGGED_IN'), 'info'); $this->grav->redirect($this->admin_route); break; } }
/** * Load current theme. * * @return Theme|object */ public function load() { // NOTE: ALL THE LOCAL VARIABLES ARE USED INSIDE INCLUDED FILE, DO NOT REMOVE THEM! $grav = $this->grav; $config = $this->config; $name = $this->current(); /** @var UniformResourceLocator $locator */ $locator = $grav['locator']; $file = $locator('theme://theme.php') ?: $locator("theme://{$name}.php"); if ($file) { // Local variables available in the file: $grav, $config, $name, $file $class = (include $file); if (!is_object($class)) { $themeClassFormat = ['Grav\\Theme\\' . ucfirst($name), 'Grav\\Theme\\' . Inflector::camelize($name)]; $themeClassName = false; foreach ($themeClassFormat as $themeClass) { if (class_exists($themeClass)) { $themeClassName = $themeClass; $class = new $themeClassName($grav, $config, $name); break; } } } } elseif (!$locator('theme://') && !defined('GRAV_CLI')) { exit("Theme '{$name}' does not exist, unable to display page."); } if (empty($class)) { $class = new Theme($grav, $config, $name); } return $class; }
/** * Create form for the given page. * * @param Page $page * @param null $name * @param null $form */ public function __construct(Page $page, $name = null, $form = null) { parent::__construct(); $this->page = $page->route(); $header = $page->header(); $this->rules = isset($header->rules) ? $header->rules : []; $this->header_data = isset($header->data) ? $header->data : []; if ($form) { $this->items = $form; } else { if (isset($header->form)) { $this->items = $header->form; // for backwards compatibility } } // Add form specific rules. if (!empty($this->items['rules']) && is_array($this->items['rules'])) { $this->rules += $this->items['rules']; } // Set form name if not set. if ($name && !is_int($name)) { $this->items['name'] = $name; } elseif (empty($this->items['name'])) { $this->items['name'] = $page->slug(); } // Set form id if not set. if (empty($this->items['id'])) { $inflector = new Inflector(); $this->items['id'] = $inflector->hyphenize($this->items['name']); } // Reset and initialize the form $this->reset(); }