/** * Check if the current route is under the admin path * * @return bool */ public function isAdminPath() { if ($this->uri->route() == $this->base || substr($this->uri->route(), 0, strlen($this->base) + 1) == $this->base . '/') { return true; } return false; }
/** * Initialize the admin. * * @throws \RuntimeException */ protected function initializeAdmin() { $this->enable(['onPagesInitialized' => ['onPagesInitialized', 1000], 'onTwigTemplatePaths' => ['onTwigTemplatePaths', 1000], 'onTwigSiteVariables' => ['onTwigSiteVariables', 1000], 'onTask.GPM' => ['onTaskGPM', 0]]); // Check for required plugins if (!$this->grav['config']->get('plugins.login.enabled') || !$this->grav['config']->get('plugins.form.enabled') || !$this->grav['config']->get('plugins.email.enabled')) { throw new \RuntimeException('One of the required plugins is missing or not enabled'); } // Double check we have system.yaml and site.yaml $config_files[] = $this->grav['locator']->findResource('user://config') . '/system.yaml'; $config_files[] = $this->grav['locator']->findResource('user://config') . '/site.yaml'; foreach ($config_files as $config_file) { if (!file_exists($config_file)) { touch($config_file); } } // Decide admin template and route. $path = trim(substr($this->uri->route(), strlen($this->base)), '/'); $this->template = 'dashboard'; if ($path) { $array = explode('/', $path, 2); $this->template = array_shift($array); $this->route = array_shift($array); } // Initialize admin class. require_once __DIR__ . '/classes/admin.php'; $this->admin = new Admin($this->grav, $this->base, $this->template, $this->route); // And store the class into DI container. $this->grav['admin'] = $this->admin; // Get theme for admin $this->theme = $this->config->get('plugins.admin.theme', 'grav'); }
public function testInvalidLinksSubDirAbsoluteUrl() { $this->config->set('system.absolute_urls', true); $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); $this->assertSame('<p><a href="http://testing.dev/subdir/item2/item2-2/no-page">Non Existent Page</a></p>', $this->parsedown->text('[Non Existent Page](no-page)')); $this->assertSame('<p><a href="http://testing.dev/subdir/item2/item2-2/existing-file.zip">Existent File</a></p>', $this->parsedown->text('[Existent File](existing-file.zip)')); $this->assertSame('<p><a href="http://testing.dev/subdir/item2/item2-2/missing-file.zip">Non Existent File</a></p>', $this->parsedown->text('[Non Existent File](missing-file.zip)')); }
public function testAddNonce() { $url = 'http://localhost/foo'; $this->assertStringStartsWith($url, Uri::addNonce($url, 'test-action')); $this->assertStringStartsWith($url . '/nonce:', Uri::addNonce($url, 'test-action')); $this->uri->initializeWithURL(Uri::addNonce($url, 'test-action'))->init(); $this->assertTrue(is_string($this->uri->param('nonce'))); $this->assertSame(Utils::getNonce('test-action'), $this->uri->param('nonce')); }
protected function _before() { $grav = Fixtures::get('grav'); $this->grav = $grav(); $this->pages = $this->grav['pages']; $this->config = $this->grav['config']; $this->uri = $this->grav['uri']; $this->language = $this->grav['language']; $this->old_home = $this->config->get('system.home.alias'); $this->config->set('system.home.alias', '/item1'); $this->config->set('system.absolute_urls', false); $this->config->set('system.languages.supported', []); unset($this->grav['language']); $this->grav['language'] = new Language($this->grav); /** @var UniformResourceLocator $locator */ $locator = $this->grav['locator']; $locator->addPath('page', '', 'tests/fake/nested-site/user/pages', false); $this->pages->init(); $defaults = ['extra' => false, 'auto_line_breaks' => false, 'auto_url_links' => false, 'escape_markup' => false, 'special_chars' => ['>' => 'gt', '<' => 'lt']]; $this->page = $this->pages->dispatch('/item2/item2-2'); $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); }
/** * Initialize the admin. * * @throws \RuntimeException */ protected function initializeAdmin() { $this->enable(['onTwigExtensions' => ['onTwigExtensions', 1000], 'onPagesInitialized' => ['onPagesInitialized', 1000], 'onTwigTemplatePaths' => ['onTwigTemplatePaths', 1000], 'onTwigSiteVariables' => ['onTwigSiteVariables', 1000], 'onTask.GPM' => ['onTaskGPM', 0]]); // Check for required plugins if (!$this->grav['config']->get('plugins.login.enabled') || !$this->grav['config']->get('plugins.form.enabled') || !$this->grav['config']->get('plugins.email.enabled')) { throw new \RuntimeException('One of the required plugins is missing or not enabled'); } // Double check we have system.yaml and site.yaml $config_files[] = $this->grav['locator']->findResource('user://config') . '/system.yaml'; $config_files[] = $this->grav['locator']->findResource('user://config') . '/site.yaml'; foreach ($config_files as $config_file) { if (!file_exists($config_file)) { touch($config_file); } } // Initialize Admin Language if needed /** @var Language $language */ $language = $this->grav['language']; if ($language->enabled() && empty($this->grav['session']->admin_lang)) { $this->grav['session']->admin_lang = $language->getLanguage(); } // Decide admin template and route. $path = trim(substr($this->uri->route(), strlen($this->base)), '/'); $this->template = 'dashboard'; if ($path) { $array = explode('/', $path, 2); $this->template = array_shift($array); $this->route = array_shift($array); } // Initialize admin class. require_once __DIR__ . '/classes/admin.php'; $this->admin = new Admin($this->grav, $this->base, $this->template, $this->route); // And store the class into DI container. $this->grav['admin'] = $this->admin; // Get theme for admin $this->theme = $this->config->get('plugins.admin.theme', 'grav'); $assets = $this->grav['assets']; $translations = 'if (!window.translations) window.translations = {}; ' . PHP_EOL . 'window.translations.PLUGIN_ADMIN = {};' . PHP_EOL; // Enable language translations $translations_actual_state = $this->config->get('system.languages.translations'); $this->config->set('system.languages.translations', true); $strings = ['EVERYTHING_UP_TO_DATE', 'UPDATES_ARE_AVAILABLE', 'IS_AVAILABLE_FOR_UPDATE', 'AND', 'IS_NOW_AVAILABLE', 'CURRENT', 'UPDATE_GRAV_NOW', 'TASK_COMPLETED', 'UPDATE', 'UPDATING_PLEASE_WAIT', 'GRAV_SYMBOLICALLY_LINKED', 'OF_YOUR', 'OF_THIS', 'HAVE_AN_UPDATE_AVAILABLE', 'UPDATE_AVAILABLE', 'UPDATES_AVAILABLE', 'FULLY_UPDATED', 'DAYS', 'PAGE_MODES', 'PAGE_TYPES', 'ACCESS_LEVELS']; foreach ($strings as $string) { $translations .= 'translations.PLUGIN_ADMIN.' . $string . ' = "' . $this->admin->translate('PLUGIN_ADMIN.' . $string) . '"; ' . PHP_EOL; } // set the actual translations state back $this->config->set('system.languages.translations', $translations_actual_state); $assets->addInlineJs($translations); }
public function onOutputGenerated() { // Clear flash objects for previously uploaded files // whenever the user switches page / reloads // ignoring any JSON / extension call if (is_null($this->uri->extension()) && $this->admin->task !== 'save') { // Discard any previously uploaded files session. // and if there were any uploaded file, remove them from the filesystem if ($flash = $this->session->getFlashObject('files-upload')) { $flash = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($flash)); foreach ($flash as $key => $value) { if ($key !== 'tmp_name') { continue; } @unlink($value); } } } }
/** * Authenticate user. * * @param array $form Form fields. * @return bool */ public function authenticate($form) { if (!$this->user->authenticated && isset($form['username']) && isset($form['password'])) { $user = User::load($form['username']); if ($user->exists()) { $user->authenticated = true; // Authenticate user. $result = $user->authenticate($form['password']); if ($result) { $this->user = $this->session->user = $user; /** @var Grav $grav */ $grav = $this->grav; $l = $this->grav['language']; $this->setMessage($l->translate('LOGIN_LOGGED_IN'), 'info'); // $redirect_route =$this->getLoginRedirect() ?: $this->uri->route(); $redirect_route = $this->uri->route(); $grav->redirect($redirect_route); } } } return $this->authorise(); }
/** * Authenticate user. * * @param array $form Form fields. * * @return bool */ public function authenticate($form) { if (!$this->user->authenticated && isset($form['username']) && isset($form['password'])) { $user = User::load($form['username']); //default to english if language not set if (empty($user->language)) { $user->set('language', 'en'); } if ($user->exists()) { $user->authenticated = true; // Authenticate user. $result = $user->authenticate($form['password']); if ($result) { $this->user = $this->session->user = $user; /** @var Grav $grav */ $grav = $this->grav; $this->setMessage($this->translate('PLUGIN_ADMIN.LOGIN_LOGGED_IN', [$this->user->language]), 'info'); $redirect_route = $this->uri->route(); $grav->redirect($redirect_route); } } } return $this->authorize(); }
/** * 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; }
/** * 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; } }
protected function getMessageFromUrl(Uri $uri) { $message_success = $this->overwriteConfigVariable('plugins.recaptchacontact.messages.success', 'RECAPTCHACONTACT.MESSAGES.SUCCESS'); $message_error = $this->overwriteConfigVariable('plugins.recaptchacontact.messages.error', 'RECAPTCHACONTACT.MESSAGES.ERROR'); $message_fail = $this->overwriteConfigVariable('plugins.recaptchacontact.messages.fail', 'RECAPTCHACONTACT.MESSAGES.FAIL'); switch ($uri->param('send')) { case 'success': $this->setSubmissionMessage('success', $message_success); break; case 'error': $this->setSubmissionMessage('error', $message_error); break; case 'fail': $this->setSubmissionMessage('fail', $message_fail); break; } }
/** * Execute shortcode. * * @param Event $event An event object. * @return string|null Return modified contents. */ public function execute(Event $event) { /* @var \Grav\Common\Grav $grav */ $grav = $event['grav']; /* @var \Grav\Plugin\Shortcodes\Shortcodes $shortcodes */ $shortcodes = $event['shortcodes']; /* @var \Grav\Common\Data\Data $options */ $options = $event['options']; $options->setDefaults($this->defaults); $type = strtolower($options->get('type')); $body = trim(strip_tags($event['body'], '<link><script>')); if ($options->get('inline')) { $shortcodes->addExtra('assets', 'addInline' . ucfirst($type), $body); } else { /* @var \Grav\Common\Page\Page $page */ $page = $event['page']; /* @var UniformResourceLocator $locator */ $locator = $grav['locator']; /* @var Uri $uri */ $uri = $grav['uri']; $priority = $options->get('priority', 10); $pipeline = $options->get('pipeline', false); $loading = $options->get('load', ''); $entries = explode("\n", $body); $name = $type === 'css' ? 'addCss' : 'addJs'; foreach ($entries as $entry) { $url = $before = trim($entry, " \t"); // Don't process protocol agnostic or external URLs if (!$grav['uri']->isExternal($url) && substr($url, 0, 2) !== '//') { if (false !== strpos($url, '://')) { // Get relative path to the resource (or false if not found). if ($resource = $locator->findResource($url, false)) { $url = rtrim($uri->rootUrl(false), '/') . '/' . $resource; } } else { // Resolve URL (relative or absolute with respect to current page) $url = Uri::convertUrl($page, $url); } if (false === strpos($url, '://')) { $url = preg_replace('~^' . preg_quote($uri->rootUrl(false)) . '~i', '', $url); $url = rtrim($uri->rootUrl(true), '/') . $url; } } $shortcodes->addExtra('assets', $name, [$url, $priority, $pipeline, $loading]); } } }
protected function inlineLink($excerpt) { if (isset($excerpt['type'])) { $type = $excerpt['type']; } else { $type = 'link'; } // do some trickery to get around Parsedown requirement for valid URL if its Twig in there if (preg_match($this->twig_link_regex, $excerpt['text'], $matches)) { $excerpt['text'] = str_replace($matches[1], '/', $excerpt['text']); $excerpt = parent::inlineLink($excerpt); $excerpt['element']['attributes']['href'] = $matches[1]; $excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1; return $excerpt; } else { $excerpt = parent::inlineLink($excerpt); } // if this is a link if (isset($excerpt['element']['attributes']['href'])) { $url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['href'])); // if there is a query, then parse it and build action calls if (isset($url['query'])) { $actions = array_reduce(explode('&', $url['query']), function ($carry, $item) { $parts = explode('=', $item, 2); $value = isset($parts[1]) ? $parts[1] : true; $carry[$parts[0]] = $value; return $carry; }, []); // valid attributes supported $valid_attributes = ['rel', 'target', 'id', 'class', 'classes']; // Unless told to not process, go through actions if (array_key_exists('noprocess', $actions)) { unset($actions['noprocess']); } else { // loop through actions for the image and call them foreach ($actions as $attrib => $value) { $key = $attrib; if (in_array($attrib, $valid_attributes)) { // support both class and classes if ($attrib == 'classes') { $attrib = 'class'; } $excerpt['element']['attributes'][$attrib] = str_replace(',', ' ', $value); unset($actions[$key]); } } } $url['query'] = http_build_query($actions, null, '&', PHP_QUERY_RFC3986); } // if no query elements left, unset query if (empty($url['query'])) { unset($url['query']); } // if there is no scheme, the file is local and we'll need to convert that URL if (!isset($url['scheme']) && count($url) > 0) { $excerpt['element']['attributes']['href'] = Uri::convertUrl($this->page, Uri::buildUrl($url), $type, true); } else { $excerpt['element']['attributes']['href'] = Uri::buildUrl($url); } } return $excerpt; }
/** * Converts links from absolute '/' or relative (../..) to a grav friendly format * * @param $page the current page to use as reference * @param string $markdown_url the URL as it was written in the markdown * * @return string the more friendly formatted url */ public static function convertUrl(Page $page, $markdown_url) { $grav = Grav::instance(); $pages_dir = $grav['locator']->findResource('page://'); $base_url = rtrim($grav['base_url'] . $grav['pages']->base(), '/'); // if absolute and starts with a base_url move on if (pathinfo($markdown_url, PATHINFO_DIRNAME) == '.' && $page->url() == '/') { return '/' . $markdown_url; // no path to convert } elseif ($base_url != '' && Utils::startsWith($markdown_url, $base_url)) { return $markdown_url; // if contains only a fragment } elseif (Utils::startsWith($markdown_url, '#')) { return $markdown_url; } else { $target = null; // see if page is relative to this or absolute if (Utils::startsWith($markdown_url, '/')) { $normalized_url = Utils::normalizePath($base_url . $markdown_url); $normalized_path = Utils::normalizePath($pages_dir . $markdown_url); } else { $normalized_url = $base_url . Utils::normalizePath($page->route() . '/' . $markdown_url); $normalized_path = Utils::normalizePath($page->path() . '/' . $markdown_url); } // special check to see if path checking is required. $just_path = str_replace($normalized_url, '', $normalized_path); if ($just_path == $page->path()) { return $normalized_url; } $url_bits = parse_url($normalized_path); $full_path = $url_bits['path']; if (file_exists($full_path)) { // do nothing } elseif (file_exists(urldecode($full_path))) { $full_path = urldecode($full_path); } else { return $normalized_url; } $path_info = pathinfo($full_path); $page_path = $path_info['dirname']; $filename = ''; if ($markdown_url == '..') { $page_path = $full_path; } else { // save the filename if a file is part of the path if (is_file($full_path)) { if ($path_info['extension'] != 'md') { $filename = '/' . $path_info['basename']; } } else { $page_path = $full_path; } } // get page instances and try to find one that fits $instances = $grav['pages']->instances(); if (isset($instances[$page_path])) { $target = $instances[$page_path]; $url_bits['path'] = $base_url . $target->route() . $filename; return Uri::buildUrl($url_bits); } return $normalized_url; } }
/** * Handle the Form Process * * @param \Grav\Common\Uri $uri */ protected function processFormAction(Uri $uri) { $message_success = $this->overwriteConfigVariable('plugins.recaptchacontact.messages.success', 'RECAPTCHACONTACT.MESSAGES.SUCCESS'); $message_error = $this->overwriteConfigVariable('plugins.recaptchacontact.messages.error', 'RECAPTCHACONTACT.MESSAGES.ERROR'); $message_fail = $this->overwriteConfigVariable('plugins.recaptchacontact.messages.fail', 'RECAPTCHACONTACT.MESSAGES.FAIL'); if ($_SERVER['REQUEST_METHOD'] == "POST" && isset($_POST['g-recaptcha-response'])) { $this->clearSession(); if (false === $this->validateFormData()) { $this->setSubmissionMessage('error', $message_error); $this->setSessionFields(); } else { if (false === $this->sendEmail()) { $this->setSubmissionMessage('fail', $message_fail); $this->setSessionFields(); } else { $this->setSubmissionMessage('success', $message_success); } } $this->grav->redirectLangSafe($uri->url()); } }
protected function inlineLink($excerpt) { if (isset($excerpt['type'])) { $type = $excerpt['type']; } else { $type = 'link'; } // do some trickery to get around Parsedown requirement for valid URL if its Twig in there if (preg_match($this->twig_link_regex, $excerpt['text'], $matches)) { $excerpt['text'] = str_replace($matches[1], '/', $excerpt['text']); $excerpt = parent::inlineLink($excerpt); $excerpt['element']['attributes']['href'] = $matches[1]; $excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1; return $excerpt; } else { $excerpt = parent::inlineLink($excerpt); } // if this is a link if (isset($excerpt['element']['attributes']['href'])) { $url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['href'])); // if there is no scheme, the file is local if (!isset($url['scheme']) && count($url) > 0) { // convert the URl is required $excerpt['element']['attributes']['href'] = Uri::convertUrl($this->page, Uri::buildUrl($url), $type); } } return $excerpt; }
protected function identifyLink($Excerpt) { /** @var Config $config */ $config = self::$grav['config']; // Run the parent method to get the actual results $Excerpt = parent::identifyLink($Excerpt); $actions = array(); $this->base_url = self::$grav['base_url']; // if this is a link if (isset($Excerpt['element']['attributes']['href'])) { $url = parse_url(htmlspecialchars_decode($Excerpt['element']['attributes']['href'])); // if there is no host set but there is a path, the file is local if (!isset($url['host']) && isset($url['path'])) { // convert the URl is required $Excerpt['element']['attributes']['href'] = $this->convertUrl(Uri::build_url($url)); } } // if this is an image if (isset($Excerpt['element']['attributes']['src'])) { $alt = isset($Excerpt['element']['attributes']['alt']) ? $Excerpt['element']['attributes']['alt'] : ''; $title = isset($Excerpt['element']['attributes']['title']) ? $Excerpt['element']['attributes']['title'] : ''; //get the url and parse it $url = parse_url(htmlspecialchars_decode($Excerpt['element']['attributes']['src'])); // if there is no host set but there is a path, the file is local if (!isset($url['host']) && isset($url['path'])) { // get the media objects for this page $media = $this->page->media(); // if there is a media file that matches the path referenced.. if (isset($media->images()[$url['path']])) { // get the medium object $medium = $media->images()[$url['path']]; // if there is a query, then parse it and build action calls if (isset($url['query'])) { parse_str($url['query'], $actions); } // loop through actions for the image and call them foreach ($actions as $action => $params) { // as long as it's a valid action if (in_array($action, Medium::$valid_actions)) { call_user_func_array(array(&$medium, $action), explode(',', $params)); } } // Get the URL for regular images, or an array of bits needed to put together // the lightbox HTML if (!isset($actions['lightbox'])) { $src = $medium->url(); } else { $src = $medium->lightboxRaw(); } // set the src element with the new generated url if (!isset($actions['lightbox']) && !is_array($src)) { $Excerpt['element']['attributes']['src'] = $src; } else { // Create the custom lightbox element $Element = array('name' => 'a', 'attributes' => array('rel' => $src['a_rel'], 'href' => $src['a_url']), 'handler' => 'element', 'text' => array('name' => 'img', 'attributes' => array('src' => $src['img_url'], 'alt' => $alt, 'title' => $title))); // Set the lightbox element on the Excerpt $Excerpt['element'] = $Element; } } else { // not a current page media file, see if it needs converting to relative $Excerpt['element']['attributes']['src'] = $this->convertUrl(Uri::build_url($url)); } } } return $Excerpt; }