示例#1
0
 /**
  * A validation function that returns an error if the value passed in is not a valid URL.
  *
  * @param string $text A string to test if it is a valid URL
  * @param FormControl $control The control that defines the value
  * @param FormContainer $form The container that holds the control
  * @param string $warning An optional error message
  * @return array An empty array if the string is a valid URL, or an array with strings describing the errors
  */
 public static function validate_url($text, $control, $form, $warning = null, $schemes = array('http', 'https'), $guess = true)
 {
     if (!empty($text)) {
         $parsed = InputFilter::parse_url($text);
         if ($parsed['is_relative']) {
             if ($guess) {
                 // guess if they meant to use an absolute link
                 $parsed = InputFilter::parse_url('http://' . $text);
                 if ($parsed['is_error']) {
                     // disallow relative URLs
                     $warning = empty($warning) ? _t('Relative urls are not allowed') : $warning;
                     return array($warning);
                 } else {
                     $warning = empty($warning) ? _t('Relative urls are not allowed') : $warning;
                     return array($warning);
                 }
             }
         }
         if ($parsed['is_pseudo'] || !in_array($parsed['scheme'], $schemes)) {
             // allow only http(s) URLs
             $warning = empty($warning) ? _t('Only %s urls are allowed', array(Format::and_list($schemes))) : $warning;
             return array($warning);
         }
     }
     return array();
 }
示例#2
0
 public function test_parse_url_sanitization_javascript()
 {
     $urls = array('javascript:alert(0);', 'javascript:alert(0);', 'java	script:alert(0);', '	javascript:alert(0);', 'java
script:alert(0);', '
javascript:alert(0);', 'java
script:alert(0);', '
javascript:alert(0);');
     foreach ($urls as $url) {
         $url = html_entity_decode($url, null, 'UTF-8');
         $parsed = InputFilter::parse_url($url);
         $this->assert_equal($parsed['scheme'], 'javascript', $url . ' != ' . $parsed['scheme']);
     }
 }
 public function execute($method, $url, $headers, $body, $config)
 {
     $merged_headers = array();
     foreach ($headers as $k => $v) {
         $merged_headers[] = $k . ': ' . $v;
     }
     // parse out the URL so we can refer to individual pieces
     $url_pieces = InputFilter::parse_url($url);
     // set up the options we'll use when creating the request's context
     $options = array('http' => array('method' => $method, 'header' => implode("\n", $merged_headers), 'timeout' => $config['timeout'], 'follow_location' => $this->can_followlocation, 'max_redirects' => $config['max_redirects'], 'verify_peer' => $config['ssl']['verify_peer'], 'cafile' => $config['ssl']['cafile'], 'capath' => $config['ssl']['capath'], 'local_cert' => $config['ssl']['local_cert'], 'passphrase' => $config['ssl']['passphrase']));
     if ($method == 'POST') {
         $options['http']['content'] = $body;
     }
     if ($config['proxy']['server'] != '' && !in_array($url_pieces['host'], $config['proxy']['exceptions'])) {
         $proxy = $config['proxy']['server'] . ':' . $config['proxy']['port'];
         if ($config['proxy']['username'] != '') {
             $proxy = $config['proxy']['username'] . ':' . $config['proxy']['password'] . '@' . $proxy;
         }
         $options['http']['proxy'] = 'tcp://' . $proxy;
     }
     // create the context
     $context = stream_context_create($options);
     // perform the actual request - we use fopen so stream_get_meta_data works
     $fh = @fopen($url, 'r', false, $context);
     if ($fh === false) {
         throw new Exception(_t('Unable to connect to %s', array($url_pieces['host'])));
     }
     // read in all the contents -- this is the same as file_get_contens, only for a specific stream handle
     $body = stream_get_contents($fh);
     // get meta data
     $meta = stream_get_meta_data($fh);
     // close the connection before we do anything else
     fclose($fh);
     // did we timeout?
     if ($meta['timed_out'] == true) {
         throw new RemoteRequest_Timeout(_t('Request timed out'));
     }
     // $meta['wrapper_data'] should be a list of the headers, the same as is loaded into $http_response_header
     $headers = array();
     foreach ($meta['wrapper_data'] as $header) {
         // break the header up into field and value
         $pieces = explode(': ', $header, 2);
         if (count($pieces) > 1) {
             // if the header was a key: value format, store it keyed in the array
             $headers[$pieces[0]] = $pieces[1];
         } else {
             // some headers (like the HTTP version in use) aren't keyed, so just store it keyed as itself
             $headers[$pieces[0]] = $pieces[0];
         }
     }
     $this->response_headers = $headers;
     $this->response_body = $body;
     $this->executed = true;
     return true;
 }
示例#4
0
 function test_url_parsing()
 {
     $this->assert_equal(InputFilter::parse_url('http://*****:*****@moeffju.net:8137/foo/bar?baz=quux#blah'), array('scheme' => 'http', 'host' => 'moeffju.net', 'port' => '8137', 'user' => 'hey', 'pass' => 'there', 'path' => '/foo/bar', 'query' => 'baz=quux', 'fragment' => 'blah', 'is_relative' => false, 'is_pseudo' => false, 'is_error' => false, 'pseudo_args' => ''));
     $this->assert_equal(InputFilter::parse_url('http://localhost/blog/'), array('scheme' => 'http', 'host' => 'localhost', 'port' => '', 'user' => '', 'pass' => '', 'path' => '/blog/', 'query' => '', 'fragment' => '', 'is_relative' => false, 'is_pseudo' => false, 'is_error' => false, 'pseudo_args' => ''));
     $this->assert_equal(InputFilter::parse_url('http:moeffju.net/blog/'), array('scheme' => 'http', 'host' => 'moeffju.net', 'port' => '', 'user' => '', 'pass' => '', 'path' => '/blog/', 'query' => '', 'fragment' => '', 'is_relative' => false, 'is_pseudo' => false, 'is_error' => false, 'pseudo_args' => ''));
     //$this->assert_equal(InputFilter::parse_url( 'file://Z:/Habari/User Manual/index.html' ), array ( 'scheme' => 'file', 'host' => '', 'port' => '', 'user' => '', 'pass' => '', 'path' => 'Z:/Habari/User Manual/index.html', 'query' => '', 'fragment' => '', 'is_relative' => false, 'is_pseudo' => false, 'is_error' => false, 'pseudo_args' => '', ) );
     $this->assert_equal(InputFilter::parse_url('blog/'), array('scheme' => '', 'host' => '', 'port' => '', 'user' => '', 'pass' => '', 'path' => 'blog/', 'query' => '', 'fragment' => '', 'is_relative' => true, 'is_pseudo' => false, 'is_error' => false, 'pseudo_args' => ''));
     $this->assert_equal(InputFilter::parse_url('/furanzen/bla'), array('scheme' => '', 'host' => '', 'port' => '', 'user' => '', 'pass' => '', 'path' => '/furanzen/bla', 'query' => '', 'fragment' => '', 'is_relative' => true, 'is_pseudo' => false, 'is_error' => false, 'pseudo_args' => ''));
     $this->assert_equal(InputFilter::parse_url('?bla=barbaz&foo'), array('scheme' => '', 'host' => '', 'port' => '', 'user' => '', 'pass' => '', 'path' => '', 'query' => 'bla=barbaz&foo', 'fragment' => '', 'is_relative' => true, 'is_pseudo' => false, 'is_error' => false, 'pseudo_args' => ''));
     $this->assert_equal(InputFilter::parse_url('#'), array('scheme' => '', 'host' => '', 'port' => '', 'user' => '', 'pass' => '', 'path' => '', 'query' => '', 'fragment' => '', 'is_relative' => true, 'is_pseudo' => false, 'is_error' => false, 'pseudo_args' => ''));
     $this->assert_equal(InputFilter::parse_url('about:blank'), array('scheme' => 'about', 'host' => '', 'port' => '', 'user' => '', 'pass' => '', 'path' => '', 'query' => '', 'fragment' => '', 'is_relative' => false, 'is_pseudo' => true, 'is_error' => false, 'pseudo_args' => 'blank'));
     $this->assert_equal(InputFilter::parse_url('javascript:alert(document.cookie)'), array('scheme' => 'javascript', 'host' => '', 'port' => '', 'user' => '', 'pass' => '', 'path' => '', 'query' => '', 'fragment' => '', 'is_relative' => false, 'is_pseudo' => true, 'is_error' => false, 'pseudo_args' => 'alert(document.cookie)'));
     $this->assert_equal(InputFilter::parse_url('javascript:alert(\'/hey/there/foo?how=about#bar\')'), array('scheme' => 'javascript', 'host' => '', 'port' => '', 'user' => '', 'pass' => '', 'path' => '', 'query' => '', 'fragment' => '', 'is_relative' => false, 'is_pseudo' => true, 'is_error' => false, 'pseudo_args' => 'alert(\'/hey/there/foo?how=about#bar\')'));
 }
示例#5
0
 /**
  * Add a comment to the site
  *
  * @param mixed $post A Post object instance or Post object id
  * @param string $name The commenter's name
  * @param string $email The commenter's email address
  * @param string $url The commenter's website URL
  * @param string $content The comment content
  * @param array $extra An associative array of extra values that should be considered
  */
 function add_comment($post, $name = null, $email = null, $url = null, $content = null, $extra = null)
 {
     if (is_numeric($post)) {
         $post = Post::get(array('id' => $post));
     }
     if (!$post instanceof Post) {
         // Not sure what you're trying to pull here, but that's no good
         header('HTTP/1.1 403 Forbidden', true, 403);
         die;
     }
     // let's do some basic sanity checking on the submission
     if (1 == Options::get('comments_require_id') && (empty($name) || empty($email))) {
         Session::error(_t('Both name and e-mail address must be provided.'));
     }
     if (empty($content)) {
         Session::error(_t('You did not provide any content for your comment!'));
     }
     if (Session::has_errors()) {
         // save whatever was provided in session data
         Session::add_to_set('comment', $name, 'name');
         Session::add_to_set('comment', $email, 'email');
         Session::add_to_set('comment', $url, 'url');
         Session::add_to_set('comment', $content, 'content');
         // now send them back to the form
         Utils::redirect($post->permalink . '#respond');
     }
     if ($post->info->comments_disabled) {
         // comments are disabled, so let's just send
         // them back to the post's permalink
         Session::error(_t('Comments on this post are disabled!'));
         Utils::redirect($post->permalink);
     }
     /* Sanitize data */
     foreach (array('name', 'url', 'email', 'content') as $k) {
         ${$k} = InputFilter::filter(${$k});
     }
     /* Sanitize the URL */
     if (!empty($url)) {
         $parsed = InputFilter::parse_url($url);
         if ($parsed['is_relative']) {
             // guess if they meant to use an absolute link
             $parsed = InputFilter::parse_url('http://' . $url);
             if (!$parsed['is_error']) {
                 $url = InputFilter::glue_url($parsed);
             } else {
                 // disallow relative URLs
                 $url = '';
             }
         }
         if ($parsed['is_pseudo'] || $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https') {
             // allow only http(s) URLs
             $url = '';
         } else {
             // reconstruct the URL from the error-tolerant parsing
             // http:moeffju.net/blog/ -> http://moeffju.net/blog/
             $url = InputFilter::glue_url($parsed);
         }
     }
     if (preg_match('/^\\p{Z}*$/u', $content)) {
         Session::error(_t('Comment contains only whitespace/empty comment'));
         Utils::redirect($post->permalink);
     }
     /* Create comment object*/
     $comment = new Comment(array('post_id' => $post->id, 'name' => $name, 'email' => $email, 'url' => $url, 'ip' => sprintf("%u", ip2long($_SERVER['REMOTE_ADDR'])), 'content' => $content, 'status' => Comment::STATUS_UNAPPROVED, 'date' => HabariDateTime::date_create(), 'type' => Comment::COMMENT));
     // Should this really be here or in a default filter?
     // In any case, we should let plugins modify the status after we set it here.
     $user = User::identify();
     if ($user->loggedin && $comment->email == $user->email) {
         $comment->status = Comment::STATUS_APPROVED;
     }
     // Users need to have permission to add comments
     if (!$user->can('comment')) {
         Session::error(_t('You do not have permission to create comments.'));
         Utils::redirect($post->permalink);
     }
     // Allow themes to work with comment hooks
     Themes::create();
     // Allow plugins to change comment data and add commentinfo based on plugin-added form fields
     Plugins::act('comment_accepted', $comment, $this->handler_vars, $extra);
     $spam_rating = 0;
     $spam_rating = Plugins::filter('spam_filter', $spam_rating, $comment, $this->handler_vars, $extra);
     $comment->insert();
     $anchor = '';
     // If the comment was saved
     if ($comment->id && $comment->status != Comment::STATUS_SPAM) {
         $anchor = '#comment-' . $comment->id;
         // store in the user's session that this comment is pending moderation
         if ($comment->status == Comment::STATUS_UNAPPROVED) {
             Session::notice(_t('Your comment is pending moderation.'), 'comment_' . $comment->id);
         }
         // if no cookie exists, we should set one
         // but only if the user provided some details
         $cookie = 'comment_' . Options::get('GUID');
         if (!User::identify()->loggedin && !isset($_COOKIE[$cookie]) && (!empty($name) || !empty($email) || !empty($url))) {
             $cookie_content = $comment->name . '#' . $comment->email . '#' . $comment->url;
             $site_url = Site::get_path('base', true);
             setcookie($cookie, $cookie_content, time() + 31536000, $site_url);
         }
     }
     // Return the commenter to the original page.
     Utils::redirect($post->permalink . $anchor);
 }
示例#6
0
 protected function get_local($file_name = '')
 {
     $parsed = InputFilter::parse_url($file_name);
     return HABARI_PATH . $parsed['path'];
 }
示例#7
0
	function upload( $photo, $title = '', $description = '', $tags = '', $perms = '', $async = 1, &$info = null )
	{
		$store = HABARI_PATH . '/' . Site::get_path( 'user' ) . '/cache';
		if ( !is_dir( $store ) ){
			mkdir( $store, 0777 );
		}
		$params = array( 'auth_token' => $this->cachedToken() );
		$url = InputFilter::parse_url( 'file://' . $photo );
		if ( isset( $url['scheme'] ) ){
			$localphoto = fopen( HABARI_PATH . '/' . $photo, 'r' );
			$store = tempnam( $store, 'G2F' );
			file_put_contents( $store, $localphoto );
			fclose( $localphoto );
			$params['photo'] = $store;
		}
		else{
			$params['photo'] = $photo;
		}

		$info = filesize( $params['photo'] );

		if ( $title ){
			$params['title'] = $title;
		}

		if ( $description ){
			$params['description'] = $description;
		}

		if ( $tags ){
			$params['tags'] = $tags;
		}

		if ( $perms ){
			if ( isset( $perms['is_public'] ) ){
				$params['is_public'] = $perms['is_public'];
			}
			if ( isset( $perms['is_friend'] ) ){
				$params['is_friend'] = $perms['is_friend'];
			}
			if ( isset( $perms['is_family'] ) ){
				$params['is_family'] = $perms['is_family'];
			}
		}

		if ( $async ){
			$params['async'] = $async;
		}
		// call the upload method.
		$xml = $this->call( 'upload', $params );

		if ( $store ){
			unlink( $store );
		}

		if ( Error::is_error( $xml ) ){
			throw $xml;
		}

		if ( $async ){
			return( (string)$xml->ticketid );
		}
		else{
			return( (string)$xml->photoid );
		}
	}
示例#8
0
 /**
  * Merge query params from the URL with given params.
  * @param string $url The URL
  * @param string $params An associative array of parameters.
  */
 private function merge_query_params($url, $params)
 {
     $urlparts = InputFilter::parse_url($url);
     if (!isset($urlparts['query'])) {
         $urlparts['query'] = '';
     }
     if (!is_array($params)) {
         parse_str($params, $params);
     }
     $urlparts['query'] = http_build_query(array_merge(Utils::get_params($urlparts['query']), $params), '', '&');
     return InputFilter::glue_url($urlparts);
 }
示例#9
0
文件: site.php 项目: wwxgitcat/habari
 /**
  * get_dir returns a complete filesystem path to the requested item
  *	'config_file' returns the complete path to the config.php file, including the filename
  *	'config' returns the path of the directory containing config.php
  *	'user' returns the path of the user directory
  *	'theme' returns the path of the site's active theme
  *  'admin_theme' returns the path to the admin directory
  *  'vendor' returns the path to the vendor directory
  * @param string the name of the path item to return
  * @param bool whether to include a trailing slash.  Default: No
  * @return string Path
  */
 public static function get_dir($name, $trail = false)
 {
     $path = '';
     switch (strtolower($name)) {
         case 'config_file':
             $path = Site::get_dir('config') . '/config.php';
             break;
         case 'config':
             if (self::$config_path) {
                 return self::$config_path;
             }
             self::$config_path = HABARI_PATH;
             $config_dirs = preg_replace('/^' . preg_quote(HABARI_PATH, '/') . '\\/user\\/sites\\/(.*)/', '$1', Utils::glob(HABARI_PATH . '/user/sites/*', GLOB_ONLYDIR));
             if (empty($config_dirs)) {
                 return self::$config_path;
             }
             $server = InputFilter::parse_url(Site::get_url('habari'));
             $request = array();
             if (isset($server['port']) && $server['port'] != '' && $server['port'] != '80') {
                 $request[] = $server['port'];
             }
             $request = array_merge($request, explode('.', $server['host']));
             $basesegments = count($request);
             $request = array_merge($request, explode('/', trim($_SERVER['REQUEST_URI'], '/')));
             $x = 0;
             do {
                 $match = implode('.', $request);
                 if (in_array($match, $config_dirs)) {
                     self::$config_dir = $match;
                     self::$config_path = HABARI_PATH . '/user/sites/' . self::$config_dir;
                     self::$config_type = $basesegments > count($request) ? Site::CONFIG_SUBDOMAIN : Site::CONFIG_SUBDIR;
                     self::$config_urldir = implode('/', array_slice($request, $basesegments));
                     break;
                 }
                 array_pop($request);
                 $x--;
                 if ($x < -10) {
                     echo $x;
                     var_dump($request);
                     die('too many ');
                 }
             } while (count($request) > 0);
             $path = self::$config_path;
             break;
         case 'user':
             if (Site::get_dir('config') == HABARI_PATH) {
                 $path = HABARI_PATH . '/user';
             } else {
                 $path = Site::get_dir('config');
             }
             break;
         case 'theme':
             $theme = Themes::get_theme_dir();
             if (file_exists(Site::get_dir('config') . '/themes/' . $theme)) {
                 $path = Site::get_dir('user') . '/themes/' . $theme;
             } elseif (file_exists(HABARI_PATH . '/user/themes/' . $theme)) {
                 $path = HABARI_PATH . '/user/themes/' . $theme;
             } elseif (file_exists(HABARI_PATH . '/3rdparty/themes/' . $theme)) {
                 $url = Site::get_url('habari') . '/3rdparty/themes/' . $theme;
             } else {
                 $path = HABARI_PATH . '/system/themes/' . $theme;
             }
             break;
         case 'admin_theme':
             $path = HABARI_PATH . '/system/admin';
             break;
         case 'vendor':
             $path = HABARI_PATH . '/system/vendor';
             break;
     }
     $path .= Utils::trail($trail);
     $path = Plugins::filter('site_dir_' . $name, $path);
     return $path;
 }
示例#10
0
	/**
	 * Scan all links in the content and send them a Pingback.
	 * @param string $content The post content to search
	 * @param string $source_uri The source of the content
	 * @param Post $post The post object of the source of the ping
	 * @param boolean $force If true, force the system to ping all links even if that had been pinged before
	 */
	public function pingback_all_links( $content, $source_uri, $post = NULL, $force = false )
	{
		
		$tokenizer = new HTMLTokenizer( $content, false );
		$tokens = $tokenizer->parse();

		// slice out only A tags
		$slices = $tokens->slice( array( 'a' ), array( ) );

		$urls = array();
		foreach ( $slices as $slice ) {

			// if there is no href attribute, just skip it, though there is something wrong
			if ( !isset( $slice[0]['attrs']['href'] ) ) {
				continue;
			}
			else {
				$url = $slice[0]['attrs']['href'];
			}

			// make sure it's a valid URL before we waste our time
			$parsed = InputFilter::parse_url( $url );
			
			if ( $parsed['is_error'] || $parsed['is_pseudo'] || $parsed['is_relative'] ) {
				continue;
			}
			else {
				$urls[] = $url;
			}

		}
		
		if ( is_object( $post ) && isset( $post->info->pingbacks_successful ) ) {
			$fn = ( $force === true ) ? 'array_merge' : 'array_diff';
			$links = $fn( $urls, $post->info->pingbacks_successful );
		}
		else {
			$links = $urls;
		}

		$links = array_unique( $links );

		foreach ( $links as $target_uri ) {
			if ( $this->send_pingback( $source_uri, $target_uri, $post ) ) {
				EventLog::log( _t( 'Sent pingbacks for "%1$s", target: %2$s', array( $post->title, $target_uri ) ), 'info', 'Pingback' );
			}
		}
	}
示例#11
0
 /**
  * @todo Does not honor timeouts on the actual request, only on the connect() call.
  */
 private function _work($method, $urlbits, $headers, $body, $timeout)
 {
     $_errno = 0;
     $_errstr = '';
     if (!isset($urlbits['port']) || $urlbits['port'] == 0) {
         $urlbits['port'] = 80;
     }
     $fp = @fsockopen($urlbits['host'], $urlbits['port'], $_errno, $_errstr, $timeout);
     if ($fp === FALSE) {
         return Error::raise(sprintf(_t('%s: Error %d: %s while connecting to %s:%d'), __CLASS__, $_errno, $_errstr, $urlbits['host'], $urlbits['port']), E_USER_WARNING);
     }
     // timeout to fsockopen() only applies for connecting
     stream_set_timeout($fp, $timeout);
     // fix headers
     $headers['Host'] = $urlbits['host'];
     $headers['Connection'] = 'close';
     // merge headers into a list
     $merged_headers = array();
     foreach ($headers as $k => $v) {
         $merged_headers[] = $k . ': ' . $v;
     }
     // build the request
     $request = array();
     $resource = $urlbits['path'];
     if (isset($urlbits['query'])) {
         $resource .= '?' . $urlbits['query'];
     }
     $request[] = "{$method} {$resource} HTTP/1.1";
     $request = array_merge($request, $merged_headers);
     $request[] = '';
     if ($method === 'POST') {
         $request[] = $body;
     }
     $request[] = '';
     $out = implode("\r\n", $request);
     if (!fwrite($fp, $out, strlen($out))) {
         return Error::raise(_t('Error writing to socket.'));
     }
     $in = '';
     while (!feof($fp)) {
         $in .= fgets($fp, 1024);
     }
     fclose($fp);
     list($header, $body) = explode("\r\n\r\n", $in);
     // to make the following REs match $ correctly
     // and thus not break parse_url
     $header = str_replace("\r\n", "\n", $header);
     preg_match('|^HTTP/1\\.[01] ([1-5][0-9][0-9]) ?(.*)|', $header, $status_matches);
     if ($status_matches[1] == '301' || $status_matches[1] == '302') {
         if (preg_match('|^Location: (.+)$|mi', $header, $location_matches)) {
             $redirect_url = $location_matches[1];
             $redirect_urlbits = InputFilter::parse_url($redirect_url);
             if (!isset($redirect_url['host'])) {
                 $redirect_urlbits['host'] = $urlbits['host'];
             }
             $this->redir_count++;
             if ($this->redir_count > $this->max_redirs) {
                 return Error::raise(_t('Maximum number of redirections exceeded.'));
             }
             return $this->_work($method, $redirect_urlbits, $headers, $body, $timeout);
         } else {
             return Error::raise(_t('Redirection response without Location: header.'));
         }
     }
     if (preg_match('|^Transfer-Encoding:.*chunked.*|mi', $header)) {
         $body = $this->_unchunk($body);
     }
     return array($header, $body);
 }
示例#12
0
文件: theme.php 项目: habari/system
 /**
  * Returns a humane commenter's link for a comment if a URL is supplied, or just display the comment author's name
  *
  * @param Theme $theme The current theme
  * @param Comment $comment The comment object
  * @return string A link to the comment author or the comment author's name with no link
  */
 public function theme_comment_author_link($theme, $comment)
 {
     $url = $comment->url;
     if ($url != '') {
         $parsed_url = InputFilter::parse_url($url);
         if ($parsed_url['host'] == '') {
             $url = '';
         } else {
             $url = InputFilter::glue_url($parsed_url);
         }
     }
     if ($url != '') {
         return '<a href="' . $url . '">' . $comment->name . '</a>';
     } else {
         return $comment->name;
     }
 }
示例#13
0
文件: site.php 项目: habari/system
 /**
  * get_dir returns a complete filesystem path to the requested item
  *	'config_file' returns the complete path to the config.php file, including the filename
  *	'config' returns the path of the directory containing config.php
  *	'user' returns the path of the user directory
  *	'theme' returns the path of the site's active theme
  *  'admin_theme' returns the path to the admin directory
  *  'vendor' returns the path to the vendor directory
  * @param string $name the name of the path item to return
  * @param bool|string $trail whether to include a trailing slash, or a string to use as the trailing value.  Default: false
  * @return string Path
  */
 public static function get_dir($name, $trail = false)
 {
     $path = '';
     switch (strtolower($name)) {
         case 'config_file':
             $path = Site::get_dir('config') . '/config.php';
             break;
         case 'config':
             if (self::$config_path) {
                 return self::$config_path;
             }
             self::$config_path = HABARI_PATH;
             $config_dirs = preg_replace('/^' . preg_quote(HABARI_PATH, '/') . '\\/user\\/sites\\/(.*)/', '$1', Utils::glob(HABARI_PATH . '/user/sites/*', GLOB_ONLYDIR));
             if (empty($config_dirs)) {
                 return self::$config_path;
             }
             // Collect host parts
             $server = InputFilter::parse_url(Site::get_url('habari'));
             $request = array();
             if (isset($server['port']) && $server['port'] != '' && $server['port'] != '80') {
                 $request[] = $server['port'];
             }
             $request = array_merge($request, explode('.', $server['host']));
             // Collect the subdirectory(s) the core is located in to determine the base path later
             // Don't add them to $request, they will be added with $_SERVER['REQUEST_URI']
             $basesegments = count($request);
             if (!empty($server['path'])) {
                 $coresubdir = explode('/', trim($server['path'], '/'));
                 $basesegments += count($coresubdir);
             }
             // Preserve $request without directories for fallback
             $request_base = $request;
             // Add directory part
             if (!empty(trim($_SERVER['REQUEST_URI'], '/'))) {
                 $subdirectories = explode('/', trim($_SERVER['REQUEST_URI'], '/'));
                 $request = array_merge($request, $subdirectories);
             }
             // Now cut parts until we found a matching site directory
             $cuts = 0;
             $dir_cuts = 0;
             do {
                 $match = implode('.', $request);
                 if (in_array($match, $config_dirs)) {
                     self::$config_dir = $match;
                     self::$config_path = HABARI_PATH . '/user/sites/' . self::$config_dir;
                     self::$config_type = isset($subdirectories) && array_intersect($subdirectories, $request) == $subdirectories ? Site::CONFIG_SUBDIR : Site::CONFIG_SUBDOMAIN;
                     self::$config_urldir = implode('/', array_slice($request, $basesegments + $cuts));
                     break;
                 }
                 // Cut a part from the beginning
                 array_shift($request);
                 $cuts--;
                 // Do not fallback to only the directory part, instead, cut one and start over
                 if ($basesegments + $cuts <= 0 && isset($subdirectories) && $dir_cuts < count($subdirectories)) {
                     $cuts = 0;
                     $dir_cuts++;
                     $request = array_merge($request_base, array_slice($subdirectories, 0, count($subdirectories) - $dir_cuts));
                 }
                 // What does the following check do?!
                 if ($cuts < -10) {
                     echo $cuts;
                     var_dump($request);
                     die('too many ');
                 }
             } while (count($request) > 0);
             $path = self::$config_path;
             break;
         case 'user':
             if (Site::get_dir('config') == HABARI_PATH) {
                 $path = HABARI_PATH . '/user';
             } else {
                 $path = Site::get_dir('config');
             }
             break;
         case 'theme':
             $theme = Themes::get_theme_dir();
             if (file_exists(Site::get_dir('config') . '/themes/' . $theme)) {
                 $path = Site::get_dir('user') . '/themes/' . $theme;
             } elseif (file_exists(HABARI_PATH . '/user/themes/' . $theme)) {
                 $path = HABARI_PATH . '/user/themes/' . $theme;
             } elseif (file_exists(HABARI_PATH . '/3rdparty/themes/' . $theme)) {
                 $path = Site::get_dir('habari') . '/3rdparty/themes/' . $theme;
             } else {
                 $path = HABARI_PATH . '/system/themes/' . $theme;
             }
             break;
         case 'admin_theme':
             $path = HABARI_PATH . '/system/admin';
             break;
         case 'vendor':
             $path = HABARI_PATH . '/system/vendor';
             break;
     }
     $path .= Utils::trail($trail);
     $path = Plugins::filter('site_dir_' . $name, $path);
     return $path;
 }
示例#14
0
 /**
  * function add_comment
  * adds a comment to a post, if the comment content is not NULL
  * @param array An associative array of content found in the $_POST array
  */
 public function act_add_comment()
 {
     Utils::check_request_method(array('POST'));
     $defaults = array('name' => '', 'email' => '', 'url' => '', 'content' => '');
     // We need to get the post anyway to redirect back to the post page.
     $post = Post::get(array('id' => $this->handler_vars['id']));
     if (!$post) {
         // trying to comment on a non-existent post?  Weirdo.
         header('HTTP/1.1 403 Forbidden', true, 403);
         die;
     }
     // make sure all our default values are set so we don't throw undefined index errors
     foreach ($defaults as $k => $v) {
         if (!isset($this->handler_vars[$k])) {
             $this->handler_vars[$k] = $v;
         }
     }
     // let's do some basic sanity checking on the submission
     if (1 == Options::get('comments_require_id') && (empty($this->handler_vars['name']) || empty($this->handler_vars['email']))) {
         Session::error(_t('Both name and e-mail address must be provided.'));
     }
     if (empty($this->handler_vars['content'])) {
         Session::error(_t('You did not provide any content for your comment!'));
     }
     if (Session::has_errors()) {
         // save whatever was provided in session data
         Session::add_to_set('comment', $this->handler_vars['name'], 'name');
         Session::add_to_set('comment', $this->handler_vars['email'], 'email');
         Session::add_to_set('comment', $this->handler_vars['url'], 'url');
         Session::add_to_set('comment', $this->handler_vars['content'], 'content');
         // now send them back to the form
         Utils::redirect($post->permalink . '#respond');
     }
     if ($post->info->comments_disabled) {
         // comments are disabled, so let's just send
         // them back to the post's permalink
         Session::error(_t('Comments on this post are disabled!'));
         Utils::redirect($post->permalink);
     }
     /* Sanitize data */
     foreach ($defaults as $k => $v) {
         $this->handler_vars[$k] = InputFilter::filter($this->handler_vars[$k]);
     }
     /* Sanitize the URL */
     if (!empty($this->handler_vars['url'])) {
         $url = $this->handler_vars['url'];
         $parsed = InputFilter::parse_url($url);
         if ($parsed['is_relative']) {
             // guess if they meant to use an absolute link
             $parsed = InputFilter::parse_url('http://' . $url);
             if (!$parsed['is_error']) {
                 $url = InputFilter::glue_url($parsed);
             } else {
                 // disallow relative URLs
                 $url = '';
             }
         }
         if ($parsed['is_pseudo'] || $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https') {
             // allow only http(s) URLs
             $url = '';
         } else {
             // reconstruct the URL from the error-tolerant parsing
             // http:moeffju.net/blog/ -> http://moeffju.net/blog/
             $url = InputFilter::glue_url($parsed);
         }
         $this->handler_vars['url'] = $url;
     }
     if (preg_match('/^\\p{Z}*$/u', $this->handler_vars['content'])) {
         Session::error(_t('Comment contains only whitespace/empty comment'));
         Utils::redirect($post->permalink);
     }
     /* Create comment object*/
     $comment = new Comment(array('post_id' => $this->handler_vars['id'], 'name' => $this->handler_vars['name'], 'email' => $this->handler_vars['email'], 'url' => $this->handler_vars['url'], 'ip' => sprintf("%u", ip2long($_SERVER['REMOTE_ADDR'])), 'content' => $this->handler_vars['content'], 'status' => Comment::STATUS_UNAPPROVED, 'date' => HabariDateTime::date_create(), 'type' => Comment::COMMENT));
     // Should this really be here or in a default filter?
     // In any case, we should let plugins modify the status after we set it here.
     $user = User::identify();
     if ($user->loggedin && $comment->email == $user->email) {
         $comment->status = Comment::STATUS_APPROVED;
     }
     // Allow themes to work with comment hooks
     Themes::create();
     $spam_rating = 0;
     $spam_rating = Plugins::filter('spam_filter', $spam_rating, $comment, $this->handler_vars);
     $comment->insert();
     $anchor = '';
     // If the comment was saved
     if ($comment->id) {
         $anchor = '#comment-' . $comment->id;
         // store in the user's session that this comment is pending moderation
         if ($comment->status == Comment::STATUS_UNAPPROVED) {
             Session::notice(_t('Your comment is pending moderation.'), 'comment_' . $comment->id);
         }
         // if no cookie exists, we should set one
         // but only if the user provided some details
         $cookie = 'comment_' . Options::get('GUID');
         if (!isset($_COOKIE[$cookie]) && (!empty($this->handler_vars['name']) || !empty($this->handler_vars['email']) || !empty($this->handler_vars['url']))) {
             $cookie_content = $comment->name . '#' . $comment->email . '#' . $comment->url;
             $site_url = Site::get_path('base', true);
             setcookie($cookie, $cookie_content, time() + 31536000, $site_url);
         }
     }
     // Return the commenter to the original page.
     Utils::redirect($post->permalink . $anchor);
 }
示例#15
0
 public function execute($method, $url, $headers, $body, $config)
 {
     $merged_headers = array();
     foreach ($headers as $k => $v) {
         $merged_headers[] = $k . ': ' . $v;
     }
     $ch = curl_init();
     $options = array(CURLOPT_URL => $url, CURLOPT_HEADERFUNCTION => array(&$this, '_headerfunction'), CURLOPT_MAXREDIRS => $config['max_redirects'], CURLOPT_CONNECTTIMEOUT => $config['connect_timeout'], CURLOPT_TIMEOUT => $config['timeout'], CURLOPT_SSL_VERIFYPEER => $config['ssl']['verify_peer'], CURLOPT_SSL_VERIFYHOST => $config['ssl']['verify_host'], CURLOPT_BUFFERSIZE => $config['buffer_size'], CURLOPT_HTTPHEADER => $merged_headers, CURLOPT_FAILONERROR => true, CURLOPT_ENCODING => '');
     if ($this->can_followlocation && $config['follow_redirects']) {
         $options[CURLOPT_FOLLOWLOCATION] = true;
         // Follow 302's and the like.
     }
     switch ($method) {
         case 'POST':
             $options[CURLOPT_POST] = true;
             // POST mode.
             $options[CURLOPT_POSTFIELDS] = $body;
             break;
         case 'HEAD':
             $options[CURLOPT_HEADER] = true;
             $options[CURLOPT_NOBODY] = true;
             break;
         default:
             $options[CURLOPT_CRLF] = true;
             // Convert UNIX newlines to \r\n
             break;
     }
     // set proxy, if needed
     $urlbits = InputFilter::parse_url($url);
     if ($config['proxy']['server'] && !in_array($urlbits['host'], $config['proxy']['exceptions'])) {
         $options[CURLOPT_PROXY] = $config['proxy']['server'] . ':' . $config['proxy']['port'];
         // Validation of the existence of the port should take place in the Options form
         if ($config['proxy']['username']) {
             $options[CURLOPT_PROXYUSERPWD] = $config['proxy']['username'] . ':' . $config['proxy']['password'];
             switch ($config['proxy']['auth_type']) {
                 case 'basic':
                     $options[CURLOPT_PROXYAUTH] = CURLAUTH_BASIC;
                     break;
                 case 'digest':
                     $options[CURLOPT_PROXYAUTH] = CURLAUTH_DIGEST;
                     break;
             }
         }
         // if it's a socks proxy, we have to tell curl that
         if ($config['proxy']['type'] == 'socks') {
             $options[CURLOPT_PROXYTYPE] = CURLPROXY_SOCKS5;
         }
     }
     curl_setopt_array($ch, $options);
     /**
      * @todo Possibly find a way to generate a temp file without needing the user
      * to set write permissions on cache directory
      *
      * @todo Fallback to using the the old way if the cache directory isn't writable
      * 
      * @todo How about trying to use the system-defined temp directory? We could at least try, even if safe_mode or something breaks it. - chrismeller
      */
     $tmp = tempnam(FILE_CACHE_LOCATION, 'RR');
     if (!$tmp) {
         throw new \Exception(_t('CURL Error. Unable to create temporary file name.'));
     }
     $fh = @fopen($tmp, 'w+b');
     if (!$fh) {
         throw new \Exception(_t('CURL Error. Unable to open temporary file.'));
     }
     curl_setopt($ch, CURLOPT_FILE, $fh);
     $success = curl_exec($ch);
     if ($success) {
         rewind($fh);
         $body = stream_get_contents($fh);
     }
     fclose($fh);
     unset($fh);
     if (isset($tmp) && file_exists($tmp)) {
         unlink($tmp);
     }
     if (curl_errno($ch) !== 0) {
         // get the number and error before we close the handle so we don't error out
         $errno = curl_errno($ch);
         $error = curl_error($ch);
         // before we throw an exception, just to be nice
         curl_close($ch);
         switch ($errno) {
             case CURLE_OPERATION_TIMEOUTED:
                 // the request timed out
                 throw new RemoteRequest_Timeout($error, $errno);
                 break;
             default:
                 throw new \Exception(_t('CURL Error %1$d: %2$s', array($errno, $error)));
                 break;
         }
     }
     curl_close($ch);
     $this->response_headers = $this->headers;
     // really redundant now, since we could write directly to response_headers, but makes it more clear where they came from
     $this->response_body = $body;
     $this->executed = true;
     return true;
 }
示例#16
0
文件: utils.php 项目: habari/system
 /**
  * Return &amp; entities in a URL querystring to their previous & glory, for use in redirects
  * @param string $value A URL, maybe with a querystring
  * @return bool|string The valid, de-amped URL
  */
 public static function de_amp($value)
 {
     $url = InputFilter::parse_url($value);
     $url['query'] = str_replace('&amp;', '&', $url['query']);
     return InputFilter::glue_url($url);
 }
 public function filter_comment_url_out($value, $comment)
 {
     $whitelist = $this->get_whitelist();
     if (count($whitelist) > 0 && $comment->url != '') {
         $comment_url = InputFilter::parse_url($value);
         $domain = $comment_url['host'];
         if (in_array($domain, $whitelist)) {
             return $value;
         }
     }
     if (isset($comment->info->redirecturl)) {
         if ($comment->info->redirecturl == URLApprove::REDIRECT) {
             $value = URL::get('comment_url_redirect', array('id' => $comment->id, 'ccode' => $this->get_hash($comment->id)));
         }
     } elseif (Options::get('urlapprove__redirect_default') == true) {
         $value = URL::get('comment_url_redirect', array('id' => $comment->id, 'ccode' => $this->get_hash($comment->id)));
     }
     return $value;
 }
示例#18
0
	/**
	 * get_dir returns a complete filesystem path to the requested item
	 *	'config_file' returns the complete path to the config.php file, including the filename
	 *	'config' returns the path of the directory containing config.php
	 *	'user' returns the path of the user directory
	 *	'theme' returns the path of the site's active theme
	 * @param string the name of the path item to return
	 * @param bool whether to include a trailing slash.  Default: No
	 * @return string Path
	 */
	public static function get_dir( $name, $trail = false )
	{
		$path = '';

		switch ( strtolower( $name ) ) {
			case 'config_file':
				$path = Site::get_dir( 'config' ) . '/config.php';
				break;
			case 'config':
				if ( self::$config_path ) {
					return self::$config_path;
				}

				self::$config_path = HABARI_PATH;

				$config_dirs = preg_replace( '/^' . preg_quote( HABARI_PATH, '/' ) . '\/user\/sites\/(.*)\/config.php/', '$1', Utils::glob( HABARI_PATH . '/user/sites/*/config.php' ) );

				if ( empty( $config_dirs ) ) {
					return self::$config_path;
				}

				$server = InputFilter::parse_url( Site::get_url( 'habari' ) );
				$server = ( isset( $server['port'] ) ) ? $server['port'] . '.' . $server['host'] . '.' : $server['host'] . '.';

				$request = explode( '/', trim( $_SERVER['REQUEST_URI'], '/' ) );
				$match = trim( $server, '.' );
				$x = count( $request );
				do {
					if ( in_array( $match, $config_dirs ) ) {
						self::$config_dir = $match;
						self::$config_path = HABARI_PATH . '/user/sites/' . self::$config_dir;
						self::$config_type = ( $x > 0 ) ? Site::CONFIG_SUBDOMAIN : Site::CONFIG_SUBDIR;
						break;
					}

					$match = MultiByte::substr( $match, MultiByte::strpos( $match, '.' ) + 1 );
					$x--;
				} while ( MultiByte::strpos( $match, '.' ) !== false );

				$path = self::$config_path;
				break;
			case 'user':
				if ( Site::get_dir( 'config' ) == HABARI_PATH ) {
					$path = HABARI_PATH . '/user';
				}
				else {
					$path = Site::get_dir( 'config' );
				}
				break;
			case 'theme':
				$theme = Themes::get_theme_dir();
				if ( file_exists( Site::get_dir( 'config' ) . '/themes/' . $theme ) ) {
					$path = Site::get_dir( 'user' ) . '/themes/' . $theme;
				}
				elseif ( file_exists( HABARI_PATH . '/user/themes/' . $theme ) ) {
					$path = HABARI_PATH . '/user/themes/' . $theme;
				}
				elseif ( file_exists( HABARI_PATH . '/3rdparty/themes/' . $theme ) ) {
					$url = Site::get_url( 'habari' ) . '/3rdparty/themes/' . $theme;
				}
				else {
					$path = HABARI_PATH . '/system/themes/' . $theme;
				}
				break;
			case 'admin_theme':
				$path = HABARI_PATH . '/system/admin';
				break;
			case 'vendor':
				$path = HABARI_PATH . '/system/vendor';
				break;
		}
		$path .= Utils::trail( $trail );
		$path = Plugins::filter( 'site_dir_' . $name, $path );
		return $path;
	}
示例#19
0
 /**
  * Receive a Pingback via XMLRPC
  * @param array $params An array of XMLRPC parameters from the remote call
  * @return string The success state of the pingback
  */
 public function xmlrpc_pingback__ping($params)
 {
     try {
         list($source_uri, $target_uri) = $params;
         // This should really be done by an Habari core function
         $target_parse = InputFilter::parse_url($target_uri);
         $target_stub = $target_parse['path'];
         $base_url = Site::get_path('base', TRUE);
         if ('/' != $base_url) {
             $target_stub = str_replace($base_url, '', $target_stub);
         }
         $target_stub = trim($target_stub, '/');
         if (strpos($target_stub, '?') !== FALSE) {
             list($target_stub, $query_string) = explode('?', $target_stub);
         }
         // Can this be used as a target?
         $target_slug = URL::parse($target_stub)->named_arg_values['slug'];
         if ($target_slug === FALSE) {
             throw new XMLRPCException(33);
         }
         // Does the target exist?
         $target_post = Post::get(array('slug' => $target_slug));
         if ($target_post === FALSE) {
             throw new XMLRPCException(32);
         }
         // Is comment allowed?
         if ($target_post->info->comments_disabled) {
             throw new XMLRPCException(33);
         }
         // Is this Pingback already registered?
         if (Comments::get(array('post_id' => $target_post->id, 'url' => $source_uri, 'type' => Comment::PINGBACK))->count() > 0) {
             throw new XMLRPCException(48);
         }
         // Retrieve source contents
         $rr = new RemoteRequest($source_uri);
         $rr->execute();
         if (!$rr->executed()) {
             throw new XMLRPCException(16);
         }
         $source_contents = $rr->get_response_body();
         // encoding is converted into internal encoding.
         // @todo check BOM at beginning of file before checking for a charset attribute
         $habari_encoding = MultiByte::hab_encoding();
         if (preg_match("/<meta[^>]+charset=([A-Za-z0-9\\-\\_]+)/i", $source_contents, $matches) !== FALSE && strtolower($habari_encoding) != strtolower($matches[1])) {
             $ret = MultiByte::convert_encoding($source_contents, $habari_encoding, $matches[1]);
             if ($ret !== FALSE) {
                 $source_contents = $ret;
             }
         }
         // Find the page's title
         preg_match('/<title>(.*)<\\/title>/is', $source_contents, $matches);
         $source_title = $matches[1];
         // Find the reciprocal links and their context
         preg_match('/<body[^>]*>(.+)<\\/body>/is', $source_contents, $matches);
         $source_contents_filtered = preg_replace('/\\s{2,}/is', ' ', strip_tags($matches[1], '<a>'));
         if (!preg_match('%.{0,100}?<a[^>]*?href\\s*=\\s*("|\'|)' . $target_uri . '\\1[^>]*?' . '>(.+?)</a>.{0,100}%s', $source_contents_filtered, $source_excerpt)) {
             throw new XMLRPCException(17);
         }
         /** Sanitize Data */
         $source_excerpt = '...' . InputFilter::filter($source_excerpt[0]) . '...';
         $source_title = InputFilter::filter($source_title);
         $source_uri = InputFilter::filter($source_uri);
         /* Sanitize the URL */
         if (!empty($source_uri)) {
             $parsed = InputFilter::parse_url($source_uri);
             if ($parsed['is_relative']) {
                 // guess if they meant to use an absolute link
                 $parsed = InputFilter::parse_url('http://' . $source_uri);
                 if (!$parsed['is_error']) {
                     $source_uri = InputFilter::glue_url($parsed);
                 } else {
                     // disallow relative URLs
                     $source_uri = '';
                 }
             }
             if ($parsed['is_pseudo'] || $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https') {
                 // allow only http(s) URLs
                 $source_uri = '';
             } else {
                 // reconstruct the URL from the error-tolerant parsing
                 // http:moeffju.net/blog/ -> http://moeffju.net/blog/
                 $source_uri = InputFilter::glue_url($parsed);
             }
         }
         // Add a new pingback comment
         $pingback = new Comment(array('post_id' => $target_post->id, 'name' => $source_title, 'email' => '', 'url' => $source_uri, 'ip' => sprintf("%u", ip2long($_SERVER['REMOTE_ADDR'])), 'content' => $source_excerpt, 'status' => Comment::STATUS_UNAPPROVED, 'date' => HabariDateTime::date_create(), 'type' => Comment::PINGBACK));
         $pingback->insert();
         // Respond to the Pingback
         return 'The pingback has been registered';
     } catch (XMLRPCException $e) {
         $e->output_fault_xml();
     }
 }
示例#20
0
 /**
  * Add a comment to the site
  *
  * @param mixed $post A Post object instance or Post object id
  * @param string $name The commenter's name
  * @param string $email The commenter's email address
  * @param string $url The commenter's website URL
  * @param string $content The comment content
  * @param array $extra An associative array of extra values that should be considered
  */
 function add_comment($post, $name = null, $email = null, $url = null, $content = null, $extra = null)
 {
     if (is_numeric($post)) {
         $post = Post::get(array('id' => $post));
     }
     if (!$post instanceof Post) {
         // Not sure what you're trying to pull here, but that's no good
         header('HTTP/1.1 403 Forbidden', true, 403);
         die;
     }
     /* Sanitize data */
     foreach (array('name', 'url', 'email', 'content') as $k) {
         ${$k} = InputFilter::filter(${$k});
     }
     // there should never be any HTML in the name, so do some extra filtering on it
     $name = strip_tags(html_entity_decode($name, ENT_QUOTES, 'UTF-8'));
     /* Sanitize the URL */
     if (!empty($url)) {
         $parsed = InputFilter::parse_url($url);
         if ($parsed['is_relative']) {
             // guess if they meant to use an absolute link
             $parsed = InputFilter::parse_url('http://' . $url);
             if (!$parsed['is_error']) {
                 $url = InputFilter::glue_url($parsed);
             } else {
                 // disallow relative URLs
                 $url = '';
             }
         }
         if ($parsed['is_pseudo'] || $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https') {
             // allow only http(s) URLs
             $url = '';
         } else {
             // reconstruct the URL from the error-tolerant parsing
             // http:moeffju.net/blog/ -> http://moeffju.net/blog/
             $url = InputFilter::glue_url($parsed);
         }
     }
     /* Create comment object*/
     $comment = new Comment(array('post_id' => $post->id, 'name' => $name, 'email' => $email, 'url' => $url, 'ip' => Utils::get_ip(), 'content' => $content, 'status' => Comment::status('approved'), 'date' => DateTime::create(), 'type' => Comment::type('comment')));
     // Should this really be here or in a default filter?
     // In any case, we should let plugins modify the status after we set it here.
     $user = User::identify();
     if ($user->loggedin && $comment->email == $user->email) {
         $comment->status = 'approved';
     }
     // Allow themes to work with comment hooks
     Themes::create();
     // Allow plugins to change comment data and add commentinfo based on plugin-added form fields
     Plugins::act('comment_accepted', $comment, $this->handler_vars, $extra);
     $spam_rating = 0;
     $spam_rating = Plugins::filter('spam_filter', $spam_rating, $comment, $this->handler_vars, $extra);
     if ($spam_rating >= Options::get('spam_percentage', 100)) {
         $comment->status = 'spam';
     }
     $comment->insert();
     $anchor = '';
     // If the comment was saved
     if ($comment->id && $comment->status != 'spam') {
         $anchor = '#comment-' . $comment->id;
         // store in the user's session that this comment is pending moderation
         if ($comment->status == 'unapproved') {
             Session::notice(_t('Your comment is pending moderation.'), 'comment_' . $comment->id);
         }
         // if no cookie exists, we should set one
         // but only if the user provided some details
         $cookie_name = 'comment_' . Options::get('public-GUID');
         // build the string we store for the cookie
         $cookie_content = implode('#', array($comment->name, $comment->email, $comment->url));
         // if the user is not logged in and there is no cookie OR the cookie differs from the current set
         if (User::identify()->loggedin == false && (!isset($_COOKIE[$cookie_name]) || $_COOKIE[$cookie_name] != $cookie_content)) {
             // update the cookie
             setcookie($cookie_name, $cookie_content, time() + DateTime::YEAR, Site::get_path('base', true));
         }
     }
     // Return the commenter to the original page.
     Utils::redirect($post->permalink . $anchor);
 }