Example #1
0
 public function testAddScheme()
 {
     $this->assertEquals('http://example.org', Html::addScheme('example.org'));
     $this->assertEquals('http://example.org', Html::addScheme('http://example.org'));
     $this->assertEquals('https://example.org', Html::addScheme('https://example.org'));
     $this->assertEquals('mailto:bob@bolt.cm', Html::addScheme('mailto:bob@bolt.cm'));
 }
Example #2
0
 /**
  * Get the excerpt of a given piece of text.
  *
  * @param int               $length
  * @param bool              $includeTitle
  * @param array|string|null $focus
  *
  * @return string|null
  */
 public function getExcerpt($length = 200, $includeTitle = false, $focus = null)
 {
     $title = null;
     if ($includeTitle && $this->title !== null) {
         $title = Html::trimText(strip_tags($this->title), $length);
         $length = $length - strlen($title);
     }
     if ($this->body instanceof Content) {
         $this->body = $this->body->getValues();
     }
     if (is_array($this->body)) {
         // Assume it's an array, strip some common fields that we don't need, implode the rest.
         $stripKeys = ['id', 'slug', 'datecreated', 'datechanged', 'username', 'ownerid', 'title', 'contenttype', 'status', 'taxonomy', 'templatefields'];
         foreach ($stripKeys as $key) {
             unset($this->body[$key]);
         }
         $excerpt = implode(' ', $this->body);
     } elseif (is_string($this->body) || is_object($this->body) && method_exists($this->body, '__toString')) {
         // otherwise we just use the string.
         $excerpt = (string) $this->body;
     } else {
         // Nope, got nothing.
         $excerpt = '';
     }
     $excerpt = str_replace('>', '> ', $excerpt);
     if (empty($focus)) {
         $excerpt = Html::trimText(strip_tags($excerpt), $length);
     } else {
         $excerpt = $this->extractRelevant($focus, strip_tags($excerpt), $length);
     }
     if ($title !== null) {
         $excerpt = '<b>' . $title . '</b> ' . $excerpt;
     }
     return $excerpt;
 }
Example #3
0
 public function testBrandingData()
 {
     $app = $this->getApp();
     $app['config']->set('general/branding/provided_by/0', 'testperson');
     $app['config']->set('general/branding/provided_by/1', 'testemail');
     $app['config']->set('general/branding/provided_link', Html::providerLink(['testperson', 'testemail']));
     $request = Request::create('/', 'GET');
     $response = $app->handle($request);
     $data = new BoltDataCollector($app);
     $data->collect($request, $response);
     $this->assertRegExp('/testperson/', $data->getBranding());
     $this->assertRegExp('/testemail/', $data->getBranding());
 }
Example #4
0
 public function testProviderLink()
 {
     $this->assertEquals('', Html::providerLink([]));
     $this->assertEquals('', Html::providerLink(false));
     $this->assertEquals('', Html::providerLink("foo"));
     $this->assertEquals('<a href="mailto:supercool@example.org">Supercool Webdesign Co.</a>', Html::providerLink(['*****@*****.**', 'Supercool Webdesign Co.']));
     $this->assertEquals('<a href="mailto:supercool@example.org">Supercool Webdesign Co.</a>', Html::providerLink(['mailto:supercool@example.org', 'Supercool Webdesign Co.']));
     $this->assertEquals('<a href="http://example.org" target="_blank">Supercool Webdesign Co.</a>', Html::providerLink(['example.org', 'Supercool Webdesign Co.']));
     $this->assertEquals('<a href="http://example.org" target="_blank">Supercool Webdesign Co.</a>', Html::providerLink(['http://example.org', 'Supercool Webdesign Co.']));
     $this->assertEquals('<a href="https://www.example.org" target="_blank">Supercool Webdesign Co.</a>', Html::providerLink(['https://www.example.org', 'Supercool Webdesign Co.']));
     $this->assertEquals('<a href="http://example.org" target="_blank">http://example.org</a>', Html::providerLink(['http://example.org']));
     $this->assertEquals('<a href="http://example.org" target="_blank">no html, please!</a>', Html::providerLink(['http://example.org', '<blink>no html, please!</blink>']));
     $this->assertEquals('<a href="http://example.org" target="_blank">http://example.org</a>', Html::providerLink(['http://example.org', '<b malformed HTML']));
 }
 /**
  * Creates RSS safe content. Wraps it in CDATA tags, strips style and
  * scripts out. Can optionally also return a (cleaned) excerpt.
  *
  * @param Content $record        Bolt Content object
  * @param string  $fields        Comma separated list of fields to clean up
  * @param integer $excerptLength Number of chars of the excerpt
  *
  * @return string RSS safe string
  */
 public function ampSafe($record, $fields = '', $excerptLength = 0)
 {
     // Make sure we have an array of fields. Even if it's only one.
     if (!is_array($fields)) {
         $fields = explode(',', $fields);
     }
     $fields = array_map('trim', $fields);
     $result = '';
     foreach ($fields as $field) {
         if (!array_key_exists($field, $record->values)) {
             continue;
         }
         // Completely remove style and script blocks
         $maid = new Maid(['output-format' => 'html', 'allowed-tags' => ['a', 'b', 'br', 'hr', 'h1', 'h2', 'h3', 'h4', 'p', 'strong', 'em', 'i', 'u', 'strike', 'ul', 'ol', 'li', 'img'], 'allowed-attribs' => ['id', 'class', 'name', 'value', 'href', 'src']]);
         $result .= $maid->clean($record->values[$field]);
     }
     if ($excerptLength > 0) {
         $result = Html::trimText($result, $excerptLength);
     }
     return new \Twig_Markup('<![CDATA[ ' . $result . ' ]]>', 'utf-8');
 }
Example #6
0
 public function description($record = null)
 {
     $this->initialize($record);
     if (!empty($this->values['record']['description'])) {
         $description = $this->values['record']['description'];
     } else {
         if (!empty($this->values['inferred']['description'])) {
             $description = $this->values['inferred']['description'];
         } else {
             $description = $this->values['default']['description'];
         }
     }
     return Html::trimText(strip_tags($description), $this->config['description_length']);
 }
Example #7
0
 /**
  * Create an excerpt for the content.
  *
  * @param integer $length
  * @param boolean $includetitle
  *
  * @return \Twig_Markup
  */
 public function getExcerpt($length = 200, $includetitle = false)
 {
     if ($includetitle) {
         $title = Html::trimText(strip_tags($this->getTitle()), $length);
         $length = $length - strlen($title);
     }
     if ($length > 0) {
         $excerptParts = [];
         if (!empty($this->contenttype['fields'])) {
             foreach ($this->contenttype['fields'] as $key => $field) {
                 // Skip empty fields, and fields used as 'title'.
                 if (!isset($this->values[$key]) || in_array($key, $this->getTitleColumnName())) {
                     continue;
                 }
                 // add 'text', 'html' and 'textarea' fields.
                 if (in_array($field['type'], ['text', 'html', 'textarea'])) {
                     $excerptParts[] = $this->values[$key];
                 }
                 // add 'markdown' field
                 if ($field['type'] === 'markdown') {
                     $excerptParts[] = $this->app['markdown']->text($this->values[$key]);
                 }
             }
         }
         $excerpt = implode(' ', $excerptParts);
         $excerpt = Html::trimText(strip_tags($excerpt), $length);
     } else {
         $excerpt = '';
     }
     if (!empty($title)) {
         $excerpt = '<b>' . $title . '</b> ' . $excerpt;
     }
     return new \Twig_Markup($excerpt, 'UTF-8');
 }
Example #8
0
 /**
  * Get a unique URL for a record
  *
  * @param string  $title
  * @param integer $id
  * @param string  $contenttypeslug
  * @param boolean $fulluri
  * @param boolean $allowempty
  * @param boolean $slugfield
  *
  * @return string
  */
 public function getUri($title, $id = 0, $contenttypeslug = "", $fulluri = true, $allowempty = true, $slugfield = 'slug')
 {
     $contenttype = $this->getContentType($contenttypeslug);
     $tablename = $this->getContenttypeTablename($contenttype);
     $id = intval($id);
     $slug = $this->app['slugify']->slugify($title);
     // Don't allow strictly numeric slugs.
     if (is_numeric($slug)) {
         $slug = $contenttype['singular_slug'] . "-" . $slug;
     }
     // Only add '{contenttype}/' if $full is requested.
     if ($fulluri) {
         $prefix = '/' . $contenttype['singular_slug'] . '/';
     } else {
         $prefix = '';
     }
     $fields = $this->getContentTypeFields($contenttypeslug);
     //check if the fieldname exists, otherwise use 'slug' as fallback
     if (!in_array($slugfield, $fields)) {
         $slugfield = 'slug';
     }
     $query = sprintf("SELECT id from %s WHERE %s=? and id!=?", $tablename, $slugfield);
     $res = $this->app['db']->executeQuery($query, array($slug, $id), array(\PDO::PARAM_STR, \PDO::PARAM_INT))->fetch();
     if (!$res) {
         $uri = $prefix . $slug;
     } else {
         for ($i = 1; $i <= 10; $i++) {
             $newslug = Html::trimText($slug, 127 - strlen($i), false) . '-' . $i;
             $res = $this->app['db']->executeQuery($query, array($newslug, $id), array(\PDO::PARAM_STR, \PDO::PARAM_INT))->fetch();
             if (!$res) {
                 $uri = $prefix . $newslug;
                 break;
             }
         }
         // otherwise, just get a random slug.
         if (empty($uri)) {
             $suffix = '-' . $this->app['randomgenerator']->generateString(6, 'abcdefghijklmnopqrstuvwxyz01234567890');
             $slug = Html::trimText($slug, 128 - strlen($suffix), false) . $suffix;
             $uri = $prefix . $slug;
         }
     }
     // When storing, we should never have an empty slug/URI. If we can't make a nice one, set it to 'slug-XXXX'.
     if (!$allowempty && empty($uri)) {
         $uri = 'slug-' . $this->app['randomgenerator']->generateString(6, 'abcdefghijklmnopqrstuvwxyz01234567890');
     }
     return $uri;
 }
Example #9
0
 /**
  * Create an excerpt for the given content.
  *
  * @param \Bolt\Legacy\Content|array|string $content
  * @param integer                    $length  Defaults to 200 characters
  *
  * @return string Resulting excerpt
  */
 public function excerpt($content, $length = 200)
 {
     // If it's an content object, let the object handle it.
     if (is_object($content)) {
         if (method_exists($content, 'excerpt')) {
             return $content->excerpt($length);
         } else {
             $output = $content;
         }
     } elseif (is_array($content)) {
         // Assume it's an array, strip some common fields that we don't need, implode the rest.
         $stripKeys = ['id', 'slug', 'datecreated', 'datechanged', 'username', 'ownerid', 'title', 'contenttype', 'status', 'taxonomy'];
         foreach ($stripKeys as $key) {
             unset($content[$key]);
         }
         $output = implode(' ', $content);
     } elseif (is_string($content)) {
         // otherwise we just use the string.
         $output = $content;
     } else {
         // Nope, got nothing.
         $output = '';
     }
     $output = str_replace('>', '> ', $output);
     $output = Html::trimText(strip_tags($output), $length);
     return $output;
 }
Example #10
0
 public function keywords($record = null)
 {
     $this->initialize($record);
     if (!empty($this->values['record']['keywords'])) {
         $keywords = $this->values['record']['keywords'];
     } else {
         if (!empty($this->values['inferred']['keywords'])) {
             $keywords = $this->values['inferred']['keywords'];
         } else {
             $keywords = $this->values['default']['keywords'];
         }
     }
     $keywords = str_replace(array("\r", "\n"), "", $keywords);
     return Html::trimText(strip_tags($keywords), $this->config['keywords_length']);
 }
Example #11
0
 /**
  * Get an array of safe (sanitised) function arguments from a trace entry.
  *
  * @param array $args
  *
  * @return array
  */
 protected function getSafeArguments(array $args)
 {
     $argsSafe = [];
     foreach ($args as $arg) {
         $type = gettype($arg);
         switch ($type) {
             case 'string':
                 $argsSafe[] = sprintf('<span>"%s"</span>', Html::trimText($arg, 30));
                 break;
             case 'integer':
             case 'float':
                 $argsSafe[] = sprintf('<span>%s</span>', $arg);
                 break;
             case 'object':
                 $className = get_class($arg);
                 $shortName = (new \ReflectionClass($arg))->getShortName();
                 $argsSafe[] = sprintf('<abbr title="%s">%s</abbr>', $className, $shortName);
                 break;
             case 'boolean':
                 $argsSafe[] = $arg ? '[true]' : '[false]';
                 break;
             default:
                 $argsSafe[] = '[' . $type . ']';
         }
     }
     return $argsSafe;
 }
Example #12
0
 public function decorateTT($str)
 {
     return Html::decorateTT($str);
 }
Example #13
0
 /**
  * Read and parse the config.yml and config_local.yml configuration files.
  *
  * @return array
  */
 protected function parseGeneral()
 {
     // Read the config and merge it. (note: We use temp variables to prevent
     // "Only variables should be passed by reference")
     $tempconfig = $this->parseConfigYaml('config.yml');
     $tempconfiglocal = $this->parseConfigYaml('config_local.yml');
     $general = Arr::mergeRecursiveDistinct($tempconfig, $tempconfiglocal);
     // Make sure old settings for 'contentsCss' are still picked up correctly
     if (isset($general['wysiwyg']['ck']['contentsCss'])) {
         $general['wysiwyg']['ck']['contentsCss'] = [1 => $general['wysiwyg']['ck']['contentsCss']];
     }
     // Make sure old settings for 'accept_file_types' are not still picked up. Before 1.5.4 we used to store them
     // as a regex-like string, and we switched to an array. If we find the old style, fall back to the defaults.
     if (isset($general['accept_file_types']) && !is_array($general['accept_file_types'])) {
         unset($general['accept_file_types']);
     }
     // Merge the array with the defaults. Setting the required values that aren't already set.
     $general = Arr::mergeRecursiveDistinct($this->defaultConfig, $general);
     // Make sure the cookie_domain for the sessions is set properly.
     if (empty($general['cookies_domain'])) {
         $request = Request::createFromGlobals();
         if ($request->server->get('HTTP_HOST', false)) {
             $hostSegments = explode(':', $request->server->get('HTTP_HOST'));
             $hostname = reset($hostSegments);
         } elseif ($request->server->get('SERVER_NAME', false)) {
             $hostname = $request->server->get('SERVER_NAME');
         } else {
             $hostname = '';
         }
         // Don't set the domain for a cookie on a "TLD" - like 'localhost', or if the server_name is an IP-address
         if (strpos($hostname, '.') > 0 && preg_match('/[a-z0-9]/i', $hostname)) {
             if (preg_match('/^www[0-9]*./', $hostname)) {
                 $general['cookies_domain'] = '.' . preg_replace('/^www[0-9]*./', '', $hostname);
             } else {
                 $general['cookies_domain'] = '.' . $hostname;
             }
             // Make sure we don't have consecutive '.'-s in the cookies_domain.
             $general['cookies_domain'] = str_replace('..', '.', $general['cookies_domain']);
         } else {
             $general['cookies_domain'] = '';
         }
     }
     // Make sure Bolt's mount point is OK:
     $general['branding']['path'] = '/' . Str::makeSafe($general['branding']['path']);
     // Set the link in branding, if provided_by is set.
     $general['branding']['provided_link'] = Html::providerLink($general['branding']['provided_by']);
     $general['database'] = $this->parseDatabase($general['database']);
     return $general;
 }
Example #14
0
 /**
  * Create an HTML link to a given URL or contenttype/slug pair.
  *
  * @param string $location
  * @param string $label
  *
  * @return string
  */
 public function link($location, $label = '[link]')
 {
     if ((string) $location === '') {
         return '';
     }
     if (Html::isURL($location)) {
         $location = Html::addScheme($location);
     } elseif ($record = $this->app['storage']->getContent($location)) {
         $location = $record->link();
     }
     return sprintf('<a href="%s">%s</a>', $location, $label);
 }
Example #15
0
 public function testDecorateTT()
 {
     $input = 'Lorem `ipsum` dolor.';
     $this->assertEquals("Lorem <tt>ipsum</tt> dolor.", Html::decorateTT($input));
 }